mirror of
https://github.com/darkrenaissance/darkfi.git
synced 2026-01-09 22:57:59 -05:00
added derived lead coin, and removed derived coin nonce from public inputs
This commit is contained in:
@@ -35,7 +35,6 @@ circuit "Lead" {
|
||||
constrain_instance(pk);
|
||||
# coin (2) rho/nonce
|
||||
c2_rho = poseidon_hash(PREFIX_EVL, c1_sk_root, c1_rho, ZERO);
|
||||
constrain_instance(c2_rho);
|
||||
# coin (1) cm/commitment
|
||||
c1_cm_msg = poseidon_hash(PREFIX_CM, pk, value, c1_rho);
|
||||
c1_cm_v = ec_mul_base(c1_cm_msg, NULLIFIER_K);
|
||||
|
||||
@@ -21,7 +21,7 @@ use darkfi_sdk::{
|
||||
pedersen::{pedersen_commitment_base, pedersen_commitment_u64},
|
||||
poseidon_hash,
|
||||
util::mod_r_p,
|
||||
MerkleNode, PublicKey, SecretKey,
|
||||
MerkleNode, SecretKey,
|
||||
},
|
||||
pasta::{arithmetic::CurveAffine, group::Curve, pallas},
|
||||
};
|
||||
@@ -30,7 +30,7 @@ use incrementalmerkletree::{bridgetree::BridgeTree, Tree};
|
||||
use log::debug;
|
||||
use rand::rngs::OsRng;
|
||||
|
||||
use super::constants::{EPOCH_LENGTH, PRF_NULLIFIER_PREFIX};
|
||||
use super::constants::{EPOCH_LENGTH};
|
||||
use crate::{
|
||||
crypto::{proof::ProvingKey, Proof},
|
||||
zk::{vm::ZkCircuit, vm_stack::Witness},
|
||||
@@ -40,7 +40,13 @@ use crate::{
|
||||
|
||||
pub const MERKLE_DEPTH_LEADCOIN: usize = 32;
|
||||
pub const MERKLE_DEPTH: u8 = 32;
|
||||
|
||||
pub const ZERO: pallas::Base = pallas::Base::zero();
|
||||
pub const ONE: pallas::Base = pallas::Base::one();
|
||||
pub const PREFIX_EVL: u64 = 2;
|
||||
pub const PREFIX_SEED: u64 = 3;
|
||||
pub const PREFIX_CM: u64 = 4;
|
||||
pub const PREFIX_PK: u64 = 5;
|
||||
pub const PREFIX_SN: u64 = 6;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct TransferStx {
|
||||
@@ -126,7 +132,7 @@ pub struct LeadCoin {
|
||||
impl LeadCoin {
|
||||
/// Create a new `LeadCoin` object using given parameters.
|
||||
pub fn new(
|
||||
// wtf is eta and why is it not in the zk proof?
|
||||
// emulation of global random oracle output from previous epoch randomness.
|
||||
eta: pallas::Base,
|
||||
// First coefficient in 1-term T (target function) approximation.
|
||||
sigma1: pallas::Base,
|
||||
@@ -151,32 +157,30 @@ impl LeadCoin {
|
||||
// Merkle tree of coin commitments
|
||||
coin_commitment_tree: &mut BridgeTree<MerkleNode, MERKLE_DEPTH>,
|
||||
) -> Self {
|
||||
let zero = pallas::Base::zero();
|
||||
let one = pallas::Base::one();
|
||||
let prefix_evl = pallas::Base::from(2);
|
||||
let prefix_seed = pallas::Base::from(3);
|
||||
let prefix_cm = pallas::Base::from(4);
|
||||
let prefix_pk = pallas::Base::from(5);
|
||||
let prefix_sn = pallas::Base::from(6);
|
||||
// Generate random blinding values for commitments:
|
||||
let coin1_blind = pallas::Scalar::random(&mut OsRng);
|
||||
let coin2_blind = pallas::Scalar::random(&mut OsRng);
|
||||
let tau = pallas::Base::from(slot_index as u64);
|
||||
// pk
|
||||
let pk_msg = [prefix_pk, coin1_sk_root.inner(), tau, zero];
|
||||
let pk_msg = [
|
||||
pallas::Base::from(PREFIX_PK),
|
||||
coin1_sk_root.inner(),
|
||||
tau,
|
||||
pallas::Base::from(ZERO)
|
||||
];
|
||||
let pk = poseidon_hash(pk_msg);
|
||||
// Derive the nonce for coin2
|
||||
let coin2_nonce_msg = [
|
||||
prefix_evl,
|
||||
pallas::Base::from(PREFIX_EVL),
|
||||
coin1_sk_root.inner(),
|
||||
pallas::Base::from(seed),
|
||||
zero,
|
||||
pallas::Base::from(ZERO),
|
||||
];
|
||||
let coin2_seed = poseidon_hash(coin2_nonce_msg);
|
||||
debug!("coin2_seed[{}]: {:?}", slot_index, coin2_seed);
|
||||
// Derive input for the commitment of coin1
|
||||
let coin1_commit_msg = [
|
||||
prefix_cm,
|
||||
pallas::Base::from(PREFIX_CM),
|
||||
pk,
|
||||
pallas::Base::from(value),
|
||||
pallas::Base::from(seed),
|
||||
@@ -196,7 +200,7 @@ impl LeadCoin {
|
||||
coin_commitment_tree.authentication_path(leaf_pos, &coin1_commitment_root).unwrap();
|
||||
// Derive input for the commitment of coin2
|
||||
let coin2_commit_msg = [
|
||||
prefix_cm,
|
||||
pallas::Base::from(PREFIX_CM),
|
||||
pk,
|
||||
pallas::Base::from(value),
|
||||
pallas::Base::from(coin2_seed),
|
||||
@@ -208,10 +212,10 @@ impl LeadCoin {
|
||||
let (y_mu, rho_mu) = Self::election_seeds(eta, pallas::Base::from(slot_index as u64));
|
||||
// Derive a nullifier
|
||||
let sn_msg = [
|
||||
prefix_sn,
|
||||
pallas::Base::from(PREFIX_SN),
|
||||
coin1_sk_root.inner(),
|
||||
pallas::Base::from(seed),
|
||||
zero
|
||||
pallas::Base::from(ZERO)
|
||||
];
|
||||
let c_sn = poseidon_hash(sn_msg);
|
||||
|
||||
@@ -269,16 +273,19 @@ impl LeadCoin {
|
||||
let prefix_pk = pallas::Base::from(5);
|
||||
|
||||
// pk
|
||||
let pk_msg = [prefix_pk, self.coin1_sk_root.inner(), self.tau, zero];
|
||||
let pk = poseidon_hash(pk_msg);
|
||||
let pk = self.pk();
|
||||
// rho
|
||||
let rho_msg = [prefix_evl, self.coin1_sk_root.inner(), self.nonce, zero];
|
||||
let c2_rho = poseidon_hash(rho_msg);
|
||||
let c2_rho = self.derived_rho();
|
||||
// coin 1-2 cm/commitment
|
||||
let c1_cm = self.coin1_commitment.to_affine().coordinates().unwrap();
|
||||
let c2_cm = self.coin2_commitment.to_affine().coordinates().unwrap();
|
||||
// lottery seed
|
||||
let seed_msg = [prefix_seed, self.coin1_sk_root.inner(), self.nonce, zero];
|
||||
let seed_msg = [
|
||||
pallas::Base::from(PREFIX_SEED),
|
||||
self.coin1_sk_root.inner(),
|
||||
self.nonce,
|
||||
pallas::Base::from(ZERO),
|
||||
];
|
||||
let seed = poseidon_hash(seed_msg);
|
||||
// y
|
||||
let y = pedersen_commitment_base(seed, mod_r_p(self.y_mu));
|
||||
@@ -288,7 +295,6 @@ impl LeadCoin {
|
||||
let rho_coord = rho.to_affine().coordinates().unwrap();
|
||||
vec![
|
||||
pk,
|
||||
c2_rho,
|
||||
*c1_cm.x(),
|
||||
*c1_cm.y(),
|
||||
*c2_cm.x(),
|
||||
@@ -302,6 +308,65 @@ impl LeadCoin {
|
||||
*rho_coord.y(),
|
||||
]
|
||||
}
|
||||
/// calculate coin public key: hash of root coin secret key
|
||||
/// and timestmap.
|
||||
pub fn pk(&self) -> pallas::Base {
|
||||
let pk_msg = [
|
||||
pallas::Base::from(PREFIX_PK),
|
||||
self.coin1_sk_root.inner(),
|
||||
self.tau,
|
||||
pallas::Base::from(ZERO)
|
||||
];
|
||||
let pk = poseidon_hash(pk_msg);
|
||||
pk
|
||||
}
|
||||
/// calculate derived coin nonce: hash of root coin secret key
|
||||
/// and old nonce
|
||||
pub fn derived_rho(&self) -> pallas::Base {
|
||||
let rho_msg = [
|
||||
pallas::Base::from(PREFIX_EVL),
|
||||
self.coin1_sk_root.inner(),
|
||||
self.nonce,
|
||||
pallas::Base::from(ZERO)
|
||||
];
|
||||
let rho = poseidon_hash(rho_msg);
|
||||
rho
|
||||
}
|
||||
|
||||
/// calculated derived coin commitment
|
||||
pub fn derived_commitment(&self, blind: pallas::Scalar) -> pallas::Point {
|
||||
let pk = self.pk();
|
||||
let rho = self.derived_rho();
|
||||
let cm_in = [
|
||||
pallas::Base::from(PREFIX_CM),
|
||||
pk,
|
||||
pallas::Base::from(self.value),
|
||||
rho,
|
||||
];
|
||||
let cm_v = poseidon_hash(cm_in);
|
||||
|
||||
let cm = pedersen_commitment_base(cm_v, blind);
|
||||
cm
|
||||
}
|
||||
/// the new coin to be minted after the current coin is spent
|
||||
/// in lottery.
|
||||
pub fn derive_coin(&self, eta: pallas::Base, slot: pallas::Base) -> LeadCoin {
|
||||
let mut derived = self.clone();
|
||||
let pk = self.pk();
|
||||
let rho = self.derived_rho();
|
||||
let blind = pallas::Scalar::random(&mut OsRng);
|
||||
let cm = self.derived_commitment(blind);
|
||||
derived.nonce = rho;
|
||||
derived.coin1_commitment = derived.coin2_commitment;
|
||||
derived.coin2_commitment = cm;
|
||||
derived.coin1_blind = derived.coin2_blind;
|
||||
derived.coin2_blind = blind;
|
||||
// update random mau_y, mau_rho in case epoch is changed
|
||||
let (y_mu, rho_mu) = Self::election_seeds(eta, slot);
|
||||
derived.y_mu = y_mu;
|
||||
derived.rho_mu = rho_mu;
|
||||
derived
|
||||
}
|
||||
|
||||
/// Try to create a ZK proof of consensus leadership
|
||||
pub fn create_lead_proof(&self, pk: &ProvingKey) -> Result<Proof> {
|
||||
@@ -334,8 +399,6 @@ impl LeadCoin {
|
||||
transfered_coin: PouredCoin) -> Result<TransferStx> {
|
||||
assert!(change_coin.value+transfered_coin.value==self.value
|
||||
&& self.value>0);
|
||||
let zero = pallas::Base::zero();
|
||||
let prefix_cm = pallas::Base::from(4);
|
||||
let bincode = include_bytes!("../../proof/tx.zk.bin");
|
||||
let zkbin = ZkBinary::decode(bincode)?;
|
||||
let retval = pallas::Base::from(change_coin.value);
|
||||
@@ -368,14 +431,14 @@ impl LeadCoin {
|
||||
];
|
||||
let circuit = ZkCircuit::new(witnesses, zkbin.clone());
|
||||
let proof = Proof::create(pk, &[circuit], &self.public_inputs(), &mut OsRng)?;
|
||||
let cm3_msg_in = [prefix_cm,
|
||||
let cm3_msg_in = [pallas::Base::from(PREFIX_CM),
|
||||
change_coin.pk,
|
||||
pallas::Base::from(change_coin.value),
|
||||
change_coin.rho,
|
||||
];
|
||||
let cm3_msg = poseidon_hash(cm3_msg_in);
|
||||
let cm3 = pedersen_commitment_base(cm3_msg, change_coin.opening);
|
||||
let cm4_msg_in = [prefix_cm,
|
||||
let cm4_msg_in = [pallas::Base::from(PREFIX_CM),
|
||||
transfered_coin.pk,
|
||||
pallas::Base::from(transfered_coin.value),
|
||||
transfered_coin.rho,
|
||||
|
||||
Reference in New Issue
Block a user