From 7ebe829cafe5c4fe51f8d2b89bfd04f4a64fb541 Mon Sep 17 00:00:00 2001 From: aggstam Date: Sat, 27 May 2023 14:23:03 +0300 Subject: [PATCH] contract/consensus/proof: consensus burn and mint proofs added --- .../consensus/proof/consensus_burn_v1.zk | 66 +++++++++++++++++++ .../consensus/proof/consensus_mint_v1.zk | 48 ++++++++++++++ 2 files changed, 114 insertions(+) create mode 100644 src/contract/consensus/proof/consensus_burn_v1.zk create mode 100644 src/contract/consensus/proof/consensus_mint_v1.zk diff --git a/src/contract/consensus/proof/consensus_burn_v1.zk b/src/contract/consensus/proof/consensus_burn_v1.zk new file mode 100644 index 000000000..ec602d0d6 --- /dev/null +++ b/src/contract/consensus/proof/consensus_burn_v1.zk @@ -0,0 +1,66 @@ +constant "ConsensusBurn_V1" { + EcFixedPointShort VALUE_COMMIT_VALUE, + EcFixedPoint VALUE_COMMIT_RANDOM, + EcFixedPointBase NULLIFIER_K, +} + +witness "ConsensusBurn_V1" { + # The value of this coin + Base value, + # The epoch this coin was minted on + Base epoch, + # Unique serial number corresponding to this coin + Base serial, + # Random blinding factor for coin + Base coin_blind, + # Random blinding factor for value commitment + Scalar value_blind, + # Secret key used to derive nullifier and coins' 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, +} + +circuit "ConsensusBurn_V1" { + # Poseidon hash of the nullifier + nullifier = poseidon_hash(secret, serial); + constrain_instance(nullifier); + + # Constrain the epoch this coin was minted on + constrain_instance(epoch); + + # We derive coins' public key for the signature and + # constrain its coordinates: + pub = ec_mul_base(secret, NULLIFIER_K); + pub_x = ec_get_x(pub); + pub_y = ec_get_y(pub); + constrain_instance(pub_x); + constrain_instance(pub_y); + + # Coin hash + C = poseidon_hash( + pub_x, + pub_y, + value, + epoch, + serial, + coin_blind, + ); + + # Merkle root + root = merkle_root(leaf_pos, path, C); + constrain_instance(root); + + # Pedersen commitment for coin's value + vcv = ec_mul_short(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 + # and constrain them: + constrain_instance(ec_get_x(value_commit)); + constrain_instance(ec_get_y(value_commit)); + + # At this point we've enforced all of our public inputs. +} diff --git a/src/contract/consensus/proof/consensus_mint_v1.zk b/src/contract/consensus/proof/consensus_mint_v1.zk new file mode 100644 index 000000000..a6c084de8 --- /dev/null +++ b/src/contract/consensus/proof/consensus_mint_v1.zk @@ -0,0 +1,48 @@ +constant "ConsensusMint_V1" { + EcFixedPointShort VALUE_COMMIT_VALUE, + EcFixedPoint VALUE_COMMIT_RANDOM, +} + +witness "ConsensusMint_V1" { + # X coordinate for public key + Base pub_x, + # Y coordinate for public key + Base pub_y, + # The value of this coin + Base value, + # The epoch this coin was minted on + Base epoch, + # Unique serial number corresponding to this coin + Base serial, + # Random blinding factor for coin + Base coin_blind, + # Random blinding factor for the value commitment + Scalar value_blind, +} + +circuit "ConsensusMint_V1" { + # Constrain the epoch this coin was minted on + constrain_instance(epoch); + + # Poseidon hash of the coin + C = poseidon_hash( + pub_x, + pub_y, + value, + epoch, + serial, + coin_blind, + ); + constrain_instance(C); + + # Pedersen commitment for coin's value + vcv = ec_mul_short(value, VALUE_COMMIT_VALUE); + vcr = ec_mul(value_blind, VALUE_COMMIT_RANDOM); + value_commit = ec_add(vcv, vcr); + # Since the 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)); + + # At this point we've enforced all of our public inputs. +}