|
|
@@ -9,30 +9,34 @@ constant "Burn_V1" {
|
|
|
EcFixedPointBase NULLIFIER_K,
|
|
|
}
|
|
|
|
|
|
-# The witness values we define for our circuit
|
|
|
+# The witness coin_values we define for our circuit
|
|
|
witness "Burn_V1" {
|
|
|
- # The value of this coin
|
|
|
- Base value,
|
|
|
- # The token ID
|
|
|
- Base token,
|
|
|
- # Random blinding factor for value commitment
|
|
|
- Scalar value_blind,
|
|
|
- # Random blinding factor for the token ID
|
|
|
- Base token_blind,
|
|
|
+ # Secret key used to derive nullifier and coin's public key
|
|
|
+ Base coin_secret,
|
|
|
+
|
|
|
+ # The coin_value of this coin
|
|
|
+ Base coin_value,
|
|
|
+ # The coin_token_id ID
|
|
|
+ Base coin_token_id,
|
|
|
# Allows composing this ZK proof to invoke other contracts
|
|
|
- Base spend_hook,
|
|
|
+ Base coin_spend_hook,
|
|
|
# Data passed from this coin to the invoked contract
|
|
|
- Base user_data,
|
|
|
+ Base coin_user_data,
|
|
|
# Unique serial number corresponding to this coin
|
|
|
Base coin_blind,
|
|
|
- # Blinding factor for the encrypted user_data
|
|
|
+
|
|
|
+ # Random blinding factor for coin_value commitment
|
|
|
+ Scalar value_blind,
|
|
|
+ # Random blinding factor for the coin_token_id ID
|
|
|
+ Base token_id_blind,
|
|
|
+ # Blinding factor for the encrypted coin_user_data
|
|
|
Base user_data_blind,
|
|
|
- # Secret key used to derive nullifier and coin's public key
|
|
|
- Base secret,
|
|
|
+
|
|
|
# Leaf position of the coin in the Merkle tree of coins
|
|
|
Uint32 leaf_pos,
|
|
|
# Merkle path to the coin
|
|
|
MerklePath path,
|
|
|
+
|
|
|
# Secret key used to derive public key for the tx signature
|
|
|
Base signature_secret,
|
|
|
}
|
|
|
@@ -40,53 +44,53 @@ witness "Burn_V1" {
|
|
|
# The definition of our circuit
|
|
|
circuit "Burn_V1" {
|
|
|
# Derive the public key used in the coin from its secret counterpart
|
|
|
- pub = ec_mul_base(secret, NULLIFIER_K);
|
|
|
+ pub = ec_mul_base(coin_secret, NULLIFIER_K);
|
|
|
# Coin hash
|
|
|
coin = poseidon_hash(
|
|
|
ec_get_x(pub),
|
|
|
ec_get_y(pub),
|
|
|
- value,
|
|
|
- token,
|
|
|
- spend_hook,
|
|
|
- user_data,
|
|
|
+ coin_value,
|
|
|
+ coin_token_id,
|
|
|
+ coin_spend_hook,
|
|
|
+ coin_user_data,
|
|
|
coin_blind,
|
|
|
);
|
|
|
|
|
|
# Poseidon hash of the nullifier
|
|
|
- nullifier = poseidon_hash(secret, coin);
|
|
|
+ nullifier = poseidon_hash(coin_secret, coin);
|
|
|
constrain_instance(nullifier);
|
|
|
|
|
|
- # Pedersen commitment for coin's value
|
|
|
- vcv = ec_mul_short(value, VALUE_COMMIT_VALUE);
|
|
|
+ # Pedersen commitment for coin's coin_value
|
|
|
+ vcv = ec_mul_short(coin_value, VALUE_COMMIT_VALUE);
|
|
|
vcr = ec_mul(value_blind, VALUE_COMMIT_RANDOM);
|
|
|
- value_commit = ec_add(vcv, vcr);
|
|
|
- # Since value_commit is a curve point, we fetch its coordinates
|
|
|
+ coin_value_commit = ec_add(vcv, vcr);
|
|
|
+ # Since coin_value_commit is a curve point, we fetch its coordinates
|
|
|
# and constrain them:
|
|
|
- constrain_instance(ec_get_x(value_commit));
|
|
|
- constrain_instance(ec_get_y(value_commit));
|
|
|
+ constrain_instance(ec_get_x(coin_value_commit));
|
|
|
+ constrain_instance(ec_get_y(coin_value_commit));
|
|
|
|
|
|
- # Commitment for coin's token ID. We do a poseidon hash since it's
|
|
|
+ # Commitment for coin's coin_token_id 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_token_id_commit = poseidon_hash(coin_token_id, token_id_blind);
|
|
|
+ constrain_instance(coin_token_id_commit);
|
|
|
|
|
|
- # With this, we can actually produce a fake coin of value 0
|
|
|
+ # With this, we can actually produce a fake coin of coin_value 0
|
|
|
# above and use it as a dummy input. The inclusion merkle tree
|
|
|
- # has a 0x00 leaf at position 0, so zero_cond will output value
|
|
|
- # iff value is 0 - which is equivalent to 0x00 so that's the
|
|
|
+ # has a 0x00 leaf at position 0, so zero_cond will output coin_value
|
|
|
+ # iff coin_value is 0 - which is equivalent to 0x00 so that's the
|
|
|
# trick we use to make the inclusion proof.
|
|
|
- coin_incl = zero_cond(value, coin);
|
|
|
+ coin_incl = zero_cond(coin_value, coin);
|
|
|
|
|
|
# Merkle root
|
|
|
root = merkle_root(leaf_pos, path, coin_incl);
|
|
|
constrain_instance(root);
|
|
|
|
|
|
- # Export user_data
|
|
|
- user_data_enc = poseidon_hash(user_data, user_data_blind);
|
|
|
- constrain_instance(user_data_enc);
|
|
|
+ # Export coin_user_data
|
|
|
+ coin_user_data_enc = poseidon_hash(coin_user_data, user_data_blind);
|
|
|
+ constrain_instance(coin_user_data_enc);
|
|
|
|
|
|
- # Reveal spend_hook
|
|
|
- constrain_instance(spend_hook);
|
|
|
+ # Reveal coin_spend_hook
|
|
|
+ constrain_instance(coin_spend_hook);
|
|
|
|
|
|
# Finally, we derive a public key for the signature and
|
|
|
# constrain its coordinates:
|