Skip to content
This repository was archived by the owner on Apr 18, 2025. It is now read-only.

Add constrain_crt_equals_bytes util function. #1442

Open
wants to merge 9 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
69 changes: 16 additions & 53 deletions aggregator/src/aggregation/batch_data.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use crate::{
aggregation::rlc::POWS_OF_256, blob_consistency::BLOB_WIDTH, constants::N_BYTES_U256,
BatchHash, ChunkInfo, RlcConfig,
blob_consistency::BLOB_WIDTH, constants::N_BYTES_U256, BatchHash, ChunkInfo, RlcConfig,
};
use eth_types::{H256, U256};
use ethers_core::utils::keccak256;
Expand Down Expand Up @@ -401,7 +400,7 @@ impl<const N_SNARKS: usize> BatchDataConfig<N_SNARKS> {
chunks_are_padding: &[AssignedCell<Fr, Fr>],
batch_data: &BatchData<N_SNARKS>,
versioned_hash: H256,
barycentric_assignments: &[CRTInteger<Fr>],
challenge_digest: &CRTInteger<Fr>,
) -> Result<AssignedBatchDataExport, Error> {
self.load_range_tables(layouter)?;

Expand All @@ -418,7 +417,7 @@ impl<const N_SNARKS: usize> BatchDataConfig<N_SNARKS> {
challenge_value,
rlc_config,
chunks_are_padding,
barycentric_assignments,
challenge_digest,
&assigned_rows,
)
},
Expand Down Expand Up @@ -550,7 +549,7 @@ impl<const N_SNARKS: usize> BatchDataConfig<N_SNARKS> {
// The chunks_are_padding assigned cells are exports from the conditional constraints in
// `core.rs`. Since these are already constrained, we can just use them as is.
chunks_are_padding: &[AssignedCell<Fr, Fr>],
barycentric_assignments: &[CRTInteger<Fr>],
assigned_challenge_digest: &CRTInteger<Fr>,
assigned_rows: &[AssignedBatchDataConfig],
) -> Result<AssignedBatchDataExport, Error> {
let n_rows_metadata = BatchData::<N_SNARKS>::n_rows_metadata();
Expand Down Expand Up @@ -579,6 +578,15 @@ impl<const N_SNARKS: usize> BatchDataConfig<N_SNARKS> {
region.constrain_equal(four.cell(), four_cell)?;
four
};
let two_fifty_six = {
let two_fifty_six =
rlc_config.load_private(region, &Fr::from(256), &mut rlc_config_offset)?;
let two_fifty_six_cell = rlc_config
.pow_of_two_hundred_and_fifty_six_cell(two_fifty_six.cell().region_index, 1);
region.constrain_equal(two_fifty_six.cell(), two_fifty_six_cell)?;
two_fifty_six
};

let fixed_chunk_indices = {
let mut fixed_chunk_indices = vec![one.clone()];
for i in 2..=N_SNARKS {
Expand All @@ -594,22 +602,6 @@ impl<const N_SNARKS: usize> BatchDataConfig<N_SNARKS> {
};
let two = fixed_chunk_indices.get(1).expect("N_SNARKS >= 2");
let n_snarks = fixed_chunk_indices.last().expect("N_SNARKS >= 2");
let pows_of_256 = {
let mut pows_of_256 = vec![one.clone()];
for (exponent, pow_of_256) in (1..=POWS_OF_256).zip_eq(
std::iter::successors(Some(Fr::from(256)), |n| Some(n * Fr::from(256)))
.take(POWS_OF_256),
) {
let pow_cell =
rlc_config.load_private(region, &pow_of_256, &mut rlc_config_offset)?;
let fixed_pow_cell = rlc_config
.pow_of_two_hundred_and_fifty_six_cell(pow_cell.cell().region_index, exponent);
region.constrain_equal(pow_cell.cell(), fixed_pow_cell)?;
pows_of_256.push(pow_cell);
}
pows_of_256
};
let two_fifty_six = pows_of_256[1].clone();

// read randomness challenges for RLC computations.
let r_keccak =
Expand Down Expand Up @@ -996,41 +988,12 @@ impl<const N_SNARKS: usize> BatchDataConfig<N_SNARKS> {
////////////////////////////////////////////////////////////////////////////////
//////////////////////////// CHALLENGE DIGEST CHECK ////////////////////////////
////////////////////////////////////////////////////////////////////////////////

assert_eq!(barycentric_assignments.len(), BLOB_WIDTH + 1);
let challenge_digest_crt = barycentric_assignments
.get(BLOB_WIDTH)
.expect("challenge digest CRT");
let challenge_digest_limb1 = rlc_config.inner_product(
rlc_config.constrain_crt_equals_bytes(
region,
&challenge_digest[0..11],
&pows_of_256,
assigned_challenge_digest,
&challenge_digest,
&mut rlc_config_offset,
)?;
let challenge_digest_limb2 = rlc_config.inner_product(
region,
&challenge_digest[11..22],
&pows_of_256,
&mut rlc_config_offset,
)?;
let challenge_digest_limb3 = rlc_config.inner_product(
region,
&challenge_digest[22..32],
&pows_of_256[0..10],
&mut rlc_config_offset,
)?;
region.constrain_equal(
challenge_digest_limb1.cell(),
challenge_digest_crt.truncation.limbs[0].cell(),
)?;
region.constrain_equal(
challenge_digest_limb2.cell(),
challenge_digest_crt.truncation.limbs[1].cell(),
)?;
region.constrain_equal(
challenge_digest_limb3.cell(),
challenge_digest_crt.truncation.limbs[2].cell(),
)?;

Ok(export)
}
Expand Down
5 changes: 2 additions & 3 deletions aggregator/src/aggregation/circuit.rs
Original file line number Diff line number Diff line change
Expand Up @@ -509,7 +509,6 @@ impl<const N_SNARKS: usize> Circuit<Fr> for BatchCircuit<N_SNARKS> {

// blob data config
{
let barycentric_assignments = &barycentric.barycentric_assignments;
let challenge_le = &barycentric.z_le;
let evaluation_le = &barycentric.y_le;

Expand All @@ -525,7 +524,7 @@ impl<const N_SNARKS: usize> Circuit<Fr> for BatchCircuit<N_SNARKS> {
BlobConsistencyConfig::<N_SNARKS>::link(
&mut layouter,
&blob_data_exports.blob_crts_limbs,
barycentric_assignments,
barycentric.blob_crts(),
)?;

let batch_data_exports = config.batch_data_config.assign(
Expand All @@ -535,7 +534,7 @@ impl<const N_SNARKS: usize> Circuit<Fr> for BatchCircuit<N_SNARKS> {
&assigned_batch_hash.chunks_are_padding,
&batch_data,
self.batch_hash.blob_consistency_witness.id(),
barycentric_assignments,
barycentric.challenge_digest(),
)?;

// conditionally encode those bytes. By default we use a worked example.
Expand Down
41 changes: 40 additions & 1 deletion aggregator/src/aggregation/rlc/gates.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
use ethers_core::utils::keccak256;
use halo2_ecc::bigint::CRTInteger;
use halo2_proofs::{
circuit::{AssignedCell, Cell, Region, RegionIndex, Value},
halo2curves::bn256::Fr,
halo2curves::{bn256::Fr, group::ff::PrimeField},
plonk::Error,
};
use itertools::Itertools;
use zkevm_circuits::util::Challenges;

// TODO: remove MAX_AGG_SNARKS and make this generic over N_SNARKS
Expand Down Expand Up @@ -547,4 +549,41 @@ impl RlcConfig {

Ok(())
}

pub fn constrain_crt_equals_bytes(
&self,
region: &mut Region<Fr>,
crt: &CRTInteger<Fr>,
bytes: &[AssignedCell<Fr, Fr>],
offset: &mut usize,
) -> Result<(), Error> {
let mut powers_of_256 = vec![];
for i in 0..11 {
let assigned_cell =
self.load_private(region, &Fr::from_u128(256u128.pow(i)), offset)?;
let region_index = assigned_cell.cell().region_index;
let fixed_cell = if i == 0 {
self.one_cell(region_index)
} else {
self.pow_of_two_hundred_and_fifty_six_cell(
region_index,
usize::try_from(i).unwrap(),
)
};
region.constrain_equal(fixed_cell, assigned_cell.cell())?;
powers_of_256.push(assigned_cell);
}

let limb_from_bytes_lo =
self.inner_product(region, &bytes[0..11], &powers_of_256, offset)?;
let limb_from_bytes_mid =
self.inner_product(region, &bytes[11..22], &powers_of_256, offset)?;
let limb_from_bytes_hi =
self.inner_product(region, &bytes[22..32], &powers_of_256[0..10], offset)?;

[limb_from_bytes_lo, limb_from_bytes_mid, limb_from_bytes_hi]
.iter()
.zip_eq(crt.limbs())
.try_for_each(|(a, b)| region.constrain_equal(a.cell(), b.cell()))
}
}
10 changes: 10 additions & 0 deletions aggregator/src/blob_consistency/avail.rs
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,16 @@ pub struct AssignedBarycentricEvaluationConfig {
pub(crate) y_le: Vec<AssignedValue<Fr>>,
}

impl AssignedBarycentricEvaluationConfig {
pub fn blob_crts(&self) -> &[CRTInteger<Fr>] {
&self.barycentric_assignments[0..BLOB_WIDTH]
}

pub fn challenge_digest(&self) -> &CRTInteger<Fr> {
&self.barycentric_assignments[BLOB_WIDTH]
}
}

/// Get the blob data bytes that will be populated in BlobDataConfig.
pub fn get_blob_bytes(_batch_bytes: &[u8]) -> Vec<u8> {
unimplemented!("trick for linting");
Expand Down
12 changes: 11 additions & 1 deletion aggregator/src/blob_consistency/eip4844/barycentric.rs
Original file line number Diff line number Diff line change
Expand Up @@ -55,13 +55,23 @@ pub struct BarycentricEvaluationConfig {
pub struct AssignedBarycentricEvaluationConfig {
/// CRTIntegers for the BLOB_WIDTH number of blob polynomial coefficients, followed by a
/// CRTInteger for the challenge digest.
pub(crate) barycentric_assignments: Vec<CRTInteger<Fr>>,
barycentric_assignments: Vec<CRTInteger<Fr>>,
/// 32 Assigned cells representing the LE-bytes of challenge z.
pub(crate) z_le: Vec<AssignedValue<Fr>>,
/// 32 Assigned cells representing the LE-bytes of evaluation y.
pub(crate) y_le: Vec<AssignedValue<Fr>>,
}

impl AssignedBarycentricEvaluationConfig {
pub fn blob_crts(&self) -> &[CRTInteger<Fr>] {
&self.barycentric_assignments[0..BLOB_WIDTH]
}

pub fn challenge_digest(&self) -> &CRTInteger<Fr> {
&self.barycentric_assignments[BLOB_WIDTH]
}
}

impl BarycentricEvaluationConfig {
pub fn construct(range: RangeConfig<Fr>) -> Self {
Self {
Expand Down
2 changes: 1 addition & 1 deletion aggregator/src/blob_consistency/eip4844/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -199,7 +199,7 @@ impl Circuit<Fr> for BlobCircuit {
challenge_values,
&config.rlc,
&chunks_are_padding,
&barycentric_assignments.barycentric_assignments,
barycentric_assignments.challenge_digest(),
&assigned_rows,
)?;

Expand Down
Loading