Skip to content

Commit cd983b6

Browse files
Idan/improve sumcheck docs (#778)
Co-authored-by: Leon Hibnik <[email protected]>
1 parent 7c8d85b commit cd983b6

File tree

10 files changed

+558
-113
lines changed

10 files changed

+558
-113
lines changed
+49-52
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,47 @@
11
# Sumcheck API Documentation
22

33
## Overview
4-
Sumchek protocol is a protocol where a Prover proves to a Verifier that the sum of a multilinear polynomial, over the boolean hypercube, is a specific sum.
4+
The Sumcheck protocol allows a Prover to prove to a Verifier that the sum of a multilinear polynomial, over the Boolean hypercube, equals a specific scalar value.
55

6-
For a polynomial $P$, with $n$ dimension $n$ the Prover is trying to prove that:
6+
For a polynomial $P$ with $n$ variables, the Prover aims to prove that:
77
$$
88
\sum_{X_1 \in \{0, 1\}}\sum_{X_2 \in \{0, 1\}}\cdot\cdot\cdot\sum_{X_n \in \{0, 1\}} P(X_1, X_2,..., X_n) = C,
99
$$
10-
for some scalar $C$.
10+
where $C$ is some scalar.
1111

12-
The proof is build in an interactive way, where the Prover and Verifier do a series of $n$ rounds. Each round is consists of a challenge (created by the Verifier), computation (made by the Prover) and verifying (done by the Verifier). Using a Fiat-Shamir (FS) scheme, the proof become non-interactive. This allow the Prover to generate the entire proof and send it to Verifier which then verify the whole proof.
12+
The proof is constructed interactively, involving a series of $n$ rounds. Each round consists of a challenge (from the Verifier), a computation (from the Prover), and a verification step (by the Verifier). Using a Fiat-Shamir (FS) scheme, the proof becomes non-interactive, enabling the Prover to generate the entire proof and send it to the Verifier for validation.
1313

1414
### Sumcheck with Combine Function
15-
The Sumcheck protocol can be generalized to an arbitrary function of several multilinear polynomials. In this case, assuming there are $m$ polynomials of $n$ variables, and let $f$ be some arbitrary function that take $m$ polynomials and return a polynomial of higher (or equal) degree. Now the Prover tries to prove that:
15+
The Sumcheck protocol can be generalized to handle multiple multilinear polynomials. In this case, assuming there are $m$ polynomials of $n$ variables, and $f$ is an arbitrary function that takes these $m$ polynomials and returns a polynomial of equal or higher degree, the Prover tries to prove that:
1616
$$
1717
\sum_{X_1 \in \{0, 1\}}\sum_{X_2 \in \{0, 1\}}\cdot\cdot\cdot\sum_{X_n \in \{0, 1\}} f\left(P_1(X_1, ..., X_n), P_2(X_1, ..., X_n), ..., P_m(X_1, ..., X_n)\right) = C,
1818
$$
19-
for some scalar $C$.
19+
where $C$ is some scalar.
2020

21-
## ICICLE's Sumecheck
22-
ICICLE implements a non-interactive Sumcheck protocol that supports a combine function. Sumcheck is supported by both CPU and CUDA backends of ICICLE. The polynomials are passed to the protocol as MLEs (evaluation representation).
21+
## ICICLE's Sumecheck Implementation
22+
ICICLE implements a non-interactive Sumcheck protocol that supports a combine function. It is available on both the CPU and CUDA backends of ICICLE. The polynomials are passed to the protocol in MLE (evaluation representation) form.
2323

2424
### Implementation Limitations
2525

26-
There are some limitations / assumptions to the Sumcheck implementation.
27-
28-
- The maximum size of the polynomials (number of evaluations = $2^n$) depends on the number of polynomials and memory size of the device (e.g. CPU/GPU) used. For 4 polynomials one should expects that a GPU equipped with 24GB of memory can run Sumcheck with polynomials of size up to $2^{29}$.
29-
- The polynomial size must be of size which is a power of 2.
26+
There are some limitations and assumptions in the Sumcheck implementation:
3027

28+
- The maximum size of the polynomials (i.e., the number of evaluations $2^n$) depends on the number of polynomials and the memory size of the device (e.g., CPU/GPU) being used. For example, with 4 polynomials, a GPU with 24GB of memory should be able to handle Sumcheck for polynomials of size up to $2^29$.
29+
- The polynomial size must a power of 2.
30+
- The current implementation does not support generating the challenge ($\alpha$) in an extension field. This functionality is necessary for ensuring security when working with small fields.
3131

3232
## C++ API
33-
A sumcheck is created by the following function:
33+
A Sumcheck object can be created using the following function:
3434
```cpp
3535
Sumcheck<scalar_t> create_sumcheck()
3636
```
3737

38-
There are two configuration structs related to the Sumcheck protocol.
38+
There are two key configuration structs related to the Sumcheck protocol.
3939

40-
The `SumcheckConfig` struct is a configuration object used to specify parameters for Sumcheck. It contains the following fields:
41-
- **`stream: icicleStreamHandle`**: Specifies the CUDA stream for asynchronous execution. If `nullptr`, the default stream is used.
42-
- **`use_extension_field: bool`**: If true extension field is used for the Fiat-Shamir results. ***Currently not supported (should always be false)***
43-
- **`batch: int`**: Number of input chunks to hash in batch.
44-
- **`are_inputs_on_device: bool`**: If true expect the input polynomials to reside on the device (e.g. GPU), if false expect them to reside on the host (e.g. CPU).
40+
### SumcheckConfig
41+
The `SumcheckConfig` struct is used to specify parameters for the Sumcheck protocol. It contains the following fields:
42+
- **`stream: icicleStreamHandle`**: The CUDA stream for asynchronous execution. If `nullptr`, the default stream is used.
43+
- **`use_extension_field: bool`**: If true, an extension field is used for Fiat-Shamir results. Currently unsupported (should always be false).
44+
- **`are_inputs_on_device: bool`**: If true, the input polynomials are expected to reside on the device (e.g., GPU); otherwise, they are expected to reside on the host (e.g., CPU).
4545
- **`is_async: bool`**: If true runs the hash asynchronously.
4646
- **`ext: ConfigExtension*`**: Backend-specific extensions.
4747

@@ -57,23 +57,24 @@ The default values are:
5757
};
5858
```
5959
60-
The `SumcheckTranscriptConfig<F>` class is a configuration object used to specify parameters to the Fiat-Shamir scheme used by the Sumcheck. It contained the following fields:
61-
- **`hasher: Hash`**: Hash function used for randomness generation by Fiat-Shamir.
62-
- **`domain_label: char*`**: Label for the domain separator in the transcript.
63-
- **`poly_label: char*`**: Label for round polynomials in the transcript.
64-
- **`challenge_label: char*`**: Label for round challenges in the transcript.
65-
- **`seed: F`**: Seed for initializing the RNG.
66-
- **`little_endian: bool`**: Encoding endianness
60+
### SumcheckTranscriptConfig
61+
The `SumcheckTranscriptConfig<F>` class is used to specify parameters for the Fiat-Shamir scheme used by the Sumcheck protocol. It contains the following fields:
62+
- **`hasher: Hash`**: The hash function used to generate randomness for Fiat-Shamir.
63+
- **`domain_label: char*`**: The label for the domain separator in the transcript.
64+
- **`poly_label: char*`**: The label for round polynomials in the transcript.
65+
- **`challenge_label: char*`**: The label for round challenges in the transcript.
66+
- **`seed: F`**: The seed for initializing the RNG.
67+
- **`little_endian: bool`**: The encoding endianness.
6768
68-
There are three constructors for `SumcheckTranscriptConfig<F>`, each one with its own arguments and default value.
69+
There are three constructors for `SumcheckTranscriptConfig<F>`, each with its own default values:
6970
70-
The default constructor:
71+
* **Default constructor**:
7172
```cpp
7273
SumcheckTranscriptConfig()
7374
: m_little_endian(true), m_seed_rng(F::from(0)), m_hasher(std::move(create_keccak_256_hash()))
7475
```
7576

76-
A constructor with byte vector for labels:
77+
* **Constructor with byte vector for labels**:
7778
```cpp
7879
SumcheckTranscriptConfig(
7980
Hash hasher,
@@ -85,7 +86,8 @@ A constructor with byte vector for labels:
8586
: m_hasher(std::move(hasher)), m_domain_separator_label(domain_label), m_round_poly_label(poly_label),
8687
m_round_challenge_label(challenge_label), m_little_endian(little_endian), m_seed_rng(seed)
8788
```
88-
A constructor with `const char*` arguments for labels
89+
90+
* **Constructor with `const char*` arguments for labels**:
8991
```cpp
9092
SumcheckTranscriptConfig(
9193
Hash hasher,
@@ -100,16 +102,16 @@ A constructor with `const char*` arguments for labels
100102
```
101103

102104
### Generating Sumcheck Proofs
103-
To generate a Proof, first and empty proof needed to be created. Sumceck proof is represented by the class `SumcheckProof<S>`:
105+
To generate a proof, first, an empty proof needs to be created. The Sumcheck proof is represented by the `SumcheckProof<S>` class:
104106

105107
```cpp
106108
template <typename S>
107109
class SumcheckProof
108110
```
109111
110-
It has only the default constructor ` SumcheckProof()` which takes no arguments.
112+
The class has a default constructor `SumcheckProof()` that takes no arguments.
111113
112-
Then, the proof can be generate by the `get_proof` method of the `Sumcheck<F>` object:
114+
The proof can be generated using the get_proof method from the `Sumcheck<F>` object:
113115
```cpp
114116
eIcicleError get_proof(
115117
const std::vector<F*>& mle_polynomials,
@@ -122,18 +124,16 @@ eIcicleError get_proof(
122124
```
123125

124126
The arguments for this method are:
125-
- **`mle_polynomials: std::vector<F*>&`**: A vector of pointer. Each pointer points to the evaluations of one of the input polynomials.
126-
- **`mle_polynomial_size: uint64_t`**: The length of the polynomials (number of evaluations). Should be a power of 2
127-
- **`claimed_sum: F&`**: The sum the claimed by the Prover to be the sum of the combine function over the evaluations of the polynomials.
128-
- **`combine_function: ReturningValueProgram<F>&`**: The combine function. Uses ICICLE's [program](program.md) API.
129-
- **`transcript_config: SumcheckTranscriptConfig<F>&&`**: The `SumcheckTranscriptConfig` object for the Fiat-Shamir scheme.
130-
- **`sumcheck_config: SumcheckConfig&`**: The `SumcheckConfig` object for the Sumcheck configuration.
131-
- **`sumcheck_proof: SumcheckProof<F>&`**: A `SumcheckProof` object which is the output of the `get_proof` method.
127+
- **`mle_polynomials: std::vector<F*>&`**: A vector of pointers, each pointing to the evaluations of one of the input polynomials.
128+
- **`mle_polynomial_size: uint64_t`**: The length of the polynomials (number of evaluations). This should be a power of 2.
129+
- **`claimed_sum: F&`**: The sum the Prover claims to be the sum of the combine function over the evaluations of the polynomials.
130+
- **`combine_function: ReturningValueProgram<F>&`**: The combine function, using ICICLE's [program](program.md) API.
131+
- **`transcript_config: SumcheckTranscriptConfig<F>&&`**: The configuration for the Fiat-Shamir scheme.
132+
- **`sumcheck_config: SumcheckConfig&`**: The configuration for the Sumcheck protocol.
133+
- **`sumcheck_proof: SumcheckProof<F>&`**: The output `SumcheckProof` object containing the generated proof.
132134

133135
#### Example: Generating a Proof
134136

135-
Generating a Sumcheck proof:
136-
137137
```cpp
138138
auto prover_sumcheck = create_sumcheck<scalar_t>();
139139
SumcheckTranscriptConfig<scalar_t> transcript_config; // default configuration
@@ -148,7 +148,7 @@ ICICLE_CHECK(prover_sumcheck.get_proof(
148148
149149
### Verifying Sumcheck Proofs
150150
151-
To verify the proof, the Verifier should use the method `verify` of the `Sumcheck<F>` object:
151+
To verify the proof, the Verifier should use the verify method of the `Sumcheck<F>` object:
152152
153153
```cpp
154154
eIcicleError verify(
@@ -159,22 +159,19 @@ eIcicleError verify(
159159
```
160160

161161
The arguments for this method are:
162-
- **`sumcheck_proof: SumcheckProof<F>&`**: The proof the verifier wants to verify.
163-
- **`claimed_sum: F&`**: The sum, claimed by the Prover, the Verifier wants to check.
164-
- **`transcript_config: SumcheckTranscriptConfig<F>&&`**: The `SumcheckTranscriptConfig` object for the Fiat-Shamir scheme.
165-
- **`valid: bool`**: The output of the method. True if the proof was verified correctly, false otherwise.
162+
- **`sumcheck_proof: SumcheckProof<F>&`**: The proof that the Verifier wants to verify.
163+
- **`claimed_sum: F&`**: The sum that the Verifier wants to check, claimed by the Prover.
164+
- **`transcript_config: SumcheckTranscriptConfig<F>&&`**: The configuration for the Fiat-Shamir scheme.
165+
- **`valid: bool`**: The output of the method. `true` if the proof is valid, `false` otherwise.
166166

167-
> **_NOTE:_** The `SumcheckTranscriptConfig` used for generating the proof should be **identical** to the one used to verify it.
167+
> **_NOTE:_** The `SumcheckTranscriptConfig` used for generating the proof must be identical to the one used for verification.
168168
169169
#### Example: Verifying a Proof
170-
171-
Verifying a Shumcheck proof:
172-
173170
```cpp
174171
auto verifier_sumcheck = create_sumcheck<scalar_t>();
175172
bool verification_pass = false;
176173
ICICLE_CHECK(
177174
verifier_sumcheck.verify(sumcheck_proof, claimed_sum, std::move(transcript_config), verification_pass));
178175
```
179176
180-
After `verifier_sumcheck.verify` the variable `verification_pass` is `true` if the proof is valid and `false` otherwise.
177+
After calling `verifier_sumcheck.verify`, the variable `verification_pass` will be `true` if the proof is valid, and `false` if not.
+133
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
# Sumcheck
2+
3+
## Sumcheck API Overview
4+
5+
### **Structs**
6+
7+
#### `SumcheckTranscriptConfig`
8+
Configuration structure for the SumCheck protocol’s transcript.
9+
10+
##### **Fields:**
11+
- `hash: &Hasher` - Reference to the hashing function used.
12+
- `domain_separator_label: Vec<u8>` - Domain separator label for transcript uniqueness.
13+
- `round_poly_label: Vec<u8>` - Label for the polynomial at each round.
14+
- `round_challenge_label: Vec<u8>` - Label for the challenge at each round.
15+
- `little_endian: bool` - Whether to use little-endian encoding.
16+
- `seed_rng: F` - Random number generator seed.
17+
18+
##### **Methods:**
19+
- **`new(hash, domain_separator_label, round_poly_label, round_challenge_label, little_endian, seed_rng) -> Self`**:
20+
Constructs a new `SumcheckTranscriptConfig` with explicit parameters.
21+
22+
- **`from_string_labels(hash, domain_separator_label, round_poly_label, round_challenge_label, little_endian, seed_rng) -> Self`**:
23+
Convenience constructor using string labels.
24+
25+
#### `SumcheckConfig`
26+
General configuration for the SumCheck execution.
27+
28+
##### **Fields:**
29+
- `stream: IcicleStreamHandle` - Stream for asynchronous execution (default: `nullptr`).
30+
- `use_extension_field: bool` - Whether to use an extension field for Fiat-Shamir transformation. Sumcheck currently does not support extension fields, always set to `false` otherwise return an error.
31+
- `batch: u64` - Number of input chunks to hash in batch (default: 1).
32+
- `are_inputs_on_device: bool` - Whether inputs reside on the device (e.g., GPU).
33+
- `is_async: bool` - Whether hashing is run asynchronously.
34+
- `ext: ConfigExtension` - Pointer to backend-specific configuration extensions.
35+
36+
##### **Methods:**
37+
- **`default() -> Self`**:
38+
Returns a default `SumcheckConfig` instance.
39+
40+
### **Traits**
41+
42+
#### `Sumcheck`
43+
Defines the main API for SumCheck operations.
44+
45+
##### **Associated Types:**
46+
- `Field: FieldImpl + Arithmetic` - The field implementation used.
47+
- `FieldConfig: FieldConfig + GenerateRandom<Self::Field> + FieldArithmetic<Self::Field>` - Field configuration.
48+
- `Proof: SumcheckProofOps<Self::Field>` - Type representing the proof.
49+
50+
##### **Methods:**
51+
- **`new() -> Result<Self, eIcicleError>`**:
52+
Initializes a new instance.
53+
54+
- **`prove(mle_polys, mle_poly_size, claimed_sum, combine_function, transcript_config, sumcheck_config) -> Self::Proof`**:
55+
Generates a proof for the polynomial sum over the Boolean hypercube.
56+
57+
- **`verify(proof, claimed_sum, transcript_config) -> Result<bool, eIcicleError>`**:
58+
Verifies the provided proof.
59+
60+
61+
#### `SumcheckProofOps`
62+
Operations for handling SumCheck proofs.
63+
64+
##### **Methods:**
65+
- **`get_round_polys(&self) -> Result<Vec<Vec<F>>, eIcicleError>`**:
66+
Retrieves the polynomials for each round.
67+
68+
- **`print(&self) -> eIcicleError`**::
69+
Prints the proof.
70+
71+
72+
## **Usage Example**
73+
74+
Below is an example demonstrating how to use the `sumcheck` module, adapted from the `check_sumcheck_simple` test.
75+
76+
```rust
77+
use icicle_core::sumcheck::{Sumcheck, SumcheckConfig, SumcheckTranscriptConfig};
78+
use icicle_core::field::FieldElement;
79+
use icicle_core::polynomial::Polynomial;
80+
use icicle_hash::keccak::Keccak256;
81+
82+
fn main() {
83+
// Initialize hashing function
84+
let hash = Keccak256::new(0).unwrap();
85+
86+
// Define a polynomial, e.g., f(x, y) = x + y
87+
let coefficients = vec![
88+
FieldElement::from(0), // Constant term
89+
FieldElement::from(1), // Coefficient for x
90+
FieldElement::from(1), // Coefficient for y
91+
];
92+
let poly = Polynomial::new(coefficients);
93+
94+
// Generate mle polynomial
95+
let mut mle_poly = Vec::with_capacity(2);
96+
for _ in 0..4 {
97+
mle_poly.push(poly);
98+
}
99+
100+
// Calculate the expected sum over the Boolean hypercube {0,1}^2
101+
let expected_sum = FieldElement::from(4);
102+
103+
// Configure transcript and execution settings
104+
let transcript_config = SumcheckTranscriptConfig::from_string_labels(
105+
&hash,
106+
"domain_separator",
107+
"round_poly",
108+
"round_challenge",
109+
false, // big endian
110+
FieldElement::from(0),
111+
);
112+
let sumcheck_config = SumcheckConfig::default();
113+
114+
// define sumcheck lambda
115+
let combine_func = P::new_predefined(PreDefinedProgram::EQtimesABminusC).unwrap();
116+
117+
// Initialize prover
118+
let prover = Sumcheck::new().expect("Failed to create Sumcheck instance");
119+
120+
// Generate proof
121+
let proof = prover.prove(
122+
mle_poly.as_slice(),
123+
2, // Number of variables in the polynomial
124+
expected_sum,
125+
combine_func, // Use pre-defined combine function eq * (a * b - c)
126+
&transcript_config,
127+
&sumcheck_config,
128+
);
129+
130+
// Verify the proof
131+
let result = prover.verify(&proof, expected_sum, &transcript_config);
132+
assert!(result.is_ok() && result.unwrap(), "SumCheck proof verification failed!");
133+
}

docs/sidebars.ts

+5
Original file line numberDiff line numberDiff line change
@@ -178,6 +178,11 @@ const rustBindingsApi = [
178178
label: "Merkle-Tree",
179179
id: "icicle/rust-bindings/merkle",
180180
},
181+
{
182+
"type": "doc",
183+
"label": "Sumcheck",
184+
"id": "icicle/rust-bindings/sumcheck"
185+
}
181186
// {
182187
// type: "doc",
183188
// label: "Multi GPU Support (TODO)",

0 commit comments

Comments
 (0)