leadcoin.rs 5.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118
  1. /* This file is part of DarkFi (https://dark.fi)
  2. *
  3. * Copyright (C) 2020-2022 Dyne.org foundation
  4. *
  5. * This program is free software: you can redistribute it and/or modify
  6. * it under the terms of the GNU Affero General Public License as
  7. * published by the Free Software Foundation, either version 3 of the
  8. * License, or (at your option) any later version.
  9. *
  10. * This program is distributed in the hope that it will be useful,
  11. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. * GNU Affero General Public License for more details.
  14. *
  15. * You should have received a copy of the GNU Affero General Public License
  16. * along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. */
  18. use darkfi_sdk::crypto::{constants::MERKLE_DEPTH_ORCHARD, MerkleNode};
  19. use halo2_gadgets::poseidon::primitives as poseidon;
  20. use halo2_proofs::circuit::Value;
  21. use pasta_curves::{arithmetic::CurveAffine, group::Curve, pallas};
  22. use crate::{
  23. crypto::{
  24. keypair::Keypair,
  25. util::{mod_r_p, pedersen_commitment_base},
  26. },
  27. zk::circuit::lead_contract::LeadContract,
  28. };
  29. pub const LEAD_PUBLIC_INPUT_LEN: usize = 4;
  30. #[derive(Debug, Default, Clone, Copy)]
  31. pub struct LeadCoin {
  32. pub value: Option<u64>, // coin stake
  33. pub cm: Option<pallas::Point>, // coin commitment
  34. pub cm2: Option<pallas::Point>, // poured coin commitment
  35. pub idx: u32, // coin index
  36. pub sl: Option<pallas::Base>, // coin slot id
  37. pub tau: Option<pallas::Base>, // coin time stamp
  38. pub nonce: Option<pallas::Base>, // coin nonce
  39. pub nonce_cm: Option<pallas::Base>, // coin nonce's commitment
  40. pub sn: Option<pallas::Base>, // coin's serial number
  41. pub keypair: Option<Keypair>,
  42. pub root_cm: Option<pallas::Base>, // root of coin commitment
  43. pub root_sk: Option<pallas::Base>, // coin's secret key
  44. pub path: Option<[MerkleNode; MERKLE_DEPTH_ORCHARD]>, // path to the coin's commitment
  45. pub path_sk: Option<[MerkleNode; MERKLE_DEPTH_ORCHARD]>, // path to the coin's secret key
  46. pub c1_blind: Option<pallas::Scalar>, // coin opening
  47. pub c2_blind: Option<pallas::Scalar>, // poured coin opening
  48. // election seeds
  49. pub y_mu: Option<pallas::Base>, // leader election nonce derived from eta at onset of epoch
  50. pub rho_mu: Option<pallas::Base>, // leader election nonce derived from eta at onset of epoch
  51. pub sigma1: Option<pallas::Base>,
  52. pub sigma2: Option<pallas::Base>,
  53. }
  54. impl LeadCoin {
  55. pub fn public_inputs_as_array(&self) -> [pallas::Base; LEAD_PUBLIC_INPUT_LEN] {
  56. let po_nonce = self.nonce_cm.unwrap();
  57. let po_pk = self.keypair.unwrap().public.0.to_affine().coordinates().unwrap();
  58. let y_mu = self.y_mu.unwrap();
  59. let _rho_mu = self.rho_mu.unwrap();
  60. let root_sk = self.root_sk.unwrap();
  61. let nonce = self.nonce.unwrap();
  62. let lottery_msg_input = [root_sk, nonce];
  63. let lottery_msg: pallas::Base =
  64. poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init()
  65. .hash(lottery_msg_input);
  66. let po_y_pt: pallas::Point = pedersen_commitment_base(lottery_msg, mod_r_p(y_mu));
  67. let po_y_x = *po_y_pt.to_affine().coordinates().unwrap().x();
  68. let po_y_y = *po_y_pt.to_affine().coordinates().unwrap().y();
  69. let y_coord_arr = [po_y_x, po_y_y];
  70. let po_y: pallas::Base =
  71. poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init()
  72. .hash(y_coord_arr);
  73. let public_inputs: [pallas::Base; LEAD_PUBLIC_INPUT_LEN] =
  74. [po_nonce, *po_pk.x(), *po_pk.y(), po_y];
  75. public_inputs
  76. }
  77. pub fn public_inputs(&self) -> Vec<pallas::Base> {
  78. self.public_inputs_as_array().to_vec()
  79. }
  80. pub fn create_contract(&self) -> LeadContract {
  81. let rho_mu = self.rho_mu.unwrap();
  82. let root_sk = self.root_sk.unwrap();
  83. let nonce = self.nonce.unwrap();
  84. let lottery_msg_input = [root_sk, nonce];
  85. let lottery_msg: pallas::Base =
  86. poseidon::Hash::<_, poseidon::P128Pow5T3, poseidon::ConstantLength<2>, 3, 2>::init()
  87. .hash(lottery_msg_input);
  88. //
  89. let rho_pt: pallas::Point = pedersen_commitment_base(lottery_msg, mod_r_p(rho_mu));
  90. LeadContract {
  91. coin1_commit_merkle_path: Value::known(self.path.unwrap()),
  92. coin1_commit_root: Value::known(self.root_cm.unwrap()),
  93. coin1_commit_leaf_pos: Value::known(self.idx),
  94. coin1_sk: Value::known(self.keypair.unwrap().secret.inner()),
  95. coin1_sk_root: Value::known(self.root_sk.unwrap()),
  96. coin1_sk_merkle_path: Value::known(self.path_sk.unwrap()),
  97. coin1_timestamp: Value::known(self.tau.unwrap()), //
  98. coin1_nonce: Value::known(self.nonce.unwrap()),
  99. coin1_blind: Value::known(self.c1_blind.unwrap()),
  100. coin1_serial: Value::known(self.sn.unwrap()),
  101. coin1_value: Value::known(pallas::Base::from(self.value.unwrap())),
  102. coin2_blind: Value::known(self.c2_blind.unwrap()),
  103. coin2_commit: Value::known(self.cm2.unwrap()),
  104. mau_rho: Value::known(mod_r_p(self.rho_mu.unwrap())),
  105. mau_y: Value::known(mod_r_p(self.y_mu.unwrap())),
  106. sigma1: Value::known(self.sigma1.unwrap()),
  107. sigma2: Value::known(self.sigma2.unwrap()),
  108. rho: Value::known(rho_pt),
  109. }
  110. }
  111. }