|
|
@@ -25,53 +25,45 @@ use darkfi::{
|
|
|
Result,
|
|
|
};
|
|
|
use darkfi_money_contract::{
|
|
|
- client::{MoneyNote, OwnCoin},
|
|
|
- model::{ConsensusInput, Input, Output, PALLAS_ZERO},
|
|
|
+ client::{ConsensusNote, ConsensusOwnCoin},
|
|
|
+ model::{ConsensusInput, ConsensusOutput, PALLAS_ZERO},
|
|
|
};
|
|
|
use darkfi_sdk::{
|
|
|
crypto::{
|
|
|
ecvrf::VrfProof, note::AeadEncryptedNote, pasta_prelude::*, pedersen_commitment_base,
|
|
|
- pedersen_commitment_u64, poseidon_hash, Coin, MerkleTree, Nullifier, PublicKey, SecretKey,
|
|
|
- TokenId, CONSENSUS_CONTRACT_ID, DARK_TOKEN_ID,
|
|
|
+ pedersen_commitment_u64, poseidon_hash, Coin, MerkleNode, MerkleTree, Nullifier, PublicKey,
|
|
|
+ SecretKey,
|
|
|
},
|
|
|
- incrementalmerkletree::Tree,
|
|
|
+ incrementalmerkletree::{Hashable, Tree},
|
|
|
pasta::{group::ff::FromUniformBytes, pallas},
|
|
|
};
|
|
|
-use log::{debug, info};
|
|
|
+use log::debug;
|
|
|
use rand::rngs::OsRng;
|
|
|
|
|
|
use crate::{
|
|
|
- client::common::{create_unstake_burn_proof, TransactionBuilderInputInfo as UnstakeTBII},
|
|
|
+ client::common::{ConsensusBurnInputInfo, ConsensusMintOutputInfo},
|
|
|
model::{
|
|
|
- ConsensusProposalBurnParamsV1, ConsensusProposalMintParamsV1,
|
|
|
- ConsensusProposalRewardParamsV1, HEADSTART, MU_RHO_PREFIX, MU_Y_PREFIX, REWARD,
|
|
|
- REWARD_PALLAS, SEED_PREFIX, SERIAL_PREFIX,
|
|
|
+ ConsensusProposalParamsV1, HEADSTART, MU_RHO_PREFIX, MU_Y_PREFIX, REWARD, REWARD_PALLAS,
|
|
|
+ SEED_PREFIX, SERIAL_PREFIX,
|
|
|
},
|
|
|
};
|
|
|
|
|
|
-// TODO: Remove TransactionBuilderOutputInfo
|
|
|
-pub struct TransactionBuilderOutputInfo {
|
|
|
- pub value: u64,
|
|
|
- pub token_id: TokenId,
|
|
|
- pub public_key: PublicKey,
|
|
|
-}
|
|
|
-
|
|
|
pub struct ConsensusProposalCallDebris {
|
|
|
- pub burn_params: ConsensusProposalBurnParamsV1,
|
|
|
- pub burn_proofs: Vec<Proof>,
|
|
|
- pub reward_params: ConsensusProposalRewardParamsV1,
|
|
|
- pub reward_proofs: Vec<Proof>,
|
|
|
- pub mint_params: ConsensusProposalMintParamsV1,
|
|
|
- pub mint_proofs: Vec<Proof>,
|
|
|
+ pub params: ConsensusProposalParamsV1,
|
|
|
+ pub proofs: Vec<Proof>,
|
|
|
pub signature_secret: SecretKey,
|
|
|
}
|
|
|
|
|
|
-pub struct ConsensusProposalRewardRevealed {
|
|
|
+pub struct ConsensusProposalRevealed {
|
|
|
pub nullifier: Nullifier,
|
|
|
+ pub epoch: u64,
|
|
|
pub public_key: PublicKey,
|
|
|
+ pub merkle_root: MerkleNode,
|
|
|
pub value_commit: pallas::Point,
|
|
|
+ pub new_serial: pallas::Base,
|
|
|
pub new_serial_commit: pallas::Point,
|
|
|
pub new_value_commit: pallas::Point,
|
|
|
+ pub new_coin: Coin,
|
|
|
pub vrf_proof: VrfProof,
|
|
|
pub mu_y: pallas::Base,
|
|
|
pub y: pallas::Base,
|
|
|
@@ -81,25 +73,31 @@ pub struct ConsensusProposalRewardRevealed {
|
|
|
pub sigma2: pallas::Base,
|
|
|
}
|
|
|
|
|
|
-impl ConsensusProposalRewardRevealed {
|
|
|
+impl ConsensusProposalRevealed {
|
|
|
pub fn to_vec(&self) -> Vec<pallas::Base> {
|
|
|
+ let epoch_palas = pallas::Base::from(self.epoch);
|
|
|
let (pub_x, pub_y) = self.public_key.xy();
|
|
|
let value_coords = self.value_commit.to_affine().coordinates().unwrap();
|
|
|
let new_serial_coords = self.new_serial_commit.to_affine().coordinates().unwrap();
|
|
|
+ let reward_pallas = pallas::Base::from(REWARD);
|
|
|
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![
|
|
|
self.nullifier.inner(),
|
|
|
+ epoch_palas,
|
|
|
pub_x,
|
|
|
pub_y,
|
|
|
+ self.merkle_root.inner(),
|
|
|
*value_coords.x(),
|
|
|
*value_coords.y(),
|
|
|
*new_serial_coords.x(),
|
|
|
*new_serial_coords.y(),
|
|
|
+ reward_pallas,
|
|
|
*new_value_coords.x(),
|
|
|
*new_value_coords.y(),
|
|
|
+ self.new_coin.inner(),
|
|
|
self.mu_y,
|
|
|
self.y,
|
|
|
self.mu_rho,
|
|
|
@@ -111,258 +109,180 @@ impl ConsensusProposalRewardRevealed {
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-pub struct ConsensusProposalMintRevealed {
|
|
|
- pub coin: Coin,
|
|
|
- pub value_commit: pallas::Point,
|
|
|
- pub token_commit: pallas::Point,
|
|
|
- pub serial_commit: pallas::Point,
|
|
|
-}
|
|
|
-
|
|
|
-impl ConsensusProposalMintRevealed {
|
|
|
- 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 sercom_coords = self.serial_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(),
|
|
|
- *sercom_coords.x(),
|
|
|
- *sercom_coords.y(),
|
|
|
- ]
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
/// Struct holding necessary information to build a proposal transaction.
|
|
|
pub struct ConsensusProposalCallBuilder {
|
|
|
- /// `OwnCoin` we're given to use in this builder
|
|
|
- pub coin: OwnCoin,
|
|
|
- /// Recipient's public key
|
|
|
- pub recipient: PublicKey,
|
|
|
+ /// `ConsensusOwnCoin` we're given to use in this builder
|
|
|
+ pub coin: ConsensusOwnCoin,
|
|
|
/// Rewarded slot checkpoint
|
|
|
pub slot_checkpoint: SlotCheckpoint,
|
|
|
/// Merkle tree of coins used to create inclusion proofs
|
|
|
pub tree: MerkleTree,
|
|
|
- /// `Burn_V1` zkas circuit ZkBinary
|
|
|
- pub burn_zkbin: ZkBinary,
|
|
|
- /// Proving key for the `Burn_V1` zk circuit
|
|
|
- pub burn_pk: ProvingKey,
|
|
|
- /// `ProposalReward_V1` zkas circuit ZkBinary
|
|
|
- pub reward_zkbin: ZkBinary,
|
|
|
- /// Proving key for the `Reward_V1` zk circuit
|
|
|
- pub reward_pk: ProvingKey,
|
|
|
- /// `ProposalMint_V1` zkas circuit ZkBinary
|
|
|
- pub mint_zkbin: ZkBinary,
|
|
|
- /// Proving key for the `Mint_V1` zk circuit
|
|
|
- pub mint_pk: ProvingKey,
|
|
|
+ /// `Proposal_V1` zkas circuit ZkBinary
|
|
|
+ pub proposal_zkbin: ZkBinary,
|
|
|
+ /// Proving key for the `Proposal_V1` zk circuit
|
|
|
+ pub proposal_pk: ProvingKey,
|
|
|
}
|
|
|
|
|
|
impl ConsensusProposalCallBuilder {
|
|
|
pub fn build(&self) -> Result<ConsensusProposalCallDebris> {
|
|
|
debug!("Building Consensus::ProposalBurnV1 contract call for proposal");
|
|
|
let value = self.coin.note.value;
|
|
|
- let token_id = self.coin.note.token_id;
|
|
|
assert!(value != 0);
|
|
|
- assert!(token_id == *DARK_TOKEN_ID);
|
|
|
|
|
|
- debug!("Building anonymous input for proposal");
|
|
|
+ debug!("Building Consensus::ProposalV1 anonymous input");
|
|
|
let leaf_position = self.coin.leaf_position;
|
|
|
let root = self.tree.root(0).unwrap();
|
|
|
let merkle_path = self.tree.authentication_path(leaf_position, &root).unwrap();
|
|
|
- let input = UnstakeTBII {
|
|
|
+ let input = ConsensusBurnInputInfo {
|
|
|
leaf_position,
|
|
|
merkle_path,
|
|
|
secret: self.coin.secret,
|
|
|
note: self.coin.note.clone(),
|
|
|
+ value_blind: pallas::Scalar::random(&mut OsRng),
|
|
|
};
|
|
|
- debug!("Finished building input for proposal");
|
|
|
|
|
|
- let value_blind = pallas::Scalar::random(&mut OsRng);
|
|
|
- let token_blind = pallas::Scalar::random(&mut OsRng);
|
|
|
- let signature_secret = SecretKey::random(&mut OsRng);
|
|
|
- let user_data_blind = pallas::Base::random(&mut OsRng);
|
|
|
- info!("Creating unstake burn proof for input for proposal");
|
|
|
- let (proof, public_inputs) = create_unstake_burn_proof(
|
|
|
- &self.burn_zkbin,
|
|
|
- &self.burn_pk,
|
|
|
+ debug!("Building anonymous output");
|
|
|
+ let reward_blind = pallas::Scalar::random(&mut OsRng);
|
|
|
+ let new_value_blind = input.value_blind + reward_blind;
|
|
|
+ let new_coin_blind = pallas::Base::random(&mut OsRng);
|
|
|
+ let output = ConsensusMintOutputInfo {
|
|
|
+ value: self.coin.note.value + REWARD,
|
|
|
+ epoch: 0,
|
|
|
+ public_key: PublicKey::from_secret(self.coin.secret),
|
|
|
+ value_blind: new_value_blind,
|
|
|
+ serial: self.coin.note.serial,
|
|
|
+ coin_blind: new_coin_blind,
|
|
|
+ };
|
|
|
+ debug!("Finished building output");
|
|
|
+
|
|
|
+ debug!("Building Consensus::ProposalV1 contract call for proposal");
|
|
|
+ let (proof, public_inputs) = create_proposal_proof(
|
|
|
+ &self.proposal_zkbin,
|
|
|
+ &self.proposal_pk,
|
|
|
&input,
|
|
|
- value_blind,
|
|
|
- token_blind,
|
|
|
- user_data_blind,
|
|
|
- signature_secret,
|
|
|
+ &output,
|
|
|
+ &self.slot_checkpoint,
|
|
|
)?;
|
|
|
|
|
|
- let input = Input {
|
|
|
+ let input = ConsensusInput {
|
|
|
+ epoch: self.coin.note.epoch,
|
|
|
value_commit: public_inputs.value_commit,
|
|
|
- token_commit: public_inputs.token_commit,
|
|
|
nullifier: public_inputs.nullifier,
|
|
|
merkle_root: public_inputs.merkle_root,
|
|
|
- spend_hook: public_inputs.spend_hook,
|
|
|
- user_data_enc: public_inputs.user_data_enc,
|
|
|
- signature_public: public_inputs.signature_public,
|
|
|
+ signature_public: public_inputs.public_key,
|
|
|
};
|
|
|
|
|
|
- // We now fill this with necessary stuff
|
|
|
- let burnt_secret_key = self.coin.secret.inner();
|
|
|
- let public_key = PublicKey::from_secret(burnt_secret_key.into());
|
|
|
- let burn_params =
|
|
|
- ConsensusProposalBurnParamsV1 { token_blind, input: input.clone(), public_key };
|
|
|
- let burn_proofs = vec![proof];
|
|
|
- let burnt_input = input;
|
|
|
-
|
|
|
- debug!("Building Consensus::ProposalMintV1 contract call for proposal");
|
|
|
- let new_value = value + REWARD;
|
|
|
- let nullifier = public_inputs.nullifier;
|
|
|
- let merkle_root = public_inputs.merkle_root;
|
|
|
- let signature_public = public_inputs.signature_public;
|
|
|
-
|
|
|
- debug!("Building anonymous output for proposal");
|
|
|
- let output =
|
|
|
- TransactionBuilderOutputInfo { value: new_value, token_id, public_key: self.recipient };
|
|
|
- debug!("Finished building output for proposal");
|
|
|
-
|
|
|
- let burnt_serial = self.coin.note.serial;
|
|
|
- let spend_hook = CONSENSUS_CONTRACT_ID.inner();
|
|
|
- let user_data = pallas::Base::random(&mut OsRng);
|
|
|
- let coin_blind = pallas::Base::random(&mut OsRng);
|
|
|
- let serial_blind = pallas::Scalar::random(&mut OsRng);
|
|
|
-
|
|
|
- info!("Creating stake mint proof for output for proposal");
|
|
|
- let (proof, public_inputs, serial) = create_proposal_mint_proof(
|
|
|
- &self.mint_zkbin,
|
|
|
- &self.mint_pk,
|
|
|
- &output,
|
|
|
- value_blind,
|
|
|
- token_blind,
|
|
|
- serial_blind,
|
|
|
- burnt_secret_key,
|
|
|
- burnt_serial,
|
|
|
- spend_hook,
|
|
|
- user_data,
|
|
|
- coin_blind,
|
|
|
- )?;
|
|
|
-
|
|
|
// Encrypted note
|
|
|
- let note = MoneyNote {
|
|
|
- serial,
|
|
|
+ let note = ConsensusNote {
|
|
|
+ serial: public_inputs.new_serial,
|
|
|
value: output.value,
|
|
|
- token_id: output.token_id,
|
|
|
- spend_hook,
|
|
|
- user_data,
|
|
|
- coin_blind,
|
|
|
- value_blind,
|
|
|
- token_blind,
|
|
|
- memo: vec![],
|
|
|
+ epoch: 0,
|
|
|
+ coin_blind: new_coin_blind,
|
|
|
+ value_blind: new_value_blind,
|
|
|
+ reward: REWARD,
|
|
|
+ reward_blind,
|
|
|
};
|
|
|
|
|
|
let encrypted_note = AeadEncryptedNote::encrypt(¬e, &output.public_key, &mut OsRng)?;
|
|
|
|
|
|
- let output = Output {
|
|
|
- value_commit: public_inputs.value_commit,
|
|
|
- token_commit: public_inputs.token_commit,
|
|
|
- coin: public_inputs.coin,
|
|
|
+ let output = ConsensusOutput {
|
|
|
+ value_commit: public_inputs.new_value_commit,
|
|
|
+ coin: public_inputs.new_coin,
|
|
|
note: encrypted_note,
|
|
|
};
|
|
|
|
|
|
- // TODO: epoch = current
|
|
|
- let input = ConsensusInput {
|
|
|
- epoch: 0,
|
|
|
- value_commit: public_inputs.value_commit,
|
|
|
- nullifier,
|
|
|
- merkle_root,
|
|
|
- signature_public,
|
|
|
- };
|
|
|
-
|
|
|
- // We now fill this with necessary stuff
|
|
|
- let serial_commit = public_inputs.serial_commit;
|
|
|
- let mint_params = ConsensusProposalMintParamsV1 {
|
|
|
- input: input.clone(),
|
|
|
- output: output.clone(),
|
|
|
- serial_commit,
|
|
|
- };
|
|
|
- let mint_proofs = vec![proof];
|
|
|
- let mint_input = input;
|
|
|
-
|
|
|
- debug!("Building Consensus::ProposalRewardV1 contract call for proposal");
|
|
|
- let secret_key = self.coin.secret.inner();
|
|
|
- let serial = self.coin.note.serial;
|
|
|
- let (proof, public_inputs) = create_proposal_reward_proof(
|
|
|
- &self.reward_zkbin,
|
|
|
- &self.reward_pk,
|
|
|
- &self.slot_checkpoint,
|
|
|
- secret_key,
|
|
|
- serial,
|
|
|
- value,
|
|
|
- value_blind,
|
|
|
- serial_blind,
|
|
|
- )?;
|
|
|
-
|
|
|
// We now fill this with necessary stuff
|
|
|
- let burnt_public_key = public_inputs.public_key;
|
|
|
- let new_serial_commit = serial_commit;
|
|
|
+ let new_serial_commit = public_inputs.new_serial_commit;
|
|
|
let slot = self.slot_checkpoint.slot;
|
|
|
let vrf_proof = public_inputs.vrf_proof;
|
|
|
let y = public_inputs.y;
|
|
|
let rho = public_inputs.rho;
|
|
|
- let reward_params = ConsensusProposalRewardParamsV1 {
|
|
|
- burnt_input,
|
|
|
- burnt_public_key,
|
|
|
- mint_input,
|
|
|
+ let params = ConsensusProposalParamsV1 {
|
|
|
+ input,
|
|
|
output,
|
|
|
+ reward: REWARD,
|
|
|
+ reward_blind,
|
|
|
new_serial_commit,
|
|
|
slot,
|
|
|
vrf_proof,
|
|
|
y,
|
|
|
rho,
|
|
|
};
|
|
|
- let reward_proofs = vec![proof];
|
|
|
+ let proofs = vec![proof];
|
|
|
|
|
|
// Now we should have all the params, zk proofs and signature secret.
|
|
|
// We return it all and let the caller deal with it.
|
|
|
- let debris = ConsensusProposalCallDebris {
|
|
|
- burn_params,
|
|
|
- burn_proofs,
|
|
|
- reward_params,
|
|
|
- reward_proofs,
|
|
|
- mint_params,
|
|
|
- mint_proofs,
|
|
|
- signature_secret,
|
|
|
- };
|
|
|
+ let debris =
|
|
|
+ ConsensusProposalCallDebris { params, proofs, signature_secret: self.coin.secret };
|
|
|
Ok(debris)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
-#[allow(clippy::too_many_arguments)]
|
|
|
-pub fn create_proposal_reward_proof(
|
|
|
+pub fn create_proposal_proof(
|
|
|
zkbin: &ZkBinary,
|
|
|
pk: &ProvingKey,
|
|
|
+ input: &ConsensusBurnInputInfo,
|
|
|
+ output: &ConsensusMintOutputInfo,
|
|
|
slot_checkpoint: &SlotCheckpoint,
|
|
|
- secret_key: pallas::Base,
|
|
|
- serial: pallas::Base,
|
|
|
- value: u64,
|
|
|
- value_blind: pallas::Scalar,
|
|
|
- new_serial_blind: pallas::Scalar,
|
|
|
-) -> Result<(Proof, ConsensusProposalRewardRevealed)> {
|
|
|
+) -> Result<(Proof, ConsensusProposalRevealed)> {
|
|
|
// Proof parameters
|
|
|
- let nullifier = Nullifier::from(poseidon_hash([secret_key, serial]));
|
|
|
- let public_key = PublicKey::from_secret(secret_key.into());
|
|
|
- let value_commit = pedersen_commitment_u64(value, value_blind);
|
|
|
- let new_serial = poseidon_hash([SERIAL_PREFIX, secret_key, serial, PALLAS_ZERO]);
|
|
|
+ let nullifier = Nullifier::from(poseidon_hash([input.secret.inner(), input.note.serial]));
|
|
|
+ let epoch = input.note.epoch;
|
|
|
+ let epoch_pallas = pallas::Base::from(epoch);
|
|
|
+ let value_pallas = pallas::Base::from(input.note.value);
|
|
|
+ let value_commit = pedersen_commitment_u64(input.note.value, input.value_blind);
|
|
|
+ let public_key = PublicKey::from_secret(input.secret);
|
|
|
+ let (pub_x, pub_y) = public_key.xy();
|
|
|
+
|
|
|
+ // Burnt coin and its merkle_root
|
|
|
+ let coin = poseidon_hash([
|
|
|
+ pub_x,
|
|
|
+ pub_y,
|
|
|
+ value_pallas,
|
|
|
+ epoch_pallas,
|
|
|
+ input.note.serial,
|
|
|
+ input.note.coin_blind,
|
|
|
+ ]);
|
|
|
+
|
|
|
+ let merkle_root = {
|
|
|
+ let position: u64 = input.leaf_position.into();
|
|
|
+ let mut current = MerkleNode::from(coin);
|
|
|
+ for (level, sibling) in input.merkle_path.iter().enumerate() {
|
|
|
+ let level = level as u8;
|
|
|
+ current = if position & (1 << level) == 0 {
|
|
|
+ MerkleNode::combine(level.into(), ¤t, sibling)
|
|
|
+ } else {
|
|
|
+ MerkleNode::combine(level.into(), sibling, ¤t)
|
|
|
+ };
|
|
|
+ }
|
|
|
+ current
|
|
|
+ };
|
|
|
+
|
|
|
+ // New coin
|
|
|
+ let new_serial = poseidon_hash([SERIAL_PREFIX, input.secret.inner(), input.note.serial]);
|
|
|
+ let new_serial_blind = pallas::Scalar::random(&mut OsRng);
|
|
|
let new_serial_commit = pedersen_commitment_base(new_serial, new_serial_blind);
|
|
|
- let new_value_commit = pedersen_commitment_u64(value + REWARD, value_blind);
|
|
|
+ let new_value_commit = pedersen_commitment_u64(output.value, output.value_blind);
|
|
|
+ let new_value_pallas = pallas::Base::from(output.value);
|
|
|
+ let (new_pub_x, new_pub_y) = output.public_key.xy();
|
|
|
+
|
|
|
+ let new_coin = Coin::from(poseidon_hash([
|
|
|
+ new_pub_x,
|
|
|
+ new_pub_y,
|
|
|
+ new_value_pallas,
|
|
|
+ PALLAS_ZERO,
|
|
|
+ new_serial,
|
|
|
+ output.coin_blind,
|
|
|
+ ]));
|
|
|
+
|
|
|
let slot_pallas = pallas::Base::from(slot_checkpoint.slot);
|
|
|
- let seed = poseidon_hash([SEED_PREFIX, serial, PALLAS_ZERO]);
|
|
|
+ let seed = poseidon_hash([SEED_PREFIX, input.note.serial]);
|
|
|
// NOTE: slot checkpoint eta to be renamed to previous_eta,
|
|
|
// corresponding to previous block eta.
|
|
|
let mut vrf_input = [0u8; 64];
|
|
|
vrf_input[..32].copy_from_slice(&slot_checkpoint.eta.to_repr());
|
|
|
vrf_input[32..].copy_from_slice(&slot_pallas.to_repr());
|
|
|
- let vrf_proof = VrfProof::prove(secret_key.into(), &vrf_input, &mut OsRng);
|
|
|
+ let vrf_proof = VrfProof::prove(input.secret, &vrf_input, &mut OsRng);
|
|
|
let mut eta = [0u8; 64];
|
|
|
eta[..blake3::OUT_LEN].copy_from_slice(vrf_proof.hash_output().as_bytes());
|
|
|
let eta = pallas::Base::from_uniform_bytes(&eta);
|
|
|
@@ -373,12 +293,16 @@ pub fn create_proposal_reward_proof(
|
|
|
let (sigma1, sigma2) = (slot_checkpoint.sigma1, slot_checkpoint.sigma2);
|
|
|
|
|
|
// Generate public inputs, witnesses and proof
|
|
|
- let public_inputs = ConsensusProposalRewardRevealed {
|
|
|
+ let public_inputs = ConsensusProposalRevealed {
|
|
|
nullifier,
|
|
|
+ epoch,
|
|
|
public_key,
|
|
|
+ merkle_root,
|
|
|
value_commit,
|
|
|
+ new_serial,
|
|
|
new_serial_commit,
|
|
|
new_value_commit,
|
|
|
+ new_coin,
|
|
|
vrf_proof,
|
|
|
mu_y,
|
|
|
y,
|
|
|
@@ -389,12 +313,20 @@ pub fn create_proposal_reward_proof(
|
|
|
};
|
|
|
|
|
|
let prover_witnesses = vec![
|
|
|
- Witness::Base(Value::known(secret_key)),
|
|
|
- Witness::Base(Value::known(serial)),
|
|
|
- Witness::Base(Value::known(pallas::Base::from(value))),
|
|
|
+ Witness::Base(Value::known(input.secret.inner())),
|
|
|
+ Witness::Base(Value::known(input.note.serial)),
|
|
|
+ Witness::Base(Value::known(pallas::Base::from(input.note.value))),
|
|
|
+ Witness::Base(Value::known(epoch_pallas)),
|
|
|
Witness::Base(Value::known(REWARD_PALLAS)),
|
|
|
- Witness::Scalar(Value::known(value_blind)),
|
|
|
+ Witness::Scalar(Value::known(input.value_blind)),
|
|
|
+ Witness::Base(Value::known(input.note.coin_blind)),
|
|
|
+ Witness::Uint32(Value::known(u64::from(input.leaf_position).try_into().unwrap())),
|
|
|
+ Witness::MerklePath(Value::known(input.merkle_path.clone().try_into().unwrap())),
|
|
|
Witness::Scalar(Value::known(new_serial_blind)),
|
|
|
+ Witness::Base(Value::known(new_pub_x)),
|
|
|
+ Witness::Base(Value::known(new_pub_y)),
|
|
|
+ Witness::Scalar(Value::known(output.value_blind)),
|
|
|
+ Witness::Base(Value::known(output.coin_blind)),
|
|
|
Witness::Base(Value::known(mu_y)),
|
|
|
Witness::Base(Value::known(mu_rho)),
|
|
|
Witness::Base(Value::known(sigma1)),
|
|
|
@@ -407,58 +339,3 @@ pub fn create_proposal_reward_proof(
|
|
|
|
|
|
Ok((proof, public_inputs))
|
|
|
}
|
|
|
-
|
|
|
-#[allow(clippy::too_many_arguments)]
|
|
|
-pub fn create_proposal_mint_proof(
|
|
|
- zkbin: &ZkBinary,
|
|
|
- pk: &ProvingKey,
|
|
|
- output: &TransactionBuilderOutputInfo,
|
|
|
- value_blind: pallas::Scalar,
|
|
|
- token_blind: pallas::Scalar,
|
|
|
- serial_blind: pallas::Scalar,
|
|
|
- burnt_secret_key: pallas::Base,
|
|
|
- burnt_serial: pallas::Base,
|
|
|
- spend_hook: pallas::Base,
|
|
|
- user_data: pallas::Base,
|
|
|
- coin_blind: pallas::Base,
|
|
|
-) -> Result<(Proof, ConsensusProposalMintRevealed, pallas::Base)> {
|
|
|
- let serial = poseidon_hash([SERIAL_PREFIX, burnt_secret_key, burnt_serial, PALLAS_ZERO]);
|
|
|
- let value_commit = pedersen_commitment_u64(output.value, value_blind);
|
|
|
- let token_commit = pedersen_commitment_base(output.token_id.inner(), token_blind);
|
|
|
- let serial_commit = pedersen_commitment_base(serial, serial_blind);
|
|
|
- let (pub_x, pub_y) = output.public_key.xy();
|
|
|
-
|
|
|
- let coin = Coin::from(poseidon_hash([
|
|
|
- pub_x,
|
|
|
- pub_y,
|
|
|
- pallas::Base::from(output.value),
|
|
|
- output.token_id.inner(),
|
|
|
- serial,
|
|
|
- spend_hook,
|
|
|
- user_data,
|
|
|
- coin_blind,
|
|
|
- ]));
|
|
|
-
|
|
|
- let public_inputs =
|
|
|
- ConsensusProposalMintRevealed { coin, value_commit, token_commit, serial_commit };
|
|
|
-
|
|
|
- let prover_witnesses = vec![
|
|
|
- Witness::Base(Value::known(pub_x)),
|
|
|
- Witness::Base(Value::known(pub_y)),
|
|
|
- Witness::Base(Value::known(pallas::Base::from(output.value))),
|
|
|
- Witness::Base(Value::known(output.token_id.inner())),
|
|
|
- Witness::Base(Value::known(burnt_secret_key)),
|
|
|
- Witness::Base(Value::known(burnt_serial)),
|
|
|
- Witness::Base(Value::known(coin_blind)),
|
|
|
- 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::Scalar(Value::known(serial_blind)),
|
|
|
- ];
|
|
|
-
|
|
|
- let circuit = ZkCircuit::new(prover_witnesses, zkbin.clone());
|
|
|
- let proof = Proof::create(pk, &[circuit], &public_inputs.to_vec(), &mut OsRng)?;
|
|
|
-
|
|
|
- Ok((proof, public_inputs, serial))
|
|
|
-}
|