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

This commit is contained in:
parazyd
2023-07-21 10:23:13 +02:00
parent a701d40a84
commit 3d5896b89b
26 changed files with 119 additions and 191 deletions

View File

@@ -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> {

View File

@@ -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.
}

View File

@@ -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.
}

View File

@@ -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);
}

View File

@@ -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,

View File

@@ -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![],
}
}

View File

@@ -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)),

View File

@@ -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

View File

@@ -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);

View File

@@ -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);

View File

@@ -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);

View File

@@ -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");

View File

@@ -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())
}

View File

@@ -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

View File

@@ -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");

View File

@@ -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");

View File

@@ -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())
}

View File

@@ -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,
}

View File

@@ -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),
)?;

View File

@@ -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 {

View File

@@ -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)

View File

@@ -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;

View File

@@ -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);