1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
// Copyright (c) Facebook, Inc. and its affiliates.
//
// This source code is licensed under the MIT license found in the
// LICENSE file in the root directory of this source tree.
//! This crate contains an implementation of the FRI protocol used by the Winterfell STARK prover
//! and verifier.
//!
//! FRI stands for Fast Reed-Solomon Interactive Oracle Proof of Proximity, and is used in the
//! STARK protocol for low-degree testing. Specifically, given a commitment to a set of evaluations
//! of some function over domain *D*, the verifier can be convinced that the function is a
//! polynomial of degree at most *d*, by making a small number of queries to the commitment.
//!
//! # Proof generation
//! FRI proofs are generated by a [FriProver] in two steps:
//!
//! 1. First, the commit phase of the protocol is executed via
//! [build_layers()](prover::FriProver::build_layers()) function. During this phase, the degree
//! of the polynomial is repeatedly reduced by applying a degree-respecting projection, until
//! the size of the domain over which the polynomial is evaluated falls under
//! `max_remainder_size` parameter. While performing the reduction, the prover writes a set of
//! layer commitments into the [ProverChannel]. These commitments should be recorded and sent
//! to the verifier as they will be needed during the proof verification procedure.
//! 2. Then, the query phase of the protocol is executed via
//! [build_proof()](prover::FriProver::build_proof()) function. The output of this function is
//! an instance of the [FriProof] struct. When FRI is executed as a part of the STARK protocol,
//! FRI proof is included into a STARK proof.
//!
//! When the crate is compiled with `concurrent` feature enabled, proof generation will be
//! performed in multiple threads (usually, as many threads as there are logical cores on the
//! machine). The number of threads can be configured via `RAYON_NUM_THREADS` environment variable.
//!
//! # Proof verification
//! FRI proofs are verified by a [FriVerifier] as follows:
//! 1. First, a FRI proof needs to be converted into a [VerifierChannel]. This crate provides a
//! default implementation of the verifier channel, but when FRI proof verification is executed
//! as a part of the larger STARK protocol, STARK verifier handles this conversion.
//! 2. Then, a [FriVerifier] should be instantiated (via [new()](FriVerifier::new()) function).
//! This will execute the commit phase of the FRI protocol from the verifier's perspective -
//! i.e., the verifier will read FRI layer commitments from the channel, and generates
//! random values needed for layer folding.
//! 3. Finally, the query phase of the FRI protocol should be executed via
//! [verify()](FriVerifier::verify()) function. Note that query values at the first FRI layer
//! are provided to the [verify()](FriVerifier::verify()) function directly. The values at
//! remaining layers, the verifier reads from the specified verifier channel.
//!
//! # Protocol parameters
//! The current implementation supports executing FRI protocol with dynamically configurable
//! parameters including:
//!
//! * Base STARK field,
//! * Extension field,
//! * Domain blowup factor,
//! * Hash function (used for Merkle tree commitments),
//! * Folding factor (used for degree reduction for each FRI layer),
//! * Maximum size of the last FRI layer.
//!
//! # References
//! * StarkWare's blog post on [Low Degree Testing](https://medium.com/starkware/low-degree-testing-f7614f5172db)
//! * [Fast Reed-Solomon Interactive Oracle Proofs of Proximity](https://eccc.weizmann.ac.il/report/2017/134/)
//! * [DEEP-FRI: Sampling Outside the Box Improves Soundness](https://eprint.iacr.org/2019/336)
//! * Swastik Kooparty's [talk on DEEP-FRI](https://www.youtube.com/watch?v=txo_kPSn59Y&list=PLcIyXLwiPilWvjvNkhMn283LV370Pk5CT&index=6)
#![cfg_attr(not(feature = "std"), no_std)]
#[cfg(not(feature = "std"))]
#[macro_use]
extern crate alloc;
pub mod folding;
mod prover;
pub use prover::{DefaultProverChannel, FriProver, ProverChannel};
mod verifier;
pub use verifier::{DefaultVerifierChannel, FriVerifier, VerifierChannel};
mod options;
pub use options::FriOptions;
mod proof;
pub use proof::FriProof;
mod errors;
pub use errors::VerifierError;
pub mod utils;