Explorar o código

contract/consensus: constrain new minted coin in proposal reward proof

aggstam %!s(int64=3) %!d(string=hai) anos
pai
achega
f55f4b7f99

+ 13 - 0
src/contract/consensus/proof/reward_v1.zk

@@ -6,6 +6,8 @@ constant "Reward_V1" {
 contract "Reward_V1" {
 	# The value of the burnt coin
 	Base value,
+	# The reward value
+	Base reward,
 	# Random blinding factor for the value commitment
 	Scalar value_blind,
 }
@@ -14,6 +16,7 @@ circuit "Reward_V1" {
 	# This is a dummy check for now.
 	# TODO: Here we will constrain all the consensus
 	# parameters for the slot.
+
 	# Pedersen commitment for coin's value
 	vcv = ec_mul_short(value, VALUE_COMMIT_VALUE);
 	vcr = ec_mul(value_blind, VALUE_COMMIT_RANDOM);
@@ -23,5 +26,15 @@ circuit "Reward_V1" {
 	constrain_instance(ec_get_x(value_commit));
 	constrain_instance(ec_get_y(value_commit));
 
+	# Pedersen commitment for new coin's value
+	new_value = base_add(value, reward);
+	nvcv = ec_mul_short(new_value, VALUE_COMMIT_VALUE);
+	nvcr = ec_mul(value_blind, VALUE_COMMIT_RANDOM);
+	new_value_commit = ec_add(nvcv, nvcr);
+	# Since the new value commit is also a curve point, we'll do the same
+	# coordinate dance:
+	constrain_instance(ec_get_x(new_value_commit));
+	constrain_instance(ec_get_y(new_value_commit));
+
 	# At this point we've enforced all of our public inputs.
 }

+ 6 - 2
src/contract/consensus/src/client/proposal_v1.rs

@@ -58,15 +58,17 @@ pub struct ConsensusProposalCallDebris {
 
 pub struct ConsensusProposalRewardRevealed {
     pub value_commit: pallas::Point,
+    pub new_value_commit: pallas::Point,
 }
 
 impl ConsensusProposalRewardRevealed {
     pub fn to_vec(&self) -> Vec<pallas::Base> {
         let value_coords = self.value_commit.to_affine().coordinates().unwrap();
+        let new_value_coords = self.new_value_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![*value_coords.x(), *value_coords.y()]
+        vec![*value_coords.x(), *value_coords.y(), *new_value_coords.x(), *new_value_coords.y()]
     }
 }
 
@@ -235,11 +237,13 @@ pub fn create_proposal_reward_proof(
     value_blind: pallas::Scalar,
 ) -> Result<(Proof, ConsensusProposalRewardRevealed)> {
     let value_commit = pedersen_commitment_u64(value, value_blind);
+    let new_value_commit = pedersen_commitment_u64(value + REWARD, value_blind);
 
-    let public_inputs = ConsensusProposalRewardRevealed { value_commit };
+    let public_inputs = ConsensusProposalRewardRevealed { value_commit, new_value_commit };
 
     let prover_witnesses = vec![
         Witness::Base(Value::known(pallas::Base::from(value))),
+        Witness::Base(Value::known(pallas::Base::from(REWARD))),
         Witness::Scalar(Value::known(value_blind)),
     ];
 

+ 3 - 1
src/contract/consensus/src/entrypoint/proposal_reward_v1.rs

@@ -54,10 +54,12 @@ pub(crate) fn consensus_proposal_reward_get_metadata_v1(
 
     // Grab the pedersen commitment for the burnt value
     let value_coords = &params.unstake_input.value_commit.to_affine().coordinates().unwrap();
+    // Grab the pedersen commitment for the minted value
+    let new_value_coords = &params.stake_input.value_commit.to_affine().coordinates().unwrap();
 
     zk_public_inputs.push((
         CONSENSUS_CONTRACT_ZKAS_REWARD_NS_V1.to_string(),
-        vec![*value_coords.x(), *value_coords.y()],
+        vec![*value_coords.x(), *value_coords.y(), *new_value_coords.x(), *new_value_coords.y()],
     ));
 
     signature_pubkeys.push(params.stake_input.signature_public);