leadcoin.rs 5.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133
  1. use halo2_gadgets::poseidon::primitives as poseidon;
  2. use halo2_proofs::circuit::Value;
  3. use pasta_curves::pallas;
  4. use crate::{
  5. crypto::{
  6. constants::MERKLE_DEPTH_ORCHARD,
  7. keypair::Keypair,
  8. merkle_node::MerkleNode,
  9. util::{mod_r_p, pedersen_commitment_base},
  10. },
  11. zk::circuit::lead_contract::LeadContract,
  12. };
  13. use incrementalmerkletree::Hashable;
  14. use pasta_curves::{arithmetic::CurveAffine, group::Curve};
  15. //use halo2_proofs::arithmetic::CurveAffine;
  16. pub const LEAD_PUBLIC_INPUT_LEN: usize = 11;
  17. #[derive(Debug, Default, Clone, Copy)]
  18. pub struct LeadCoin {
  19. pub value: Option<u64>, // coin stake
  20. pub cm: Option<pallas::Point>, // coin commitment
  21. pub cm2: Option<pallas::Point>, // poured coin commitment
  22. pub idx: u32, // coin idex
  23. pub sl: Option<pallas::Base>, // coin slot id
  24. pub tau: Option<pallas::Base>, // coin time stamp
  25. pub nonce: Option<pallas::Base>, // coin nonce
  26. pub nonce_cm: Option<pallas::Base>, // coin nonce's commitment
  27. pub sn: Option<pallas::Base>, // coin's serial number
  28. pub keypair: Option<Keypair>,
  29. pub root_cm: Option<pallas::Scalar>, // root of coin commitment
  30. pub root_sk: Option<pallas::Base>, // coin's secret key
  31. pub path: Option<[MerkleNode; MERKLE_DEPTH_ORCHARD]>, // path to the coin's commitment
  32. pub path_sk: Option<[MerkleNode; MERKLE_DEPTH_ORCHARD]>, // path to the coin's secret key
  33. pub c1_blind: Option<pallas::Scalar>, // coin opening
  34. pub c2_blind: Option<pallas::Scalar>, // poured coin opening
  35. // election seeds
  36. pub y_mu: Option<pallas::Base>, // leader election nonce derived from eta at onset of epoch
  37. pub rho_mu: Option<pallas::Base>, // leader election nonce derived from eta at onset of epoch
  38. pub sigma1: Option<pallas::Base>,
  39. pub sigma2: Option<pallas::Base>,
  40. }
  41. impl LeadCoin {
  42. pub fn public_inputs_as_array(&self) -> [pallas::Base; LEAD_PUBLIC_INPUT_LEN] {
  43. let po_nonce = self.nonce_cm.unwrap();
  44. let _po_tau = pedersen_commitment_base(self.tau.unwrap(), self.root_cm.unwrap())
  45. .to_affine()
  46. .coordinates()
  47. .unwrap();
  48. let po_cm = self.cm.unwrap().to_affine().coordinates().unwrap();
  49. let po_cm2 = self.cm2.unwrap().to_affine().coordinates().unwrap();
  50. let po_pk = self.keypair.unwrap().public.0.to_affine().coordinates().unwrap();
  51. let po_sn = self.sn.unwrap();
  52. let y_mu = self.y_mu.unwrap();
  53. let rho_mu = self.rho_mu.unwrap();
  54. let root_sk = self.root_sk.unwrap();
  55. let nonce = self.nonce.unwrap();
  56. let lottery_msg_input = [root_sk, nonce];
  57. let lottery_msg: pallas::Base =
  58. poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init()
  59. .hash(lottery_msg_input);
  60. //
  61. let po_y_pt: pallas::Point = pedersen_commitment_base(lottery_msg, mod_r_p(y_mu));
  62. let po_y = *po_y_pt.to_affine().coordinates().unwrap().x();
  63. //
  64. let po_rho_pt: pallas::Point = pedersen_commitment_base(lottery_msg, mod_r_p(rho_mu));
  65. let po_rho = *po_rho_pt.to_affine().coordinates().unwrap().x();
  66. let cm_pos = self.idx;
  67. let cm_root = {
  68. let pos: u32 = cm_pos;
  69. let c_cm_coordinates = self.cm.unwrap().to_affine().coordinates().unwrap();
  70. let c_cm_base: pallas::Base = c_cm_coordinates.x() * c_cm_coordinates.y();
  71. let mut current = MerkleNode(c_cm_base);
  72. for (level, sibling) in self.path.unwrap().iter().enumerate() {
  73. let level = level as u8;
  74. current = if pos & (1 << level) == 0 {
  75. MerkleNode::combine(level.into(), &current, sibling)
  76. } else {
  77. MerkleNode::combine(level.into(), sibling, &current)
  78. };
  79. }
  80. current
  81. };
  82. let public_inputs: [pallas::Base; LEAD_PUBLIC_INPUT_LEN] = [
  83. *po_cm.x(),
  84. *po_cm.y(),
  85. *po_cm2.x(),
  86. *po_cm2.y(),
  87. po_nonce,
  88. cm_root.0,
  89. *po_pk.x(),
  90. *po_pk.y(),
  91. po_sn,
  92. po_y,
  93. po_rho,
  94. ];
  95. public_inputs
  96. }
  97. pub fn public_inputs(&self) -> Vec<pallas::Base> {
  98. self.public_inputs_as_array().to_vec()
  99. }
  100. pub fn create_contract(&self) -> LeadContract {
  101. LeadContract {
  102. path: Value::known(self.path.unwrap()),
  103. sk: Value::known(self.keypair.unwrap().secret.inner()),
  104. root_sk: Value::known(self.root_sk.unwrap()),
  105. path_sk: Value::known(self.path_sk.unwrap()),
  106. coin_timestamp: Value::known(self.tau.unwrap()), //
  107. coin_nonce: Value::known(self.nonce.unwrap()),
  108. coin1_blind: Value::known(self.c1_blind.unwrap()),
  109. value: Value::known(pallas::Base::from(self.value.unwrap())),
  110. coin2_blind: Value::known(self.c2_blind.unwrap()),
  111. cm_pos: Value::known(self.idx),
  112. //sn_c1: Value::known(self.sn.unwrap()),
  113. slot: Value::known(self.sl.unwrap()),
  114. mau_rho: Value::known(mod_r_p(self.rho_mu.unwrap())),
  115. mau_y: Value::known(mod_r_p(self.y_mu.unwrap())),
  116. root_cm: Value::known(self.root_cm.unwrap()),
  117. sigma1: Value::known(self.sigma1.unwrap()),
  118. sigma2: Value::known(self.sigma2.unwrap()),
  119. }
  120. }
  121. }