Bladeren bron

[consensus/rcpt] encrypted TxRcpt of transfer Tx

mohab metwally 3 jaren geleden
bovenliggende
commit
93f06ea754
4 gewijzigde bestanden met toevoegingen van 102 en 18 verwijderingen
  1. 4 18
      src/consensus/leadcoin.rs
  2. 4 0
      src/consensus/mod.rs
  3. 94 0
      src/consensus/rcpt.rs
  4. 0 0
      src/consensus/tx.rs

+ 4 - 18
src/consensus/leadcoin.rs

@@ -32,6 +32,7 @@ use rand::rngs::OsRng;
 
 use super::constants::{EPOCH_LENGTH};
 use crate::{
+    consensus::{TxRcpt,EncryptedTxRcpt},
     crypto::{proof::ProvingKey, Proof},
     zk::{vm::ZkCircuit, vm_stack::Witness},
     zkas::ZkBinary,
@@ -62,21 +63,6 @@ pub struct TransferStx {
     pub proof: Proof,
 }
 
-/// transfered leadcoin is poured into two coins,
-/// first coin is transfered poured coin.
-/// second coin is the change returning to sender, or different address.
-#[derive(Debug, Clone, Copy)]
-pub struct PouredCoin {
-    /// poured coin public key
-    pub pk: pallas::Base,
-    /// poured coin nonce
-    pub rho: pallas::Base,
-    /// poured coin commitment opening
-    pub opening: pallas::Scalar,
-    /// poured coin value
-    pub value: u64,
-}
-
 // TODO: Unify item names with the names in the ZK proof (those are more descriptive)
 /// Structure representing the consensus leader coin
 #[derive(Debug, Clone, Copy)]
@@ -85,7 +71,7 @@ pub struct LeadCoin {
     pub value: u64,
     /// Commitment for coin1
     pub coin1_commitment: pallas::Point,
-    /// Commitment for coin2 (poured coin)
+    /// Commitment for coin2 (rcpt coin)
     pub coin2_commitment: pallas::Point,
     /// Coin index
     pub idx: u32,
@@ -395,8 +381,8 @@ impl LeadCoin {
 
     pub fn create_xfer_proof(&self,
                              pk: &ProvingKey,
-                             change_coin: PouredCoin,
-                             transfered_coin: PouredCoin) -> Result<TransferStx> {
+                             change_coin: TxRcpt,
+                             transfered_coin: TxRcpt) -> Result<TransferStx> {
         assert!(change_coin.value+transfered_coin.value==self.value
                 && self.value>0);
         let bincode = include_bytes!("../../proof/tx.zk.bin");

+ 4 - 0
src/consensus/mod.rs

@@ -53,3 +53,7 @@ pub mod utils;
 
 /// Wallet functions
 pub mod wallet;
+
+/// received transaction.
+pub mod rcpt;
+pub use rcpt::{TxRcpt,EncryptedTxRcpt};

+ 94 - 0
src/consensus/rcpt.rs

@@ -0,0 +1,94 @@
+use darkfi_sdk::{
+    crypto::{
+        diffie_hellman::{kdf_sapling, sapling_ka_agree},
+        pedersen::{pedersen_commitment_base, pedersen_commitment_u64},
+        poseidon_hash,
+        util::mod_r_p,
+        MerkleNode, SecretKey,
+    },
+    pasta::{arithmetic::CurveAffine, group::Curve, pallas},
+
+
+};
+use halo2_proofs::{arithmetic::Field, circuit::Value};
+use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
+use log::debug;
+use rand::rngs::OsRng;
+
+use super::constants::{EPOCH_LENGTH};
+use crate::{
+    crypto::{proof::ProvingKey, Proof},
+    zk::{vm::ZkCircuit, vm_stack::Witness},
+    zkas::ZkBinary,
+    serial::darkfi_derive::{SerialDecodable, SerialEncodable};
+    Result,
+};
+use crypto_api_chachapoly::ChachaPolyIetf;
+
+
+/// transfered leadcoin is rcpt into two coins,
+/// first coin is transfered rcpt coin.
+/// second coin is the change returning to sender, or different address.
+#[derive(Debug, Clone, Copy, Eq, PartialEq, SerialEncodable, SerialDecodable)]
+pub struct TxRcpt {
+    /// rcpt coin public key
+    pub pk: pallas::Base,
+    /// rcpt coin nonce
+    pub rho: pallas::Base,
+    /// rcpt coin commitment opening
+    pub opening: pallas::Scalar,
+    /// rcpt coin value
+    pub value: u64,
+}
+
+
+pub const PLAINTEXT_SIZE: usize = 32 + 32 + 32 + 8;
+pub const AEAD_TAG_SIZE: usize = 16;
+pub const CIPHER_SIZE: usize = PLAINTEXT_SIZE + AEAD_TAG_SIZE;
+
+impl TxRcpt {
+    /// encrypt received coin, by recipient public key
+    pub fn encrypt(&self, public: &PublicKey) -> EncryptedTxRcpt {
+        let ephem_secret = SecretKey::random(&mut OsRng);
+        let ephem_public = PublicKey::from_secret(ephem_secret);
+        let shared_secret = sapling_ka_agree(&ephem_secret, public);
+        let key = kdf_sapling(&shared_secret, &ephem_public);
+
+        let mut input = Vec::new();
+        self.encode(&mut input)?;
+
+        let mut ciphertext = [0u8; CIPHER_SIZE];
+        assert_eq!(
+            ChachaPolyIetf::aead_cipher()
+                .seal_to(&mut ciphertext, &input, &[], key.as_ref(), &[0u8; 12])
+                .unwrap(),
+            CIPHER_SIZE
+        );
+
+        Ok(EncryptedTxRcpt { ciphertext, ephem_public })
+    }
+}
+
+
+#[derive(Debug, Clone, PartialEq, SerialEncodable, SerialDecodable)]
+pub struct EncryptedTxRcpt {
+    ciphertext: [u8; CIPHER_SIZE],
+    ephem_public: PublicKey,
+}
+
+impl EncryptedTxRcpt {
+    pub fn decrypt(&self, secret: &SecretKey) -> Result<TxRcpt> {
+        let shared_secret = sapling_ka_agree(secret, &self.ephem_public);
+        let key = kdf_sapling(&shared_secret, &self.ephem_public);
+
+        let mut plaintext = [0; CIPHER_SIZE];
+        assert_eq!(
+            ChachaPolyIetf::aead_cipher()
+                .open_to(&mut plaintext, &self.ciphertext, &[], key.as_ref(), &[0u8; 12])
+                .map_err(|_| Error::NoteDecryptionFailed)?,
+            PLAINTEXT_SIZE
+        );
+
+        TxRcpt::decode(&plaintext[..])
+    }
+}

+ 0 - 0
src/consensus/tx.rs