You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

145 lines
3.6 KiB

  1. #![allow(non_snake_case)]
  2. use nova_snark::{
  3. traits::{Group, StepCircuit},
  4. PublicParams, RecursiveSNARK,
  5. };
  6. type G1 = pasta_curves::pallas::Point;
  7. type G2 = pasta_curves::vesta::Point;
  8. #[derive(Clone, Debug)]
  9. struct TrivialTestCircuit<F: PrimeField> {
  10. _p: PhantomData<F>,
  11. }
  12. impl<F> StepCircuit<F> for TrivialTestCircuit<F>
  13. where
  14. F: PrimeField,
  15. {
  16. fn synthesize<CS: ConstraintSystem<F>>(
  17. &self,
  18. _cs: &mut CS,
  19. z: AllocatedNum<F>,
  20. ) -> Result<AllocatedNum<F>, SynthesisError> {
  21. Ok(z)
  22. }
  23. fn compute(&self, z: &F) -> F {
  24. *z
  25. }
  26. }
  27. type C1 = TrivialTestCircuit<<G1 as Group>::Scalar>;
  28. type C2 = TrivialTestCircuit<<G2 as Group>::Scalar>;
  29. use bellperson::{gadgets::num::AllocatedNum, ConstraintSystem, SynthesisError};
  30. use core::marker::PhantomData;
  31. use criterion::*;
  32. use ff::PrimeField;
  33. use std::time::Duration;
  34. fn recursive_snark_benchmark(c: &mut Criterion) {
  35. let num_samples = 10;
  36. bench_recursive_snark(c, num_samples);
  37. }
  38. fn set_duration() -> Criterion {
  39. Criterion::default().warm_up_time(Duration::from_millis(3000))
  40. }
  41. criterion_group! {
  42. name = recursive_snark;
  43. config = set_duration();
  44. targets = recursive_snark_benchmark
  45. }
  46. criterion_main!(recursive_snark);
  47. fn bench_recursive_snark(c: &mut Criterion, num_samples: usize) {
  48. let mut group = c.benchmark_group("RecursiveSNARK".to_string());
  49. group.sample_size(num_samples);
  50. // Produce public parameters
  51. let pp = PublicParams::<G1, G2, C1, C2>::setup(
  52. TrivialTestCircuit {
  53. _p: Default::default(),
  54. },
  55. TrivialTestCircuit {
  56. _p: Default::default(),
  57. },
  58. );
  59. // Bench time to produce a recursive SNARK;
  60. // we execute a certain number of warm-up steps since executing
  61. // the first step is cheaper than other steps owing to the presence of
  62. // a lot of zeros in the satisfying assignment
  63. let num_warmup_steps = 10;
  64. let mut recursive_snark: Option<RecursiveSNARK<G1, G2, C1, C2>> = None;
  65. for i in 0..num_warmup_steps {
  66. let res = RecursiveSNARK::prove_step(
  67. &pp,
  68. recursive_snark,
  69. TrivialTestCircuit {
  70. _p: Default::default(),
  71. },
  72. TrivialTestCircuit {
  73. _p: Default::default(),
  74. },
  75. <G1 as Group>::Scalar::one(),
  76. <G2 as Group>::Scalar::zero(),
  77. );
  78. assert!(res.is_ok());
  79. let recursive_snark_unwrapped = res.unwrap();
  80. // verify the recursive snark at each step of recursion
  81. let res = recursive_snark_unwrapped.verify(
  82. &pp,
  83. i + 1,
  84. <G1 as Group>::Scalar::one(),
  85. <G2 as Group>::Scalar::zero(),
  86. );
  87. assert!(res.is_ok());
  88. // set the running variable for the next iteration
  89. recursive_snark = Some(recursive_snark_unwrapped);
  90. }
  91. group.bench_function("Prove", |b| {
  92. b.iter(|| {
  93. // produce a recursive SNARK for a step of the recursion
  94. assert!(RecursiveSNARK::prove_step(
  95. black_box(&pp),
  96. black_box(recursive_snark.clone()),
  97. black_box(TrivialTestCircuit {
  98. _p: Default::default(),
  99. }),
  100. black_box(TrivialTestCircuit {
  101. _p: Default::default(),
  102. }),
  103. black_box(<G1 as Group>::Scalar::zero()),
  104. black_box(<G2 as Group>::Scalar::zero()),
  105. )
  106. .is_ok());
  107. })
  108. });
  109. let recursive_snark = recursive_snark.unwrap();
  110. // Benchmark the verification time
  111. let name = "Verify";
  112. group.bench_function(name, |b| {
  113. b.iter(|| {
  114. assert!(black_box(&recursive_snark)
  115. .verify(
  116. black_box(&pp),
  117. black_box(num_warmup_steps),
  118. black_box(<G1 as Group>::Scalar::zero()),
  119. black_box(<G2 as Group>::Scalar::zero()),
  120. )
  121. .is_ok());
  122. });
  123. });
  124. group.finish();
  125. }