Skip to content
Snippets Groups Projects
Commit 9ed9b013 authored by E__Man's Association's avatar E__Man's Association
Browse files

Renamed prover.rs to commit.rs

parent 85fba9da
No related branches found
No related tags found
No related merge requests found
use ark_ff::FftField;
use ark_poly::{EvaluationDomain, GeneralEvaluationDomain};
use ark_serialize::CanonicalSerialize;
use rs_merkle::{Hasher, MerkleTree};
use crate::{utils::MerkleTreeExt, folding::FoldedEvaluations};
use crate::{
folding::{reduce_polynomial, FoldedEvaluations},
rng::ReseedableRng,
utils::{to_polynomial, AssertPowerOfTwo, HasherExt, MerkleTreeExt},
};
#[derive(Clone)]
pub(crate) struct FriLayer<const N: usize, F, H: Hasher> {
......@@ -27,7 +32,12 @@ impl<const N: usize, F, H: Hasher> FriLayer<N, F, H> {
}
}
/// Result of a polynomial folding. Use [`fri::build_proof`] to get a FRI proof.
/// Result of a polynomial folding (FRI COMMIT phase).
///
/// Use [`fri::commit_polynomial`] to create a [`FriCommitments`] from a polynomial in coefficient form,
/// or [`FriCommitments::new`] to create it from the evaluations directly.
///
/// Use [`fri::build_proof`] to get an actual FRI proof from a [`FriCommitments`].
#[derive(Clone)]
pub struct FriCommitments<const N: usize, F, H: Hasher> {
layers: Vec<FriLayer<N, F, H>>,
......@@ -35,11 +45,57 @@ pub struct FriCommitments<const N: usize, F, H: Hasher> {
}
impl<const N: usize, F: FftField, H: Hasher> FriCommitments<N, F, H> {
pub(crate) fn new(degree_bound: usize) -> Self {
let layers = Vec::with_capacity(degree_bound.ilog2().div_ceil(N.ilog2()) as usize);
/// Commits the polynomial according to FRI algorithm.
/// - `evaluations` is the list of evaluations of the polynomial on the `n`-th roots of unity
/// (where `n = evaluations.len()`).
///
/// See [`fri::commit_polynomial`] for information about the other parameters.
///
/// # Panics
/// This may either panic or have unspecified behaviour if `remainder_degree_plus_one` is inconsistent with
/// the degree-bound of the polynomial and the folding factor, or if `F` does not contain a subgroup of size
/// `evaluations.len()`.
pub fn new<R>(
mut evaluations: Vec<F>,
mut rng: R,
blowup_factor: usize,
remainder_degree_plus_one: usize,
) -> Self
where
R: ReseedableRng<Seed = H::Hash>,
{
let _: () = AssertPowerOfTwo::<N>::OK;
let degree_bound = evaluations.len() / blowup_factor;
debug_assert!(
(degree_bound.ilog2() - remainder_degree_plus_one.ilog2()) % N.ilog2() == 0,
"Invalid remainder degree {} for polynomial of degree {} and folding factor {N} (would result in degree truncation)",
remainder_degree_plus_one - 1,
degree_bound - 1
);
let mut layers = Vec::with_capacity(
((degree_bound.ilog2() - remainder_degree_plus_one.ilog2()) / N.ilog2()) as usize,
);
// Reduce the polynomial from its evaluations:
let domain = GeneralEvaluationDomain::<F>::new(N).unwrap();
while evaluations.len() > remainder_degree_plus_one * blowup_factor {
let layer = FriLayer::new(&evaluations);
rng.reseed(layer.tree().root().expect("cannot get tree root"));
evaluations =
reduce_polynomial::<N, _>(layer.evaluations(), rng.draw_alpha(), Some(&domain));
layers.push(layer);
}
// Commit remainder directly
let poly = to_polynomial(evaluations, remainder_degree_plus_one);
rng.reseed(H::hash_item(&poly));
Self {
layers,
remainder: vec![],
remainder: poly,
}
}
pub(crate) fn layers(&self) -> &[FriLayer<N, F, H>] {
......@@ -48,11 +104,4 @@ impl<const N: usize, F: FftField, H: Hasher> FriCommitments<N, F, H> {
pub(crate) fn remainder(self) -> Vec<F> {
self.remainder
}
pub(crate) fn commit_layer(&mut self, layer: FriLayer<N, F, H>)
{
self.layers.push(layer);
}
pub(crate) fn set_remainder(&mut self, polynomial: Vec<F>) {
self.remainder = polynomial;
}
}
......@@ -4,15 +4,15 @@ use ark_ff::FftField;
use ark_poly::{
univariate::DensePolynomial, EvaluationDomain, GeneralEvaluationDomain, Polynomial,
};
use folding::{fold_positions, reduce_polynomial, FoldedEvaluationsSlice};
use prover::{FriCommitments, FriLayer};
pub use commit::FriCommitments;
use folding::{fold_positions, FoldedEvaluationsSlice};
use rng::ReseedableRng;
use rs_merkle::{Hasher, MerkleProof};
use utils::{to_evaluations, to_polynomial, AssertPowerOfTwo, HasherExt};
use utils::{to_evaluations, AssertPowerOfTwo, HasherExt};
pub mod algorithms;
pub mod commit;
pub mod folding;
pub mod prover;
pub mod rng;
pub mod utils;
......@@ -88,54 +88,38 @@ impl<F: Copy, H: Hasher> FriProofLayer<F, H> {
/// Commits the polynomial according to FRI algorithm.
///
/// - `N` is the folding factor. It should be a power of two.
/// - `polynomial` is the list of coefficients of the polynomial.
/// - `polynomial` is the list of coefficients of the polynomial. See [`FriCommitments::new`] for an alternative
/// function that accepts the evaluations directly.
/// - `rng` is the pseudo-random number generator to be used by the algorithm.
/// - The initial evaluation domain will have size at least `polynomial.len() * blowup_factor` (rounded up to
/// the next power of two).
/// - `remainder_degree` is the degree of the remainder polynomial in the last FRI layer.
/// - `remainder_degree_plus_one` is one more than degree of the remainder polynomial in the last FRI layer.
/// It should be a power of `N`.
///
/// # Panics
/// This panics if `polynomial.len() * blowup_factor > 2^63` and if `F` does not contain a subgroup of the size
/// of the requested evaluation domain.
/// This may either panic or have unspecified behaviour if `polynomial.len() * blowup_factor > 2^63`,
/// if `remainder_degree_plus_one` is inconsistent with `polynomial.len()` and `N`, or if `F` does not contain
/// a subgroup of the size of the requested evaluation domain.
pub fn commit_polynomial<const N: usize, F, H, R>(
polynomial: Vec<F>,
mut rng: R,
rng: R,
blowup_factor: usize,
remainder_degree: usize,
remainder_degree_plus_one: usize,
) -> FriCommitments<N, F, H>
where
F: FftField,
H: Hasher,
R: ReseedableRng<Seed = H::Hash>,
{
let _: () = AssertPowerOfTwo::<N>::OK;
// Convert the polynonial to evaluation form:
let num_coeffs = polynomial.len();
let mut prover = FriCommitments::new(num_coeffs);
let domain_size = (polynomial.len() * blowup_factor)
.checked_next_power_of_two()
.unwrap_or_else(|| panic!(
"Domain size out of bounds for blowup factor {blowup_factor} and polynomial of degree-bound {}", polynomial.len()
));
let mut evaluations = to_evaluations(polynomial, domain_size);
// Reduce the polynomial from its evaluations:
let domain = GeneralEvaluationDomain::<F>::new(N).unwrap();
while evaluations.len() > remainder_degree * blowup_factor {
let layer = FriLayer::new(&evaluations);
rng.reseed(layer.tree().root().expect("cannot get tree root"));
evaluations =
reduce_polynomial::<N, _>(layer.evaluations(), rng.draw_alpha(), Some(&domain));
prover.commit_layer(layer);
}
// Commit remainder directly
let poly = to_polynomial(evaluations, remainder_degree);
rng.reseed(H::hash_item(&poly));
prover.set_remainder(poly);
prover
let evaluations = to_evaluations(polynomial, domain_size);
FriCommitments::new(evaluations, rng, blowup_factor, remainder_degree_plus_one)
}
// TODO? create a function that combines `commit_polynomial` and `build_proof`?
......
......@@ -7,7 +7,7 @@ use winter_utils::transpose_slice;
use crate::{
algorithms::Blake3,
build_proof, commit_polynomial,
folding::FoldedEvaluations,
folding::{reduce_polynomial, FoldedEvaluations},
rng::FriChallenger,
utils::to_evaluations,
};
......@@ -45,7 +45,7 @@ fn test_reduction() {
let transposed = transpose_slice::<_, FACTOR>(&evaluations);
evaluations = winter_fri::folding::apply_drp(&transposed, BaseElement::ONE, alpha);
let folded = FoldedEvaluations::new(&evaluations2);
evaluations2 = super::reduce_polynomial::<FACTOR, _>(&folded, alpha2, None);
evaluations2 = reduce_polynomial::<FACTOR, _>(&folded, alpha2, None);
assert_eq!(convert_many(&evaluations), evaluations2);
}
......@@ -62,7 +62,7 @@ fn test_prove_verify() {
println!("--Folding factor={FACTOR}");
let mut rng = FriChallenger::<Blake3>::default();
let commitments = commit_polynomial::<FACTOR, _, Blake3, _>(poly.clone(), &mut rng, BLOWUP_FACTOR, FACTOR);
let commitments = commit_polynomial::<FACTOR, _, Blake3, _>(poly.clone(), &mut rng, BLOWUP_FACTOR, 1);
let proof = build_proof(commitments, &mut rng, NUM_QUERIES);
rng.reset();
......
......@@ -71,14 +71,25 @@ impl<H: Hasher> MerkleTreeExt for MerkleTree<H> {
/// `domain_size` must be a power of two and strictly greater than the degree of the polynomial.
///
/// # Example
/// ```ignore
/// let polynomial = /* vec of coeffs */;
/// let evaluations = to_evaluations(polynomial, domain_size);
/// ```
/// use ark_ff::FftField;
/// use ark_poly::{Polynomial, DenseUVPolynomial, univariate::DensePolynomial};
/// use rand::{thread_rng, Rng};
///
/// use fri::utils::{to_evaluations, to_polynomial};
/// use fri_test_utils::Fq;
///
/// const POLY_COEFFS_LEN: usize = 32;
/// const DOMAIN_SIZE: usize = 128;
///
/// let mut rng = thread_rng();
/// let polynomial: Vec<Fq> = (0..POLY_COEFFS_LEN).map(|_| rng.gen()).collect();
/// let evaluations = to_evaluations(polynomial.clone(), DOMAIN_SIZE);
/// let dense_poly = DensePolynomial::from_coefficients_vec(polynomial.clone());
///
/// let w = F::get_root_of_unity(domain_size).unwrap();
/// let w = Fq::get_root_of_unity(DOMAIN_SIZE as u64).unwrap();
///
/// assert_eq!(evaluations[0], dense_poly.evaluate(&w));
/// assert_eq!(evaluations[1], dense_poly.evaluate(&w));
///
/// let interpolated = to_polynomial(evaluations, polynomial.len());
///
......
......@@ -3,7 +3,7 @@
use ark_ff::{Fp128, MontBackend, MontConfig};
pub const NUMBER_OF_POLYNOMIALS: usize = 10;
pub const POLY_COEFFS_LEN: usize = 2048;
pub const POLY_COEFFS_LEN: usize = 4096;
pub const BLOWUP_FACTOR: usize = 4;
pub const NUM_QUERIES: usize = 32;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment