Ver Fonte

working tx builder + verification!

narodnik há 5 anos atrás
pai
commit
059389cf90

+ 2 - 2
lisp/core.rs

@@ -628,8 +628,8 @@ fn scalar_is_zero(a: MalArgs) -> MalRet {
     }
 }
 
-fn add_scalar(a: MalArgs) -> MalRet {  
-    println!("add_scalar {:?}", a);  
+fn add_scalar(a: MalArgs) -> MalRet {
+    println!("add_scalar {:?}", a);
     match (a[0].clone(), a[1].clone()) {
         (Func(_, _), ZKScalar(a1)) => {
             if let Vector(ref values, _) = a[0].apply(vec![]).unwrap() {

+ 8 - 10
lisp/lisp.rs

@@ -11,11 +11,9 @@ use bls12_381::Bls12;
 // use fnv::FnvHashMap;
 use itertools::Itertools;
 use rand::rngs::OsRng;
+use std::borrow::{Borrow, BorrowMut};
 use std::rc::Rc;
 use std::time::Instant;
-use std::{
-    borrow::{Borrow, BorrowMut},    
-};
 use std::{cell::RefCell, collections::HashMap};
 use types::EnforceAllocation;
 
@@ -353,7 +351,7 @@ fn eval(mut ast: MalVal, mut env: Env) -> MalRet {
                     }
                     Sym(ref a0sym) if a0sym == "kill" => {
                         error(&format!("KILL at: {:?}", ast).to_string())
-                    }                
+                    }
                     Sym(ref a0sym) if a0sym == "alloc-const" => {
                         let start = Instant::now();
                         let a1 = l[1].clone();
@@ -652,7 +650,7 @@ pub fn setup(_ast: MalVal, env: Env) -> Result<VerifyKeyParams, MalErr> {
     })
 }
 
-pub fn prove(_ast: MalVal, env: Env) -> MalRet {    
+pub fn prove(_ast: MalVal, env: Env) -> MalRet {
     let start = Instant::now();
     let allocs_input = get_allocations(&env, "AllocationsInput");
     let allocs = get_allocations(&env, "Allocations");
@@ -691,12 +689,12 @@ pub fn prove(_ast: MalVal, env: Env) -> MalRet {
         };
     }
     println!("groth16::create_random_proof: {:?}", start.elapsed());
-    // verification process 
+    // verification process
     let start = Instant::now();
     let result = groth16::verify_proof(verifying_key.as_ref().unwrap(), &proof, &vec_input);
     println!("groth16::verify_proof: {:?}", start.elapsed());
     println!("vec public {:?}", vec_input);
-    println!("result {:?}", result);    
+    println!("result {:?}", result);
     Ok(MalVal::Nil)
 }
 
@@ -766,13 +764,13 @@ fn repl_load(file: String) -> Result<(), ()> {
     match rep(&format!("(load-file \"{}\")", file), &repl_env) {
         Ok(_) => {
             println!("lisp end \t {:?}", start.elapsed());
-            std::process::exit(0) 
-        },
+            std::process::exit(0)
+        }
         Err(e) => {
             println!("Error: {}", format_error(e));
             std::process::exit(1);
         }
-    }    
+    }
 }
 
 #[cfg(test)]

+ 10 - 7
lisp/types.rs

@@ -1,8 +1,11 @@
 use bellman::{gadgets::Assignment, groth16, Circuit, ConstraintSystem, SynthesisError};
 use sapvi::bls_extensions::BlsStringConversion;
-use std::{ops::{Add, AddAssign, MulAssign, SubAssign}, time::Instant};
 use std::rc::Rc;
 use std::{cell::RefCell, collections::HashMap};
+use std::{
+    ops::{Add, AddAssign, MulAssign, SubAssign},
+    time::Instant,
+};
 // use fnv::FnvHashMap;
 use itertools::Itertools;
 
@@ -77,7 +80,7 @@ impl Circuit<bls12_381::Scalar> for LispCircuit {
         let circuitTime = Instant::now();
         let start = Instant::now();
         // println!("Allocations\n");
-        // TODO is the private and params 
+        // TODO is the private and params
         for (k, v) in &self.allocs {
             match v {
                 MalVal::ZKScalar(val) => {
@@ -101,7 +104,7 @@ impl Circuit<bls12_381::Scalar> for LispCircuit {
             }
         }
         println!("circuit alloc \t {:?}", start.elapsed());
-        let start = Instant::now();        
+        let start = Instant::now();
         // println!("Allocations Input\n");
         // TODO alloc-input is the public value
         for (k, v) in &self.alloc_inputs {
@@ -122,7 +125,7 @@ impl Circuit<bls12_381::Scalar> for LispCircuit {
                 }
             }
         }
-        println!("circuit alloc input \t {:?}", start.elapsed());        
+        println!("circuit alloc input \t {:?}", start.elapsed());
         let start = Instant::now();
         let mut enforce_sorted = self.constraints.clone();
         // enforce_sorted.sort_by(|a, b| a.idx.cmp(&b.idx));
@@ -249,9 +252,9 @@ impl Circuit<bls12_381::Scalar> for LispCircuit {
                 |_| right.clone(),
                 |_| output.clone(),
             );
-        }     
-        println!("circuit enforce \t {:?}", start.elapsed());        
-        println!("end circuit \t {:?}", circuitTime.elapsed());        
+        }
+        println!("circuit enforce \t {:?}", start.elapsed());
+        println!("end circuit \t {:?}", circuitTime.elapsed());
         Ok(())
     }
 }

+ 11 - 3
src/bin/mint-classic.rs

@@ -5,7 +5,9 @@ use bls12_381::Bls12;
 use ff::Field;
 use group::{Curve, Group, GroupEncoding};
 
-use sapvi::crypto::{save_params, load_params, setup_mint_prover, create_mint_proof, verify_mint_proof};
+use sapvi::crypto::{
+    create_mint_proof, load_params, save_params, setup_mint_prover, verify_mint_proof,
+};
 
 fn main() {
     use rand::rngs::OsRng;
@@ -25,8 +27,14 @@ fn main() {
     }
     let (params, pvk) = load_params("mint.params").expect("params should load");
 
-    let (proof, revealed) = create_mint_proof(&params, value, randomness_value, serial, randomness_coin,
-                                              public);
+    let (proof, revealed) = create_mint_proof(
+        &params,
+        value,
+        randomness_value,
+        serial,
+        randomness_coin,
+        public,
+    );
 
     assert!(verify_mint_proof(&pvk, &proof, &revealed));
 }

+ 12 - 3
src/bin/spend-classic.rs

@@ -7,7 +7,9 @@ use ff::{Field, PrimeField};
 use group::{Curve, GroupEncoding};
 
 use sapvi::circuit::spend_contract::SpendContract;
-use sapvi::crypto::{save_params, load_params, setup_spend_prover, create_spend_proof, verify_spend_proof};
+use sapvi::crypto::{
+    create_spend_proof, load_params, save_params, setup_spend_prover, verify_spend_proof,
+};
 
 // This thing is nasty lol
 pub fn merkle_hash(
@@ -190,8 +192,15 @@ fn main() {
     }
     let (params, pvk) = load_params("spend.params").expect("params should load");
 
-    let (proof, revealed) = create_spend_proof(&params, value, randomness_value, serial, randomness_coin,
-                                              secret, merkle_path);
+    let (proof, revealed) = create_spend_proof(
+        &params,
+        value,
+        randomness_value,
+        serial,
+        randomness_coin,
+        secret,
+        merkle_path,
+    );
 
     assert!(verify_spend_proof(&pvk, &proof, &revealed));
 }

+ 42 - 21
src/bin/tx.rs

@@ -1,17 +1,24 @@
-use rand::rngs::OsRng;
-use ff::Field;
 use bellman::groth16;
 use bls12_381::Bls12;
+use ff::Field;
+use group::Group;
+use rand::rngs::OsRng;
 
-use sapvi::crypto::{save_params, load_params, setup_mint_prover, create_mint_proof, verify_mint_proof, MintRevealedValues};
+use sapvi::crypto::{
+    create_mint_proof, load_params, save_params, setup_mint_prover, verify_mint_proof,
+    MintRevealedValues,
+};
 
 struct TransactionBuilder {
     clear_inputs: Vec<TransactionBuilderClearInputInfo>,
-    outputs: Vec<TransactionBuilderOutputInfo>
+    outputs: Vec<TransactionBuilderOutputInfo>,
 }
 
 impl TransactionBuilder {
-    fn compute_remainder_blind(clear_inputs: &Vec<TransactionClearInput>, output_blinds: &Vec<jubjub::Fr>) -> jubjub::Fr {
+    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;
@@ -22,7 +29,7 @@ impl TransactionBuilder {
             rhs_total += output_blind;
         }
 
-        rhs_total - lhs_total
+        lhs_total - rhs_total
     }
 
     fn build(self, mint_params: &groth16::Parameters<Bls12>) -> Transaction {
@@ -31,7 +38,7 @@ impl TransactionBuilder {
             let valcom_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
             let clear_input = TransactionClearInput {
                 value: input.value,
-                valcom_blind
+                valcom_blind,
             };
             clear_inputs.push(clear_input);
         }
@@ -49,17 +56,24 @@ impl TransactionBuilder {
             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 (mint_proof, revealed) = create_mint_proof(
+                mint_params,
+                output.value,
+                valcom_blind,
+                serial,
+                coin_blind,
+                output.public,
+            );
             let output = TransactionOutput {
                 mint_proof,
-                revealed
+                revealed,
             };
             outputs.push(output);
         }
 
         Transaction {
             clear_inputs,
-            outputs
+            outputs,
         }
     }
 }
@@ -73,32 +87,38 @@ struct TransactionBuilderOutputInfo {
     public: jubjub::SubgroupPoint,
 }
 
-impl TransactionBuilderOutputInfo {
-    fn build() {
-    }
-}
-
 struct Transaction {
     clear_inputs: Vec<TransactionClearInput>,
-    outputs: Vec<TransactionOutput>
+    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;
         }
-        true
+
+        valcom_total == jubjub::SubgroupPoint::identity()
     }
 }
 
 struct TransactionClearInput {
     value: u64,
-    valcom_blind: jubjub::Fr
+    valcom_blind: jubjub::Fr,
 }
 
 struct TransactionOutput {
@@ -113,12 +133,13 @@ fn main() {
     }
     let (mint_params, mint_pvk) = load_params("mint.params").expect("params should load");
 
+    let public = jubjub::SubgroupPoint::random(&mut OsRng);
+
     let builder = TransactionBuilder {
-        clear_inputs: vec![],
-        outputs: vec![]
+        clear_inputs: vec![TransactionBuilderClearInputInfo { value: 110 }],
+        outputs: vec![TransactionBuilderOutputInfo { value: 110, public }],
     };
 
     let tx = builder.build(&mint_params);
     assert!(tx.verify(&mint_pvk));
 }
-

+ 0 - 1
src/circuit/mod.rs

@@ -1,3 +1,2 @@
 pub mod mint_contract;
 pub mod spend_contract;
-

+ 7 - 8
src/crypto/mint_proof.rs

@@ -1,14 +1,14 @@
-use rand::rngs::OsRng;
-use std::time::Instant;
 use bellman::gadgets::multipack;
 use bellman::groth16;
 use blake2s_simd::Params as Blake2sParams;
 use bls12_381::Bls12;
 use ff::Field;
 use group::{Curve, Group, GroupEncoding};
+use rand::rngs::OsRng;
+use std::time::Instant;
 
-use crate::error::Result;
 use crate::circuit::mint_contract::MintContract;
+use crate::error::Result;
 
 pub struct MintRevealedValues {
     pub value_commit: jubjub::SubgroupPoint,
@@ -97,8 +97,8 @@ pub fn create_mint_proof(
     randomness_value: jubjub::Fr,
     serial: jubjub::Fr,
     randomness_coin: jubjub::Fr,
-    public: jubjub::SubgroupPoint
-    ) -> (groth16::Proof<Bls12>, MintRevealedValues) {
+    public: jubjub::SubgroupPoint,
+) -> (groth16::Proof<Bls12>, MintRevealedValues) {
     let revealed =
         MintRevealedValues::compute(value, &randomness_value, &serial, &randomness_coin, &public);
 
@@ -120,8 +120,8 @@ pub fn create_mint_proof(
 pub fn verify_mint_proof(
     pvk: &groth16::PreparedVerifyingKey<Bls12>,
     proof: &groth16::Proof<Bls12>,
-    revealed: &MintRevealedValues
-    ) -> bool {
+    revealed: &MintRevealedValues,
+) -> bool {
     let public_input = revealed.make_outputs();
 
     let start = Instant::now();
@@ -129,4 +129,3 @@ pub fn verify_mint_proof(
     println!("Verify: [{:?}]", start.elapsed());
     result
 }
-

+ 10 - 4
src/crypto/mod.rs

@@ -5,8 +5,10 @@ use bellman::groth16;
 use bls12_381::Bls12;
 
 use crate::error::Result;
-pub use mint_proof::{setup_mint_prover, create_mint_proof, verify_mint_proof, MintRevealedValues};
-pub use spend_proof::{setup_spend_prover, create_spend_proof, verify_spend_proof, SpendRevealedValues};
+pub use mint_proof::{create_mint_proof, setup_mint_prover, verify_mint_proof, MintRevealedValues};
+pub use spend_proof::{
+    create_spend_proof, setup_spend_prover, verify_spend_proof, SpendRevealedValues,
+};
 
 pub fn save_params(filename: &str, params: &groth16::Parameters<Bls12>) -> Result<()> {
     let buffer = std::fs::File::create(filename)?;
@@ -14,10 +16,14 @@ pub fn save_params(filename: &str, params: &groth16::Parameters<Bls12>) -> Resul
     Ok(())
 }
 
-pub fn load_params(filename: &str) -> Result<(groth16::Parameters<Bls12>, groth16::PreparedVerifyingKey<Bls12>)> {
+pub fn load_params(
+    filename: &str,
+) -> Result<(
+    groth16::Parameters<Bls12>,
+    groth16::PreparedVerifyingKey<Bls12>,
+)> {
     let buffer = std::fs::File::open(filename)?;
     let params = groth16::Parameters::<Bls12>::read(buffer, false)?;
     let pvk = groth16::prepare_verifying_key(&params.vk);
     Ok((params, pvk))
 }
-

+ 7 - 8
src/crypto/spend_proof.rs

@@ -1,5 +1,3 @@
-use rand::rngs::OsRng;
-use std::time::Instant;
 use bellman::gadgets::multipack;
 use bellman::groth16;
 use bitvec::{order::Lsb0, view::AsBits};
@@ -7,9 +5,11 @@ use blake2s_simd::Params as Blake2sParams;
 use bls12_381::Bls12;
 use ff::{Field, PrimeField};
 use group::{Curve, GroupEncoding};
+use rand::rngs::OsRng;
+use std::time::Instant;
 
-use crate::error::Result;
 use crate::circuit::spend_contract::SpendContract;
+use crate::error::Result;
 
 // This thing is nasty lol
 pub fn merkle_hash(
@@ -201,8 +201,8 @@ pub fn create_spend_proof(
     serial: jubjub::Fr,
     randomness_coin: jubjub::Fr,
     secret: jubjub::Fr,
-    merkle_path: [(bls12_381::Scalar, bool); 4]
-    ) -> (groth16::Proof<Bls12>, SpendRevealedValues) {
+    merkle_path: [(bls12_381::Scalar, bool); 4],
+) -> (groth16::Proof<Bls12>, SpendRevealedValues) {
     let c = SpendContract {
         value: Some(value),
         randomness_value: Some(randomness_value),
@@ -239,8 +239,8 @@ pub fn create_spend_proof(
 pub fn verify_spend_proof(
     pvk: &groth16::PreparedVerifyingKey<Bls12>,
     proof: &groth16::Proof<Bls12>,
-    revealed: &SpendRevealedValues
-    ) -> bool {
+    revealed: &SpendRevealedValues,
+) -> bool {
     let public_input = revealed.make_outputs();
 
     let start = Instant::now();
@@ -248,4 +248,3 @@ pub fn verify_spend_proof(
     println!("Verify: [{:?}]", start.elapsed());
     result
 }
-