Skip to content

Commit

Permalink
Bring back the range check
Browse files Browse the repository at this point in the history
  • Loading branch information
alxkzmn committed Feb 1, 2024
1 parent 1a51248 commit b9955c3
Show file tree
Hide file tree
Showing 5 changed files with 94 additions and 78 deletions.
16 changes: 14 additions & 2 deletions kzg_prover/benches/kzg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,8 @@ use summa_solvency::{
circuits::{
univariate_grand_sum::UnivariateGrandSum,
utils::{
full_prover, generate_setup_artifacts, open_grand_sums, open_user_points,
verify_grand_sum_openings, verify_user_inclusion,
batch_open_user_points, full_prover, generate_setup_artifacts, open_grand_sums,
open_user_points, verify_grand_sum_openings, verify_user_inclusion,
},
},
cryptocurrency::Cryptocurrency,
Expand All @@ -32,6 +32,8 @@ fn bench_kzg<const K: u32, const N_USERS: usize, const N_CURRENCIES: usize, cons
let range_check_bench_name = format!("<{}> range check", name);
let opening_grand_sum_bench_name = format!("<{}> opening grand sum", name);
let opening_user_bench_name = format!("<{}> opening user inclusion", name);
let batch_opening_user_bench_name =
format!("<{}> batch opening all 2^{} user inclusions", name, K);
let verifying_grand_sum_bench_name = format!("<{}> verifying grand sum", name);
let verifying_user_bench_name = format!("<{}> verifying user inclusion", name);

Expand Down Expand Up @@ -115,6 +117,16 @@ fn bench_kzg<const K: u32, const N_USERS: usize, const N_CURRENCIES: usize, cons
);
});

c.bench_function(&batch_opening_user_bench_name, |b| {
b.iter_batched(
|| (0..N_CURRENCIES + 1),
|column_range| {
batch_open_user_points(&advice_polys.advice_polys, &params, column_range, omega)
},
criterion::BatchSize::SmallInput,
);
});

// Open grand sum for benchmark verifying grand sum
let balance_column_range = 1..N_CURRENCIES + 1;
let grand_sums_batch_proof = open_grand_sums(
Expand Down
8 changes: 2 additions & 6 deletions kzg_prover/src/circuits/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,10 +18,9 @@ mod test {
use halo2_proofs::halo2curves::group::Curve;
use halo2_proofs::plonk::{Any, ProvingKey, VerifyingKey};
use halo2_proofs::poly::kzg::commitment::{KZGCommitmentScheme, ParamsKZG};
use halo2_proofs::poly::EvaluationDomain;
use num_bigint::BigUint;

const K: u32 = 9;
const K: u32 = 17;
const N_CURRENCIES: usize = 2;
const N_USERS: usize = 16;

Expand All @@ -35,10 +34,6 @@ mod test {

let f_poly = advice_polys.advice_polys.get(1).unwrap();

// Double the polynomial length, thus K + 1
let double_domain = EvaluationDomain::new(1, K + 1);
let mut h = compute_h(&params, f_poly, &double_domain);

let kzg_commitment = commit_kzg(&params, &f_poly);

// Open the polynomial at X = omega^1 (user 1) using the standard KZG
Expand Down Expand Up @@ -72,6 +67,7 @@ mod test {
);
println!("KZG proof verified");

let mut h = compute_h(&params, f_poly);
// Compute all openings to the polynomial using the amortized KZG approach (FK23)
best_fft(&mut h, omega, f_poly.len().trailing_zeros());

Expand Down
90 changes: 45 additions & 45 deletions kzg_prover/src/circuits/univariate_grand_sum.rs
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@ where
{
username: Column<Advice>,
balances: [Column<Advice>; N_CURRENCIES],
// range_check_configs: [RangeCheckU64Config; N_CURRENCIES],
range_check_configs: [RangeCheckU64Config; N_CURRENCIES],
range_u16: Column<Fixed>,
}

Expand All @@ -65,29 +65,29 @@ where
meta.annotate_lookup_any_column(range_u16, || "LOOKUP_MAXBITS_RANGE");

// Create an empty array of range check configs
// let mut range_check_configs = Vec::with_capacity(N_CURRENCIES);
let mut range_check_configs = Vec::with_capacity(N_CURRENCIES);

// for item in balances.iter().take(N_CURRENCIES) {
// let z = *item;
// // Create 4 advice columns for each range check chip
// let zs = [(); 4].map(|_| meta.advice_column());
for item in balances.iter().take(N_CURRENCIES) {
let z = *item;
// Create 4 advice columns for each range check chip
let zs = [(); 4].map(|_| meta.advice_column());

// for column in &zs {
// meta.enable_equality(*column);
// }
for column in &zs {
meta.enable_equality(*column);
}

// let range_check_config = RangeCheckU64Chip::configure(meta, z, zs, range_u16);
let range_check_config = RangeCheckU64Chip::configure(meta, z, zs, range_u16);

// range_check_configs.push(range_check_config);
// }
range_check_configs.push(range_check_config);
}

let instance = meta.instance_column();
meta.enable_equality(instance);

Self {
username,
balances,
// range_check_configs: range_check_configs.try_into().unwrap(),
range_check_configs: range_check_configs.try_into().unwrap(),
range_u16,
}
}
Expand Down Expand Up @@ -157,46 +157,46 @@ where
mut layouter: impl Layouter<Fp>,
) -> Result<(), Error> {
// Initiate the range check chips
// let range_check_chips = config
// .range_check_configs
// .iter()
// .map(|config| RangeCheckU64Chip::construct(*config))
// .collect::<Vec<_>>();
let range_check_chips = config
.range_check_configs
.iter()
.map(|config| RangeCheckU64Chip::construct(*config))
.collect::<Vec<_>>();

// Load lookup table for range check u64 chip
// let range = 1 << 16;

// layouter.assign_region(
// || format!("load range check table of 16 bits"),
// |mut region| {
// for i in 0..range {
// region.assign_fixed(
// || "assign cell in fixed column",
// config.range_u16,
// i,
// || Value::known(Fp::from(i as u64)),
// )?;
// }
// Ok(())
// },
// )?;
let range = 1 << 16;

layouter.assign_region(
|| format!("load range check table of 16 bits"),
|mut region| {
for i in 0..range {
region.assign_fixed(
|| "assign cell in fixed column",
config.range_u16,
i,
|| Value::known(Fp::from(i as u64)),
)?;
}
Ok(())
},
)?;

// Assign entries
let assigned_balances =
config.assign_entries(layouter.namespace(|| "assign entries"), &self.entries)?;

// Perform range check on the assigned balances
// for i in 0..N_USERS {
// for j in 0..N_CURRENCIES {
// layouter.assign_region(
// || format!("Perform range check on balance {} of user {}", j, i),
// |mut region| {
// range_check_chips[j].assign(&mut region, &assigned_balances[i][j])?;
// Ok(())
// },
// )?;
// }
// }
for i in 0..N_USERS {
for j in 0..N_CURRENCIES {
layouter.assign_region(
|| format!("Perform range check on balance {} of user {}", j, i),
|mut region| {
range_check_chips[j].assign(&mut region, &assigned_balances[i][j])?;
Ok(())
},
)?;
}
}

Ok(())
}
Expand Down
25 changes: 22 additions & 3 deletions kzg_prover/src/circuits/utils.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@ use std::{fs::File, ops::Range};
use ark_std::{end_timer, start_timer};
use ethers::types::U256;
use halo2_proofs::{
arithmetic::Field,
arithmetic::{best_fft, Field},
halo2curves::{
bn256::{Bn256, Fr as Fp, G1Affine},
bn256::{Bn256, Fr as Fp, G1Affine, G1},
ff::{PrimeField, WithSmallOrderMulGroup},
},
plonk::{
Expand All @@ -28,8 +28,9 @@ use halo2_proofs::{
};
use num_bigint::BigUint;
use rand::rngs::OsRng;
use rayon::prelude::*;

use crate::utils::fp_to_big_uint;
use crate::utils::{batched_kzg::compute_h, fp_to_big_uint};

/// Generate setup artifacts for a circuit of size `k`, where 2^k represents the number of rows in the circuit.
///
Expand Down Expand Up @@ -198,6 +199,24 @@ pub fn open_user_points(
)
}

pub fn batch_open_user_points(
advice_polys: &[Polynomial<Fp, Coeff>],
params: &ParamsKZG<Bn256>,
column_range: Range<usize>,
omega: Fp,
) -> Vec<G1> {
// Use Rayon's par_iter() to iterate over the slice in parallel
advice_polys[column_range]
.par_iter()
.map(|poly| {
let mut h = compute_h(params, poly);
best_fft(&mut h, omega, poly.len().trailing_zeros());
h
})
.flatten() // Flatten to combine all the h vectors into one
.collect()
}

/// Verifies the univariate polynomial grand sum openings
/// and calculates the grand sums
///
Expand Down
33 changes: 11 additions & 22 deletions kzg_prover/src/utils/batched_kzg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use halo2_proofs::{
pairing::{Engine, PairingCurveAffine},
},
poly::{
commitment::{Blind, CommitmentScheme, ParamsProver},
commitment::{Blind, CommitmentScheme, Params, ParamsProver},
kzg::commitment::ParamsKZG,
Coeff, EvaluationDomain, Polynomial,
},
Expand All @@ -17,14 +17,12 @@ pub fn commit_kzg(params: &ParamsKZG<Bn256>, poly: &Polynomial<Fp, Coeff>) -> G1
}

/// Computes the polynomial h(X) for the batch KZG algorithm.
pub fn compute_h(
params: &ParamsKZG<Bn256>,
f_poly: &Polynomial<Fp, Coeff>,
double_domain: &EvaluationDomain<Fp>,
) -> Vec<G1> {
pub fn compute_h(params: &ParamsKZG<Bn256>, f_poly: &Polynomial<Fp, Coeff>) -> Vec<G1> {
// Double the polynomial length, thus K + 1
let double_domain = EvaluationDomain::new(1, params.k() + 1);

let d = f_poly.len(); // Degree of the polynomial

println!("d: {}", d);
// Extract s_commitments from ParamsKZG and extend with neutral elements
let mut s_commitments_reversed = params
.get_g()
Expand All @@ -38,30 +36,21 @@ pub fn compute_h(

// Prepare coefficients vector and zero-pad at the beginning
let mut v = vec![Fp::zero(); 2 * d];
v[d..(2 * d)].copy_from_slice(&f_poly);
v[d..(2 * d)].copy_from_slice(f_poly);

println!("c_fft and s_fft assigned");
let nu = double_domain.get_omega(); // 2d-th root of unity
println!("performing FFT on s");
// Perform FFT on s
best_fft(&mut y, nu, (2 * d).trailing_zeros());
println!("performing FFT on c");
// Perform FFT on c
best_fft(&mut v, nu, (2 * d).trailing_zeros());

println!("Computing powers of nu");
// Compute powers of nu
let mut nu_powers = vec![Fp::one(); 2 * d];
for i in 1..(2 * d) {
nu_powers[i] = nu_powers[i - 1] * nu;
}

println!("Performing Hadamard product");
// Perform the Hadamard product
let u: Vec<G1> = y.iter().zip(v.iter()).map(|(&y, &v)| y * v).collect();

// Perform inverse FFT
let nu_inv = nu.invert().unwrap(); // Inverse of 2d-th root of unity
let mut h = u;
println!("Performing inverse FFT on h");
// Perform inverse FFT on h
best_fft(&mut h, nu_inv, (2 * d).trailing_zeros());

// Scale the result by the size of the vector (part of the iFFT)
Expand All @@ -84,7 +73,7 @@ pub fn create_standard_kzg_proof<
f_poly: &Polynomial<<Scheme as CommitmentScheme>::Scalar, Coeff>,
challenge: Fp,
) -> G1 {
let z = eval_polynomial(&f_poly, challenge);
let z = eval_polynomial(f_poly, challenge);
let numerator = f_poly - z;
let mut t_y_vals = kate_division(&numerator.to_vec(), challenge);
// The resulting degree is one less than the degree of the numerator, so we need to pad it with zeros back to the original polynomial size
Expand All @@ -103,7 +92,7 @@ where
let c_g_to_minus_z: G1 = c + g_to_minus_z;
let left_side = Bn256::pairing(&c_g_to_minus_z.to_affine(), &G2Affine::generator());

let g_to_minus_y = G2Affine::generator() * &(-challenge);
let g_to_minus_y = G2Affine::generator() * (-challenge);
let g_tau = params.s_g2();
let g_tau_g_to_minus_y = g_tau + g_to_minus_y;
let right_side = Bn256::pairing(&pi.to_affine(), &g_tau_g_to_minus_y.to_affine());
Expand Down

0 comments on commit b9955c3

Please sign in to comment.