26 implement prod(0,x) (#27)

This commit is contained in:
zhenfei
2022-05-20 16:29:14 -04:00
committed by GitHub
parent 97a89d7ecc
commit 3ea5b61c5e
4 changed files with 106 additions and 11 deletions

View File

@@ -0,0 +1,92 @@
//! This module implements the permutation check protocol.
use ark_ff::PrimeField;
use ark_poly::DenseMultilinearExtension;
use crate::PolyIOPErrors;
/// Compute `prod(0,x) := prod(0, x1, …, xn)` which is the MLE over the
/// evaluations of the following polynomial on the boolean hypercube {0,1}^n:
///
/// (w(x) + \beta s_id(x) + \gamma)/(w(x) + \beta s_perm(x) + \gamma)
///
/// where
/// - beta and gamma are challenges
/// - w(x), s_id(x), s_perm(x) are mle-s
#[allow(dead_code)]
// TODO: remove
fn compute_prod_0<F: PrimeField>(
beta: &F,
gamma: &F,
w: &DenseMultilinearExtension<F>,
s_id: &DenseMultilinearExtension<F>,
s_perm: &DenseMultilinearExtension<F>,
) -> Result<DenseMultilinearExtension<F>, PolyIOPErrors> {
let num_vars = w.num_vars;
if num_vars != s_id.num_vars || num_vars != s_perm.num_vars {
return Err(PolyIOPErrors::InvalidParameters(
"num of variables do not match".to_string(),
));
}
let eval: Vec<F> = w
.iter()
.zip(s_id.iter().zip(s_perm.iter()))
.map(|(wi, (s_id_i, s_perm_i))| {
let tmp = *wi + *gamma;
(tmp + *beta * *s_id_i) / (tmp + *beta * *s_perm_i)
})
.collect();
let res = DenseMultilinearExtension::from_evaluations_vec(num_vars, eval);
Ok(res)
}
#[cfg(test)]
mod test {
use super::*;
use crate::utils::bit_decompose;
use ark_bls12_381::Fr;
use ark_ff::UniformRand;
use ark_poly::MultilinearExtension;
use ark_std::test_rng;
#[test]
fn test_compute_prod_0() -> Result<(), PolyIOPErrors> {
let mut rng = test_rng();
for num_vars in 2..6 {
let w_vec: Vec<Fr> = (0..(1 << num_vars)).map(|_| Fr::rand(&mut rng)).collect();
let w = DenseMultilinearExtension::from_evaluations_vec(num_vars, w_vec);
let s_id_vec: Vec<Fr> = (0..(1 << num_vars)).map(|_| Fr::rand(&mut rng)).collect();
let s_id = DenseMultilinearExtension::from_evaluations_vec(num_vars, s_id_vec);
let s_perm_vec: Vec<Fr> = (0..(1 << num_vars)).map(|_| Fr::rand(&mut rng)).collect();
let s_perm = DenseMultilinearExtension::from_evaluations_vec(num_vars, s_perm_vec);
let beta = Fr::rand(&mut rng);
let gamma = Fr::rand(&mut rng);
for i in 0..1 << num_vars {
let r: Vec<Fr> = bit_decompose(i, num_vars)
.iter()
.map(|&x| Fr::from(x))
.collect();
let prod_0 = compute_prod_0(&beta, &gamma, &w, &s_id, &s_perm)?;
let eval = prod_0.evaluate(&r).unwrap();
let w_eval = w.evaluate(&r).unwrap();
let s_id_eval = s_id.evaluate(&r).unwrap();
let s_perm_eval = s_perm.evaluate(&r).unwrap();
let eval_rec =
(w_eval + beta * s_id_eval + gamma) / (w_eval + beta * s_perm_eval + gamma);
assert_eq!(eval, eval_rec);
}
}
Ok(())
}
}