Skip to content

Commit 055dc6f

Browse files
Add quadratic and cubic sumcheck (#1003)
* first commit, add quadratic and cubic * fix quadratic and cubic sumcheck implementation * refactor code to use wrappers * save work * small refactor * implement suggestion * add number of factors and number of variables to transcript * fix clippy * fix clippy --------- Co-authored-by: Diego K <43053772+diegokingston@users.noreply.github.com>
1 parent 3a04406 commit 055dc6f

File tree

6 files changed

+726
-329
lines changed

6 files changed

+726
-329
lines changed

crates/provers/stark/src/constraints/transition.rs

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ use itertools::Itertools;
77
use lambdaworks_math::field::element::FieldElement;
88
use lambdaworks_math::field::traits::{IsFFTField, IsField, IsSubFieldOf};
99
use lambdaworks_math::polynomial::Polynomial;
10-
use num_integer::Integer;
10+
1111
/// TransitionConstraint represents the behaviour that a transition constraint
1212
/// over the computation that wants to be proven must comply with.
1313
pub trait TransitionConstraint<F, E>: Send + Sync
@@ -117,11 +117,12 @@ where
117117

118118
// If there is an exemptions period defined for this constraint, the evaluations are calculated directly
119119
// by computing P_exemptions(x) / Zerofier(x)
120+
#[expect(clippy::incompatible_msrv)]
120121
if let Some(exemptions_period) = self.exemptions_period() {
121122
// FIXME: Rather than making this assertions here, it would be better to handle these
122123
// errors or make these checks when the AIR is initialized.
123124

124-
debug_assert!(exemptions_period.is_multiple_of(&self.period()));
125+
debug_assert!(exemptions_period.is_multiple_of(self.period()));
125126

126127
debug_assert!(self.periodic_exemptions_offset().is_some());
127128

@@ -218,8 +219,9 @@ where
218219
) -> FieldElement<E> {
219220
let end_exemptions_poly = self.end_exemptions_poly(trace_primitive_root, trace_length);
220221

222+
#[expect(clippy::incompatible_msrv)]
221223
if let Some(exemptions_period) = self.exemptions_period() {
222-
debug_assert!(exemptions_period.is_multiple_of(&self.period()));
224+
debug_assert!(exemptions_period.is_multiple_of(self.period()));
223225

224226
debug_assert!(self.periodic_exemptions_offset().is_some());
225227

crates/provers/sumcheck/README.md

Lines changed: 37 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
# Sumcheck Protocol
22

3-
A naive implementation of the Sumcheck Protocol.
3+
A naive implementation of the Sumcheck Protocol with support for linear, quadratic, and cubic polynomials.
44

55
## Overview
66

@@ -10,6 +10,14 @@ It is an essential building block for many SNARK protocols, given that it reduce
1010

1111
The protocol proceeds in rounds, with one round per variable of the multivariate polynomial. In each round, the prover sends a univariate polynomial, and the verifier responds with a random challenge. This process reduces a claim about a multivariate polynomial to a claim about a single evaluation point.
1212

13+
### Convenience Wrapper Functions
14+
15+
This implementation provides the following convenience **wrapper functions** for common interaction degrees:
16+
- `prove_linear` / `verify_linear` (Sum of P(x))
17+
- `prove_quadratic` / `verify_quadratic` (Sum of P₁(x)P₂(x))
18+
- `prove_cubic` / `verify_cubic` (Sum of P₁(x)P₂(x)P₃(x))
19+
20+
1321

1422
## Example
1523

@@ -23,22 +31,41 @@ use lambdaworks_sumcheck::{prove, verify};
2331

2432
// Define the field
2533
type F = U64PrimeField<17>;
34+
type FE = FieldElement<F>;
2635

2736
// Create a multilinear polynomial
37+
// P(x1, x2) = evals [3, 4, 5, 7]
2838
let evaluations = vec![
29-
FieldElement::<F>::from(3),
30-
FieldElement::<F>::from(4),
31-
FieldElement::<F>::from(5),
32-
FieldElement::<F>::from(7),
39+
FE::from(3),
40+
FE::from(4),
41+
FE::from(5),
42+
FE::from(7),
3343
];
3444
let poly = DenseMultilinearPolynomial::new(evaluations);
45+
let num_vars = poly.num_vars();
46+
47+
// Generate a proof using the linear wrapper
48+
let prove_result = prove_linear(poly.clone());
49+
assert!(prove_result.is_ok());
50+
let (claimed_sum, proof_polys) = prove_result.unwrap();
51+
52+
// Verify the proof using the linear wrapper
53+
let verification_result = verify_linear(num_vars, claimed_sum, proof_polys, poly);
54+
assert!(verification_result.is_ok() && verification_result.unwrap());
55+
println!("Simple verification successful!");
56+
```
57+
To use the quadratic wrapper, you can use the `prove_quadratic` and `verify_quadratic` functions.
3558

36-
// Generate a proof
37-
let (claimed_sum, proof) = prove(poly);
59+
```rust
60+
let prove_result = prove_quadratic(poly1, poly2);
61+
let verification_result = verify_quadratic(num_vars, claimed_sum, proof_polys, poly1, poly2);
62+
```
3863

39-
// Verify the proof
40-
let result = verify(poly.num_vars(), claimed_sum, proof, Some(poly));
41-
assert!(result.is_ok() && result.unwrap());
64+
To use the cubic wrapper, you can use the `prove_cubic` and `verify_cubic` functions.
65+
66+
```rust
67+
let prove_result = prove_cubic(poly1, poly2, poly3);
68+
let verification_result = verify_cubic(num_vars, claimed_sum, proof_polys, poly1, poly2, poly3);
4269
```
4370

4471

0 commit comments

Comments
 (0)