basic_minimal.rs 3.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113
  1. use bellman::{
  2. gadgets::{
  3. Assignment,
  4. },
  5. groth16, Circuit, ConstraintSystem, SynthesisError,
  6. };
  7. use bls12_381::Bls12;
  8. use ff::{Field};
  9. use rand::rngs::OsRng;
  10. pub const CRH_IVK_PERSONALIZATION: &[u8; 8] = b"Zcashivk";
  11. struct MyCircuit {
  12. aux: Vec<Option<bls12_381::Scalar>>,
  13. }
  14. impl Circuit<bls12_381::Scalar> for MyCircuit {
  15. fn synthesize<CS: ConstraintSystem<bls12_381::Scalar>>(
  16. self,
  17. cs: &mut CS,
  18. ) -> Result<(), SynthesisError> {
  19. //let x = num::AllocatedNum::alloc(cs.namespace(|| "conditional anchor"), || {
  20. // Ok(*self.aux_values[0].get()?)
  21. //})?;
  22. //let x2 = x.mul(cs.namespace(|| "x2"), &x)?;
  23. //let x3 = x.mul(cs.namespace(|| "x2"), &x2)?;
  24. //x3.inputize(cs.namespace(|| "pubx2"))?;
  25. // ------------------
  26. // x
  27. let x_var = cs.alloc(|| "num", || Ok(*self.aux[0].get()?))?;
  28. // x2 = x * x
  29. let x2_var = cs.alloc(|| "product num", || Ok(*self.aux[1].get()?))?;
  30. let x3_var = cs.alloc(|| "product num", || Ok(*self.aux[2].get()?))?;
  31. let input = cs.alloc_input(|| "input variable", || Ok(*self.aux[2].get()?))?;
  32. let coeff = bls12_381::Scalar::one();
  33. let lc0 = bellman::LinearCombination::zero() + (coeff, x_var);
  34. let lc1 = bellman::LinearCombination::zero() + (coeff, x_var);
  35. let lc2 = bellman::LinearCombination::zero() + (coeff, x2_var);
  36. cs.enforce(|| "multiplication constraint", |_| lc0, |_| lc1, |_| lc2);
  37. // x3 = x2 * x
  38. let coeff = bls12_381::Scalar::one();
  39. let lc0 = bellman::LinearCombination::zero() + (coeff, x2_var);
  40. let lc1 = bellman::LinearCombination::zero() + (coeff, x_var);
  41. let lc2 = bellman::LinearCombination::zero() + (coeff, x3_var);
  42. cs.enforce(|| "multiplication constraint", |_| lc0, |_| lc1, |_| lc2);
  43. // inputize values
  44. let coeff = bls12_381::Scalar::one();
  45. let lc0 = bellman::LinearCombination::zero() + (coeff, input);
  46. let lc1 = bellman::LinearCombination::zero() + (coeff, CS::one());
  47. let lc2 = bellman::LinearCombination::zero() + (coeff, x3_var);
  48. cs.enforce(|| "enforce input is correct", |_| lc0, |_| lc1, |_| lc2);
  49. Ok(())
  50. }
  51. }
  52. fn main() {
  53. use std::time::Instant;
  54. let start = Instant::now();
  55. // Create parameters for our circuit. In a production deployment these would
  56. // be generated securely using a multiparty computation.
  57. let params = {
  58. let c = MyCircuit { aux: vec![None] };
  59. groth16::generate_random_parameters::<Bls12, _, _>(c, &mut OsRng).unwrap()
  60. };
  61. println!("Setup: [{:?}]", start.elapsed());
  62. // Prepare the verification key (for proof verification).
  63. let pvk = groth16::prepare_verifying_key(&params.vk);
  64. // Pick a preimage and compute its hash.
  65. let quantity = bls12_381::Scalar::from(3);
  66. // Create an instance of our circuit (with the preimage as a witness).
  67. let c = MyCircuit {
  68. aux: vec![
  69. Some(quantity),
  70. Some(quantity * quantity),
  71. Some(quantity * quantity * quantity),
  72. ],
  73. };
  74. let start = Instant::now();
  75. // Create a Groth16 proof with our parameters.
  76. let proof = groth16::create_random_proof(c, &params, &mut OsRng).unwrap();
  77. println!("Prove: [{:?}]", start.elapsed());
  78. let public_input = vec![bls12_381::Scalar::from(27)];
  79. let start = Instant::now();
  80. // Check the proof!
  81. assert!(groth16::verify_proof(&pvk, &proof, &public_input).is_ok());
  82. println!("Verify: [{:?}]", start.elapsed());
  83. }