Skip to content

Commit

Permalink
sketch of the hyper kzg from univariate kzg
Browse files Browse the repository at this point in the history
  • Loading branch information
tonyfloatersu committed Jan 31, 2025
1 parent 922ccd8 commit e2ea745
Show file tree
Hide file tree
Showing 3 changed files with 147 additions and 50 deletions.
181 changes: 137 additions & 44 deletions poly_commit/src/kzg/hyperkzg.rs
Original file line number Diff line number Diff line change
@@ -1,73 +1,166 @@
use std::iter;

use arith::ExtensionField;
use halo2curves::{ff::Field, group::Group, pairing::MultiMillerLoop, CurveAffine};
use halo2curves::{ff::Field, group::GroupEncoding, pairing::MultiMillerLoop, CurveAffine};
use itertools::izip;
use transcript::Transcript;

use crate::{
coeff_form_uni_kzg_commit, coeff_form_uni_kzg_open, even_odd_coeffs_separate, merge_coeffs,
powers_of_field_elements, univariate_evaluate,
coeff_form_uni_kzg_commit, even_odd_coeffs_separate, powers_of_field_elements,
univariate_degree_one_quotient, univariate_evaluate,
};

use super::CoefFormUniKZGSRS;
use super::{CoefFormUniKZGSRS, HyperKZGOpening};

pub fn coeff_form_uni_hyperkzg_open<E: MultiMillerLoop, T: Transcript<E::Fr>>(
srs: &CoefFormUniKZGSRS<E>,
coeffs: &[E::Fr],
coeffs: &Vec<E::Fr>,
alphas: &[E::Fr],
_eval: E::Fr,
beta: E::Fr,
gamma: E::Fr,
_transcript: &mut T,
) where
fs_transcript: &mut T,
) -> HyperKZGOpening<E>
where
E::G1Affine: CurveAffine<ScalarExt = E::Fr, CurveExt = E::G1>,
E::Fr: ExtensionField,
{
let beta2 = beta * beta;
let power_series = powers_of_field_elements(&beta2, coeffs.len() >> 1);
let mut local_coeffs = coeffs.to_vec();
let mut combine_weight = E::Fr::ONE;

let mut folded_commitment_agg: E::G1 = E::G1::generator() * E::Fr::ZERO;
let mut odd_commitment_agg: E::G1 = E::G1::generator() * E::Fr::ZERO;
let mut even_commitment_agg: E::G1 = E::G1::generator() * E::Fr::ZERO;
let (folded_oracle_commits, folded_oracle_coeffs): (Vec<E::G1>, Vec<Vec<E::Fr>>) = alphas
[..alphas.len() - 1]
.iter()
.map(|alpha| {
let (evens, odds) = even_odd_coeffs_separate(&local_coeffs);

local_coeffs = izip!(&evens, &odds)
.map(|(e, o)| (E::Fr::ONE - alpha) * e + *alpha * *o)
.collect();

let folded_oracle_commit = coeff_form_uni_kzg_commit(srs, &local_coeffs);

fs_transcript.append_u8_slice(folded_oracle_commit.to_bytes().as_ref());

(folded_oracle_commit, local_coeffs.clone())
})
.unzip();

let beta = fs_transcript.generate_challenge_field_element();
let beta2 = beta * beta;
let beta_inv = beta.invert().unwrap();
let two_inv = E::Fr::ONE.double().invert().unwrap();
let beta_pow_series = powers_of_field_elements(&beta, coeffs.len());
let neg_beta_pow_series = powers_of_field_elements(&(-beta), coeffs.len());

let beta2_eval = {
let beta2_pow_series = powers_of_field_elements(&beta2, coeffs.len());
univariate_evaluate(coeffs, &beta2_pow_series)
};

let mut total_opening_agg: E::G1 = E::G1::generator() * E::Fr::ZERO;
let mut odd_opening_agg: E::G1 = E::G1::generator() * E::Fr::ZERO;
let mut even_opening_agg: E::G1 = E::G1::generator() * E::Fr::ZERO;
fs_transcript.append_field_element(&beta2_eval);
let mut beta2_evals = vec![beta2_eval];

let mut odd_eval_agg: E::Fr = E::Fr::ZERO;
let mut even_eval_agg: E::Fr = E::Fr::ZERO;
let (beta_evals, neg_beta_evals): (Vec<E::Fr>, Vec<E::Fr>) = izip!(
iter::once(coeffs).chain(folded_oracle_coeffs.iter()),
alphas
)
.enumerate()
.map(|(i, (cs, alpha))| {
let beta_eval = univariate_evaluate(cs, &beta_pow_series);
let neg_beta_eval = univariate_evaluate(cs, &neg_beta_pow_series);

alphas.iter().enumerate().for_each(|(i, alpha)| {
if i != 0 {
let local_com = coeff_form_uni_kzg_commit(srs, &local_coeffs);
folded_commitment_agg += local_com * combine_weight;
if i < alphas.len() - 1 {
let beta2_eval = (beta_eval + neg_beta_eval) * two_inv * (E::Fr::ONE - alpha)
+ (beta_eval - neg_beta_eval) * two_inv * beta_inv * alpha;

beta2_evals.push(beta2_eval);
}

let (evens, odds) = even_odd_coeffs_separate(&local_coeffs);
fs_transcript.append_field_element(&beta_eval);
fs_transcript.append_field_element(&neg_beta_eval);

(beta_eval, neg_beta_eval)
})
.unzip();

let gamma = fs_transcript.generate_challenge_field_element();
let gamma_pow_series = powers_of_field_elements(&gamma, alphas.len());
let v_beta = univariate_evaluate(&beta_evals, &gamma_pow_series);
let v_neg_beta = univariate_evaluate(&neg_beta_evals, &gamma_pow_series);
let v_beta2 = univariate_evaluate(&beta2_evals, &gamma_pow_series);
let f_gamma = {
let mut f = coeffs.clone();
izip!(&gamma_pow_series[1..], &folded_oracle_coeffs).for_each(|(gamma_i, folded_f)| {
izip!(&mut f, folded_f).for_each(|(f_i, folded_f_i)| {
*f_i += *folded_f_i * *gamma_i;
});
});
f
};
let lagrange_degree2: Vec<E::Fr> = {
let l_beta_nom = vec![-beta2 * beta, -beta2 + beta, E::Fr::ONE];
let l_beta_denom_inv: E::Fr = ((beta - beta2) * (beta + beta)).invert().unwrap();
let l_beta: Vec<E::Fr> = l_beta_nom.iter().map(|i| *i * l_beta_denom_inv).collect();

let l_neg_beta_norm = vec![beta2 * beta, -beta2 - beta, E::Fr::ONE];
let l_neg_beta_denom_inv: E::Fr = ((beta2 - beta) * (beta2 + beta)).invert().unwrap();
let l_neg_beta: Vec<E::Fr> = l_neg_beta_norm
.iter()
.map(|i| *i * l_neg_beta_denom_inv)
.collect();

let l_beta2_norm = vec![-beta2, E::Fr::ZERO, E::Fr::ONE];
let l_beta2_denom_inv: E::Fr = ((beta + beta2) * (beta + beta)).invert().unwrap();
let l_beta2: Vec<E::Fr> = l_beta2_norm
.iter()
.map(|i| *i * l_beta2_denom_inv)
.collect();

izip!(l_beta, l_neg_beta, l_beta2)
.map(|(l_beta_i, l_neg_beta_i, l_beta2_i)| {
l_beta_i * v_beta + l_neg_beta_i * v_neg_beta + l_beta2_i * v_beta2
})
.collect()
};
let f_gamma_quotient = {
let mut nom = f_gamma.clone();
izip!(&mut nom, &lagrange_degree2).for_each(|(n, l)| *n -= l);

let (nom_1, remainder_1) = univariate_degree_one_quotient(&nom, beta);
assert_eq!(remainder_1, E::Fr::ZERO);

let (nom_2, remainder_2) = univariate_degree_one_quotient(&nom_1, beta2);
assert_eq!(remainder_2, E::Fr::ZERO);

let local_evens_com = coeff_form_uni_kzg_commit(srs, &evens);
even_commitment_agg += local_evens_com * combine_weight;
let (nom_3, remainder_3) = univariate_degree_one_quotient(&nom_2, -beta);
assert_eq!(remainder_3, E::Fr::ZERO);

let local_odds_com = coeff_form_uni_kzg_commit(srs, &odds);
odd_commitment_agg += local_odds_com * combine_weight;
nom_3
};
let f_gamma_quotient_com = coeff_form_uni_kzg_commit(srs, &f_gamma_quotient);
fs_transcript.append_u8_slice(f_gamma_quotient_com.to_bytes().as_ref());

let evens_beta2_eval = univariate_evaluate(&evens, &power_series);
let local_even_opening = coeff_form_uni_kzg_open(srs, &evens, beta2, evens_beta2_eval);
even_opening_agg += local_even_opening * combine_weight;
even_eval_agg += evens_beta2_eval * combine_weight;
let tau = fs_transcript.generate_challenge_field_element();
let vanishing_at_tau = {
let f_gamma_denom = (tau - beta) * (tau + beta) * (tau - beta2);
let lagrange_degree2_at_tau =
lagrange_degree2[0] + lagrange_degree2[1] * tau + lagrange_degree2[2] * tau * tau;

let odds_beta2_eval = univariate_evaluate(&odds, &power_series);
let local_odd_opening = coeff_form_uni_kzg_open(srs, &odds, beta2, odds_beta2_eval);
odd_opening_agg += local_odd_opening * combine_weight;
odd_eval_agg += odds_beta2_eval * combine_weight;
let mut poly = f_gamma.clone();
poly[0] -= lagrange_degree2_at_tau;
izip!(&mut poly, &f_gamma_quotient).for_each(|(p, f)| *p -= *f * f_gamma_denom);

let current_eval = evens_beta2_eval + beta * odds_beta2_eval;
let local_total_opening = coeff_form_uni_kzg_open(srs, &local_coeffs, beta, current_eval);
total_opening_agg += local_total_opening * combine_weight;
let (quotient, remainder) = univariate_degree_one_quotient(&poly, tau);
assert_eq!(remainder, E::Fr::ZERO);

local_coeffs = merge_coeffs(evens, odds, *alpha);
combine_weight *= gamma;
});
quotient
};
let vanishing_at_tau_commitment = coeff_form_uni_kzg_commit(srs, &vanishing_at_tau);

todo!()
HyperKZGOpening {
folded_oracle_commitments: folded_oracle_commits,
f_beta2: beta2_eval,
evals_at_beta: beta_evals,
evals_at_neg_beta: neg_beta_evals,
beta_commitment: f_gamma_quotient_com,
tau_vanishing_commitment: vanishing_at_tau_commitment,
}
}
10 changes: 10 additions & 0 deletions poly_commit/src/kzg/structs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -113,3 +113,13 @@ impl<E: Engine> From<&CoefFormUniKZGSRS<E>> for UniKZGVerifierParams<E> {
}
}
}

#[derive(Debug, Default)]
pub struct HyperKZGOpening<E: Engine> {
pub folded_oracle_commitments: Vec<E::G1>,
pub f_beta2: E::Fr,
pub evals_at_beta: Vec<E::Fr>,
pub evals_at_neg_beta: Vec<E::Fr>,
pub beta_commitment: E::G1,
pub tau_vanishing_commitment: E::G1,
}
6 changes: 0 additions & 6 deletions poly_commit/src/kzg/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,9 +60,3 @@ pub(crate) fn even_odd_coeffs_separate<F: Field>(coeffs: &[F]) -> (Vec<F>, Vec<F

(even, odd)
}

pub(crate) fn merge_coeffs<F: Field>(evens: Vec<F>, odds: Vec<F>, alpha: F) -> Vec<F> {
assert_eq!(evens.len(), odds.len());

izip!(&evens, &odds).map(|(e, o)| *e + alpha * *o).collect()
}

0 comments on commit e2ea745

Please sign in to comment.