mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-02 13:53:07 +00:00
Merge pull request #716 from mir-protocol/s/l1/l0
Change Lagrange polynomial notation
This commit is contained in:
commit
8647f144b7
@ -181,8 +181,8 @@ fn verify_stark_proof_with_challenges_circuit<
|
||||
let degree_bits = proof.recover_degree_bits(inner_config);
|
||||
let zeta_pow_deg = builder.exp_power_of_2_extension(challenges.stark_zeta, degree_bits);
|
||||
let z_h_zeta = builder.sub_extension(zeta_pow_deg, one);
|
||||
let (l_1, l_last) =
|
||||
eval_l_1_and_l_last_circuit(builder, degree_bits, challenges.stark_zeta, z_h_zeta);
|
||||
let (l_0, l_last) =
|
||||
eval_l_0_and_l_last_circuit(builder, degree_bits, challenges.stark_zeta, z_h_zeta);
|
||||
let last =
|
||||
builder.constant_extension(F::Extension::primitive_root_of_unity(degree_bits).inverse());
|
||||
let z_last = builder.sub_extension(challenges.stark_zeta, last);
|
||||
@ -191,7 +191,7 @@ fn verify_stark_proof_with_challenges_circuit<
|
||||
builder.zero_extension(),
|
||||
challenges.stark_alphas.clone(),
|
||||
z_last,
|
||||
l_1,
|
||||
l_0,
|
||||
l_last,
|
||||
);
|
||||
|
||||
@ -254,7 +254,7 @@ fn verify_stark_proof_with_challenges_circuit<
|
||||
);
|
||||
}
|
||||
|
||||
fn eval_l_1_and_l_last_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
fn eval_l_0_and_l_last_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
log_n: usize,
|
||||
x: ExtensionTarget<D>,
|
||||
@ -263,12 +263,12 @@ fn eval_l_1_and_l_last_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
let n = builder.constant_extension(F::Extension::from_canonical_usize(1 << log_n));
|
||||
let g = builder.constant_extension(F::Extension::primitive_root_of_unity(log_n));
|
||||
let one = builder.one_extension();
|
||||
let l_1_deno = builder.mul_sub_extension(n, x, n);
|
||||
let l_0_deno = builder.mul_sub_extension(n, x, n);
|
||||
let l_last_deno = builder.mul_sub_extension(g, x, one);
|
||||
let l_last_deno = builder.mul_extension(n, l_last_deno);
|
||||
|
||||
(
|
||||
builder.div_extension(z_x, l_1_deno),
|
||||
builder.div_extension(z_x, l_0_deno),
|
||||
builder.div_extension(z_x, l_last_deno),
|
||||
)
|
||||
}
|
||||
|
||||
@ -133,7 +133,7 @@ where
|
||||
};
|
||||
|
||||
let degree_bits = proof.recover_degree_bits(config);
|
||||
let (l_1, l_last) = eval_l_1_and_l_last(degree_bits, challenges.stark_zeta);
|
||||
let (l_0, l_last) = eval_l_0_and_l_last(degree_bits, challenges.stark_zeta);
|
||||
let last = F::primitive_root_of_unity(degree_bits).inverse();
|
||||
let z_last = challenges.stark_zeta - last.into();
|
||||
let mut consumer = ConstraintConsumer::<F::Extension>::new(
|
||||
@ -143,7 +143,7 @@ where
|
||||
.map(|&alpha| F::Extension::from_basefield(alpha))
|
||||
.collect::<Vec<_>>(),
|
||||
z_last,
|
||||
l_1,
|
||||
l_0,
|
||||
l_last,
|
||||
);
|
||||
let num_permutation_zs = stark.num_permutation_batches(config);
|
||||
@ -204,10 +204,10 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Evaluate the Lagrange polynomials `L_1` and `L_n` at a point `x`.
|
||||
/// `L_1(x) = (x^n - 1)/(n * (x - 1))`
|
||||
/// `L_n(x) = (x^n - 1)/(n * (g * x - 1))`, with `g` the first element of the subgroup.
|
||||
fn eval_l_1_and_l_last<F: Field>(log_n: usize, x: F) -> (F, F) {
|
||||
/// Evaluate the Lagrange polynomials `L_0` and `L_(n-1)` at a point `x`.
|
||||
/// `L_0(x) = (x^n - 1)/(n * (x - 1))`
|
||||
/// `L_(n-1)(x) = (x^n - 1)/(n * (g * x - 1))`, with `g` the first element of the subgroup.
|
||||
fn eval_l_0_and_l_last<F: Field>(log_n: usize, x: F) -> (F, F) {
|
||||
let n = F::from_canonical_usize(1 << log_n);
|
||||
let g = F::primitive_root_of_unity(log_n);
|
||||
let z_x = x.exp_power_of_2(log_n) - F::ONE;
|
||||
@ -222,10 +222,10 @@ mod tests {
|
||||
use plonky2::field::polynomial::PolynomialValues;
|
||||
use plonky2::field::types::Field;
|
||||
|
||||
use crate::verifier::eval_l_1_and_l_last;
|
||||
use crate::verifier::eval_l_0_and_l_last;
|
||||
|
||||
#[test]
|
||||
fn test_eval_l_1_and_l_last() {
|
||||
fn test_eval_l_0_and_l_last() {
|
||||
type F = GoldilocksField;
|
||||
let log_n = 5;
|
||||
let n = 1 << log_n;
|
||||
@ -234,7 +234,7 @@ mod tests {
|
||||
let expected_l_first_x = PolynomialValues::selector(n, 0).ifft().eval(x);
|
||||
let expected_l_last_x = PolynomialValues::selector(n, n - 1).ifft().eval(x);
|
||||
|
||||
let (l_first_x, l_last_x) = eval_l_1_and_l_last(log_n, x);
|
||||
let (l_first_x, l_last_x) = eval_l_0_and_l_last(log_n, x);
|
||||
assert_eq!(l_first_x, expected_l_first_x);
|
||||
assert_eq!(l_last_x, expected_l_last_x);
|
||||
}
|
||||
|
||||
@ -51,8 +51,8 @@ impl<F: Field> ZeroPolyOnCoset<F> {
|
||||
packed
|
||||
}
|
||||
|
||||
/// Returns `L_1(x) = Z_H(x)/(n * (x - 1))` with `x = w^i`.
|
||||
pub fn eval_l1(&self, i: usize, x: F) -> F {
|
||||
/// Returns `L_0(x) = Z_H(x)/(n * (x - 1))` with `x = w^i`.
|
||||
pub fn eval_l_0(&self, i: usize, x: F) -> F {
|
||||
// Could also precompute the inverses using Montgomery.
|
||||
self.eval(i) * (self.n * (x - F::ONE)).inverse()
|
||||
}
|
||||
|
||||
@ -64,31 +64,31 @@ pub(crate) fn eval_zero_poly<F: Field>(n: usize, x: F) -> F {
|
||||
x.exp_u64(n as u64) - F::ONE
|
||||
}
|
||||
|
||||
/// Evaluate the Lagrange basis `L_1` with `L_1(1) = 1`, and `L_1(x) = 0` for other members of an
|
||||
/// Evaluate the Lagrange basis `L_0` with `L_0(1) = 1`, and `L_0(x) = 0` for other members of the
|
||||
/// order `n` multiplicative subgroup.
|
||||
pub(crate) fn eval_l_1<F: Field>(n: usize, x: F) -> F {
|
||||
pub(crate) fn eval_l_0<F: Field>(n: usize, x: F) -> F {
|
||||
if x.is_one() {
|
||||
// The code below would divide by zero, since we have (x - 1) in both the numerator and
|
||||
// denominator.
|
||||
return F::ONE;
|
||||
}
|
||||
|
||||
// L_1(x) = (x^n - 1) / (n * (x - 1))
|
||||
// L_0(x) = (x^n - 1) / (n * (x - 1))
|
||||
// = Z(x) / (n * (x - 1))
|
||||
eval_zero_poly(n, x) / (F::from_canonical_usize(n) * (x - F::ONE))
|
||||
}
|
||||
|
||||
/// Evaluates the Lagrange basis L_1(x), which has L_1(1) = 1 and vanishes at all other points in
|
||||
/// Evaluates the Lagrange basis L_0(x), which has L_0(1) = 1 and vanishes at all other points in
|
||||
/// the order-`n` subgroup.
|
||||
///
|
||||
/// Assumes `x != 1`; if `x` could be 1 then this is unsound.
|
||||
pub(crate) fn eval_l_1_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
pub(crate) fn eval_l_0_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
n: usize,
|
||||
x: ExtensionTarget<D>,
|
||||
x_pow_n: ExtensionTarget<D>,
|
||||
) -> ExtensionTarget<D> {
|
||||
// L_1(x) = (x^n - 1) / (n * (x - 1))
|
||||
// L_0(x) = (x^n - 1) / (n * (x - 1))
|
||||
// = Z(x) / (n * (x - 1))
|
||||
let one = builder.one_extension();
|
||||
let neg_one = builder.neg_one();
|
||||
|
||||
@ -10,7 +10,7 @@ use crate::plonk::circuit_builder::CircuitBuilder;
|
||||
use crate::plonk::circuit_data::CommonCircuitData;
|
||||
use crate::plonk::config::GenericConfig;
|
||||
use crate::plonk::plonk_common;
|
||||
use crate::plonk::plonk_common::eval_l_1_circuit;
|
||||
use crate::plonk::plonk_common::eval_l_0_circuit;
|
||||
use crate::plonk::vars::{EvaluationTargets, EvaluationVars, EvaluationVarsBaseBatch};
|
||||
use crate::util::partial_products::{check_partial_products, check_partial_products_circuit};
|
||||
use crate::util::reducing::ReducingFactorTarget;
|
||||
@ -41,17 +41,17 @@ pub(crate) fn eval_vanishing_poly<
|
||||
|
||||
let constraint_terms = evaluate_gate_constraints(common_data, vars);
|
||||
|
||||
// The L_1(x) (Z(x) - 1) vanishing terms.
|
||||
// The L_0(x) (Z(x) - 1) vanishing terms.
|
||||
let mut vanishing_z_1_terms = Vec::new();
|
||||
// The terms checking the partial products.
|
||||
let mut vanishing_partial_products_terms = Vec::new();
|
||||
|
||||
let l1_x = plonk_common::eval_l_1(common_data.degree(), x);
|
||||
let l_0_x = plonk_common::eval_l_0(common_data.degree(), x);
|
||||
|
||||
for i in 0..common_data.config.num_challenges {
|
||||
let z_x = local_zs[i];
|
||||
let z_gx = next_zs[i];
|
||||
vanishing_z_1_terms.push(l1_x * (z_x - F::Extension::ONE));
|
||||
vanishing_z_1_terms.push(l_0_x * (z_x - F::Extension::ONE));
|
||||
|
||||
let numerator_values = (0..common_data.config.num_routed_wires)
|
||||
.map(|j| {
|
||||
@ -135,7 +135,7 @@ pub(crate) fn eval_vanishing_poly_base_batch<
|
||||
let mut numerator_values = Vec::with_capacity(num_routed_wires);
|
||||
let mut denominator_values = Vec::with_capacity(num_routed_wires);
|
||||
|
||||
// The L_1(x) (Z(x) - 1) vanishing terms.
|
||||
// The L_0(x) (Z(x) - 1) vanishing terms.
|
||||
let mut vanishing_z_1_terms = Vec::with_capacity(num_challenges);
|
||||
// The terms checking the partial products.
|
||||
let mut vanishing_partial_products_terms = Vec::new();
|
||||
@ -152,11 +152,11 @@ pub(crate) fn eval_vanishing_poly_base_batch<
|
||||
|
||||
let constraint_terms = PackedStridedView::new(&constraint_terms_batch, n, k);
|
||||
|
||||
let l1_x = z_h_on_coset.eval_l1(index, x);
|
||||
let l_0_x = z_h_on_coset.eval_l_0(index, x);
|
||||
for i in 0..num_challenges {
|
||||
let z_x = local_zs[i];
|
||||
let z_gx = next_zs[i];
|
||||
vanishing_z_1_terms.push(l1_x * z_x.sub_one());
|
||||
vanishing_z_1_terms.push(l_0_x * z_x.sub_one());
|
||||
|
||||
numerator_values.extend((0..num_routed_wires).map(|j| {
|
||||
let wire_value = vars.local_wires[j];
|
||||
@ -332,12 +332,12 @@ pub(crate) fn eval_vanishing_poly_circuit<
|
||||
evaluate_gate_constraints_circuit(builder, common_data, vars,)
|
||||
);
|
||||
|
||||
// The L_1(x) (Z(x) - 1) vanishing terms.
|
||||
// The L_0(x) (Z(x) - 1) vanishing terms.
|
||||
let mut vanishing_z_1_terms = Vec::new();
|
||||
// The terms checking the partial products.
|
||||
let mut vanishing_partial_products_terms = Vec::new();
|
||||
|
||||
let l1_x = eval_l_1_circuit(builder, common_data.degree(), x, x_pow_deg);
|
||||
let l_0_x = eval_l_0_circuit(builder, common_data.degree(), x, x_pow_deg);
|
||||
|
||||
// Holds `k[i] * x`.
|
||||
let mut s_ids = Vec::new();
|
||||
@ -350,8 +350,8 @@ pub(crate) fn eval_vanishing_poly_circuit<
|
||||
let z_x = local_zs[i];
|
||||
let z_gx = next_zs[i];
|
||||
|
||||
// L_1(x) Z(x) = 0.
|
||||
vanishing_z_1_terms.push(builder.mul_sub_extension(l1_x, z_x, l1_x));
|
||||
// L_0(x) (Z(x) - 1) = 0.
|
||||
vanishing_z_1_terms.push(builder.mul_sub_extension(l_0_x, z_x, l_0_x));
|
||||
|
||||
let mut numerator_values = Vec::new();
|
||||
let mut denominator_values = Vec::new();
|
||||
|
||||
@ -102,8 +102,8 @@ fn verify_stark_proof_with_challenges_circuit<
|
||||
|
||||
let zeta_pow_deg = builder.exp_power_of_2_extension(challenges.stark_zeta, degree_bits);
|
||||
let z_h_zeta = builder.sub_extension(zeta_pow_deg, one);
|
||||
let (l_1, l_last) =
|
||||
eval_l_1_and_l_last_circuit(builder, degree_bits, challenges.stark_zeta, z_h_zeta);
|
||||
let (l_0, l_last) =
|
||||
eval_l_0_and_l_last_circuit(builder, degree_bits, challenges.stark_zeta, z_h_zeta);
|
||||
let last =
|
||||
builder.constant_extension(F::Extension::primitive_root_of_unity(degree_bits).inverse());
|
||||
let z_last = builder.sub_extension(challenges.stark_zeta, last);
|
||||
@ -112,7 +112,7 @@ fn verify_stark_proof_with_challenges_circuit<
|
||||
builder.zero_extension(),
|
||||
challenges.stark_alphas,
|
||||
z_last,
|
||||
l_1,
|
||||
l_0,
|
||||
l_last,
|
||||
);
|
||||
|
||||
@ -170,7 +170,7 @@ fn verify_stark_proof_with_challenges_circuit<
|
||||
);
|
||||
}
|
||||
|
||||
fn eval_l_1_and_l_last_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
fn eval_l_0_and_l_last_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
builder: &mut CircuitBuilder<F, D>,
|
||||
log_n: usize,
|
||||
x: ExtensionTarget<D>,
|
||||
@ -179,12 +179,12 @@ fn eval_l_1_and_l_last_circuit<F: RichField + Extendable<D>, const D: usize>(
|
||||
let n = builder.constant_extension(F::Extension::from_canonical_usize(1 << log_n));
|
||||
let g = builder.constant_extension(F::Extension::primitive_root_of_unity(log_n));
|
||||
let one = builder.one_extension();
|
||||
let l_1_deno = builder.mul_sub_extension(n, x, n);
|
||||
let l_0_deno = builder.mul_sub_extension(n, x, n);
|
||||
let l_last_deno = builder.mul_sub_extension(g, x, one);
|
||||
let l_last_deno = builder.mul_extension(n, l_last_deno);
|
||||
|
||||
(
|
||||
builder.div_extension(z_x, l_1_deno),
|
||||
builder.div_extension(z_x, l_0_deno),
|
||||
builder.div_extension(z_x, l_last_deno),
|
||||
)
|
||||
}
|
||||
|
||||
@ -78,7 +78,7 @@ where
|
||||
.unwrap(),
|
||||
};
|
||||
|
||||
let (l_1, l_last) = eval_l_1_and_l_last(degree_bits, challenges.stark_zeta);
|
||||
let (l_0, l_last) = eval_l_0_and_l_last(degree_bits, challenges.stark_zeta);
|
||||
let last = F::primitive_root_of_unity(degree_bits).inverse();
|
||||
let z_last = challenges.stark_zeta - last.into();
|
||||
let mut consumer = ConstraintConsumer::<F::Extension>::new(
|
||||
@ -88,7 +88,7 @@ where
|
||||
.map(|&alpha| F::Extension::from_basefield(alpha))
|
||||
.collect::<Vec<_>>(),
|
||||
z_last,
|
||||
l_1,
|
||||
l_0,
|
||||
l_last,
|
||||
);
|
||||
let permutation_data = stark.uses_permutation_args().then(|| PermutationCheckVars {
|
||||
@ -144,10 +144,10 @@ where
|
||||
Ok(())
|
||||
}
|
||||
|
||||
/// Evaluate the Lagrange polynomials `L_1` and `L_n` at a point `x`.
|
||||
/// `L_1(x) = (x^n - 1)/(n * (x - 1))`
|
||||
/// `L_n(x) = (x^n - 1)/(n * (g * x - 1))`, with `g` the first element of the subgroup.
|
||||
fn eval_l_1_and_l_last<F: Field>(log_n: usize, x: F) -> (F, F) {
|
||||
/// Evaluate the Lagrange polynomials `L_0` and `L_(n-1)` at a point `x`.
|
||||
/// `L_0(x) = (x^n - 1)/(n * (x - 1))`
|
||||
/// `L_(n-1)(x) = (x^n - 1)/(n * (g * x - 1))`, with `g` the first element of the subgroup.
|
||||
fn eval_l_0_and_l_last<F: Field>(log_n: usize, x: F) -> (F, F) {
|
||||
let n = F::from_canonical_usize(1 << log_n);
|
||||
let g = F::primitive_root_of_unity(log_n);
|
||||
let z_x = x.exp_power_of_2(log_n) - F::ONE;
|
||||
@ -189,10 +189,10 @@ mod tests {
|
||||
use plonky2::field::polynomial::PolynomialValues;
|
||||
use plonky2::field::types::Field;
|
||||
|
||||
use crate::verifier::eval_l_1_and_l_last;
|
||||
use crate::verifier::eval_l_0_and_l_last;
|
||||
|
||||
#[test]
|
||||
fn test_eval_l_1_and_l_last() {
|
||||
fn test_eval_l_0_and_l_last() {
|
||||
type F = GoldilocksField;
|
||||
let log_n = 5;
|
||||
let n = 1 << log_n;
|
||||
@ -201,7 +201,7 @@ mod tests {
|
||||
let expected_l_first_x = PolynomialValues::selector(n, 0).ifft().eval(x);
|
||||
let expected_l_last_x = PolynomialValues::selector(n, n - 1).ifft().eval(x);
|
||||
|
||||
let (l_first_x, l_last_x) = eval_l_1_and_l_last(log_n, x);
|
||||
let (l_first_x, l_last_x) = eval_l_0_and_l_last(log_n, x);
|
||||
assert_eq!(l_first_x, expected_l_first_x);
|
||||
assert_eq!(l_last_x, expected_l_last_x);
|
||||
}
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user