-
Notifications
You must be signed in to change notification settings - Fork 124
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
FRI Implementation: frontend + CPU Backend + GPU Backend #795
Open
ShanieWinitz
wants to merge
135
commits into
main
Choose a base branch
from
swinitz/fri_cpu
base: main
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
Open
Changes from all commits
Commits
Show all changes
135 commits
Select commit
Hold shift + click to select a range
b848b0e
add sumcheck frontend
mickeyasa 92f3579
format
mickeyasa d6a9c59
strange compilation err
mickeyasa e6672ff
added test for kickoff
mickeyasa bb3b1d5
small fixes to sumcheck frontend compilation
yshekel 46b4d72
fix rust warppers
yshekel 563694d
enable sumcheck for all fields and curves
yshekel ee5b5de
removed Sumcheck test from field api
mickeyasa aa68bb5
dummy backend added
mickeyasa ffae6b4
compilation fix
yshekel f3331cc
test fix
mickeyasa 6cdcee8
format
mickeyasa 9e9ca5a
changinf sumcheck without hash compilatio to warning
mickeyasa 766dbe9
removed sumcheck file duplication
mickeyasa 588a84c
default hash on for cargo
mickeyasa 1a83ec2
cmake fix
mickeyasa e7ed244
removed commented code
mickeyasa 7248477
format
mickeyasa 4a22355
review
mickeyasa a9b6256
added comment to the MLE polynomial
mickeyasa b989711
review fixes
mickeyasa 6a71b95
format
mickeyasa 44663c1
mle polynomials is a vector of pointers
mickeyasa 85de44d
format
mickeyasa 01b7137
cpu backend inplementation start
mickeyasa d61ca9e
nackend implementation
mickeyasa d8abe7a
backend implementation
mickeyasa 6550860
Merge remote-tracking branch 'origin/main' into add-sumcheck-frontend
mickeyasa 30fc2bb
compilation start
mickeyasa 1628b52
compile, fail on verification test
mickeyasa 3b1165e
verification failed on round 1
mickeyasa 698fb7e
test pass
mickeyasa b2b5ff1
format
mickeyasa 3928fd9
spell check
mickeyasa 8cc6078
test fix
mickeyasa a00a1d1
format
mickeyasa 17fb2d1
adjusting sumcheck test to all fields
mickeyasa d7673f6
format
mickeyasa 3cb70fa
reduce alpha feet small and large fields
mickeyasa 07c1e85
format
mickeyasa 9e60bb9
documentation
mickeyasa 53dd569
format
mickeyasa b7d5ddc
go comp issue
mickeyasa d94ebec
remove prints
mickeyasa 7b06f73
return the std::
mickeyasa 2840f91
name fix
mickeyasa c22d38e
include added for compilation
mickeyasa 48f30df
review fixes
mickeyasa 81d870f
format
mickeyasa 5baee05
removed OR HASH
mickeyasa ae57939
review fixes
mickeyasa 7956576
format
mickeyasa 51d6e8d
spell
mickeyasa 5bd4e56
added use_extension_field for Sumcheckconfig
mickeyasa 6d20856
format
mickeyasa 9ea4eea
enlarging the sumcheck test to 8k
mickeyasa a9da45d
fiat shamir moved to frontend
mickeyasa 17a659e
format
mickeyasa 12469fb
another format
mickeyasa bc5e639
Fix/release script (#721)
LeonHibnik 8447e1a
Fix bug in CPU vec ops regarding nof workers (#731)
yshekel db78555
Support android and vulkan (#735)
yshekel 28cab47
Parallelize-vecop-program-execution (#736)
mickeyasa 31dbb47
Create docs for program & program execution (#722)
idanfr-ingo 64767a6
Feat: Blake3 (#733)
aviadingo be8cd4c
Bump rust crates' version
7f98ad6
Bump docs version
8a02604
Update sidebars.ts (#729)
ShaniBabayoff 752dc93
Update documentation for v3.4 (#738)
ShaniBabayoff 87677d0
Deprecated icicle/api headers and updated examples/docs (#740)
yshekel 31a5efb
avoid warning
mickeyasa 430afc1
fri_cpu initial implementation
ShanieWinitz b478aa6
When creating FRI without a given MerkleTree vector, generate it in t…
ShanieWinitz 9ee1b8d
basic test added, api fix
ShanieWinitz 7e3dbd5
merkle_trees passed by value (only holds std::shared_ptr<MerkleTreeBa…
ShanieWinitz c35f823
merge main to fri_cpu branch
ShanieWinitz a334b0e
fri_transcript moved to frontend
ShanieWinitz 1b1fc4e
verifier added
ShanieWinitz c4122f1
Change create_fri API to accept separate hash functions for Merkle tr…
ShanieWinitz c06a038
FIXMEs and TODOs fixed and removed
ShanieWinitz c2953a1
merge with main
ShanieWinitz 2efd9ae
FRI: ext_field support added. F::from() function added for ext_field
ShanieWinitz 40392af
format
ShanieWinitz 1048dfb
Merge remote-tracking branch 'origin/main' into swinitz/fri_cpu
ShanieWinitz d11f03a
Fixed fri_transcript_config: using the same instance for both prover …
ShanieWinitz e503dd8
format
ShanieWinitz b4b2d1d
format
ShanieWinitz 59b0e72
format
ShanieWinitz dc3f2bf
format
ShanieWinitz 0b4dafe
format
ShanieWinitz cdbe020
format
ShanieWinitz 0e8670a
debug function removed
ShanieWinitz 13ef0f0
remove code in comment, fri test under ifdef
ShanieWinitz 00a5ef3
format
ShanieWinitz 518318d
Remove unnecessary files
ShanieWinitz a9bce88
asserts replaced with errors
ShanieWinitz 77f2646
merkle_trees is now moved into CpuFriBackend when calling create_fri.…
ShanieWinitz 907abbf
Replaced assertions with error logs, applied additional code review f…
ShanieWinitz 627947b
rand_query_indicies function update
ShanieWinitz 42fa634
Removed fri_c_api.cpp. It will be added back in the next PR
ShanieWinitz 1569b2a
m_first_round removed
ShanieWinitz 02a39f5
refactored verify method with smaller calls
ShanieWinitz 7205dbe
Pass fri_transcript_config by reference, and test for non-default config
ShanieWinitz f5cefa1
FriProof init: Added description and error handling for invalid argum…
ShanieWinitz 755b0f5
format
ShanieWinitz 9b2a900
revert MerkleTree build method to use sizeof(T)
ShanieWinitz 366f1b8
Removed for this PR: create_fri frontend for the case where merkle_tr…
ShanieWinitz f092a76
added test for cases where fri should fail. The basic test is now wit…
ShanieWinitz 881f0cb
format
ShanieWinitz 20585e6
minor
ShanieWinitz 48da21b
minor
ShanieWinitz 9ab1880
Merge branch 'main' into swinitz/fri_cpu
ShanieWinitz f4fc903
Merge remote-tracking branch 'origin/main' into swinitz/fri_cpu
ShanieWinitz 4cefe5d
Merge branch 'swinitz/fri_cpu' of github.com:ingonyama-zk/icicle into…
ShanieWinitz bd238aa
FRI frontend and cpu changes (#803)
jeremyfelder 6319dee
Formatting
jeremyfelder 01893ed
added documentation, removed debug prints
ShanieWinitz 5f49f36
api update - creat_fri() removed, now just calling get_proof or verify
ShanieWinitz 14db388
format
ShanieWinitz 2f16963
Changed FriShouldFailCases test to be deterministic. Removed redundan…
ShanieWinitz 2d792dc
format
ShanieWinitz fafb40d
Uncommented CUDA tests
ShanieWinitz c1eb318
Added more cases to FriShouldFailCases test. + some more code review …
ShanieWinitz 0746e1b
format
ShanieWinitz 6f6435b
Merge remote-tracking branch 'origin/main' into swinitz/fri_cpu
ShanieWinitz 19abf19
update documentation
ShanieWinitz c205291
copy MerkleTree instead of using a reference (The MerkleTree class on…
ShanieWinitz 39ab65f
format
ShanieWinitz d69b33e
FRI struct replaced with fri_merkle_tree namespace. const added to Fr…
ShanieWinitz 4da615c
"output_store_min_layer" removed from verify
ShanieWinitz 56ed067
change names to get_fri_proof_merkle_tree, fri_merkle_tree::prove, ve…
ShanieWinitz d80d180
moved Fri class from fri.h to fri.cpp.
ShanieWinitz 414b7dc
format
ShanieWinitz d3789cb
removed S from template
ShanieWinitz 58a8cc7
format
ShanieWinitz File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
250 changes: 250 additions & 0 deletions
250
docs/versioned_docs/version-3.5.0/icicle/primitives/fri.md
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,250 @@ | ||
# FRI API Documentation | ||
|
||
## Overview | ||
The Fast Reed-Solomon Interactive Oracle Proof of Proximity (FRI) protocol is used to efficiently verify that a given polynomial has a bounded degree. | ||
|
||
The Prover asserts that they know a low-degree polynomial F(x) of degree d, and they provide oracle access to a Reed-Solomon (RS) codeword representing evaluations of this polynomial over a domain L: | ||
|
||
$$ | ||
RS(F(x), L, n) = \{F(1), F(\alpha), F(\alpha^2), ..., F(\alpha^{n-1})\} | ||
$$ | ||
|
||
where α is a primitive root of unity, and $n = 2^l$ (for $l ∈ Z$) is the domain size. | ||
|
||
## How it works | ||
The proof construction consists of three phases: the Commit and Fold Phase, the Proof of Work Phase (optional), and the Query Phase. | ||
Using a Fiat-Shamir (FS) scheme, the proof is generated in a non-interactive manner, enabling the Prover to generate the entire proof and send it to the Verifier for validation. | ||
The polynomial size must be a power of 2 and is passed to the protocol in evaluation form. | ||
|
||
### Prover | ||
|
||
#### Commit and Fold Phase | ||
* The prover commits to the polynomial evaluations by constructing a Merkle tree. | ||
* A folding step is performed iteratively to reduce the polynomial degree. | ||
* In each step, the polynomial is rewritten using random coefficients derived from Fiat-Shamir hashing, and a new Merkle tree is built for the reduced polynomial. | ||
* This process continues recursively until the polynomial reaches a minimal length. | ||
* Currently, only a folding factor of 2 is supported. | ||
|
||
#### Proof of Work Phase (Optional) | ||
* If enabled, the prover is required to find a nonce such that, when hashed with the final Merkle tree root, the result meets a certain number of leading zero bits. | ||
|
||
#### Query Phase | ||
* Using the Fiat-Shamir transform, the prover determines the random query indices based on the previously committed Merkle roots. | ||
* For each sampled index, the prover provides the corresponding Merkle proof, showing that the value is part of the committed Merkle tree. | ||
* The prover returns all required data as the FriProof, which is then verified by the verifier. | ||
|
||
### Verifier | ||
* The verifier checks the Merkle proofs to ensure the sampled values were indeed committed to in the commit phase. | ||
* The verifier reconstructs the Fiat-Shamir challenges from the prover's commitments and verifies that the prover followed the protocol honestly. | ||
* The folding relation is checked for each sampled query. | ||
* If all checks pass, the proof is accepted as valid. | ||
|
||
|
||
## C++ API | ||
|
||
### Configuration structs | ||
There are two key configuration structs related to the Fri protocol. | ||
|
||
#### FriConfig | ||
The `FriConfig` struct is used to specify parameters for the FRI protocol. It contains the following fields: | ||
- **`stream: icicleStreamHandle`**: The CUDA stream for asynchronous execution. If `nullptr`, the default stream is used. | ||
- **`folding_factor: size_t`**: The factor by which the codeword is folded in each round. | ||
- **`stopping_degree: size_t`**: The minimal polynomial degree at which folding stops. | ||
- **`pow_bits: size_t`**: Number of leading zeros required for proof-of-work. If set, the optional proof-of-work phase is executed. | ||
- **`nof_queries: size_t`**: Number of queries computed for each folded layer of FRI. | ||
- **`are_inputs_on_device: bool`**: If true, the input polynomials are stored on the device (e.g., GPU); otherwise, they remain on the host (e.g., CPU). | ||
- **`is_async: bool`**: If true, it runs the hash asynchronously. | ||
Comment on lines
+51
to
+56
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. What are the defaults? |
||
- **`ext: ConfigExtension*`**: Backend-specific extensions. | ||
|
||
The default values are: | ||
```cpp | ||
// icicle/fri/fri_config.h | ||
struct FriConfig { | ||
icicleStreamHandle stream = nullptr; | ||
size_t folding_factor = 2; | ||
size_t stopping_degree = 0; | ||
size_t pow_bits = 16; | ||
size_t nof_queries = 100; | ||
bool are_inputs_on_device = false; | ||
bool is_async = false; | ||
ConfigExtension* ext = nullptr; | ||
}; | ||
``` | ||
> **_NOTE:_** Currently, only a folding factor of 2 is supported. | ||
|
||
#### FriTranscriptConfig | ||
The `FriTranscriptConfig<TypeParam>` class is used to specify parameters for the Fiat-Shamir scheme used by the FRI protocol. It contains the following fields: | ||
- **`hasher: Hash`**: The hash function used to generate randomness for Fiat-Shamir. | ||
- **`domain_separator_label: std::vector<std::byte>`** | ||
- **`round_challenge_label: std::vector<std::byte>`** | ||
- **`commit_phase_label: std::vector<std::byte>`** | ||
- **`nonce_label: std::vector<std::byte>`** | ||
- **`public_state: std::vector<std::byte>`** | ||
- **`seed_rng: TypeParam`**: The seed for initializing the RNG. | ||
|
||
> **_NOTE:_** the encoding is little endian. | ||
|
||
There are three constructors for `FriTranscriptConfig<TypeParam>`: | ||
|
||
* **Default constructor**: | ||
```cpp | ||
// icicle/fri/fri_transcript_config.h | ||
FriTranscriptConfig() | ||
: m_hasher(create_keccak_256_hash()), m_domain_separator_label({}), m_commit_phase_label({}), m_nonce_label({}), | ||
m_public({}), m_seed_rng(F::zero()) | ||
``` | ||
|
||
* **Constructor with byte vector for labels**: | ||
```cpp | ||
FriTranscriptConfig( | ||
Hash hasher, | ||
std::vector<std::byte>&& domain_separator_label, | ||
std::vector<std::byte>&& round_challenge_label, | ||
std::vector<std::byte>&& commit_phase_label, | ||
std::vector<std::byte>&& nonce_label, | ||
std::vector<std::byte>&& public_state, | ||
F seed_rng) | ||
: m_hasher(std::move(hasher)), m_domain_separator_label(std::move(domain_separator_label)), | ||
m_round_challenge_label(std::move(round_challenge_label)), | ||
m_commit_phase_label(std::move(commit_phase_label)), m_nonce_label(std::move(nonce_label)), | ||
m_public(std::move(public_state)), m_seed_rng(seed_rng) | ||
``` | ||
|
||
* **Constructor with `const char*` arguments for labels**: | ||
```cpp | ||
FriTranscriptConfig( | ||
Hash hasher, | ||
const char* domain_separator_label, | ||
const char* round_challenge_label, | ||
const char* commit_phase_label, | ||
const char* nonce_label, | ||
std::vector<std::byte>&& public_state, | ||
F seed_rng) | ||
: m_hasher(std::move(hasher)), m_domain_separator_label(cstr_to_bytes(domain_separator_label)), | ||
m_round_challenge_label(cstr_to_bytes(round_challenge_label)), | ||
m_commit_phase_label(cstr_to_bytes(commit_phase_label)), m_nonce_label(cstr_to_bytes(nonce_label)), | ||
m_public(std::move(public_state)), m_seed_rng(seed_rng) | ||
``` | ||
|
||
### Generating FRI Proofs | ||
To generate a proof, first, an empty proof needs to be created. The FRI proof is represented by the `FriProof<TypeParam>` class: | ||
|
||
```cpp | ||
// icicle/fri/fri_proof.h | ||
template <typename F> | ||
class FriProof | ||
``` | ||
|
||
The class has a default constructor `FriProof()` that takes no arguments. | ||
|
||
To generate a FRI proof using the Merkle Tree commit scheme, use one of the following functions: | ||
1. **Directly call `prove_fri_merkle_tree`:** | ||
```cpp | ||
template <typename F> | ||
eIcicleError prove_fri_merkle_tree( | ||
const FriConfig& fri_config, | ||
const FriTranscriptConfig<F>& fri_transcript_config, | ||
const F* input_data, | ||
const size_t input_size, | ||
Hash merkle_tree_leaves_hash, | ||
Hash merkle_tree_compress_hash, | ||
const uint64_t output_store_min_layer, | ||
FriProof<F>& fri_proof /* OUT */); | ||
``` | ||
2. **Use the `fri_merkle_tree` namespace, which internally calls `prove_fri_merkle_tree`:** | ||
```cpp | ||
fri_merkle_tree::prove<TypeParam>( ... ); | ||
``` | ||
This approach calls `prove_fri_merkle_tree` internally but provides a more structured way to access it. | ||
|
||
- **`input_data: const F*`**: Evaluations of The input polynomial. | ||
- **`fri_proof: FriProof<F>&`**: The output `FriProof` object containing the generated proof. | ||
* `merkle_tree_leaves_hash`, `merkle_tree_compress_hash` and `output_store_min_layer` refer to the hashes used in the Merkle Trees built in each round of the folding. For further information about ICICLE's Merkle Trees, see [Merkle-Tree documentation](./merkle.md) and [Hash documentation](./merkle.md). | ||
|
||
> **_NOTE:_** `folding_factor` must be divisible by `merkle_tree_compress_hash`. | ||
|
||
|
||
> **_NOTE:_** An NTT domain is used for proof generation, so before generating a proof, an NTT domain of at least the input_data size must be initialized. For more information see [NTT documentation](./ntt.md). | ||
|
||
```cpp | ||
NTTInitDomainConfig init_domain_config = default_ntt_init_domain_config(); | ||
ntt_init_domain(scalar_t::omega(log_input_size), init_domain_config) | ||
``` | ||
::: | ||
|
||
#### Example: Generating a Proof | ||
|
||
```cpp | ||
// Initialize ntt domain | ||
NTTInitDomainConfig init_domain_config = default_ntt_init_domain_config(); | ||
ntt_init_domain(scalar_t::omega(log_input_size), init_domain_config); | ||
|
||
// Define hashers for merkle tree | ||
uint64_t merkle_tree_arity = 2; | ||
Hash hash = Keccak256::create(sizeof(TypeParam)); // hash element -> 32B | ||
Hash compress = Keccak256::create(merkle_tree_arity * hash.output_size()); // hash every 64B to 32B | ||
|
||
// set transcript config | ||
const char* domain_separator_label = "domain_separator_label"; | ||
const char* round_challenge_label = "round_challenge_label"; | ||
const char* commit_phase_label = "commit_phase_label"; | ||
const char* nonce_label = "nonce_label"; | ||
std::vector<std::byte>&& public_state = {}; | ||
TypeParam seed_rng = TypeParam::one(); | ||
|
||
FriTranscriptConfig<TypeParam> transcript_config( | ||
hash, domain_separator_label, round_challenge_label, commit_phase_label, nonce_label, std::move(public_state), | ||
seed_rng); | ||
|
||
// set fri config | ||
FriConfig fri_config; | ||
fri_config.nof_queries = 100; | ||
fri_config.pow_bits = 16; | ||
fri_config.folding_factor = 2; | ||
fri_config.stopping_degree = 0; | ||
|
||
FriProof<TypeParam> fri_proof; | ||
|
||
// get fri proof | ||
eIcicleError err = fri_merkle_tree::prove<TypeParam>( | ||
fri_config, transcript_config, scalars.get(), input_size, hash, compress, output_store_min_layer, fri_proof); | ||
ICICLE_CHECK(err); | ||
|
||
// Release ntt domain | ||
ntt_release_domain<scalar_t>(); | ||
``` | ||
|
||
### Verifying Fri Proofs | ||
|
||
To verify the FRI proof using the Merkle Tree commit scheme, use one of the following functions: | ||
|
||
1. **Directly call `verify_fri_merkle_tree`**: | ||
```cpp | ||
// icicle/fri/fri.h | ||
template <typename F> | ||
eIcicleError verify_fri_merkle_tree( | ||
const FriConfig& fri_config, | ||
const FriTranscriptConfig<F>& fri_transcript_config, | ||
FriProof<F>& fri_proof, | ||
Hash merkle_tree_leaves_hash, | ||
Hash merkle_tree_compress_hash, | ||
bool& valid /* OUT */); | ||
``` | ||
|
||
2. **Use the `fri_merkle_tree` namespac, which internally calls `verify_fri_merkle_tree`:** | ||
```cpp | ||
fri_merkle_tree::verify<TypeParam>( ... ); | ||
``` | ||
|
||
> **_NOTE:_** `FriConfig` and `FriTranscriptConfig` used for generating the proof must be identical to the one used for verification. | ||
|
||
#### Example: Verifying a Proof | ||
```cpp | ||
bool valid = false; | ||
eIcicleError err = fri_merkle_tree::verify<TypeParam>( | ||
fri_config, transcript_config, fri_proof, hash, compress, valid); | ||
ICICLE_CHECK(err); | ||
ASSERT_EQ(true, valid); // Ensure proof verification succeeds | ||
``` | ||
|
||
After calling `fri_merkle_tree::verify`, the variable `valid` will be set to `true` if the proof is valid, and `false` otherwise. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Move out of versioned docs @ShanieWinitz, this only relates to v3.5 and we don't have fri in this version