vm2.rs 4.5 KB

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