Skip to content

Commit

Permalink
Integrate Bitwise Builtin
Browse files Browse the repository at this point in the history
  • Loading branch information
Gali-StarkWare committed Jan 29, 2025
1 parent c2b33a6 commit 045711d
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 22 deletions.
1 change: 1 addition & 0 deletions stwo_cairo_prover/crates/prover/src/cairo_air/air.rs
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ impl CairoClaimGenerator {
tree_builder,
&self.memory_address_to_id_trace_generator,
&self.memory_id_to_value_trace_generator,
&self.verify_bitwise_xor_9_trace_generator,
);
let (verify_bitwise_xor_9_claim, verify_bitwise_xor_9_interaction_gen) = self
.verify_bitwise_xor_9_trace_generator
Expand Down
137 changes: 120 additions & 17 deletions stwo_cairo_prover/crates/prover/src/cairo_air/builtins_air.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use cairo_vm::types::builtin_name::BuiltinName;
use itertools::chain;
use num_traits::Zero;
use serde::{Deserialize, Serialize};
Expand All @@ -12,50 +13,88 @@ use stwo_prover::core::pcs::{TreeBuilder, TreeVec};

use super::air::CairoInteractionElements;
use super::debug_tools::indented_component_display;
use crate::components::{memory_address_to_id, memory_id_to_big, range_check_builtin_bits_128};
use crate::components::{
bitwise_builtin, memory_address_to_id, memory_id_to_big, range_check_builtin_bits_128,
verify_bitwise_xor_9,
};
use crate::input::builtin_segments::BuiltinSegments;

#[derive(Serialize, Deserialize, CairoSerialize)]
pub struct BuiltinsClaim {
pub range_check_128_builtin: Option<range_check_builtin_bits_128::Claim>,
pub bitwise_builtin: Option<bitwise_builtin::Claim>,
}
impl BuiltinsClaim {
pub fn mix_into(&self, channel: &mut impl Channel) {
if let Some(range_check_128_builtin) = &self.range_check_128_builtin {
range_check_128_builtin.mix_into(channel);
}
if let Some(bitwise_builtin) = &self.bitwise_builtin {
bitwise_builtin.mix_into(channel);
}
}

pub fn log_sizes(&self) -> TreeVec<Vec<u32>> {
TreeVec::concat_cols(chain!(self
.range_check_128_builtin
.map(|range_check_128_builtin| range_check_128_builtin.log_sizes())
.into_iter()))
TreeVec::concat_cols(chain!(
self.range_check_128_builtin
.map(|range_check_128_builtin| range_check_128_builtin.log_sizes())
.into_iter(),
self.bitwise_builtin
.map(|bitwise_builtin| bitwise_builtin.log_sizes())
.into_iter(),
))
}
}

pub struct BuiltinsClaimGenerator {
range_check_128_builtin_trace_generator: Option<range_check_builtin_bits_128::ClaimGenerator>,
bitwise_builtin_trace_generator: Option<bitwise_builtin::ClaimGenerator>,
}
impl BuiltinsClaimGenerator {
pub fn new(builtin_segments: BuiltinSegments) -> Self {
let range_check_128_builtin_trace_generator =
builtin_segments
.range_check_bits_128
.map(|range_check_bits_128| {
assert!(
(range_check_bits_128.stop_ptr - range_check_bits_128.begin_addr)
.is_power_of_two(),
"range_check_bits_128 segment length is not a power of two"
);
range_check_builtin_bits_128::ClaimGenerator::new(
(range_check_bits_128.stop_ptr - range_check_bits_128.begin_addr).ilog2(),
range_check_bits_128.begin_addr as u32,
)
});
.range_check_bits_128
.map(|range_check_bits_128| {
let rc128_builtin_cells_per_instance =
BuiltinSegments::builtin_memory_cells_per_instance(BuiltinName::range_check);
assert!(
((range_check_bits_128.stop_ptr - range_check_bits_128.begin_addr) % rc128_builtin_cells_per_instance) == 0,
"range_check_bits_128 segment length is not a multiple of rc128_builtin_cells_per_instance"
);
assert!(
((range_check_bits_128.stop_ptr - range_check_bits_128.begin_addr) / rc128_builtin_cells_per_instance)
.is_power_of_two(),
"range_check_bits_128 instances number is not a power of two"
);
range_check_builtin_bits_128::ClaimGenerator::new(
((range_check_bits_128.stop_ptr - range_check_bits_128.begin_addr) / rc128_builtin_cells_per_instance)
.ilog2(),
range_check_bits_128.begin_addr as u32,
)
});
let bitwise_builtin_trace_generator = builtin_segments.bitwise.map(|bitwise| {
let bitwise_builtin_cells_per_instance =
BuiltinSegments::builtin_memory_cells_per_instance(BuiltinName::bitwise);
assert!(
((bitwise.stop_ptr - bitwise.begin_addr) % bitwise_builtin_cells_per_instance) == 0,
"bitwise segment length is not a multiple of bitwise_builtin_cells_per_instance"
);
assert!(
((bitwise.stop_ptr - bitwise.begin_addr) / bitwise_builtin_cells_per_instance)
.is_power_of_two(),
"bitwise instances number is not a power of two"
);
bitwise_builtin::ClaimGenerator::new(
((bitwise.stop_ptr - bitwise.begin_addr) / bitwise_builtin_cells_per_instance)
.ilog2(),
bitwise.begin_addr as u32,
)
});

Self {
range_check_128_builtin_trace_generator,
bitwise_builtin_trace_generator,
}
}

Expand All @@ -64,6 +103,7 @@ impl BuiltinsClaimGenerator {
tree_builder: &mut TreeBuilder<'_, '_, SimdBackend, MC>,
memory_address_to_id_trace_generator: &memory_address_to_id::ClaimGenerator,
memory_id_to_value_trace_generator: &memory_id_to_big::ClaimGenerator,
verify_bitwise_xor_9_trace_generator: &verify_bitwise_xor_9::ClaimGenerator,
) -> (BuiltinsClaim, BuiltinsInteractionClaimGenerator)
where
SimdBackend: BackendForChannel<MC>,
Expand All @@ -81,12 +121,26 @@ impl BuiltinsClaimGenerator {
} else {
(None, None)
};
let (bitwise_builtin_claim, bitwise_builtin_interaction_gen) =
if let Some(bitwise_builtin_trace_generator) = self.bitwise_builtin_trace_generator {
let (claim, interaction_gen) = bitwise_builtin_trace_generator.write_trace(
tree_builder,
memory_address_to_id_trace_generator,
memory_id_to_value_trace_generator,
verify_bitwise_xor_9_trace_generator,
);
(Some(claim), Some(interaction_gen))
} else {
(None, None)
};
(
BuiltinsClaim {
range_check_128_builtin: range_check_128_builtin_claim,
bitwise_builtin: bitwise_builtin_claim,
},
BuiltinsInteractionClaimGenerator {
range_check_128_builtin_interaction_gen,
bitwise_builtin_interaction_gen,
},
)
}
Expand All @@ -95,26 +149,34 @@ impl BuiltinsClaimGenerator {
#[derive(Serialize, Deserialize, CairoSerialize)]
pub struct BuiltinsInteractionClaim {
pub range_check_128_builtin: Option<range_check_builtin_bits_128::InteractionClaim>,
pub bitwise_builtin: Option<bitwise_builtin::InteractionClaim>,
}
impl BuiltinsInteractionClaim {
pub fn mix_into(&self, channel: &mut impl Channel) {
if let Some(range_check_128_builtin) = self.range_check_128_builtin {
range_check_128_builtin.mix_into(channel)
}
if let Some(bitwise_builtin) = self.bitwise_builtin {
bitwise_builtin.mix_into(channel)
}
}

pub fn sum(&self) -> SecureField {
let mut sum = QM31::zero();
if let Some(range_check_128_builtin) = &self.range_check_128_builtin {
sum += range_check_128_builtin.logup_sums.0;
}
if let Some(bitwise_builtin) = &self.bitwise_builtin {
sum += bitwise_builtin.logup_sums.0;
}
sum
}
}

pub struct BuiltinsInteractionClaimGenerator {
range_check_128_builtin_interaction_gen:
Option<range_check_builtin_bits_128::InteractionClaimGenerator>,
bitwise_builtin_interaction_gen: Option<bitwise_builtin::InteractionClaimGenerator>,
}
impl BuiltinsInteractionClaimGenerator {
pub fn write_interaction_trace<MC: MerkleChannel>(
Expand All @@ -134,14 +196,26 @@ impl BuiltinsInteractionClaimGenerator {
&interaction_elements.memory_id_to_value,
)
});
let bitwise_builtin_interaction_claim =
self.bitwise_builtin_interaction_gen
.map(|bitwise_builtin_interaction_gen| {
bitwise_builtin_interaction_gen.write_interaction_trace(
tree_builder,
&interaction_elements.memory_address_to_id,
&interaction_elements.memory_id_to_value,
&interaction_elements.verify_bitwise_xor_9,
)
});
BuiltinsInteractionClaim {
range_check_128_builtin: range_check_128_builtin_interaction_claim,
bitwise_builtin: bitwise_builtin_interaction_claim,
}
}
}

pub struct BuiltinComponents {
range_check_128_builtin: Option<range_check_builtin_bits_128::Component>,
bitwise_builtin: Option<bitwise_builtin::Component>,
}
impl BuiltinComponents {
pub fn new(
Expand Down Expand Up @@ -171,8 +245,27 @@ impl BuiltinComponents {
.logup_sums,
)
});
let bitwise_builtin_component = claim.bitwise_builtin.map(|bitwise_builtin| {
bitwise_builtin::Component::new(
tree_span_provider,
bitwise_builtin::Eval {
claim: bitwise_builtin,
memory_address_to_id_lookup_elements: interaction_elements
.memory_address_to_id
.clone(),
memory_id_to_big_lookup_elements: interaction_elements
.memory_id_to_value
.clone(),
verify_bitwise_xor_9_lookup_elements: interaction_elements
.verify_bitwise_xor_9
.clone(),
},
interaction_claim.bitwise_builtin.unwrap().logup_sums,
)
});
Self {
range_check_128_builtin: range_check_128_builtin_component,
bitwise_builtin: bitwise_builtin_component,
}
}

Expand All @@ -181,6 +274,9 @@ impl BuiltinComponents {
if let Some(range_check_128_builtin) = &self.range_check_128_builtin {
vec.push(range_check_128_builtin as &dyn ComponentProver<SimdBackend>);
}
if let Some(bitwise_builtin) = &self.bitwise_builtin {
vec.push(bitwise_builtin as &dyn ComponentProver<SimdBackend>);
}
vec
}
}
Expand All @@ -194,6 +290,13 @@ impl std::fmt::Display for BuiltinComponents {
indented_component_display(range_check_128_builtin)
)?;
}
if let Some(bitwise_builtin) = &self.bitwise_builtin {
writeln!(
f,
"BitwiseBuiltin: {}",
indented_component_display(bitwise_builtin)
)?;
}
Ok(())
}
}
26 changes: 21 additions & 5 deletions stwo_cairo_prover/crates/prover/src/cairo_air/debug_tools.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,11 @@ use super::air::CairoClaim;
use crate::components::{
add_ap_opcode, add_ap_opcode_imm, add_ap_opcode_op_1_base_fp, add_opcode, add_opcode_imm,
add_opcode_small, add_opcode_small_imm, assert_eq_opcode, assert_eq_opcode_double_deref,
assert_eq_opcode_imm, call_opcode, call_opcode_op_1_base_fp, call_opcode_rel, generic_opcode,
jnz_opcode, jnz_opcode_dst_base_fp, jnz_opcode_taken, jnz_opcode_taken_dst_base_fp,
jump_opcode, jump_opcode_double_deref, jump_opcode_rel, jump_opcode_rel_imm,
memory_address_to_id, memory_id_to_big, mul_opcode, mul_opcode_imm, range_check_11,
range_check_19, range_check_4_3, range_check_7_2_5, range_check_9_9,
assert_eq_opcode_imm, bitwise_builtin, call_opcode, call_opcode_op_1_base_fp, call_opcode_rel,
generic_opcode, jnz_opcode, jnz_opcode_dst_base_fp, jnz_opcode_taken,
jnz_opcode_taken_dst_base_fp, jump_opcode, jump_opcode_double_deref, jump_opcode_rel,
jump_opcode_rel_imm, memory_address_to_id, memory_id_to_big, mul_opcode, mul_opcode_imm,
range_check_11, range_check_19, range_check_4_3, range_check_7_2_5, range_check_9_9,
range_check_builtin_bits_128, ret_opcode, verify_bitwise_xor_9, verify_instruction,
};
use crate::felt::split_f252;
Expand Down Expand Up @@ -485,6 +485,22 @@ where
);
}

if let Some(bitwise_builtin) = claim.builtins.bitwise_builtin {
entries.extend(
RelationTrackerComponent::new(
tree_span_provider,
bitwise_builtin::Eval {
claim: bitwise_builtin,
memory_address_to_id_lookup_elements: relations::MemoryAddressToId::dummy(),
memory_id_to_big_lookup_elements: relations::MemoryIdToBig::dummy(),
verify_bitwise_xor_9_lookup_elements: relations::VerifyBitwiseXor_9::dummy(),
},
1 << bitwise_builtin.log_size,
)
.entries(trace),
);
}

entries.extend(
RelationTrackerComponent::new(
tree_span_provider,
Expand Down

0 comments on commit 045711d

Please sign in to comment.