feat: public inputs

This commit is contained in:
Daniel Tehrani
2023-07-29 16:13:48 -07:00
parent 068623edab
commit cda41a9374
12 changed files with 274 additions and 143 deletions

View File

@@ -17,5 +17,6 @@ halo2curves = "0.1.0"
criterion = { version = "0.4", features = ["html_reports"] }
[[bench]]
name = "prove"
name = "pcs"
path = "benches/prove.rs"
harness = false

View File

@@ -7,6 +7,7 @@ pub struct EqPoly<F: FieldExt> {
}
impl<F: FieldExt> EqPoly<F> {
// `t` should be in big-endian.
pub fn new(t: Vec<F>) -> Self {
Self { t }
}
@@ -23,18 +24,18 @@ impl<F: FieldExt> EqPoly<F> {
// Copied from microsoft/Spartan
pub fn evals(&self) -> Vec<F> {
let ell = self.t.len(); // 4
let ell = self.t.len();
let mut evals: Vec<F> = vec![F::ONE; 2usize.pow(ell as u32)];
let mut size = 1;
for j in 0..ell {
// in each iteration, we double the size of chis
size *= 2; // 2 4 8 16
size *= 2;
for i in (0..size).rev().step_by(2) {
// copy each element from the prior iteration twice
let scalar = evals[i / 2]; // i = 0, 2, 4, 7
evals[i] = scalar * self.t[j]; // (1 * t0)(1 * t1)
evals[i - 1] = scalar - evals[i]; // 1 - (1 * t0)(1 * t1)
let scalar = evals[i / 2];
evals[i] = scalar * self.t[j];
evals[i - 1] = scalar - evals[i];
}
}
evals
@@ -44,25 +45,30 @@ impl<F: FieldExt> EqPoly<F> {
#[cfg(test)]
mod tests {
use super::*;
use crate::polynomial::sparse_ml_poly::SparseMLPoly;
use halo2curves::ff::Field;
type F = halo2curves::secp256k1::Fp;
pub fn dot_prod<F: FieldExt>(x: &[F], y: &[F]) -> F {
assert_eq!(x.len(), y.len());
let mut result = F::ZERO;
for i in 0..x.len() {
result += x[i] * y[i];
}
result
}
use halo2curves::ff::Field;
#[test]
fn test_eq_poly() {
let m = 4;
let t = (0..m).map(|i| F::from((i + 33) as u64)).collect::<Vec<F>>();
let eq_poly = EqPoly::new(t.clone());
eq_poly.evals();
let evals = eq_poly.evals();
let eval_first = eq_poly.eval(&[F::ZERO, F::ZERO, F::ZERO, F::ZERO]);
assert_eq!(eval_first, evals[0], "The first evaluation is not correct");
let eval_second = eq_poly.eval(&[F::ZERO, F::ZERO, F::ZERO, F::ONE]);
assert_eq!(
eval_second, evals[1],
"The second evaluation is not correct"
);
let eval_last = eq_poly.eval(&[F::ONE, F::ONE, F::ONE, F::ONE]);
assert_eq!(
eval_last,
evals[evals.len() - 1],
"The last evaluation is not correct"
);
}
}

View File

@@ -14,8 +14,8 @@ impl<F: FieldExt> SparseMLPoly<F> {
pub fn from_dense(dense_evals: Vec<F>) -> Self {
let sparse_evals = dense_evals
.iter()
.filter(|eval| **eval != F::ZERO)
.enumerate()
.filter(|(_, eval)| **eval != F::ZERO)
.map(|(i, eval)| (i, *eval))
.collect::<Vec<(usize, F)>>();
let num_vars = (dense_evals.len() as f64).log2() as usize;
@@ -26,7 +26,9 @@ impl<F: FieldExt> SparseMLPoly<F> {
}
}
// `t` should be in big-endian form.
pub fn eval(&self, t: &[F]) -> F {
assert_eq!(self.num_vars, t.len());
// Evaluate the multilinear extension of the polynomial `a`,
// over the boolean hypercube
@@ -42,3 +44,36 @@ impl<F: FieldExt> SparseMLPoly<F> {
result
}
}
#[cfg(test)]
mod tests {
use super::*;
type F = halo2curves::secp256k1::Fp;
use halo2curves::ff::Field;
#[test]
fn test_sparse_ml_poly_eval() {
let num_vars = 4;
let num_evals = 2usize.pow(num_vars as u32);
let evals = (0..num_evals)
.map(|x| F::from((x as u64) as u64))
.collect::<Vec<F>>();
let ml_poly = SparseMLPoly::from_dense(evals.clone());
let eval_last = ml_poly.eval(&[F::ONE, F::ONE, F::ONE, F::ONE]);
assert_eq!(
eval_last,
evals[evals.len() - 1],
"The last evaluation is not correct"
);
let eval_first = ml_poly.eval(&[F::ZERO, F::ZERO, F::ZERO, F::ZERO]);
assert_eq!(eval_first, evals[0], "The first evaluation is not correct");
let eval_second = ml_poly.eval(&[F::ZERO, F::ZERO, F::ZERO, F::ONE]);
assert_eq!(
eval_second, evals[1],
"The second evaluation is not correct"
);
}
}

View File

@@ -120,11 +120,9 @@ impl<F: FieldExt> TensorMultilinearPCS<F> {
// ########################################
// Get the evaluation point
let mut point_rev = point.to_vec();
point_rev.reverse();
let log2_num_rows = (num_rows as f64).log2() as usize;
let q1 = EqPoly::new(point_rev[0..log2_num_rows].to_vec()).evals();
let q1 = EqPoly::new(point[0..log2_num_rows].to_vec()).evals();
let eval_r_prime = rlc_rows(blinder, &q1);
@@ -134,7 +132,7 @@ impl<F: FieldExt> TensorMultilinearPCS<F> {
TensorMLOpening {
x: point.to_vec(),
y: poly.eval(&point_rev),
y: poly.eval(&point),
eval_query_leaves: eval_queries,
test_query_leaves: test_queries,
u_hat_comm: u_hat_comm.committed_tree.root(),
@@ -163,7 +161,6 @@ impl<F: FieldExt> TensorMultilinearPCS<F> {
// ########################################
let r_u = transcript.challenge_vec(num_rows);
println!("r_u = {:?}", r_u);
let test_u_prime_rs_codeword = self
.rs_encode(&opening.test_u_prime)
@@ -197,12 +194,9 @@ impl<F: FieldExt> TensorMultilinearPCS<F> {
// Verify evaluation phase
// ########################################
let mut x_rev = opening.x.clone();
x_rev.reverse();
let log2_num_rows = (num_rows as f64).log2() as usize;
let q1 = EqPoly::new(x_rev[0..log2_num_rows].to_vec()).evals();
let q2 = EqPoly::new(x_rev[log2_num_rows..].to_vec()).evals();
let q1 = EqPoly::new(opening.x[0..log2_num_rows].to_vec()).evals();
let q2 = EqPoly::new(opening.x[log2_num_rows..].to_vec()).evals();
let eval_u_prime_rs_codeword = self
.rs_encode(&opening.eval_u_prime)