Explorar o código

split mega tx.rs file into subfiles inside tx module

narodnik %!s(int64=5) %!d(string=hai) anos
pai
achega
4edca469cb
Modificáronse 4 ficheiros con 376 adicións e 329 borrados
  1. 10 0
      src/crypto/nullifier.rs
  2. 194 0
      src/tx/builder.rs
  3. 73 329
      src/tx/mod.rs
  4. 99 0
      src/tx/partial.rs

+ 10 - 0
src/crypto/nullifier.rs

@@ -0,0 +1,10 @@
+pub struct Nullifier {
+    pub repr: [u8; 32],
+}
+
+impl Nullifier {
+    pub fn new(repr: [u8; 32]) -> Self {
+        Self { repr }
+    }
+}
+

+ 194 - 0
src/tx/builder.rs

@@ -0,0 +1,194 @@
+use bellman::groth16;
+use bls12_381::Bls12;
+use rand::rngs::OsRng;
+use std::collections::HashMap;
+use std::io;
+use ff::Field;
+
+use crate::error::{Error, Result};
+use crate::serial::{Decodable, Encodable, VarInt};
+use super::{TransactionClearInput, TransactionInput, TransactionOutput, Transaction, partial::{PartialTransactionClearInput, PartialTransactionInput, PartialTransaction}};
+use crate::crypto::{
+    coin::Coin,
+    create_mint_proof, create_spend_proof, load_params,
+    merkle::CommitmentTree,
+    note::{EncryptedNote, Note},
+    save_params, schnorr, setup_mint_prover, setup_spend_prover, verify_mint_proof,
+    verify_spend_proof, MintRevealedValues, SpendRevealedValues,
+};
+
+pub struct TransactionBuilder {
+    pub clear_inputs: Vec<TransactionBuilderClearInputInfo>,
+    pub inputs: Vec<TransactionBuilderInputInfo>,
+    pub outputs: Vec<TransactionBuilderOutputInfo>,
+}
+
+pub struct TransactionBuilderClearInputInfo {
+    pub value: u64,
+    pub signature_secret: jubjub::Fr,
+}
+
+pub struct TransactionBuilderInputInfo {
+    pub merkle_path: Vec<(bls12_381::Scalar, bool)>,
+    pub secret: jubjub::Fr,
+    pub note: Note,
+}
+
+pub struct TransactionBuilderOutputInfo {
+    pub value: u64,
+    pub public: jubjub::SubgroupPoint,
+}
+
+impl TransactionBuilder {
+    fn compute_remainder_blind(
+        clear_inputs: &Vec<PartialTransactionClearInput>,
+        input_blinds: &Vec<jubjub::Fr>,
+        output_blinds: &Vec<jubjub::Fr>,
+    ) -> jubjub::Fr {
+        let mut total = jubjub::Fr::zero();
+
+        for input in clear_inputs {
+            total += input.valcom_blind;
+        }
+
+        for input_blind in input_blinds {
+            total += input_blind;
+        }
+
+        for output_blind in output_blinds {
+            total -= output_blind;
+        }
+
+        total
+    }
+
+    pub fn build(
+        self,
+        mint_params: &groth16::Parameters<Bls12>,
+        spend_params: &groth16::Parameters<Bls12>,
+    ) -> Transaction {
+        let mut clear_inputs = vec![];
+        for input in &self.clear_inputs {
+            let signature_public =
+                zcash_primitives::constants::SPENDING_KEY_GENERATOR * input.signature_secret;
+
+            let valcom_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
+            let clear_input = PartialTransactionClearInput {
+                value: input.value,
+                valcom_blind,
+                signature_public,
+            };
+            clear_inputs.push(clear_input);
+        }
+
+        let mut inputs = vec![];
+        let mut input_blinds = vec![];
+        let mut signature_secrets = vec![];
+        for input in &self.inputs {
+            input_blinds.push(input.note.valcom_blind.clone());
+
+            let signature_secret: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
+
+            // make proof
+
+            let (proof, revealed) = create_spend_proof(
+                &spend_params,
+                input.note.value,
+                input.note.valcom_blind,
+                input.note.serial,
+                input.note.coin_blind,
+                input.secret,
+                input.merkle_path.clone(),
+                signature_secret.clone(),
+            );
+
+            // First we make the tx then sign after
+            let signature_secret = schnorr::SecretKey(signature_secret);
+            signature_secrets.push(signature_secret);
+
+            let input = PartialTransactionInput {
+                spend_proof: proof,
+                revealed,
+            };
+            inputs.push(input);
+        }
+
+        let mut outputs = vec![];
+        let mut output_blinds = vec![];
+        for (i, output) in self.outputs.iter().enumerate() {
+            let valcom_blind = if i == self.outputs.len() - 1 {
+                Self::compute_remainder_blind(&clear_inputs, &input_blinds, &output_blinds)
+            } else {
+                jubjub::Fr::random(&mut OsRng)
+            };
+            output_blinds.push(valcom_blind);
+
+            let serial: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
+            let coin_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
+
+            let (mint_proof, revealed) = create_mint_proof(
+                mint_params,
+                output.value,
+                valcom_blind.clone(),
+                serial.clone(),
+                coin_blind.clone(),
+                output.public.clone(),
+            );
+
+            // Encrypted note
+
+            let note = Note {
+                serial,
+                value: output.value,
+                coin_blind,
+                valcom_blind,
+            };
+
+            let encrypted_note = note.encrypt(&output.public).unwrap();
+
+            let output = TransactionOutput {
+                mint_proof,
+                revealed,
+                enc_note: encrypted_note,
+            };
+            outputs.push(output);
+        }
+
+        let partial_tx = PartialTransaction {
+            clear_inputs,
+            inputs,
+            outputs,
+        };
+
+        let mut unsigned_tx_data = vec![];
+        partial_tx
+            .encode(&mut unsigned_tx_data)
+            .expect("TODO handle this");
+
+        let mut clear_inputs = vec![];
+        for (input, info) in partial_tx.clear_inputs.into_iter().zip(self.clear_inputs) {
+            let secret = schnorr::SecretKey(info.signature_secret.clone());
+            let signature = secret.sign(&unsigned_tx_data[..]);
+            let input = TransactionClearInput::from_partial(input, signature);
+            clear_inputs.push(input);
+        }
+
+        let mut inputs = vec![];
+        for (input, signature_secret) in partial_tx
+            .inputs
+            .into_iter()
+            .zip(signature_secrets.into_iter())
+        {
+            let signature = signature_secret.sign(&unsigned_tx_data[..]);
+            let input = TransactionInput::from_partial(input, signature);
+            inputs.push(input);
+        }
+
+        Transaction {
+            clear_inputs,
+            inputs,
+            outputs: partial_tx.outputs,
+        }
+    }
+}
+

+ 73 - 329
src/tx.rs → src/tx/mod.rs

@@ -1,3 +1,6 @@
+pub mod builder;
+pub mod partial;
+
 use bellman::groth16;
 use bls12_381::Bls12;
 use ff::Field;
@@ -18,212 +21,9 @@ use crate::error::{Error, Result};
 use crate::impl_vec;
 use crate::serial::{Decodable, Encodable, VarInt};
 use crate::state;
+use self::partial::{PartialTransactionClearInput, PartialTransactionInput};
 
-pub struct TransactionBuilder {
-    pub clear_inputs: Vec<TransactionBuilderClearInputInfo>,
-    pub inputs: Vec<TransactionBuilderInputInfo>,
-    pub outputs: Vec<TransactionBuilderOutputInfo>,
-}
-
-impl TransactionBuilder {
-    fn compute_remainder_blind(
-        clear_inputs: &Vec<PartialTransactionClearInput>,
-        input_blinds: &Vec<jubjub::Fr>,
-        output_blinds: &Vec<jubjub::Fr>,
-    ) -> jubjub::Fr {
-        let mut total = jubjub::Fr::zero();
-
-        for input in clear_inputs {
-            total += input.valcom_blind;
-        }
-
-        for input_blind in input_blinds {
-            total += input_blind;
-        }
-
-        for output_blind in output_blinds {
-            total -= output_blind;
-        }
-
-        total
-    }
-
-    pub fn build(
-        self,
-        mint_params: &groth16::Parameters<Bls12>,
-        spend_params: &groth16::Parameters<Bls12>,
-    ) -> Transaction {
-        let mut clear_inputs = vec![];
-        for input in &self.clear_inputs {
-            let signature_public =
-                zcash_primitives::constants::SPENDING_KEY_GENERATOR * input.signature_secret;
-
-            let valcom_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
-            let clear_input = PartialTransactionClearInput {
-                value: input.value,
-                valcom_blind,
-                signature_public,
-            };
-            clear_inputs.push(clear_input);
-        }
-
-        let mut inputs = vec![];
-        let mut input_blinds = vec![];
-        let mut signature_secrets = vec![];
-        for input in &self.inputs {
-            input_blinds.push(input.note.valcom_blind.clone());
-
-            let signature_secret: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
-
-            // make proof
-
-            let (proof, revealed) = create_spend_proof(
-                &spend_params,
-                input.note.value,
-                input.note.valcom_blind,
-                input.note.serial,
-                input.note.coin_blind,
-                input.secret,
-                input.merkle_path.clone(),
-                signature_secret.clone(),
-            );
-
-            // First we make the tx then sign after
-            let signature_secret = schnorr::SecretKey(signature_secret);
-            signature_secrets.push(signature_secret);
-
-            let input = PartialTransactionInput {
-                spend_proof: proof,
-                revealed,
-            };
-            inputs.push(input);
-        }
-
-        let mut outputs = vec![];
-        let mut output_blinds = vec![];
-        for (i, output) in self.outputs.iter().enumerate() {
-            let valcom_blind = if i == self.outputs.len() - 1 {
-                Self::compute_remainder_blind(&clear_inputs, &input_blinds, &output_blinds)
-            } else {
-                jubjub::Fr::random(&mut OsRng)
-            };
-            output_blinds.push(valcom_blind);
-
-            let serial: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
-            let coin_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
-
-            let (mint_proof, revealed) = create_mint_proof(
-                mint_params,
-                output.value,
-                valcom_blind.clone(),
-                serial.clone(),
-                coin_blind.clone(),
-                output.public.clone(),
-            );
-
-            // Encrypted note
-
-            let note = Note {
-                serial,
-                value: output.value,
-                coin_blind,
-                valcom_blind,
-            };
-
-            let encrypted_note = note.encrypt(&output.public).unwrap();
-
-            let output = TransactionOutput {
-                mint_proof,
-                revealed,
-                enc_note: encrypted_note,
-            };
-            outputs.push(output);
-        }
-
-        let partial_tx = PartialTransaction {
-            clear_inputs,
-            inputs,
-            outputs,
-        };
-
-        let mut unsigned_tx_data = vec![];
-        partial_tx
-            .encode(&mut unsigned_tx_data)
-            .expect("TODO handle this");
-
-        let mut clear_inputs = vec![];
-        for (input, info) in partial_tx.clear_inputs.into_iter().zip(self.clear_inputs) {
-            let secret = schnorr::SecretKey(info.signature_secret.clone());
-            let signature = secret.sign(&unsigned_tx_data[..]);
-            let input = TransactionClearInput::from_partial(input, signature);
-            clear_inputs.push(input);
-        }
-
-        let mut inputs = vec![];
-        for (input, signature_secret) in partial_tx
-            .inputs
-            .into_iter()
-            .zip(signature_secrets.into_iter())
-        {
-            let signature = signature_secret.sign(&unsigned_tx_data[..]);
-            let input = TransactionInput::from_partial(input, signature);
-            inputs.push(input);
-        }
-
-        Transaction {
-            clear_inputs,
-            inputs,
-            outputs: partial_tx.outputs,
-        }
-    }
-}
-
-pub struct TransactionBuilderClearOutputInfo {
-    pub value: u64,
-    pub instructions: String,
-}
-
-pub struct TransactionBuilderClearInputInfo {
-    pub value: u64,
-    pub signature_secret: jubjub::Fr,
-}
-
-pub struct TransactionBuilderInputInfo {
-    pub merkle_path: Vec<(bls12_381::Scalar, bool)>,
-    pub secret: jubjub::Fr,
-    pub note: Note,
-}
-
-pub struct TransactionBuilderOutputInfo {
-    pub value: u64,
-    pub public: jubjub::SubgroupPoint,
-}
-
-pub struct PartialTransaction {
-    pub clear_inputs: Vec<PartialTransactionClearInput>,
-    pub inputs: Vec<PartialTransactionInput>,
-    pub outputs: Vec<TransactionOutput>,
-}
-
-impl Encodable for PartialTransaction {
-    fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
-        let mut len = 0;
-        len += self.clear_inputs.encode(&mut s)?;
-        len += self.inputs.encode(&mut s)?;
-        len += self.outputs.encode(s)?;
-        Ok(len)
-    }
-}
-
-impl Decodable for PartialTransaction {
-    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
-        Ok(Self {
-            clear_inputs: Decodable::decode(&mut d)?,
-            inputs: Decodable::decode(&mut d)?,
-            outputs: Decodable::decode(d)?,
-        })
-    }
-}
+pub use self::builder::{TransactionBuilder, TransactionBuilderClearInputInfo, TransactionBuilderInputInfo, TransactionBuilderOutputInfo};
 
 pub struct Transaction {
     pub clear_inputs: Vec<TransactionClearInput>,
@@ -231,24 +31,23 @@ pub struct Transaction {
     pub outputs: Vec<TransactionOutput>,
 }
 
-impl Encodable for Transaction {
-    fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
-        let mut len = 0;
-        len += self.clear_inputs.encode(&mut s)?;
-        len += self.inputs.encode(&mut s)?;
-        len += self.outputs.encode(s)?;
-        Ok(len)
-    }
+pub struct TransactionClearInput {
+    pub value: u64,
+    pub valcom_blind: jubjub::Fr,
+    pub signature_public: jubjub::SubgroupPoint,
+    pub signature: schnorr::Signature,
 }
 
-impl Decodable for Transaction {
-    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
-        Ok(Self {
-            clear_inputs: Decodable::decode(&mut d)?,
-            inputs: Decodable::decode(&mut d)?,
-            outputs: Decodable::decode(d)?,
-        })
-    }
+pub struct TransactionInput {
+    pub spend_proof: groth16::Proof<Bls12>,
+    pub revealed: SpendRevealedValues,
+    pub signature: schnorr::Signature,
+}
+
+pub struct TransactionOutput {
+    pub mint_proof: groth16::Proof<Bls12>,
+    pub revealed: MintRevealedValues,
+    pub enc_note: EncryptedNote,
 }
 
 impl Transaction {
@@ -314,13 +113,6 @@ impl Transaction {
     }
 }
 
-pub struct TransactionClearInput {
-    pub value: u64,
-    pub valcom_blind: jubjub::Fr,
-    pub signature_public: jubjub::SubgroupPoint,
-    pub signature: schnorr::Signature,
-}
-
 impl TransactionClearInput {
     fn from_partial(partial: PartialTransactionClearInput, signature: schnorr::Signature) -> Self {
         Self {
@@ -340,130 +132,65 @@ impl TransactionClearInput {
     }
 }
 
-macro_rules! impl_vec_without_signature {
-    ($type: ty) => {
-        impl EncodableWithoutSignature for Vec<$type> {
-            #[inline]
-            fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
-                let mut len = 0;
-                len += VarInt(self.len() as u64).encode(&mut s)?;
-                for c in self.iter() {
-                    len += c.encode_without_signature(&mut s)?;
-                }
-                Ok(len)
-            }
+impl TransactionInput {
+    fn from_partial(partial: PartialTransactionInput, signature: schnorr::Signature) -> Self {
+        Self {
+            spend_proof: partial.spend_proof,
+            revealed: partial.revealed,
+            signature,
         }
-    };
-}
-
-impl_vec_without_signature!(TransactionClearInput);
+    }
 
-impl_vec!(TransactionClearInput);
+    fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
+        let mut len = 0;
+        len += self.spend_proof.encode(&mut s)?;
+        len += self.revealed.encode(&mut s)?;
+        Ok(len)
+    }
+}
 
-impl Encodable for TransactionClearInput {
+impl Encodable for Transaction {
     fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
         let mut len = 0;
-        len += self.value.encode(&mut s)?;
-        len += self.valcom_blind.encode(&mut s)?;
-        len += self.signature_public.encode(&mut s)?;
-        len += self.signature.encode(s)?;
+        len += self.clear_inputs.encode(&mut s)?;
+        len += self.inputs.encode(&mut s)?;
+        len += self.outputs.encode(s)?;
         Ok(len)
     }
 }
 
-impl Decodable for TransactionClearInput {
+impl Decodable for Transaction {
     fn decode<D: io::Read>(mut d: D) -> Result<Self> {
         Ok(Self {
-            value: Decodable::decode(&mut d)?,
-            valcom_blind: Decodable::decode(&mut d)?,
-            signature_public: Decodable::decode(&mut d)?,
-            signature: Decodable::decode(d)?,
+            clear_inputs: Decodable::decode(&mut d)?,
+            inputs: Decodable::decode(&mut d)?,
+            outputs: Decodable::decode(d)?,
         })
     }
 }
 
-pub struct PartialTransactionClearInput {
-    pub value: u64,
-    pub valcom_blind: jubjub::Fr,
-    pub signature_public: jubjub::SubgroupPoint,
-}
-
-impl_vec!(PartialTransactionClearInput);
-
-impl Encodable for PartialTransactionClearInput {
+impl Encodable for TransactionClearInput {
     fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
         let mut len = 0;
         len += self.value.encode(&mut s)?;
         len += self.valcom_blind.encode(&mut s)?;
         len += self.signature_public.encode(&mut s)?;
+        len += self.signature.encode(s)?;
         Ok(len)
     }
 }
 
-impl Decodable for PartialTransactionClearInput {
+impl Decodable for TransactionClearInput {
     fn decode<D: io::Read>(mut d: D) -> Result<Self> {
         Ok(Self {
             value: Decodable::decode(&mut d)?,
             valcom_blind: Decodable::decode(&mut d)?,
             signature_public: Decodable::decode(&mut d)?,
+            signature: Decodable::decode(d)?,
         })
     }
 }
 
-pub struct PartialTransactionInput {
-    pub spend_proof: groth16::Proof<Bls12>,
-    pub revealed: SpendRevealedValues,
-}
-
-impl Encodable for PartialTransactionInput {
-    fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
-        let mut len = 0;
-        len += self.spend_proof.encode(&mut s)?;
-        len += self.revealed.encode(s)?;
-        Ok(len)
-    }
-}
-
-impl Decodable for PartialTransactionInput {
-    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
-        Ok(Self {
-            spend_proof: Decodable::decode(&mut d)?,
-            revealed: Decodable::decode(d)?,
-        })
-    }
-}
-
-impl_vec!(PartialTransactionInput);
-
-pub struct TransactionInput {
-    pub spend_proof: groth16::Proof<Bls12>,
-    pub revealed: SpendRevealedValues,
-    pub signature: schnorr::Signature,
-}
-
-impl TransactionInput {
-    fn from_partial(partial: PartialTransactionInput, signature: schnorr::Signature) -> Self {
-        Self {
-            spend_proof: partial.spend_proof,
-            revealed: partial.revealed,
-            signature,
-        }
-    }
-
-    fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
-        let mut len = 0;
-        len += self.spend_proof.encode(&mut s)?;
-        len += self.revealed.encode(&mut s)?;
-        Ok(len)
-    }
-}
-
-trait EncodableWithoutSignature {
-    fn encode_without_signature<S: io::Write>(&self, s: S) -> Result<usize>;
-}
-
-impl_vec_without_signature!(TransactionInput);
-
 impl Encodable for TransactionInput {
     fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
         let mut len = 0;
@@ -484,16 +211,6 @@ impl Decodable for TransactionInput {
     }
 }
 
-impl_vec!(TransactionInput);
-
-pub struct TransactionOutput {
-    pub mint_proof: groth16::Proof<Bls12>,
-    pub revealed: MintRevealedValues,
-    pub enc_note: EncryptedNote,
-}
-
-impl_vec!(TransactionOutput);
-
 impl Encodable for TransactionOutput {
     fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
         let mut len = 0;
@@ -513,3 +230,30 @@ impl Decodable for TransactionOutput {
         })
     }
 }
+
+trait EncodableWithoutSignature {
+    fn encode_without_signature<S: io::Write>(&self, s: S) -> Result<usize>;
+}
+
+macro_rules! impl_vec_without_signature {
+    ($type: ty) => {
+        impl EncodableWithoutSignature for Vec<$type> {
+            #[inline]
+            fn encode_without_signature<S: io::Write>(&self, mut s: S) -> Result<usize> {
+                let mut len = 0;
+                len += VarInt(self.len() as u64).encode(&mut s)?;
+                for c in self.iter() {
+                    len += c.encode_without_signature(&mut s)?;
+                }
+                Ok(len)
+            }
+        }
+    };
+}
+
+impl_vec_without_signature!(TransactionClearInput);
+impl_vec_without_signature!(TransactionInput);
+impl_vec!(TransactionClearInput);
+impl_vec!(TransactionInput);
+impl_vec!(TransactionOutput);
+

+ 99 - 0
src/tx/partial.rs

@@ -0,0 +1,99 @@
+use bellman::groth16;
+use bls12_381::Bls12;
+use rand::rngs::OsRng;
+use std::collections::HashMap;
+use std::io;
+use ff::Field;
+
+use crate::error::{Error, Result};
+use crate::impl_vec;
+use crate::serial::{Decodable, Encodable, VarInt};
+use super::{TransactionClearInput, TransactionInput, TransactionOutput, Transaction};
+use crate::crypto::{
+    coin::Coin,
+    create_mint_proof, create_spend_proof, load_params,
+    merkle::CommitmentTree,
+    note::{EncryptedNote, Note},
+    save_params, schnorr, setup_mint_prover, setup_spend_prover, verify_mint_proof,
+    verify_spend_proof, MintRevealedValues, SpendRevealedValues,
+};
+
+pub struct PartialTransaction {
+    pub clear_inputs: Vec<PartialTransactionClearInput>,
+    pub inputs: Vec<PartialTransactionInput>,
+    pub outputs: Vec<TransactionOutput>,
+}
+
+pub struct PartialTransactionClearInput {
+    pub value: u64,
+    pub valcom_blind: jubjub::Fr,
+    pub signature_public: jubjub::SubgroupPoint,
+}
+
+pub struct PartialTransactionInput {
+    pub spend_proof: groth16::Proof<Bls12>,
+    pub revealed: SpendRevealedValues,
+}
+
+impl Encodable for PartialTransaction {
+    fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
+        let mut len = 0;
+        len += self.clear_inputs.encode(&mut s)?;
+        len += self.inputs.encode(&mut s)?;
+        len += self.outputs.encode(s)?;
+        Ok(len)
+    }
+}
+
+impl Decodable for PartialTransaction {
+    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
+        Ok(Self {
+            clear_inputs: Decodable::decode(&mut d)?,
+            inputs: Decodable::decode(&mut d)?,
+            outputs: Decodable::decode(d)?,
+        })
+    }
+}
+
+impl Encodable for PartialTransactionClearInput {
+    fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
+        let mut len = 0;
+        len += self.value.encode(&mut s)?;
+        len += self.valcom_blind.encode(&mut s)?;
+        len += self.signature_public.encode(&mut s)?;
+        Ok(len)
+    }
+}
+
+impl Decodable for PartialTransactionClearInput {
+    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
+        Ok(Self {
+            value: Decodable::decode(&mut d)?,
+            valcom_blind: Decodable::decode(&mut d)?,
+            signature_public: Decodable::decode(&mut d)?,
+        })
+    }
+}
+
+
+impl Encodable for PartialTransactionInput {
+    fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
+        let mut len = 0;
+        len += self.spend_proof.encode(&mut s)?;
+        len += self.revealed.encode(s)?;
+        Ok(len)
+    }
+}
+
+impl Decodable for PartialTransactionInput {
+    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
+        Ok(Self {
+            spend_proof: Decodable::decode(&mut d)?,
+            revealed: Decodable::decode(d)?,
+        })
+    }
+}
+
+impl_vec!(PartialTransactionClearInput);
+impl_vec!(PartialTransactionInput);
+