From 226c4755674a3177f5ef532efcd5a0d899af03a7 Mon Sep 17 00:00:00 2001 From: Gali Michlevich Date: Tue, 28 Jan 2025 17:47:26 +0200 Subject: [PATCH] Integrate Bitwise Builtin --- .../crates/prover/src/cairo_air/air.rs | 1 + .../prover/src/cairo_air/builtins_air.rs | 95 ++++++++++++++++++- .../prover/src/cairo_air/debug_tools.rs | 24 ++--- 3 files changed, 106 insertions(+), 14 deletions(-) diff --git a/stwo_cairo_prover/crates/prover/src/cairo_air/air.rs b/stwo_cairo_prover/crates/prover/src/cairo_air/air.rs index b520eddc..677c2432 100644 --- a/stwo_cairo_prover/crates/prover/src/cairo_air/air.rs +++ b/stwo_cairo_prover/crates/prover/src/cairo_air/air.rs @@ -256,6 +256,7 @@ impl CairoClaimGenerator { &self.memory_address_to_id_trace_generator, &self.memory_id_to_value_trace_generator, &self.range_checks_trace_generator.rc_6_trace_generator, + &self.verify_bitwise_xor_9_trace_generator, ); let (memory_address_to_id_claim, memory_address_to_id_interaction_gen) = self .memory_address_to_id_trace_generator diff --git a/stwo_cairo_prover/crates/prover/src/cairo_air/builtins_air.rs b/stwo_cairo_prover/crates/prover/src/cairo_air/builtins_air.rs index cd3c3721..8554e5d0 100644 --- a/stwo_cairo_prover/crates/prover/src/cairo_air/builtins_air.rs +++ b/stwo_cairo_prover/crates/prover/src/cairo_air/builtins_air.rs @@ -14,8 +14,8 @@ 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_6, range_check_builtin_bits_128, - range_check_builtin_bits_96, + bitwise_builtin, memory_address_to_id, memory_id_to_big, range_check_6, + range_check_builtin_bits_128, range_check_builtin_bits_96, verify_bitwise_xor_9, }; use crate::input::builtin_segments::BuiltinSegments; @@ -23,6 +23,7 @@ use crate::input::builtin_segments::BuiltinSegments; pub struct BuiltinsClaim { pub range_check_128_builtin: Option, pub range_check_96_builtin: Option, + pub bitwise_builtin: Option, } impl BuiltinsClaim { pub fn mix_into(&self, channel: &mut impl Channel) { @@ -32,6 +33,9 @@ impl BuiltinsClaim { if let Some(range_check_96_builtin) = &self.range_check_96_builtin { range_check_96_builtin.mix_into(channel); } + if let Some(bitwise_builtin) = &self.bitwise_builtin { + bitwise_builtin.mix_into(channel); + } } pub fn log_sizes(&self) -> TreeVec> { @@ -42,6 +46,9 @@ impl BuiltinsClaim { self.range_check_96_builtin .map(|range_check_96_builtin| range_check_96_builtin.log_sizes()) .into_iter(), + self.bitwise_builtin + .map(|bitwise_builtin| bitwise_builtin.log_sizes()) + .into_iter(), )) } } @@ -49,6 +56,7 @@ impl BuiltinsClaim { pub struct BuiltinsClaimGenerator { range_check_128_builtin_trace_generator: Option, range_check_96_builtin_trace_generator: Option, + bitwise_builtin_trace_generator: Option, } impl BuiltinsClaimGenerator { pub fn new(builtin_segments: BuiltinSegments) -> Self { @@ -96,10 +104,29 @@ impl BuiltinsClaimGenerator { range_check_bits_96.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, range_check_96_builtin_trace_generator, + bitwise_builtin_trace_generator, } } @@ -109,6 +136,7 @@ impl BuiltinsClaimGenerator { memory_address_to_id_trace_generator: &memory_address_to_id::ClaimGenerator, memory_id_to_value_trace_generator: &memory_id_to_big::ClaimGenerator, range_check_6_trace_generator: &range_check_6::ClaimGenerator, + verify_bitwise_xor_9_trace_generator: &verify_bitwise_xor_9::ClaimGenerator, ) -> (BuiltinsClaim, BuiltinsInteractionClaimGenerator) where SimdBackend: BackendForChannel, @@ -140,14 +168,28 @@ 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, range_check_96_builtin: range_check_96_builtin_claim, + bitwise_builtin: bitwise_builtin_claim, }, BuiltinsInteractionClaimGenerator { range_check_128_builtin_interaction_gen, range_check_96_builtin_interaction_gen, + bitwise_builtin_interaction_gen, }, ) } @@ -157,6 +199,7 @@ impl BuiltinsClaimGenerator { pub struct BuiltinsInteractionClaim { pub range_check_128_builtin: Option, pub range_check_96_builtin: Option, + pub bitwise_builtin: Option, } impl BuiltinsInteractionClaim { pub fn mix_into(&self, channel: &mut impl Channel) { @@ -166,6 +209,9 @@ impl BuiltinsInteractionClaim { if let Some(range_check_96_builtin) = &self.range_check_96_builtin { range_check_96_builtin.mix_into(channel); } + if let Some(bitwise_builtin) = self.bitwise_builtin { + bitwise_builtin.mix_into(channel) + } } pub fn sum(&self) -> SecureField { @@ -176,6 +222,9 @@ impl BuiltinsInteractionClaim { if let Some(range_check_96_builtin) = &self.range_check_96_builtin { sum += range_check_96_builtin.claimed_sum; } + if let Some(bitwise_builtin) = &self.bitwise_builtin { + sum += bitwise_builtin.claimed_sum; + } sum } } @@ -185,6 +234,7 @@ pub struct BuiltinsInteractionClaimGenerator { Option, range_check_96_builtin_interaction_gen: Option, + bitwise_builtin_interaction_gen: Option, } impl BuiltinsInteractionClaimGenerator { pub fn write_interaction_trace( @@ -214,9 +264,20 @@ impl BuiltinsInteractionClaimGenerator { &interaction_elements.range_checks.rc_6, ) }); + 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, range_check_96_builtin: range_check_96_builtin_interaction_claim, + bitwise_builtin: bitwise_builtin_interaction_claim, } } } @@ -224,6 +285,7 @@ impl BuiltinsInteractionClaimGenerator { pub struct BuiltinComponents { range_check_128_builtin: Option, range_check_96_builtin: Option, + bitwise_builtin: Option, } impl BuiltinComponents { pub fn new( @@ -276,9 +338,28 @@ impl BuiltinComponents { .claimed_sum, ) }); + 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().claimed_sum, + ) + }); Self { range_check_128_builtin: range_check_128_builtin_component, range_check_96_builtin: range_check_96_builtin_component, + bitwise_builtin: bitwise_builtin_component, } } @@ -290,6 +371,9 @@ impl BuiltinComponents { if let Some(range_check_96_builtin) = &self.range_check_96_builtin { vec.push(range_check_96_builtin as &dyn ComponentProver); } + if let Some(bitwise_builtin) = &self.bitwise_builtin { + vec.push(bitwise_builtin as &dyn ComponentProver); + } vec } } @@ -310,6 +394,13 @@ impl std::fmt::Display for BuiltinComponents { indented_component_display(range_check_96_builtin) )?; } + if let Some(bitwise_builtin) = &self.bitwise_builtin { + writeln!( + f, + "BitwiseBuiltin: {}", + indented_component_display(bitwise_builtin) + )?; + } Ok(()) } } diff --git a/stwo_cairo_prover/crates/prover/src/cairo_air/debug_tools.rs b/stwo_cairo_prover/crates/prover/src/cairo_air/debug_tools.rs index f773f5ca..5109125b 100644 --- a/stwo_cairo_prover/crates/prover/src/cairo_air/debug_tools.rs +++ b/stwo_cairo_prover/crates/prover/src/cairo_air/debug_tools.rs @@ -17,13 +17,13 @@ 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_6, range_check_7_2_5, range_check_9_9, - range_check_builtin_bits_128, range_check_builtin_bits_96, ret_opcode, verify_bitwise_xor_9, - verify_instruction, + 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_6, range_check_7_2_5, + range_check_9_9, range_check_builtin_bits_128, range_check_builtin_bits_96, ret_opcode, + verify_bitwise_xor_9, verify_instruction, }; use crate::felt::split_f252; use crate::relations; @@ -502,17 +502,17 @@ where ); } - if let Some(range_check_96_builtin) = claim.builtins.range_check_96_builtin { + if let Some(bitwise_builtin) = claim.builtins.bitwise_builtin { entries.extend( RelationTrackerComponent::new( tree_span_provider, - range_check_builtin_bits_96::Eval { - claim: range_check_96_builtin, + bitwise_builtin::Eval { + claim: bitwise_builtin, memory_address_to_id_lookup_elements: relations::MemoryAddressToId::dummy(), memory_id_to_big_lookup_elements: relations::MemoryIdToBig::dummy(), - range_check_6_lookup_elements: relations::RangeCheck_6::dummy(), + verify_bitwise_xor_9_lookup_elements: relations::VerifyBitwiseXor_9::dummy(), }, - 1 << range_check_96_builtin.log_size, + 1 << bitwise_builtin.log_size, ) .entries(trace), );