Просмотр исходного кода

example of build a merkle tree and witness from a newly minted coin

narodnik 5 лет назад
Родитель
Сommit
bfe5d85ec9
3 измененных файлов с 36 добавлено и 12 удалено
  1. 21 2
      src/bin/tx.rs
  2. 10 10
      src/crypto/coin.rs
  3. 5 0
      src/tx.rs

+ 21 - 2
src/bin/tx.rs

@@ -1,14 +1,16 @@
 use std::io;
 use bellman::groth16;
 use bls12_381::Bls12;
-use ff::Field;
+use ff::{Field, PrimeField};
 use group::Group;
 use rand::rngs::OsRng;
 
 use sapvi::crypto::{
     create_mint_proof, load_params, save_params, setup_mint_prover, verify_mint_proof,
     MintRevealedValues,
-    note::Note
+    note::Note,
+    merkle::{IncrementalWitness, CommitmentTree},
+    coin::Coin,
 };
 use sapvi::serial::{Decodable, Encodable, VarInt};
 use sapvi::error::{Error, Result};
@@ -33,9 +35,26 @@ fn txbuilding() {
         let tx = builder.build(&mint_params);
         tx.encode(&mut tx_data).expect("encode tx");
     }
+    let mut tree = CommitmentTree::empty();
+    for i in 0..5 {
+        let cmu = Coin::new(bls12_381::Scalar::random(&mut OsRng).to_repr());
+        tree.append(cmu);
+    }
     {
         let tx = tx::Transaction::decode(&tx_data[..]).unwrap();
         assert!(tx.verify(&mint_pvk));
+        tree.append(Coin::new(tx.outputs[0].revealed.coin)).expect("append merkle");
+    }
+    let mut witness = IncrementalWitness::from_tree(&tree);
+    assert_eq!(witness.position(), 5);
+    assert_eq!(tree.root(), witness.root());
+
+    // Add some random coins in
+    for i in 0..10 {
+        let cmu = Coin::new(bls12_381::Scalar::random(&mut OsRng).to_repr());
+        tree.append(cmu);
+        witness.append(cmu);
+        assert_eq!(tree.root(), witness.root());
     }
 }
 

+ 10 - 10
src/crypto/coin.rs

@@ -44,21 +44,21 @@ pub fn merkle_hash(depth: usize, lhs: &[u8; 32], rhs: &[u8; 32]) -> bls12_381::S
 
 /// A node within the Sapling commitment tree.
 #[derive(Clone, Copy, Debug, PartialEq)]
-pub struct Node {
+pub struct Coin {
     repr: [u8; 32],
 }
 
-impl Node {
+impl Coin {
     pub fn new(repr: [u8; 32]) -> Self {
-        Node { repr }
+        Coin { repr }
     }
 }
 
-impl Hashable for Node {
+impl Hashable for Coin {
     fn read<R: io::Read>(mut reader: R) -> io::Result<Self> {
         let mut repr = [0u8; 32];
         reader.read_exact(&mut repr)?;
-        Ok(Node::new(repr))
+        Ok(Coin::new(repr))
     }
 
     fn write<W: io::Write>(&self, mut writer: W) -> io::Result<()> {
@@ -66,7 +66,7 @@ impl Hashable for Node {
     }
 
     fn combine(depth: usize, lhs: &Self, rhs: &Self) -> Self {
-        Node {
+        Coin {
             repr: merkle_hash(depth, &lhs.repr, &rhs.repr).to_repr(),
         }
     }
@@ -75,7 +75,7 @@ impl Hashable for Node {
         // The smallest u-coordinate that is not on the curve
         // is one.
         let uncommitted_note = bls12_381::Scalar::one();
-        Node {
+        Coin {
             repr: uncommitted_note.to_repr(),
         }
     }
@@ -86,10 +86,10 @@ impl Hashable for Node {
 }
 
 lazy_static! {
-    static ref EMPTY_ROOTS: Vec<Node> = {
-        let mut v = vec![Node::blank()];
+    static ref EMPTY_ROOTS: Vec<Coin> = {
+        let mut v = vec![Coin::blank()];
         for d in 0..SAPLING_COMMITMENT_TREE_DEPTH {
-            let next = Node::combine(d, &v[d], &v[d]);
+            let next = Coin::combine(d, &v[d], &v[d]);
             v.push(next);
         }
         v

+ 5 - 0
src/tx.rs

@@ -87,6 +87,11 @@ pub struct TransactionBuilderClearInputInfo {
     pub value: u64,
 }
 
+pub struct TransactionBuilderInputInfo {
+    pub value: u64,
+    pub serial: jubjub::Fr,
+}
+
 pub struct TransactionBuilderOutputInfo {
     pub value: u64,
     pub public: jubjub::SubgroupPoint,