فهرست منبع

move tx builder code to src/tx.rs

narodnik 5 سال پیش
والد
کامیت
2781c1a4ae
5فایلهای تغییر یافته به همراه255 افزوده شده و 127 حذف شده
  1. 20 125
      src/bin/tx.rs
  2. 22 1
      src/crypto/fr_serial.rs
  3. 21 1
      src/crypto/mint_proof.rs
  4. 1 0
      src/lib.rs
  5. 191 0
      src/tx.rs

+ 20 - 125
src/bin/tx.rs

@@ -1,3 +1,4 @@
+use std::io;
 use bellman::groth16;
 use bls12_381::Bls12;
 use ff::Field;
@@ -9,123 +10,9 @@ use sapvi::crypto::{
     MintRevealedValues,
     note::Note
 };
-
-struct TransactionBuilder {
-    clear_inputs: Vec<TransactionBuilderClearInputInfo>,
-    outputs: Vec<TransactionBuilderOutputInfo>,
-}
-
-impl TransactionBuilder {
-    fn compute_remainder_blind(
-        clear_inputs: &Vec<TransactionClearInput>,
-        output_blinds: &Vec<jubjub::Fr>,
-    ) -> jubjub::Fr {
-        let mut lhs_total = jubjub::Fr::zero();
-        for input in clear_inputs {
-            lhs_total += input.valcom_blind;
-        }
-
-        let mut rhs_total = jubjub::Fr::zero();
-        for output_blind in output_blinds {
-            rhs_total += output_blind;
-        }
-
-        lhs_total - rhs_total
-    }
-
-    fn build(self, mint_params: &groth16::Parameters<Bls12>) -> Transaction {
-        let mut clear_inputs = vec![];
-        for input in &self.clear_inputs {
-            let valcom_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
-            let clear_input = TransactionClearInput {
-                value: input.value,
-                valcom_blind,
-            };
-            clear_inputs.push(clear_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, &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,
-                serial,
-                coin_blind,
-                output.public,
-            );
-            let output = TransactionOutput {
-                mint_proof,
-                revealed,
-            };
-            outputs.push(output);
-        }
-
-        Transaction {
-            clear_inputs,
-            outputs,
-        }
-    }
-}
-
-struct TransactionBuilderClearInputInfo {
-    value: u64,
-}
-
-struct TransactionBuilderOutputInfo {
-    value: u64,
-    public: jubjub::SubgroupPoint,
-}
-
-struct Transaction {
-    clear_inputs: Vec<TransactionClearInput>,
-    outputs: Vec<TransactionOutput>,
-}
-
-impl Transaction {
-    fn compute_value_commit(value: u64, blind: &jubjub::Fr) -> jubjub::SubgroupPoint {
-        let value_commit = (zcash_primitives::constants::VALUE_COMMITMENT_VALUE_GENERATOR
-            * jubjub::Fr::from(value))
-            + (zcash_primitives::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR * blind);
-        value_commit
-    }
-
-    fn verify(&self, pvk: &groth16::PreparedVerifyingKey<Bls12>) -> bool {
-        let mut valcom_total = jubjub::SubgroupPoint::identity();
-        for input in &self.clear_inputs {
-            valcom_total += Self::compute_value_commit(input.value, &input.valcom_blind);
-        }
-        for output in &self.outputs {
-            if !verify_mint_proof(pvk, &output.mint_proof, &output.revealed) {
-                return false;
-            }
-            valcom_total -= &output.revealed.value_commit;
-        }
-
-        valcom_total == jubjub::SubgroupPoint::identity()
-    }
-}
-
-struct TransactionClearInput {
-    value: u64,
-    valcom_blind: jubjub::Fr,
-}
-
-struct TransactionOutput {
-    mint_proof: groth16::Proof<Bls12>,
-    revealed: MintRevealedValues,
-}
+use sapvi::serial::{Decodable, Encodable, VarInt};
+use sapvi::error::{Error, Result};
+use sapvi::tx;
 
 fn txbuilding() {
     {
@@ -136,18 +23,25 @@ fn txbuilding() {
 
     let public = jubjub::SubgroupPoint::random(&mut OsRng);
 
-    let builder = TransactionBuilder {
-        clear_inputs: vec![TransactionBuilderClearInputInfo { value: 110 }],
-        outputs: vec![TransactionBuilderOutputInfo { value: 110, public }],
+    let builder = tx::TransactionBuilder {
+        clear_inputs: vec![tx::TransactionBuilderClearInputInfo { value: 110 }],
+        outputs: vec![tx::TransactionBuilderOutputInfo { value: 110, public }],
     };
 
-    let tx = builder.build(&mint_params);
-    assert!(tx.verify(&mint_pvk));
+    let mut tx_data = vec![];
+    {
+        let tx = builder.build(&mint_params);
+        tx.encode(&mut tx_data).expect("encode tx");
+    }
+    {
+        let tx = tx::Transaction::decode(&tx_data[..]).unwrap();
+        assert!(tx.verify(&mint_pvk));
+    }
 }
 
 fn main() {
-    // txbuilding()
-    let note = Note {
+    txbuilding();
+    /*let note = Note {
         serial: jubjub::Fr::random(&mut OsRng),
         value: 110,
         coin_blind: jubjub::Fr::random(&mut OsRng),
@@ -159,5 +53,6 @@ fn main() {
 
     let encrypted_note = note.encrypt(&public).unwrap();
     let note2 = encrypted_note.decrypt(&secret).unwrap();
-    assert_eq!(note.value, note2.value);
+    assert_eq!(note.value, note2.value);*/
 }
+

+ 22 - 1
src/crypto/fr_serial.rs

@@ -1,6 +1,7 @@
 use std::io;
-use crate::serial::{Encodable, Decodable, ReadExt, WriteExt};
+use group::GroupEncoding;
 
+use crate::serial::{Encodable, Decodable, ReadExt, WriteExt};
 use crate::error::{Error, Result};
 
 impl Encodable for jubjub::Fr {
@@ -23,3 +24,23 @@ impl Decodable for jubjub::Fr {
     }
 }
 
+impl Encodable for jubjub::SubgroupPoint {
+    fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
+        s.write_slice(&self.to_bytes()[..])?;
+        Ok(32)
+    }
+}
+
+impl Decodable for jubjub::SubgroupPoint {
+    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
+        let mut bytes = [0u8; 32];
+        d.read_slice(&mut bytes)?;
+        let result = Self::from_bytes(&bytes);
+        if result.is_some().into() {
+            Ok(result.unwrap())
+        } else {
+            Err(Error::BadOperationType)
+        }
+    }
+}
+

+ 21 - 1
src/crypto/mint_proof.rs

@@ -3,12 +3,14 @@ use bellman::groth16;
 use blake2s_simd::Params as Blake2sParams;
 use bls12_381::Bls12;
 use ff::Field;
+use std::io;
 use group::{Curve, Group, GroupEncoding};
 use rand::rngs::OsRng;
 use std::time::Instant;
 
 use crate::circuit::mint_contract::MintContract;
-use crate::error::Result;
+use crate::error::{Error, Result};
+use crate::serial::{Decodable, Encodable};
 
 pub struct MintRevealedValues {
     pub value_commit: jubjub::SubgroupPoint,
@@ -74,6 +76,24 @@ impl MintRevealedValues {
     }
 }
 
+impl Encodable for MintRevealedValues {
+    fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
+        let mut len = 0;
+        len += self.value_commit.encode(&mut s)?;
+        len += self.coin.encode(&mut s)?;
+        Ok(len)
+    }
+}
+
+impl Decodable for MintRevealedValues {
+    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
+        Ok(Self {
+            value_commit: Decodable::decode(&mut d)?,
+            coin: Decodable::decode(d)?
+        })
+    }
+}
+
 pub fn setup_mint_prover() -> groth16::Parameters<Bls12> {
     println!("Making random params...");
     let start = Instant::now();

+ 1 - 0
src/lib.rs

@@ -13,6 +13,7 @@ pub mod gui;
 pub mod net;
 pub mod serial;
 pub mod system;
+pub mod tx;
 pub mod vm;
 pub mod vm_serial;
 

+ 191 - 0
src/tx.rs

@@ -0,0 +1,191 @@
+use std::io;
+use bellman::groth16;
+use bls12_381::Bls12;
+use ff::Field;
+use group::Group;
+use rand::rngs::OsRng;
+
+use crate::crypto::{
+    create_mint_proof, load_params, save_params, setup_mint_prover, verify_mint_proof,
+    MintRevealedValues,
+    note::Note
+};
+use crate::serial::{Decodable, Encodable, VarInt};
+use crate::error::{Error, Result};
+use crate::impl_vec;
+
+pub struct TransactionBuilder {
+    pub clear_inputs: Vec<TransactionBuilderClearInputInfo>,
+    pub outputs: Vec<TransactionBuilderOutputInfo>,
+}
+
+impl TransactionBuilder {
+    fn compute_remainder_blind(
+        clear_inputs: &Vec<TransactionClearInput>,
+        output_blinds: &Vec<jubjub::Fr>,
+    ) -> jubjub::Fr {
+        let mut lhs_total = jubjub::Fr::zero();
+        for input in clear_inputs {
+            lhs_total += input.valcom_blind;
+        }
+
+        let mut rhs_total = jubjub::Fr::zero();
+        for output_blind in output_blinds {
+            rhs_total += output_blind;
+        }
+
+        lhs_total - rhs_total
+    }
+
+    pub fn build(self, mint_params: &groth16::Parameters<Bls12>) -> Transaction {
+        let mut clear_inputs = vec![];
+        for input in &self.clear_inputs {
+            let valcom_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
+            let clear_input = TransactionClearInput {
+                value: input.value,
+                valcom_blind,
+            };
+            clear_inputs.push(clear_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, &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,
+                serial,
+                coin_blind,
+                output.public,
+            );
+            let output = TransactionOutput {
+                mint_proof,
+                revealed,
+            };
+            outputs.push(output);
+        }
+
+        Transaction {
+            clear_inputs,
+            outputs,
+        }
+    }
+}
+
+pub struct TransactionBuilderClearInputInfo {
+    pub value: u64,
+}
+
+pub struct TransactionBuilderOutputInfo {
+    pub value: u64,
+    pub public: jubjub::SubgroupPoint,
+}
+
+pub struct Transaction {
+    pub clear_inputs: Vec<TransactionClearInput>,
+    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.outputs.encode(&mut s)?;
+        Ok(len)
+    }
+}
+
+impl Decodable for Transaction {
+    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
+        Ok(Self {
+            clear_inputs: Decodable::decode(&mut d)?,
+            outputs: Decodable::decode(d)?
+        })
+    }
+}
+
+impl Transaction {
+    fn compute_value_commit(value: u64, blind: &jubjub::Fr) -> jubjub::SubgroupPoint {
+        let value_commit = (zcash_primitives::constants::VALUE_COMMITMENT_VALUE_GENERATOR
+            * jubjub::Fr::from(value))
+            + (zcash_primitives::constants::VALUE_COMMITMENT_RANDOMNESS_GENERATOR * blind);
+        value_commit
+    }
+
+    pub fn verify(&self, pvk: &groth16::PreparedVerifyingKey<Bls12>) -> bool {
+        let mut valcom_total = jubjub::SubgroupPoint::identity();
+        for input in &self.clear_inputs {
+            valcom_total += Self::compute_value_commit(input.value, &input.valcom_blind);
+        }
+        for output in &self.outputs {
+            if !verify_mint_proof(pvk, &output.mint_proof, &output.revealed) {
+                return false;
+            }
+            valcom_total -= &output.revealed.value_commit;
+        }
+
+        valcom_total == jubjub::SubgroupPoint::identity()
+    }
+}
+
+pub struct TransactionClearInput {
+    pub value: u64,
+    pub valcom_blind: jubjub::Fr,
+}
+
+impl_vec!(TransactionClearInput);
+
+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)?;
+        Ok(len)
+    }
+}
+
+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(d)?
+        })
+    }
+}
+
+pub struct TransactionOutput {
+    pub mint_proof: groth16::Proof<Bls12>,
+    pub revealed: MintRevealedValues,
+}
+
+impl_vec!(TransactionOutput);
+
+impl Encodable for TransactionOutput {
+    fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
+        let mut len = 0;
+        len += self.mint_proof.encode(&mut s)?;
+        len += self.revealed.encode(&mut s)?;
+        Ok(len)
+    }
+}
+
+impl Decodable for TransactionOutput {
+    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
+        Ok(Self {
+            mint_proof: Decodable::decode(&mut d)?,
+            revealed: Decodable::decode(d)?
+        })
+    }
+}
+