瀏覽代碼

add nullifier to walletdb and attached to OwnCoin

ghassmo 4 年之前
父節點
當前提交
82a78e078c
共有 4 個文件被更改,包括 57 次插入10 次删除
  1. 2 1
      sql/schema.sql
  2. 18 2
      src/client.rs
  3. 1 0
      src/crypto/mod.rs
  4. 36 7
      src/wallet/walletdb.rs

+ 2 - 1
sql/schema.sql

@@ -13,5 +13,6 @@ CREATE TABLE IF NOT EXISTS coins(
 	token_id INT NOT NULL,
 	witness BLOB NOT NULL,
 	secret BLOB NOT NULL,
-	is_spent BLOB NOT NULL
+	is_spent BLOB NOT NULL,
+	nullifier BLOB NOT NULL
 );

+ 18 - 2
src/client.rs

@@ -5,6 +5,7 @@ use bellman::groth16;
 use bls12_381::Bls12;
 use log::{debug, info, warn};
 use url::Url;
+use blake2s_simd::Params as Blake2sParams;
 
 use crate::{
     blockchain::{rocks::columns, Rocks, RocksColumn, Slab},
@@ -268,7 +269,7 @@ impl Client {
                     wallet.clone(),
                     Some(notify.clone()),
                 )
-                .await;
+                    .await;
 
                 if let Err(e) = update_state {
                     warn!("Update state: {}", e.to_string());
@@ -308,7 +309,7 @@ impl Client {
                     wallet.clone(),
                     None,
                 )
-                .await;
+                    .await;
 
                 if let Err(e) = update_state {
                     warn!("Update state: {}", e.to_string());
@@ -474,11 +475,26 @@ impl State {
                     // Make a new witness for this coin
                     let witness = IncrementalWitness::from_tree(&self.tree);
 
+                    let mut nullifier = [0; 32];
+                    nullifier.copy_from_slice(
+                        Blake2sParams::new()
+                        .hash_length(32)
+                        .personal(zcash_primitives::constants::PRF_NF_PERSONALIZATION)
+                        .to_state()
+                        .update(&secret.to_bytes())
+                        .update(&note.serial.to_bytes())
+                        .finalize()
+                        .as_bytes(),
+                    );
+
+                    let nullifier = Nullifier::new(nullifier);
+
                     let own_coin = OwnCoin {
                         coin: coin.clone(),
                         note: note.clone(),
                         secret: *secret,
                         witness: witness.clone(),
+                        nullifier
                     };
 
                     wallet.put_own_coins(own_coin)?;

+ 1 - 0
src/crypto/mod.rs

@@ -25,6 +25,7 @@ pub struct OwnCoin {
     pub note: note::Note,
     pub secret: jubjub::Fr,
     pub witness: merkle::IncrementalWitness<merkle_node::MerkleNode>,
+    pub nullifier: nullifier::Nullifier 
 }
 
 pub type OwnCoins = Vec<OwnCoin>;

+ 36 - 7
src/wallet/walletdb.rs

@@ -10,7 +10,8 @@ use rusqlite::{named_params, params, Connection};
 use super::WalletApi;
 use crate::client::ClientFailed;
 use crate::crypto::{
-    coin::Coin, merkle::IncrementalWitness, merkle_node::MerkleNode, note::Note, OwnCoin, OwnCoins,
+    coin::Coin, merkle::IncrementalWitness, merkle_node::MerkleNode, note::Note,
+    nullifier::Nullifier, OwnCoin, OwnCoins,
 };
 use crate::serial;
 use crate::{Error, Result};
@@ -27,6 +28,7 @@ pub struct Keypair {
 pub struct Balance {
     pub token_id: jubjub::Fr,
     pub value: u64,
+    pub nullifier: Nullifier,
 }
 
 #[derive(Debug, Clone)]
@@ -173,6 +175,7 @@ impl WalletDb {
                 row.get(5)?,
                 row.get(6)?,
                 row.get(7)?,
+                row.get(9)?,
             ))
         })?;
 
@@ -199,12 +202,14 @@ impl WalletDb {
 
             let witness = self.get_value_deserialized(&row.6)?;
             let secret: jubjub::Fr = self.get_value_deserialized(&row.7)?;
+            let nullifier: Nullifier = self.get_value_deserialized(&row.8)?;
 
             let oc = OwnCoin {
                 coin,
                 note,
                 secret,
                 witness,
+                nullifier,
             };
 
             own_coins.push(oc)
@@ -231,12 +236,15 @@ impl WalletDb {
         let witness = self.get_value_serialized(&own_coin.witness)?;
         let secret = self.get_value_serialized(&own_coin.secret)?;
         let is_spent = self.get_value_serialized(&false)?;
+        let nullifier = self.get_value_serialized(&own_coin.nullifier)?;
 
         conn.execute(
             "INSERT OR REPLACE INTO coins
-            (coin, serial, value, token_id, coin_blind, valcom_blind, witness, secret, is_spent)
+            (coin, serial, value, token_id, coin_blind, 
+            valcom_blind, witness, secret, is_spent, nullifier)
             VALUES
-            (:coin, :serial, :value, :token_id, :coin_blind, :valcom_blind, :witness, :secret, :is_spent);",
+            (:coin, :serial, :value, :token_id, :coin_blind, 
+             :valcom_blind, :witness, :secret, :is_spent, :nullifier);",
             named_params! {
                 ":coin": coin,
                 ":serial": serial,
@@ -247,6 +255,7 @@ impl WalletDb {
                 ":witness": witness,
                 ":secret": secret,
                 ":is_spent": is_spent,
+                ":nullifier": nullifier,
             },
         )?;
         Ok(())
@@ -338,10 +347,11 @@ impl WalletDb {
 
         let is_spent = self.get_value_serialized(&false)?;
 
-        let mut stmt =
-            conn.prepare("SELECT value, token_id FROM coins  WHERE is_spent = :is_spent ;")?;
+        let mut stmt = conn.prepare(
+            "SELECT value, token_id, nullifier FROM coins  WHERE is_spent = :is_spent ;",
+        )?;
         let rows = stmt.query_map(&[(":is_spent", &is_spent)], |row| {
-            Ok((row.get(0)?, row.get(1)?))
+            Ok((row.get(0)?, row.get(1)?, row.get(2)?))
         })?;
 
         let mut balances = Balances { list: Vec::new() };
@@ -350,7 +360,12 @@ impl WalletDb {
             let row = row?;
             let value: u64 = row.0;
             let token_id: jubjub::Fr = self.get_value_deserialized(&row.1)?;
-            balances.add(&Balance { token_id, value });
+            let nullifier: Nullifier = self.get_value_deserialized(&row.2)?;
+            balances.add(&Balance {
+                token_id,
+                value,
+                nullifier,
+            });
         }
 
         Ok(balances)
@@ -452,11 +467,14 @@ mod tests {
 
         let witness = IncrementalWitness::from_tree(&tree);
 
+        let nullifier = Nullifier::new(coin.repr);
+
         let own_coin = OwnCoin {
             coin,
             note,
             secret,
             witness,
+            nullifier,
         };
 
         wallet.put_own_coins(own_coin.clone())?;
@@ -507,11 +525,14 @@ mod tests {
 
         let witness = IncrementalWitness::from_tree(&tree);
 
+        let nullifier = Nullifier::new(coin.repr);
+
         let own_coin = OwnCoin {
             coin,
             note,
             secret,
             witness,
+            nullifier,
         };
 
         wallet.put_own_coins(own_coin.clone())?;
@@ -583,11 +604,14 @@ mod tests {
 
         assert_eq!(coin, crate::serial::deserialize(&coin_ser)?);
 
+        let nullifier = Nullifier::new(coin.repr);
+
         let own_coin = OwnCoin {
             coin,
             note: note.clone(),
             secret,
             witness: witness.clone(),
+            nullifier: nullifier.clone(),
         };
 
         wallet.put_own_coins(own_coin)?;
@@ -599,6 +623,7 @@ mod tests {
         assert_eq!(own_coin.secret, secret);
         assert_eq!(own_coin.witness.root(), witness.root());
         assert_eq!(own_coin.witness.path(), witness.path());
+        assert_eq!(own_coin.nullifier, nullifier);
 
         wallet.confirm_spend_coin(&own_coin.coin)?;
 
@@ -655,11 +680,15 @@ mod tests {
 
         let witness = IncrementalWitness::from_tree(&tree);
 
+        // for testing
+        let nullifier = Nullifier::new(coin.repr);
+
         let own_coin = OwnCoin {
             coin,
             note,
             secret,
             witness,
+            nullifier,
         };
 
         wallet.put_own_coins(own_coin.clone())?;