Skip to content

Commit aa27d0f

Browse files
feat: prove through a Multiframe trait (#709)
* feat: Introduce MultiFrame trait Mutability leftovers (see #680) - Updated benchmarking scripts to no longer mutate the `store` variable during evaluation frames retrieval. - Reformed `get_evaluation_frames` method across several files to use immutable references to `store` instead of mutable references. Multiframe definition - Introduced several new traits - `CEKState`, `FrameLike`, `EvaluationStore` and `MultiFrameTrait` to manage complex evaluation and circuit proof operations in the `proof/mod.rs` file. - Detailed implementations of the above traits introduced in `circuit/circuit_frame.rs`, providing methods for handling evaluation frames, synthesizing data from multiple frames and more. * refactor: make nova proofs use the generic trait - uses the generic MultiFrame trait introduced in the prior commit to generically prove using nova, - For references on the latest work defining this trait, see #629 (and its history, incl. #642, #707) and #677. - make the benches use the generic trait, so LEM can bench similarly, - make the examples use the generic trait, so LEM can example similarly, - make Supernova use the generic trait, so LEM can NIVC similarly, * use a type alias to simplify test calls --------- Co-authored-by: Arthur Paulino <arthurleonardo.ap@gmail.com>
1 parent 894047a commit aa27d0f

File tree

30 files changed

+1145
-571
lines changed

30 files changed

+1145
-571
lines changed

benches/end2end.rs

Lines changed: 52 additions & 54 deletions
Original file line numberDiff line numberDiff line change
@@ -5,14 +5,15 @@ use criterion::{
55
};
66

77
use lurk::{
8+
circuit::circuit_frame::MultiFrame,
89
eval::{
910
empty_sym_env,
1011
lang::{Coproc, Lang},
1112
Evaluator,
1213
},
1314
field::LurkField,
14-
proof::nova::NovaProver,
1515
proof::Prover,
16+
proof::{nova::NovaProver, MultiFrameTrait},
1617
ptr::Ptr,
1718
public_parameters,
1819
state::State,
@@ -70,7 +71,7 @@ fn end2end_benchmark(c: &mut Criterion) {
7071
let prover = NovaProver::new(reduction_count, lang_pallas);
7172

7273
// use cached public params
73-
let pp = public_parameters::public_params(
74+
let pp = public_parameters::public_params::<_, _, MultiFrame<'_, _, Coproc<pallas::Scalar>>>(
7475
reduction_count,
7576
true,
7677
lang_pallas_rc.clone(),
@@ -87,7 +88,7 @@ fn end2end_benchmark(c: &mut Criterion) {
8788
b.iter(|| {
8889
let ptr = go_base::<pallas::Scalar>(&mut store, state.clone(), s.0, s.1);
8990
let _result = prover
90-
.evaluate_and_prove(&pp, ptr, env, &mut store, limit, lang_pallas_rc.clone())
91+
.evaluate_and_prove(&pp, ptr, env, &mut store, limit, &lang_pallas_rc)
9192
.unwrap();
9293
})
9394
});
@@ -290,27 +291,26 @@ fn prove_benchmark(c: &mut Criterion) {
290291
group.bench_with_input(benchmark_id, &size, |b, &s| {
291292
let ptr = go_base::<pallas::Scalar>(&mut store, state.clone(), s.0, s.1);
292293
let prover = NovaProver::new(reduction_count, lang_pallas.clone());
293-
let pp = public_parameters::public_params(
294-
reduction_count,
295-
true,
296-
lang_pallas_rc.clone(),
297-
Utf8Path::new(PUBLIC_PARAMS_PATH),
298-
)
299-
.unwrap();
300-
let frames = prover
301-
.get_evaluation_frames(
302-
ptr,
303-
empty_sym_env(&store),
304-
&mut store,
305-
limit,
294+
let pp =
295+
public_parameters::public_params::<_, _, MultiFrame<'_, _, Coproc<pallas::Scalar>>>(
296+
reduction_count,
297+
true,
306298
lang_pallas_rc.clone(),
299+
Utf8Path::new(PUBLIC_PARAMS_PATH),
307300
)
308301
.unwrap();
302+
let frames = MultiFrame::get_evaluation_frames(
303+
|count| prover.needs_frame_padding(count),
304+
ptr,
305+
empty_sym_env(&store),
306+
&store,
307+
limit,
308+
&lang_pallas,
309+
)
310+
.unwrap();
309311

310312
b.iter(|| {
311-
let result = prover
312-
.prove(&pp, &frames, &store, lang_pallas_rc.clone())
313-
.unwrap();
313+
let result = prover.prove(&pp, &frames, &store, &lang_pallas_rc).unwrap();
314314
black_box(result);
315315
})
316316
});
@@ -340,30 +340,30 @@ fn prove_compressed_benchmark(c: &mut Criterion) {
340340

341341
let state = State::init_lurk_state().rccell();
342342

343+
let pp = public_parameters::public_params::<_, _, MultiFrame<'_, _, _>>(
344+
reduction_count,
345+
true,
346+
lang_pallas_rc.clone(),
347+
Utf8Path::new(PUBLIC_PARAMS_PATH),
348+
)
349+
.unwrap();
350+
343351
group.bench_with_input(benchmark_id, &size, |b, &s| {
344352
let ptr = go_base::<pallas::Scalar>(&mut store, state.clone(), s.0, s.1);
345353
let prover = NovaProver::new(reduction_count, lang_pallas.clone());
346-
let pp = public_parameters::public_params(
347-
reduction_count,
348-
true,
349-
lang_pallas_rc.clone(),
350-
Utf8Path::new(PUBLIC_PARAMS_PATH),
354+
355+
let frames = MultiFrame::get_evaluation_frames(
356+
|count| prover.needs_frame_padding(count),
357+
ptr,
358+
empty_sym_env(&store),
359+
&store,
360+
limit,
361+
&lang_pallas,
351362
)
352363
.unwrap();
353-
let frames = prover
354-
.get_evaluation_frames(
355-
ptr,
356-
empty_sym_env(&store),
357-
&mut store,
358-
limit,
359-
lang_pallas_rc.clone(),
360-
)
361-
.unwrap();
362364

363365
b.iter(|| {
364-
let (proof, _, _, _) = prover
365-
.prove(&pp, &frames, &store, lang_pallas_rc.clone())
366-
.unwrap();
366+
let (proof, _, _, _) = prover.prove(&pp, &frames, &store, &lang_pallas_rc).unwrap();
367367

368368
let compressed_result = proof.compress(&pp).unwrap();
369369
black_box(compressed_result);
@@ -395,25 +395,24 @@ fn verify_benchmark(c: &mut Criterion) {
395395
group.bench_with_input(benchmark_id, &size, |b, &s| {
396396
let ptr = go_base(&mut store, state.clone(), s.0, s.1);
397397
let prover = NovaProver::new(reduction_count, lang_pallas.clone());
398-
let pp = public_parameters::public_params(
398+
let pp = public_parameters::public_params::<_, _, MultiFrame<'_, _, _>>(
399399
reduction_count,
400400
true,
401401
lang_pallas_rc.clone(),
402402
Utf8Path::new(PUBLIC_PARAMS_PATH),
403403
)
404404
.unwrap();
405-
let frames = prover
406-
.get_evaluation_frames(
407-
ptr,
408-
empty_sym_env(&store),
409-
&mut store,
410-
limit,
411-
lang_pallas_rc.clone(),
412-
)
413-
.unwrap();
414-
let (proof, z0, zi, num_steps) = prover
415-
.prove(&pp, &frames, &store, lang_pallas_rc.clone())
416-
.unwrap();
405+
let frames = MultiFrame::get_evaluation_frames(
406+
|count| prover.needs_frame_padding(count),
407+
ptr,
408+
empty_sym_env(&store),
409+
&store,
410+
limit,
411+
&lang_pallas,
412+
)
413+
.unwrap();
414+
let (proof, z0, zi, num_steps) =
415+
prover.prove(&pp, &frames, &store, &lang_pallas_rc).unwrap();
417416

418417
b.iter_batched(
419418
|| z0.clone(),
@@ -453,7 +452,7 @@ fn verify_compressed_benchmark(c: &mut Criterion) {
453452
group.bench_with_input(benchmark_id, &size, |b, &s| {
454453
let ptr = go_base(&mut store, state.clone(), s.0, s.1);
455454
let prover = NovaProver::new(reduction_count, lang_pallas.clone());
456-
let pp = public_parameters::public_params(
455+
let pp = public_parameters::public_params::<_, _, MultiFrame<'_, _, _>>(
457456
reduction_count,
458457
true,
459458
lang_pallas_rc.clone(),
@@ -464,14 +463,13 @@ fn verify_compressed_benchmark(c: &mut Criterion) {
464463
.get_evaluation_frames(
465464
ptr,
466465
empty_sym_env(&store),
467-
&mut store,
466+
&store,
468467
limit,
469468
lang_pallas_rc.clone(),
470469
)
471470
.unwrap();
472-
let (proof, z0, zi, num_steps) = prover
473-
.prove(&pp, &frames, &store, lang_pallas_rc.clone())
474-
.unwrap();
471+
let (proof, z0, zi, num_steps) =
472+
prover.prove(&pp, &frames, &store, &lang_pallas_rc).unwrap();
475473

476474
let compressed_proof = proof.compress(&pp).unwrap();
477475

benches/fibonacci.rs

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ use criterion::{
99
use pasta_curves::pallas;
1010

1111
use lurk::{
12+
circuit::circuit_frame::MultiFrame,
1213
eval::{
1314
empty_sym_env,
1415
lang::{Coproc, Lang},
@@ -75,7 +76,7 @@ fn fibo_prove<M: measurement::Measurement>(
7576
let lang_rc = Arc::new(lang_pallas.clone());
7677

7778
// use cached public params
78-
let pp = public_params(
79+
let pp = public_params::<_, _, MultiFrame<'_, _, _>>(
7980
prove_params.reduction_count,
8081
true,
8182
lang_rc.clone(),
@@ -98,13 +99,13 @@ fn fibo_prove<M: measurement::Measurement>(
9899
let prover = NovaProver::new(prove_params.reduction_count, lang_pallas.clone());
99100

100101
let frames = &prover
101-
.get_evaluation_frames(ptr, env, &mut store, limit, lang_rc.clone())
102+
.get_evaluation_frames(ptr, env, &store, limit, lang_rc.clone())
102103
.unwrap();
103104

104105
b.iter_batched(
105106
|| (frames, lang_rc.clone()),
106107
|(frames, lang_rc)| {
107-
let result = prover.prove(&pp, frames, &store, lang_rc);
108+
let result = prover.prove(&pp, frames, &store, &lang_rc);
108109
let _ = black_box(result);
109110
},
110111
BatchSize::LargeInput,

benches/public_params.rs

Lines changed: 15 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
use blstrs::Scalar as Fr;
22
use criterion::{black_box, criterion_group, criterion_main, Criterion, SamplingMode};
33
use lurk::{
4+
circuit::circuit_frame::MultiFrame,
45
eval::lang::{Coproc, Lang},
56
proof::groth16::Groth16Prover,
67
proof::nova,
@@ -26,15 +27,26 @@ fn public_params_benchmark(c: &mut Criterion) {
2627

2728
group.bench_function("public_params_nova", |b| {
2829
b.iter(|| {
29-
let result = nova::public_params(reduction_count, lang_pallas_rc.clone());
30+
let result = nova::public_params::<_, _, MultiFrame<'_, _, _>>(
31+
reduction_count,
32+
lang_pallas_rc.clone(),
33+
);
3034
black_box(result)
3135
})
3236
});
3337

3438
group.bench_function("public_params_groth", |b| {
3539
b.iter(|| {
36-
let result =
37-
Groth16Prover::create_groth_params(DEFAULT_REDUCTION_COUNT, lang_bls_rc.clone());
40+
let result = Groth16Prover::<
41+
_,
42+
Coproc<Fr>,
43+
Fr,
44+
MultiFrame<'_, Fr, Coproc<Fr>>,
45+
>::create_groth_params(
46+
DEFAULT_REDUCTION_COUNT,
47+
lang_bls_rc.clone(),
48+
)
49+
.unwrap();
3850
black_box(result)
3951
})
4052
});

benches/sha256_ivc.rs

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
//! Note: The example [example/sha256_ivc.rs] is this same benchmark but as an example
77
//! that's easier to play with and run.
88
9+
use lurk::circuit::circuit_frame::MultiFrame;
910
use lurk::circuit::gadgets::data::GlobalAllocations;
1011
use lurk::state::user_sym;
1112
use lurk::{circuit::gadgets::pointer::AllocatedContPtr, tag::Tag};
@@ -226,7 +227,7 @@ fn sha256_ivc_prove<M: measurement::Measurement>(
226227
let lang_rc = Arc::new(lang.clone());
227228

228229
// use cached public params
229-
let pp = public_params(
230+
let pp = public_params::<_, _, MultiFrame<'_, _, _>>(
230231
reduction_count,
231232
true,
232233
lang_rc.clone(),
@@ -256,7 +257,7 @@ fn sha256_ivc_prove<M: measurement::Measurement>(
256257
b.iter_batched(
257258
|| (frames, lang_rc.clone()),
258259
|(frames, lang_rc)| {
259-
let result = prover.prove(&pp, frames, store, lang_rc);
260+
let result = prover.prove(&pp, frames, store, &lang_rc);
260261
let _ = black_box(result);
261262
},
262263
BatchSize::LargeInput,
@@ -309,7 +310,7 @@ fn sha256_ivc_prove_compressed<M: measurement::Measurement>(
309310
let lang_rc = Arc::new(lang.clone());
310311

311312
// use cached public params
312-
let pp = public_params(
313+
let pp = public_params::<_, _, MultiFrame<'_, _, _>>(
313314
reduction_count,
314315
true,
315316
lang_rc.clone(),
@@ -339,7 +340,7 @@ fn sha256_ivc_prove_compressed<M: measurement::Measurement>(
339340
b.iter_batched(
340341
|| (frames, lang_rc.clone()),
341342
|(frames, lang_rc)| {
342-
let (proof, _, _, _) = prover.prove(&pp, frames, store, lang_rc).unwrap();
343+
let (proof, _, _, _) = prover.prove(&pp, frames, store, &lang_rc).unwrap();
343344
let compressed_result = proof.compress(&pp).unwrap();
344345

345346
let _ = black_box(compressed_result);

benches/synthesis.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,10 +58,13 @@ fn synthesize<M: measurement::Measurement>(
5858
let env = empty_sym_env(&store);
5959
let fib_n = (reduction_count / 3) as u64; // Heuristic, since one fib is 35 iterations.
6060
let ptr = fib::<pasta_curves::Fq>(&mut store, state.clone(), black_box(fib_n));
61-
let prover = NovaProver::new(*reduction_count, lang_pallas.clone());
61+
let prover = NovaProver::<_, _, MultiFrame<'_, _, _>>::new(
62+
*reduction_count,
63+
lang_pallas.clone(),
64+
);
6265

6366
let frames = prover
64-
.get_evaluation_frames(ptr, env, &mut store, limit, lang_rc.clone())
67+
.get_evaluation_frames(ptr, env, &store, limit, lang_rc.clone())
6568
.unwrap();
6669
let folding_config =
6770
Arc::new(FoldingConfig::new_ivc(lang_rc.clone(), *reduction_count));

clutch/src/lib.rs

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ use fcomm::{
88
CommittedExpression, CommittedExpressionMap, LurkCont, LurkPtr, NovaProofCache, Opening, Proof,
99
PtrEvaluation,
1010
};
11+
use lurk::circuit::circuit_frame::MultiFrame;
1112
use lurk::lurk_sym_ptr;
1213
use lurk::public_parameters::public_params;
1314

@@ -147,7 +148,14 @@ impl ReplTrait<F, Coproc<F>> for ClutchState<F, Coproc<F>> {
147148

148149
let lang_rc = Arc::new(lang.clone());
149150
// Load params from disk cache, or generate them in the background.
150-
thread::spawn(move || public_params(reduction_count, true, lang_rc, &public_param_dir()));
151+
thread::spawn(move || {
152+
public_params::<_, _, MultiFrame<'_, _, Coproc<_>>>(
153+
reduction_count,
154+
true,
155+
lang_rc,
156+
&public_param_dir(),
157+
)
158+
});
151159

152160
Self {
153161
repl_state: ReplState::new(s, limit, command, lang),
@@ -531,7 +539,10 @@ impl ClutchState<F, Coproc<F>> {
531539
fn prove(&mut self, store: &mut Store<F>, rest: Ptr<F>) -> Result<Option<Ptr<F>>> {
532540
let (proof_in_expr, _rest1) = store.car_cdr(&rest)?;
533541

534-
let prover = NovaProver::<F, Coproc<F>>::new(self.reduction_count, (*self.lang()).clone());
542+
let prover = NovaProver::<'_, F, Coproc<F>, MultiFrame<'_, F, Coproc<F>>>::new(
543+
self.reduction_count,
544+
(*self.lang()).clone(),
545+
);
535546
let pp = public_params(self.reduction_count, true, self.lang(), &public_param_dir())?;
536547

537548
let proof = if rest.is_nil() {

examples/circom.rs

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,7 @@ use std::marker::PhantomData;
3232
use std::sync::Arc;
3333
use std::time::Instant;
3434

35+
use lurk::circuit::circuit_frame::MultiFrame;
3536
use lurk::circuit::gadgets::circom::CircomGadget;
3637
use lurk::circuit::gadgets::pointer::AllocatedPtr;
3738

@@ -114,13 +115,16 @@ fn main() {
114115
let expr = format!("({coproc_expr})");
115116
let ptr = store.read(&expr).unwrap();
116117

117-
let nova_prover = NovaProver::<Fr, Sha256Coproc<Fr>>::new(REDUCTION_COUNT, lang.clone());
118+
let nova_prover = NovaProver::<Fr, Sha256Coproc<Fr>, MultiFrame<'_, _, _>>::new(
119+
REDUCTION_COUNT,
120+
lang.clone(),
121+
);
118122
let lang_rc = Arc::new(lang);
119123

120124
println!("Setting up public parameters...");
121125

122126
let pp_start = Instant::now();
123-
let pp = public_params::<_, Sha256Coproc<Fr>>(
127+
let pp = public_params::<_, Sha256Coproc<Fr>, MultiFrame<'_, _, _>>(
124128
REDUCTION_COUNT,
125129
true,
126130
lang_rc.clone(),
@@ -135,7 +139,7 @@ fn main() {
135139

136140
let proof_start = Instant::now();
137141
let (proof, z0, zi, num_steps) = nova_prover
138-
.evaluate_and_prove(&pp, ptr, empty_sym_env(store), store, 10000, lang_rc)
142+
.evaluate_and_prove(&pp, ptr, empty_sym_env(store), store, 10000, &lang_rc)
139143
.unwrap();
140144
let proof_end = proof_start.elapsed();
141145

0 commit comments

Comments
 (0)