Jelajahi Sumber

working clear inputs for tx2, check correct public key

narodnik 4 tahun lalu
induk
melakukan
5b0b4065e5
7 mengubah file dengan 121 tambahan dan 19 penghapusan
  1. 107 5
      src/bin/tx2.rs
  2. 2 2
      src/crypto/note.rs
  3. 1 1
      src/crypto/schnorr.rs
  4. 2 2
      src/crypto/spend_proof.rs
  5. 1 1
      src/tx/builder.rs
  6. 1 1
      src/types.rs
  7. 7 7
      src/wallet/walletdb.rs

+ 107 - 5
src/bin/tx2.rs

@@ -1,5 +1,6 @@
 use rand::rngs::OsRng;
 use std::{fmt, time::Instant};
+use log::*;
 
 use halo2::{
     circuit::{Layouter, SimpleFloorPlanner},
@@ -37,10 +38,12 @@ use pasta_curves::{
 
 use drk::{
     crypto::{
+        coin::Coin,
         constants::{
             sinsemilla::{OrchardCommitDomains, OrchardHashDomains, MERKLE_CRH_PERSONALIZATION},
             OrchardFixedBases,
         },
+        nullifier::Nullifier,
         util::{
             pedersen_commitment_u64,
             pedersen_commitment_scalar
@@ -54,6 +57,9 @@ struct MemoryState {
 }
 
 impl ProgramState for MemoryState {
+    fn is_valid_cashier_public_key(&self, public: &pallas::Point) -> bool {
+        true
+    }
 }
 
 impl MemoryState {
@@ -68,6 +74,8 @@ mod tx2 {
         pallas,
     };
 
+    use drk::types::derive_public_key;
+
     pub struct TransactionBuilder {
         pub clear_inputs: Vec<TransactionBuilderClearInputInfo>,
         pub inputs: Vec<TransactionBuilderInputInfo>,
@@ -91,16 +99,87 @@ mod tx2 {
 
     impl TransactionBuilder {
         pub fn build(self) -> Transaction {
-            Transaction {}
+            let mut clear_inputs = vec![];
+            //let token_blind = DrkValueBlind::random(&mut OsRng);
+            for input in &self.clear_inputs {
+                let signature_public = derive_public_key(input.signature_secret);
+                //let value_blind = DrkValueBlind::random(&mut OsRng);
+
+                let clear_input = PartialTransactionClearInput {
+                    value: input.value,
+                    //token_id: input.token_id,
+                    //value_blind,
+                    //token_blind,
+                    signature_public,
+                };
+                clear_inputs.push(clear_input);
+            }
+
+            let partial_tx = PartialTransaction {
+                clear_inputs,
+                //inputs,
+                //outputs,
+            };
+
+            let mut clear_inputs = vec![];
+            for (input, info) in partial_tx.clear_inputs.into_iter().zip(self.clear_inputs) {
+                //let secret = schnorr::SecretKey(info.signature_secret);
+                //let signature = secret.sign(&unsigned_tx_data[..]);
+                let input = TransactionClearInput::from_partial(input);
+                clear_inputs.push(input);
+            }
+
+            Transaction {
+                clear_inputs
+            }
         }
     }
 
+    pub struct PartialTransaction {
+        pub clear_inputs: Vec<PartialTransactionClearInput>,
+        //pub inputs: Vec<PartialTransactionInput>,
+        //pub outputs: Vec<TransactionOutput>,
+    }
+    
+    pub struct PartialTransactionClearInput {
+        pub value: u64,
+        //pub token_id: DrkTokenId,
+        //pub value_blind: DrkValueBlind,
+        //pub token_blind: DrkValueBlind,
+        pub signature_public: pallas::Point,
+    }
+
     pub struct Transaction {
+        pub clear_inputs: Vec<TransactionClearInput>,
+    }
+
+    pub struct TransactionClearInput {
+        pub value: u64,
+        //pub token_id: DrkTokenId,
+        //pub value_blind: DrkValueBlind,
+        //pub token_blind: DrkValueBlind,
+        pub signature_public: pallas::Point,
+        //pub signature: schnorr::Signature,
+    }
+
+    impl TransactionClearInput {
+        fn from_partial(
+            partial: PartialTransactionClearInput,
+        ) -> Self {
+            Self {
+                value: partial.value,
+                //token_id: partial.token_id,
+                //value_blind: partial.value_blind,
+                //token_blind: partial.token_blind,
+                signature_public: partial.signature_public,
+                //signature,
+            }
+        }
     }
 }
 
 pub trait ProgramState {
-    //fn is_valid_cashier_public_key(&self, public: &DrkPublicKey) -> bool;
+    fn is_valid_cashier_public_key(&self, public: &pallas::Point) -> bool;
     //// TODO: fn is_valid_merkle(&self, merkle: &MerkleNode) -> bool;
     //fn nullifier_exists(&self, nullifier: &Nullifier) -> bool;
 
@@ -109,8 +188,8 @@ pub trait ProgramState {
 }
 
 pub struct StateUpdate {
-    //pub nullifiers: Vec<Nullifier>,
-    //pub coins: Vec<Coin>,
+    pub nullifiers: Vec<Nullifier>,
+    pub coins: Vec<Coin>,
     //pub enc_notes: Vec<EncryptedNote>,
 }
 
@@ -163,7 +242,29 @@ pub fn state_transition<S: ProgramState>(
     state: &S,
     tx: tx2::Transaction,
 ) -> VerifyResult<StateUpdate> {
-    Ok(StateUpdate {})
+    // Check deposits are legit
+
+    debug!(target: "STATE TRANSITION", "iterate clear_inputs");
+
+    for (i, input) in tx.clear_inputs.iter().enumerate() {
+        // Check the public key in the clear inputs
+        // It should be a valid public key for the cashier
+
+        if !state.is_valid_cashier_public_key(&input.signature_public) {
+            log::error!(target: "STATE TRANSITION", "Not valid cashier public key");
+            return Err(VerifyFailed::InvalidCashierKey(i));
+        }
+    }
+
+    let mut nullifiers = vec![];
+
+    // Newly created coins for this tx
+    let mut coins = vec![];
+
+    Ok(StateUpdate {
+        nullifiers,
+        coins,
+    })
 }
 
 fn main() -> std::result::Result<(), failure::Error> {
@@ -195,6 +296,7 @@ fn main() -> std::result::Result<(), failure::Error> {
     let tx = builder.build();
 
     let update = state_transition(&state, tx)?;
+    state.apply(update);
 
     Ok(())
 }

+ 2 - 2
src/crypto/note.rs

@@ -58,7 +58,7 @@ impl Decodable for Note {
 impl Note {
     pub fn encrypt(&self, public: &DrkPublicKey) -> Result<EncryptedNote> {
         let ephem_secret = DrkSecretKey::random(&mut OsRng);
-        let ephem_public = derive_publickey(ephem_secret);
+        let ephem_public = derive_public_key(ephem_secret);
         let shared_secret = sapling_ka_agree(&mod_r_p(ephem_secret), public);
         let key = kdf_sapling(shared_secret, &ephem_public);
 
@@ -142,7 +142,7 @@ fn test_note_encdec() {
     };
 
     let secret = DrkSecretKey::random(&mut OsRng);
-    let public = derive_publickey(secret);
+    let public = derive_public_key(secret);
 
     let encrypted_note = note.encrypt(&public).unwrap();
     let note2 = encrypted_note.decrypt(&secret).unwrap();

+ 1 - 1
src/crypto/schnorr.rs

@@ -32,7 +32,7 @@ impl SecretKey {
     }
 
     pub fn public_key(&self) -> PublicKey {
-        PublicKey(derive_publickey(self.0))
+        PublicKey(derive_public_key(self.0))
     }
 }
 

+ 2 - 2
src/crypto/spend_proof.rs

@@ -48,7 +48,7 @@ impl SpendRevealedValues {
         let nullifier =
             primitives::poseidon::Hash::init(P128Pow5T3, ConstantLength::<2>).hash(nullifier);
 
-        let public_key = derive_publickey(secret);
+        let public_key = derive_public_key(secret);
         let coords = public_key.to_affine().coordinates().unwrap();
         let messages = [
             [*coords.x(), *coords.y()],
@@ -66,7 +66,7 @@ impl SpendRevealedValues {
         let value_commit = pedersen_commitment_u64(value, value_blind);
         let token_commit = pedersen_commitment_scalar(mod_r_p(token_id), token_blind);
 
-        let signature_public = derive_publickey(signature_secret);
+        let signature_public = derive_public_key(signature_secret);
 
         SpendRevealedValues {
             value_commit,

+ 1 - 1
src/tx/builder.rs

@@ -62,7 +62,7 @@ impl TransactionBuilder {
         let mut clear_inputs = vec![];
         let token_blind = DrkValueBlind::random(&mut OsRng);
         for input in &self.clear_inputs {
-            let signature_public = derive_publickey(input.signature_secret);
+            let signature_public = derive_public_key(input.signature_secret);
             let value_blind = DrkValueBlind::random(&mut OsRng);
 
             let clear_input = PartialTransactionClearInput {

+ 1 - 1
src/types.rs

@@ -23,6 +23,6 @@ pub type DrkValueCommit = pasta::Ep;
 pub type DrkPublicKey = pasta::Ep;
 pub type DrkSecretKey = pasta::Fp;
 
-pub fn derive_publickey(s: DrkSecretKey) -> DrkPublicKey {
+pub fn derive_public_key(s: DrkSecretKey) -> DrkPublicKey {
     OrchardFixedBases::SpendAuthG.generator() * mod_r_p(s)
 }

+ 7 - 7
src/wallet/walletdb.rs

@@ -79,7 +79,7 @@ impl WalletDb {
 
         if !key_check {
             let secret = DrkSecretKey::random(&mut OsRng);
-            let public = derive_publickey(secret);
+            let public = derive_public_key(secret);
             self.put_keypair(&public, &secret)?;
             return Ok(());
         }
@@ -368,7 +368,7 @@ mod tests {
     use super::*;
     use crate::crypto::{
         coin::Coin,
-        types::{derive_publickey, CoinBlind, NullifierSerial, ValueCommitBlind},
+        types::{derive_public_key, CoinBlind, NullifierSerial, ValueCommitBlind},
         OwnCoin,
     };
     use crate::util::join_config_path;
@@ -398,7 +398,7 @@ mod tests {
         init_db(&walletdb_path, password)?;
 
         let secret = DrkSecretKey::random(&mut OsRng);
-        let public = secret.derive_publickey();
+        let public = secret.derive_public_key();
 
         wallet.put_keypair(&public, &secret)?;
 
@@ -456,7 +456,7 @@ mod tests {
         init_db(&walletdb_path, password)?;
 
         let secret = DrkSecretKey::random(&mut OsRng);
-        let public = secret.derive_publickey();
+        let public = secret.derive_public_key();
 
         wallet.put_keypair(&public, &secret)?;
 
@@ -511,7 +511,7 @@ mod tests {
         init_db(&walletdb_path, password)?;
 
         let secret = DrkSecretKey::random(&mut OsRng);
-        let public = secret.derive_publickey();
+        let public = secret.derive_public_key();
 
         wallet.put_keypair(&public, &secret)?;
 
@@ -533,7 +533,7 @@ mod tests {
         init_db(&walletdb_path, password)?;
 
         let secret = DrkSecretKey::random(&mut OsRng);
-        let public = secret.derive_publickey();
+        let public = secret.derive_public_key();
 
         wallet.put_keypair(&public, &secret)?;
 
@@ -604,7 +604,7 @@ mod tests {
         init_db(&walletdb_path, password)?;
 
         let secret = DrkSecretKey::random(&mut OsRng);
-        let public = secret.derive_publickey();
+        let public = secret.derive_public_key();
 
         wallet.put_keypair(&public, &secret)?;