simple3.rs 3.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130
  1. use halo2::{
  2. circuit::{SimpleFloorPlanner, Chip, Layouter},
  3. pasta::{EqAffine, Fp},
  4. plonk::{Advice, Circuit, Column, ConstraintSystem, Error, Expression, Selector, create_proof, verify_proof, keygen_vk, keygen_pk},
  5. poly::{commitment::Params, Rotation},
  6. transcript::{Blake2bRead, Blake2bWrite, Challenge255},
  7. };
  8. use std::time::Instant;
  9. #[derive(Clone, Debug)]
  10. struct CoolConfig {
  11. a_col: Column<Advice>,
  12. s_range: Selector,
  13. }
  14. struct CoolChip {
  15. config: CoolConfig
  16. }
  17. impl Chip<Fp> for CoolChip {
  18. type Config = CoolConfig;
  19. type Loaded = ();
  20. fn config(&self) -> &Self::Config {
  21. &self.config
  22. }
  23. fn loaded(&self) -> &Self::Loaded {
  24. &()
  25. }
  26. }
  27. impl CoolChip {
  28. fn construct(config: CoolConfig) -> Self {
  29. Self { config }
  30. }
  31. fn configure(cs: &mut ConstraintSystem<Fp>) -> CoolConfig {
  32. let a_col = cs.advice_column();
  33. let s_range = cs.selector();
  34. cs.create_gate("check", |cs| {
  35. let a = cs.query_advice(a_col, Rotation::cur());
  36. let s_range = cs.query_selector(s_range);
  37. vec![s_range * (a - Expression::Constant(Fp::from(2)))]
  38. });
  39. CoolConfig { a_col, s_range }
  40. }
  41. fn alloc_and_check(
  42. &self,
  43. layouter: &mut impl Layouter<Fp>,
  44. a: Option<Fp>,
  45. ) -> Result<(), Error> {
  46. layouter.assign_region(
  47. || "load private inputs",
  48. |mut region| {
  49. let row_offset = 0;
  50. self.config.s_range.enable(&mut region, row_offset)?;
  51. region.assign_advice(
  52. || "private input 'a'",
  53. self.config.a_col,
  54. row_offset,
  55. || a.ok_or(Error::SynthesisError),
  56. )?;
  57. Ok(())
  58. },
  59. )
  60. }
  61. }
  62. #[derive(Clone)]
  63. struct CoolCircuit {
  64. // Private input.
  65. a: Option<Fp>,
  66. }
  67. impl Circuit<Fp> for CoolCircuit {
  68. type Config = CoolConfig;
  69. type FloorPlanner = SimpleFloorPlanner;
  70. fn without_witnesses(&self) -> Self {
  71. Self { a: None }
  72. }
  73. fn configure(cs: &mut ConstraintSystem<Fp>) -> Self::Config {
  74. CoolChip::configure(cs)
  75. }
  76. fn synthesize(&self, config: Self::Config, mut layouter: impl Layouter<Fp>) -> Result<(), Error> {
  77. let chip = CoolChip::construct(config);
  78. chip.alloc_and_check(&mut layouter, self.a)
  79. }
  80. }
  81. fn main() {
  82. let start = Instant::now();
  83. let params: Params<EqAffine> = Params::new(4);
  84. let empty_circuit = CoolCircuit { a: None };
  85. let vk = keygen_vk(&params, &empty_circuit).expect("keygen_vk should not fail");
  86. let pk = keygen_pk(&params, vk, &empty_circuit).expect("keygen_pk should not fail");
  87. println!("Setup: [{:?}]", start.elapsed());
  88. let start = Instant::now();
  89. let circuit = CoolCircuit {
  90. a: Some(Fp::from(2)),
  91. };
  92. // Create a proof
  93. let mut transcript = Blake2bWrite::<_, _, Challenge255<_>>::init(vec![]);
  94. create_proof(&params, &pk, &[circuit], &[&[]], &mut transcript)
  95. .expect("proof generation should not fail");
  96. let proof = transcript.finalize();
  97. println!("Prove: [{:?}]", start.elapsed());
  98. let start = Instant::now();
  99. let msm = params.empty_msm();
  100. let mut transcript = Blake2bRead::<_, _, Challenge255<_>>::init(&proof[..]);
  101. let verification = verify_proof(&params, pk.get_vk(), msm, &[&[]], &mut transcript);
  102. if let Err(err) = verification {
  103. panic!("error {:?}", err);
  104. }
  105. let guard = verification.unwrap();
  106. let msm = guard.clone().use_challenges();
  107. assert!(msm.eval());
  108. println!("Verify: [{:?}]", start.elapsed());
  109. }