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

contract/money: Remove NullifierAttributes and use the OwnCoin API

parazyd 2 лет назад
Родитель
Сommit
2a49b2d79e

+ 26 - 27
src/contract/money/src/client/fee_v1.rs

@@ -22,7 +22,7 @@ use darkfi::{
     Result,
 };
 use darkfi_sdk::{
-    bridgetree::{self, Hashable},
+    bridgetree::Hashable,
     crypto::{
         pasta_prelude::{Curve, CurveAffine},
         pedersen_commitment_u64, poseidon_hash, BaseBlind, FuncId, MerkleNode, PublicKey,
@@ -33,8 +33,8 @@ use darkfi_sdk::{
 use rand::rngs::OsRng;
 
 use crate::{
-    client::{Coin, MoneyNote},
-    model::{CoinAttributes, Nullifier, NullifierAttributes},
+    client::{Coin, MoneyNote, OwnCoin},
+    model::{CoinAttributes, Nullifier},
 };
 
 /// Fixed gas used by the fee call.
@@ -102,10 +102,11 @@ impl FeeRevealed {
 }
 
 pub struct FeeCallInput {
-    pub leaf_position: bridgetree::Position,
+    /// The [`OwnCoin`] containing necessary metadata to create an input
+    pub coin: OwnCoin,
+    /// Merkle path in the Money Merkle tree for `coin`
     pub merkle_path: Vec<MerkleNode>,
-    pub secret: SecretKey,
-    pub note: MoneyNote,
+    /// The blinding factor for user_data
     pub user_data_blind: BaseBlind,
 }
 
@@ -126,25 +127,22 @@ pub fn create_fee_proof(
     token_blind: BaseBlind,
     signature_secret: SecretKey,
 ) -> Result<(Proof, FeeRevealed)> {
-    let public_key = PublicKey::from_secret(input.secret);
+    let public_key = PublicKey::from_secret(input.coin.secret);
     let signature_public = PublicKey::from_secret(signature_secret);
 
     // Create input coin
     let input_coin = CoinAttributes {
         public_key,
-        value: input.note.value,
-        token_id: input.note.token_id,
-        spend_hook: input.note.spend_hook,
-        user_data: input.note.user_data,
-        blind: input.note.coin_blind,
+        value: input.coin.note.value,
+        token_id: input.coin.note.token_id,
+        spend_hook: input.coin.note.spend_hook,
+        user_data: input.coin.note.user_data,
+        blind: input.coin.note.coin_blind,
     }
     .to_coin();
 
-    let nullifier =
-        NullifierAttributes { secret_key: input.secret, coin: input_coin }.to_nullifier();
-
     let merkle_root = {
-        let position: u64 = input.leaf_position.into();
+        let position: u64 = input.coin.leaf_position.into();
         let mut current = MerkleNode::from(input_coin.inner());
         for (level, sibling) in input.merkle_path.iter().enumerate() {
             let level = level as u8;
@@ -157,10 +155,11 @@ pub fn create_fee_proof(
         current
     };
 
-    let input_user_data_enc = poseidon_hash([input.note.user_data, input.user_data_blind.inner()]);
-    let input_value_commit = pedersen_commitment_u64(input.note.value, input_value_blind);
+    let input_user_data_enc =
+        poseidon_hash([input.coin.note.user_data, input.user_data_blind.inner()]);
+    let input_value_commit = pedersen_commitment_u64(input.coin.note.value, input_value_blind);
     let output_value_commit = pedersen_commitment_u64(output.value, output_value_blind);
-    let token_commit = poseidon_hash([input.note.token_id.inner(), token_blind.inner()]);
+    let token_commit = poseidon_hash([input.coin.note.token_id.inner(), token_blind.inner()]);
 
     // Create output coin
     let output_coin = CoinAttributes {
@@ -174,7 +173,7 @@ pub fn create_fee_proof(
     .to_coin();
 
     let public_inputs = FeeRevealed {
-        nullifier,
+        nullifier: input.coin.nullifier(),
         input_value_commit,
         token_commit,
         merkle_root,
@@ -185,22 +184,22 @@ pub fn create_fee_proof(
     };
 
     let prover_witnesses = vec![
-        Witness::Base(Value::known(input.secret.inner())),
-        Witness::Uint32(Value::known(u64::from(input.leaf_position).try_into().unwrap())),
+        Witness::Base(Value::known(input.coin.secret.inner())),
+        Witness::Uint32(Value::known(u64::from(input.coin.leaf_position).try_into().unwrap())),
         Witness::MerklePath(Value::known(input.merkle_path.clone().try_into().unwrap())),
         Witness::Base(Value::known(signature_secret.inner())),
-        Witness::Base(Value::known(pallas::Base::from(input.note.value))),
+        Witness::Base(Value::known(pallas::Base::from(input.coin.note.value))),
         Witness::Scalar(Value::known(input_value_blind.inner())),
-        Witness::Base(Value::known(input.note.spend_hook.inner())),
-        Witness::Base(Value::known(input.note.user_data)),
-        Witness::Base(Value::known(input.note.coin_blind.inner())),
+        Witness::Base(Value::known(input.coin.note.spend_hook.inner())),
+        Witness::Base(Value::known(input.coin.note.user_data)),
+        Witness::Base(Value::known(input.coin.note.coin_blind.inner())),
         Witness::Base(Value::known(input.user_data_blind.inner())),
         Witness::Base(Value::known(pallas::Base::from(output.value))),
         Witness::Base(Value::known(output_spend_hook.inner())),
         Witness::Base(Value::known(output_user_data)),
         Witness::Scalar(Value::known(output_value_blind.inner())),
         Witness::Base(Value::known(output_coin_blind.inner())),
-        Witness::Base(Value::known(input.note.token_id.inner())),
+        Witness::Base(Value::known(input.coin.note.token_id.inner())),
         Witness::Base(Value::known(token_blind.inner())),
     ];
 

+ 2 - 7
src/contract/money/src/client/swap_v1.rs

@@ -108,14 +108,9 @@ impl SwapCallBuilder {
             return Err(ClientFailed::InvalidTokenId(self.coin.note.token_id.to_string()).into())
         }
 
-        let leaf_position = self.coin.leaf_position;
-        let merkle_path = self.tree.witness(leaf_position, 0).unwrap();
-
         let input = TransferCallInput {
-            leaf_position,
-            merkle_path,
-            secret: self.coin.secret,
-            note: self.coin.note.clone(),
+            coin: self.coin.clone(),
+            merkle_path: self.tree.witness(self.coin.leaf_position, 0).unwrap(),
             user_data_blind: self.user_data_blind_send,
         };
 

+ 3 - 4
src/contract/money/src/client/transfer_v1/builder.rs

@@ -21,7 +21,6 @@ use darkfi::{
     Result,
 };
 use darkfi_sdk::{
-    bridgetree,
     crypto::{
         note::AeadEncryptedNote, pasta_prelude::*, BaseBlind, Blind, MerkleNode, ScalarBlind,
         SecretKey,
@@ -62,10 +61,10 @@ pub struct TransferCallClearInput {
 }
 
 pub struct TransferCallInput {
-    pub leaf_position: bridgetree::Position,
+    /// The [`OwnCoin`] containing necessary metadata to create an input
+    pub coin: OwnCoin,
+    /// Merkle path in the Money Merkle tree for `coin`
     pub merkle_path: Vec<MerkleNode>,
-    pub secret: SecretKey,
-    pub note: MoneyNote,
     // In the DAO all inputs must have the same user_data_enc and use the same blind
     // So support allowing the user to set their own blind.
     pub user_data_blind: BaseBlind,

+ 2 - 7
src/contract/money/src/client/transfer_v1/mod.rs

@@ -110,14 +110,9 @@ pub fn make_transfer_call(
     let (spent_coins, change_value) = select_coins(coins, value)?;
 
     for coin in spent_coins.iter() {
-        let leaf_position = coin.leaf_position;
-        let merkle_path = tree.witness(leaf_position, 0).unwrap();
-
         let input = TransferCallInput {
-            leaf_position,
-            merkle_path,
-            secret: coin.secret,
-            note: coin.note.clone(),
+            coin: coin.clone(),
+            merkle_path: tree.witness(coin.leaf_position, 0).unwrap(),
             user_data_blind: Blind::random(&mut OsRng),
         };
 

+ 20 - 22
src/contract/money/src/client/transfer_v1/proof.rs

@@ -33,7 +33,7 @@ use log::debug;
 use rand::rngs::OsRng;
 
 use super::{TransferCallInput, TransferCallOutput};
-use crate::model::{Coin, CoinAttributes, Nullifier, NullifierAttributes};
+use crate::model::{Coin, CoinAttributes, Nullifier};
 
 pub struct TransferMintRevealed {
     pub coin: Coin,
@@ -89,23 +89,21 @@ pub fn create_transfer_burn_proof(
     token_blind: BaseBlind,
     signature_secret: SecretKey,
 ) -> Result<(Proof, TransferBurnRevealed)> {
-    let public_key = PublicKey::from_secret(input.secret);
+    let public_key = PublicKey::from_secret(input.coin.secret);
     let signature_public = PublicKey::from_secret(signature_secret);
 
     let coin = CoinAttributes {
         public_key,
-        value: input.note.value,
-        token_id: input.note.token_id,
-        spend_hook: input.note.spend_hook,
-        user_data: input.note.user_data,
-        blind: input.note.coin_blind,
+        value: input.coin.note.value,
+        token_id: input.coin.note.token_id,
+        spend_hook: input.coin.note.spend_hook,
+        user_data: input.coin.note.user_data,
+        blind: input.coin.note.coin_blind,
     }
     .to_coin();
 
-    let nullifier = NullifierAttributes { secret_key: input.secret, coin }.to_nullifier();
-
     let merkle_root = {
-        let position: u64 = input.leaf_position.into();
+        let position: u64 = input.coin.leaf_position.into();
         let mut current = MerkleNode::from(coin.inner());
         for (level, sibling) in input.merkle_path.iter().enumerate() {
             let level = level as u8;
@@ -118,31 +116,31 @@ pub fn create_transfer_burn_proof(
         current
     };
 
-    let user_data_enc = poseidon_hash([input.note.user_data, input.user_data_blind.inner()]);
-    let value_commit = pedersen_commitment_u64(input.note.value, value_blind);
-    let token_commit = poseidon_hash([input.note.token_id.inner(), token_blind.inner()]);
+    let user_data_enc = poseidon_hash([input.coin.note.user_data, input.user_data_blind.inner()]);
+    let value_commit = pedersen_commitment_u64(input.coin.note.value, value_blind);
+    let token_commit = poseidon_hash([input.coin.note.token_id.inner(), token_blind.inner()]);
 
     let public_inputs = TransferBurnRevealed {
         value_commit,
         token_commit,
-        nullifier,
+        nullifier: input.coin.nullifier(),
         merkle_root,
-        spend_hook: input.note.spend_hook,
+        spend_hook: input.coin.note.spend_hook,
         user_data_enc,
         signature_public,
     };
 
     let prover_witnesses = vec![
-        Witness::Base(Value::known(input.secret.inner())),
-        Witness::Base(Value::known(pallas::Base::from(input.note.value))),
-        Witness::Base(Value::known(input.note.token_id.inner())),
-        Witness::Base(Value::known(input.note.spend_hook.inner())),
-        Witness::Base(Value::known(input.note.user_data)),
-        Witness::Base(Value::known(input.note.coin_blind.inner())),
+        Witness::Base(Value::known(input.coin.secret.inner())),
+        Witness::Base(Value::known(pallas::Base::from(input.coin.note.value))),
+        Witness::Base(Value::known(input.coin.note.token_id.inner())),
+        Witness::Base(Value::known(input.coin.note.spend_hook.inner())),
+        Witness::Base(Value::known(input.coin.note.user_data)),
+        Witness::Base(Value::known(input.coin.note.coin_blind.inner())),
         Witness::Scalar(Value::known(value_blind.inner())),
         Witness::Base(Value::known(token_blind.inner())),
         Witness::Base(Value::known(input.user_data_blind.inner())),
-        Witness::Uint32(Value::known(u64::from(input.leaf_position).try_into().unwrap())),
+        Witness::Uint32(Value::known(u64::from(input.coin.leaf_position).try_into().unwrap())),
         Witness::MerklePath(Value::known(input.merkle_path.clone().try_into().unwrap())),
         Witness::Base(Value::known(signature_secret.inner())),
     ];

+ 0 - 16
src/contract/money/src/model/mod.rs

@@ -113,22 +113,6 @@ impl TokenAttributes {
     }
 }
 
-#[derive(Debug, Clone, SerialEncodable, SerialDecodable)]
-pub struct NullifierAttributes {
-    /// Secret key for the public key in the coin.
-    /// We need some secret info to avoid revealing which coin this
-    /// nullifier is connected to. We use the secret key for that.
-    pub secret_key: SecretKey,
-    /// The corresponding coin being spent.
-    pub coin: Coin,
-}
-
-impl NullifierAttributes {
-    pub fn to_nullifier(&self) -> Nullifier {
-        Nullifier::from(poseidon_hash([self.secret_key.inner(), self.coin.inner()]))
-    }
-}
-
 #[derive(Clone, Debug, SerialEncodable, SerialDecodable)]
 // ANCHOR: money-clear-input
 /// A contract call's clear input

+ 2 - 7
src/contract/test-harness/src/dao_exec.rs

@@ -97,14 +97,9 @@ impl TestHarness {
 
         let mut inputs = vec![];
         for coin in &spent_coins {
-            let leaf_position = coin.leaf_position;
-            let merkle_path = tree.witness(leaf_position, 0).unwrap();
-
             inputs.push(xfer::TransferCallInput {
-                leaf_position,
-                merkle_path,
-                secret: coin.secret,
-                note: coin.note.clone(),
+                coin: coin.clone(),
+                merkle_path: tree.witness(coin.leaf_position, 0).unwrap(),
                 user_data_blind: input_user_data_blind,
             });
         }

+ 2 - 6
src/contract/test-harness/src/money_fee.rs

@@ -65,10 +65,8 @@ impl TestHarness {
 
         // Input and output setup
         let input = FeeCallInput {
-            leaf_position: coin.leaf_position,
+            coin: coin.clone(),
             merkle_path: wallet.money_merkle_tree.witness(coin.leaf_position, 0).unwrap(),
-            secret: coin.secret,
-            note: coin.note.clone(),
             user_data_blind: Blind::random(&mut OsRng),
         };
 
@@ -230,10 +228,8 @@ impl TestHarness {
 
         // Input and output setup
         let input = FeeCallInput {
-            leaf_position: coin.leaf_position,
+            coin: coin.clone(),
             merkle_path: wallet.money_merkle_tree.witness(coin.leaf_position, 0).unwrap(),
-            secret: coin.secret,
-            note: coin.note.clone(),
             user_data_blind: BaseBlind::random(&mut OsRng),
         };