-
Notifications
You must be signed in to change notification settings - Fork 37
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sketch of the hyper kzg from univariate kzg
- Loading branch information
1 parent
922ccd8
commit e2ea745
Showing
3 changed files
with
147 additions
and
50 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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, | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters