basic_minimal.rs 3.7 KB

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