Explorar el Código

merkle checking is correct

narodnik hace 5 años
padre
commit
62e0da8630

+ 8 - 2
src/async_serial.rs

@@ -78,7 +78,10 @@ macro_rules! async_decoder_fn {
         pub async fn $name<R: AsyncRead + Unpin>(stream: &mut R) -> Result<$val_type> {
             assert_eq!(::std::mem::size_of::<$val_type>(), $byte_len); // size_of isn't a constfn in 1.22
             let mut val = [0; $byte_len];
-            stream.read_exact(&mut val[..]).await.map_err(|e| Error::Io(e.kind()))?;
+            stream
+                .read_exact(&mut val[..])
+                .await
+                .map_err(|e| Error::Io(e.kind()))?;
             Ok(endian::$readfn(&val))
         }
     };
@@ -106,6 +109,9 @@ impl AsyncWriteExt {
     async_encoder_fn!(write_u16, u16, u16_to_array_le);
 
     pub async fn write_u8<W: AsyncWrite + Unpin>(stream: &mut W, v: u8) -> Result<()> {
-        stream.write_all(&[v]).await.map_err(|e| Error::Io(e.kind()))
+        stream
+            .write_all(&[v])
+            .await
+            .map_err(|e| Error::Io(e.kind()))
     }
 }

+ 2 - 3
src/bin/dfi.rs

@@ -1,23 +1,22 @@
 #[macro_use]
 extern crate clap;
 use async_executor::Executor;
-use sapvi::rpc::options::ProgramOptions;
 use async_native_tls::TlsAcceptor;
 use async_std::sync::Mutex;
 use easy_parallel::Parallel;
 use http_types::{Request, Response, StatusCode};
 use log::*;
+use sapvi::rpc::adapter::RpcAdapter;
 use sapvi::rpc::jsonserver;
 use sapvi::rpc::jsonserver::RpcInterface;
+use sapvi::rpc::options::ProgramOptions;
 use sapvi::{net, Result};
-use sapvi::rpc::adapter::RpcAdapter;
 use serde_json::json;
 use smol::Async;
 use std::net::SocketAddr;
 use std::net::TcpListener;
 use std::sync::Arc;
 
-
 /*
 async fn start2(executor: Arc<Executor<'_>>, options: ProgramOptions) -> Result<()> {
     let connections = Arc::new(Mutex::new(HashMap::new()));

+ 42 - 7
src/bin/tx.rs

@@ -1,17 +1,19 @@
 use bellman::groth16;
+use bitvec::{order::Lsb0, view::AsBits};
 use bls12_381::Bls12;
 use ff::{Field, PrimeField};
+use group::Curve;
 use group::Group;
 use rand::rngs::OsRng;
 use std::io;
 use std::path::Path;
 
 use sapvi::crypto::{
-    coin::Coin,
+    coin::{hash_coin, Coin},
     create_mint_proof, create_spend_proof, load_params,
     merkle::{CommitmentTree, IncrementalWitness},
-    nullifier::Nullifier,
     note::{EncryptedNote, Note},
+    nullifier::Nullifier,
     save_params, setup_mint_prover, setup_spend_prover, verify_mint_proof, verify_spend_proof,
     MintRevealedValues, SpendRevealedValues,
 };
@@ -22,6 +24,7 @@ use sapvi::tx;
 
 struct MemoryState {
     tree: CommitmentTree<Coin>,
+    merkle_roots: Vec<bls12_381::Scalar>,
     nullifiers: Vec<Nullifier>,
     own_coins: Vec<(Coin, Note, jubjub::Fr, IncrementalWitness<Coin>)>,
     mint_pvk: groth16::PreparedVerifyingKey<Bls12>,
@@ -35,10 +38,10 @@ impl ProgramState for MemoryState {
         public == &self.cashier_public
     }
     fn is_valid_merkle(&self, merkle: &bls12_381::Scalar) -> bool {
-        true
+        self.merkle_roots.iter().any(|m| *m == *merkle)
     }
     fn nullifier_exists(&self, nullifier: &[u8; 32]) -> bool {
-        false
+        self.nullifiers.iter().any(|n| n.repr == *nullifier)
     }
 
     fn mint_pvk(&self) -> &groth16::PreparedVerifyingKey<Bls12> {
@@ -55,11 +58,22 @@ impl MemoryState {
 
         // Update merkle tree and witnesses
         for (coin, enc_note) in updates.coins.into_iter().zip(updates.enc_notes.into_iter()) {
+            let node = hash_coin(coin.repr);
+
             // Add the new coins to the merkle tree
             self.tree
-                .append(coin.clone())
+                .append(Coin::new(node.to_repr()))
                 .expect("Append to merkle tree");
 
+            let root = self.tree.root();
+            self.merkle_roots.push(root.into());
+            for (_, _, _, witness) in self.own_coins.iter_mut() {
+                witness
+                    .append(Coin::new(node.to_repr()))
+                    .expect("append to witness");
+            }
+            assert_eq!(self.own_coins.len(), 0);
+
             if let Some((note, secret)) = self.try_decrypt_note(enc_note) {
                 // We need to keep track of the witness for this coin.
                 // This allows us to prove inclusion of the coin in the merkle tree with ZK.
@@ -119,6 +133,7 @@ fn main() {
 
     let mut state = MemoryState {
         tree: CommitmentTree::empty(),
+        merkle_roots: vec![],
         nullifiers: vec![],
         own_coins: vec![],
         mint_pvk,
@@ -161,6 +176,9 @@ fn main() {
         for i in 0..5 {
             let cmu = Coin::new(bls12_381::Scalar::random(&mut OsRng).to_repr());
             tree.append(cmu);
+
+            let root = tree.root();
+            state.merkle_roots.push(root.into());
         }
     }
 
@@ -178,9 +196,9 @@ fn main() {
     assert_eq!(state.own_coins.len(), 1);
     //let (coin, note, secret, witness) = &mut state.own_coins[0];
 
-    let auth_path =
-    {
+    let auth_path = {
         let tree = &mut state.tree;
+        let coin = state.own_coins[0].0;
         let witness = &mut state.own_coins[0].3;
         // Check this is the 6th coin we added
         assert_eq!(witness.position(), 5);
@@ -192,8 +210,13 @@ fn main() {
             tree.append(cmu);
             witness.append(cmu);
             assert_eq!(tree.root(), witness.root());
+
+            let root = tree.root();
+            state.merkle_roots.push(root.into());
         }
 
+        assert_eq!(state.merkle_roots.len(), 16);
+
         // TODO: Some stupid glue code. Need to put this somewhere else.
         let merkle_path = witness.path().unwrap();
         let auth_path: Vec<(bls12_381::Scalar, bool)> = merkle_path
@@ -201,6 +224,16 @@ fn main() {
             .iter()
             .map(|(node, b)| ((*node).into(), *b))
             .collect();
+
+        let node = hash_coin(coin.repr).to_repr();
+
+        let root = tree.root();
+        drop(tree);
+        drop(witness);
+        assert_eq!(merkle_path.root(Coin::new(node)), root);
+        let root = root.into();
+        assert!(state.is_valid_merkle(&root));
+
         auth_path
     };
 
@@ -245,6 +278,8 @@ fn main() {
     // Verify it's valid
     {
         let tx = tx::Transaction::decode(&tx_data[..]).unwrap();
+        println!("tx {:?}", tx.inputs[0].revealed.merkle_root);
+        assert!(state.is_valid_merkle(&tx.inputs[0].revealed.merkle_root));
         let update = state_transition(&state, tx).expect("step 3 state transition failed");
     }
 }

+ 7 - 0
src/circuit/spend_contract.rs

@@ -253,6 +253,13 @@ impl Circuit<bls12_381::Scalar> for SpendContract {
         // Line 168: ec_get_u current cm
         let mut current = cm.get_u().clone();
 
+        match current.get_value() {
+            Some(v) => {
+                println!("coin hashed {:?}", v);
+            }
+            None => {}
+        }
+
         // Line 174: alloc_scalar branch param:branch_0
         let branch = num::AllocatedNum::alloc(
             cs.namespace(|| "Line 174: alloc_scalar branch param:branch_0"),

+ 17 - 0
src/crypto/coin.rs

@@ -42,6 +42,23 @@ pub fn merkle_hash(depth: usize, lhs: &[u8; 32], rhs: &[u8; 32]) -> bls12_381::S
     .get_u()
 }
 
+pub fn hash_coin(coin: [u8; 32]) -> bls12_381::Scalar {
+    let rhs = {
+        let mut tmp = [false; 256];
+        for (a, b) in tmp.iter_mut().zip(coin.as_bits::<Lsb0>()) {
+            *a = *b;
+        }
+        tmp
+    };
+
+    jubjub::ExtendedPoint::from(zcash_primitives::pedersen_hash::pedersen_hash(
+        zcash_primitives::pedersen_hash::Personalization::NoteCommitment,
+        rhs.iter().copied(),
+    ))
+    .to_affine()
+    .get_u()
+}
+
 /// A node within the Sapling commitment tree.
 #[derive(Clone, Copy, Debug, PartialEq)]
 pub struct Coin {

+ 0 - 1
src/crypto/nullifier.rs

@@ -7,4 +7,3 @@ impl Nullifier {
         Self { repr }
     }
 }
-

+ 1 - 2
src/error.rs

@@ -11,7 +11,7 @@ pub type Result<T> = std::result::Result<T, Error>;
 //#[derive(Debug, Copy, Clone)]
 
 // need to be able to copy the errors into theads
-// net error has clone and copy attribute 
+// net error has clone and copy attribute
 // copy vs clone
 //struct Error;
 
@@ -184,4 +184,3 @@ impl From<state::VerifyFailed> for Error {
         Error::VerifyFailed
     }
 }
-

+ 7 - 3
src/rpc/jsonserver.rs

@@ -1,6 +1,6 @@
-use crate::{net, serial, Error, Result};
-use crate::rpc::options::ProgramOptions;
 use crate::rpc::adapter::RpcAdapter;
+use crate::rpc::options::ProgramOptions;
+use crate::{net, serial, Error, Result};
 use async_executor::Executor;
 use async_native_tls::TlsAcceptor;
 use async_std::sync::Mutex;
@@ -80,7 +80,11 @@ pub async fn listen(
     }
 }
 
-pub async fn start(executor: Arc<Executor<'_>>, options: ProgramOptions, adapter: Arc<RpcAdapter>) -> Result<()> {
+pub async fn start(
+    executor: Arc<Executor<'_>>,
+    options: ProgramOptions,
+    adapter: Arc<RpcAdapter>,
+) -> Result<()> {
     let p2p = net::P2p::new(options.network_settings);
 
     let rpc = RpcInterface::new(p2p.clone());

+ 1 - 1
src/rpc/mod.rs

@@ -1,4 +1,4 @@
-pub mod options;
 pub mod adapter;
 pub mod jsonserver;
+pub mod options;
 pub mod test;

+ 4 - 2
src/serial.rs

@@ -103,7 +103,8 @@ macro_rules! encoder_fn {
     ($name:ident, $val_type:ty, $writefn:ident) => {
         #[inline]
         fn $name(&mut self, v: $val_type) -> Result<()> {
-            self.write_all(&endian::$writefn(v)).map_err(|e| Error::Io(e.kind()))
+            self.write_all(&endian::$writefn(v))
+                .map_err(|e| Error::Io(e.kind()))
         }
     };
 }
@@ -114,7 +115,8 @@ macro_rules! decoder_fn {
         fn $name(&mut self) -> Result<$val_type> {
             assert_eq!(::std::mem::size_of::<$val_type>(), $byte_len); // size_of isn't a constfn in 1.22
             let mut val = [0; $byte_len];
-            self.read_exact(&mut val[..]).map_err(|e| Error::Io(e.kind()))?;
+            self.read_exact(&mut val[..])
+                .map_err(|e| Error::Io(e.kind()))?;
             Ok(endian::$readfn(&val))
         }
     };

+ 15 - 3
src/state.rs

@@ -2,7 +2,15 @@ use bellman::groth16;
 use bls12_381::Bls12;
 use std::fmt;
 
-use crate::{crypto::{coin::Coin, note::{EncryptedNote, Note}, nullifier::Nullifier}, error::{Error, Result}, tx};
+use crate::{
+    crypto::{
+        coin::Coin,
+        note::{EncryptedNote, Note},
+        nullifier::Nullifier,
+    },
+    error::{Error, Result},
+    tx,
+};
 
 pub trait ProgramState {
     fn is_valid_cashier_public_key(&self, public: &jubjub::SubgroupPoint) -> bool;
@@ -16,7 +24,7 @@ pub trait ProgramState {
 pub struct StateUpdates {
     pub nullifiers: Vec<Nullifier>,
     pub coins: Vec<Coin>,
-    pub enc_notes: Vec<EncryptedNote>
+    pub enc_notes: Vec<EncryptedNote>,
 }
 
 pub type VerifyResult<T> = std::result::Result<T, VerifyFailed>;
@@ -109,5 +117,9 @@ pub fn state_transition<S: ProgramState>(
         enc_notes.push(output.enc_note);
     }
 
-    Ok(StateUpdates { nullifiers, coins, enc_notes })
+    Ok(StateUpdates {
+        nullifiers,
+        coins,
+        enc_notes,
+    })
 }

+ 7 - 5
src/tx/builder.rs

@@ -1,13 +1,14 @@
 use bellman::groth16;
 use bls12_381::Bls12;
+use ff::Field;
 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 super::{
+    partial::{PartialTransaction, PartialTransactionClearInput, PartialTransactionInput},
+    Transaction, TransactionClearInput, TransactionInput, TransactionOutput,
+};
 use crate::crypto::{
     coin::Coin,
     create_mint_proof, create_spend_proof, load_params,
@@ -16,6 +17,8 @@ use crate::crypto::{
     save_params, schnorr, setup_mint_prover, setup_spend_prover, verify_mint_proof,
     verify_spend_proof, MintRevealedValues, SpendRevealedValues,
 };
+use crate::error::{Error, Result};
+use crate::serial::{Decodable, Encodable, VarInt};
 
 pub struct TransactionBuilder {
     pub clear_inputs: Vec<TransactionBuilderClearInputInfo>,
@@ -191,4 +194,3 @@ impl TransactionBuilder {
         }
     }
 }
-

+ 5 - 3
src/tx/mod.rs

@@ -9,6 +9,7 @@ use rand::rngs::OsRng;
 use std::collections::HashMap;
 use std::io;
 
+use self::partial::{PartialTransactionClearInput, PartialTransactionInput};
 use crate::crypto::{
     coin::Coin,
     create_mint_proof, create_spend_proof, load_params,
@@ -21,9 +22,11 @@ use crate::error::{Error, Result};
 use crate::impl_vec;
 use crate::serial::{Decodable, Encodable, VarInt};
 use crate::state;
-use self::partial::{PartialTransactionClearInput, PartialTransactionInput};
 
-pub use self::builder::{TransactionBuilder, TransactionBuilderClearInputInfo, TransactionBuilderInputInfo, TransactionBuilderOutputInfo};
+pub use self::builder::{
+    TransactionBuilder, TransactionBuilderClearInputInfo, TransactionBuilderInputInfo,
+    TransactionBuilderOutputInfo,
+};
 
 pub struct Transaction {
     pub clear_inputs: Vec<TransactionClearInput>,
@@ -256,4 +259,3 @@ impl_vec_without_signature!(TransactionInput);
 impl_vec!(TransactionClearInput);
 impl_vec!(TransactionInput);
 impl_vec!(TransactionOutput);
-

+ 5 - 7
src/tx/partial.rs

@@ -1,14 +1,11 @@
 use bellman::groth16;
 use bls12_381::Bls12;
+use ff::Field;
 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 super::{Transaction, TransactionClearInput, TransactionInput, TransactionOutput};
 use crate::crypto::{
     coin::Coin,
     create_mint_proof, create_spend_proof, load_params,
@@ -17,6 +14,9 @@ use crate::crypto::{
     save_params, schnorr, setup_mint_prover, setup_spend_prover, verify_mint_proof,
     verify_spend_proof, MintRevealedValues, SpendRevealedValues,
 };
+use crate::error::{Error, Result};
+use crate::impl_vec;
+use crate::serial::{Decodable, Encodable, VarInt};
 
 pub struct PartialTransaction {
     pub clear_inputs: Vec<PartialTransactionClearInput>,
@@ -75,7 +75,6 @@ impl Decodable for PartialTransactionClearInput {
     }
 }
 
-
 impl Encodable for PartialTransactionInput {
     fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
         let mut len = 0;
@@ -96,4 +95,3 @@ impl Decodable for PartialTransactionInput {
 
 impl_vec!(PartialTransactionClearInput);
 impl_vec!(PartialTransactionInput);
-