lead.rs 8.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226
  1. use halo2_proofs::{arithmetic::Field, dev::MockProver};
  2. use incrementalmerkletree::{bridgetree::BridgeTree, Hashable, Tree};
  3. use pasta_curves::{
  4. arithmetic::CurveAffine,
  5. group::{ff::PrimeField, Curve, GroupEncoding},
  6. pallas, Fp,
  7. };
  8. use rand::{thread_rng, Rng};
  9. use serde::{Deserialize, Serialize};
  10. use darkfi::{
  11. crypto::{
  12. constants::{
  13. NullifierK, OrchardFixedBases, OrchardFixedBasesFull, ValueCommitV,
  14. MERKLE_DEPTH_ORCHARD,
  15. },
  16. keypair::{Keypair, PublicKey, SecretKey},
  17. lead_proof::{create_lead_proof, verify_lead_proof},
  18. leadcoin::LeadCoin,
  19. merkle_node::MerkleNode,
  20. nullifier::Nullifier,
  21. proof::{Proof, ProvingKey, VerifyingKey},
  22. types::{DrkCoinBlind, DrkSerial, DrkTokenId, DrkValue, DrkValueBlind, DrkValueCommit, *},
  23. util::{mod_r_p, pedersen_commitment_scalar, pedersen_commitment_u64},
  24. },
  25. zk::circuit::lead_contract::LeadContract,
  26. };
  27. fn create_coins_sks(len: usize) -> (Vec<MerkleNode>, Vec<[MerkleNode; MERKLE_DEPTH_ORCHARD]>) {
  28. /*
  29. at the onset of an epoch, the first slot's coin's secret key
  30. is sampled at random, and the reset of the secret keys are derived,
  31. for sk (secret key) at time i+1 is derived from secret key at time i.
  32. */
  33. let mut rng = thread_rng();
  34. let sk: u64 = rng.gen();
  35. let mut tree = BridgeTree::<MerkleNode, 32>::new(len);
  36. let mut root_sks: Vec<MerkleNode> = vec![];
  37. let mut path_sks: Vec<[MerkleNode; MERKLE_DEPTH_ORCHARD]> = vec![];
  38. for i in 0..len {
  39. //TODO (research) why the conversion between point and base is panicing?
  40. // is the endianess different?
  41. let base = pedersen_commitment_scalar(pallas::Scalar::one(), pallas::Scalar::from(sk));
  42. let coord = base.to_affine().coordinates().unwrap();
  43. //let sk = coord.x() * coord.y();
  44. //let sk = *coord.y();
  45. let sk: [u8; 32] = pallas::Base::random(rng.clone()).to_repr();
  46. let node = MerkleNode::from_bytes(&sk).unwrap();
  47. //let serialized = serde_json::to_string(&node).unwrap();
  48. //println!("serialized: {}", serialized);
  49. tree.append(&node.clone());
  50. let leaf_position = tree.witness();
  51. let root = tree.root(0).unwrap();
  52. //let (leaf_pos, path) = tree.authentication_path(leaf_position.unwrap()).unwrap();
  53. let path = tree.authentication_path(leaf_position.unwrap(), &root).unwrap();
  54. //note root sk is at tree.root()
  55. //root_sks.push(node);
  56. root_sks.push(root);
  57. path_sks.push(path.as_slice().try_into().unwrap());
  58. }
  59. (root_sks, path_sks)
  60. }
  61. fn create_coins(
  62. root_sks: Vec<MerkleNode>,
  63. path_sks: Vec<[MerkleNode; MERKLE_DEPTH_ORCHARD]>,
  64. values: Vec<u64>,
  65. cm1_blind: pallas::Base,
  66. cm2_blind: pallas::Base,
  67. len: usize,
  68. ) -> Vec<LeadCoin> {
  69. let mut rng = thread_rng();
  70. let mut seeds: Vec<u64> = vec![];
  71. for i in 0..len {
  72. let rho: u64 = rng.gen();
  73. seeds.push(rho.clone());
  74. }
  75. let mut tree_cm = BridgeTree::<MerkleNode, 32>::new(len);
  76. let mut coins: Vec<LeadCoin> = vec![];
  77. for i in 0..len {
  78. let c_v = pallas::Base::from(values[i]);
  79. //random sampling of the same size of prf,
  80. //pseudo random sampling that is the size of pederson commitment
  81. // coin slot number
  82. let c_sl = pallas::Base::from(u64::try_from(i).unwrap());
  83. //
  84. let c_tau = pallas::Base::from(u64::try_from(i).unwrap()); // let's assume it's sl for simplicity
  85. //
  86. let c_root_sk: MerkleNode = root_sks[i];
  87. let c_pk = pedersen_commitment_scalar(mod_r_p(c_tau), mod_r_p(c_root_sk.inner()));
  88. let c_seed = pallas::Base::from(seeds[i]);
  89. let c_sn = pedersen_commitment_scalar(mod_r_p(c_seed), mod_r_p(c_root_sk.inner()));
  90. let c_pk_pt = c_pk.to_affine().coordinates().unwrap();
  91. let c_pk_pt_x: pallas::Base = *c_pk_pt.x();
  92. let c_pk_pt_y: pallas::Base = *c_pk_pt.y();
  93. let c_cm_v = c_v.clone() * c_seed.clone() * c_pk_pt_x * c_pk_pt_y;
  94. let c_cm1_blind = cm1_blind; //TODO (fix) should be read from DrkValueBlind
  95. let c_cm2_blind = cm2_blind; //TODO (fix) should be read from DrkValueBlind
  96. let c_cm: pallas::Point = pedersen_commitment_scalar(mod_r_p(c_cm_v), mod_r_p(c_cm1_blind));
  97. let c_cm_coordinates = c_cm.to_affine().coordinates().unwrap();
  98. let c_cm_base: pallas::Base = c_cm_coordinates.x() * c_cm_coordinates.y();
  99. let c_cm_node = MerkleNode(c_cm_base);
  100. tree_cm.append(&c_cm_node.clone());
  101. let leaf_position = tree_cm.witness();
  102. let c_root_cm = tree_cm.root(0).unwrap();
  103. let c_cm_path = tree_cm.authentication_path(leaf_position.unwrap(), &c_root_cm).unwrap();
  104. // lead coin commitment
  105. let c_seed2 = pedersen_commitment_scalar(mod_r_p(c_seed), mod_r_p(c_root_sk.inner()));
  106. let c_seed2_pt = c_seed2.to_affine().coordinates().unwrap();
  107. /*
  108. let lead_coin_msg = [c_pk_pt_y.clone(),
  109. c_pk_pt_x.clone(),
  110. c_v,
  111. *c_seed2_pt.x(),
  112. *c_seed2_pt.y()
  113. ];
  114. let lead_coin_msg_hash =
  115. poseidon::Hash::<_, P128Pow5T3, ConstantLength<5>, 3, 2>::init().hash(lead_coin_msg);
  116. */
  117. let lead_coin_msg =
  118. c_pk_pt_y.clone() * c_pk_pt_x.clone() * c_v * *c_seed2_pt.x() * *c_seed2_pt.y();
  119. let c_cm2 = pedersen_commitment_scalar(mod_r_p(lead_coin_msg), mod_r_p(c_cm2_blind));
  120. let c_root_sk = root_sks[i];
  121. let c_root_sk_bytes: [u8; 32] = c_root_sk.inner().to_repr();
  122. let mut c_root_sk_base_bytes: [u8; 32] = [0; 32];
  123. for i in 0..23 {
  124. c_root_sk_base_bytes[i] = c_root_sk_bytes[i];
  125. }
  126. let c_root_sk_base = pallas::Base::from_repr(c_root_sk_base_bytes);
  127. let c_path_sk = path_sks[i];
  128. let coin = LeadCoin {
  129. value: Some(c_v),
  130. cm: Some(c_cm),
  131. cm2: Some(c_cm2),
  132. idx: u32::try_from(i).unwrap(),
  133. sl: Some(c_sl),
  134. tau: Some(c_tau),
  135. nonce: Some(c_seed),
  136. nonce_cm: Some(c_seed2),
  137. sn: Some(c_sn),
  138. pk: Some(c_pk),
  139. pk_x: Some(c_pk_pt_x),
  140. pk_y: Some(c_pk_pt_y),
  141. root_cm: Some(mod_r_p(c_root_cm.inner())),
  142. root_sk: Some(c_root_sk.inner()),
  143. path: Some(c_cm_path.as_slice().try_into().unwrap()),
  144. path_sk: Some(c_path_sk),
  145. opening1: Some(c_cm1_blind),
  146. opening2: Some(c_cm2_blind),
  147. };
  148. coins.push(coin);
  149. }
  150. coins
  151. }
  152. fn main() {
  153. let k: u32 = 13;
  154. //let lead_pk = ProvingKey::build(k, &LeadContract::default());
  155. //let lead_vk = VerifyingKey::build(k, &LeadContract::default());
  156. //
  157. const LEN: usize = 10;
  158. let mut rng = thread_rng();
  159. let mut root_sks: Vec<MerkleNode> = vec![];
  160. let mut path_sks: Vec<[MerkleNode; MERKLE_DEPTH_ORCHARD]> = vec![];
  161. let mut values: Vec<u64> = vec![];
  162. for i in 0..LEN {
  163. values.push(u64::try_from(i * 2).unwrap());
  164. }
  165. let cm1_val: u64 = rng.gen();
  166. let cm1_blind: pallas::Base = pallas::Base::from(cm1_val);
  167. let cm2_val: u64 = rng.gen();
  168. let cm2_blind: pallas::Base = pallas::Base::from(cm2_val);
  169. (root_sks, path_sks) = create_coins_sks(LEN);
  170. let mut coins: Vec<LeadCoin> =
  171. create_coins(root_sks.clone(), path_sks.clone(), values, cm1_blind, cm2_blind, LEN);
  172. //
  173. let coin_idx = 0;
  174. let coin = coins[coin_idx];
  175. let yu64: u64 = rng.gen();
  176. let rhou64: u64 = rng.gen();
  177. let mau_y: pallas::Base = pallas::Base::from(yu64);
  178. let mau_rho: pallas::Base = pallas::Base::from(rhou64);
  179. let contract = LeadContract {
  180. path: coin.path,
  181. coin_pk_x: coin.pk_x,
  182. coin_pk_y: coin.pk_y,
  183. root_sk: coin.root_sk,
  184. sf_root_sk: Some(mod_r_p(coin.root_sk.unwrap())),
  185. path_sk: coin.path_sk,
  186. coin_timestamp: coin.tau, //
  187. coin_nonce: coin.nonce,
  188. coin_opening_1: Some(mod_r_p(coin.opening1.unwrap())),
  189. value: coin.value,
  190. coin_opening_2: Some(mod_r_p(coin.opening2.unwrap())),
  191. cm_pos: Some(coin.idx),
  192. //sn_c1: Some(coin.sn.unwrap()),
  193. slot: Some(coin.sl.unwrap()),
  194. mau_rho: Some(mod_r_p(mau_rho.clone())),
  195. mau_y: Some(mod_r_p(mau_y.clone())),
  196. root_cm: Some(coin.root_cm.unwrap()),
  197. };
  198. //let proof = create_lead_proof(lead_pk.clone(), coin.clone()).unwrap();
  199. //verify_lead_proof(&lead_vk, &proof, coin);
  200. // calculate public inputs
  201. let public_inputs = coin.public_inputs();
  202. let prover = MockProver::run(k, &contract, vec![public_inputs]).unwrap();
  203. //
  204. assert_eq!(prover.verify(), Ok(()));
  205. //
  206. }