mirror of
https://github.com/arnaucube/shockwave-plus.git
synced 2026-01-12 17:11:30 +01:00
feat: public inputs
This commit is contained in:
@@ -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
|
||||
@@ -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"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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"
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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)
|
||||
|
||||
Reference in New Issue
Block a user