vm2.rs 4.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154
  1. use halo2::{
  2. arithmetic::{CurveAffine, Field},
  3. dev::MockProver,
  4. };
  5. use halo2_gadgets::primitives::{
  6. poseidon,
  7. poseidon::{ConstantLength, P128Pow5T3},
  8. };
  9. use incrementalmerkletree::{bridgetree::BridgeTree, Frontier, Tree};
  10. use pasta_curves::{group::Curve, pallas};
  11. use rand::rngs::OsRng;
  12. use simplelog::{ColorChoice, LevelFilter, TermLogger, TerminalMode};
  13. use darkfi::{
  14. crypto::{
  15. keypair::{PublicKey, SecretKey},
  16. merkle_node::MerkleNode,
  17. mint_proof::MintRevealedValues,
  18. spend_proof::SpendRevealedValues,
  19. },
  20. zk::vm2::{WitnessVar, ZkCircuit},
  21. zkas::decoder::ZkBinary,
  22. Result,
  23. };
  24. fn mint_proof() -> Result<()> {
  25. let bincode = include_bytes!("../proofs/mint.zk.bin");
  26. let zkbin = ZkBinary::decode(bincode)?;
  27. let value = 42;
  28. let token_id = pallas::Base::from(22);
  29. let value_blind = pallas::Scalar::random(&mut OsRng);
  30. let token_blind = pallas::Scalar::random(&mut OsRng);
  31. let serial = pallas::Base::random(&mut OsRng);
  32. let coin_blind = pallas::Base::random(&mut OsRng);
  33. let public_key = PublicKey::random(&mut OsRng);
  34. let revealed = MintRevealedValues::compute(
  35. value,
  36. token_id,
  37. value_blind,
  38. token_blind,
  39. serial,
  40. coin_blind,
  41. public_key,
  42. );
  43. let pk_coords = public_key.0.to_affine().coordinates().unwrap();
  44. let witnesses = vec![
  45. WitnessVar::Base(*pk_coords.x()),
  46. WitnessVar::Base(*pk_coords.y()),
  47. WitnessVar::Base(pallas::Base::from(value)),
  48. WitnessVar::Base(token_id),
  49. WitnessVar::Base(serial),
  50. WitnessVar::Base(coin_blind),
  51. WitnessVar::Scalar(value_blind),
  52. WitnessVar::Scalar(token_blind),
  53. ];
  54. let circuit = ZkCircuit::new(witnesses, revealed.make_outputs().to_vec(), zkbin);
  55. let prover = MockProver::run(11, &circuit, vec![revealed.make_outputs().to_vec()]).unwrap();
  56. assert_eq!(prover.verify(), Ok(()));
  57. Ok(())
  58. }
  59. fn burn_proof() -> Result<()> {
  60. let bincode = include_bytes!("../proofs/burn.zk.bin");
  61. let zkbin = ZkBinary::decode(bincode)?;
  62. let value = 42;
  63. let token_id = pallas::Base::from(22);
  64. let value_blind = pallas::Scalar::random(&mut OsRng);
  65. let token_blind = pallas::Scalar::random(&mut OsRng);
  66. let serial = pallas::Base::random(&mut OsRng);
  67. let coin_blind = pallas::Base::random(&mut OsRng);
  68. let secret = SecretKey::random(&mut OsRng);
  69. let sig_secret = SecretKey::random(&mut OsRng);
  70. let mut tree = BridgeTree::<MerkleNode, 32>::new(100);
  71. let random_coin_1 = pallas::Base::random(&mut OsRng);
  72. tree.append(&MerkleNode(random_coin_1));
  73. tree.witness();
  74. let random_coin_2 = pallas::Base::random(&mut OsRng);
  75. tree.append(&MerkleNode(random_coin_2));
  76. let coin = {
  77. let coords = PublicKey::from_secret(secret).0.to_affine().coordinates().unwrap();
  78. let messages =
  79. [*coords.x(), *coords.y(), pallas::Base::from(value), token_id, serial, coin_blind];
  80. poseidon::Hash::init(P128Pow5T3, ConstantLength::<6>).hash(messages)
  81. };
  82. tree.append(&MerkleNode(coin));
  83. tree.witness();
  84. let random_coin_3 = pallas::Base::random(&mut OsRng);
  85. tree.append(&MerkleNode(random_coin_3));
  86. tree.witness();
  87. let (leaf_position, merkle_path) = tree.authentication_path(&MerkleNode(coin)).unwrap();
  88. let revealed = SpendRevealedValues::compute(
  89. value,
  90. token_id,
  91. value_blind,
  92. token_blind,
  93. serial,
  94. coin_blind,
  95. secret,
  96. leaf_position,
  97. merkle_path.clone(),
  98. sig_secret,
  99. );
  100. // Why are these types not matched in halo2 gadgets?
  101. let leaf_pos: u64 = leaf_position.into();
  102. let leaf_pos = leaf_pos as u32;
  103. let witnesses = vec![
  104. WitnessVar::Base(secret.0),
  105. WitnessVar::Base(serial),
  106. WitnessVar::Base(pallas::Base::from(value)),
  107. WitnessVar::Base(token_id),
  108. WitnessVar::Base(coin_blind),
  109. WitnessVar::Scalar(value_blind),
  110. WitnessVar::Scalar(token_blind),
  111. WitnessVar::Uint32(leaf_pos),
  112. WitnessVar::MerklePath(merkle_path),
  113. WitnessVar::Base(sig_secret.0),
  114. ];
  115. let circuit = ZkCircuit::new(witnesses, revealed.make_outputs().to_vec(), zkbin);
  116. let prover = MockProver::run(11, &circuit, vec![revealed.make_outputs().to_vec()])?;
  117. assert_eq!(prover.verify(), Ok(()));
  118. Ok(())
  119. }
  120. fn main() -> Result<()> {
  121. TermLogger::init(
  122. LevelFilter::Debug,
  123. simplelog::Config::default(),
  124. TerminalMode::Mixed,
  125. ColorChoice::Auto,
  126. )?;
  127. mint_proof()?;
  128. burn_proof()?;
  129. Ok(())
  130. }