vm.rs 3.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. use halo2::dev::MockProver;
  2. use halo2_gadgets::{
  3. primitives,
  4. primitives::poseidon::{ConstantLength, P128Pow5T3},
  5. };
  6. use pasta_curves::{
  7. arithmetic::{CurveAffine, Field},
  8. group::{Curve, Group},
  9. pallas,
  10. };
  11. use rand::rngs::OsRng;
  12. use std::{collections::HashMap, fs::File, time::Instant};
  13. use darkfi::{
  14. crypto::{
  15. constants::OrchardFixedBases,
  16. proof::{Proof, ProvingKey, VerifyingKey},
  17. util::pedersen_commitment_u64,
  18. },
  19. util::serial::Decodable,
  20. zk::vm,
  21. Error,
  22. };
  23. fn main() -> std::result::Result<(), Error> {
  24. // The number of rows in our circuit cannot exceed 2^k
  25. let k: u32 = 11;
  26. let start = Instant::now();
  27. let file = File::open("../proof/mint.zk.bin")?;
  28. let zkbin = vm::ZkBinary::decode(file)?;
  29. for contract_name in zkbin.contracts.keys() {
  30. println!("Loaded '{}' contract.", contract_name);
  31. }
  32. println!("Load time: [{:?}]", start.elapsed());
  33. let contract = &zkbin.contracts["Mint"];
  34. //contract.witness_base(...);
  35. //contract.witness_base(...);
  36. //contract.witness_base(...);
  37. let pubkey = pallas::Point::random(&mut OsRng);
  38. let coords = pubkey.to_affine().coordinates().unwrap();
  39. let value = 110;
  40. let asset = 1;
  41. let value_blind = pallas::Scalar::random(&mut OsRng);
  42. let asset_blind = pallas::Scalar::random(&mut OsRng);
  43. let serial = pallas::Base::random(&mut OsRng);
  44. let coin_blind = pallas::Base::random(&mut OsRng);
  45. let mut coin = pallas::Base::zero();
  46. let messages = [
  47. [*coords.x(), *coords.y()],
  48. [pallas::Base::from(value), pallas::Base::from(asset)],
  49. [serial, coin_blind],
  50. ];
  51. for msg in messages.iter() {
  52. coin += primitives::poseidon::Hash::init(P128Pow5T3, ConstantLength::<2>).hash(*msg);
  53. }
  54. let _coin2 = primitives::poseidon::Hash::init(P128Pow5T3, ConstantLength::<2>)
  55. .hash([*coords.x(), *coords.y()]);
  56. let value_commit = pedersen_commitment_u64(value, value_blind);
  57. let value_coords = value_commit.to_affine().coordinates().unwrap();
  58. let asset_commit = pedersen_commitment_u64(asset, asset_blind);
  59. let asset_coords = asset_commit.to_affine().coordinates().unwrap();
  60. let public_inputs =
  61. vec![coin, *value_coords.x(), *value_coords.y(), *asset_coords.x(), *asset_coords.y()];
  62. let mut const_fixed_points = HashMap::new();
  63. const_fixed_points.insert("VALUE_COMMIT_VALUE".to_string(), OrchardFixedBases::ValueCommitV);
  64. const_fixed_points.insert("VALUE_COMMIT_RANDOM".to_string(), OrchardFixedBases::ValueCommitR);
  65. let mut circuit = vm::ZkCircuit::new(const_fixed_points, &zkbin.constants, contract);
  66. let empty_circuit = circuit.clone();
  67. circuit.witness_base("pub_x", *coords.x())?;
  68. circuit.witness_base("pub_y", *coords.y())?;
  69. circuit.witness_base("value", pallas::Base::from(value))?;
  70. circuit.witness_base("asset", pallas::Base::from(asset))?;
  71. circuit.witness_base("serial", serial)?;
  72. circuit.witness_base("coin_blind", coin_blind)?;
  73. circuit.witness_scalar("value_blind", value_blind)?;
  74. circuit.witness_scalar("asset_blind", asset_blind)?;
  75. // Valid MockProver
  76. let prover = MockProver::run(k, &circuit, vec![public_inputs.clone()]).unwrap();
  77. assert_eq!(prover.verify(), Ok(()));
  78. // Actual ZK proof
  79. let start = Instant::now();
  80. let vk = VerifyingKey::build(k, empty_circuit.clone());
  81. let pk = ProvingKey::build(k, empty_circuit.clone());
  82. println!("\nSetup: [{:?}]", start.elapsed());
  83. let start = Instant::now();
  84. let proof = Proof::create(&pk, &[circuit], &public_inputs).unwrap();
  85. println!("Prove: [{:?}]", start.elapsed());
  86. let start = Instant::now();
  87. assert!(proof.verify(&vk, &public_inputs).is_ok());
  88. println!("Verify: [{:?}]", start.elapsed());
  89. Ok(())
  90. }