From 61c848f055f0f65d3fc38ace35d2796c359ede02 Mon Sep 17 00:00:00 2001 From: arnaucube Date: Sun, 5 Mar 2023 10:42:17 +0100 Subject: [PATCH] Add poly split, start prover --- src/lib.rs | 100 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 100 insertions(+) create mode 100644 src/lib.rs diff --git a/src/lib.rs b/src/lib.rs new file mode 100644 index 0000000..d7a846e --- /dev/null +++ b/src/lib.rs @@ -0,0 +1,100 @@ +#![allow(non_snake_case)] + +pub mod merkletree; +use merkletree::{MerkleTreePoseidon as MT, Params as MTParams}; + +use ark_ff::PrimeField; +use ark_poly::{univariate::DensePolynomial, UVPolynomial}; +use ark_std::log2; +use ark_std::marker::PhantomData; +use ark_std::ops::Mul; +use ark_std::{rand::Rng, UniformRand}; + +pub struct FRI> { + _f: PhantomData, + _poly: PhantomData

, +} + +impl> FRI { + pub fn new() -> Self { + Self { + _f: PhantomData, + _poly: PhantomData, + } + } + + pub fn split(p: &P) -> (P, P) { + // let d = p.degree() + 1; + let d = p.coeffs().len(); + if (d != 0) && (d & (d - 1) != 0) { + println!("d={:?}", d); + panic!("d should be a power of 2"); + } + + let coeffs = p.coeffs(); + let odd: Vec = coeffs.iter().step_by(2).cloned().collect(); + let even: Vec = coeffs.iter().skip(1).step_by(2).cloned().collect(); + + return ( + P::from_coefficients_vec(odd), + P::from_coefficients_vec(even), + ); + } + + pub fn prove(rng: &mut R, p: &P) -> (Vec, [F; 2]) { + // f_0(x) = fL_0(x^2) + x fR_0(x^2) + let mut f_i1 = p.clone(); + + // TODO challenge a_0 + let mut f_is: Vec

= Vec::new(); + f_is.push(p.clone()); + let mut commitments: Vec = Vec::new(); + let mut mts: Vec> = Vec::new(); + while f_i1.degree() > 1 { + let alpha_i = F::from(3_u64); // TODO: WIP, defined by Verifier (well, hash transcript) + + let (fL_i, fR_i) = Self::split(&f_i1); + + // compute f_{i+1}(x) = fL_i(x) + alpha_i * fR_i(x) + let aux = DensePolynomial::from_coefficients_slice(fR_i.coeffs()); + f_i1 = fL_i.clone() + P::from_coefficients_slice(aux.mul(alpha_i).coeffs()); + f_is.push(f_i1.clone()); + } + let (fL_i, fR_i) = Self::split(&f_i1); + let constant_fL_l: F = fL_i.coeffs()[0].clone(); + let constant_fR_l: F = fR_i.coeffs()[0].clone(); + + // TODO evaluate f_i(z^{2^i}) + let evals: Vec = Vec::new(); + + (evals, [constant_fL_l, constant_fR_l]) + } +} + +#[cfg(test)] +mod tests { + use super::*; + use ark_ff::Field; + use ark_std::UniformRand; + pub type Fr = ark_bn254::Fr; // scalar field + use ark_poly::univariate::DensePolynomial; + use ark_poly::Polynomial; + + #[test] + fn test_split() { + let mut rng = ark_std::test_rng(); + let deg = 7; + let p = DensePolynomial::::rand(deg, &mut rng); + assert_eq!(p.degree(), deg); + + type FRIC = FRI>; + let (pL, pR) = FRIC::split(&p); + + // check that f(z) == fL(x^2) + x * fR(x^2), for a rand z + let z = Fr::rand(&mut rng); + assert_eq!( + p.evaluate(&z), + pL.evaluate(&z.square()) + z * pR.evaluate(&z.square()) + ); + } +}