mirror of
https://github.com/arnaucube/fri-commitment.git
synced 2026-01-12 08:51:32 +01:00
Add prove & verify methods for FRI low-degree testing
This commit is contained in:
97
src/lib.rs
97
src/lib.rs
@@ -41,7 +41,7 @@ impl<F: PrimeField, P: UVPolynomial<F>> FRI<F, P> {
|
||||
);
|
||||
}
|
||||
|
||||
pub fn prove<R: Rng>(rng: &mut R, p: &P) -> (Vec<F>, [F; 2]) {
|
||||
pub fn prove<R: Rng>(rng: &mut R, p: &P) -> (Vec<F>, Vec<F>, [F; 2]) {
|
||||
// f_0(x) = fL_0(x^2) + x fR_0(x^2)
|
||||
let mut f_i1 = p.clone();
|
||||
|
||||
@@ -59,15 +59,84 @@ impl<F: PrimeField, P: UVPolynomial<F>> FRI<F, P> {
|
||||
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());
|
||||
|
||||
// commit to f_{i+1}(x) = fL_i(x) + alpha_i * fR_i(x)
|
||||
let (cm_i, mt_i) = MT::commit(f_i1.coeffs());
|
||||
commitments.push(cm_i);
|
||||
mts.push(mt_i);
|
||||
}
|
||||
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<F> = Vec::new();
|
||||
// TODO this will be a hash from the transcript
|
||||
// V sets rand z \in \mathbb{F} challenge
|
||||
let z = F::from(10_u64);
|
||||
|
||||
(evals, [constant_fL_l, constant_fR_l])
|
||||
let mut evals: Vec<F> = Vec::new();
|
||||
// TODO this will be done inside the prev loop, now it is here just for clarity
|
||||
// evaluate f_i(z^{2^i})
|
||||
for i in 0..f_is.len() {
|
||||
// TODO check usage of .pow(u64)
|
||||
let z_2i = z.pow([2_u64.pow(i as u32)]); // z^{2^i}
|
||||
let neg_z_2i = z_2i.neg();
|
||||
let eval_i = f_is[i].evaluate(&z_2i);
|
||||
evals.push(eval_i);
|
||||
let eval_i = f_is[i].evaluate(&neg_z_2i);
|
||||
evals.push(eval_i);
|
||||
}
|
||||
|
||||
// TODO return also the commitment_proofs
|
||||
// return: Comm(f_i(x)), f_i(+-z^{2^i}), constant values {f_l^L, f_l^R}
|
||||
(commitments, evals, [constant_fL_l, constant_fR_l])
|
||||
}
|
||||
|
||||
pub fn verify(commitments: Vec<F>, evals: Vec<F>, constants: [F; 2]) -> bool {
|
||||
let z = F::from(10_u64); // TODO this will be a hash from the transcript
|
||||
|
||||
// TODO check commitments.len()==evals.len()/2
|
||||
|
||||
for i in (0..evals.len()).step_by(2) {
|
||||
let alpha_i = F::from(3_u64); // TODO: WIP, defined by Verifier (well, hash transcript)
|
||||
|
||||
let z_2i = z.pow([2_u64.pow((i as u32) / 2)]); // z^{2^i}
|
||||
// take f_i(z^2) from evals
|
||||
let fi_z = evals[i];
|
||||
let neg_fi_z = evals[i + 1];
|
||||
// compute f_i^L(z^2), f_i^R(z^2) from the linear combination
|
||||
let L = (fi_z + neg_fi_z) * F::from(2_u32).inverse().unwrap();
|
||||
let R = (fi_z - neg_fi_z) * (F::from(2_u32) * z_2i).inverse().unwrap();
|
||||
|
||||
// compute f_{i+1}(z^2) = f_i^L(z^2) + a_i f_i^R(z^2)
|
||||
let next_fi_z2 = L + alpha_i * R;
|
||||
|
||||
// check: obtained f_{i+1}(z^2) == evals.f_{i+1}(z^2) (=evals[i+2])
|
||||
if i < evals.len() - 2 {
|
||||
if next_fi_z2 != evals[i + 2] {
|
||||
println!("\nerr, i={:?}", i);
|
||||
println!(" next_fi^z2 {:?}", next_fi_z2.to_string());
|
||||
println!(" e[i] {:?}", evals[i + 2].to_string());
|
||||
panic!("should f_i+1(z^2) == evals.f_i+1(z^2) (=evals[i+2])");
|
||||
}
|
||||
}
|
||||
|
||||
// check commitment opening
|
||||
// TODO
|
||||
|
||||
// last iteration, check constant values equal to the obtained f_i^L(z^{2^i}),
|
||||
// f_i^R(z^{2^i})
|
||||
if i == evals.len() - 2 {
|
||||
if L != constants[0] {
|
||||
panic!("constant L not equal");
|
||||
}
|
||||
if R != constants[1] {
|
||||
println!("R {:?}\n {:?}", R.to_string(), constants[1].to_string());
|
||||
panic!("constant R not equal");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
true
|
||||
}
|
||||
}
|
||||
|
||||
@@ -97,4 +166,24 @@ mod tests {
|
||||
pL.evaluate(&z.square()) + z * pR.evaluate(&z.square())
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn test_prove() {
|
||||
let mut rng = ark_std::test_rng();
|
||||
|
||||
let deg = 15;
|
||||
let p = DensePolynomial::<Fr>::rand(deg, &mut rng);
|
||||
assert_eq!(p.degree(), deg);
|
||||
// println!("p {:?}", p);
|
||||
|
||||
type FRIC = FRI<Fr, DensePolynomial<Fr>>;
|
||||
// prover
|
||||
let (commitments, evals, constvals) = FRIC::prove(&mut rng, &p);
|
||||
// commitments contains the commitments to each f_0, f_1, ..., f_n, with n=log2(d)
|
||||
assert_eq!(commitments.len(), log2(p.coeffs().len()) as usize - 1);
|
||||
assert_eq!(evals.len(), 2 * log2(p.coeffs().len()) as usize);
|
||||
|
||||
let v = FRIC::verify(commitments, evals, constvals);
|
||||
assert!(v);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user