Parcourir la source

add encrypted output note

narodnik il y a 5 ans
Parent
commit
37baa83f16
6 fichiers modifiés avec 99 ajouts et 32 suppressions
  1. 21 12
      src/bin/tx.rs
  2. 3 3
      src/bin/wallet/darkd.rs
  3. 21 0
      src/crypto/note.rs
  4. 1 1
      src/crypto/schnorr.rs
  5. 5 2
      src/crypto/spend_proof.rs
  6. 48 14
      src/tx.rs

+ 21 - 12
src/bin/tx.rs

@@ -18,18 +18,19 @@ use sapvi::serial::{Decodable, Encodable, VarInt};
 use sapvi::tx;
 
 fn txbuilding() {
-    {
-        let params = setup_mint_prover();
-        save_params("mint.params", &params);
-    }
-    {
-        let params = setup_spend_prover();
-        save_params("spend.params", &params);
-    }
+    //{
+    //    let params = setup_mint_prover();
+    //    save_params("mint.params", &params);
+    //}
+    //{
+    //    let params = setup_spend_prover();
+    //    save_params("spend.params", &params);
+    //}
     let (mint_params, mint_pvk) = load_params("mint.params").expect("params should load");
     let (spend_params, spend_pvk) = load_params("spend.params").expect("params should load");
 
-    let public = jubjub::SubgroupPoint::random(&mut OsRng);
+    let secret = jubjub::Fr::random(&mut OsRng);
+    let public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * secret;
 
     let builder = tx::TransactionBuilder {
         clear_inputs: vec![tx::TransactionBuilderClearInputInfo { value: 110 }],
@@ -49,12 +50,17 @@ fn txbuilding() {
         let cmu = Coin::new(bls12_381::Scalar::random(&mut OsRng).to_repr());
         tree.append(cmu);
     }
+    let note =
     {
         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");
-    }
+
+        // Try to decrypt output note
+        let note = tx.outputs[0].enc_note.decrypt(&secret).expect("note should be destined for us");
+        note
+    };
     let mut witness = IncrementalWitness::from_tree(&tree);
     assert_eq!(witness.position(), 5);
     assert_eq!(tree.root(), witness.root());
@@ -82,8 +88,11 @@ fn txbuilding() {
     };
     let builder = tx::TransactionBuilder {
         clear_inputs: vec![],
-        inputs: vec![tx::TransactionBuilderInputInfo { coin, merkle_path: auth_path }],
-        outputs: vec![tx::TransactionBuilderOutputInfo { value: 110, public }]
+        inputs: vec![tx::TransactionBuilderInputInfo {
+            coin,
+            merkle_path: auth_path,
+        }],
+        outputs: vec![tx::TransactionBuilderOutputInfo { value: 110, public }],
     };
 
     /*let note = Note {

+ 3 - 3
src/bin/wallet/darkd.rs

@@ -4,16 +4,16 @@ use async_executor::Executor;
 use async_native_tls::TlsAcceptor;
 use async_std::sync::Mutex;
 use easy_parallel::Parallel;
+use ff::Field;
 use http_types::{Request, Response, StatusCode};
 use log::*;
+use rand::rngs::OsRng;
+use sapvi::serial;
 use serde_json::json;
 use smol::Async;
 use std::net::SocketAddr;
 use std::net::TcpListener;
 use std::sync::Arc;
-use ff::Field;
-use sapvi::serial;
-use rand::rngs::OsRng;
 
 use sapvi::{net, Result};
 

+ 21 - 0
src/crypto/note.rs

@@ -73,6 +73,27 @@ pub struct EncryptedNote {
     ephem_public: jubjub::SubgroupPoint,
 }
 
+impl Encodable for EncryptedNote {
+    fn encode<S: io::Write>(&self, mut s: S) -> Result<usize> {
+        let mut len = 0;
+        s.write_slice(&self.ciphertext)?;
+        len += ENC_CIPHERTEXT_SIZE;
+        len += self.ephem_public.encode(&mut s)?;
+        Ok(len)
+    }
+}
+
+impl Decodable for EncryptedNote {
+    fn decode<D: io::Read>(mut d: D) -> Result<Self> {
+        let mut ciphertext = [0u8; ENC_CIPHERTEXT_SIZE];
+        d.read_slice(&mut ciphertext[..])?;
+        Ok(Self {
+            ciphertext,
+            ephem_public: Decodable::decode(d)?
+        })
+    }
+}
+
 impl EncryptedNote {
     pub fn decrypt(&self, secret: &jubjub::Fr) -> Result<Note> {
         let shared_secret = sapling_ka_agree(&secret, &self.ephem_public.into());

+ 1 - 1
src/crypto/schnorr.rs

@@ -3,9 +3,9 @@ use group::{Group, GroupEncoding};
 use rand::rngs::OsRng;
 use std::io;
 
+use super::util::hash_to_scalar;
 use crate::error::{Error, Result};
 use crate::serial::{Decodable, Encodable};
-use super::util::hash_to_scalar;
 
 pub struct SecretKey(pub jubjub::Fr);
 

+ 5 - 2
src/crypto/spend_proof.rs

@@ -6,8 +6,8 @@ use bls12_381::Bls12;
 use ff::{Field, PrimeField};
 use group::{Curve, GroupEncoding};
 use rand::rngs::OsRng;
-use std::time::Instant;
 use std::io;
+use std::time::Instant;
 
 use super::coin::merkle_hash;
 use crate::circuit::spend_contract::SpendContract;
@@ -210,7 +210,10 @@ pub fn create_spend_proof(
     signature_secret: jubjub::Fr,
 ) -> (groth16::Proof<Bls12>, SpendRevealedValues) {
     assert_eq!(merkle_path.len(), 4);
-    assert_eq!(merkle_path.len(), super::coin::SAPLING_COMMITMENT_TREE_DEPTH);
+    assert_eq!(
+        merkle_path.len(),
+        super::coin::SAPLING_COMMITMENT_TREE_DEPTH
+    );
     let c = SpendContract {
         value: Some(value),
         randomness_value: Some(randomness_value),

+ 48 - 14
src/tx.rs

@@ -1,15 +1,15 @@
-use std::collections::HashMap;
 use bellman::groth16;
 use bls12_381::Bls12;
 use ff::Field;
 use group::Group;
 use rand::rngs::OsRng;
+use std::collections::HashMap;
 use std::io;
 
 use crate::crypto::{
-    create_mint_proof, load_params, note::Note, save_params, setup_mint_prover, verify_mint_proof,
+    create_mint_proof, create_spend_proof, load_params, note::{Note, EncryptedNote}, save_params, schnorr,
+    setup_mint_prover, setup_spend_prover, verify_mint_proof, verify_spend_proof,
     MintRevealedValues, SpendRevealedValues,
-    schnorr
 };
 use crate::error::{Error, Result};
 use crate::impl_vec;
@@ -24,18 +24,17 @@ pub trait CoinLookup {
 pub struct CoinAttributes {
     serial: jubjub::Fr,
     coin_blind: jubjub::Fr,
-    valcom_blind: jubjub::Fr,
-    value: u64
+    value: u64,
 }
 
 pub struct CoinHashMap {
-    map: HashMap<[u8; 32], CoinAttributes>
+    map: HashMap<[u8; 32], CoinAttributes>,
 }
 
 impl CoinHashMap {
     pub fn new() -> Self {
         Self {
-            map: HashMap::new()
+            map: HashMap::new(),
         }
     }
 }
@@ -93,6 +92,27 @@ impl TransactionBuilder {
         let mut inputs = vec![];
         for input in &self.inputs {
             let valcom_blind: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
+
+            let signature_secret: jubjub::Fr = jubjub::Fr::random(&mut OsRng);
+            let signature_public = zcash_primitives::constants::SPENDING_KEY_GENERATOR * signature_secret;
+
+            // make proof
+            let attrs = coin_look.lookup(&input.coin);
+
+            /*
+            let (proof, revealed) = create_spend_proof(
+                &spend_params,
+                attrs.value,
+                valcom_blind.clone(),
+                attrs.serial,
+                attrs.coin_blind,
+                secret,
+                merkle_path,
+                signature_secret,
+            );
+            */
+
+            // make signature
         }
 
         let mut outputs = vec![];
@@ -111,24 +131,35 @@ impl TransactionBuilder {
             let coin_attrs = CoinAttributes {
                 serial: serial.clone(),
                 coin_blind: coin_blind.clone(),
-                valcom_blind: valcom_blind.clone(),
-                value: output.value
+                value: output.value,
             };
 
             let (mint_proof, revealed) = create_mint_proof(
                 mint_params,
                 output.value,
-                valcom_blind,
-                serial,
-                coin_blind,
-                output.public,
+                valcom_blind.clone(),
+                serial.clone(),
+                coin_blind.clone(),
+                output.public.clone(),
             );
 
             coin_look.add(revealed.coin.clone(), coin_attrs);
 
+            // Encrypted note
+
+            let note = Note {
+                serial,
+                value: output.value,
+                coin_blind,
+                valcom_blind,
+            };
+
+            let encrypted_note = note.encrypt(&output.public).unwrap();
+
             let output = TransactionOutput {
                 mint_proof,
                 revealed,
+                enc_note: encrypted_note
             };
             outputs.push(output);
         }
@@ -261,6 +292,7 @@ impl_vec!(TransactionInput);
 pub struct TransactionOutput {
     pub mint_proof: groth16::Proof<Bls12>,
     pub revealed: MintRevealedValues,
+    pub enc_note: EncryptedNote,
 }
 
 impl_vec!(TransactionOutput);
@@ -270,6 +302,7 @@ impl Encodable for TransactionOutput {
         let mut len = 0;
         len += self.mint_proof.encode(&mut s)?;
         len += self.revealed.encode(&mut s)?;
+        len += self.enc_note.encode(&mut s)?;
         Ok(len)
     }
 }
@@ -278,7 +311,8 @@ 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)?,
+            revealed: Decodable::decode(&mut d)?,
+            enc_note: Decodable::decode(&mut d)?,
         })
     }
 }