mirror of
https://github.com/logos-storage/plonky2.git
synced 2026-01-10 09:43:09 +00:00
Update check_ctls with extra looking values (#1290)
This commit is contained in:
parent
d89966b076
commit
c9391be024
@ -838,13 +838,13 @@ pub(crate) mod testutils {
|
||||
type MultiSet<F> = HashMap<Vec<F>, Vec<(Table, usize)>>;
|
||||
|
||||
/// Check that the provided traces and cross-table lookups are consistent.
|
||||
#[allow(unused)] // TODO: used later?
|
||||
pub(crate) fn check_ctls<F: Field>(
|
||||
trace_poly_values: &[Vec<PolynomialValues<F>>],
|
||||
cross_table_lookups: &[CrossTableLookup<F>],
|
||||
extra_memory_looking_values: &[Vec<F>],
|
||||
) {
|
||||
for (i, ctl) in cross_table_lookups.iter().enumerate() {
|
||||
check_ctl(trace_poly_values, ctl, i);
|
||||
check_ctl(trace_poly_values, ctl, i, extra_memory_looking_values);
|
||||
}
|
||||
}
|
||||
|
||||
@ -852,6 +852,7 @@ pub(crate) mod testutils {
|
||||
trace_poly_values: &[Vec<PolynomialValues<F>>],
|
||||
ctl: &CrossTableLookup<F>,
|
||||
ctl_index: usize,
|
||||
extra_memory_looking_values: &[Vec<F>],
|
||||
) {
|
||||
let CrossTableLookup {
|
||||
looking_tables,
|
||||
@ -868,6 +869,18 @@ pub(crate) mod testutils {
|
||||
}
|
||||
process_table(trace_poly_values, looked_table, &mut looked_multiset);
|
||||
|
||||
// Extra looking values for memory
|
||||
if ctl_index == Table::Memory as usize {
|
||||
for row in extra_memory_looking_values.iter() {
|
||||
// The table and the row index don't matter here, as we just want to enforce
|
||||
// that the special extra values do appear when looking against the Memory table.
|
||||
looking_multiset
|
||||
.entry(row.to_vec())
|
||||
.or_default()
|
||||
.push((Table::Cpu, 0));
|
||||
}
|
||||
}
|
||||
|
||||
let empty = &vec![];
|
||||
// Check that every row in the looking tables appears in the looked table the same number of times.
|
||||
for (row, looking_locations) in &looking_multiset {
|
||||
|
||||
@ -1,5 +1,3 @@
|
||||
use std::any::type_name;
|
||||
|
||||
use anyhow::{ensure, Result};
|
||||
use itertools::Itertools;
|
||||
use once_cell::sync::Lazy;
|
||||
@ -35,6 +33,10 @@ use crate::lookup::{lookup_helper_columns, Lookup, LookupCheckVars};
|
||||
use crate::proof::{AllProof, PublicValues, StarkOpeningSet, StarkProof, StarkProofWithMetadata};
|
||||
use crate::stark::Stark;
|
||||
use crate::vanishing_poly::eval_vanishing_poly;
|
||||
#[cfg(test)]
|
||||
use crate::{
|
||||
cross_table_lookup::testutils::check_ctls, verifier::testutils::get_memory_extra_looking_values,
|
||||
};
|
||||
|
||||
/// Generate traces, then create all STARK proofs.
|
||||
pub fn prove<F, C, const D: usize>(
|
||||
@ -142,7 +144,7 @@ where
|
||||
prove_with_commitments(
|
||||
all_stark,
|
||||
config,
|
||||
trace_poly_values,
|
||||
&trace_poly_values,
|
||||
trace_commitments,
|
||||
ctl_data_per_table,
|
||||
&mut challenger,
|
||||
@ -151,6 +153,15 @@ where
|
||||
)?
|
||||
);
|
||||
|
||||
#[cfg(test)]
|
||||
{
|
||||
check_ctls(
|
||||
&trace_poly_values,
|
||||
&all_stark.cross_table_lookups,
|
||||
&get_memory_extra_looking_values(&public_values),
|
||||
);
|
||||
}
|
||||
|
||||
Ok(AllProof {
|
||||
stark_proofs,
|
||||
ctl_challenges,
|
||||
@ -161,7 +172,7 @@ where
|
||||
fn prove_with_commitments<F, C, const D: usize>(
|
||||
all_stark: &AllStark<F, D>,
|
||||
config: &StarkConfig,
|
||||
trace_poly_values: [Vec<PolynomialValues<F>>; NUM_TABLES],
|
||||
trace_poly_values: &[Vec<PolynomialValues<F>>; NUM_TABLES],
|
||||
trace_commitments: Vec<PolynomialBatch<F, C, D>>,
|
||||
ctl_data_per_table: [CtlData<F>; NUM_TABLES],
|
||||
challenger: &mut Challenger<F, C::Hasher>,
|
||||
@ -365,7 +376,9 @@ where
|
||||
challenger.observe_cap(&auxiliary_polys_cap);
|
||||
|
||||
let alphas = challenger.get_n_challenges(config.num_challenges);
|
||||
if cfg!(test) {
|
||||
|
||||
#[cfg(test)]
|
||||
{
|
||||
check_constraints(
|
||||
stark,
|
||||
trace_commitment,
|
||||
@ -378,6 +391,7 @@ where
|
||||
num_lookup_columns,
|
||||
);
|
||||
}
|
||||
|
||||
let quotient_polys = timed!(
|
||||
timing,
|
||||
"compute quotient polys",
|
||||
@ -606,6 +620,7 @@ where
|
||||
.collect()
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
/// Check that all constraints evaluate to zero on `H`.
|
||||
/// Can also be used to check the degree of the constraints by evaluating on a larger subgroup.
|
||||
fn check_constraints<'a, F, C, S, const D: usize>(
|
||||
@ -705,7 +720,7 @@ fn check_constraints<'a, F, C, S, const D: usize>(
|
||||
assert!(
|
||||
v.iter().all(|x| x.is_zero()),
|
||||
"Constraint failed in {}",
|
||||
type_name::<S>()
|
||||
std::any::type_name::<S>()
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@ -455,6 +455,152 @@ fn eval_l_0_and_l_last<F: Field>(log_n: usize, x: F) -> (F, F) {
|
||||
(z_x * invs[0], z_x * invs[1])
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
pub(crate) mod testutils {
|
||||
use super::*;
|
||||
|
||||
/// Output all the extra memory rows that don't appear in the CPU trace but are
|
||||
/// necessary to correctly check the MemoryStark CTL.
|
||||
pub(crate) fn get_memory_extra_looking_values<F, const D: usize>(
|
||||
public_values: &PublicValues,
|
||||
) -> Vec<Vec<F>>
|
||||
where
|
||||
F: RichField + Extendable<D>,
|
||||
{
|
||||
// Add metadata and tries writes.
|
||||
let fields = [
|
||||
(
|
||||
GlobalMetadata::BlockBeneficiary,
|
||||
U256::from_big_endian(&public_values.block_metadata.block_beneficiary.0),
|
||||
),
|
||||
(
|
||||
GlobalMetadata::BlockTimestamp,
|
||||
public_values.block_metadata.block_timestamp,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::BlockNumber,
|
||||
public_values.block_metadata.block_number,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::BlockRandom,
|
||||
public_values.block_metadata.block_random.into_uint(),
|
||||
),
|
||||
(
|
||||
GlobalMetadata::BlockDifficulty,
|
||||
public_values.block_metadata.block_difficulty,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::BlockGasLimit,
|
||||
public_values.block_metadata.block_gaslimit,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::BlockChainId,
|
||||
public_values.block_metadata.block_chain_id,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::BlockBaseFee,
|
||||
public_values.block_metadata.block_base_fee,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::BlockCurrentHash,
|
||||
h2u(public_values.block_hashes.cur_hash),
|
||||
),
|
||||
(
|
||||
GlobalMetadata::BlockGasUsed,
|
||||
public_values.block_metadata.block_gas_used,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::TxnNumberBefore,
|
||||
public_values.extra_block_data.txn_number_before,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::TxnNumberAfter,
|
||||
public_values.extra_block_data.txn_number_after,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::BlockGasUsedBefore,
|
||||
public_values.extra_block_data.gas_used_before,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::BlockGasUsedAfter,
|
||||
public_values.extra_block_data.gas_used_after,
|
||||
),
|
||||
(
|
||||
GlobalMetadata::StateTrieRootDigestBefore,
|
||||
h2u(public_values.trie_roots_before.state_root),
|
||||
),
|
||||
(
|
||||
GlobalMetadata::TransactionTrieRootDigestBefore,
|
||||
h2u(public_values.trie_roots_before.transactions_root),
|
||||
),
|
||||
(
|
||||
GlobalMetadata::ReceiptTrieRootDigestBefore,
|
||||
h2u(public_values.trie_roots_before.receipts_root),
|
||||
),
|
||||
(
|
||||
GlobalMetadata::StateTrieRootDigestAfter,
|
||||
h2u(public_values.trie_roots_after.state_root),
|
||||
),
|
||||
(
|
||||
GlobalMetadata::TransactionTrieRootDigestAfter,
|
||||
h2u(public_values.trie_roots_after.transactions_root),
|
||||
),
|
||||
(
|
||||
GlobalMetadata::ReceiptTrieRootDigestAfter,
|
||||
h2u(public_values.trie_roots_after.receipts_root),
|
||||
),
|
||||
];
|
||||
|
||||
let segment = F::from_canonical_u32(Segment::GlobalMetadata as u32);
|
||||
let mut extra_looking_rows = Vec::new();
|
||||
|
||||
fields.map(|(field, val)| {
|
||||
extra_looking_rows.push(add_extra_looking_row(segment, field as usize, val))
|
||||
});
|
||||
|
||||
// Add block bloom writes.
|
||||
let bloom_segment = F::from_canonical_u32(Segment::GlobalBlockBloom as u32);
|
||||
for index in 0..8 {
|
||||
let val = public_values.block_metadata.block_bloom[index];
|
||||
extra_looking_rows.push(add_extra_looking_row(bloom_segment, index, val));
|
||||
}
|
||||
|
||||
for index in 0..8 {
|
||||
let val = public_values.extra_block_data.block_bloom_before[index];
|
||||
extra_looking_rows.push(add_extra_looking_row(bloom_segment, index + 8, val));
|
||||
}
|
||||
for index in 0..8 {
|
||||
let val = public_values.extra_block_data.block_bloom_after[index];
|
||||
extra_looking_rows.push(add_extra_looking_row(bloom_segment, index + 16, val));
|
||||
}
|
||||
|
||||
// Add Blockhashes writes.
|
||||
let block_hashes_segment = F::from_canonical_u32(Segment::BlockHashes as u32);
|
||||
for index in 0..256 {
|
||||
let val = h2u(public_values.block_hashes.prev_hashes[index]);
|
||||
extra_looking_rows.push(add_extra_looking_row(block_hashes_segment, index, val));
|
||||
}
|
||||
|
||||
extra_looking_rows
|
||||
}
|
||||
|
||||
fn add_extra_looking_row<F, const D: usize>(segment: F, index: usize, val: U256) -> Vec<F>
|
||||
where
|
||||
F: RichField + Extendable<D>,
|
||||
{
|
||||
let mut row = vec![F::ZERO; 13];
|
||||
row[0] = F::ZERO; // is_read
|
||||
row[1] = F::ZERO; // context
|
||||
row[2] = segment;
|
||||
row[3] = F::from_canonical_usize(index);
|
||||
|
||||
for j in 0..VALUE_LIMBS {
|
||||
row[j + 4] = F::from_canonical_u32((val >> (j * 32)).low_u32());
|
||||
}
|
||||
row[12] = F::ONE; // timestamp
|
||||
row
|
||||
}
|
||||
}
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use plonky2::field::goldilocks_field::GoldilocksField;
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user