From 2094274851b03add1588026bc9ee1037a3a64491 Mon Sep 17 00:00:00 2001 From: zero Date: Thu, 8 Feb 2024 15:24:07 +0100 Subject: [PATCH] add a Blind type to the SDK, which is used in all bullas as the explicit blinding factor. --- bin/drk/src/dao.rs | 26 ++++---- bin/drk/src/money.rs | 10 +-- bin/drk/src/swap.rs | 28 ++++---- bin/drk/src/token.rs | 5 +- src/contract/dao/src/client/auth_xfer.rs | 25 +++---- src/contract/dao/src/client/exec.rs | 20 +++--- src/contract/dao/src/client/mint.rs | 2 +- src/contract/dao/src/client/propose.rs | 26 ++++---- src/contract/dao/src/client/vote.rs | 25 +++---- src/contract/dao/src/model.rs | 10 +-- src/contract/dao/tests/integration.rs | 14 ++-- .../money/src/client/auth_token_mint_v1.rs | 12 ++-- src/contract/money/src/client/fee_v1.rs | 46 ++++++------- .../money/src/client/genesis_mint_v1.rs | 10 +-- src/contract/money/src/client/mod.rs | 22 +++---- .../money/src/client/pow_reward_v1.rs | 11 ++-- src/contract/money/src/client/swap_v1.rs | 15 +++-- .../money/src/client/token_freeze_v1.rs | 2 +- .../money/src/client/token_mint_v1.rs | 4 +- .../money/src/client/transfer_v1/builder.rs | 19 +++--- .../money/src/client/transfer_v1/mod.rs | 8 +-- .../money/src/client/transfer_v1/proof.rs | 34 +++++----- src/contract/money/src/entrypoint/fee_v1.rs | 2 +- .../money/src/entrypoint/genesis_mint_v1.rs | 2 +- .../money/src/entrypoint/pow_reward_v1.rs | 2 +- .../money/src/entrypoint/transfer_v1.rs | 2 +- src/contract/money/src/model/mod.rs | 21 +++--- src/contract/test-harness/src/dao_exec.rs | 15 ++--- src/contract/test-harness/src/dao_propose.rs | 4 +- src/contract/test-harness/src/lib.rs | 14 ++-- .../test-harness/src/money_airdrop.rs | 4 +- .../test-harness/src/money_otc_swap.rs | 14 ++-- src/contract/test-harness/src/money_token.rs | 4 +- src/sdk/python/src/crypto.rs | 4 +- src/sdk/src/crypto/blind.rs | 66 +++++++++++++++++++ src/sdk/src/crypto/mod.rs | 4 ++ src/sdk/src/crypto/pedersen.rs | 9 +-- tests/halo2_vk_ser.rs | 6 +- tests/zkvm_opcodes.rs | 6 +- 39 files changed, 318 insertions(+), 235 deletions(-) create mode 100644 src/sdk/src/crypto/blind.rs diff --git a/bin/drk/src/dao.rs b/bin/drk/src/dao.rs index 2d29b469b..99298ddb6 100644 --- a/bin/drk/src/dao.rs +++ b/bin/drk/src/dao.rs @@ -42,8 +42,8 @@ use darkfi_sdk::{ crypto::{ poseidon_hash, util::{fp_mod_fv, fp_to_u64}, - FuncId, FuncRef, Keypair, MerkleNode, MerkleTree, PublicKey, SecretKey, DAO_CONTRACT_ID, - MONEY_CONTRACT_ID, + BaseBlind, Blind, FuncId, FuncRef, Keypair, MerkleNode, MerkleTree, PublicKey, ScalarBlind, + SecretKey, DAO_CONTRACT_ID, MONEY_CONTRACT_ID, }, pasta::pallas, ContractCall, @@ -120,7 +120,7 @@ pub struct DaoProposalInfo { pub dest: PublicKey, pub amount: u64, pub token_id: TokenId, - pub blind: pallas::Base, + pub blind: BaseBlind, } #[derive(SerialEncodable, SerialDecodable)] @@ -193,7 +193,7 @@ pub struct Dao { /// Secret key for the DAO pub secret_key: SecretKey, /// DAO bulla blind - pub bulla_blind: pallas::Base, + pub bulla_blind: BaseBlind, /// Leaf position of the DAO in the Merkle tree of DAOs pub leaf_position: Option, /// The transaction hash where the DAO was deployed @@ -214,7 +214,7 @@ impl Dao { self.gov_token_id.inner(), x, y, - self.bulla_blind, + self.bulla_blind.inner(), ])) } @@ -276,7 +276,7 @@ pub struct DaoProposal { /// Token ID to be sent pub token_id: TokenId, /// Proposal's bulla blind - pub bulla_blind: pallas::Base, + pub bulla_blind: BaseBlind, /// Leaf position of this proposal in the Merkle tree of proposals pub leaf_position: Option, /// Snapshotted Money Merkle tree @@ -299,7 +299,7 @@ impl DaoProposal { pallas::Base::from(self.amount), self.token_id.inner(), self.dao_bulla.inner(), - self.bulla_blind, + self.bulla_blind.inner(), ]) } } @@ -346,11 +346,11 @@ pub struct DaoVote { /// The vote pub vote_option: bool, /// Blinding factor for the yes vote - pub yes_vote_blind: pallas::Scalar, + pub yes_vote_blind: ScalarBlind, /// Value of all votes pub all_vote_value: u64, /// Blinding facfor of all votes - pub all_vote_blind: pallas::Scalar, + pub all_vote_blind: ScalarBlind, /// Transaction hash where this vote was casted pub tx_hash: Option, /// call index in the transaction where this vote was casted @@ -819,9 +819,9 @@ impl Drk { let vote_option = fp_to_u64(note[0]).unwrap(); assert!(vote_option == 0 || vote_option == 1); let vote_option = vote_option != 0; - let yes_vote_blind = fp_mod_fv(note[1]); + let yes_vote_blind = Blind(fp_mod_fv(note[1])); let all_vote_value = fp_to_u64(note[2]).unwrap(); - let all_vote_blind = fp_mod_fv(note[3]); + let all_vote_blind = Blind(fp_mod_fv(note[3])); let v = DaoVote { id: 0, @@ -1545,7 +1545,7 @@ impl Drk { duration_days: 30, user_data: pallas::Base::ZERO, dao_bulla: dao.bulla(), - blind: pallas::Base::random(&mut OsRng), + blind: Blind::random(&mut OsRng), }; // TODO: Simplify this model struct import once @@ -1658,7 +1658,7 @@ impl Drk { duration_days: 30, user_data: pallas::Base::ZERO, dao_bulla: dao.bulla(), - blind: pallas::Base::random(&mut OsRng), + blind: Blind::random(&mut OsRng), }; // TODO: Simplify this model struct import once diff --git a/bin/drk/src/money.rs b/bin/drk/src/money.rs index f04aa30b1..e55595a21 100644 --- a/bin/drk/src/money.rs +++ b/bin/drk/src/money.rs @@ -34,8 +34,8 @@ use darkfi_money_contract::{ use darkfi_sdk::{ bridgetree, crypto::{ - note::AeadEncryptedNote, poseidon_hash, FuncId, Keypair, MerkleNode, MerkleTree, PublicKey, - SecretKey, MONEY_CONTRACT_ID, + note::AeadEncryptedNote, poseidon_hash, BaseBlind, FuncId, Keypair, MerkleNode, MerkleTree, + PublicKey, ScalarBlind, SecretKey, MONEY_CONTRACT_ID, }, pasta::pallas, }; @@ -436,17 +436,17 @@ impl Drk { let Value::Blob(ref coin_blind_bytes) = row[6] else { return Err(Error::ParseFailed("[get_coins] Coin blind bytes parsing failed")) }; - let coin_blind: pallas::Base = deserialize(coin_blind_bytes)?; + let coin_blind: BaseBlind = deserialize(coin_blind_bytes)?; let Value::Blob(ref value_blind_bytes) = row[7] else { return Err(Error::ParseFailed("[get_coins] Value blind bytes parsing failed")) }; - let value_blind: pallas::Scalar = deserialize(value_blind_bytes)?; + let value_blind: ScalarBlind = deserialize(value_blind_bytes)?; let Value::Blob(ref token_blind_bytes) = row[8] else { return Err(Error::ParseFailed("[get_coins] Token blind bytes parsing failed")) }; - let token_blind: pallas::Base = deserialize(token_blind_bytes)?; + let token_blind: BaseBlind = deserialize(token_blind_bytes)?; let Value::Blob(ref secret_bytes) = row[9] else { return Err(Error::ParseFailed("[get_coins] Secret bytes parsing failed")) diff --git a/bin/drk/src/swap.rs b/bin/drk/src/swap.rs index 023cab0b2..e343a7cb9 100644 --- a/bin/drk/src/swap.rs +++ b/bin/drk/src/swap.rs @@ -33,8 +33,8 @@ use darkfi_money_contract::{ }; use darkfi_sdk::{ crypto::{ - contract_id::MONEY_CONTRACT_ID, pedersen::pedersen_commitment_u64, poseidon_hash, FuncId, - PublicKey, SecretKey, + contract_id::MONEY_CONTRACT_ID, pedersen::pedersen_commitment_u64, poseidon_hash, + BaseBlind, Blind, FuncId, PublicKey, ScalarBlind, SecretKey, }, pasta::pallas, tx::ContractCall, @@ -51,8 +51,8 @@ pub struct PartialSwapData { proofs: Vec, value_pair: (u64, u64), token_pair: (TokenId, TokenId), - value_blinds: Vec, - token_blinds: Vec, + value_blinds: Vec, + token_blinds: Vec, } impl fmt::Display for PartialSwapData { @@ -125,8 +125,8 @@ impl Drk { let burn_circuit = ZkCircuit::new(empty_witnesses(&burn_zkbin)?, &burn_zkbin); // Since we're creating the first half, we generate the blinds. - let value_blinds = [pallas::Scalar::random(&mut OsRng), pallas::Scalar::random(&mut OsRng)]; - let token_blinds = [pallas::Base::random(&mut OsRng), pallas::Base::random(&mut OsRng)]; + let value_blinds = [Blind::random(&mut OsRng), Blind::random(&mut OsRng)]; + let token_blinds = [Blind::random(&mut OsRng), Blind::random(&mut OsRng)]; // Now we should have everything we need to build the swap half eprintln!("Creating Mint and Burn circuit proving keys"); @@ -138,9 +138,9 @@ impl Drk { token_id_send: token_send, value_recv, token_id_recv: token_recv, - user_data_blind_send: pallas::Base::random(&mut OsRng), // <-- FIXME: Perhaps should be passed in - spend_hook_recv: FuncId::none(), // <-- FIXME: Should be passed in - user_data_recv: pallas::Base::zero(), // <-- FIXME: Should be passed in + user_data_blind_send: Blind::random(&mut OsRng), // <-- FIXME: Perhaps should be passed in + spend_hook_recv: FuncId::none(), // <-- FIXME: Should be passed in + user_data_recv: pallas::Base::ZERO, // <-- FIXME: Should be passed in value_blinds, token_blinds, coin: burn_coin, @@ -228,9 +228,9 @@ impl Drk { token_id_send: partial.token_pair.1, value_recv: partial.value_pair.0, token_id_recv: partial.token_pair.0, - user_data_blind_send: pallas::Base::random(&mut OsRng), // <-- FIXME: Perhaps should be passed in - spend_hook_recv: FuncId::none(), // <-- FIXME: Should be passed in - user_data_recv: pallas::Base::ZERO, // <-- FIXME: Should be passed in + user_data_blind_send: Blind::random(&mut OsRng), // <-- FIXME: Perhaps should be passed in + spend_hook_recv: FuncId::none(), // <-- FIXME: Should be passed in + user_data_recv: pallas::Base::ZERO, // <-- FIXME: Should be passed in value_blinds: [partial.value_blinds[1], partial.value_blinds[0]], token_blinds: [partial.token_blinds[1], partial.token_blinds[0]], coin: burn_coin, @@ -361,7 +361,7 @@ impl Drk { pub_y, pallas::Base::from(note.value), note.token_id.inner(), - note.coin_blind, + note.coin_blind.inner(), ])); if coin == params.outputs[output_idx].coin { @@ -372,7 +372,7 @@ impl Drk { } let valcom = pedersen_commitment_u64(note.value, note.value_blind); - let tokcom = poseidon_hash([note.token_id.inner(), note.token_blind]); + let tokcom = poseidon_hash([note.token_id.inner(), note.token_blind.inner()]); if valcom != params.outputs[output_idx].value_commit { eprintln!( diff --git a/bin/drk/src/token.rs b/bin/drk/src/token.rs index 399a39d6f..6e741feef 100644 --- a/bin/drk/src/token.rs +++ b/bin/drk/src/token.rs @@ -37,8 +37,7 @@ use darkfi_money_contract::{ }; use darkfi_sdk::{ crypto::{ - contract_id::MONEY_CONTRACT_ID, pasta_prelude::*, FuncId, FuncRef, Keypair, PublicKey, - SecretKey, + contract_id::MONEY_CONTRACT_ID, Blind, FuncId, FuncRef, Keypair, PublicKey, SecretKey, }, dark_tree::DarkLeaf, pasta::pallas, @@ -225,7 +224,7 @@ impl Drk { token_id, spend_hook, user_data, - blind: pallas::Base::random(&mut OsRng), + blind: Blind::random(&mut OsRng), }; let builder = TokenMintCallBuilder { diff --git a/src/contract/dao/src/client/auth_xfer.rs b/src/contract/dao/src/client/auth_xfer.rs index bf81162b8..ef09e627f 100644 --- a/src/contract/dao/src/client/auth_xfer.rs +++ b/src/contract/dao/src/client/auth_xfer.rs @@ -18,7 +18,7 @@ use darkfi_money_contract::model::CoinAttributes; use darkfi_sdk::{ - crypto::{note::ElGamalEncryptedNote, poseidon_hash, PublicKey, SecretKey}, + crypto::{note::ElGamalEncryptedNote, poseidon_hash, BaseBlind, PublicKey, SecretKey}, pasta::pallas, }; @@ -36,7 +36,7 @@ pub struct DaoAuthMoneyTransferCall { pub proposal: DaoProposal, pub proposal_coinattrs: Vec, pub dao: Dao, - pub input_user_data_blind: pallas::Base, + pub input_user_data_blind: BaseBlind, pub dao_coin_attrs: CoinAttributes, } @@ -69,7 +69,7 @@ impl DaoAuthMoneyTransferCall { coin_attrs.token_id.inner(), coin_attrs.spend_hook.inner(), coin_attrs.user_data, - coin_attrs.blind, + coin_attrs.blind.inner(), ]; let enc_note = ElGamalEncryptedNote::encrypt(note, &ephem_secret, &coin_attrs.public_key); @@ -80,7 +80,7 @@ impl DaoAuthMoneyTransferCall { Witness::Base(Value::known(coin_attrs.token_id.inner())), Witness::Base(Value::known(coin_attrs.spend_hook.inner())), Witness::Base(Value::known(coin_attrs.user_data)), - Witness::Base(Value::known(coin_attrs.blind)), + Witness::Base(Value::known(coin_attrs.blind.inner())), Witness::Base(Value::known(ephem_secret.inner())), ]; @@ -112,8 +112,11 @@ impl DaoAuthMoneyTransferCall { let dao_public_key = self.dao.public_key.inner(); let dao_change_value = pallas::Base::from(self.dao_coin_attrs.value); - let note = - [dao_change_value, self.dao_coin_attrs.token_id.inner(), self.dao_coin_attrs.blind]; + let note = [ + dao_change_value, + self.dao_coin_attrs.token_id.inner(), + self.dao_coin_attrs.blind.inner(), + ]; let dao_change_attrs = ElGamalEncryptedNote::encrypt(note, &ephem_secret, &self.dao.public_key); @@ -125,7 +128,7 @@ impl DaoAuthMoneyTransferCall { let dao_approval_ratio_base = pallas::Base::from(self.dao.approval_ratio_base); let input_user_data_enc = - poseidon_hash([self.dao.to_bulla().inner(), self.input_user_data_blind]); + poseidon_hash([self.dao.to_bulla().inner(), self.input_user_data_blind.inner()]); let prover_witnesses = vec![ // proposal params @@ -133,7 +136,7 @@ impl DaoAuthMoneyTransferCall { Witness::Base(Value::known(pallas::Base::from(self.proposal.creation_day))), Witness::Base(Value::known(pallas::Base::from(self.proposal.duration_days))), Witness::Base(Value::known(self.proposal.user_data)), - Witness::Base(Value::known(self.proposal.blind)), + Witness::Base(Value::known(self.proposal.blind.inner())), // DAO params Witness::Base(Value::known(dao_proposer_limit)), Witness::Base(Value::known(dao_quorum)), @@ -141,13 +144,13 @@ impl DaoAuthMoneyTransferCall { Witness::Base(Value::known(dao_approval_ratio_base)), Witness::Base(Value::known(self.dao.gov_token_id.inner())), Witness::EcNiPoint(Value::known(dao_public_key)), - Witness::Base(Value::known(self.dao.bulla_blind)), + Witness::Base(Value::known(self.dao.bulla_blind.inner())), // Dao input user data blind - Witness::Base(Value::known(self.input_user_data_blind)), + Witness::Base(Value::known(self.input_user_data_blind.inner())), // Dao output coin attrs Witness::Base(Value::known(dao_change_value)), Witness::Base(Value::known(self.dao_coin_attrs.token_id.inner())), - Witness::Base(Value::known(self.dao_coin_attrs.blind)), + Witness::Base(Value::known(self.dao_coin_attrs.blind.inner())), // DAO::exec() func ID Witness::Base(Value::known(self.dao_coin_attrs.spend_hook.inner())), // Encrypted change DAO output diff --git a/src/contract/dao/src/client/exec.rs b/src/contract/dao/src/client/exec.rs index e663d57ab..8fda3249d 100644 --- a/src/contract/dao/src/client/exec.rs +++ b/src/contract/dao/src/client/exec.rs @@ -17,7 +17,9 @@ */ use darkfi_sdk::{ - crypto::{pasta_prelude::*, pedersen_commitment_u64, PublicKey, SecretKey}, + crypto::{ + pasta_prelude::*, pedersen_commitment_u64, BaseBlind, PublicKey, ScalarBlind, SecretKey, + }, pasta::pallas, }; @@ -37,11 +39,11 @@ pub struct DaoExecCall { pub dao: Dao, pub yes_vote_value: u64, pub all_vote_value: u64, - pub yes_vote_blind: pallas::Scalar, - pub all_vote_blind: pallas::Scalar, + pub yes_vote_blind: ScalarBlind, + pub all_vote_blind: ScalarBlind, pub input_value: u64, - pub input_value_blind: pallas::Scalar, - pub input_user_data_blind: pallas::Base, + pub input_value_blind: ScalarBlind, + pub input_user_data_blind: BaseBlind, pub hook_dao_exec: pallas::Base, pub signature_secret: SecretKey, } @@ -82,7 +84,7 @@ impl DaoExecCall { Witness::Base(Value::known(pallas::Base::from(self.proposal.creation_day))), Witness::Base(Value::known(pallas::Base::from(self.proposal.duration_days))), Witness::Base(Value::known(self.proposal.user_data)), - Witness::Base(Value::known(self.proposal.blind)), + Witness::Base(Value::known(self.proposal.blind.inner())), // DAO params Witness::Base(Value::known(dao_proposer_limit)), Witness::Base(Value::known(dao_quorum)), @@ -91,12 +93,12 @@ impl DaoExecCall { Witness::Base(Value::known(self.dao.gov_token_id.inner())), Witness::Base(Value::known(dao_pub_x)), Witness::Base(Value::known(dao_pub_y)), - Witness::Base(Value::known(self.dao.bulla_blind)), + Witness::Base(Value::known(self.dao.bulla_blind.inner())), // votes Witness::Base(Value::known(pallas::Base::from(self.yes_vote_value))), Witness::Base(Value::known(pallas::Base::from(self.all_vote_value))), - Witness::Scalar(Value::known(self.yes_vote_blind)), - Witness::Scalar(Value::known(self.all_vote_blind)), + Witness::Scalar(Value::known(self.yes_vote_blind.inner())), + Witness::Scalar(Value::known(self.all_vote_blind.inner())), // signature secret Witness::Base(Value::known(self.signature_secret.inner())), ]; diff --git a/src/contract/dao/src/client/mint.rs b/src/contract/dao/src/client/mint.rs index 5356e714b..9a575c1e2 100644 --- a/src/contract/dao/src/client/mint.rs +++ b/src/contract/dao/src/client/mint.rs @@ -64,7 +64,7 @@ pub fn make_mint_call( Witness::Base(halo2::Value::known(dao_approval_ratio_base)), Witness::Base(halo2::Value::known(dao.gov_token_id.inner())), Witness::Base(halo2::Value::known(dao_secret_key.inner())), - Witness::Base(halo2::Value::known(dao.bulla_blind)), + Witness::Base(halo2::Value::known(dao.bulla_blind.inner())), ]; let (pub_x, pub_y) = dao.public_key.xy(); diff --git a/src/contract/dao/src/client/propose.rs b/src/contract/dao/src/client/propose.rs index fe35d6a7d..09ce1b225 100644 --- a/src/contract/dao/src/client/propose.rs +++ b/src/contract/dao/src/client/propose.rs @@ -22,7 +22,7 @@ use darkfi_sdk::{ bridgetree::Hashable, crypto::{ note::AeadEncryptedNote, pasta_prelude::*, pedersen::pedersen_commitment_u64, - poseidon_hash, FuncId, MerkleNode, PublicKey, SecretKey, + poseidon_hash, Blind, FuncId, MerkleNode, PublicKey, ScalarBlind, SecretKey, }, pasta::pallas, }; @@ -63,14 +63,14 @@ impl DaoProposeCall { ) -> Result<(DaoProposeParams, Vec)> { let mut proofs = vec![]; - let gov_token_blind = pallas::Base::random(&mut OsRng); + let gov_token_blind = Blind::random(&mut OsRng); let mut inputs = vec![]; let mut total_funds = 0; - let mut total_funds_blinds = pallas::Scalar::from(0); + let mut total_funds_blinds = ScalarBlind::ZERO; for input in self.inputs { - let funds_blind = pallas::Scalar::random(&mut OsRng); + let funds_blind = Blind::random(&mut OsRng); total_funds += input.note.value; total_funds_blinds += funds_blind; @@ -86,9 +86,9 @@ impl DaoProposeCall { Witness::Base(Value::known(note.token_id.inner())), Witness::Base(Value::known(pallas::Base::ZERO)), Witness::Base(Value::known(pallas::Base::ZERO)), - Witness::Base(Value::known(note.coin_blind)), - Witness::Scalar(Value::known(funds_blind)), - Witness::Base(Value::known(gov_token_blind)), + Witness::Base(Value::known(note.coin_blind.inner())), + Witness::Scalar(Value::known(funds_blind.inner())), + Witness::Base(Value::known(gov_token_blind.inner())), Witness::Uint32(Value::known(leaf_pos.try_into().unwrap())), Witness::MerklePath(Value::known(input.merkle_path.clone().try_into().unwrap())), Witness::Base(Value::known(input.signature_secret.inner())), @@ -123,7 +123,7 @@ impl DaoProposeCall { let nullifier: Nullifier = poseidon_hash([input.secret.inner(), coin.inner()]).into(); - let token_commit = poseidon_hash([note.token_id.inner(), gov_token_blind]); + let token_commit = poseidon_hash([note.token_id.inner(), gov_token_blind.inner()]); assert_eq!(self.dao.gov_token_id, note.token_id); let value_commit = pedersen_commitment_u64(note.value, funds_blind); @@ -155,7 +155,7 @@ impl DaoProposeCall { let total_funds_coords = total_funds_commit.to_affine().coordinates().unwrap(); let total_funds = pallas::Base::from(total_funds); - let token_commit = poseidon_hash([self.dao.gov_token_id.inner(), gov_token_blind]); + let token_commit = poseidon_hash([self.dao.gov_token_id.inner(), gov_token_blind.inner()]); let dao_proposer_limit = pallas::Base::from(self.dao.proposer_limit); let dao_quorum = pallas::Base::from(self.dao.quorum); @@ -171,15 +171,15 @@ impl DaoProposeCall { let prover_witnesses = vec![ // Proposers total number of gov tokens Witness::Base(Value::known(total_funds)), - Witness::Scalar(Value::known(total_funds_blinds)), + Witness::Scalar(Value::known(total_funds_blinds.inner())), // Used for blinding exported gov token ID - Witness::Base(Value::known(gov_token_blind)), + Witness::Base(Value::known(gov_token_blind.inner())), // proposal params Witness::Base(Value::known(self.proposal.auth_calls.commit())), Witness::Base(Value::known(pallas::Base::from(self.proposal.creation_day))), Witness::Base(Value::known(pallas::Base::from(self.proposal.duration_days))), Witness::Base(Value::known(self.proposal.user_data)), - Witness::Base(Value::known(self.proposal.blind)), + Witness::Base(Value::known(self.proposal.blind.inner())), // DAO params Witness::Base(Value::known(dao_proposer_limit)), Witness::Base(Value::known(dao_quorum)), @@ -188,7 +188,7 @@ impl DaoProposeCall { Witness::Base(Value::known(self.dao.gov_token_id.inner())), Witness::Base(Value::known(dao_pub_x)), Witness::Base(Value::known(dao_pub_y)), - Witness::Base(Value::known(self.dao.bulla_blind)), + Witness::Base(Value::known(self.dao.bulla_blind.inner())), Witness::Uint32(Value::known(dao_leaf_position.try_into().unwrap())), Witness::MerklePath(Value::known(self.dao_merkle_path.try_into().unwrap())), ]; diff --git a/src/contract/dao/src/client/vote.rs b/src/contract/dao/src/client/vote.rs index 08ba0aaa2..840c4fd32 100644 --- a/src/contract/dao/src/client/vote.rs +++ b/src/contract/dao/src/client/vote.rs @@ -22,7 +22,7 @@ use darkfi_sdk::{ bridgetree::Hashable, crypto::{ note::ElGamalEncryptedNote, pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, - util::fv_mod_fp_unsafe, FuncId, Keypair, MerkleNode, PublicKey, SecretKey, + util::fv_mod_fp_unsafe, Blind, FuncId, Keypair, MerkleNode, PublicKey, SecretKey, }, pasta::pallas, }; @@ -111,7 +111,7 @@ impl DaoVoteCall { Witness::Base(Value::known(note.token_id.inner())), Witness::Base(Value::known(pallas::Base::ZERO)), Witness::Base(Value::known(pallas::Base::ZERO)), - Witness::Base(Value::known(note.coin_blind)), + Witness::Base(Value::known(note.coin_blind.inner())), Witness::Scalar(Value::known(value_blind)), Witness::Base(Value::known(gov_token_blind)), Witness::Uint32(Value::known(leaf_pos.try_into().unwrap())), @@ -149,7 +149,7 @@ impl DaoVoteCall { let nullifier = poseidon_hash([input.secret.inner(), coin.inner()]); - let vote_commit = pedersen_commitment_u64(note.value, value_blind); + let vote_commit = pedersen_commitment_u64(note.value, Blind(value_blind)); let vote_commit_coords = vote_commit.to_affine().coordinates().unwrap(); let (sig_x, sig_y) = signature_public.xy(); @@ -196,17 +196,18 @@ impl DaoVoteCall { break blind } }; - let yes_vote_commit = pedersen_commitment_u64(vote_option * all_vote_value, yes_vote_blind); + let yes_vote_commit = + pedersen_commitment_u64(vote_option * all_vote_value, Blind(yes_vote_blind)); let yes_vote_commit_coords = yes_vote_commit.to_affine().coordinates().unwrap(); - let all_vote_commit = pedersen_commitment_u64(all_vote_value, all_vote_blind); + let all_vote_commit = pedersen_commitment_u64(all_vote_value, Blind(all_vote_blind)); assert_eq!(all_vote_commit, inputs.iter().map(|i| i.vote_commit).sum()); let all_vote_commit_coords = all_vote_commit.to_affine().coordinates().unwrap(); // Convert blinds to 𝔽ₚ, which should work fine since we selected them // to be convertable. - let yes_vote_blind = fv_mod_fp_unsafe(yes_vote_blind).unwrap(); - let all_vote_blind = fv_mod_fp_unsafe(all_vote_blind).unwrap(); + let yes_vote_blind = Blind(fv_mod_fp_unsafe(yes_vote_blind).unwrap()); + let all_vote_blind = Blind(fv_mod_fp_unsafe(all_vote_blind).unwrap()); let vote_option = pallas::Base::from(vote_option); let all_vote_value_fp = pallas::Base::from(all_vote_value); @@ -221,7 +222,7 @@ impl DaoVoteCall { Witness::Base(Value::known(pallas::Base::from(self.proposal.creation_day))), Witness::Base(Value::known(pallas::Base::from(self.proposal.duration_days))), Witness::Base(Value::known(self.proposal.user_data)), - Witness::Base(Value::known(self.proposal.blind)), + Witness::Base(Value::known(self.proposal.blind.inner())), // DAO params Witness::Base(Value::known(dao_proposer_limit)), Witness::Base(Value::known(dao_quorum)), @@ -229,13 +230,13 @@ impl DaoVoteCall { Witness::Base(Value::known(dao_approval_ratio_base)), Witness::Base(Value::known(self.dao.gov_token_id.inner())), Witness::EcNiPoint(Value::known(dao_public_key)), - Witness::Base(Value::known(self.dao.bulla_blind)), + Witness::Base(Value::known(self.dao.bulla_blind.inner())), // Vote Witness::Base(Value::known(vote_option)), - Witness::Base(Value::known(yes_vote_blind)), + Witness::Base(Value::known(yes_vote_blind.inner())), // Total number of gov tokens allocated Witness::Base(Value::known(all_vote_value_fp)), - Witness::Base(Value::known(all_vote_blind)), + Witness::Base(Value::known(all_vote_blind.inner())), // gov token Witness::Base(Value::known(gov_token_blind)), // time checks @@ -247,7 +248,7 @@ impl DaoVoteCall { assert_eq!(self.dao.to_bulla(), self.proposal.dao_bulla); let proposal_bulla = self.proposal.to_bulla(); - let note = [vote_option, yes_vote_blind, all_vote_value_fp, all_vote_blind]; + let note = [vote_option, yes_vote_blind.inner(), all_vote_value_fp, all_vote_blind.inner()]; let enc_note = ElGamalEncryptedNote::encrypt(note, &ephem_secret, &self.dao_keypair.public); let public_inputs = vec![ diff --git a/src/contract/dao/src/model.rs b/src/contract/dao/src/model.rs index 07a81f319..cd4efccf7 100644 --- a/src/contract/dao/src/model.rs +++ b/src/contract/dao/src/model.rs @@ -23,7 +23,7 @@ use darkfi_sdk::{ crypto::{ note::{AeadEncryptedNote, ElGamalEncryptedNote}, pasta_prelude::*, - poseidon_hash, MerkleNode, PublicKey, + poseidon_hash, BaseBlind, MerkleNode, PublicKey, }, error::ContractError, pasta::pallas, @@ -43,7 +43,7 @@ pub struct Dao { pub approval_ratio_base: u64, pub gov_token_id: TokenId, pub public_key: PublicKey, - pub bulla_blind: pallas::Base, + pub bulla_blind: BaseBlind, } // ANCHOR_END: dao @@ -62,7 +62,7 @@ impl Dao { self.gov_token_id.inner(), pub_x, pub_y, - self.bulla_blind, + self.bulla_blind.inner(), ]); DaoBulla(bulla) } @@ -148,7 +148,7 @@ pub struct DaoProposal { /// Arbitrary data provided by the user. We don't use this. pub user_data: pallas::Base, pub dao_bulla: DaoBulla, - pub blind: pallas::Base, + pub blind: BaseBlind, } // ANCHOR_END: dao-proposal @@ -160,7 +160,7 @@ impl DaoProposal { pallas::Base::from(self.duration_days), self.user_data, self.dao_bulla.inner(), - self.blind, + self.blind.inner(), ]); DaoProposalBulla(bulla) } diff --git a/src/contract/dao/tests/integration.rs b/src/contract/dao/tests/integration.rs index 461a2c6c7..1f9b7a6b0 100644 --- a/src/contract/dao/tests/integration.rs +++ b/src/contract/dao/tests/integration.rs @@ -31,7 +31,7 @@ use darkfi_sdk::{ pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, util::{fp_mod_fv, fp_to_u64}, - FuncId, FuncRef, DAO_CONTRACT_ID, MONEY_CONTRACT_ID, + Blind, FuncId, FuncRef, DAO_CONTRACT_ID, MONEY_CONTRACT_ID, }, pasta::pallas, }; @@ -98,7 +98,7 @@ fn integration_test() -> Result<()> { approval_ratio_quot: 1, gov_token_id, public_key: dao_keypair.public, - bulla_blind: pallas::Base::random(&mut OsRng), + bulla_blind: Blind::random(&mut OsRng), }; // ==================== @@ -249,7 +249,7 @@ fn integration_test() -> Result<()> { token_id: drk_token_id, spend_hook: FuncId::none(), user_data: pallas::Base::ZERO, - blind: pallas::Base::random(&mut OsRng), + blind: Blind::random(&mut OsRng), }]; // We can add whatever we want in here, even arbitrary text // It's up to the auth module to decide what to do with it. @@ -342,8 +342,8 @@ fn integration_test() -> Result<()> { let mut total_yes_vote_value = 0; let mut total_all_vote_value = 0; let mut blind_total_vote = DaoBlindAggregateVote::default(); - let mut total_yes_vote_blind = pallas::Scalar::ZERO; - let mut total_all_vote_blind = pallas::Scalar::ZERO; + let mut total_yes_vote_blind = Blind::ZERO; + let mut total_all_vote_blind = Blind::ZERO; for (i, (note, params)) in [ (vote_note_1, alice_vote_params), @@ -360,9 +360,9 @@ fn integration_test() -> Result<()> { // all_vote_blind, // ] let vote_option = fp_to_u64(note[0]).unwrap(); - let yes_vote_blind = fp_mod_fv(note[1]); + let yes_vote_blind = Blind(fp_mod_fv(note[1])); let all_vote_value = fp_to_u64(note[2]).unwrap(); - let all_vote_blind = fp_mod_fv(note[3]); + let all_vote_blind = Blind(fp_mod_fv(note[3])); assert!(vote_option == 0 || vote_option == 1); total_yes_vote_blind += yes_vote_blind; diff --git a/src/contract/money/src/client/auth_token_mint_v1.rs b/src/contract/money/src/client/auth_token_mint_v1.rs index 75c0fceea..248a5295c 100644 --- a/src/contract/money/src/client/auth_token_mint_v1.rs +++ b/src/contract/money/src/client/auth_token_mint_v1.rs @@ -22,7 +22,7 @@ use darkfi::{ Result, }; use darkfi_sdk::{ - crypto::{note::AeadEncryptedNote, pasta_prelude::*, pedersen_commitment_u64, Keypair}, + crypto::{note::AeadEncryptedNote, pasta_prelude::*, pedersen_commitment_u64, Blind, Keypair}, pasta::pallas, }; use log::info; @@ -56,7 +56,7 @@ impl AuthTokenMintCallBuilder { pub fn build(&self) -> Result { info!("Building Money::AuthTokenMintV1 contract call"); - let value_blind = pallas::Scalar::random(&mut OsRng); + let value_blind = Blind::random(&mut OsRng); let value_commit = pedersen_commitment_u64(self.coin_attrs.value, value_blind); // Create the proof @@ -70,14 +70,14 @@ impl AuthTokenMintCallBuilder { Witness::Base(Value::known(pallas::Base::from(self.coin_attrs.value))), Witness::Base(Value::known(self.coin_attrs.spend_hook.inner())), Witness::Base(Value::known(self.coin_attrs.user_data)), - Witness::Base(Value::known(self.coin_attrs.blind)), + Witness::Base(Value::known(self.coin_attrs.blind.inner())), // Token attributes Witness::Base(Value::known(self.token_attrs.auth_parent.inner())), - Witness::Base(Value::known(self.token_attrs.blind)), + Witness::Base(Value::known(self.token_attrs.blind.inner())), // Secret key used by mint Witness::Base(Value::known(self.mint_keypair.secret.inner())), // Random blinding factor for the value commitment - Witness::Scalar(Value::known(value_blind)), + Witness::Scalar(Value::known(value_blind.inner())), ]; let mint_pubkey = self.mint_keypair.public; @@ -104,7 +104,7 @@ impl AuthTokenMintCallBuilder { user_data: self.coin_attrs.user_data, coin_blind: self.coin_attrs.blind, value_blind, - token_blind: pallas::Base::ZERO, + token_blind: Blind::ZERO, memo: vec![], }; diff --git a/src/contract/money/src/client/fee_v1.rs b/src/contract/money/src/client/fee_v1.rs index a6adde162..3fe235da4 100644 --- a/src/contract/money/src/client/fee_v1.rs +++ b/src/contract/money/src/client/fee_v1.rs @@ -31,8 +31,8 @@ use darkfi_sdk::{ crypto::{ note::AeadEncryptedNote, pasta_prelude::{Curve, CurveAffine, Field}, - pedersen_commitment_u64, poseidon_hash, FuncId, Keypair, MerkleNode, MerkleTree, PublicKey, - SecretKey, + pedersen_commitment_u64, poseidon_hash, BaseBlind, Blind, FuncId, Keypair, MerkleNode, + MerkleTree, PublicKey, ScalarBlind, SecretKey, }, pasta::pallas, }; @@ -109,7 +109,7 @@ pub async fn append_fee_call( merkle_path: tree.witness(coin.leaf_position, 0).unwrap(), secret: coin.secret, note: coin.note.clone(), - user_data_blind: pallas::Base::random(&mut OsRng), + user_data_blind: Blind::random(&mut OsRng), }; let output = FeeCallOutput { @@ -118,13 +118,13 @@ pub async fn append_fee_call( token_id: coin.note.token_id, spend_hook: FuncId::none(), user_data: pallas::Base::ZERO, - blind: pallas::Base::random(&mut OsRng), + blind: Blind::random(&mut OsRng), }; - let token_blind = pallas::Base::random(&mut OsRng); + let token_blind = Blind::random(&mut OsRng); - let input_value_blind = pallas::Scalar::random(&mut OsRng); - let fee_value_blind = pallas::Scalar::random(&mut OsRng); + let input_value_blind = Blind::random(&mut OsRng); + let fee_value_blind = Blind::random(&mut OsRng); let output_value_blind = compute_remainder_blind(&[], &[input_value_blind], &[fee_value_blind]); let signature_secret = SecretKey::random(&mut OsRng); @@ -194,9 +194,9 @@ pub struct FeeCallSecrets { /// Decrypted note associated with the output pub note: MoneyNote, /// The value blind created for the input - pub input_value_blind: pallas::Scalar, + pub input_value_blind: ScalarBlind, /// The value blind created for the output - pub output_value_blind: pallas::Scalar, + pub output_value_blind: ScalarBlind, } /// Revealed public inputs of the `Fee_V1` ZK proof @@ -253,7 +253,7 @@ struct FeeCallInput { merkle_path: Vec, secret: SecretKey, note: MoneyNote, - user_data_blind: pallas::Base, + user_data_blind: BaseBlind, } type FeeCallOutput = CoinAttributes; @@ -264,13 +264,13 @@ fn create_fee_proof( zkbin: &ZkBinary, pk: &ProvingKey, input: &FeeCallInput, - input_value_blind: pallas::Scalar, + input_value_blind: ScalarBlind, output: &FeeCallOutput, - output_value_blind: pallas::Scalar, + output_value_blind: ScalarBlind, output_spend_hook: FuncId, output_user_data: pallas::Base, - output_coin_blind: pallas::Base, - token_blind: pallas::Base, + output_coin_blind: BaseBlind, + token_blind: BaseBlind, signature_secret: SecretKey, ) -> Result<(Proof, FeeRevealed)> { let public_key = PublicKey::from_secret(input.secret); @@ -304,10 +304,10 @@ fn create_fee_proof( current }; - let input_user_data_enc = poseidon_hash([input.note.user_data, input.user_data_blind]); + 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 output_value_commit = pedersen_commitment_u64(output.value, output_value_blind); - let token_commit = poseidon_hash([input.note.token_id.inner(), token_blind]); + let token_commit = poseidon_hash([input.note.token_id.inner(), token_blind.inner()]); // Create output coin let output_coin = CoinAttributes { @@ -316,7 +316,7 @@ fn create_fee_proof( token_id: output.token_id, spend_hook: output_spend_hook, user_data: output_user_data, - blind: output_coin_blind, + blind: output_coin_blind.clone(), } .to_coin(); @@ -338,18 +338,18 @@ fn create_fee_proof( 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::Scalar(Value::known(input_value_blind)), + 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)), - Witness::Base(Value::known(input.user_data_blind)), + Witness::Base(Value::known(input.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)), - Witness::Base(Value::known(output_coin_blind)), + 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(token_blind)), + Witness::Base(Value::known(token_blind.inner())), ]; let circuit = ZkCircuit::new(prover_witnesses, zkbin); diff --git a/src/contract/money/src/client/genesis_mint_v1.rs b/src/contract/money/src/client/genesis_mint_v1.rs index e55de5121..3d036b3a5 100644 --- a/src/contract/money/src/client/genesis_mint_v1.rs +++ b/src/contract/money/src/client/genesis_mint_v1.rs @@ -22,7 +22,7 @@ use darkfi::{ Result, }; use darkfi_sdk::{ - crypto::{note::AeadEncryptedNote, pasta_prelude::*, FuncId, Keypair, PublicKey}, + crypto::{note::AeadEncryptedNote, pasta_prelude::*, Blind, FuncId, Keypair, PublicKey}, pasta::pallas, }; use log::{debug, info}; @@ -96,14 +96,14 @@ impl GenesisMintCallBuilder { token_id, spend_hook: FuncId::none(), user_data: pallas::Base::ZERO, - blind: pallas::Base::random(&mut OsRng), + blind: Blind::random(&mut OsRng), }; // We just create the commitment blinds here. We simply encofce // that the clear input and the anon output have the same commitments. // Not sure if this can be avoided, but also is it really necessary to avoid? - let value_blind = pallas::Scalar::random(&mut OsRng); - let token_blind = pallas::Base::random(&mut OsRng); + let value_blind = Blind::random(&mut OsRng); + let token_blind = Blind::random(&mut OsRng); let c_input = ClearInput { value: input.value, @@ -113,7 +113,7 @@ impl GenesisMintCallBuilder { signature_public: PublicKey::from_secret(input.signature_secret), }; - let coin_blind = pallas::Base::random(&mut OsRng); + let coin_blind = Blind::random(&mut OsRng); info!("Creating token mint proof for output"); let (proof, public_inputs) = create_transfer_mint_proof( diff --git a/src/contract/money/src/client/mod.rs b/src/contract/money/src/client/mod.rs index c30400907..1dd0634d8 100644 --- a/src/contract/money/src/client/mod.rs +++ b/src/contract/money/src/client/mod.rs @@ -28,7 +28,7 @@ use darkfi_sdk::{ bridgetree, - crypto::{FuncId, SecretKey}, + crypto::{BaseBlind, Blind, FuncId, ScalarBlind, SecretKey}, pasta::pallas, }; use darkfi_serial::{async_trait, SerialDecodable, SerialEncodable}; @@ -75,12 +75,12 @@ pub struct MoneyNote { /// User data used by protocol when spend hook is enabled pub user_data: pallas::Base, /// Blinding factor for the coin - pub coin_blind: pallas::Base, + pub coin_blind: BaseBlind, // TODO: look into removing these fields. We potentially don't need them [ /// Blinding factor for the value pedersen commitment - pub value_blind: pallas::Scalar, + pub value_blind: ScalarBlind, /// Blinding factor for the token ID pedersen commitment - pub token_blind: pallas::Base, + pub token_blind: BaseBlind, // ] ^ the receiver is not interested in the value commit / token commits. // we just want to examine the coins in the outputs. The money::transfer() contract // should ensure everything else is correct. @@ -105,22 +105,22 @@ pub struct OwnCoin { pub fn compute_remainder_blind( clear_inputs: &[crate::model::ClearInput], - input_blinds: &[pallas::Scalar], - output_blinds: &[pallas::Scalar], -) -> pallas::Scalar { + input_blinds: &[ScalarBlind], + output_blinds: &[ScalarBlind], +) -> ScalarBlind { let mut total = pallas::Scalar::zero(); for input in clear_inputs { - total += input.value_blind; + total += input.value_blind.inner(); } for input_blind in input_blinds { - total += input_blind; + total += input_blind.inner(); } for output_blind in output_blinds { - total -= output_blind; + total -= output_blind.inner(); } - total + Blind(total) } diff --git a/src/contract/money/src/client/pow_reward_v1.rs b/src/contract/money/src/client/pow_reward_v1.rs index a587b1fcd..9891755ba 100644 --- a/src/contract/money/src/client/pow_reward_v1.rs +++ b/src/contract/money/src/client/pow_reward_v1.rs @@ -24,7 +24,8 @@ use darkfi::{ use darkfi_sdk::{ blockchain::expected_reward, crypto::{ - ecvrf::VrfProof, note::AeadEncryptedNote, pasta_prelude::*, FuncId, PublicKey, SecretKey, + ecvrf::VrfProof, note::AeadEncryptedNote, pasta_prelude::*, Blind, FuncId, PublicKey, + SecretKey, }, pasta::pallas, }; @@ -101,14 +102,14 @@ impl PoWRewardCallBuilder { token_id, spend_hook: FuncId::none(), user_data: pallas::Base::ZERO, - blind: pallas::Base::random(&mut OsRng), + blind: Blind::random(&mut OsRng), }; // We just create the commitment blinds here. We simply encofce // that the clear input and the anon output have the same commitments. // Not sure if this can be avoided, but also is it really necessary to avoid? - let value_blind = pallas::Scalar::random(&mut OsRng); - let token_blind = pallas::Base::random(&mut OsRng); + let value_blind = Blind::random(&mut OsRng); + let token_blind = Blind::random(&mut OsRng); let c_input = ClearInput { value: input.value, @@ -118,7 +119,7 @@ impl PoWRewardCallBuilder { signature_public: PublicKey::from_secret(input.signature_secret), }; - let coin_blind = pallas::Base::random(&mut OsRng); + let coin_blind = Blind::random(&mut OsRng); info!("Creating token mint proof for output"); let (proof, public_inputs) = create_transfer_mint_proof( diff --git a/src/contract/money/src/client/swap_v1.rs b/src/contract/money/src/client/swap_v1.rs index 2c78ceb67..2c6f0e6ab 100644 --- a/src/contract/money/src/client/swap_v1.rs +++ b/src/contract/money/src/client/swap_v1.rs @@ -24,7 +24,10 @@ use darkfi::{ ClientFailed, Result, }; use darkfi_sdk::{ - crypto::{note::AeadEncryptedNote, pasta_prelude::*, FuncId, MerkleTree, PublicKey, SecretKey}, + crypto::{ + note::AeadEncryptedNote, pasta_prelude::*, BaseBlind, Blind, FuncId, MerkleTree, PublicKey, + ScalarBlind, SecretKey, + }, pasta::pallas, }; use darkfi_serial::serialize; @@ -63,7 +66,7 @@ pub struct SwapCallBuilder { /// The token ID of the party's output to receive pub token_id_recv: TokenId, /// User data blind for the party's input - pub user_data_blind_send: pallas::Base, + pub user_data_blind_send: BaseBlind, /// Spend hook for the party's output pub spend_hook_recv: FuncId, /// User data for the party's output @@ -72,9 +75,9 @@ pub struct SwapCallBuilder { /// `[0]` is used for input 0 and output 1, and `[1]` is /// used for input 1 and output 0. The same applies to /// `token_blinds`. - pub value_blinds: [pallas::Scalar; 2], + pub value_blinds: [ScalarBlind; 2], /// The blinds to be used for token ID pedersen commitments - pub token_blinds: [pallas::Base; 2], + pub token_blinds: [BaseBlind; 2], /// The coin to be used as the input to the swap pub coin: OwnCoin, /// Merkle tree of coins used to create inclusion proofs @@ -122,7 +125,7 @@ impl SwapCallBuilder { token_id: self.token_id_recv, spend_hook: FuncId::none(), user_data: pallas::Base::ZERO, - blind: pallas::Base::random(&mut OsRng), + blind: Blind::random(&mut OsRng), }; // Now we fill this with necessary stuff @@ -155,7 +158,7 @@ impl SwapCallBuilder { proofs.push(proof); // For the output, we create a new coin blind - let coin_blind = pallas::Base::random(&mut OsRng); + let coin_blind = Blind::random(&mut OsRng); info!("Creating mint proof for output"); let (proof, public_inputs) = create_transfer_mint_proof( diff --git a/src/contract/money/src/client/token_freeze_v1.rs b/src/contract/money/src/client/token_freeze_v1.rs index 686ad3fbd..d70128d38 100644 --- a/src/contract/money/src/client/token_freeze_v1.rs +++ b/src/contract/money/src/client/token_freeze_v1.rs @@ -52,7 +52,7 @@ impl TokenFreezeCallBuilder { let prover_witnesses = vec![ // Token attributes Witness::Base(Value::known(self.token_attrs.auth_parent.inner())), - Witness::Base(Value::known(self.token_attrs.blind)), + Witness::Base(Value::known(self.token_attrs.blind.inner())), // Secret key used by mint Witness::Base(Value::known(self.mint_keypair.secret.inner())), ]; diff --git a/src/contract/money/src/client/token_mint_v1.rs b/src/contract/money/src/client/token_mint_v1.rs index 505e4a7db..dbf9080f3 100644 --- a/src/contract/money/src/client/token_mint_v1.rs +++ b/src/contract/money/src/client/token_mint_v1.rs @@ -55,11 +55,11 @@ impl TokenMintCallBuilder { Witness::Base(Value::known(pallas::Base::from(self.coin_attrs.value))), Witness::Base(Value::known(self.coin_attrs.spend_hook.inner())), Witness::Base(Value::known(self.coin_attrs.user_data)), - Witness::Base(Value::known(self.coin_attrs.blind)), + Witness::Base(Value::known(self.coin_attrs.blind.inner())), // Token attributes Witness::Base(Value::known(self.token_attrs.auth_parent.inner())), Witness::Base(Value::known(self.token_attrs.user_data)), - Witness::Base(Value::known(self.token_attrs.blind)), + Witness::Base(Value::known(self.token_attrs.blind.inner())), ]; let coin = self.coin_attrs.to_coin(); diff --git a/src/contract/money/src/client/transfer_v1/builder.rs b/src/contract/money/src/client/transfer_v1/builder.rs index 6cd8d5c65..bb6cec3c8 100644 --- a/src/contract/money/src/client/transfer_v1/builder.rs +++ b/src/contract/money/src/client/transfer_v1/builder.rs @@ -22,7 +22,10 @@ use darkfi::{ }; use darkfi_sdk::{ bridgetree, - crypto::{note::AeadEncryptedNote, pasta_prelude::*, MerkleNode, PublicKey, SecretKey}, + crypto::{ + note::AeadEncryptedNote, pasta_prelude::*, BaseBlind, Blind, MerkleNode, PublicKey, + ScalarBlind, SecretKey, + }, pasta::pallas, }; use log::{debug, info}; @@ -65,7 +68,7 @@ pub struct TransferCallInput { 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: pallas::Base, + pub user_data_blind: BaseBlind, } pub type TransferCallOutput = CoinAttributes; @@ -80,12 +83,12 @@ impl TransferCallBuilder { let mut signature_secrets = vec![]; let mut proofs = vec![]; - let token_blind = pallas::Base::random(&mut OsRng); + let token_blind = Blind::random(&mut OsRng); debug!("Building clear inputs"); for input in self.clear_inputs { signature_secrets.push(input.signature_secret); let signature_public = PublicKey::from_secret(input.signature_secret); - let value_blind = pallas::Scalar::random(&mut OsRng); + let value_blind = Blind::random(&mut OsRng); params.clear_inputs.push(ClearInput { value: input.value, @@ -101,7 +104,7 @@ impl TransferCallBuilder { debug!("Building anonymous inputs"); for (i, input) in self.inputs.iter().enumerate() { - let value_blind = pallas::Scalar::random(&mut OsRng); + let value_blind = Blind::random(&mut OsRng); input_blinds.push(value_blind); let signature_secret = SecretKey::random(&mut OsRng); @@ -138,7 +141,7 @@ impl TransferCallBuilder { let value_blind = if i == self.outputs.len() - 1 { compute_remainder_blind(¶ms.clear_inputs, &input_blinds, &output_blinds) } else { - pallas::Scalar::random(&mut OsRng) + Blind::random(&mut OsRng) }; output_blinds.push(value_blind); @@ -203,9 +206,9 @@ pub struct TransferCallSecrets { pub output_notes: Vec, /// The value blinds created for the inputs - pub input_value_blinds: Vec, + pub input_value_blinds: Vec, /// The value blinds created for the outputs - pub output_value_blinds: Vec, + pub output_value_blinds: Vec, } impl TransferCallSecrets { diff --git a/src/contract/money/src/client/transfer_v1/mod.rs b/src/contract/money/src/client/transfer_v1/mod.rs index 60937b147..f1a890d18 100644 --- a/src/contract/money/src/client/transfer_v1/mod.rs +++ b/src/contract/money/src/client/transfer_v1/mod.rs @@ -17,7 +17,7 @@ */ use darkfi::{zk::ProvingKey, zkas::ZkBinary, ClientFailed, Result}; use darkfi_sdk::{ - crypto::{pasta_prelude::*, FuncId, Keypair, MerkleTree, PublicKey}, + crypto::{pasta_prelude::*, Blind, FuncId, Keypair, MerkleTree, PublicKey}, pasta::pallas, }; use log::{debug, error}; @@ -118,7 +118,7 @@ pub fn make_transfer_call( merkle_path, secret: coin.secret, note: coin.note.clone(), - user_data_blind: pallas::Base::random(&mut OsRng), + user_data_blind: Blind::random(&mut OsRng), }; inputs.push(input); @@ -131,7 +131,7 @@ pub fn make_transfer_call( token_id, spend_hook: FuncId::none(), user_data: pallas::Base::ZERO, - blind: pallas::Base::random(&mut OsRng), + blind: Blind::random(&mut OsRng), }); if change_value > 0 { @@ -141,7 +141,7 @@ pub fn make_transfer_call( token_id, spend_hook: FuncId::none(), user_data: pallas::Base::ZERO, - blind: pallas::Base::random(&mut OsRng), + blind: Blind::random(&mut OsRng), }); } diff --git a/src/contract/money/src/client/transfer_v1/proof.rs b/src/contract/money/src/client/transfer_v1/proof.rs index 2e6862f96..921653f9a 100644 --- a/src/contract/money/src/client/transfer_v1/proof.rs +++ b/src/contract/money/src/client/transfer_v1/proof.rs @@ -24,8 +24,8 @@ use darkfi::{ use darkfi_sdk::{ bridgetree::Hashable, crypto::{ - pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, FuncId, MerkleNode, PublicKey, - SecretKey, + pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, BaseBlind, FuncId, MerkleNode, + PublicKey, ScalarBlind, SecretKey, }, pasta::pallas, }; @@ -85,8 +85,8 @@ pub fn create_transfer_burn_proof( zkbin: &ZkBinary, pk: &ProvingKey, input: &TransferCallInput, - value_blind: pallas::Scalar, - token_blind: pallas::Base, + value_blind: ScalarBlind, + token_blind: BaseBlind, signature_secret: SecretKey, ) -> Result<(Proof, TransferBurnRevealed)> { let public_key = PublicKey::from_secret(input.secret); @@ -118,9 +118,9 @@ pub fn create_transfer_burn_proof( current }; - let user_data_enc = poseidon_hash([input.note.user_data, input.user_data_blind]); + 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]); + let token_commit = poseidon_hash([input.note.token_id.inner(), token_blind.inner()]); let public_inputs = TransferBurnRevealed { value_commit, @@ -138,10 +138,10 @@ pub fn create_transfer_burn_proof( 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)), - Witness::Scalar(Value::known(value_blind)), - Witness::Base(Value::known(token_blind)), - Witness::Base(Value::known(input.user_data_blind)), + Witness::Base(Value::known(input.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::MerklePath(Value::known(input.merkle_path.clone().try_into().unwrap())), Witness::Base(Value::known(signature_secret.inner())), @@ -158,14 +158,14 @@ pub fn create_transfer_mint_proof( zkbin: &ZkBinary, pk: &ProvingKey, output: &TransferCallOutput, - value_blind: pallas::Scalar, - token_blind: pallas::Base, + value_blind: ScalarBlind, + token_blind: BaseBlind, spend_hook: FuncId, user_data: pallas::Base, - coin_blind: pallas::Base, + coin_blind: BaseBlind, ) -> Result<(Proof, TransferMintRevealed)> { let value_commit = pedersen_commitment_u64(output.value, value_blind); - let token_commit = poseidon_hash([output.token_id.inner(), token_blind]); + let token_commit = poseidon_hash([output.token_id.inner(), token_blind.inner()]); let (pub_x, pub_y) = output.public_key.xy(); let coin = CoinAttributes { @@ -188,9 +188,9 @@ pub fn create_transfer_mint_proof( Witness::Base(Value::known(output.token_id.inner())), Witness::Base(Value::known(spend_hook.inner())), Witness::Base(Value::known(user_data)), - Witness::Base(Value::known(coin_blind)), - Witness::Scalar(Value::known(value_blind)), - Witness::Base(Value::known(token_blind)), + Witness::Base(Value::known(coin_blind.inner())), + Witness::Scalar(Value::known(value_blind.inner())), + Witness::Base(Value::known(token_blind.inner())), ]; let circuit = ZkCircuit::new(prover_witnesses, zkbin); diff --git a/src/contract/money/src/entrypoint/fee_v1.rs b/src/contract/money/src/entrypoint/fee_v1.rs index 96bafef9d..2b9c05461 100644 --- a/src/contract/money/src/entrypoint/fee_v1.rs +++ b/src/contract/money/src/entrypoint/fee_v1.rs @@ -108,7 +108,7 @@ pub(crate) fn money_fee_process_instruction_v1( // Fees can only be paid using the native token, so we'll compare // the token commitments with this one: - let native_token_commit = poseidon_hash([DARK_TOKEN_ID.inner(), params.token_blind]); + let native_token_commit = poseidon_hash([DARK_TOKEN_ID.inner(), params.token_blind.inner()]); // =================================== // Perform the actual state transition diff --git a/src/contract/money/src/entrypoint/genesis_mint_v1.rs b/src/contract/money/src/entrypoint/genesis_mint_v1.rs index e00d573b2..2a26abd4b 100644 --- a/src/contract/money/src/entrypoint/genesis_mint_v1.rs +++ b/src/contract/money/src/entrypoint/genesis_mint_v1.rs @@ -116,7 +116,7 @@ pub(crate) fn money_genesis_mint_process_instruction_v1( return Err(MoneyError::ValueMismatch.into()) } - if poseidon_hash([params.input.token_id.inner(), params.input.token_blind]) != + if poseidon_hash([params.input.token_id.inner(), params.input.token_blind.inner()]) != params.output.token_commit { msg!("[GenesisMintV1] Error: Token commitment mismatch"); diff --git a/src/contract/money/src/entrypoint/pow_reward_v1.rs b/src/contract/money/src/entrypoint/pow_reward_v1.rs index 79f16cab2..06f189e96 100644 --- a/src/contract/money/src/entrypoint/pow_reward_v1.rs +++ b/src/contract/money/src/entrypoint/pow_reward_v1.rs @@ -155,7 +155,7 @@ pub(crate) fn money_pow_reward_process_instruction_v1( return Err(MoneyError::ValueMismatch.into()) } - if poseidon_hash([params.input.token_id.inner(), params.input.token_blind]) != + if poseidon_hash([params.input.token_id.inner(), params.input.token_blind.inner()]) != params.output.token_commit { msg!("[PoWRewardV1] Error: Token commitment mismatch"); diff --git a/src/contract/money/src/entrypoint/transfer_v1.rs b/src/contract/money/src/entrypoint/transfer_v1.rs index 704edd0fe..7d133ea2d 100644 --- a/src/contract/money/src/entrypoint/transfer_v1.rs +++ b/src/contract/money/src/entrypoint/transfer_v1.rs @@ -237,7 +237,7 @@ pub(crate) fn money_transfer_process_instruction_v1( params .clear_inputs .iter() - .any(|x| poseidon_hash([x.token_id.inner(), x.token_blind]) != tokcom); + .any(|x| poseidon_hash([x.token_id.inner(), x.token_blind.inner()]) != tokcom); if failed_tokcom { msg!("[TransferV1] Error: Token commitments do not match"); diff --git a/src/contract/money/src/model/mod.rs b/src/contract/money/src/model/mod.rs index bd1ec51d7..4c5ba1858 100644 --- a/src/contract/money/src/model/mod.rs +++ b/src/contract/money/src/model/mod.rs @@ -18,8 +18,8 @@ use darkfi_sdk::{ crypto::{ - ecvrf::VrfProof, note::AeadEncryptedNote, pasta_prelude::PrimeField, poseidon_hash, FuncId, - MerkleNode, PublicKey, SecretKey, + ecvrf::VrfProof, note::AeadEncryptedNote, pasta_prelude::PrimeField, poseidon_hash, + BaseBlind, FuncId, MerkleNode, PublicKey, ScalarBlind, SecretKey, }, error::ContractError, pasta::pallas, @@ -78,7 +78,7 @@ pub struct CoinAttributes { pub spend_hook: FuncId, pub user_data: pallas::Base, /// Simultaneously blinds the coin and ensures uniqueness - pub blind: pallas::Base, + pub blind: BaseBlind, } // ANCHOR_END: coin-attributes @@ -92,7 +92,7 @@ impl CoinAttributes { self.token_id.inner(), self.spend_hook.inner(), self.user_data, - self.blind, + self.blind.inner(), ]); Coin(coin) } @@ -102,12 +102,13 @@ impl CoinAttributes { pub struct TokenAttributes { pub auth_parent: FuncId, pub user_data: pallas::Base, - pub blind: pallas::Base, + pub blind: BaseBlind, } impl TokenAttributes { pub fn to_token_id(&self) -> TokenId { - let token_id = poseidon_hash([self.auth_parent.inner(), self.user_data, self.blind]); + let token_id = + poseidon_hash([self.auth_parent.inner(), self.user_data, self.blind.inner()]); TokenId::from(token_id) } } @@ -137,9 +138,9 @@ pub struct ClearInput { /// Input's token ID pub token_id: TokenId, /// Blinding factor for `value` - pub value_blind: pallas::Scalar, + pub value_blind: ScalarBlind, /// Blinding factor for `token_id` - pub token_blind: pallas::Base, + pub token_blind: BaseBlind, /// Public key for the signature pub signature_public: PublicKey, } @@ -189,9 +190,9 @@ pub struct MoneyFeeParamsV1 { /// Anonymous outputs pub output: Output, /// Fee value blind - pub fee_value_blind: pallas::Scalar, + pub fee_value_blind: ScalarBlind, /// Token ID blind - pub token_blind: pallas::Base, + pub token_blind: BaseBlind, } /// State update for `Money::Fee` diff --git a/src/contract/test-harness/src/dao_exec.rs b/src/contract/test-harness/src/dao_exec.rs index 7660ed912..1d6f57fb9 100644 --- a/src/contract/test-harness/src/dao_exec.rs +++ b/src/contract/test-harness/src/dao_exec.rs @@ -32,11 +32,10 @@ use darkfi_money_contract::{ }; use darkfi_sdk::{ crypto::{ - pasta_prelude::Field, pedersen_commitment_u64, FuncRef, MerkleNode, SecretKey, + pedersen_commitment_u64, Blind, FuncRef, MerkleNode, ScalarBlind, SecretKey, DAO_CONTRACT_ID, MONEY_CONTRACT_ID, }, dark_tree::DarkLeaf, - pasta::pallas, ContractCall, }; use darkfi_serial::{serialize, Encodable}; @@ -54,8 +53,8 @@ impl TestHarness { proposal_coinattrs: Vec, yes_vote_value: u64, all_vote_value: u64, - yes_vote_blind: pallas::Scalar, - all_vote_blind: pallas::Scalar, + yes_vote_blind: ScalarBlind, + all_vote_blind: ScalarBlind, ) -> Result<(Transaction, MoneyTransferParamsV1, DaoExecParams)> { let dao_wallet = self.holders.get(&Holder::Dao).unwrap(); @@ -77,7 +76,7 @@ impl TestHarness { let tx_action_benchmark = self.tx_action_benchmarks.get_mut(&TxAction::DaoExec).unwrap(); let timer = Instant::now(); - let input_user_data_blind = pallas::Base::random(&mut OsRng); + let input_user_data_blind = Blind::random(&mut OsRng); let exec_signature_secret = SecretKey::random(&mut OsRng); assert!(!proposal_coinattrs.is_empty()); @@ -124,7 +123,7 @@ impl TestHarness { token_id: proposal_token_id, spend_hook, user_data: dao_bulla.inner(), - blind: pallas::Base::random(&mut OsRng), + blind: Blind::random(&mut OsRng), }; outputs.push(dao_coin_attrs.clone()); @@ -146,10 +145,10 @@ impl TestHarness { // We need to extract stuff from the inputs and outputs that we'll also // use in the DAO::Exec call. This DAO API needs to be better. let mut input_value = 0; - let mut input_value_blind = pallas::Scalar::ZERO; + let mut input_value_blind = Blind::ZERO; for (input, blind) in spent_coins.iter().zip(xfer_secrets.input_value_blinds.iter()) { input_value += input.note.value; - input_value_blind += blind; + input_value_blind += *blind; } assert_eq!( pedersen_commitment_u64(input_value, input_value_blind), diff --git a/src/contract/test-harness/src/dao_propose.rs b/src/contract/test-harness/src/dao_propose.rs index 7685f6a66..a396e104b 100644 --- a/src/contract/test-harness/src/dao_propose.rs +++ b/src/contract/test-harness/src/dao_propose.rs @@ -30,7 +30,7 @@ use darkfi_dao_contract::{ }; use darkfi_money_contract::{client::OwnCoin, model::CoinAttributes, MoneyFunction}; use darkfi_sdk::{ - crypto::{pasta_prelude::Field, MerkleNode, SecretKey, DAO_CONTRACT_ID, MONEY_CONTRACT_ID}, + crypto::{Blind, MerkleNode, SecretKey, DAO_CONTRACT_ID, MONEY_CONTRACT_ID}, pasta::pallas, ContractCall, }; @@ -106,7 +106,7 @@ impl TestHarness { duration_days: 30, user_data, dao_bulla: dao.to_bulla(), - blind: pallas::Base::random(&mut OsRng), + blind: Blind::random(&mut OsRng), }; let call = DaoProposeCall { diff --git a/src/contract/test-harness/src/lib.rs b/src/contract/test-harness/src/lib.rs index 26cace8d0..878c5f295 100644 --- a/src/contract/test-harness/src/lib.rs +++ b/src/contract/test-harness/src/lib.rs @@ -35,8 +35,8 @@ use darkfi_money_contract::{ use darkfi_sdk::{ bridgetree, crypto::{ - note::AeadEncryptedNote, pasta_prelude::Field, poseidon_hash, ContractId, Keypair, - MerkleNode, MerkleTree, PublicKey, SecretKey, + note::AeadEncryptedNote, pasta_prelude::Field, poseidon_hash, BaseBlind, Blind, ContractId, + Keypair, MerkleNode, MerkleTree, PublicKey, SecretKey, }, pasta::pallas, }; @@ -64,13 +64,13 @@ mod money_transfer; pub fn init_logger() { let mut cfg = simplelog::ConfigBuilder::new(); cfg.add_filter_ignore("sled".to_string()); - cfg.set_target_level(simplelog::LevelFilter::Error); + //cfg.set_target_level(simplelog::LevelFilter::Error); // We check this error so we can execute same file tests in parallel, // otherwise second one fails to init logger here. if simplelog::TermLogger::init( - //simplelog::LevelFilter::Info, - simplelog::LevelFilter::Debug, + simplelog::LevelFilter::Info, + //simplelog::LevelFilter::Debug, //simplelog::LevelFilter::Trace, cfg.build(), simplelog::TerminalMode::Mixed, @@ -112,7 +112,7 @@ pub enum TxAction { pub struct Wallet { pub keypair: Keypair, pub token_mint_authority: Keypair, - pub token_blind: pallas::Base, + pub token_blind: BaseBlind, pub contract_deploy_authority: Keypair, pub validator: ValidatorPtr, pub money_merkle_tree: MerkleTree, @@ -162,7 +162,7 @@ impl Wallet { let spent_money_coins = vec![]; let token_mint_authority = Keypair::random(&mut OsRng); - let token_blind = pallas::Base::random(&mut OsRng); + let token_blind = Blind::random(&mut OsRng); let contract_deploy_authority = Keypair::random(&mut OsRng); Ok(Self { diff --git a/src/contract/test-harness/src/money_airdrop.rs b/src/contract/test-harness/src/money_airdrop.rs index e47cadf43..59fdee494 100644 --- a/src/contract/test-harness/src/money_airdrop.rs +++ b/src/contract/test-harness/src/money_airdrop.rs @@ -29,7 +29,7 @@ use darkfi_money_contract::{ MoneyFunction, MONEY_CONTRACT_ZKAS_BURN_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1, }; use darkfi_sdk::{ - crypto::{FuncId, MerkleNode, MONEY_CONTRACT_ID}, + crypto::{Blind, FuncId, MerkleNode, MONEY_CONTRACT_ID}, pasta::pallas, ContractCall, }; @@ -74,7 +74,7 @@ impl TestHarness { token_id: *DARK_TOKEN_ID, spend_hook: rcpt_spend_hook.unwrap_or(FuncId::none()), user_data: rcpt_user_data.unwrap_or(pallas::Base::ZERO), - blind: pallas::Base::random(&mut OsRng), + blind: Blind::random(&mut OsRng), }], mint_zkbin: mint_zkbin.clone(), mint_pk: mint_pk.clone(), diff --git a/src/contract/test-harness/src/money_otc_swap.rs b/src/contract/test-harness/src/money_otc_swap.rs index 3854b9eea..566b1e93a 100644 --- a/src/contract/test-harness/src/money_otc_swap.rs +++ b/src/contract/test-harness/src/money_otc_swap.rs @@ -29,7 +29,7 @@ use darkfi_money_contract::{ MoneyFunction, MONEY_CONTRACT_ZKAS_BURN_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1, }; use darkfi_sdk::{ - crypto::{FuncId, MerkleNode, MONEY_CONTRACT_ID}, + crypto::{Blind, FuncId, MerkleNode, MONEY_CONTRACT_ID}, pasta::pallas, ContractCall, }; @@ -62,14 +62,14 @@ impl TestHarness { // We're just going to be using a zero spend-hook and user-data let rcpt_spend_hook = FuncId::none(); - let rcpt_user_data = pallas::Base::zero(); - let rcpt_user_data_blind = pallas::Base::random(&mut OsRng); + let rcpt_user_data = pallas::Base::ZERO; + let rcpt_user_data_blind = Blind::random(&mut OsRng); // Generating swap blinds - let value_send_blind = pallas::Scalar::random(&mut OsRng); - let value_recv_blind = pallas::Scalar::random(&mut OsRng); - let token_send_blind = pallas::Base::random(&mut OsRng); - let token_recv_blind = pallas::Base::random(&mut OsRng); + let value_send_blind = Blind::random(&mut OsRng); + let value_recv_blind = Blind::random(&mut OsRng); + let token_send_blind = Blind::random(&mut OsRng); + let token_recv_blind = Blind::random(&mut OsRng); // Builder first holder part let builder = SwapCallBuilder { diff --git a/src/contract/test-harness/src/money_token.rs b/src/contract/test-harness/src/money_token.rs index 88f091ecf..0ac8d51b1 100644 --- a/src/contract/test-harness/src/money_token.rs +++ b/src/contract/test-harness/src/money_token.rs @@ -36,7 +36,7 @@ use darkfi_money_contract::{ MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1, }; use darkfi_sdk::{ - crypto::{poseidon_hash, FuncId, FuncRef, MerkleNode, MONEY_CONTRACT_ID}, + crypto::{poseidon_hash, Blind, FuncId, FuncRef, MerkleNode, MONEY_CONTRACT_ID}, dark_tree::DarkLeaf, pasta::pallas, ContractCall, @@ -96,7 +96,7 @@ impl TestHarness { token_id, spend_hook: spend_hook.unwrap_or(FuncId::none()), user_data: user_data.unwrap_or(pallas::Base::ZERO), - blind: pallas::Base::random(&mut OsRng), + blind: Blind::random(&mut OsRng), }; let builder = TokenMintCallBuilder { diff --git a/src/sdk/python/src/crypto.rs b/src/sdk/python/src/crypto.rs index a3bcd1d19..9f45e2b61 100644 --- a/src/sdk/python/src/crypto.rs +++ b/src/sdk/python/src/crypto.rs @@ -51,7 +51,7 @@ pub fn poseidon_hash(messages: Vec<&PyCell>) -> Fp { /// Calculate a Pedersen commitment with an u64 value. #[pyfunction] pub fn pedersen_commitment_u64(value: u64, blind: &PyCell) -> Ep { - Ep(crypto::pedersen::pedersen_commitment_u64(value, blind.borrow().deref().0)) + Ep(crypto::pedersen::pedersen_commitment_u64(value, crypto::Blind(blind.borrow().deref().0))) } /// Calculate a Pedersen commitment with an Fp value. @@ -59,7 +59,7 @@ pub fn pedersen_commitment_u64(value: u64, blind: &PyCell) -> Ep { pub fn pedersen_commitment_base(value: &PyCell, blind: &PyCell) -> Ep { Ep(crypto::pedersen::pedersen_commitment_base( value.borrow().deref().0, - blind.borrow().deref().0, + crypto::Blind(blind.borrow().deref().0), )) } diff --git a/src/sdk/src/crypto/blind.rs b/src/sdk/src/crypto/blind.rs new file mode 100644 index 000000000..40a82b495 --- /dev/null +++ b/src/sdk/src/crypto/blind.rs @@ -0,0 +1,66 @@ +/* This file is part of DarkFi (https://dark.fi) + * + * Copyright (C) 2020-2024 Dyne.org foundation + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU Affero General Public License as + * published by the Free Software Foundation, either version 3 of the + * License, or (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU Affero General Public License for more details. + * + * You should have received a copy of the GNU Affero General Public License + * along with this program. If not, see . + */ + +#[cfg(feature = "async")] +use darkfi_serial::{async_trait, AsyncDecodable, AsyncEncodable}; +use darkfi_serial::{Decodable, Encodable, SerialDecodable, SerialEncodable}; + +use pasta_curves::{group::ff::Field, pallas}; + +#[cfg(feature = "async")] +pub trait EncDecode: Encodable + Decodable + AsyncEncodable + AsyncDecodable {} +#[cfg(not(feature = "async"))] +pub trait EncDecode: Encodable + Decodable {} + +impl EncDecode for pallas::Base {} +impl EncDecode for pallas::Scalar {} + +/// Blinding factor used in bullas. Every bulla should contain one. +#[derive(Debug, Copy, Clone, Eq, PartialEq, SerialEncodable, SerialDecodable)] +pub struct Blind(pub F); + +impl Blind { + pub const ZERO: Self = Self(F::ZERO); + + pub fn random(rng: &mut RngCore) -> Self { + Self(F::random(rng)) + } + + pub fn inner(&self) -> F { + self.0 + } +} + +impl<'a, 'b, F: Field + EncDecode> std::ops::Add<&'b Blind> for &'a Blind { + type Output = Blind; + + #[inline] + fn add(self, rhs: &'b Blind) -> Blind { + Blind(self.0.add(rhs.0)) + } +} + +impl std::ops::AddAssign for Blind { + #[inline] + fn add_assign(&mut self, other: Self) { + self.0.add_assign(other.0) + } +} + +pub type BaseBlind = Blind; +pub type ScalarBlind = Blind; diff --git a/src/sdk/src/crypto/mod.rs b/src/sdk/src/crypto/mod.rs index 6ccc542a7..e979d9dd2 100644 --- a/src/sdk/src/crypto/mod.rs +++ b/src/sdk/src/crypto/mod.rs @@ -16,6 +16,10 @@ * along with this program. If not, see . */ +/// Blinding factors +pub mod blind; +pub use blind::{BaseBlind, Blind, ScalarBlind}; + /// Cryptographic constants pub mod constants; diff --git a/src/sdk/src/crypto/pedersen.rs b/src/sdk/src/crypto/pedersen.rs index e6d4a447e..1958bc3fd 100644 --- a/src/sdk/src/crypto/pedersen.rs +++ b/src/sdk/src/crypto/pedersen.rs @@ -20,6 +20,7 @@ use halo2_gadgets::ecc::chip::FixedPoint; use pasta_curves::{arithmetic::CurveExt, pallas}; use super::{ + blind::ScalarBlind, constants::{ fixed_bases::{ VALUE_COMMITMENT_PERSONALIZATION, VALUE_COMMITMENT_R_BYTES, VALUE_COMMITMENT_V_BYTES, @@ -31,20 +32,20 @@ use super::{ /// Pedersen commitment for a full-width base field element. #[allow(non_snake_case)] -pub fn pedersen_commitment_base(value: pallas::Base, blind: pallas::Scalar) -> pallas::Point { +pub fn pedersen_commitment_base(value: pallas::Base, blind: ScalarBlind) -> pallas::Point { let hasher = pallas::Point::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION); let V = NullifierK.generator(); let R = hasher(&VALUE_COMMITMENT_R_BYTES); - V * fp_mod_fv(value) + R * blind + V * fp_mod_fv(value) + R * blind.inner() } /// Pedersen commitment for a 64-bit value, in the base field. #[allow(non_snake_case)] -pub fn pedersen_commitment_u64(value: u64, blind: pallas::Scalar) -> pallas::Point { +pub fn pedersen_commitment_u64(value: u64, blind: ScalarBlind) -> pallas::Point { let hasher = pallas::Point::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION); let V = hasher(&VALUE_COMMITMENT_V_BYTES); let R = hasher(&VALUE_COMMITMENT_R_BYTES); - V * fp_mod_fv(pallas::Base::from(value)) + R * blind + V * fp_mod_fv(pallas::Base::from(value)) + R * blind.inner() } diff --git a/tests/halo2_vk_ser.rs b/tests/halo2_vk_ser.rs index 8512993db..9231698bb 100644 --- a/tests/halo2_vk_ser.rs +++ b/tests/halo2_vk_ser.rs @@ -18,7 +18,7 @@ use std::io::Cursor; use darkfi_sdk::crypto::{ - pedersen::pedersen_commitment_u64, util::fp_mod_fv, MerkleNode, MerkleTree, PublicKey, + pedersen::pedersen_commitment_u64, util::fp_mod_fv, Blind, MerkleNode, MerkleTree, PublicKey, SecretKey, }; use halo2_gadgets::poseidon::{ @@ -88,7 +88,7 @@ fn halo2_vk_ser() -> Result<()> { let pk = ProvingKey::build(zkbin.k, &circuit); let value = 666_u64; - let value_blind = pallas::Scalar::random(&mut OsRng); + let value_blind = Blind::random(&mut OsRng); let blind = pallas::Base::random(&mut OsRng); let secret = pallas::Base::random(&mut OsRng); let a = pallas::Base::from(42); @@ -120,7 +120,7 @@ fn halo2_vk_ser() -> Result<()> { let (ephem_x, ephem_y) = PublicKey::from(pubkey * fp_mod_fv(ephem_secret.inner())).xy(); let prover_witnesses = vec![ Witness::Base(Value::known(pallas::Base::from(value))), - Witness::Scalar(Value::known(value_blind)), + Witness::Scalar(Value::known(value_blind.inner())), Witness::Base(Value::known(blind)), Witness::Base(Value::known(a)), Witness::Base(Value::known(b)), diff --git a/tests/zkvm_opcodes.rs b/tests/zkvm_opcodes.rs index ac32300a8..c6338d1bd 100644 --- a/tests/zkvm_opcodes.rs +++ b/tests/zkvm_opcodes.rs @@ -17,7 +17,7 @@ */ use darkfi_sdk::crypto::{ - pedersen::pedersen_commitment_u64, util::fp_mod_fv, MerkleNode, MerkleTree, PublicKey, + pedersen::pedersen_commitment_u64, util::fp_mod_fv, Blind, MerkleNode, MerkleTree, PublicKey, SecretKey, }; use halo2_gadgets::poseidon::{ @@ -50,7 +50,7 @@ fn zkvm_opcodes() -> Result<()> { // Values for the proof let value = 666_u64; - let value_blind = pallas::Scalar::random(&mut OsRng); + let value_blind = Blind::random(&mut OsRng); let blind = pallas::Base::random(&mut OsRng); let secret = pallas::Base::random(&mut OsRng); let a = pallas::Base::from(42); @@ -83,7 +83,7 @@ fn zkvm_opcodes() -> Result<()> { let prover_witnesses = vec![ Witness::Base(Value::known(pallas::Base::from(value))), - Witness::Scalar(Value::known(value_blind)), + Witness::Scalar(Value::known(value_blind.inner())), Witness::Base(Value::known(blind)), Witness::Base(Value::known(a)), Witness::Base(Value::known(b)),