Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add preprocessed traces of various log size #104

Merged
merged 3 commits into from
Dec 2, 2024
Merged
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
47 changes: 38 additions & 9 deletions crates/brainfuck_prover/src/brainfuck_air/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@ use crate::components::{
use brainfuck_vm::machine::Machine;
use stwo_prover::{
constraint_framework::{
preprocessed_columns::PreprocessedColumn, TraceLocationAllocator, INTERACTION_TRACE_IDX,
ORIGINAL_TRACE_IDX, PREPROCESSED_TRACE_IDX,
preprocessed_columns::{gen_is_first, PreprocessedColumn},
TraceLocationAllocator, INTERACTION_TRACE_IDX, ORIGINAL_TRACE_IDX, PREPROCESSED_TRACE_IDX,
},
core::{
air::{Component, ComponentProver},
Expand Down Expand Up @@ -49,7 +49,13 @@ impl BrainfuckClaim {
}

pub fn log_sizes(&self) -> TreeVec<Vec<u32>> {
self.memory.log_sizes()
let mut log_sizes = self.memory.log_sizes();

// We overwrite the preprocessed column claim to have all log sizes
// in the merkle root for the verification.
log_sizes[PREPROCESSED_TRACE_IDX] = IS_FIRST_LOG_SIZES.to_vec();

log_sizes
}
}

Expand Down Expand Up @@ -105,10 +111,13 @@ impl BrainfuckComponents {
interaction_elements: &BrainfuckInteractionElements,
interaction_claim: &BrainfuckInteractionClaim,
) -> Self {
let memory_is_first_column = PreprocessedColumn::IsFirst(claim.memory.log_size);

let tree_span_provider =
&mut TraceLocationAllocator::new_with_preproccessed_columnds(&[memory_is_first_column]);
let tree_span_provider = &mut TraceLocationAllocator::new_with_preproccessed_columnds(
&IS_FIRST_LOG_SIZES
.iter()
.copied()
.map(PreprocessedColumn::IsFirst)
.collect::<Vec<_>>(),
);

let memory = MemoryComponent::new(
tree_span_provider,
Expand Down Expand Up @@ -139,6 +148,22 @@ impl BrainfuckComponents {
/// Means that the ZK-VM does not accept programs with more than 2^20 steps (1M steps).
const LOG_MAX_ROWS: u32 = 20;

/// Log sizes of the preprocessed columns
/// used for enforcing boundary constraints.
///
/// Preprocessed columns are generated ahead of time,
/// so at this moment we don't know the log size
/// of the main and interaction traces.
///
/// Therefore, we generate all log sizes that we
/// want to support, so that the verifier can be
/// provided a merkle root it can trust, for a claim
/// of any dynamic size.
///
/// Ideally, we should cover all possible log sizes, between
/// 1 and `LOG_MAX_ROW`
const IS_FIRST_LOG_SIZES: [u32; 4] = [10, 9, 8, 5];

/// Generate a STARK proof of the given Brainfuck program execution.
///
/// # Arguments
Expand All @@ -165,8 +190,12 @@ pub fn prove_brainfuck(
// │ Interaction Phase 0 - Preprocessed Trace │
// └───────────────────────────────────────────────┘

// Generate constant columns (e.g. is_first)
let tree_builder = commitment_scheme.tree_builder();
// Generate all preprocessed columns
let mut tree_builder = commitment_scheme.tree_builder();

tree_builder.extend_evals(IS_FIRST_LOG_SIZES.iter().copied().map(gen_is_first::<SimdBackend>));

// Commit the preprocessed trace
tree_builder.commit(channel);

// ┌───────────────────────────────────────┐
Expand Down
2 changes: 1 addition & 1 deletion crates/brainfuck_prover/src/components/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,7 @@ impl<T: TraceColumn> Claim<T> {
/// NOTE: Currently only the main trace is provided.
pub fn log_sizes(&self) -> TreeVec<Vec<u32>> {
// TODO: Add the preprocessed and interaction trace correct sizes
let preprocessed_trace_log_sizes: Vec<u32> = vec![];
let preprocessed_trace_log_sizes: Vec<u32> = vec![self.log_size];
let trace_log_sizes = vec![self.log_size; T::count()];
let interaction_trace_log_sizes: Vec<u32> = vec![];
TreeVec::new(vec![
Expand Down
Loading