Skip to content
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
16 changes: 8 additions & 8 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

10 changes: 5 additions & 5 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -43,11 +43,11 @@ stwo-air-utils-derive = { version = "2.2.0" }
stwo-air-utils = { version = "2.2.0" }

# stwo-cairo
cairo-air = { git = "https://github.com/starkware-libs/stwo-cairo", rev = "8a3950c2" }
stwo_cairo_prover = { package = "stwo-cairo-prover", git = "https://github.com/starkware-libs/stwo-cairo", rev = "8a3950c2" }
stwo_cairo_common = { package = "stwo-cairo-common", git = "https://github.com/starkware-libs/stwo-cairo", rev = "8a3950c2" }
stwo_cairo_dev_utils = { package = "stwo-cairo-dev-utils", git = "https://github.com/starkware-libs/stwo-cairo", rev = "8a3950c2" }
stwo_cairo_utils = { package = "stwo-cairo-utils", git = "https://github.com/starkware-libs/stwo-cairo", rev = "8a3950c2" }
cairo-air = { git = "https://github.com/starkware-libs/stwo-cairo", rev = "0a5e70b7" }
stwo_cairo_prover = { package = "stwo-cairo-prover", git = "https://github.com/starkware-libs/stwo-cairo", rev = "0a5e70b7" }
stwo_cairo_common = { package = "stwo-cairo-common", git = "https://github.com/starkware-libs/stwo-cairo", rev = "0a5e70b7" }
stwo_cairo_dev_utils = { package = "stwo-cairo-dev-utils", git = "https://github.com/starkware-libs/stwo-cairo", rev = "0a5e70b7" }
stwo_cairo_utils = { package = "stwo-cairo-utils", git = "https://github.com/starkware-libs/stwo-cairo", rev = "0a5e70b7" }

# local crates
circuits = { path = "crates/circuits"}
Expand Down
23 changes: 11 additions & 12 deletions crates/cairo_air/src/privacy.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use cairo_air::verifier::INTERACTION_POW_BITS;
use circuits::ivalue::NoValue;
use circuits_stark_verifier::constraint_eval::CircuitEval;
use circuits_stark_verifier::empty_component::EmptyComponent;
use circuits_stark_verifier::proof::ProofConfig;
use indexmap::IndexMap;
use std::collections::HashSet;
Expand All @@ -21,18 +20,17 @@ pub mod test;
pub fn privacy_cairo_verifier_config(log_blowup_factor: u32) -> CairoVerifierConfig {
let preprocessed_trace_variant = PreProcessedTraceVariant::CanonicalSmall;
let privacy_set = privacy_components();
// Build `enabled_bits` (one flag per component in the full list) and `components` (only the
// enabled entries, as expected by `ProofConfig::from_components`) in a single pass.
let (enabled_bits, components): (Vec<bool>, Vec<_>) = all_components::<NoValue>()
.into_iter()
.map(|(name, component)| {
let enabled = privacy_set.contains(name);
(enabled, enabled.then_some((name, component)))
})
.unzip();
let components: IndexMap<&'static str, Box<dyn CircuitEval<NoValue>>> =
all_components::<NoValue>()
.into_iter()
.map(|(name, component)| {
let c: Box<dyn CircuitEval<NoValue>> = if privacy_set.contains(name) {
component
} else {
Box::new(EmptyComponent {})
};
(name, c)
})
.collect();
components.into_iter().flatten().collect();

// Derive proof config parameters from the log blowup factor, targeting 96-bit security.
let (pow_bits, n_queries) = match log_blowup_factor {
Expand All @@ -54,6 +52,7 @@ pub fn privacy_cairo_verifier_config(log_blowup_factor: u32) -> CairoVerifierCon

let proof_config = ProofConfig::from_components(
&components,
enabled_bits,
preprocessed_trace_variant.to_preprocessed_trace().ids().len(),
&pcs_config,
INTERACTION_POW_BITS,
Expand Down
7 changes: 6 additions & 1 deletion crates/cairo_air/src/privacy_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,11 @@ fn verify_circuit_proof(
preprocessed_root: HashValue<QM31>,
) -> Context<QM31> {
let preprocessed_column_ids = preprocessed_circuit.preprocessed_trace.ids();
let components = all_circuit_components::<QM31>();
let enabled_bits = vec![true; components.len()];
let proof_config = ProofConfig::from_components(
&all_circuit_components::<QM31>(),
&components,
enabled_bits,
preprocessed_column_ids.len(),
&circuit_proof.pcs_config,
circuit_air::statement::INTERACTION_POW_BITS,
Expand Down Expand Up @@ -252,8 +255,10 @@ fn test_privacy_proof_info() {
circuit_config.preprocessed_root,
);

let enabled_bits = vec![true; all_circuit_components::<NoValue>().len()];
let proof_config = ProofConfig::from_statement(
&statement,
enabled_bits,
&circuit_config.config,
circuit_air::statement::INTERACTION_POW_BITS,
);
Expand Down
8 changes: 4 additions & 4 deletions crates/cairo_air/src/statement.rs
Original file line number Diff line number Diff line change
Expand Up @@ -226,11 +226,11 @@ impl<Value: IValue> CairoStatement<Value> {
let mut range_checks = vec![];

for ((name, _size), actual_uses) in zip_eq(builtin_instance_sizes, actual_uses_iter) {
let index = self.components.get_index_of(name).unwrap();
if self.components[index].is_disabled() {
// Component is disabled - actual_uses must be 0.
let Some(index) = self.components.get_index_of(name) else {
// The component is not supported by the circuit - actual_uses must be 0.
eq(context, actual_uses, context.zero());
}
continue;
Comment thread
cursor[bot] marked this conversation as resolved.
};

let component_size = component_sizes[index];
// Check that 0 <= component_size - actual_uses < 2^27 => actual_uses <= component_size.
Expand Down
34 changes: 17 additions & 17 deletions crates/cairo_air/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@ use circuits::context::Context;
use circuits::ivalue::NoValue;
use circuits::ops::Guess;
use circuits_stark_verifier::constraint_eval::CircuitEval;
use circuits_stark_verifier::empty_component::EmptyComponent;
use circuits_stark_verifier::proof::{ProofConfig, empty_proof};
use circuits_stark_verifier::verify::verify;
use itertools::Itertools;
Expand All @@ -33,20 +32,17 @@ use crate::preprocessed_columns::MAX_SEQUENCE_LOG_SIZE;
use crate::statement::{CairoStatement, MEMORY_VALUES_LIMBS, PUBLIC_DATA_LEN};
use crate::utils::get_proof_file_path;
use crate::verify::{
CairoVerifierConfig, get_preprocessed_root, prepare_cairo_proof_for_circuit_verifier,
verify_fixed_cairo_circuit,
CairoVerifierConfig, enabled_components, get_preprocessed_root,
prepare_cairo_proof_for_circuit_verifier, verify_fixed_cairo_circuit,
};

/// Circuit Verifies a [CairoProof].
pub fn verify_cairo(proof: &CairoProof<Blake2sM31MerkleHasher>) -> Result<Context<QM31>, String> {
let FlatClaim { component_enable_bits, component_log_sizes: _, public_data: _ } =
proof.claim.flatten_claim();

let components = HashSet::from_iter(
zip_eq(all_components::<QM31>().into_keys(), &component_enable_bits)
.filter(|(_, enable_bit)| **enable_bit)
.map(|(component_name, _)| component_name),
);
let components: HashSet<&str> =
enabled_components::<QM31>(&component_enable_bits).into_keys().collect();

verify_cairo_with_component_set(proof, components)
}
Expand All @@ -60,24 +56,23 @@ pub fn verify_cairo_with_component_set(
cairo_proof.claim.flatten_claim();
let components: indexmap::IndexMap<&'static str, Box<dyn CircuitEval<QM31>>> =
zip_eq(all_components::<QM31>().into_iter(), &component_enable_bits)
.map(|((component_name, component), &enable_bit)| {
.filter_map(|((component_name, component), &enable_bit)| {
let component_in_set = component_set.contains(component_name);
if component_in_set != enable_bit {
return Err(format!(
return Some(Err(format!(
"Proof was produced with the wrong components set: expected the component '{}' to be {} according to the component set, but it is {} in the proof.",
component_name,
if component_in_set { "enabled" } else { "disabled" },
if enable_bit { "enabled" } else { "disabled" }
));
)));
}
let c: Box<dyn CircuitEval<QM31>> =
if enable_bit { component } else { Box::new(EmptyComponent {}) };
Ok((component_name, c))
if enable_bit { Some(Ok((component_name, component))) } else { None }
})
.try_collect()?;

let proof_config = ProofConfig::from_components(
&components,
component_enable_bits,
cairo_proof.preprocessed_trace_variant.to_preprocessed_trace().ids().len(),
&cairo_proof.extended_stark_proof.proof.config,
INTERACTION_POW_BITS,
Expand Down Expand Up @@ -132,9 +127,14 @@ fn test_verify() {
);
// Remove the pedersen points table component since it requires long preprocessed columns, which
// are not supported.
statement.components["pedersen_points_table_window_bits_18"] = Box::new(EmptyComponent {});

let config = ProofConfig::from_statement(&statement, &pcs_config, INTERACTION_POW_BITS);
let pedersen_points_index =
all_components::<NoValue>().get_full("pedersen_points_table_window_bits_18").unwrap().0;
statement.components.shift_remove("pedersen_points_table_window_bits_18");

let mut enabled_bits = vec![true; all_components::<NoValue>().len()];
enabled_bits[pedersen_points_index] = false;
let config =
ProofConfig::from_statement(&statement, enabled_bits, &pcs_config, INTERACTION_POW_BITS);

let empty_proof = empty_proof(&config);

Expand Down
40 changes: 20 additions & 20 deletions crates/cairo_air/src/verify.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,14 +7,15 @@ use cairo_air::air::PublicData;
use cairo_air::flat_claims::FlatClaim;
use circuits::blake::HashValue;
use circuits::context::{Context, TraceContext};
use circuits::ivalue::NoValue;
use circuits::ivalue::{IValue, NoValue};
use circuits::ops::Guess;
use circuits_stark_verifier::empty_component::EmptyComponent;
use circuits_stark_verifier::constraint_eval::CircuitEval;
use circuits_stark_verifier::proof::{Claim, Proof, ProofConfig, empty_proof};
use circuits_stark_verifier::proof_from_stark_proof::{
pack_component_log_sizes, proof_from_stark_proof,
};
use circuits_stark_verifier::verify::verify;
use indexmap::IndexMap;
use itertools::{Itertools, zip_eq};
use num_traits::Zero;
use stwo::core::fields::m31::M31;
Expand Down Expand Up @@ -87,6 +88,16 @@ pub fn verify_fixed_cairo_circuit(
Ok(context)
}

/// Returns the entries of [`all_components`] whose corresponding bit in `enabled_bits` is set,
/// preserving the order of [`all_components`].
pub fn enabled_components<V: IValue>(
enabled_bits: &[bool],
) -> IndexMap<&'static str, Box<dyn CircuitEval<V>>> {
zip_eq(all_components::<V>(), enabled_bits)
.filter_map(|((name, component), &enabled)| enabled.then_some((name, component)))
.collect()
}

/// Builds the Cairo verifier circuit context for a fixed circuit configuration.
///
/// The context can be used for proof verification or recursive proving.
Expand All @@ -97,13 +108,7 @@ pub fn build_fixed_cairo_circuit(
outputs: Vec<[M31; MEMORY_VALUES_LIMBS]>,
) -> Context<QM31> {
let config = &verifier_config.proof_config;
let components = zip_eq(all_components(), config.enabled_components())
.map(|((name, component), enable_bit)| {
let component: Box<dyn circuits_stark_verifier::constraint_eval::CircuitEval<QM31>> =
if enable_bit { component } else { Box::new(EmptyComponent {}) };
(name, component)
})
.collect();
let components = enabled_components(&config.enabled_bits);

let public_claim = public_claim.iter().map(|u32| M31::from(*u32)).collect_vec();
let mut context = TraceContext::default();
Expand All @@ -130,13 +135,7 @@ pub fn build_fixed_cairo_circuit(
/// [NoValue] and an [empty_proof].
pub fn build_cairo_verifier_circuit(verifier_config: &CairoVerifierConfig) -> Context<NoValue> {
let config = &verifier_config.proof_config;
let components = zip_eq(all_components::<NoValue>(), config.enabled_components())
.map(|((name, component), enable_bit)| {
let component: Box<dyn circuits_stark_verifier::constraint_eval::CircuitEval<NoValue>> =
if enable_bit { component } else { Box::new(EmptyComponent {}) };
(name, component)
})
.collect();
let components = enabled_components::<NoValue>(&config.enabled_bits);

let n_outputs = verifier_config.n_outputs;
let program_len = verifier_config.program.len();
Expand Down Expand Up @@ -176,14 +175,15 @@ pub fn prepare_cairo_proof_for_circuit_verifier(

let FlatClaim { component_enable_bits, component_log_sizes, public_data } =
claim.flatten_claim();
let component_claimed_sums = interaction_claim.flatten_interaction_claim();
let claimed_sums = interaction_claim.flatten_interaction_claim();

debug_assert_eq!(component_enable_bits.len(), proof_config.n_components);
debug_assert_eq!(component_claimed_sums.len(), proof_config.n_components);
debug_assert_eq!(component_enable_bits, proof_config.enabled_bits);
debug_assert_eq!(component_log_sizes.len(), proof_config.n_components);
debug_assert_eq!(claimed_sums.len(), proof_config.n_components);

let claim = Claim {
packed_component_log_sizes: pack_component_log_sizes(&component_log_sizes),
claimed_sums: component_claimed_sums,
claimed_sums,
};

let proof = proof_from_stark_proof(
Expand Down
9 changes: 7 additions & 2 deletions crates/circuit_air/src/verify.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
use circuits::{blake::HashValue, context::Context, ivalue::IValue, ops::Guess};
use circuits_stark_verifier::{
proof::{Proof, ProofConfig},
statement::Statement,
verify::verify,
};
use stwo::core::{fields::qm31::QM31, pcs::PcsConfig};
Expand Down Expand Up @@ -36,8 +37,12 @@ pub fn build_verification_circuit<Value: IValue>(
circuit_config.preprocessed_root,
);

let proof_config =
ProofConfig::from_statement(&statement, &circuit_config.config, INTERACTION_POW_BITS);
let proof_config = ProofConfig::from_statement(
&statement,
vec![true; statement.get_components().len()],
&circuit_config.config,
INTERACTION_POW_BITS,
);
let proof_vars = proof.guess(&mut context);

verify(&mut context, &proof_vars, &proof_config, &statement);
Expand Down
5 changes: 4 additions & 1 deletion crates/circuit_prover/src/prover_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -236,8 +236,11 @@ fn circuit_verify(
preprocessed_root: [u32; 8],
) {
let preprocessed_column_ids = preprocessed_circuit.preprocessed_trace.ids();
let all_components = all_circuit_components::<QM31>();
let enabled_bits: Vec<bool> = vec![true; all_components.len()];
let proof_config = ProofConfig::from_components(
&all_circuit_components::<QM31>(),
&all_components,
enabled_bits,
Comment thread
cursor[bot] marked this conversation as resolved.
preprocessed_column_ids.len(),
&circuit_proof.pcs_config,
INTERACTION_POW_BITS,
Expand Down
5 changes: 3 additions & 2 deletions crates/circuit_serialize/src/test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,15 +5,16 @@ use crate::serialize::CircuitSerialize;
use circuits_stark_verifier::proof::{ProofConfig, ProofInfo};
use circuits_stark_verifier::proof_from_stark_proof::proof_from_stark_proof;
use circuits_stark_verifier_examples::simple_air::create_proof;
use circuits_stark_verifier_examples::simple_statement::SimpleStatement;
use circuits_stark_verifier_examples::simple_statement::{COMPONENT_ENABLE_BITS, SimpleStatement};

#[test]
fn test_serialize_deserialize() {
let (_components, claim, pcs_config, proof, interaction_pow_nonce, channel_salt) =
create_proof();

let statement = &SimpleStatement::<QM31>::default();
let config = ProofConfig::from_statement(statement, &pcs_config, 8);
let config =
ProofConfig::from_statement(statement, COMPONENT_ENABLE_BITS.to_vec(), &pcs_config, 8);
let proof = proof_from_stark_proof(&proof, &config, claim, interaction_pow_nonce, channel_salt);

let mut serialized = Vec::new();
Expand Down
Loading
Loading