Browse Source

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

main
zhenfei 2 years ago
committed by GitHub
parent
commit
3ea5b61c5e
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 106 additions and 11 deletions
  1. +1
    -0
      poly-iop/src/lib.rs
  2. +92
    -0
      poly-iop/src/perm_check/mod.rs
  3. +11
    -0
      poly-iop/src/utils.rs
  4. +2
    -11
      poly-iop/src/virtual_poly.rs

+ 1
- 0
poly-iop/src/lib.rs

@ -2,6 +2,7 @@ use ark_ff::PrimeField;
use std::marker::PhantomData;
mod errors;
mod perm_check;
mod structs;
mod sum_check;
mod transcript;

+ 92
- 0
poly-iop/src/perm_check/mod.rs

@ -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(())
}
}

+ 11
- 0
poly-iop/src/utils.rs

@ -11,6 +11,17 @@ macro_rules! to_bytes {
}};
}
#[cfg(test)]
pub(crate) fn bit_decompose(input: u64, num_var: usize) -> Vec<bool> {
let mut res = Vec::with_capacity(num_var);
let mut i = input;
for _ in 0..num_var {
res.push(i & 1 == 1);
i >>= 1;
}
res
}
#[test]
fn test_to_bytes() {
use ark_bls12_381::Fr;

+ 2
- 11
poly-iop/src/virtual_poly.rs

@ -436,8 +436,9 @@ fn build_eq_x_r_helper(r: &[F], buf: &mut Vec) -> Result<(), P
}
#[cfg(test)]
pub(crate) mod test {
mod test {
use super::*;
use crate::utils::bit_decompose;
use ark_bls12_381::Fr;
use ark_ff::UniformRand;
use ark_std::test_rng;
@ -548,14 +549,4 @@ pub(crate) mod test {
end_timer!(start);
res
}
fn bit_decompose(input: u64, num_var: usize) -> Vec<bool> {
let mut res = Vec::with_capacity(num_var);
let mut i = input;
for _ in 0..num_var {
res.push(i & 1 == 1);
i >>= 1;
}
res
}
}

Loading…
Cancel
Save