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

contract/money: Replace token pedersen commitment with a poseidon hash.

parazyd 3 лет назад
Родитель
Сommit
3d5896b89b

+ 0 - 3
Cargo.lock

@@ -1818,8 +1818,6 @@ dependencies = [
  "darkfi-serial",
  "easy-parallel",
  "futures",
- "hex",
- "libsqlite3-sys",
  "log",
  "rand 0.8.5",
  "rustls-pemfile",
@@ -1828,7 +1826,6 @@ dependencies = [
  "signal-hook",
  "signal-hook-async-std",
  "simplelog",
- "sled",
  "smol",
  "structopt",
  "structopt-toml",

+ 5 - 6
bin/drk/src/rpc_swap.rs

@@ -31,9 +31,8 @@ use darkfi_money_contract::{
 };
 use darkfi_sdk::{
     crypto::{
-        contract_id::MONEY_CONTRACT_ID,
-        pedersen::{pedersen_commitment_base, pedersen_commitment_u64},
-        poseidon_hash, PublicKey, SecretKey, TokenId,
+        contract_id::MONEY_CONTRACT_ID, pedersen::pedersen_commitment_u64, poseidon_hash,
+        PublicKey, SecretKey, TokenId,
     },
     pasta::pallas,
     tx::ContractCall,
@@ -52,7 +51,7 @@ pub struct PartialSwapData {
     value_pair: (u64, u64),
     token_pair: (TokenId, TokenId),
     value_blinds: Vec<pallas::Scalar>,
-    token_blinds: Vec<pallas::Scalar>,
+    token_blinds: Vec<pallas::Base>,
 }
 
 impl fmt::Display for PartialSwapData {
@@ -129,7 +128,7 @@ impl Drk {
 
         // 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::Scalar::random(&mut OsRng), pallas::Scalar::random(&mut OsRng)];
+        let token_blinds = [pallas::Base::random(&mut OsRng), pallas::Base::random(&mut OsRng)];
 
         // Now we should have everything we need to build the swap half
         eprintln!("Creating Mint and Burn circuit proving keys");
@@ -370,7 +369,7 @@ impl Drk {
             }
 
             let valcom = pedersen_commitment_u64(note.value, note.value_blind);
-            let tokcom = pedersen_commitment_base(note.token_id.inner(), note.token_blind);
+            let tokcom = poseidon_hash([note.token_id.inner(), note.token_blind]);
 
             if valcom != params.outputs[output_idx].value_commit {
                 eprintln!(

+ 1 - 1
bin/drk/src/wallet_money.rs

@@ -319,7 +319,7 @@ impl Drk {
             let value_blind: pallas::Scalar = deserialize(&value_blind_bytes)?;
 
             let token_blind_bytes: Vec<u8> = serde_json::from_value(row[8].clone())?;
-            let token_blind: pallas::Scalar = deserialize(&token_blind_bytes)?;
+            let token_blind: pallas::Base = deserialize(&token_blind_bytes)?;
 
             let secret_bytes: Vec<u8> = serde_json::from_value(row[9].clone())?;
             let secret: SecretKey = deserialize(&secret_bytes)?;

+ 2 - 2
src/contract/consensus/src/client/genesis_stake_v1.rs

@@ -64,7 +64,7 @@ impl ConsensusGenesisStakeCallBuilder {
         // enforce that the clear input and the anon output have the same
         // commitments.
         let value_blind = pallas::Scalar::random(&mut OsRng);
-        let token_blind = pallas::Scalar::random(&mut OsRng);
+        let token_blind = pallas::Base::random(&mut OsRng);
         let reward_blind = pallas::Scalar::random(&mut OsRng);
 
         // FIXME: The coin's serial number here is arbitrary, and allows grinding attacks.
@@ -76,7 +76,7 @@ impl ConsensusGenesisStakeCallBuilder {
     pub fn build_with_params(
         &self,
         value_blind: pallas::Scalar,
-        token_blind: pallas::Scalar,
+        token_blind: pallas::Base,
         reward_blind: pallas::Scalar,
         serial: pallas::Base,
     ) -> Result<ConsensusGenesisStakeCallDebris> {

+ 15 - 18
src/contract/money/proof/burn_v1.zk

@@ -1,11 +1,14 @@
+# The k parameter defining the number of rows used in our circuit (2^k)
 k = 13;
 
+# The constants we define for our circuit
 constant "Burn_V1" {
 	EcFixedPointShort VALUE_COMMIT_VALUE,
 	EcFixedPoint VALUE_COMMIT_RANDOM,
 	EcFixedPointBase NULLIFIER_K,
 }
 
+# The witness values we define for our circuit
 witness "Burn_V1" {
 	# The value of this coin
 	Base value,
@@ -14,7 +17,7 @@ witness "Burn_V1" {
 	# Random blinding factor for value commitment
 	Scalar value_blind,
 	# Random blinding factor for the token ID
-	Scalar token_blind,
+	Base token_blind,
 	# Unique serial number corresponding to this coin
 	Base serial,
 	# Allows composing this ZK proof to invoke other contracts
@@ -33,6 +36,7 @@ witness "Burn_V1" {
 	Base signature_secret,
 }
 
+# The definition of our circuit
 circuit "Burn_V1" {
 	# Poseidon hash of the nullifier
 	nullifier = poseidon_hash(secret, serial);
@@ -47,22 +51,17 @@ circuit "Burn_V1" {
 	constrain_instance(ec_get_x(value_commit));
 	constrain_instance(ec_get_y(value_commit));
 
-	# Pedersen commitment for coin's token ID
-	tcv = ec_mul_base(token, NULLIFIER_K);
-	tcr = ec_mul(token_blind, VALUE_COMMIT_RANDOM);
-	token_commit = ec_add(tcv, tcr);
-	# Since token_commit is also a curve point, we'll do the same
-	# coordinate dance:
-	constrain_instance(ec_get_x(token_commit));
-	constrain_instance(ec_get_y(token_commit));
+	# Commitment for coin's token ID. We do a poseidon hash since it's
+	# cheaper than EC operations and doesn't need the homomorphic prop.
+	token_commit = poseidon_hash(token, token_blind);
+	constrain_instance(token_commit);
 
-	# Coin hash
+	# Derive the public key used in the coin from its secret counterpart
 	pub = ec_mul_base(secret, NULLIFIER_K);
-	pub_x = ec_get_x(pub);
-	pub_y = ec_get_y(pub);
+	# Coin hash
 	C = poseidon_hash(
-		pub_x,
-		pub_y,
+		ec_get_x(pub),
+		ec_get_y(pub),
 		value,
 		token,
 		serial,
@@ -91,10 +90,8 @@ circuit "Burn_V1" {
 	# Finally, we derive a public key for the signature and
 	# constrain its coordinates:
 	signature_public = ec_mul_base(signature_secret, NULLIFIER_K);
-	signature_x = ec_get_x(signature_public);
-	signature_y = ec_get_y(signature_public);
-	constrain_instance(signature_x);
-	constrain_instance(signature_y);
+	constrain_instance(ec_get_x(signature_public));
+	constrain_instance(ec_get_y(signature_public));
 
 	# At this point we've enforced all of our public inputs.
 }

+ 9 - 9
src/contract/money/proof/mint_v1.zk

@@ -1,11 +1,14 @@
+# The k parameter defining the number of rows used in our circuit (2^k)
 k = 13;
 
+# The constants we define for our circuit
 constant "Mint_V1" {
 	EcFixedPointShort VALUE_COMMIT_VALUE,
 	EcFixedPoint VALUE_COMMIT_RANDOM,
 	EcFixedPointBase NULLIFIER_K,
 }
 
+# The witness values we define for our circuit
 witness "Mint_V1" {
 	# X coordinate for public key
 	Base pub_x,
@@ -24,9 +27,10 @@ witness "Mint_V1" {
 	# Random blinding factor for the value commitment
 	Scalar value_blind,
 	# Random blinding factor for the token ID
-	Scalar token_blind,
+	Base token_blind,
 }
 
+# The definition of our circuit
 circuit "Mint_V1" {
 	# Poseidon hash of the coin
 	C = poseidon_hash(
@@ -49,14 +53,10 @@ circuit "Mint_V1" {
 	constrain_instance(ec_get_x(value_commit));
 	constrain_instance(ec_get_y(value_commit));
 
-	# Pedersen commitment for coin's token ID
-	tcv = ec_mul_base(token, NULLIFIER_K);
-	tcr = ec_mul(token_blind, VALUE_COMMIT_RANDOM);
-	token_commit = ec_add(tcv, tcr);
-	# Since token_commit is also a curve point, we'll do the same
-	# coordinate dance:
-	constrain_instance(ec_get_x(token_commit));
-	constrain_instance(ec_get_y(token_commit));
+	# Commitment for coin's token ID. We do a poseidon hash since it's
+	# cheaper than EC operations and doesn't need the homomorphic prop.
+	token_commit = poseidon_hash(token, token_blind);
+	constrain_instance(token_commit);
 
 	# At this point we've enforced all of our public inputs.
 }

+ 4 - 9
src/contract/money/proof/token_mint_v1.zk

@@ -26,12 +26,10 @@ witness "TokenMint_V1" {
 	# Random blinding factor for the value commitment
 	Scalar value_blind,
 	# Random blinding factor for the token ID
-	Scalar token_blind,
+	Base token_blind,
 }
 
 circuit "TokenMint_V1" {
-	# TODO: verify if supply must be > 0 and add corresponding opcode
-
 	# TokenID derivation path (See darkfi_sdk::crypto::TokenId)
 	derivation_path = witness_base(69);
 
@@ -65,10 +63,7 @@ circuit "TokenMint_V1" {
 	constrain_instance(ec_get_x(value_commit));
 	constrain_instance(ec_get_y(value_commit));
 
-	# Pedersen commitment for the token ID
-	tcv = ec_mul_base(token_id, NULLIFIER_K);
-	tcr = ec_mul(token_blind, VALUE_COMMIT_RANDOM);
-	token_commit = ec_add(tcv, tcr);
-	constrain_instance(ec_get_x(token_commit));
-	constrain_instance(ec_get_y(token_commit));
+	# Commitment for the coin's token ID
+	token_commit = poseidon_hash(token_id, token_blind);
+	constrain_instance(token_commit);
 }

+ 6 - 14
src/contract/money/src/client/genesis_mint_v1.rs

@@ -47,23 +47,16 @@ pub struct GenesisMintCallDebris {
 pub struct GenesisMintRevealed {
     pub coin: Coin,
     pub value_commit: pallas::Point,
-    pub token_commit: pallas::Point,
+    pub token_commit: pallas::Base,
 }
 
 impl GenesisMintRevealed {
     pub fn to_vec(&self) -> Vec<pallas::Base> {
         let valcom_coords = self.value_commit.to_affine().coordinates().unwrap();
-        let tokcom_coords = self.token_commit.to_affine().coordinates().unwrap();
 
         // NOTE: It's important to keep these in the same order
         // as the `constrain_instance` calls in the zkas code.
-        vec![
-            self.coin.inner(),
-            *valcom_coords.x(),
-            *valcom_coords.y(),
-            *tokcom_coords.x(),
-            *tokcom_coords.y(),
-        ]
+        vec![self.coin.inner(), *valcom_coords.x(), *valcom_coords.y(), self.token_commit]
     }
 }
 
@@ -104,12 +97,11 @@ impl GenesisMintCallBuilder {
             public_key: self.keypair.public,
         };
 
-        // We just create the pedersen commitment blinds here. We simply
-        // enforce 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?
+        // 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::Scalar::random(&mut OsRng);
+        let token_blind = pallas::Base::random(&mut OsRng);
 
         let c_input = ClearInput {
             value: input.value,

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

@@ -112,7 +112,7 @@ pub struct MoneyNote {
     /// Blinding factor for the value pedersen commitment
     pub value_blind: pallas::Scalar,
     /// Blinding factor for the token ID pedersen commitment
-    pub token_blind: pallas::Scalar,
+    pub token_blind: pallas::Base,
     /// Attached memo (arbitrary data)
     pub memo: Vec<u8>,
 }
@@ -158,7 +158,7 @@ impl From<ConsensusNote> for MoneyNote {
             spend_hook: pallas::Base::ZERO,
             user_data: pallas::Base::ZERO,
             value_blind: consensus_note.value_blind,
-            token_blind: pallas::Scalar::ZERO,
+            token_blind: pallas::Base::ZERO,
             memo: vec![],
         }
     }

+ 8 - 10
src/contract/money/src/client/stake_v1.rs

@@ -27,8 +27,8 @@ use darkfi_sdk::{
     bridgetree,
     bridgetree::Hashable,
     crypto::{
-        pasta_prelude::*, pedersen_commitment_base, pedersen_commitment_u64, poseidon_hash,
-        MerkleNode, MerkleTree, Nullifier, PublicKey, SecretKey, DARK_TOKEN_ID,
+        pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, MerkleNode, MerkleTree,
+        Nullifier, PublicKey, SecretKey, DARK_TOKEN_ID,
     },
     pasta::pallas,
 };
@@ -49,7 +49,7 @@ pub struct MoneyStakeCallDebris {
 
 pub struct MoneyStakeBurnRevealed {
     pub value_commit: pallas::Point,
-    pub token_commit: pallas::Point,
+    pub token_commit: pallas::Base,
     pub nullifier: Nullifier,
     pub merkle_root: MerkleNode,
     pub spend_hook: pallas::Base,
@@ -60,7 +60,6 @@ pub struct MoneyStakeBurnRevealed {
 impl MoneyStakeBurnRevealed {
     pub fn to_vec(&self) -> Vec<pallas::Base> {
         let valcom_coords = self.value_commit.to_affine().coordinates().unwrap();
-        let tokcom_coords = self.token_commit.to_affine().coordinates().unwrap();
         let sigpub_coords = self.signature_public.inner().to_affine().coordinates().unwrap();
 
         // NOTE: It's important to keep these in the same order
@@ -69,8 +68,7 @@ impl MoneyStakeBurnRevealed {
             self.nullifier.inner(),
             *valcom_coords.x(),
             *valcom_coords.y(),
-            *tokcom_coords.x(),
-            *tokcom_coords.y(),
+            self.token_commit,
             self.merkle_root.inner(),
             self.user_data_enc,
             pallas::Base::ZERO, // We force spend_hook==0 here
@@ -117,7 +115,7 @@ impl MoneyStakeCallBuilder {
 
         // Create new random blinds and an ephemeral signature key
         let value_blind = pallas::Scalar::random(&mut OsRng);
-        let token_blind = pallas::Scalar::random(&mut OsRng);
+        let token_blind = pallas::Base::random(&mut OsRng);
         let signature_secret = SecretKey::random(&mut OsRng);
         let user_data_blind = pallas::Base::random(&mut OsRng);
 
@@ -158,7 +156,7 @@ pub fn create_stake_burn_proof(
     pk: &ProvingKey,
     input: &TransactionBuilderInputInfo,
     value_blind: pallas::Scalar,
-    token_blind: pallas::Scalar,
+    token_blind: pallas::Base,
     user_data_blind: pallas::Base,
     signature_secret: SecretKey,
 ) -> Result<(Proof, MoneyStakeBurnRevealed)> {
@@ -194,7 +192,7 @@ pub fn create_stake_burn_proof(
 
     let user_data_enc = poseidon_hash([input.note.user_data, user_data_blind]);
     let value_commit = pedersen_commitment_u64(input.note.value, value_blind);
-    let token_commit = pedersen_commitment_base(input.note.token_id.inner(), token_blind);
+    let token_commit = poseidon_hash([input.note.token_id.inner(), token_blind]);
 
     let public_inputs = MoneyStakeBurnRevealed {
         value_commit,
@@ -210,7 +208,7 @@ pub fn create_stake_burn_proof(
         Witness::Base(Value::known(pallas::Base::from(input.note.value))),
         Witness::Base(Value::known(input.note.token_id.inner())),
         Witness::Scalar(Value::known(value_blind)),
-        Witness::Scalar(Value::known(token_blind)),
+        Witness::Base(Value::known(token_blind)),
         Witness::Base(Value::known(input.note.serial)),
         Witness::Base(Value::known(input.note.spend_hook)),
         Witness::Base(Value::known(input.note.user_data)),

+ 1 - 1
src/contract/money/src/client/swap_v1.rs

@@ -76,7 +76,7 @@ pub struct SwapCallBuilder {
     /// `token_blinds`.
     pub value_blinds: [pallas::Scalar; 2],
     /// The blinds to be used for token ID pedersen commitments
-    pub token_blinds: [pallas::Scalar; 2],
+    pub token_blinds: [pallas::Base; 2],
     /// The coin to be used as the input to the swap
     pub coin: OwnCoin,
     /// Merkle tree of coins used to create inclusion proofs

+ 8 - 10
src/contract/money/src/client/token_mint_v1.rs

@@ -23,8 +23,8 @@ use darkfi::{
 };
 use darkfi_sdk::{
     crypto::{
-        note::AeadEncryptedNote, pasta_prelude::*, pedersen_commitment_base,
-        pedersen_commitment_u64, poseidon_hash, Keypair, PublicKey, TokenId,
+        note::AeadEncryptedNote, pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, Keypair,
+        PublicKey, TokenId,
     },
     pasta::pallas,
 };
@@ -49,14 +49,13 @@ pub struct TokenMintRevealed {
     pub token_id: TokenId,
     pub coin: Coin,
     pub value_commit: pallas::Point,
-    pub token_commit: pallas::Point,
+    pub token_commit: pallas::Base,
 }
 
 impl TokenMintRevealed {
     pub fn to_vec(&self) -> Vec<pallas::Base> {
         let (sig_x, sig_y) = self.signature_public.xy();
         let valcom_coords = self.value_commit.to_affine().coordinates().unwrap();
-        let tokcom_coords = self.token_commit.to_affine().coordinates().unwrap();
 
         // NOTE: It's important to keep these in the same order
         // as the `constrain_instance` calls in the zkas code.
@@ -67,8 +66,7 @@ impl TokenMintRevealed {
             self.coin.inner(),
             *valcom_coords.x(),
             *valcom_coords.y(),
-            *tokcom_coords.x(),
-            *tokcom_coords.y(),
+            self.token_commit,
         ]
     }
 }
@@ -117,7 +115,7 @@ impl TokenMintCallBuilder {
         // 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::Scalar::random(&mut OsRng);
+        let token_blind = pallas::Base::random(&mut OsRng);
 
         let c_input = ClearInput {
             value: input.value,
@@ -175,7 +173,7 @@ pub fn create_token_mint_proof(
     output: &TransactionBuilderOutputInfo,
     mint_authority: &Keypair,
     value_blind: pallas::Scalar,
-    token_blind: pallas::Scalar,
+    token_blind: pallas::Base,
     serial: pallas::Base,
     spend_hook: pallas::Base,
     user_data: pallas::Base,
@@ -183,7 +181,7 @@ pub fn create_token_mint_proof(
     let token_id = TokenId::derive(mint_authority.secret);
 
     let value_commit = pedersen_commitment_u64(output.value, value_blind);
-    let token_commit = pedersen_commitment_base(token_id.inner(), token_blind);
+    let token_commit = poseidon_hash([token_id.inner(), token_blind]);
 
     let (rcpt_x, rcpt_y) = output.public_key.xy();
 
@@ -214,7 +212,7 @@ pub fn create_token_mint_proof(
         Witness::Base(Value::known(spend_hook)),
         Witness::Base(Value::known(user_data)),
         Witness::Scalar(Value::known(value_blind)),
-        Witness::Scalar(Value::known(token_blind)),
+        Witness::Base(Value::known(token_blind)),
     ];
 
     let circuit = ZkCircuit::new(prover_witnesses, zkbin);

+ 13 - 23
src/contract/money/src/client/transfer_v1.rs

@@ -27,9 +27,8 @@ use darkfi_sdk::{
     bridgetree,
     bridgetree::Hashable,
     crypto::{
-        note::AeadEncryptedNote, pasta_prelude::*, pedersen_commitment_base,
-        pedersen_commitment_u64, poseidon_hash, Keypair, MerkleNode, MerkleTree, Nullifier,
-        PublicKey, SecretKey, TokenId,
+        note::AeadEncryptedNote, pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, Keypair,
+        MerkleNode, MerkleTree, Nullifier, PublicKey, SecretKey, TokenId,
     },
     pasta::pallas,
 };
@@ -62,29 +61,22 @@ pub struct TransferCallDebris {
 pub struct TransferMintRevealed {
     pub coin: Coin,
     pub value_commit: pallas::Point,
-    pub token_commit: pallas::Point,
+    pub token_commit: pallas::Base,
 }
 
 impl TransferMintRevealed {
     pub fn to_vec(&self) -> Vec<pallas::Base> {
         let valcom_coords = self.value_commit.to_affine().coordinates().unwrap();
-        let tokcom_coords = self.token_commit.to_affine().coordinates().unwrap();
 
         // NOTE: It's important to keep these in the same order
         // as the `constrain_instance` calls in the zkas code.
-        vec![
-            self.coin.inner(),
-            *valcom_coords.x(),
-            *valcom_coords.y(),
-            *tokcom_coords.x(),
-            *tokcom_coords.y(),
-        ]
+        vec![self.coin.inner(), *valcom_coords.x(), *valcom_coords.y(), self.token_commit]
     }
 }
 
 pub struct TransferBurnRevealed {
     pub value_commit: pallas::Point,
-    pub token_commit: pallas::Point,
+    pub token_commit: pallas::Base,
     pub nullifier: Nullifier,
     pub merkle_root: MerkleNode,
     pub spend_hook: pallas::Base,
@@ -95,7 +87,6 @@ pub struct TransferBurnRevealed {
 impl TransferBurnRevealed {
     pub fn to_vec(&self) -> Vec<pallas::Base> {
         let valcom_coords = self.value_commit.to_affine().coordinates().unwrap();
-        let tokcom_coords = self.token_commit.to_affine().coordinates().unwrap();
         let sigpub_coords = self.signature_public.inner().to_affine().coordinates().unwrap();
 
         // NOTE: It's important to keep these in the same order
@@ -104,8 +95,7 @@ impl TransferBurnRevealed {
             self.nullifier.inner(),
             *valcom_coords.x(),
             *valcom_coords.y(),
-            *tokcom_coords.x(),
-            *tokcom_coords.y(),
+            self.token_commit,
             self.merkle_root.inner(),
             self.user_data_enc,
             self.spend_hook,
@@ -259,7 +249,7 @@ impl TransferCallBuilder {
         let mut params =
             MoneyTransferParamsV1 { clear_inputs: vec![], inputs: vec![], outputs: vec![] };
 
-        let token_blind = pallas::Scalar::random(&mut OsRng);
+        let token_blind = pallas::Base::random(&mut OsRng);
         for input in clear_inputs {
             let signature_public = PublicKey::from_secret(input.signature_secret);
             let value_blind = pallas::Scalar::random(&mut OsRng);
@@ -393,7 +383,7 @@ pub fn create_transfer_burn_proof(
     pk: &ProvingKey,
     input: &TransactionBuilderInputInfo,
     value_blind: pallas::Scalar,
-    token_blind: pallas::Scalar,
+    token_blind: pallas::Base,
     user_data_blind: pallas::Base,
     signature_secret: SecretKey,
 ) -> Result<(Proof, TransferBurnRevealed)> {
@@ -429,7 +419,7 @@ pub fn create_transfer_burn_proof(
 
     let user_data_enc = poseidon_hash([input.note.user_data, user_data_blind]);
     let value_commit = pedersen_commitment_u64(input.note.value, value_blind);
-    let token_commit = pedersen_commitment_base(input.note.token_id.inner(), token_blind);
+    let token_commit = poseidon_hash([input.note.token_id.inner(), token_blind]);
 
     let public_inputs = TransferBurnRevealed {
         value_commit,
@@ -445,7 +435,7 @@ pub fn create_transfer_burn_proof(
         Witness::Base(Value::known(pallas::Base::from(input.note.value))),
         Witness::Base(Value::known(input.note.token_id.inner())),
         Witness::Scalar(Value::known(value_blind)),
-        Witness::Scalar(Value::known(token_blind)),
+        Witness::Base(Value::known(token_blind)),
         Witness::Base(Value::known(input.note.serial)),
         Witness::Base(Value::known(input.note.spend_hook)),
         Witness::Base(Value::known(input.note.user_data)),
@@ -468,13 +458,13 @@ pub fn create_transfer_mint_proof(
     pk: &ProvingKey,
     output: &TransactionBuilderOutputInfo,
     value_blind: pallas::Scalar,
-    token_blind: pallas::Scalar,
+    token_blind: pallas::Base,
     serial: pallas::Base,
     spend_hook: pallas::Base,
     user_data: pallas::Base,
 ) -> Result<(Proof, TransferMintRevealed)> {
     let value_commit = pedersen_commitment_u64(output.value, value_blind);
-    let token_commit = pedersen_commitment_base(output.token_id.inner(), token_blind);
+    let token_commit = poseidon_hash([output.token_id.inner(), token_blind]);
     let (pub_x, pub_y) = output.public_key.xy();
 
     let coin = Coin::from(poseidon_hash([
@@ -498,7 +488,7 @@ pub fn create_transfer_mint_proof(
         Witness::Base(Value::known(spend_hook)),
         Witness::Base(Value::known(user_data)),
         Witness::Scalar(Value::known(value_blind)),
-        Witness::Scalar(Value::known(token_blind)),
+        Witness::Base(Value::known(token_blind)),
     ];
 
     let circuit = ZkCircuit::new(prover_witnesses, zkbin);

+ 8 - 16
src/contract/money/src/client/unstake_v1.rs

@@ -25,9 +25,8 @@ use darkfi::{
 };
 use darkfi_sdk::{
     crypto::{
-        note::AeadEncryptedNote, pasta_prelude::*, pedersen_commitment_base,
-        pedersen_commitment_u64, poseidon_hash, MerkleNode, Nullifier, PublicKey, TokenId,
-        DARK_TOKEN_ID,
+        note::AeadEncryptedNote, pasta_prelude::*, pedersen_commitment_u64, poseidon_hash,
+        MerkleNode, Nullifier, PublicKey, TokenId, DARK_TOKEN_ID,
     },
     pasta::pallas,
 };
@@ -47,23 +46,16 @@ pub struct MoneyUnstakeCallDebris {
 pub struct MoneyMintRevealed {
     pub coin: Coin,
     pub value_commit: pallas::Point,
-    pub token_commit: pallas::Point,
+    pub token_commit: pallas::Base,
 }
 
 impl MoneyMintRevealed {
     pub fn to_vec(&self) -> Vec<pallas::Base> {
         let valcom_coords = self.value_commit.to_affine().coordinates().unwrap();
-        let tokcom_coords = self.token_commit.to_affine().coordinates().unwrap();
 
         // NOTE: It's important to keep these in the same order
         // as the `constrain_instance` calls in the zkas code.
-        vec![
-            self.coin.inner(),
-            *valcom_coords.x(),
-            *valcom_coords.y(),
-            *tokcom_coords.x(),
-            *tokcom_coords.y(),
-        ]
+        vec![self.coin.inner(), *valcom_coords.x(), *valcom_coords.y(), self.token_commit]
     }
 }
 
@@ -108,7 +100,7 @@ impl MoneyUnstakeCallBuilder {
         let serial = pallas::Base::random(&mut OsRng);
         let spend_hook = pallas::Base::ZERO;
         let user_data_enc = pallas::Base::random(&mut OsRng);
-        let token_blind = pallas::Scalar::ZERO;
+        let token_blind = pallas::Base::ZERO;
 
         info!("Building Money::UnstakeV1 Mint ZK proof");
         let (proof, public_inputs) = create_unstake_mint_proof(
@@ -167,13 +159,13 @@ pub fn create_unstake_mint_proof(
     pk: &ProvingKey,
     output: &TransactionBuilderOutputInfo,
     value_blind: pallas::Scalar,
-    token_blind: pallas::Scalar,
+    token_blind: pallas::Base,
     serial: pallas::Base,
     spend_hook: pallas::Base,
     user_data: pallas::Base,
 ) -> Result<(Proof, MoneyMintRevealed)> {
     let value_commit = pedersen_commitment_u64(output.value, value_blind);
-    let token_commit = pedersen_commitment_base(output.token_id.inner(), token_blind);
+    let token_commit = poseidon_hash([output.token_id.inner(), token_blind]);
     let (pub_x, pub_y) = output.public_key.xy();
 
     let coin = Coin::from(poseidon_hash([
@@ -197,7 +189,7 @@ pub fn create_unstake_mint_proof(
         Witness::Base(Value::known(spend_hook)),
         Witness::Base(Value::known(user_data)),
         Witness::Scalar(Value::known(value_blind)),
-        Witness::Scalar(Value::known(token_blind)),
+        Witness::Base(Value::known(token_blind)),
     ];
 
     let circuit = ZkCircuit::new(prover_witnesses, zkbin);

+ 3 - 8
src/contract/money/src/entrypoint/genesis_mint_v1.rs

@@ -17,10 +17,7 @@
  */
 
 use darkfi_sdk::{
-    crypto::{
-        pasta_prelude::*, pedersen_commitment_base, pedersen_commitment_u64, ContractId,
-        DARK_TOKEN_ID,
-    },
+    crypto::{pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, ContractId, DARK_TOKEN_ID},
     db::{db_contains_key, db_lookup},
     error::ContractError,
     msg,
@@ -52,7 +49,6 @@ pub(crate) fn money_genesis_mint_get_metadata_v1(
 
     // Grab the pedersen commitment from the anonymous output
     let value_coords = params.output.value_commit.to_affine().coordinates().unwrap();
-    let token_coords = params.output.token_commit.to_affine().coordinates().unwrap();
 
     zk_public_inputs.push((
         MONEY_CONTRACT_ZKAS_MINT_NS_V1.to_string(),
@@ -60,8 +56,7 @@ pub(crate) fn money_genesis_mint_get_metadata_v1(
             params.output.coin.inner(),
             *value_coords.x(),
             *value_coords.y(),
-            *token_coords.x(),
-            *token_coords.y(),
+            params.output.token_commit,
         ],
     ));
 
@@ -115,7 +110,7 @@ pub(crate) fn money_genesis_mint_process_instruction_v1(
         return Err(MoneyError::ValueMismatch.into())
     }
 
-    if pedersen_commitment_base(params.input.token_id.inner(), params.input.token_blind) !=
+    if poseidon_hash([params.input.token_id.inner(), params.input.token_blind]) !=
         params.output.token_commit
     {
         msg!("[GenesisMintV1] Error: Token commitment mismatch");

+ 3 - 8
src/contract/money/src/entrypoint/stake_v1.rs

@@ -17,10 +17,7 @@
  */
 
 use darkfi_sdk::{
-    crypto::{
-        pasta_prelude::*, pedersen_commitment_base, ContractId, CONSENSUS_CONTRACT_ID,
-        DARK_TOKEN_ID,
-    },
+    crypto::{pasta_prelude::*, poseidon_hash, ContractId, CONSENSUS_CONTRACT_ID, DARK_TOKEN_ID},
     db::{db_contains_key, db_lookup, db_set},
     error::{ContractError, ContractResult},
     msg,
@@ -54,7 +51,6 @@ pub(crate) fn money_stake_get_metadata_v1(
     // Grab the pedersen commitments and signature pubkeys from the
     // anonymous input
     let value_coords = input.value_commit.to_affine().coordinates().unwrap();
-    let token_coords = input.token_commit.to_affine().coordinates().unwrap();
     let (sig_x, sig_y) = input.signature_public.xy();
 
     // It is very important that these are in the same order as the
@@ -66,8 +62,7 @@ pub(crate) fn money_stake_get_metadata_v1(
             input.nullifier.inner(),
             *value_coords.x(),
             *value_coords.y(),
-            *token_coords.x(),
-            *token_coords.y(),
+            input.token_commit,
             input.merkle_root.inner(),
             input.user_data_enc,
             pallas::Base::ZERO, // We enforce spend_hook==0
@@ -112,7 +107,7 @@ pub(crate) fn money_stake_process_instruction_v1(
     }
 
     // Only native token can be staked
-    if input.token_commit != pedersen_commitment_base(DARK_TOKEN_ID.inner(), params.token_blind) {
+    if input.token_commit != poseidon_hash([DARK_TOKEN_ID.inner(), params.token_blind]) {
         msg!("[MoneyStakeV1] Error: Input used non-native token");
         return Err(MoneyError::StakeInputNonNativeToken.into())
     }

+ 0 - 1
src/contract/money/src/entrypoint/token_freeze_v1.rs

@@ -75,7 +75,6 @@ pub(crate) fn money_token_freeze_process_instruction_v1(
 
     // We just check if the mint was already frozen beforehand
     let token_freeze_db = db_lookup(cid, MONEY_CONTRACT_TOKEN_FREEZE_TREE)?;
-
     let token_id = TokenId::derive_public(params.signature_public);
 
     // Check that the mint is not frozen

+ 3 - 6
src/contract/money/src/entrypoint/token_mint_v1.rs

@@ -18,8 +18,7 @@
 
 use darkfi_sdk::{
     crypto::{
-        pasta_prelude::*, pedersen_commitment_base, pedersen_commitment_u64, ContractId,
-        MerkleNode, TokenId,
+        pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, ContractId, MerkleNode, TokenId,
     },
     db::{db_contains_key, db_lookup, db_set},
     error::{ContractError, ContractResult},
@@ -59,7 +58,6 @@ pub(crate) fn money_token_mint_get_metadata_v1(
     let token_id = TokenId::derive_public(params.input.signature_public);
 
     let value_coords = params.output.value_commit.to_affine().coordinates().unwrap();
-    let token_coords = params.output.token_commit.to_affine().coordinates().unwrap();
 
     zk_public_inputs.push((
         MONEY_CONTRACT_ZKAS_TOKEN_MINT_NS_V1.to_string(),
@@ -70,8 +68,7 @@ pub(crate) fn money_token_mint_get_metadata_v1(
             params.output.coin.inner(),
             *value_coords.x(),
             *value_coords.y(),
-            *token_coords.x(),
-            *token_coords.y(),
+            params.output.token_commit,
         ],
     ));
 
@@ -126,7 +123,7 @@ pub(crate) fn money_token_mint_process_instruction_v1(
         return Err(MoneyError::ValueMismatch.into())
     }
 
-    if pedersen_commitment_base(params.input.token_id.inner(), params.input.token_blind) !=
+    if poseidon_hash([params.input.token_id.inner(), params.input.token_blind]) !=
         params.output.token_commit
     {
         msg!("[MintV1] Error: Token commitment mismatch");

+ 5 - 14
src/contract/money/src/entrypoint/transfer_v1.rs

@@ -18,8 +18,8 @@
 
 use darkfi_sdk::{
     crypto::{
-        pasta_prelude::*, pedersen_commitment_base, pedersen_commitment_u64, ContractId,
-        MerkleNode, PublicKey, DARK_TOKEN_ID,
+        pasta_prelude::*, pedersen_commitment_u64, poseidon_hash, ContractId, MerkleNode,
+        PublicKey, DARK_TOKEN_ID,
     },
     db::{db_contains_key, db_get, db_lookup, db_set},
     error::{ContractError, ContractResult},
@@ -61,7 +61,6 @@ pub(crate) fn money_transfer_get_metadata_v1(
     // anonymous inputs
     for input in &params.inputs {
         let value_coords = input.value_commit.to_affine().coordinates().unwrap();
-        let token_coords = input.token_commit.to_affine().coordinates().unwrap();
         let (sig_x, sig_y) = input.signature_public.xy();
 
         // It is very important that these are in the same order as the
@@ -73,8 +72,7 @@ pub(crate) fn money_transfer_get_metadata_v1(
                 input.nullifier.inner(),
                 *value_coords.x(),
                 *value_coords.y(),
-                *token_coords.x(),
-                *token_coords.y(),
+                input.token_commit,
                 input.merkle_root.inner(),
                 input.user_data_enc,
                 input.spend_hook,
@@ -89,17 +87,10 @@ pub(crate) fn money_transfer_get_metadata_v1(
     // Grab the pedersen commitments from the anonymous outputs
     for output in &params.outputs {
         let value_coords = output.value_commit.to_affine().coordinates().unwrap();
-        let token_coords = output.token_commit.to_affine().coordinates().unwrap();
 
         zk_public_inputs.push((
             MONEY_CONTRACT_ZKAS_MINT_NS_V1.to_string(),
-            vec![
-                output.coin.inner(),
-                *value_coords.x(),
-                *value_coords.y(),
-                *token_coords.x(),
-                *token_coords.y(),
-            ],
+            vec![output.coin.inner(), *value_coords.x(), *value_coords.y(), output.token_commit],
         ));
     }
 
@@ -247,7 +238,7 @@ pub(crate) fn money_transfer_process_instruction_v1(
         params
             .clear_inputs
             .iter()
-            .any(|x| pedersen_commitment_base(x.token_id.inner(), x.token_blind) != tokcom);
+            .any(|x| poseidon_hash([x.token_id.inner(), x.token_blind]) != tokcom);
 
     if failed_tokcom {
         msg!("[TransferV1] Error: Token commitments do not match");

+ 4 - 7
src/contract/money/src/entrypoint/unstake_v1.rs

@@ -18,8 +18,8 @@
 
 use darkfi_sdk::{
     crypto::{
-        pasta_prelude::*, pedersen_commitment_base, ContractId, MerkleNode, PublicKey,
-        CONSENSUS_CONTRACT_ID, DARK_TOKEN_ID,
+        pasta_prelude::*, poseidon_hash, ContractId, MerkleNode, PublicKey, CONSENSUS_CONTRACT_ID,
+        DARK_TOKEN_ID,
     },
     db::{db_contains_key, db_lookup, db_set},
     error::{ContractError, ContractResult},
@@ -54,7 +54,6 @@ pub(crate) fn money_unstake_get_metadata_v1(
 
     // Grab the pedersen commitment from the anonymous output
     let value_coords = params.output.value_commit.to_affine().coordinates().unwrap();
-    let token_coords = params.output.token_commit.to_affine().coordinates().unwrap();
 
     zk_public_inputs.push((
         MONEY_CONTRACT_ZKAS_MINT_NS_V1.to_string(),
@@ -62,8 +61,7 @@ pub(crate) fn money_unstake_get_metadata_v1(
             params.output.coin.inner(),
             *value_coords.x(),
             *value_coords.y(),
-            *token_coords.x(),
-            *token_coords.y(),
+            params.output.token_commit,
         ],
     ));
 
@@ -128,8 +126,7 @@ pub(crate) fn money_unstake_process_instruction_v1(
     // Only native token can be minted here.
     // Since consensus coins don't have token commitments, we use zero as
     // the token blind for the token commitment of the newly minted token
-    if output.token_commit != pedersen_commitment_base(DARK_TOKEN_ID.inner(), pallas::Scalar::ZERO)
-    {
+    if output.token_commit != poseidon_hash([DARK_TOKEN_ID.inner(), pallas::Base::ZERO]) {
         msg!("[MoneyUnstakeV1] Error: Input used non-native token");
         return Err(MoneyError::StakeInputNonNativeToken.into())
     }

+ 6 - 6
src/contract/money/src/model.rs

@@ -68,7 +68,7 @@ pub struct ClearInput {
     /// Blinding factor for `value`
     pub value_blind: pallas::Scalar,
     /// Blinding factor for `token_id`
-    pub token_blind: pallas::Scalar,
+    pub token_blind: pallas::Base,
     /// Public key for the signature
     pub signature_public: PublicKey,
 }
@@ -78,8 +78,8 @@ pub struct ClearInput {
 pub struct Input {
     /// Pedersen commitment for the input's value
     pub value_commit: pallas::Point,
-    /// Pedersen commitment for the input's token ID
-    pub token_commit: pallas::Point,
+    /// Commitment for the input's token ID
+    pub token_commit: pallas::Base,
     /// Revealed nullifier
     pub nullifier: Nullifier,
     /// Revealed Merkle root
@@ -116,8 +116,8 @@ pub struct ConsensusInput {
 pub struct Output {
     /// Pedersen commitment for the output's value
     pub value_commit: pallas::Point,
-    /// Pedersen commitment for the output's token ID
-    pub token_commit: pallas::Point,
+    /// Commitment for the output's token ID
+    pub token_commit: pallas::Base,
     /// Minted coin
     pub coin: Coin,
     /// AEAD encrypted note
@@ -192,7 +192,7 @@ pub struct MoneyTokenFreezeUpdateV1 {
 // ANCHOR: MoneyStakeParams
 pub struct MoneyStakeParamsV1 {
     /// Blinding factor for `token_id`
-    pub token_blind: pallas::Scalar,
+    pub token_blind: pallas::Base,
     /// Anonymous input
     pub input: Input,
 }

+ 1 - 1
src/contract/test-harness/src/consensus_genesis_stake.rs

@@ -60,7 +60,7 @@ impl TestHarness {
         }
         .build_with_params(
             pallas::Scalar::random(&mut OsRng),
-            pallas::Scalar::random(&mut OsRng),
+            pallas::Base::random(&mut OsRng),
             pallas::Scalar::random(&mut OsRng),
             pallas::Base::from(28),
         )?;

+ 5 - 5
src/contract/test-harness/src/money_otc_swap.rs

@@ -25,7 +25,7 @@ use darkfi_money_contract::{
     MoneyFunction, MONEY_CONTRACT_ZKAS_BURN_NS_V1, MONEY_CONTRACT_ZKAS_MINT_NS_V1,
 };
 use darkfi_sdk::{
-    crypto::{MerkleNode, ValueBlind, MONEY_CONTRACT_ID},
+    crypto::{MerkleNode, MONEY_CONTRACT_ID},
     pasta::pallas,
     ContractCall,
 };
@@ -62,10 +62,10 @@ impl TestHarness {
         let rcpt_user_data_blind = pallas::Base::random(&mut OsRng);
 
         // Generating  swap blinds
-        let value_send_blind = ValueBlind::random(&mut OsRng);
-        let value_recv_blind = ValueBlind::random(&mut OsRng);
-        let token_send_blind = ValueBlind::random(&mut OsRng);
-        let token_recv_blind = ValueBlind::random(&mut OsRng);
+        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);
 
         // Builder first holder part
         let builder = SwapCallBuilder {

+ 2 - 3
src/sdk/python/src/point.rs

@@ -23,7 +23,6 @@ use darkfi_sdk::{
             VALUE_COMMITMENT_V_BYTES,
         },
         util::mod_r_p,
-        ValueCommit,
     },
     pasta::{
         arithmetic::CurveExt,
@@ -55,7 +54,7 @@ impl Point {
 
     #[staticmethod]
     fn mul_short(value: &Base) -> Self {
-        let hasher = ValueCommit::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION);
+        let hasher = pallas::Point::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION);
         let v = hasher(&VALUE_COMMITMENT_V_BYTES);
         Self(v * mod_r_p(value.0))
     }
@@ -70,7 +69,7 @@ impl Point {
     // Why not a pycell?
     #[staticmethod]
     fn mul_r_generator(blind: &Scalar) -> Self {
-        let hasher = ValueCommit::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION);
+        let hasher = pallas::Point::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION);
         let r = hasher(&VALUE_COMMITMENT_R_BYTES);
         let r = Self(r);
         Self(r.0 * blind.0)

+ 1 - 1
src/sdk/src/crypto/mod.rs

@@ -51,7 +51,7 @@ pub use nullifier::Nullifier;
 
 /// Pedersen commitment utilities
 pub mod pedersen;
-pub use pedersen::{pedersen_commitment_base, pedersen_commitment_u64, ValueBlind, ValueCommit};
+pub use pedersen::{pedersen_commitment_base, pedersen_commitment_u64};
 
 /// Schnorr signature traits
 pub mod schnorr;

+ 4 - 7
src/sdk/src/crypto/pedersen.rs

@@ -29,13 +29,10 @@ use super::{
     util::mod_r_p,
 };
 
-pub type ValueBlind = pallas::Scalar;
-pub type ValueCommit = pallas::Point;
-
 /// Pedersen commitment for a full-width base field element.
 #[allow(non_snake_case)]
-pub fn pedersen_commitment_base(value: pallas::Base, blind: ValueBlind) -> ValueCommit {
-    let hasher = ValueCommit::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION);
+pub fn pedersen_commitment_base(value: pallas::Base, blind: pallas::Scalar) -> pallas::Point {
+    let hasher = pallas::Point::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION);
     let V = NullifierK.generator();
     let R = hasher(&VALUE_COMMITMENT_R_BYTES);
 
@@ -44,8 +41,8 @@ pub fn pedersen_commitment_base(value: pallas::Base, blind: ValueBlind) -> Value
 
 /// Pedersen commitment for a 64-bit value, in the base field.
 #[allow(non_snake_case)]
-pub fn pedersen_commitment_u64(value: u64, blind: ValueBlind) -> ValueCommit {
-    let hasher = ValueCommit::hash_to_curve(VALUE_COMMITMENT_PERSONALIZATION);
+pub fn pedersen_commitment_u64(value: u64, blind: pallas::Scalar) -> 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);