From c9d73e030e8a1cadbfb2066acbad5274a32f9b71 Mon Sep 17 00:00:00 2001 From: Yogesh Shahi Date: Thu, 11 Jun 2026 07:08:10 +0530 Subject: [PATCH 01/11] feat(build): add bn254/goldilocks field features across the workspace - `provekit-common` gains mutually-informed `bn254` (default) and `goldilocks` field features; `bn254` takes precedence when both are on so `--all-features` builds as BN254. `provekit_ntt` now implies `bn254`. - `mavros-vm`/`mavros-artifacts` become optional deps tied to `bn254`. - Root manifest sets `provekit-common`/`provekit-verifier` to `default-features = false`; every consumer crate re-enables `bn254` explicitly so the goldilocks build can opt out with `--no-default-features --features goldilocks`. --- Cargo.lock | 17 +++++++++-------- Cargo.toml | 7 +++++-- playground/passport-input-gen/Cargo.toml | 2 +- provekit/common/Cargo.toml | 16 ++++++++++++---- provekit/prover/Cargo.toml | 22 ++++++++++++++++++---- provekit/r1cs-compiler/Cargo.toml | 2 +- provekit/verifier/Cargo.toml | 13 +++++++++++++ tooling/cli/Cargo.toml | 4 ++-- tooling/provekit-bench/Cargo.toml | 4 ++-- tooling/provekit-ffi/Cargo.toml | 4 ++-- tooling/provekit-gnark/Cargo.toml | 2 +- tooling/provekit-wasm/Cargo.toml | 6 +++--- tooling/verifier-server/Cargo.toml | 2 +- 13 files changed, 70 insertions(+), 31 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b1f19ea22..6f567c1b7 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -4584,7 +4584,7 @@ dependencies = [ [[package]] name = "provekit-bench" -version = "0.1.0" +version = "1.0.0" dependencies = [ "acir", "anyhow", @@ -4606,7 +4606,7 @@ dependencies = [ [[package]] name = "provekit-cli" -version = "0.1.0" +version = "1.0.0" dependencies = [ "acir", "anyhow", @@ -4635,7 +4635,7 @@ dependencies = [ [[package]] name = "provekit-common" -version = "0.1.0" +version = "1.0.0" dependencies = [ "acir", "anyhow", @@ -4675,7 +4675,7 @@ dependencies = [ [[package]] name = "provekit-ffi" -version = "0.1.0" +version = "1.0.0" dependencies = [ "anyhow", "libc", @@ -4705,7 +4705,7 @@ dependencies = [ [[package]] name = "provekit-prover" -version = "0.1.0" +version = "1.0.0" dependencies = [ "acir", "anyhow", @@ -4720,13 +4720,14 @@ dependencies = [ "num-bigint", "postcard", "provekit-common", + "provekit-verifier", "tracing", "whir", ] [[package]] name = "provekit-r1cs-compiler" -version = "0.1.0" +version = "1.0.0" dependencies = [ "acir", "anyhow", @@ -4747,7 +4748,7 @@ dependencies = [ [[package]] name = "provekit-verifier" -version = "0.1.0" +version = "1.0.0" dependencies = [ "anyhow", "ark-std 0.5.0", @@ -7034,7 +7035,7 @@ dependencies = [ [[package]] name = "verifier-server" -version = "0.1.0" +version = "1.0.0" dependencies = [ "anyhow", "axum", diff --git a/Cargo.toml b/Cargo.toml index dc6ce9676..8f308d033 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -97,12 +97,15 @@ poseidon2 = { path = "poseidon2" } # Workspace members - ProveKit provekit-bench = { path = "tooling/provekit-bench" } provekit-cli = { path = "tooling/cli" } -provekit-common = { path = "provekit/common" , features = ["provekit_ntt"]} +# No default features: consumers pick the field (`bn254`/`goldilocks`) plus +# `parallel`/`provekit_ntt` explicitly — required so the goldilocks build can +# exclude the default `bn254` feature. +provekit-common = { path = "provekit/common", default-features = false } provekit-ffi = { path = "tooling/provekit-ffi" } provekit-gnark = { path = "tooling/provekit-gnark" } provekit-prover = { path = "provekit/prover", default-features = false } provekit-r1cs-compiler = { path = "provekit/r1cs-compiler" } -provekit-verifier = { path = "provekit/verifier" } +provekit-verifier = { path = "provekit/verifier", default-features = false } provekit-verifier-server = { path = "tooling/verifier-server" } provekit-wasm = { path = "tooling/provekit-wasm" } diff --git a/playground/passport-input-gen/Cargo.toml b/playground/passport-input-gen/Cargo.toml index 55166f1e9..907474204 100644 --- a/playground/passport-input-gen/Cargo.toml +++ b/playground/passport-input-gen/Cargo.toml @@ -21,7 +21,7 @@ ark-ff.workspace = true base64.workspace = true hex.workspace = true noirc_abi.workspace = true -provekit-common.workspace = true +provekit-common = { workspace = true, features = ["bn254", "parallel", "provekit_ntt"] } provekit-prover = { workspace = true, features = ["witness-generation"] } serde.workspace = true serde_json.workspace = true diff --git a/provekit/common/Cargo.toml b/provekit/common/Cargo.toml index 2d761d7e0..50779d5ae 100644 --- a/provekit/common/Cargo.toml +++ b/provekit/common/Cargo.toml @@ -9,9 +9,16 @@ homepage.workspace = true repository.workspace = true [features] -default = ["parallel"] +default = ["parallel", "bn254"] +# At least one field feature must be enabled; `bn254` takes precedence when +# both are on (so `--all-features` builds as BN254). `bn254` is the +# production default; `goldilocks` selects the Goldilocks cubic extension +# (Field64_3, ~192 bits) for off-chain, crate-scoped builds only — always +# pair it with `--no-default-features`. +bn254 = ["dep:mavros-vm", "dep:mavros-artifacts"] +goldilocks = [] parallel = [] -provekit_ntt = [] +provekit_ntt = ["bn254"] [dependencies] # Workspace crates @@ -53,8 +60,8 @@ zerocopy.workspace = true # Target-specific dependencies: only on non-WASM targets [target.'cfg(not(target_arch = "wasm32"))'.dependencies] zstd.workspace = true -mavros-vm.workspace = true -mavros-artifacts.workspace = true +mavros-vm = { workspace = true, optional = true } +mavros-artifacts = { workspace = true, optional = true } xz2.workspace = true [package.metadata.cargo-machete] @@ -69,6 +76,7 @@ proptest.workspace = true [[bench]] name = "rs_bench" harness = false +required-features = ["bn254"] [lints] workspace = true diff --git a/provekit/prover/Cargo.toml b/provekit/prover/Cargo.toml index dd9498608..889875905 100644 --- a/provekit/prover/Cargo.toml +++ b/provekit/prover/Cargo.toml @@ -9,8 +9,17 @@ homepage.workspace = true repository.workspace = true [features] -default = ["witness-generation", "parallel"] -witness-generation = ["nargo", "bn254_blackbox_solver", "noir_artifact_cli"] +default = ["witness-generation", "parallel", "bn254"] +# At least one field feature must be enabled; `bn254` takes precedence when +# both are on. Pair `goldilocks` with `--no-default-features`. +bn254 = [ + "provekit-common/bn254", + "provekit-common/provekit_ntt", + "dep:mavros-vm", + "dep:mavros-artifacts", +] +goldilocks = ["provekit-common/goldilocks"] +witness-generation = ["bn254", "nargo", "bn254_blackbox_solver", "noir_artifact_cli"] parallel = ["provekit-common/parallel"] [dependencies] @@ -37,8 +46,13 @@ tracing.workspace = true bn254_blackbox_solver = { workspace = true, optional = true } nargo = { workspace = true, optional = true } noir_artifact_cli = { workspace = true, optional = true } -mavros-vm.workspace = true -mavros-artifacts.workspace = true +mavros-vm = { workspace = true, optional = true } +mavros-artifacts = { workspace = true, optional = true } + +[dev-dependencies] +# No default features: the field feature must unify from this crate's own +# `bn254`/`goldilocks` selection, not be forced to bn254 by the dev-dep. +provekit-verifier = { workspace = true, default-features = false } [lints] workspace = true diff --git a/provekit/r1cs-compiler/Cargo.toml b/provekit/r1cs-compiler/Cargo.toml index 334514124..ef3537dfc 100644 --- a/provekit/r1cs-compiler/Cargo.toml +++ b/provekit/r1cs-compiler/Cargo.toml @@ -10,7 +10,7 @@ repository.workspace = true [dependencies] # Workspace crates -provekit-common.workspace = true +provekit-common = { workspace = true, features = ["bn254", "parallel", "provekit_ntt"] } poseidon2.workspace = true # Noir language diff --git a/provekit/verifier/Cargo.toml b/provekit/verifier/Cargo.toml index 595b04d70..57ec36ac8 100644 --- a/provekit/verifier/Cargo.toml +++ b/provekit/verifier/Cargo.toml @@ -8,6 +8,19 @@ license.workspace = true homepage.workspace = true repository.workspace = true +[features] +default = ["bn254"] +# At least one field feature must be enabled; `bn254` takes precedence when +# both are on. Pair `goldilocks` with `--no-default-features`. +# `provekit_ntt`/`parallel` mirror what the workspace-wide BN254 build +# enabled before the field split. +bn254 = [ + "provekit-common/bn254", + "provekit-common/provekit_ntt", + "provekit-common/parallel", +] +goldilocks = ["provekit-common/goldilocks"] + [dependencies] # Workspace crates provekit-common.workspace = true diff --git a/tooling/cli/Cargo.toml b/tooling/cli/Cargo.toml index c45feb548..5029d918c 100644 --- a/tooling/cli/Cargo.toml +++ b/tooling/cli/Cargo.toml @@ -10,11 +10,11 @@ repository.workspace = true [dependencies] # Workspace crates -provekit-common.workspace = true +provekit-common = { workspace = true, features = ["bn254", "parallel", "provekit_ntt"] } provekit-gnark.workspace = true provekit-prover = { workspace = true, features = ["witness-generation", "parallel"] } provekit-r1cs-compiler.workspace = true -provekit-verifier.workspace = true +provekit-verifier = { workspace = true, features = ["bn254"] } # Noir language acir.workspace = true diff --git a/tooling/provekit-bench/Cargo.toml b/tooling/provekit-bench/Cargo.toml index 0121caa37..27fec107d 100644 --- a/tooling/provekit-bench/Cargo.toml +++ b/tooling/provekit-bench/Cargo.toml @@ -10,10 +10,10 @@ repository.workspace = true [dependencies] # Workspace crates -provekit-common.workspace = true +provekit-common = { workspace = true, features = ["bn254", "parallel", "provekit_ntt"] } provekit-prover = { workspace = true, features = ["witness-generation", "parallel"] } provekit-r1cs-compiler.workspace = true -provekit-verifier.workspace = true +provekit-verifier = { workspace = true, features = ["bn254"] } # Noir language acir.workspace = true diff --git a/tooling/provekit-ffi/Cargo.toml b/tooling/provekit-ffi/Cargo.toml index f602f43f6..42692aaa1 100644 --- a/tooling/provekit-ffi/Cargo.toml +++ b/tooling/provekit-ffi/Cargo.toml @@ -13,10 +13,10 @@ crate-type = ["staticlib", "rlib"] [dependencies] # Workspace crates -provekit-common.workspace = true +provekit-common = { workspace = true, features = ["bn254", "parallel", "provekit_ntt"] } provekit-prover = { workspace = true, features = ["witness-generation", "parallel"] } provekit-r1cs-compiler = { workspace = true } -provekit-verifier = { workspace = true } +provekit-verifier = { workspace = true, features = ["bn254"] } # 3rd party anyhow.workspace = true diff --git a/tooling/provekit-gnark/Cargo.toml b/tooling/provekit-gnark/Cargo.toml index da48874cb..20da14c19 100644 --- a/tooling/provekit-gnark/Cargo.toml +++ b/tooling/provekit-gnark/Cargo.toml @@ -10,7 +10,7 @@ repository.workspace = true [dependencies] # Workspace crates -provekit-common.workspace = true +provekit-common = { workspace = true, features = ["bn254", "parallel", "provekit_ntt"] } # Cryptography and proof systems ark-poly.workspace = true diff --git a/tooling/provekit-wasm/Cargo.toml b/tooling/provekit-wasm/Cargo.toml index e1a76003f..ab00be861 100644 --- a/tooling/provekit-wasm/Cargo.toml +++ b/tooling/provekit-wasm/Cargo.toml @@ -22,9 +22,9 @@ crate-type = ["cdylib", "rlib"] [dependencies] # Workspace crates - enable parallel features with wasm-bindgen-rayon -provekit-common.workspace = true -provekit-prover = { workspace = true, default-features = false, features = ["parallel"] } -provekit-verifier.workspace = true +provekit-common = { workspace = true, features = ["bn254", "parallel", "provekit_ntt"] } +provekit-prover = { workspace = true, default-features = false, features = ["bn254", "parallel"] } +provekit-verifier = { workspace = true, features = ["bn254"] } # Noir language acir.workspace = true diff --git a/tooling/verifier-server/Cargo.toml b/tooling/verifier-server/Cargo.toml index 302749158..5073ac61e 100644 --- a/tooling/verifier-server/Cargo.toml +++ b/tooling/verifier-server/Cargo.toml @@ -10,7 +10,7 @@ repository.workspace = true [dependencies] # Workspace crates -provekit-common.workspace = true +provekit-common = { workspace = true, features = ["bn254", "parallel", "provekit_ntt"] } provekit-gnark.workspace = true # 3rd party From 61ecc0a7d1e8e85560f0b31d2fa08ca9884169ea Mon Sep 17 00:00:00 2001 From: Yogesh Shahi Date: Thu, 11 Jun 2026 07:08:21 +0530 Subject: [PATCH 02/11] feat(common): select FieldElement by field feature and relocate WhirR1CSSchemeBuilder - Split the `FieldElement` alias: `ark_bn254::Fr` under `bn254`, `whir::algebra::fields::Field64_3` under `goldilocks`. Gate the BN254-only modules (mavros, noir_proof_scheme, ntt, optimize, poseidon2, prover, skyscraper, verifier) and the Skyscraper/Poseidon2 engine registrations in `register_ntt`. - Move `WhirR1CSSchemeBuilder` (and the `MIN_*` consts) from `r1cs-compiler` into `common`, re-exporting it from both crates. The move rides here because the crate-root re-export and the field split touch the same `lib.rs`. The Mavros constructor stays `bn254`-gated. --- provekit/common/src/lib.rs | 45 ++- provekit/common/src/whir_r1cs.rs | 247 +++++++++++++- provekit/r1cs-compiler/src/lib.rs | 3 +- .../r1cs-compiler/src/noir_proof_scheme.rs | 7 +- provekit/r1cs-compiler/src/whir_r1cs.rs | 305 ------------------ 5 files changed, 287 insertions(+), 320 deletions(-) delete mode 100644 provekit/r1cs-compiler/src/whir_r1cs.rs diff --git a/provekit/common/src/lib.rs b/provekit/common/src/lib.rs index 3953207d8..b3e763015 100644 --- a/provekit/common/src/lib.rs +++ b/provekit/common/src/lib.rs @@ -1,20 +1,36 @@ +// `bn254` takes precedence when both field features are enabled (CI builds +// with `--all-features`, which unavoidably turns both on). A goldilocks +// build must therefore disable the default: +// cargo build -p provekit-common -p provekit-prover -p provekit-verifier \ +// --no-default-features --features goldilocks +#[cfg(not(any(feature = "bn254", feature = "goldilocks")))] +compile_error!("enable a field feature: `bn254` (default) or `goldilocks`"); + pub mod file; pub use file::binary_format; pub mod hash_config; mod interner; +#[cfg(feature = "bn254")] mod mavros; +#[cfg(feature = "bn254")] mod noir_proof_scheme; +#[cfg(feature = "bn254")] pub mod ntt; +#[cfg(feature = "bn254")] pub mod optimize; +#[cfg(feature = "bn254")] pub mod poseidon2; pub mod prefix_covector; +#[cfg(feature = "bn254")] mod prover; mod r1cs; +#[cfg(feature = "bn254")] pub mod skyscraper; pub mod sparse_matrix; mod transcript_sponge; pub mod u256_arith; pub mod utils; +#[cfg(feature = "bn254")] mod verifier; mod whir_r1cs; pub mod witness; @@ -23,18 +39,29 @@ use crate::{ interner::{InternedFieldElement, Interner}, sparse_matrix::{HydratedSparseMatrix, SparseMatrix}, }; +/// The proof system's field. BN254 scalar field by default; the Goldilocks +/// cubic extension (`Field64_3`, ~192 bits — `Field`/`FftField` but not +/// `PrimeField`) under the `goldilocks` feature. +#[cfg(feature = "bn254")] +pub use ark_bn254::Fr as FieldElement; +#[cfg(all(feature = "goldilocks", not(feature = "bn254")))] +pub use whir::algebra::fields::Field64_3 as FieldElement; +#[cfg(feature = "bn254")] pub use { acir::FieldElement as NoirElement, - ark_bn254::Fr as FieldElement, - hash_config::HashConfig, mavros::{MavrosProver, MavrosSchemeData}, noir_proof_scheme::{NoirProof, NoirProofScheme, NoirSchemeData}, - prefix_covector::{OffsetCovector, PrefixCovector, SparseCovector}, prover::{NoirProver, Prover}, + verifier::Verifier, +}; +pub use { + hash_config::HashConfig, + prefix_covector::{OffsetCovector, PrefixCovector, SparseCovector}, r1cs::R1CS, transcript_sponge::TranscriptSponge, - verifier::Verifier, - whir_r1cs::{R1csHash, WhirConfig, WhirR1CSProof, WhirR1CSScheme, WhirZkConfig}, + whir_r1cs::{ + R1csHash, WhirConfig, WhirR1CSProof, WhirR1CSScheme, WhirR1CSSchemeBuilder, WhirZkConfig, + }, witness::PublicInputs, }; @@ -59,7 +86,11 @@ pub fn register_ntt() { // Register ProveKit-specific engines; WHIR's built-in engines // (SHA2, Keccak, Blake3, etc.) are pre-registered via whir::hash::ENGINES. - whir::hash::ENGINES.register(Arc::new(skyscraper::SkyscraperHashEngine)); - whir::hash::ENGINES.register(Arc::new(poseidon2::Poseidon2HashEngine)); + // Skyscraper and Poseidon2 are BN254-only constructions. + #[cfg(feature = "bn254")] + { + whir::hash::ENGINES.register(Arc::new(skyscraper::SkyscraperHashEngine)); + whir::hash::ENGINES.register(Arc::new(poseidon2::Poseidon2HashEngine)); + } }); } diff --git a/provekit/common/src/whir_r1cs.rs b/provekit/common/src/whir_r1cs.rs index 5b26d3d17..06acd0c10 100644 --- a/provekit/common/src/whir_r1cs.rs +++ b/provekit/common/src/whir_r1cs.rs @@ -1,12 +1,19 @@ +#[cfg(all(feature = "bn254", not(target_arch = "wasm32")))] +use mavros_artifacts::R1CS as MavrosR1CS; #[cfg(debug_assertions)] use std::fmt::Debug; #[cfg(debug_assertions)] use whir::transcript::Interaction; use { - crate::{utils::serde_hex, FieldElement, HashConfig}, + crate::{ + utils::{next_power_of_two, serde_hex}, + FieldElement, HashConfig, R1CS, + }, serde::{Deserialize, Serialize}, whir::{ algebra::embedding::Identity, + engines::EngineId, + parameters::ProtocolParameters, protocols::{whir::Config as GenericWhirConfig, whir_zk::Config as GenericWhirZkConfig}, transcript, }, @@ -74,6 +81,195 @@ impl WhirR1CSScheme { } } +const MIN_WHIR_NUM_VARIABLES: usize = 13; +const MIN_SUMCHECK_NUM_VARIABLES: usize = 1; + +/// Constructors for [`WhirR1CSScheme`], sizing the WHIR configuration from an +/// R1CS instance (or raw dimensions) and stamping the instance-binding +/// `r1cs_hash`. +pub trait WhirR1CSSchemeBuilder { + /// Build a scheme for `r1cs`, stamping `r1cs_hash = r1cs.hash()`. + fn new_for_r1cs( + r1cs: &R1CS, + w1_size: usize, + num_challenges: usize, + challenge_offsets: Vec, + has_public_inputs: bool, + hash_config: HashConfig, + ) -> Self; + + /// Build a scheme from a Mavros R1CS, leaving `r1cs_hash` unset. + #[cfg(all(feature = "bn254", not(target_arch = "wasm32")))] + fn new_from_mavros_r1cs( + r1cs: &MavrosR1CS, + w1_size: usize, + num_challenges: usize, + challenge_offsets: Vec, + has_public_inputs: bool, + hash_config: HashConfig, + ) -> Self; + + /// Build a scheme from raw dimensions, leaving `r1cs_hash` unset. + fn new_from_dimensions( + num_witnesses: usize, + num_constraints: usize, + a_num_entries: usize, + w1_size: usize, + num_challenges: usize, + challenge_offsets: Vec, + has_public_inputs: bool, + hash_config: HashConfig, + ) -> Self; + + /// Build the WHIR ZK configuration for `num_variables` (clamped to the + /// protocol minimum) and `num_polynomials`. + fn new_whir_zk_config_for_size( + num_variables: usize, + num_polynomials: usize, + hash_id: EngineId, + ) -> WhirZkConfig; +} + +impl WhirR1CSSchemeBuilder for WhirR1CSScheme { + fn new_for_r1cs( + r1cs: &R1CS, + w1_size: usize, + num_challenges: usize, + challenge_offsets: Vec, + has_public_inputs: bool, + hash_config: HashConfig, + ) -> Self { + assert_eq!( + num_challenges, + challenge_offsets.len(), + "num_challenges ({num_challenges}) != challenge_offsets.len() ({})", + challenge_offsets.len() + ); + let total_witnesses = r1cs.num_witnesses(); + assert!( + w1_size <= total_witnesses, + "w1_size exceeds total witnesses" + ); + let w2_size = total_witnesses - w1_size; + + let m1_raw = next_power_of_two(w1_size); + let m2_raw = next_power_of_two(w2_size); + let m0_raw = next_power_of_two(r1cs.num_constraints()); + + let mut m_raw = m1_raw.max(m2_raw).max(MIN_WHIR_NUM_VARIABLES); + let m_0 = m0_raw.max(MIN_SUMCHECK_NUM_VARIABLES); + + // Ensure w1's zero-padding has room for the blinding polynomial coefficients. + if (1usize << m_raw) - w1_size < 4 * m_0 { + m_raw += 1; + } + + Self { + m: m_raw, + w1_size, + m_0, + a_num_terms: next_power_of_two(r1cs.a().iter().count()), + num_challenges, + challenge_offsets, + whir_witness: Self::new_whir_zk_config_for_size(m_raw, 1, hash_config.engine_id()), + has_public_inputs, + r1cs_hash: r1cs.hash(), + hash_config, + } + } + + fn new_whir_zk_config_for_size( + num_variables: usize, + num_polynomials: usize, + hash_id: EngineId, + ) -> WhirZkConfig { + let nv = num_variables.max(MIN_WHIR_NUM_VARIABLES); + + // Parameters tuned for 128-bit security under the Johnson bound (the old + // ConjectureList soundness was disproven). Rate=2 balances query count vs + // codeword size; ff=3 keeps blinding polynomials small; pow_bits=10 shifts + // security budget toward algebraic hardness (118 bits) with light PoW per + // round, which is faster than the default ~18-bit grinding. + let whir_params = ProtocolParameters { + unique_decoding: false, + security_level: 128, + pow_bits: 10, + initial_folding_factor: 3, + folding_factor: 3, + starting_log_inv_rate: 2, + batch_size: 1, + hash_id, + }; + WhirZkConfig::new(1 << nv, &whir_params, num_polynomials) + } + + #[cfg(all(feature = "bn254", not(target_arch = "wasm32")))] + fn new_from_mavros_r1cs( + r1cs: &MavrosR1CS, + w1_size: usize, + num_challenges: usize, + challenge_offsets: Vec, + has_public_inputs: bool, + hash_config: HashConfig, + ) -> Self { + let num_witnesses = r1cs.witness_layout.size(); + let num_constraints = r1cs.constraints.len(); + let a_num_entries: usize = r1cs.constraints.iter().map(|c| c.a.len()).sum(); + + Self::new_from_dimensions( + num_witnesses, + num_constraints, + a_num_entries, + w1_size, + num_challenges, + challenge_offsets, + has_public_inputs, + hash_config, + ) + } + + fn new_from_dimensions( + num_witnesses: usize, + num_constraints: usize, + a_num_entries: usize, + w1_size: usize, + num_challenges: usize, + challenge_offsets: Vec, + has_public_inputs: bool, + hash_config: HashConfig, + ) -> Self { + debug_assert_eq!( + num_challenges, + challenge_offsets.len(), + "num_challenges ({num_challenges}) != challenge_offsets.len() ({})", + challenge_offsets.len() + ); + let m_raw = next_power_of_two(num_witnesses); + let m0_raw = next_power_of_two(num_constraints); + + let mut m = m_raw.max(MIN_WHIR_NUM_VARIABLES); + let m_0 = m0_raw.max(MIN_SUMCHECK_NUM_VARIABLES); + + // Ensure w1's zero-padding has room for the blinding polynomial coefficients. + if (1usize << m) - w1_size < 4 * m_0 { + m += 1; + } + + Self { + m, + m_0, + a_num_terms: next_power_of_two(a_num_entries), + whir_witness: Self::new_whir_zk_config_for_size(m, 1, hash_config.engine_id()), + w1_size, + num_challenges, + challenge_offsets, + has_public_inputs, + r1cs_hash: R1csHash::UNSET, + hash_config, + } + } +} + #[derive(Debug, Clone, PartialEq, Serialize, Deserialize)] pub struct WhirR1CSProof { #[serde(with = "serde_hex")] @@ -87,3 +283,52 @@ pub struct WhirR1CSProof { #[serde(skip)] pub pattern: Vec, } + +#[cfg(test)] +mod tests { + use super::*; + + #[test] + fn verify_security_level() { + let config = WhirR1CSScheme::new_whir_zk_config_for_size(20, 1, whir::hash::SHA2); + let sec_blinded = config + .blinded_commitment + .security_level(config.blinded_commitment.initial_committer.num_vectors, 1); + let sec_blinding = config + .blinding_commitment + .security_level(config.blinding_commitment.initial_committer.num_vectors, 1); + assert!( + sec_blinded >= 128.0, + "Blinded commitment security {sec_blinded:.2} < 128 bits" + ); + assert!( + sec_blinding >= 128.0, + "Blinding commitment security {sec_blinding:.2} < 128 bits" + ); + } + + #[test] + fn verify_security_level_min_variables() { + let config = WhirR1CSScheme::new_whir_zk_config_for_size( + MIN_WHIR_NUM_VARIABLES, + 1, + whir::hash::SHA2, + ); + let sec_blinded = config + .blinded_commitment + .security_level(config.blinded_commitment.initial_committer.num_vectors, 1); + let sec_blinding = config + .blinding_commitment + .security_level(config.blinding_commitment.initial_committer.num_vectors, 1); + assert!( + sec_blinded >= 128.0, + "Blinded commitment security {sec_blinded:.2} < 128 bits at nv={}", + MIN_WHIR_NUM_VARIABLES + ); + assert!( + sec_blinding >= 128.0, + "Blinding commitment security {sec_blinding:.2} < 128 bits at nv={}", + MIN_WHIR_NUM_VARIABLES + ); + } +} diff --git a/provekit/r1cs-compiler/src/lib.rs b/provekit/r1cs-compiler/src/lib.rs index 0b9890a8a..c96f003ce 100644 --- a/provekit/r1cs-compiler/src/lib.rs +++ b/provekit/r1cs-compiler/src/lib.rs @@ -10,11 +10,10 @@ pub mod range_check; mod sha256_compression; mod spread; mod uints; -mod whir_r1cs; mod witness_generator; pub use { noir_proof_scheme::{MavrosCompiler, NoirCompiler}, noir_to_r1cs::{noir_to_r1cs, noir_to_r1cs_with_breakdown, R1CSBreakdown}, - whir_r1cs::WhirR1CSSchemeBuilder, + provekit_common::WhirR1CSSchemeBuilder, }; diff --git a/provekit/r1cs-compiler/src/noir_proof_scheme.rs b/provekit/r1cs-compiler/src/noir_proof_scheme.rs index 468107e40..a1e176104 100644 --- a/provekit/r1cs-compiler/src/noir_proof_scheme.rs +++ b/provekit/r1cs-compiler/src/noir_proof_scheme.rs @@ -1,8 +1,5 @@ use { - crate::{ - noir_to_r1cs, whir_r1cs::WhirR1CSSchemeBuilder, - witness_generator::NoirWitnessGeneratorBuilder, - }, + crate::{noir_to_r1cs, witness_generator::NoirWitnessGeneratorBuilder}, anyhow::{ensure, Context as _, Result}, mavros_artifacts::R1CS as MavrosR1CS, noirc_abi::AbiVisibility, @@ -10,7 +7,7 @@ use { provekit_common::{ utils::{convert_mavros_r1cs_to_provekit, PrintAbi}, witness::{NoirWitnessGenerator, WitnessBuilder}, - MavrosSchemeData, NoirProofScheme, NoirSchemeData, WhirR1CSScheme, + MavrosSchemeData, NoirProofScheme, NoirSchemeData, WhirR1CSScheme, WhirR1CSSchemeBuilder, }, serde::Deserialize, std::{collections::HashSet, fs::File, path::Path}, diff --git a/provekit/r1cs-compiler/src/whir_r1cs.rs b/provekit/r1cs-compiler/src/whir_r1cs.rs deleted file mode 100644 index d71f05f04..000000000 --- a/provekit/r1cs-compiler/src/whir_r1cs.rs +++ /dev/null @@ -1,305 +0,0 @@ -use { - mavros_artifacts::R1CS as MavrosR1CS, - provekit_common::{ - utils::next_power_of_two, HashConfig, R1csHash, WhirR1CSScheme, WhirZkConfig, R1CS, - }, - whir::{engines::EngineId, parameters::ProtocolParameters}, -}; - -const MIN_WHIR_NUM_VARIABLES: usize = 13; -const MIN_SUMCHECK_NUM_VARIABLES: usize = 1; - -pub trait WhirR1CSSchemeBuilder { - fn new_for_r1cs( - r1cs: &R1CS, - w1_size: usize, - num_challenges: usize, - challenge_offsets: Vec, - has_public_inputs: bool, - hash_config: HashConfig, - ) -> Self; - - fn new_from_mavros_r1cs( - r1cs: &MavrosR1CS, - w1_size: usize, - num_challenges: usize, - challenge_offsets: Vec, - has_public_inputs: bool, - hash_config: HashConfig, - ) -> Self; - - fn new_from_dimensions( - num_witnesses: usize, - num_constraints: usize, - a_num_entries: usize, - w1_size: usize, - num_challenges: usize, - challenge_offsets: Vec, - has_public_inputs: bool, - hash_config: HashConfig, - ) -> Self; - - fn new_whir_zk_config_for_size( - num_variables: usize, - num_polynomials: usize, - hash_id: EngineId, - ) -> WhirZkConfig; -} - -impl WhirR1CSSchemeBuilder for WhirR1CSScheme { - fn new_for_r1cs( - r1cs: &R1CS, - w1_size: usize, - num_challenges: usize, - challenge_offsets: Vec, - has_public_inputs: bool, - hash_config: HashConfig, - ) -> Self { - assert_eq!( - num_challenges, - challenge_offsets.len(), - "num_challenges ({num_challenges}) != challenge_offsets.len() ({})", - challenge_offsets.len() - ); - let total_witnesses = r1cs.num_witnesses(); - assert!( - w1_size <= total_witnesses, - "w1_size exceeds total witnesses" - ); - let w2_size = total_witnesses - w1_size; - - let m1_raw = next_power_of_two(w1_size); - let m2_raw = next_power_of_two(w2_size); - let m0_raw = next_power_of_two(r1cs.num_constraints()); - - let mut m_raw = m1_raw.max(m2_raw).max(MIN_WHIR_NUM_VARIABLES); - let m_0 = m0_raw.max(MIN_SUMCHECK_NUM_VARIABLES); - - // Ensure w1's zero-padding has room for the blinding polynomial coefficients. - if (1usize << m_raw) - w1_size < 4 * m_0 { - m_raw += 1; - } - - Self { - m: m_raw, - w1_size, - m_0, - a_num_terms: next_power_of_two(r1cs.a().iter().count()), - num_challenges, - challenge_offsets, - whir_witness: Self::new_whir_zk_config_for_size(m_raw, 1, hash_config.engine_id()), - has_public_inputs, - r1cs_hash: r1cs.hash(), - hash_config, - } - } - - fn new_whir_zk_config_for_size( - num_variables: usize, - num_polynomials: usize, - hash_id: EngineId, - ) -> WhirZkConfig { - let nv = num_variables.max(MIN_WHIR_NUM_VARIABLES); - - // Parameters tuned for 128-bit security under the Johnson bound (the old - // ConjectureList soundness was disproven). Rate=2 balances query count vs - // codeword size; ff=3 keeps blinding polynomials small; pow_bits=10 shifts - // security budget toward algebraic hardness (118 bits) with light PoW per - // round, which is faster than the default ~18-bit grinding. - let whir_params = ProtocolParameters { - unique_decoding: false, - security_level: 128, - pow_bits: 10, - initial_folding_factor: 3, - folding_factor: 3, - starting_log_inv_rate: 2, - batch_size: 1, - hash_id, - }; - WhirZkConfig::new(1 << nv, &whir_params, num_polynomials) - } - - fn new_from_mavros_r1cs( - r1cs: &MavrosR1CS, - w1_size: usize, - num_challenges: usize, - challenge_offsets: Vec, - has_public_inputs: bool, - hash_config: HashConfig, - ) -> Self { - let num_witnesses = r1cs.witness_layout.size(); - let num_constraints = r1cs.constraints.len(); - let a_num_entries: usize = r1cs.constraints.iter().map(|c| c.a.len()).sum(); - - Self::new_from_dimensions( - num_witnesses, - num_constraints, - a_num_entries, - w1_size, - num_challenges, - challenge_offsets, - has_public_inputs, - hash_config, - ) - } - - fn new_from_dimensions( - num_witnesses: usize, - num_constraints: usize, - a_num_entries: usize, - w1_size: usize, - num_challenges: usize, - challenge_offsets: Vec, - has_public_inputs: bool, - hash_config: HashConfig, - ) -> Self { - debug_assert_eq!( - num_challenges, - challenge_offsets.len(), - "num_challenges ({num_challenges}) != challenge_offsets.len() ({})", - challenge_offsets.len() - ); - assert!(w1_size <= num_witnesses, "w1_size exceeds total witnesses"); - let w2_size = num_witnesses - w1_size; - - let m1_raw = next_power_of_two(w1_size); - let m2_raw = next_power_of_two(w2_size); - let m0_raw = next_power_of_two(num_constraints); - - let mut m = m1_raw.max(m2_raw).max(MIN_WHIR_NUM_VARIABLES); - let m_0 = m0_raw.max(MIN_SUMCHECK_NUM_VARIABLES); - - // Ensure w1's zero-padding has room for the blinding polynomial coefficients. - if (1usize << m) - w1_size < 4 * m_0 { - m += 1; - } - - Self { - m, - m_0, - a_num_terms: next_power_of_two(a_num_entries), - whir_witness: Self::new_whir_zk_config_for_size(m, 1, hash_config.engine_id()), - w1_size, - num_challenges, - challenge_offsets, - has_public_inputs, - r1cs_hash: R1csHash::UNSET, - hash_config, - } - } -} - -#[cfg(test)] -mod tests { - use super::*; - - fn r1cs_with_dimensions(num_witnesses: usize, num_constraints: usize) -> R1CS { - let mut r1cs = R1CS::new(); - r1cs.grow_matrices(num_constraints, num_witnesses); - r1cs - } - - fn assert_dimension_builders( - num_witnesses: usize, - num_constraints: usize, - w1_size: usize, - expected_m: usize, - expected_m_0: usize, - ) { - let from_dimensions = WhirR1CSScheme::new_from_dimensions( - num_witnesses, - num_constraints, - 0, - w1_size, - 0, - vec![], - false, - HashConfig::Sha256, - ); - assert_eq!(from_dimensions.m, expected_m); - assert_eq!(from_dimensions.m_0, expected_m_0); - assert_eq!(from_dimensions.w1_size, w1_size); - - let r1cs = r1cs_with_dimensions(num_witnesses, num_constraints); - let from_r1cs = - WhirR1CSScheme::new_for_r1cs(&r1cs, w1_size, 0, vec![], false, HashConfig::Sha256); - assert_eq!(from_r1cs.m, expected_m); - assert_eq!(from_r1cs.m_0, expected_m_0); - assert_eq!(from_r1cs.w1_size, w1_size); - } - - #[test] - fn verify_security_level() { - let config = WhirR1CSScheme::new_whir_zk_config_for_size(20, 1, whir::hash::SHA2); - let sec_blinded = config - .blinded_commitment - .security_level(config.blinded_commitment.initial_committer.num_vectors, 1); - let sec_blinding = config - .blinding_commitment - .security_level(config.blinding_commitment.initial_committer.num_vectors, 1); - assert!( - sec_blinded >= 128.0, - "Blinded commitment security {sec_blinded:.2} < 128 bits" - ); - assert!( - sec_blinding >= 128.0, - "Blinding commitment security {sec_blinding:.2} < 128 bits" - ); - } - - #[test] - fn verify_security_level_min_variables() { - let config = WhirR1CSScheme::new_whir_zk_config_for_size( - MIN_WHIR_NUM_VARIABLES, - 1, - whir::hash::SHA2, - ); - let sec_blinded = config - .blinded_commitment - .security_level(config.blinded_commitment.initial_committer.num_vectors, 1); - let sec_blinding = config - .blinding_commitment - .security_level(config.blinding_commitment.initial_committer.num_vectors, 1); - assert!( - sec_blinded >= 128.0, - "Blinded commitment security {sec_blinded:.2} < 128 bits at nv={}", - MIN_WHIR_NUM_VARIABLES - ); - assert!( - sec_blinding >= 128.0, - "Blinding commitment security {sec_blinding:.2} < 128 bits at nv={}", - MIN_WHIR_NUM_VARIABLES - ); - } - - #[test] - fn mavros_dimensions_use_largest_commitment_not_total_witnesses() { - let scheme = WhirR1CSScheme::new_from_dimensions( - 600_000, - 8, - 8, - 300_000, - 2, - vec![0, 1], - false, - HashConfig::Sha256, - ); - - assert_eq!(scheme.m, 19); - } - - #[test] - fn dimension_builders_handle_empty_w2() { - assert_dimension_builders(64, 8, 64, MIN_WHIR_NUM_VARIABLES, 3); - } - - #[test] - fn dimension_builders_handle_empty_w1() { - assert_dimension_builders(64, 8, 0, MIN_WHIR_NUM_VARIABLES, 3); - } - - #[test] - fn dimension_builders_bump_exact_power_of_two_w1_for_blinding_room() { - assert_dimension_builders(12_288, 2_048, 8_192, 14, 11); - } -} From fce179a4d1643a111be285faedc7a6118d7236fc Mon Sep 17 00:00:00 2001 From: Yogesh Shahi Date: Thu, 11 Jun 2026 07:08:31 +0530 Subject: [PATCH 03/11] feat(common): gate BN254-only hashes and add Goldilocks byte bridges - Gate the Skyscraper/Poseidon2 `HashConfig` and `TranscriptSponge` variants behind `bn254`; the goldilocks default hash is `Sha256`. - Add Goldilocks twins for the field<->byte bridges (`field_to_bytes_le` -> 24 bytes, digest-to-field via the base subfield) and switch the sumcheck `HALF` constant to a `LazyLock`. --- provekit/common/src/hash_config.rs | 97 ++++++++++++++++++++---- provekit/common/src/transcript_sponge.rs | 16 +++- provekit/common/src/utils/mod.rs | 42 +++++++--- 3 files changed, 126 insertions(+), 29 deletions(-) diff --git a/provekit/common/src/hash_config.rs b/provekit/common/src/hash_config.rs index 515b74eb6..f382557f9 100644 --- a/provekit/common/src/hash_config.rs +++ b/provekit/common/src/hash_config.rs @@ -7,23 +7,31 @@ use { crate::{utils::field_to_bytes_le, FieldElement}, - ark_ff::{BigInt, PrimeField}, serde::{Deserialize, Serialize}, - std::{fmt, sync::LazyLock}, + std::fmt, +}; +#[cfg(feature = "bn254")] +use { + ark_ff::{BigInt, PrimeField}, + std::sync::LazyLock, }; /// Hash algorithm configuration that can be selected at runtime. /// /// Each variant selects the same algorithm for Merkle commitments, -/// Fiat-Shamir sponge, and public-input binding. [`Self::Skyscraper`] is the -/// default. +/// Fiat-Shamir sponge, and public-input binding. Skyscraper and Poseidon2 +/// are BN254-only constructions and exist only under the `bn254` feature; +/// the default is Skyscraper under `bn254` and [`Self::Sha256`] under +/// `goldilocks`. #[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] #[serde(rename_all = "kebab-case")] pub enum HashConfig { + #[cfg(feature = "bn254")] #[default] #[serde(alias = "sky")] Skyscraper, + #[cfg_attr(all(feature = "goldilocks", not(feature = "bn254")), default)] #[serde(alias = "sha", alias = "sha-256")] Sha256, @@ -33,6 +41,7 @@ pub enum HashConfig { #[serde(alias = "blake-3", alias = "b3")] Blake3, + #[cfg(feature = "bn254")] #[serde(alias = "pos2", alias = "p2")] Poseidon2, } @@ -54,6 +63,7 @@ pub enum HashConfig { /// Regression trip-wires: the KATs in `witness::tests` freeze the /// byte-exact output of each variant under this constant. const PUBLIC_INPUTS_DST: &[u8] = b"PROVEKIT_PUBLIC_INPUTS_V1"; +#[cfg(feature = "bn254")] static PUBLIC_INPUTS_DST_FE: LazyLock = LazyLock::new(|| { use sha2::{Digest, Sha256}; FieldElement::from_le_bytes_mod_order(&Sha256::digest(PUBLIC_INPUTS_DST)) @@ -64,10 +74,12 @@ impl HashConfig { #[must_use] pub fn name(&self) -> &'static str { match self { + #[cfg(feature = "bn254")] Self::Skyscraper => "skyscraper", Self::Sha256 => "sha256", Self::Keccak => "keccak", Self::Blake3 => "blake3", + #[cfg(feature = "bn254")] Self::Poseidon2 => "poseidon2", } } @@ -76,10 +88,12 @@ impl HashConfig { #[must_use] pub fn engine_id(&self) -> whir::engines::EngineId { match self { + #[cfg(feature = "bn254")] Self::Skyscraper => crate::skyscraper::SKYSCRAPER, Self::Sha256 => whir::hash::SHA2, Self::Keccak => whir::hash::KECCAK, Self::Blake3 => whir::hash::BLAKE3, + #[cfg(feature = "bn254")] Self::Poseidon2 => crate::poseidon2::POSEIDON2, } } @@ -88,10 +102,12 @@ impl HashConfig { #[must_use] pub fn to_byte(&self) -> u8 { match self { + #[cfg(feature = "bn254")] Self::Skyscraper => 0, Self::Sha256 => 1, Self::Keccak => 2, Self::Blake3 => 3, + #[cfg(feature = "bn254")] Self::Poseidon2 => 4, } } @@ -100,10 +116,12 @@ impl HashConfig { #[must_use] pub fn from_byte(byte: u8) -> Option { match byte { + #[cfg(feature = "bn254")] 0 => Some(Self::Skyscraper), 1 => Some(Self::Sha256), 2 => Some(Self::Keccak), 3 => Some(Self::Blake3), + #[cfg(feature = "bn254")] 4 => Some(Self::Poseidon2), _ => None, } @@ -114,10 +132,12 @@ impl HashConfig { pub fn parse(s: &str) -> Option { let lower = s.to_lowercase(); match lower.as_str() { + #[cfg(feature = "bn254")] "skyscraper" | "sky" => Some(Self::Skyscraper), "sha256" | "sha" | "sha-256" => Some(Self::Sha256), "keccak" | "keccak-256" | "shake" => Some(Self::Keccak), "blake3" | "blake-3" | "b3" => Some(Self::Blake3), + #[cfg(feature = "bn254")] "poseidon2" | "pos2" | "p2" => Some(Self::Poseidon2), _ => None, } @@ -142,10 +162,12 @@ impl HashConfig { #[must_use] pub fn hash_field_elements(self, elements: &[FieldElement]) -> FieldElement { match self { + #[cfg(feature = "bn254")] Self::Skyscraper => hash_skyscraper(elements), Self::Sha256 => hash_digest::(PUBLIC_INPUTS_DST, elements), Self::Keccak => hash_digest::(PUBLIC_INPUTS_DST, elements), Self::Blake3 => hash_blake3(PUBLIC_INPUTS_DST, elements), + #[cfg(feature = "bn254")] Self::Poseidon2 => hash_poseidon2(elements), } } @@ -161,10 +183,13 @@ impl std::str::FromStr for HashConfig { type Err = String; fn from_str(s: &str) -> Result { + #[cfg(feature = "bn254")] + const VALID: &str = "skyscraper, sha256, keccak, blake3, poseidon2"; + #[cfg(all(feature = "goldilocks", not(feature = "bn254")))] + const VALID: &str = "sha256, keccak, blake3"; Self::parse(s).ok_or_else(|| { format!( - "Invalid hash configuration: '{}'. Valid options: skyscraper, sha256, keccak, \ - blake3, poseidon2", + "Invalid hash configuration: '{}'. Valid options: {VALID}", s ) }) @@ -173,6 +198,7 @@ impl std::str::FromStr for HashConfig { /// Pairwise Skyscraper compression; empty input hashes to 0. Not /// domain-separated (see [`PUBLIC_INPUTS_DST`]). +#[cfg(feature = "bn254")] #[inline] fn hash_skyscraper(elements: &[FieldElement]) -> FieldElement { #[inline] @@ -189,12 +215,36 @@ fn hash_skyscraper(elements: &[FieldElement]) -> FieldElement { } } -/// DST-tagged [`sha2::digest::Digest`] hash (SHA-256, Keccak-256) over -/// `elements`. +/// Reduces a hash digest into a [`FieldElement`] (BN254: straight +/// little-endian mod-p reduction; ~2⁻²⁵⁴ bias — negligible for FS instance +/// binding, but not a uniform field sampler). +#[cfg(feature = "bn254")] +#[inline] +fn digest_to_field(digest: &[u8]) -> FieldElement { + FieldElement::from_le_bytes_mod_order(digest) +} + +/// Reduces a hash digest into a [`FieldElement`] by reducing into the +/// Goldilocks base field and embedding into the cubic extension. /// -/// The final [`FieldElement::from_le_bytes_mod_order`] reduction introduces -/// ~2⁻²⁵⁴ bias — negligible for FS instance binding, but this is not a -/// uniform field sampler. +/// NOTE: the image lies in the base subfield — only ~64 bits of entropy in +/// the field representation. That is fine for public-input/DST *binding* +/// (collision resistance lives in the 256-bit digest; real public-input +/// soundness is the sumcheck public-eval check), but this value must NEVER +/// feed challenge derivation. Optional strengthening: split the digest into +/// 3 chunks via `from_base_prime_field_elems` for a ~192-bit image. +#[cfg(all(feature = "goldilocks", not(feature = "bn254")))] +#[inline] +fn digest_to_field(digest: &[u8]) -> FieldElement { + use { + ark_ff::{Field, PrimeField}, + whir::algebra::fields::Field64, + }; + FieldElement::from_base_prime_field(Field64::from_le_bytes_mod_order(digest)) +} + +/// DST-tagged [`sha2::digest::Digest`] hash (SHA-256, Keccak-256) over +/// `elements`, reduced to a field element via [`digest_to_field`]. #[inline] fn hash_digest(dst: &[u8], elements: &[FieldElement]) -> FieldElement where @@ -205,7 +255,7 @@ where for fe in elements { hasher.update(field_to_bytes_le(*fe)); } - FieldElement::from_le_bytes_mod_order(&hasher.finalize()) + digest_to_field(&hasher.finalize()) } /// Poseidon2 one-shot hash over `elements` (including empty input). @@ -216,6 +266,7 @@ where /// [`poseidon2::poseidon2_hash`] separately provides **length** domain- /// separation, so the two combined mirror what SHA/Keccak/BLAKE3 get via /// the raw [`PUBLIC_INPUTS_DST`] byte prefix. +#[cfg(feature = "bn254")] #[inline] fn hash_poseidon2(elements: &[FieldElement]) -> FieldElement { let mut tagged = Vec::with_capacity(elements.len() + 1); @@ -234,7 +285,7 @@ fn hash_blake3(dst: &[u8], elements: &[FieldElement]) -> FieldElement { for fe in elements { hasher.update(&field_to_bytes_le(*fe)); } - FieldElement::from_le_bytes_mod_order(hasher.finalize().as_bytes()) + digest_to_field(hasher.finalize().as_bytes()) } #[cfg(test)] @@ -244,6 +295,7 @@ mod tests { /// All known variants. If a new variant is added to `HashConfig`, this /// list must be updated — causing the exhaustiveness tests below to fail /// until `from_byte` / `to_byte` are also updated. + #[cfg(feature = "bn254")] const ALL_VARIANTS: &[HashConfig] = &[ HashConfig::Skyscraper, HashConfig::Sha256, @@ -251,6 +303,9 @@ mod tests { HashConfig::Blake3, HashConfig::Poseidon2, ]; + #[cfg(all(feature = "goldilocks", not(feature = "bn254")))] + const ALL_VARIANTS: &[HashConfig] = + &[HashConfig::Sha256, HashConfig::Keccak, HashConfig::Blake3]; #[test] fn from_byte_roundtrips_with_to_byte() { @@ -264,10 +319,10 @@ mod tests { #[test] fn from_byte_returns_none_for_invalid() { - let first_invalid = ALL_VARIANTS.len() as u8; + // 5 is the first byte beyond the full (bn254) variant space. assert!( - HashConfig::from_byte(first_invalid).is_none(), - "from_byte({first_invalid}) should be None" + HashConfig::from_byte(5).is_none(), + "from_byte(5) should be None" ); assert!( HashConfig::from_byte(u8::MAX).is_none(), @@ -275,6 +330,16 @@ mod tests { ); } + /// Goldilocks builds must reject the BN254-only header bytes + /// (0 = Skyscraper, 4 = Poseidon2) gracefully rather than panic. + #[cfg(all(feature = "goldilocks", not(feature = "bn254")))] + #[test] + fn from_byte_rejects_bn254_only_headers() { + assert!(HashConfig::from_byte(0).is_none(), "byte 0 is Skyscraper"); + assert!(HashConfig::from_byte(4).is_none(), "byte 4 is Poseidon2"); + } + + #[cfg(feature = "bn254")] #[test] fn to_byte_values_are_contiguous_from_zero() { let mut bytes: Vec = ALL_VARIANTS.iter().map(|v| v.to_byte()).collect(); diff --git a/provekit/common/src/transcript_sponge.rs b/provekit/common/src/transcript_sponge.rs index eb42294c9..0858bbd64 100644 --- a/provekit/common/src/transcript_sponge.rs +++ b/provekit/common/src/transcript_sponge.rs @@ -5,8 +5,10 @@ //! The branch cost is negligible — the sponge is called O(log n) times //! per proof for Fiat-Shamir challenges, not in a tight inner loop. +#[cfg(feature = "bn254")] +use crate::{poseidon2::Poseidon2Sponge, skyscraper::SkyscraperSponge}; use { - crate::{poseidon2::Poseidon2Sponge, skyscraper::SkyscraperSponge, HashConfig}, + crate::HashConfig, spongefish::{instantiations, DuplexSpongeInterface}, std::fmt, }; @@ -19,7 +21,9 @@ pub enum TranscriptSponge { Sha256(instantiations::SHA256), Blake3(instantiations::Blake3), Keccak(instantiations::Keccak), + #[cfg(feature = "bn254")] Skyscraper(SkyscraperSponge), + #[cfg(feature = "bn254")] Poseidon2(Poseidon2Sponge), } @@ -29,7 +33,9 @@ impl fmt::Debug for TranscriptSponge { Self::Sha256(_) => f.debug_tuple("Sha256").finish(), Self::Blake3(_) => f.debug_tuple("Blake3").finish(), Self::Keccak(_) => f.debug_tuple("Keccak").finish(), + #[cfg(feature = "bn254")] Self::Skyscraper(_) => f.debug_tuple("Skyscraper").finish(), + #[cfg(feature = "bn254")] Self::Poseidon2(_) => f.debug_tuple("Poseidon2").finish(), } } @@ -42,7 +48,9 @@ impl TranscriptSponge { HashConfig::Sha256 => Self::Sha256(Default::default()), HashConfig::Blake3 => Self::Blake3(Default::default()), HashConfig::Keccak => Self::Keccak(Default::default()), + #[cfg(feature = "bn254")] HashConfig::Skyscraper => Self::Skyscraper(Default::default()), + #[cfg(feature = "bn254")] HashConfig::Poseidon2 => Self::Poseidon2(Default::default()), } } @@ -68,9 +76,11 @@ impl DuplexSpongeInterface for TranscriptSponge { Self::Keccak(s) => { s.absorb(input); } + #[cfg(feature = "bn254")] Self::Skyscraper(s) => { s.absorb(input); } + #[cfg(feature = "bn254")] Self::Poseidon2(s) => { s.absorb(input); } @@ -89,9 +99,11 @@ impl DuplexSpongeInterface for TranscriptSponge { Self::Keccak(s) => { s.squeeze(output); } + #[cfg(feature = "bn254")] Self::Skyscraper(s) => { s.squeeze(output); } + #[cfg(feature = "bn254")] Self::Poseidon2(s) => { s.squeeze(output); } @@ -110,9 +122,11 @@ impl DuplexSpongeInterface for TranscriptSponge { Self::Keccak(s) => { s.ratchet(); } + #[cfg(feature = "bn254")] Self::Skyscraper(s) => { s.ratchet(); } + #[cfg(feature = "bn254")] Self::Poseidon2(s) => { s.ratchet(); } diff --git a/provekit/common/src/utils/mod.rs b/provekit/common/src/utils/mod.rs index dff782968..fc64ca4fd 100644 --- a/provekit/common/src/utils/mod.rs +++ b/provekit/common/src/utils/mod.rs @@ -9,6 +9,7 @@ pub mod sumcheck; pub use self::print_abi::PrintAbi; /// Deserializes a BN254 field element from up to 32 little-endian bytes. +#[cfg(feature = "bn254")] #[inline] pub fn bytes_to_field(bytes: &[u8]) -> FieldElement { FieldElement::from_le_bytes_mod_order(bytes) @@ -17,6 +18,7 @@ pub fn bytes_to_field(bytes: &[u8]) -> FieldElement { /// Serializes a BN254 field element to its canonical 32-byte little-endian /// representation. Zero-allocation: copies the 4 canonical limbs directly /// instead of routing through `BigInt::to_bytes_le`'s `Vec`. +#[cfg(feature = "bn254")] #[inline] pub fn field_to_bytes_le(fe: FieldElement) -> [u8; 32] { let limbs = fe.into_bigint().0; @@ -27,21 +29,40 @@ pub fn field_to_bytes_le(fe: FieldElement) -> [u8; 32] { out } +/// Serializes a `Field64_3` element to its canonical 24-byte little-endian +/// representation (three 8-byte Goldilocks base-field coefficients). +#[cfg(all(feature = "goldilocks", not(feature = "bn254")))] +#[inline] +pub fn field_to_bytes_le(fe: FieldElement) -> [u8; 24] { + use ark_serialize::CanonicalSerialize; + let mut out = Vec::with_capacity(24); + fe.serialize_compressed(&mut out) + .expect("Field64_3 serialization is infallible"); + out.try_into().expect("Field64_3 serializes to 24 bytes") +} + use { - crate::{FieldElement, NoirElement}, - ark_ff::{BigInt, Field, PrimeField}, - ruint::{aliases::U256, uint}, + crate::FieldElement, + ark_ff::Field, std::{ fmt::{Display, Formatter, Result as FmtResult}, mem::MaybeUninit, + sync::LazyLock, }, tracing::instrument, }; +#[cfg(feature = "bn254")] +use { + crate::NoirElement, + ark_ff::{BigInt, PrimeField}, +}; -/// 1/2 for the BN254 -pub const HALF: FieldElement = uint_to_field(uint!( - 10944121435919637611123202872628637544274182200208017171849102093287904247809_U256 -)); +/// 1/2 in the proof field. +pub static HALF: LazyLock = LazyLock::new(|| { + FieldElement::from(2u64) + .inverse() + .expect("2 is invertible in a field of odd characteristic") +}); /// Target single-thread workload size for `T`. /// Should ideally be a multiple of a cache line (64 bytes) @@ -76,11 +97,8 @@ fn unzip_double_array( (left, right) } -pub const fn uint_to_field(i: U256) -> FieldElement { - FieldElement::new(BigInt(i.into_limbs())) -} - /// Convert a Noir field element to a native `FieldElement` +#[cfg(feature = "bn254")] #[inline(always)] pub fn noir_to_native(n: NoirElement) -> FieldElement { let limbs = n.into_repr().into_bigint().0; @@ -181,7 +199,7 @@ pub fn batch_inverse_montgomery(values: &[FieldElement]) -> Vec { inverses } -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(feature = "bn254", not(target_arch = "wasm32")))] pub fn convert_mavros_r1cs_to_provekit(mavros_r1cs: &mavros_artifacts::R1CS) -> crate::R1CS { let num_witnesses = mavros_r1cs.witness_layout.size(); let num_constraints = mavros_r1cs.constraints.len(); From cd4f81e744dba44f532ae1dc73c6dee5e0b289da Mon Sep 17 00:00:00 2001 From: Yogesh Shahi Date: Thu, 11 Jun 2026 07:08:37 +0530 Subject: [PATCH 04/11] feat(common): gate BN254-only witness builders and proof IO - Gate the Noir/BN254-coupled witness modules (binops, digits, limbs, ram, scheduling, witness builders) and the `NoirProof`/scheme `FileFormat` impls behind `bn254`; the field-agnostic IO machinery and `PublicInputs` stay shared. - Add the goldilocks `PublicInputs::hash_bytes` twin (24 -> 32 pad). --- provekit/common/src/file/io/mod.rs | 12 ++++- provekit/common/src/witness/mod.rs | 73 ++++++++++++++++++++++++++++++ 2 files changed, 84 insertions(+), 1 deletion(-) diff --git a/provekit/common/src/file/io/mod.rs b/provekit/common/src/file/io/mod.rs index 049c984a7..e3fa1023e 100644 --- a/provekit/common/src/file/io/mod.rs +++ b/provekit/common/src/file/io/mod.rs @@ -3,6 +3,8 @@ mod buf_ext; mod counting_writer; mod json; +#[cfg(feature = "bn254")] +use crate::{NoirProof, NoirProofScheme, Prover, Verifier}; use { self::{ bin::{ @@ -13,7 +15,7 @@ use { counting_writer::CountingWriter, json::{read_json, write_json}, }, - crate::{HashConfig, NoirProof, NoirProofScheme, Prover, Verifier}, + crate::HashConfig, anyhow::Result, serde::{Deserialize, Serialize}, std::{ffi::OsStr, path::Path}, @@ -34,6 +36,7 @@ pub(crate) trait MaybeHashAware { } /// Impl for Prover (has hash config). +#[cfg(feature = "bn254")] impl MaybeHashAware for Prover { fn maybe_hash_config(&self) -> Option { match self { @@ -44,6 +47,7 @@ impl MaybeHashAware for Prover { } /// Impl for Verifier (has hash config). +#[cfg(feature = "bn254")] impl MaybeHashAware for Verifier { fn maybe_hash_config(&self) -> Option { Some(self.hash_config) @@ -51,6 +55,7 @@ impl MaybeHashAware for Verifier { } /// Impl for NoirProof (no hash config). +#[cfg(feature = "bn254")] impl MaybeHashAware for NoirProof { fn maybe_hash_config(&self) -> Option { None @@ -58,6 +63,7 @@ impl MaybeHashAware for NoirProof { } /// Impl for NoirProofScheme (has hash config). +#[cfg(feature = "bn254")] impl MaybeHashAware for NoirProofScheme { fn maybe_hash_config(&self) -> Option { match self { @@ -67,6 +73,7 @@ impl MaybeHashAware for NoirProofScheme { } } +#[cfg(feature = "bn254")] impl FileFormat for NoirProofScheme { const FORMAT: [u8; 8] = crate::binary_format::NOIR_PROOF_SCHEME_FORMAT; const EXTENSION: &'static str = "nps"; @@ -74,6 +81,7 @@ impl FileFormat for NoirProofScheme { const COMPRESSION: Compression = Compression::Zstd; } +#[cfg(feature = "bn254")] impl FileFormat for Prover { const FORMAT: [u8; 8] = crate::binary_format::PROVER_FORMAT; const EXTENSION: &'static str = "pkp"; @@ -81,6 +89,7 @@ impl FileFormat for Prover { const COMPRESSION: Compression = Compression::Xz; } +#[cfg(feature = "bn254")] impl FileFormat for Verifier { const FORMAT: [u8; 8] = crate::binary_format::VERIFIER_FORMAT; const EXTENSION: &'static str = "pkv"; @@ -88,6 +97,7 @@ impl FileFormat for Verifier { const COMPRESSION: Compression = Compression::Zstd; } +#[cfg(feature = "bn254")] impl FileFormat for NoirProof { const FORMAT: [u8; 8] = crate::binary_format::NOIR_PROOF_FORMAT; const EXTENSION: &'static str = "np"; diff --git a/provekit/common/src/witness/mod.rs b/provekit/common/src/witness/mod.rs index 403a58e45..603dcb987 100644 --- a/provekit/common/src/witness/mod.rs +++ b/provekit/common/src/witness/mod.rs @@ -1,9 +1,19 @@ +// The witness builders are Noir/BN254-coupled (BigInt decompositions, EC +// gadgets, Noir witness maps); Phase 1 of the goldilocks build hand-builds +// R1CS witnesses instead. +#[cfg(feature = "bn254")] mod binops; +#[cfg(feature = "bn254")] mod digits; +#[cfg(feature = "bn254")] mod limbs; +#[cfg(feature = "bn254")] mod ram; +#[cfg(feature = "bn254")] mod scheduling; +#[cfg(feature = "bn254")] mod witness_builder; +#[cfg(feature = "bn254")] mod witness_generator; use { @@ -14,6 +24,7 @@ use { ark_ff::One, serde::{Deserialize, Serialize}, }; +#[cfg(feature = "bn254")] pub use { binops::BINOP_ATOMIC_BITS, digits::{decompose_into_digits, DigitalDecompositionWitnesses}, @@ -98,11 +109,24 @@ impl PublicInputs { /// /// Used as the Fiat-Shamir instance tag binding the transcript to these /// public inputs. + #[cfg(feature = "bn254")] #[inline] #[must_use] pub fn hash_bytes(&self, config: HashConfig) -> [u8; 32] { field_to_bytes_le(self.hash(config)) } + + /// Returns [`Self::hash`] as a 32-byte little-endian instance tag: the + /// canonical 24-byte `Field64_3` serialization, zero-padded to keep the + /// transcript instance width stable. + #[cfg(all(feature = "goldilocks", not(feature = "bn254")))] + #[inline] + #[must_use] + pub fn hash_bytes(&self, config: HashConfig) -> [u8; 32] { + let mut out = [0u8; 32]; + out[..24].copy_from_slice(&field_to_bytes_le(self.hash(config))); + out + } } impl Default for PublicInputs { @@ -115,6 +139,7 @@ impl Default for PublicInputs { mod tests { use {super::*, proptest::prelude::*}; + #[cfg(feature = "bn254")] const ALL_CONFIGS: [HashConfig; 5] = [ HashConfig::Skyscraper, HashConfig::Sha256, @@ -122,6 +147,9 @@ mod tests { HashConfig::Blake3, HashConfig::Poseidon2, ]; + #[cfg(all(feature = "goldilocks", not(feature = "bn254")))] + const ALL_CONFIGS: [HashConfig; 3] = + [HashConfig::Sha256, HashConfig::Keccak, HashConfig::Blake3]; fn fe(n: u64) -> FieldElement { FieldElement::from(n) @@ -157,6 +185,7 @@ mod tests { } } + #[cfg(feature = "bn254")] #[test] fn hash_bytes_is_le_serialization_of_hash() { let inputs = pi(&[7, 13]); @@ -169,8 +198,24 @@ mod tests { } } + #[cfg(all(feature = "goldilocks", not(feature = "bn254")))] + #[test] + fn hash_bytes_is_padded_le_serialization_of_hash() { + let inputs = pi(&[7, 13]); + for config in ALL_CONFIGS { + let bytes = inputs.hash_bytes(config); + assert_eq!( + bytes[..24], + field_to_bytes_le(inputs.hash(config)), + "{config:?}: hash_bytes[..24] must equal LE(hash())" + ); + assert_eq!(bytes[24..], [0u8; 8], "{config:?}: padding must be zero"); + } + } + // --- empty input --- + #[cfg(feature = "bn254")] #[test] fn skyscraper_empty_returns_zero() { // Transcript-visible back-compat: Skyscraper hashes [] to 0. @@ -262,6 +307,7 @@ mod tests { // mod-reduction, Skyscraper compression order) will fail these and must be // a deliberate, reviewed format change. + #[cfg(feature = "bn254")] #[test] fn kat_empty_skyscraper() { // Skyscraper on empty input is 0 by construction; no DST. @@ -269,6 +315,7 @@ mod tests { assert_eq!(got, [0u8; 32], "Skyscraper empty-input KAT drift"); } + #[cfg(feature = "bn254")] #[test] fn kat_one_two_skyscraper() { let got = pi(&[1, 2]).hash_bytes(HashConfig::Skyscraper); @@ -283,42 +330,49 @@ mod tests { ); } + #[cfg(feature = "bn254")] #[test] fn kat_empty_sha256() { let got = PublicInputs::new().hash_bytes(HashConfig::Sha256); assert_eq!(got, KAT_EMPTY_SHA256, "SHA-256 empty-input KAT drift"); } + #[cfg(feature = "bn254")] #[test] fn kat_one_two_sha256() { let got = pi(&[1, 2]).hash_bytes(HashConfig::Sha256); assert_eq!(got, KAT_ONE_TWO_SHA256, "SHA-256 [1, 2] KAT drift"); } + #[cfg(feature = "bn254")] #[test] fn kat_empty_keccak() { let got = PublicInputs::new().hash_bytes(HashConfig::Keccak); assert_eq!(got, KAT_EMPTY_KECCAK, "Keccak-256 empty-input KAT drift"); } + #[cfg(feature = "bn254")] #[test] fn kat_one_two_keccak() { let got = pi(&[1, 2]).hash_bytes(HashConfig::Keccak); assert_eq!(got, KAT_ONE_TWO_KECCAK, "Keccak-256 [1, 2] KAT drift"); } + #[cfg(feature = "bn254")] #[test] fn kat_empty_blake3() { let got = PublicInputs::new().hash_bytes(HashConfig::Blake3); assert_eq!(got, KAT_EMPTY_BLAKE3, "BLAKE3 empty-input KAT drift"); } + #[cfg(feature = "bn254")] #[test] fn kat_one_two_blake3() { let got = pi(&[1, 2]).hash_bytes(HashConfig::Blake3); assert_eq!(got, KAT_ONE_TWO_BLAKE3, "BLAKE3 [1, 2] KAT drift"); } + #[cfg(feature = "bn254")] #[test] fn kat_empty_poseidon2() { // Non-zero: even with no user inputs, the DST field element is @@ -327,6 +381,7 @@ mod tests { assert_eq!(got, KAT_EMPTY_POSEIDON2, "Poseidon2 empty-input KAT drift"); } + #[cfg(feature = "bn254")] #[test] fn kat_one_two_poseidon2() { let got = pi(&[1, 2]).hash_bytes(HashConfig::Poseidon2); @@ -335,31 +390,37 @@ mod tests { // Frozen outputs. Regenerate only for a deliberate, reviewed format change. + #[cfg(feature = "bn254")] const KAT_EMPTY_SHA256: [u8; 32] = [ 0xc6, 0xa2, 0x48, 0x23, 0x44, 0xd4, 0x29, 0xf5, 0x53, 0x37, 0xc3, 0xb6, 0x87, 0xb5, 0xc3, 0x54, 0x47, 0x5c, 0x7c, 0x7f, 0x17, 0xac, 0x26, 0xeb, 0x47, 0x92, 0x78, 0x00, 0x11, 0xfe, 0xa0, 0x26, ]; + #[cfg(feature = "bn254")] const KAT_ONE_TWO_SHA256: [u8; 32] = [ 0x0f, 0x7b, 0x4c, 0xec, 0x9b, 0x45, 0x3f, 0xe5, 0x2f, 0xf4, 0x32, 0x96, 0x96, 0x60, 0xd2, 0xd8, 0x92, 0x5e, 0x7c, 0x34, 0xdd, 0x27, 0x59, 0x05, 0x7f, 0xc0, 0xf2, 0x73, 0x43, 0x53, 0x76, 0x1d, ]; + #[cfg(feature = "bn254")] const KAT_EMPTY_KECCAK: [u8; 32] = [ 0xb2, 0x2f, 0xf9, 0x91, 0x4f, 0xaf, 0xbd, 0xd0, 0x3c, 0x4f, 0xa2, 0x7a, 0xb0, 0x8a, 0x34, 0x5f, 0x0e, 0x1c, 0x62, 0x53, 0xf4, 0xc0, 0x02, 0x37, 0x2b, 0xaa, 0x50, 0x3c, 0x82, 0xb1, 0x2d, 0x23, ]; + #[cfg(feature = "bn254")] const KAT_ONE_TWO_KECCAK: [u8; 32] = [ 0xb1, 0xe0, 0x10, 0xfa, 0x01, 0x19, 0xcf, 0x35, 0x85, 0xac, 0x34, 0xb3, 0xdb, 0xb0, 0x11, 0x17, 0x57, 0xa9, 0x63, 0xff, 0x8d, 0x3c, 0x76, 0xc9, 0xf7, 0xc6, 0x79, 0xb0, 0xfb, 0xf1, 0x41, 0x16, ]; + #[cfg(feature = "bn254")] const KAT_EMPTY_BLAKE3: [u8; 32] = [ 0x7b, 0x01, 0x61, 0xea, 0x26, 0xb6, 0x36, 0xbc, 0x69, 0x23, 0xf3, 0x87, 0x7d, 0x4d, 0xca, 0xb8, 0xf7, 0xa9, 0xb4, 0x8d, 0x38, 0x56, 0x01, 0x13, 0x93, 0x57, 0xa0, 0x55, 0x37, 0x0c, 0xda, 0x27, ]; + #[cfg(feature = "bn254")] const KAT_ONE_TWO_BLAKE3: [u8; 32] = [ 0x84, 0x08, 0x71, 0x4e, 0xb3, 0xb2, 0x8e, 0x8f, 0xd6, 0xb5, 0xd0, 0x3d, 0x35, 0x99, 0x08, 0x4e, 0x47, 0x7d, 0x1f, 0xf9, 0xf5, 0x79, 0xc1, 0x46, 0xb4, 0x28, 0x84, 0xa5, 0x6b, 0xc5, @@ -369,11 +430,13 @@ mod tests { // the empty-input case is still a one-element absorb of the DST tag // (role-DS) with the length-IV set for `n = 1`. The DST field element // is derived as SHA256(PUBLIC_INPUTS_DST) reduced mod p. + #[cfg(feature = "bn254")] const KAT_EMPTY_POSEIDON2: [u8; 32] = [ 0x88, 0x8d, 0xd0, 0xb7, 0xbb, 0x12, 0xee, 0x46, 0xf0, 0x73, 0x14, 0x15, 0x2c, 0xec, 0x94, 0xf8, 0x5f, 0x5a, 0xbd, 0x58, 0xe3, 0xfd, 0x8a, 0x96, 0xb5, 0x18, 0x4c, 0x23, 0xd8, 0x7d, 0xf3, 0x01, ]; + #[cfg(feature = "bn254")] const KAT_ONE_TWO_POSEIDON2: [u8; 32] = [ 0x54, 0xfa, 0xbf, 0xce, 0x1b, 0xe4, 0xbb, 0xe9, 0x92, 0xb0, 0x6a, 0x42, 0xeb, 0xf7, 0x2d, 0xf4, 0x47, 0x8a, 0x2d, 0xb1, 0x9c, 0x5f, 0x35, 0xbf, 0x7c, 0x62, 0xba, 0x9d, 0x65, 0x67, @@ -382,6 +445,7 @@ mod tests { // --- property tests --- + #[cfg(feature = "bn254")] fn any_hash_config() -> impl Strategy { prop_oneof![ Just(HashConfig::Skyscraper), @@ -392,6 +456,15 @@ mod tests { ] } + #[cfg(all(feature = "goldilocks", not(feature = "bn254")))] + fn any_hash_config() -> impl Strategy { + prop_oneof![ + Just(HashConfig::Sha256), + Just(HashConfig::Keccak), + Just(HashConfig::Blake3), + ] + } + fn any_public_inputs() -> impl Strategy { prop::collection::vec(any::(), 0..32) .prop_map(|v| PublicInputs::from_vec(v.into_iter().map(FieldElement::from).collect())) From f459ccf6e6deca8ebac9aa7968aca754215f3bd8 Mon Sep 17 00:00:00 2001 From: Yogesh Shahi Date: Thu, 11 Jun 2026 07:08:43 +0530 Subject: [PATCH 05/11] feat(prover): gate Noir entry points and add the goldilocks roundtrip test - Gate the `Prove`/`Verify` traits, Noir/Mavros prover paths, and EC/ bigint gadgets behind `bn254`; expose `whir_r1cs` publicly under goldilocks (and in the verifier) so hand-built R1CS instances can be proved/verified directly. - Add `roundtrip_tests.rs`: a `Field64_3` `x*y=z` prove/verify roundtrip plus soundness negatives, the Phase-1 milestone. --- provekit/prover/src/lib.rs | 26 ++++- provekit/prover/src/roundtrip_tests.rs | 135 +++++++++++++++++++++++++ provekit/prover/src/whir_r1cs.rs | 8 +- provekit/verifier/src/lib.rs | 6 +- 4 files changed, 166 insertions(+), 9 deletions(-) create mode 100644 provekit/prover/src/roundtrip_tests.rs diff --git a/provekit/prover/src/lib.rs b/provekit/prover/src/lib.rs index 1f5474a9f..1826a0c47 100644 --- a/provekit/prover/src/lib.rs +++ b/provekit/prover/src/lib.rs @@ -1,5 +1,6 @@ -#[cfg(test)] +#[cfg(all(test, feature = "bn254"))] use crate::r1cs::R1CSSolver; +#[cfg(feature = "bn254")] use { crate::{ r1cs::{CompressedLayers, CompressedR1CS}, @@ -20,27 +21,42 @@ use { bn254_blackbox_solver::Bn254BlackBoxSolver, nargo::foreign_calls::DefaultForeignCallBuilder, noir_artifact_cli::fs::inputs::read_inputs_from_file, noirc_abi::InputMap, }; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(feature = "bn254", not(target_arch = "wasm32")))] use { mavros_vm::interpreter as mavros_interpreter, provekit_common::MavrosProver, std::path::Path, whir::transcript::VerifierMessage, }; +#[cfg(feature = "bn254")] pub(crate) mod bigint_mod; +#[cfg(feature = "bn254")] pub(crate) mod ec_arith; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(feature = "bn254", not(target_arch = "wasm32")))] pub mod input_utils; +#[cfg(feature = "bn254")] mod logging; +#[cfg(feature = "bn254")] pub(crate) mod r1cs; +#[cfg(test)] +mod roundtrip_tests; +// Private under bn254 (the `Prove` trait is the public entry point); public +// under goldilocks, where `WhirR1CSProver` is the only proving API for +// hand-built R1CS instances. +#[cfg(feature = "bn254")] mod whir_r1cs; +#[cfg(all(feature = "goldilocks", not(feature = "bn254")))] +pub mod whir_r1cs; +#[cfg(feature = "bn254")] mod witness; // Public re-exports for items used by integration tests and benchmarks. +#[cfg(feature = "bn254")] pub use {ec_arith::ec_scalar_mul, r1cs::solve_witness_vec}; /// `prove` and `prove_with_toml` are native-only (cfg-gated out on wasm32). /// `prove_with_witness` is available on all targets. `MavrosProver` does not /// support `prove_with_witness` (errors at runtime). +#[cfg(feature = "bn254")] pub trait Prove { #[cfg(all(feature = "witness-generation", not(target_arch = "wasm32")))] fn prove(self, input_map: InputMap) -> Result; @@ -83,6 +99,7 @@ fn generate_noir_witness( .witness) } +#[cfg(feature = "bn254")] impl Prove for NoirProver { #[cfg(all(feature = "witness-generation", not(target_arch = "wasm32")))] #[instrument(skip_all)] @@ -271,7 +288,7 @@ impl Prove for NoirProver { } } -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(feature = "bn254", not(target_arch = "wasm32")))] impl Prove for MavrosProver { #[cfg(feature = "witness-generation")] fn prove(mut self, input_map: InputMap) -> Result { @@ -405,6 +422,7 @@ impl Prove for MavrosProver { } } +#[cfg(feature = "bn254")] impl Prove for Prover { #[cfg(all(feature = "witness-generation", not(target_arch = "wasm32")))] fn prove(self, input_map: InputMap) -> Result { diff --git a/provekit/prover/src/roundtrip_tests.rs b/provekit/prover/src/roundtrip_tests.rs new file mode 100644 index 000000000..75416bd71 --- /dev/null +++ b/provekit/prover/src/roundtrip_tests.rs @@ -0,0 +1,135 @@ +//! End-to-end toy-circuit roundtrip tests, runnable under either field +//! feature (`bn254` or `goldilocks`). +//! +//! The circuit is a single constraint `x * y = z` with `z` public. The +//! witness layout is load-bearing: `witness[0]` is the constant `1`, +//! public inputs occupy `1..=num_public_inputs`, so the full witness is +//! `[1, z, x, y]`. The hash configuration is pinned to SHA-256 because the +//! BN254 default (Skyscraper) does not exist in goldilocks builds. + +use { + crate::whir_r1cs::WhirR1CSProver, + ark_ff::One, + provekit_common::{ + register_ntt, FieldElement, HashConfig, PublicInputs, TranscriptSponge, WhirR1CSProof, + WhirR1CSScheme, WhirR1CSSchemeBuilder, R1CS, + }, + provekit_verifier::whir_r1cs::WhirR1CSVerifier, + whir::transcript::ProverState, +}; + +const HASH: HashConfig = HashConfig::Sha256; + +/// Build the toy R1CS for `x * y = z` over witness layout `[1, z, x, y]`. +fn toy_r1cs() -> R1CS { + let mut r1cs = R1CS::new(); + r1cs.add_witnesses(4); + r1cs.num_public_inputs = 1; + let one = FieldElement::one(); + // A·w = x (index 2), B·w = y (index 3), C·w = z (index 1) + r1cs.add_constraint(&[(one, 2)], &[(one, 3)], &[(one, 1)]); + r1cs +} + +/// Full witness `[1, z, x, y]` for given x, y (z computed). +fn toy_witness(x: u64, y: u64) -> Vec { + let xf = FieldElement::from(x); + let yf = FieldElement::from(y); + vec![FieldElement::one(), xf * yf, xf, yf] +} + +/// Prove the toy circuit with the given full witness and public inputs. +fn prove( + r1cs: &R1CS, + full_witness: Vec, + public_inputs: &PublicInputs, +) -> anyhow::Result<(WhirR1CSScheme, WhirR1CSProof)> { + register_ntt(); + let scheme = WhirR1CSScheme::new_for_r1cs( + r1cs, + full_witness.len(), // w1_size: everything in w1, no challenge phase + 0, + vec![], + true, + HASH, + ); + + let instance = public_inputs.hash_bytes(HASH); + let ds = scheme.create_domain_separator().instance(&instance); + let mut merlin = ProverState::new(&ds, TranscriptSponge::from_config(HASH)); + + let commitment = scheme.commit( + &mut merlin, + r1cs.num_witnesses(), + r1cs.num_constraints(), + full_witness.clone(), + true, + )?; + let proof = scheme.prove_noir( + merlin, + r1cs.clone(), + vec![commitment], + full_witness, + public_inputs, + )?; + Ok((scheme, proof)) +} + +#[test] +fn toy_roundtrip_proves_and_verifies() { + let r1cs = toy_r1cs(); + let witness = toy_witness(3, 5); + let public_inputs = PublicInputs::from_vec(vec![witness[1]]); + + let (scheme, proof) = prove(&r1cs, witness, &public_inputs).expect("proving failed"); + scheme + .verify(&proof, &public_inputs, &r1cs) + .expect("verification failed"); +} + +#[test] +fn corrupted_witness_is_rejected() { + let r1cs = toy_r1cs(); + let mut witness = toy_witness(3, 5); + // Break the constraint: z stays 15 but y becomes 6. + witness[3] = FieldElement::from(6u64); + let public_inputs = PublicInputs::from_vec(vec![witness[1]]); + + // Proving may fail outright; if it mechanically succeeds, the proof + // must not verify. + if let Ok((scheme, proof)) = prove(&r1cs, witness, &public_inputs) { + assert!( + scheme.verify(&proof, &public_inputs, &r1cs).is_err(), + "proof over a non-satisfying witness must not verify" + ); + } +} + +#[test] +fn tampered_public_input_is_rejected() { + let r1cs = toy_r1cs(); + let witness = toy_witness(3, 5); + let public_inputs = PublicInputs::from_vec(vec![witness[1]]); + + let (scheme, proof) = prove(&r1cs, witness, &public_inputs).expect("proving failed"); + + let tampered = PublicInputs::from_vec(vec![FieldElement::from(16u64)]); + assert!( + scheme.verify(&proof, &tampered, &r1cs).is_err(), + "verification must fail when public inputs are tampered after proving" + ); +} + +/// The goldilocks field must be the ~192-bit cubic extension and clear the +/// 128-bit security floor the WHIR parameters assume. +#[cfg(all(feature = "goldilocks", not(feature = "bn254")))] +#[test] +fn goldilocks_field_size_is_192_bits() { + use whir::algebra::fields::FieldWithSize; + let bits = ::field_size_bits(); + assert!( + (190.0..=194.0).contains(&bits), + "expected ~192-bit field, got {bits}" + ); + assert!(bits >= 128.0, "below the 128-bit security floor"); +} diff --git a/provekit/prover/src/whir_r1cs.rs b/provekit/prover/src/whir_r1cs.rs index 3b1a5a97e..450417a60 100644 --- a/provekit/prover/src/whir_r1cs.rs +++ b/provekit/prover/src/whir_r1cs.rs @@ -28,7 +28,7 @@ use { transcript::{ProverState, VerifierMessage}, }, }; -#[cfg(not(target_arch = "wasm32"))] +#[cfg(all(feature = "bn254", not(target_arch = "wasm32")))] use { mavros_artifacts::{ConstraintsLayout, WitnessLayout}, mavros_vm::interpreter::WitgenResult, @@ -64,7 +64,7 @@ pub trait WhirR1CSProver { public_inputs: &PublicInputs, ) -> Result; - #[cfg(not(target_arch = "wasm32"))] + #[cfg(all(feature = "bn254", not(target_arch = "wasm32")))] fn prove_mavros( &self, merlin: ProverState, @@ -186,7 +186,7 @@ impl WhirR1CSProver for WhirR1CSScheme { ) } - #[cfg(not(target_arch = "wasm32"))] + #[cfg(all(feature = "bn254", not(target_arch = "wasm32")))] #[instrument(skip_all)] fn prove_mavros( &self, @@ -578,7 +578,7 @@ pub fn run_zk_sumcheck_prover( let g_at_minus_one = g_poly[0] - g_poly[1] + g_poly[2] - g_poly[3]; let combined_at_em1 = hhat_i_at_em1 + rho * g_at_minus_one; - combined_hhat_i_coeffs[2] = HALF + combined_hhat_i_coeffs[2] = *HALF * (saved_val_for_sumcheck_equality_assertion + combined_at_em1 - combined_hhat_i_coeffs[0] - combined_hhat_i_coeffs[0] diff --git a/provekit/verifier/src/lib.rs b/provekit/verifier/src/lib.rs index 1c3461fa8..8c4b8fb47 100644 --- a/provekit/verifier/src/lib.rs +++ b/provekit/verifier/src/lib.rs @@ -1,5 +1,6 @@ -mod whir_r1cs; +pub mod whir_r1cs; +#[cfg(feature = "bn254")] use { crate::whir_r1cs::WhirR1CSVerifier, anyhow::{Context, Result}, @@ -7,10 +8,13 @@ use { tracing::instrument, }; +/// Verify a [`NoirProof`] against a Noir proof scheme's [`Verifier`]. +#[cfg(feature = "bn254")] pub trait Verify { fn verify(&mut self, proof: &NoirProof) -> Result<()>; } +#[cfg(feature = "bn254")] impl Verify for Verifier { #[instrument(skip_all)] fn verify(&mut self, proof: &NoirProof) -> Result<()> { From 13ce0bb7bb063913027871a3a95ffc1ef2f16e06 Mon Sep 17 00:00:00 2001 From: Yogesh Shahi Date: Thu, 11 Jun 2026 16:28:08 +0530 Subject: [PATCH 06/11] feat(build): finalize field-feature flags and drop the ruint dependency --- Cargo.lock | 829 +++++++++++-------------------------- Cargo.toml | 1 - provekit/common/Cargo.toml | 3 +- provekit/common/build.rs | 27 ++ provekit/prover/Cargo.toml | 6 +- 5 files changed, 287 insertions(+), 579 deletions(-) create mode 100644 provekit/common/build.rs diff --git a/Cargo.lock b/Cargo.lock index 6f567c1b7..6304dbf40 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,8 +29,8 @@ version = "1.0.0-beta.19" source = "git+https://github.com/noir-lang/noir?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" dependencies = [ "ark-bn254", - "ark-ff 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-std", "cfg-if", "hex", "num-bigint", @@ -45,7 +45,7 @@ dependencies = [ "acir", "acvm_blackbox_solver", "brillig_vm", - "indexmap 2.13.1", + "indexmap 2.13.0", "rustc-hash", "serde", "thiserror 1.0.69", @@ -66,7 +66,7 @@ dependencies = [ "keccak 0.2.0-rc.2", "log", "p256", - "sha2 0.11.0", + "sha2 0.11.0-rc.5", "thiserror 1.0.69", ] @@ -123,16 +123,6 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" -[[package]] -name = "alloy-rlp" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc90b1e703d3c03f4ff7f48e82dd0bc1c8211ab7d079cd836a06fcfeb06651cb" -dependencies = [ - "arrayvec", - "bytes", -] - [[package]] name = "android_system_properties" version = "0.1.5" @@ -242,8 +232,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" dependencies = [ "ark-ec", - "ark-ff 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-std", ] [[package]] @@ -253,10 +243,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" dependencies = [ "ahash", - "ark-ff 0.5.0", + "ark-ff", "ark-poly", - "ark-serialize 0.5.0", - "ark-std 0.5.0", + "ark-serialize", + "ark-std", "educe", "fnv", "hashbrown 0.15.5", @@ -267,54 +257,16 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ark-ff" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" -dependencies = [ - "ark-ff-asm 0.3.0", - "ark-ff-macros 0.3.0", - "ark-serialize 0.3.0", - "ark-std 0.3.0", - "derivative", - "num-bigint", - "num-traits", - "paste", - "rustc_version 0.3.3", - "zeroize", -] - -[[package]] -name = "ark-ff" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" -dependencies = [ - "ark-ff-asm 0.4.2", - "ark-ff-macros 0.4.2", - "ark-serialize 0.4.2", - "ark-std 0.4.0", - "derivative", - "digest 0.10.7", - "itertools 0.10.5", - "num-bigint", - "num-traits", - "paste", - "rustc_version 0.4.1", - "zeroize", -] - [[package]] name = "ark-ff" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" dependencies = [ - "ark-ff-asm 0.5.0", - "ark-ff-macros 0.5.0", - "ark-serialize 0.5.0", - "ark-std 0.5.0", + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", "arrayvec", "digest 0.10.7", "educe", @@ -325,26 +277,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ark-ff-asm" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-ff-asm" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" -dependencies = [ - "quote", - "syn 1.0.109", -] - [[package]] name = "ark-ff-asm" version = "0.5.0" @@ -355,31 +287,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "ark-ff-macros" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" -dependencies = [ - "num-bigint", - "num-traits", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-ff-macros" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" -dependencies = [ - "num-bigint", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "ark-ff-macros" version = "0.5.0" @@ -401,8 +308,8 @@ checksum = "ef677b59f5aff4123207c4dceb1c0ec8fdde2d4af7886f48be42ad864bfa0352" dependencies = [ "ark-bn254", "ark-ec", - "ark-ff 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-std", ] [[package]] @@ -412,35 +319,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" dependencies = [ "ahash", - "ark-ff 0.5.0", - "ark-serialize 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-serialize", + "ark-std", "educe", "fnv", "hashbrown 0.15.5", ] -[[package]] -name = "ark-serialize" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" -dependencies = [ - "ark-std 0.3.0", - "digest 0.9.0", -] - -[[package]] -name = "ark-serialize" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" -dependencies = [ - "ark-std 0.4.0", - "digest 0.10.7", - "num-bigint", -] - [[package]] name = "ark-serialize" version = "0.5.0" @@ -448,7 +334,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" dependencies = [ "ark-serialize-derive", - "ark-std 0.5.0", + "ark-std", "arrayvec", "digest 0.10.7", "num-bigint", @@ -465,26 +351,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "ark-std" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" -dependencies = [ - "num-traits", - "rand 0.8.5", -] - -[[package]] -name = "ark-std" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" -dependencies = [ - "num-traits", - "rand 0.8.5", -] - [[package]] name = "ark-std" version = "0.5.0" @@ -595,17 +461,6 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -[[package]] -name = "auto_impl" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - [[package]] name = "autocfg" version = "1.5.0" @@ -772,11 +627,11 @@ dependencies = [ [[package]] name = "blake2" -version = "0.11.0-rc.6" +version = "0.11.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "061f1a09225e328e1ffbb378d2d49923c0ca5fee19fb5ac1cc9c1e9d52b93690" +checksum = "d52965399b470437fc7f4d4b51134668dbc96573fea6f1b83318a420e4605745" dependencies = [ - "digest 0.11.3", + "digest 0.11.2", ] [[package]] @@ -827,12 +682,12 @@ name = "bn254-multiplier" version = "0.1.0" dependencies = [ "ark-bn254", - "ark-ff 0.5.0", + "ark-ff", "bn254-multiplier-codegen", "divan", "fp-rounding", "hla", - "primitive-types 0.13.1", + "primitive-types", "proptest", "rand 0.9.2", "seq-macro", @@ -854,7 +709,7 @@ dependencies = [ "acvm_blackbox_solver", "ark-bn254", "ark-ec", - "ark-ff 0.5.0", + "ark-ff", "ark-grumpkin", "hex", ] @@ -952,9 +807,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.58" +version = "1.2.57" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" +checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" dependencies = [ "find-msvc-tools", "jobserver", @@ -1027,7 +882,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common 0.1.6", + "crypto-common 0.1.7", "inout", ] @@ -1094,9 +949,9 @@ dependencies = [ [[package]] name = "cmov" -version = "0.5.3" +version = "0.5.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" +checksum = "de0758edba32d61d1fd9f4d69491b47604b91ee2f7e6b33de7e54ca4ebe55dc3" [[package]] name = "cobs" @@ -1294,9 +1149,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpubits" -version = "0.1.1" +version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" +checksum = "5ef0c543070d296ea414df2dd7625d1b24866ce206709d8a4a424f28377f5861" [[package]] name = "cpufeatures" @@ -1388,9 +1243,9 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" -version = "0.7.3" +version = "0.7.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42a0d26b245348befa0c121944541476763dcc46ede886c88f9d12e1697d27c3" +checksum = "9fde2467e74147f492aebb834985186b2c74761927b8b9b3bd303bcb2e72199d" dependencies = [ "cpubits", "ctutils", @@ -1404,9 +1259,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" +checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" dependencies = [ "generic-array", "typenum", @@ -1446,9 +1301,9 @@ dependencies = [ [[package]] name = "ctutils" -version = "0.4.2" +version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" +checksum = "1005a6d4446f5120ef475ad3d2af2b30c49c2c9c6904258e3bb30219bebed5e4" dependencies = [ "cmov", "subtle", @@ -1551,17 +1406,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "derive-where" version = "1.6.1" @@ -1573,15 +1417,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - [[package]] name = "digest" version = "0.10.7" @@ -1590,15 +1425,15 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", "const-oid 0.9.6", - "crypto-common 0.1.6", + "crypto-common 0.1.7", "subtle", ] [[package]] name = "digest" -version = "0.11.3" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" +checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" dependencies = [ "block-buffer 0.12.0", "const-oid 0.10.2", @@ -1713,16 +1548,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.17.0-rc.18" +version = "0.17.0-rc.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "54fb064faabbee66e1fc8e5c5a9458d4269dc2d8b638fe86a425adb2510d1a96" +checksum = "91bbdd377139884fafcad8dc43a760a3e1e681aa26db910257fa6535b70e1829" dependencies = [ "der 0.8.0", - "digest 0.11.3", + "digest 0.11.2", "elliptic-curve", "rfc6979", - "signature 3.0.0", - "spki 0.8.0", + "signature 3.0.0-rc.10", + "spki 0.8.0-rc.4", "zeroize", ] @@ -1746,18 +1581,18 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elliptic-curve" -version = "0.14.0-rc.32" +version = "0.14.0-rc.29" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cda94f31325c4275e9706adecbb6f0650dee2f904c915a98e3d81adaaaa757aa" +checksum = "e84043d573efd4ac9d2d125817979a379204bf7e328b25a4a30487e8d100e618" dependencies = [ "base16ct", "crypto-bigint", "crypto-common 0.2.1", - "digest 0.11.3", + "digest 0.11.2", "hybrid-array", "once_cell", "pem-rfc7468 1.0.0", - "pkcs8 0.11.0", + "pkcs8 0.11.0-rc.11", "rand_core 0.10.0", "rustcrypto-ff", "rustcrypto-group", @@ -1821,9 +1656,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "1.0.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" +checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f" dependencies = [ "log", "regex", @@ -1831,9 +1666,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.10" +version = "0.11.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" +checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d" dependencies = [ "env_filter", "log", @@ -1881,28 +1716,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" -[[package]] -name = "fastrlp" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" -dependencies = [ - "arrayvec", - "auto_impl", - "bytes", -] - -[[package]] -name = "fastrlp" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce8dba4714ef14b8274c371879b175aa55b16b30f269663f19d576f380018dc4" -dependencies = [ - "arrayvec", - "auto_impl", - "bytes", -] - [[package]] name = "fd-lock" version = "3.0.13" @@ -1940,7 +1753,7 @@ checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" dependencies = [ "cfg-if", "libc", - "libredox 0.1.15", + "libredox 0.1.14", ] [[package]] @@ -2157,9 +1970,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.9" +version = "0.14.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" +checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" dependencies = [ "typenum", "version_check", @@ -2226,7 +2039,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.13.1", + "indexmap 2.13.0", "slab", "tokio", "tokio-util", @@ -2284,7 +2097,7 @@ checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" dependencies = [ "atomic-polyfill", "hash32", - "rustc_version 0.4.1", + "rustc_version", "serde", "spin 0.9.8", "stable_deref_trait", @@ -2331,11 +2144,11 @@ dependencies = [ [[package]] name = "hmac" -version = "0.13.0" +version = "0.13.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" +checksum = "ef451d73f36d8a3f93ad32c332ea01146c9650e1ec821a9b0e46c01277d544f8" dependencies = [ - "digest 0.11.3", + "digest 0.11.2", ] [[package]] @@ -2385,9 +2198,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hybrid-array" -version = "0.4.11" +version = "0.4.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "08d46837a0ed51fe95bd3b05de33cd64a1ee88fc797477ca48446872504507c5" +checksum = "8655f91cd07f2b9d0c24137bd650fe69617773435ee5ec83022377777ce65ef1" dependencies = [ "subtle", "typenum", @@ -2396,9 +2209,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.9.0" +version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" +checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" dependencies = [ "atomic-waker", "bytes", @@ -2411,6 +2224,7 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", + "pin-utils", "smallvec", "tokio", "want", @@ -2500,13 +2314,12 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" +checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" dependencies = [ "displaydoc", "potential_utf", - "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -2514,9 +2327,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" +checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" dependencies = [ "displaydoc", "litemap", @@ -2527,9 +2340,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" +checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -2541,15 +2354,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" +checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" [[package]] name = "icu_properties" -version = "2.2.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" +checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" dependencies = [ "icu_collections", "icu_locale_core", @@ -2561,15 +2374,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.2.0" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" +checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" [[package]] name = "icu_provider" -version = "2.2.0" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" +checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" dependencies = [ "displaydoc", "icu_locale_core", @@ -2628,15 +2441,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "impl-codec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" -dependencies = [ - "parity-scale-codec", -] - [[package]] name = "impl-codec" version = "0.7.1" @@ -2676,9 +2480,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.1" +version = "2.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" +checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" dependencies = [ "equivalent", "hashbrown 0.16.1", @@ -2733,9 +2537,9 @@ checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iri-string" -version = "0.7.12" +version = "0.7.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" +checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" dependencies = [ "memchr", "serde", @@ -2792,9 +2596,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.18" +version = "1.0.17" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" +checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" [[package]] name = "jni" @@ -2805,7 +2609,7 @@ dependencies = [ "cesu8", "cfg-if", "combine", - "jni-sys 0.3.1", + "jni-sys", "log", "thiserror 1.0.69", "walkdir", @@ -2814,31 +2618,9 @@ dependencies = [ [[package]] name = "jni-sys" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" -dependencies = [ - "jni-sys 0.4.1", -] - -[[package]] -name = "jni-sys" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" -dependencies = [ - "jni-sys-macros", -] - -[[package]] -name = "jni-sys-macros" -version = "0.4.1" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" -dependencies = [ - "quote", - "syn 2.0.117", -] +checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" [[package]] name = "jobserver" @@ -2951,15 +2733,15 @@ checksum = "17ab85f84ca42c5ec520e6f3c9966ba1fd62909ce260f8837e248857d2560509" [[package]] name = "k256" -version = "0.14.0-rc.9" +version = "0.14.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b382cbfd43caf55991a93850ce538aa1aa67bb264af367d22dfe7937c4e997d" +checksum = "f7d2c6c227649d5ec80eaae541f1736232641a0bcdb3062a52b34edb42054158" dependencies = [ "cpubits", "ecdsa", "elliptic-curve", - "sha2 0.11.0", - "signature 3.0.0", + "sha2 0.11.0-rc.5", + "signature 3.0.0-rc.10", ] [[package]] @@ -3037,9 +2819,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.184" +version = "0.2.183" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" +checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" [[package]] name = "libm" @@ -3060,9 +2842,9 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.15" +version = "0.1.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08" +checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" dependencies = [ "bitflags 2.11.0", "libc", @@ -3084,9 +2866,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" +checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" [[package]] name = "lock_api" @@ -3208,33 +2990,22 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "mavros-artifacts" version = "0.1.0" -source = "git+https://github.com/reilabs/mavros?rev=7550b42e03d35b44781ff37f15b50773eb2a6fa0#7550b42e03d35b44781ff37f15b50773eb2a6fa0" +source = "git+https://github.com/reilabs/mavros?rev=3e47fd58001a0109a0314bc080b5246fd807ba04#3e47fd58001a0109a0314bc080b5246fd807ba04" dependencies = [ "ark-bn254", - "ark-ff 0.5.0", + "ark-ff", "serde", "tracing", ] -[[package]] -name = "mavros-opcode-gen" -version = "0.1.0" -source = "git+https://github.com/reilabs/mavros?rev=7550b42e03d35b44781ff37f15b50773eb2a6fa0#7550b42e03d35b44781ff37f15b50773eb2a6fa0" -dependencies = [ - "proc-macro2", - "quote", - "stringcase", - "syn 2.0.117", -] - [[package]] name = "mavros-vm" version = "0.1.0" -source = "git+https://github.com/reilabs/mavros?rev=7550b42e03d35b44781ff37f15b50773eb2a6fa0#7550b42e03d35b44781ff37f15b50773eb2a6fa0" +source = "git+https://github.com/reilabs/mavros?rev=3e47fd58001a0109a0314bc080b5246fd807ba04#3e47fd58001a0109a0314bc080b5246fd807ba04" dependencies = [ - "ark-ff 0.5.0", + "ark-ff", "mavros-artifacts", - "mavros-opcode-gen", + "opcode-gen", "tracing", ] @@ -3289,9 +3060,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.2.0" +version = "1.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" +checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" dependencies = [ "libc", "wasi", @@ -3425,7 +3196,7 @@ dependencies = [ "nargo", "noirc_driver", "noirc_frontend", - "semver 1.0.27", + "semver", "serde", "thiserror 1.0.69", "toml 0.7.8", @@ -3711,7 +3482,7 @@ dependencies = [ "chrono", "fm", "im", - "indexmap 2.13.1", + "indexmap 2.13.0", "iter-extended", "noirc_artifacts", "noirc_errors", @@ -3831,8 +3602,8 @@ name = "ntt" version = "0.1.0" dependencies = [ "ark-bn254", - "ark-ff 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-std", "bn254-multiplier", "divan", "proptest", @@ -3877,9 +3648,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.1" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" +checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" [[package]] name = "num-integer" @@ -3996,6 +3767,17 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" +[[package]] +name = "opcode-gen" +version = "0.1.0" +source = "git+https://github.com/reilabs/mavros?rev=3e47fd58001a0109a0314bc080b5246fd807ba04#3e47fd58001a0109a0314bc080b5246fd807ba04" +dependencies = [ + "proc-macro2", + "quote", + "stringcase", + "syn 2.0.117", +] + [[package]] name = "openssl" version = "0.10.76" @@ -4048,9 +3830,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ordered-float" -version = "5.3.0" +version = "5.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b7d950ca161dc355eaf28f82b11345ed76c6e1f6eb1f4f4479e0323b9e2fbd0e" +checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d" dependencies = [ "num-traits", "rand 0.8.5", @@ -4065,15 +3847,15 @@ checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" [[package]] name = "p256" -version = "0.14.0-rc.9" +version = "0.14.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b97e3bf0465157ae90975ff52dbeb1362ba618924878c9f74c25baa27a65f9a" +checksum = "44f0a10fe314869359cb2901342b045f4e5a962ef9febc006f03d2a8c848fe4c" dependencies = [ "ecdsa", "elliptic-curve", "primefield", "primeorder", - "sha2 0.11.0", + "sha2 0.11.0-rc.5", ] [[package]] @@ -4285,7 +4067,7 @@ dependencies = [ "anyhow", "argh", "ark-bn254", - "ark-ff 0.5.0", + "ark-ff", "base64", "chrono", "hex", @@ -4339,16 +4121,6 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" -[[package]] -name = "pest" -version = "2.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" -dependencies = [ - "memchr", - "ucd-trie", -] - [[package]] name = "petgraph" version = "0.8.3" @@ -4357,7 +4129,7 @@ checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" dependencies = [ "fixedbitset", "hashbrown 0.15.5", - "indexmap 2.13.1", + "indexmap 2.13.0", "serde", ] @@ -4387,6 +4159,12 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" +[[package]] +name = "pin-utils" +version = "0.1.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" + [[package]] name = "pkcs1" version = "0.7.5" @@ -4410,12 +4188,12 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.11.0" +version = "0.11.0-rc.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" +checksum = "12922b6296c06eb741b02d7b5161e3aaa22864af38dfa025a1a3ba3f68c84577" dependencies = [ "der 0.8.0", - "spki 0.8.0", + "spki 0.8.0-rc.4", ] [[package]] @@ -4435,8 +4213,8 @@ name = "poseidon2" version = "0.1.0" dependencies = [ "ark-bn254", - "ark-ff 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-std", ] [[package]] @@ -4454,9 +4232,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.5" +version = "0.1.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" +checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" dependencies = [ "zerovec", ] @@ -4502,9 +4280,9 @@ dependencies = [ [[package]] name = "primefield" -version = "0.14.0-rc.9" +version = "0.14.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1b52e6ee42db392378a95622b463c9740631171d1efce43fa445a569c1600cb6" +checksum = "c6543f5eec854fbf74ba5ef651fbdc9408919b47c3e1526623687135c16d12e9" dependencies = [ "crypto-bigint", "crypto-common 0.2.1", @@ -4516,24 +4294,13 @@ dependencies = [ [[package]] name = "primeorder" -version = "0.14.0-rc.9" +version = "0.14.0-rc.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0556580e42c19833f5d232aca11a7687a503ee41f937b54f5ae1d50fc2a6a36a" +checksum = "569d9ad6ef822bb0322c7e7d84e5e286244050bd5246cac4c013535ae91c2c90" dependencies = [ "elliptic-curve", ] -[[package]] -name = "primitive-types" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" -dependencies = [ - "fixed-hash", - "impl-codec 0.6.0", - "uint 0.9.5", -] - [[package]] name = "primitive-types" version = "0.13.1" @@ -4541,8 +4308,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d15600a7d856470b7d278b3fe0e311fe28c2526348549f8ef2ff7db3299c87f5" dependencies = [ "fixed-hash", - "impl-codec 0.7.1", - "uint 0.10.0", + "impl-codec", + "uint", ] [[package]] @@ -4551,7 +4318,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.25.10+spec-1.1.0", + "toml_edit 0.25.5+spec-1.1.0", ] [[package]] @@ -4565,9 +4332,9 @@ dependencies = [ [[package]] name = "proptest" -version = "1.11.0" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" +checksum = "37566cb3fdacef14c0737f9546df7cfeadbfbc9fef10991038bf5015d0c80532" dependencies = [ "bit-set", "bit-vec", @@ -4588,7 +4355,7 @@ version = "1.0.0" dependencies = [ "acir", "anyhow", - "ark-ff 0.5.0", + "ark-ff", "divan", "nargo", "nargo_cli", @@ -4611,7 +4378,7 @@ dependencies = [ "acir", "anyhow", "argh", - "ark-ff 0.5.0", + "ark-ff", "base64", "hex", "nargo", @@ -4640,9 +4407,9 @@ dependencies = [ "acir", "anyhow", "ark-bn254", - "ark-ff 0.5.0", - "ark-serialize 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-serialize", + "ark-std", "base64", "blake3", "bytes", @@ -4658,7 +4425,6 @@ dependencies = [ "postcard", "proptest", "rayon", - "ruint", "serde", "serde_json", "sha2 0.10.9", @@ -4709,8 +4475,8 @@ version = "1.0.0" dependencies = [ "acir", "anyhow", - "ark-ff 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-std", "bn254_blackbox_solver", "mavros-artifacts", "mavros-vm", @@ -4731,8 +4497,8 @@ version = "1.0.0" dependencies = [ "acir", "anyhow", - "ark-ff 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-std", "bincode", "mavros-artifacts", "noirc_abi", @@ -4751,7 +4517,7 @@ name = "provekit-verifier" version = "1.0.0" dependencies = [ "anyhow", - "ark-std 0.5.0", + "ark-std", "provekit-common", "rayon", "tracing", @@ -5068,7 +4834,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom 0.2.17", - "libredox 0.1.15", + "libredox 0.1.14", "thiserror 1.0.69", ] @@ -5079,7 +4845,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.17", - "libredox 0.1.15", + "libredox 0.1.14", "thiserror 2.0.18", ] @@ -5202,16 +4968,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rlp" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" -dependencies = [ - "bytes", - "rustc-hex", -] - [[package]] name = "rmp" version = "0.8.15" @@ -5252,40 +5008,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ruint" -version = "1.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c141e807189ad38a07276942c6623032d3753c8859c146104ac2e4d68865945a" -dependencies = [ - "alloy-rlp", - "ark-ff 0.3.0", - "ark-ff 0.4.2", - "ark-ff 0.5.0", - "bytes", - "fastrlp 0.3.1", - "fastrlp 0.4.0", - "num-bigint", - "num-integer", - "num-traits", - "parity-scale-codec", - "primitive-types 0.12.2", - "proptest", - "rand 0.8.5", - "rand 0.9.2", - "rlp", - "ruint-macro", - "serde_core", - "valuable", - "zeroize", -] - -[[package]] -name = "ruint-macro" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" - [[package]] name = "rust-embed" version = "8.11.0" @@ -5328,9 +5050,9 @@ checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" [[package]] name = "rustc-hash" -version = "2.1.2" +version = "2.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" +checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" [[package]] name = "rustc-hex" @@ -5344,29 +5066,20 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "781442f29170c5c93b7185ad559492601acdc71d5bb0706f5868094f45cfcd08" -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - [[package]] name = "rustc_version" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.27", + "semver", ] [[package]] name = "rustcrypto-ff" -version = "0.14.0-rc.1" +version = "0.14.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fd2a8adb347447693cd2ba0d218c4b66c62da9b0a5672b17b981e4291ec65ff6" +checksum = "c5db129183b2c139d7d87d08be57cba626c715789db17aec65c8866bfd767d1f" dependencies = [ "rand_core 0.10.0", "subtle", @@ -5374,9 +5087,9 @@ dependencies = [ [[package]] name = "rustcrypto-group" -version = "0.14.0-rc.1" +version = "0.14.0-rc.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "369f9b61aa45933c062c9f6b5c3c50ab710687eca83dd3802653b140b43f85ed" +checksum = "57c4b1463f274a3ff6fb2f44da43e576cb9424367bd96f185ead87b52fe00523" dependencies = [ "rand_core 0.10.0", "rustcrypto-ff", @@ -5483,9 +5196,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.10" +version = "0.103.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" +checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" dependencies = [ "ring", "rustls-pki-types", @@ -5662,9 +5375,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sec1" -version = "0.8.1" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" +checksum = "f46b9a5ab87780a3189a1d704766579517a04ad59de653b7aad7d38e8a15f7dc" dependencies = [ "base16ct", "ctutils", @@ -5697,30 +5410,12 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" -[[package]] -name = "semver-parser" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" -dependencies = [ - "pest", -] - [[package]] name = "seq-macro" version = "0.3.6" @@ -5843,7 +5538,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.13.1", + "indexmap 2.13.0", "schemars 0.9.0", "schemars 1.2.1", "serde_core", @@ -5878,13 +5573,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.11.0" +version = "0.11.0-rc.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" +checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024" dependencies = [ "cfg-if", - "cpufeatures 0.3.0", - "digest 0.11.3", + "cpufeatures 0.2.17", + "digest 0.11.2", ] [[package]] @@ -5961,19 +5656,19 @@ dependencies = [ [[package]] name = "signature" -version = "3.0.0" +version = "3.0.0-rc.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" +checksum = "7f1880df446116126965eeec169136b2e0251dba37c6223bcc819569550edea3" dependencies = [ - "digest 0.11.3", + "digest 0.11.2", "rand_core 0.10.0", ] [[package]] name = "simd-adler32" -version = "0.3.9" +version = "0.3.8" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" +checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" [[package]] name = "similar" @@ -6010,7 +5705,7 @@ name = "skyscraper" version = "0.1.0" dependencies = [ "ark-bn254", - "ark-ff 0.5.0", + "ark-ff", "bn254-multiplier", "divan", "fp-rounding", @@ -6130,9 +5825,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.8.0" +version = "0.8.0-rc.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" +checksum = "8baeff88f34ed0691978ec34440140e1572b68c7dd4a495fd14a3dc1944daa80" dependencies = [ "base64ct", "der 0.8.0", @@ -6143,8 +5838,8 @@ name = "spongefish" version = "1.0.0-rc1" source = "git+https://github.com/arkworks-rs/spongefish?rev=fcc277f8a857fdeeadd7cca92ab08de63b1ff1a1#fcc277f8a857fdeeadd7cca92ab08de63b1ff1a1" dependencies = [ - "ark-ff 0.5.0", - "ark-serialize 0.5.0", + "ark-ff", + "ark-serialize", "blake3", "digest 0.10.7", "keccak 0.1.6", @@ -6333,12 +6028,12 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.4.4" +version = "0.4.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" +checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" dependencies = [ "rustix 1.1.4", - "windows-sys 0.61.2", + "windows-sys 0.60.2", ] [[package]] @@ -6499,9 +6194,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.3" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" +checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" dependencies = [ "displaydoc", "zerovec", @@ -6509,13 +6204,13 @@ dependencies = [ [[package]] name = "tokio" -version = "1.51.0" +version = "1.50.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2bd1c4c0fc4a7ab90fc15ef6daaa3ec3b893f004f915f2392557ed23237820cd" +checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" dependencies = [ "bytes", "libc", - "mio 1.2.0", + "mio 1.1.1", "parking_lot", "pin-project-lite", "signal-hook-registry", @@ -6526,9 +6221,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.7.0" +version = "2.6.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" +checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" dependencies = [ "proc-macro2", "quote", @@ -6604,9 +6299,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "1.1.1+spec-1.1.0" +version = "1.0.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" +checksum = "9b320e741db58cac564e26c607d3cc1fdc4a88fd36c879568c07856ed83ff3e9" dependencies = [ "serde_core", ] @@ -6617,7 +6312,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.13.0", "serde", "serde_spanned", "toml_datetime 0.6.11", @@ -6630,7 +6325,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.13.1", + "indexmap 2.13.0", "serde", "serde_spanned", "toml_datetime 0.6.11", @@ -6640,23 +6335,23 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.10+spec-1.1.0" +version = "0.25.5+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a82418ca169e235e6c399a84e395ab6debeb3bc90edc959bf0f48647c6a32d1b" +checksum = "8ca1a40644a28bce036923f6a431df0b34236949d111cc07cb6dca830c9ef2e1" dependencies = [ - "indexmap 2.13.1", - "toml_datetime 1.1.1+spec-1.1.0", + "indexmap 2.13.0", + "toml_datetime 1.0.1+spec-1.1.0", "toml_parser", - "winnow 1.0.1", + "winnow 1.0.0", ] [[package]] name = "toml_parser" -version = "1.1.2+spec-1.1.0" +version = "1.0.10+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" +checksum = "7df25b4befd31c4816df190124375d5a20c6b6921e2cad937316de3fccd63420" dependencies = [ - "winnow 1.0.1", + "winnow 1.0.0", ] [[package]] @@ -6875,15 +6570,15 @@ checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" [[package]] name = "typenum" -version = "1.20.0" +version = "1.19.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" +checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" [[package]] name = "typewit" -version = "1.15.0" +version = "1.14.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "06fee3a8df48c50c55ad646a4e03b00a370da6fe1850ebf467a8d0165dfcafae" +checksum = "f8c1ae7cc0fdb8b842d65d127cb981574b0d2b249b74d1c7a2986863dc134f71" dependencies = [ "typewit_proc_macros", ] @@ -6894,24 +6589,6 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" -[[package]] -name = "ucd-trie" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" - -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "uint" version = "0.10.0" @@ -6950,9 +6627,9 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-segmentation" -version = "1.13.2" +version = "1.12.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" +checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" [[package]] name = "unicode-width" @@ -6999,9 +6676,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.23.0" +version = "1.22.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" +checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" dependencies = [ "getrandom 0.4.2", ] @@ -7224,7 +6901,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" dependencies = [ "anyhow", - "indexmap 2.13.1", + "indexmap 2.13.0", "wasm-encoder", "wasmparser", ] @@ -7248,8 +6925,8 @@ checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ "bitflags 2.11.0", "hashbrown 0.15.5", - "indexmap 2.13.1", - "semver 1.0.27", + "indexmap 2.13.0", + "semver", ] [[package]] @@ -7285,9 +6962,9 @@ name = "whir" version = "0.1.0" source = "git+https://github.com/WizardOfMenlo/whir/?rev=0aeaa7f337c743d9ddfcb9d909628d6491e3355c#0aeaa7f337c743d9ddfcb9d909628d6491e3355c" dependencies = [ - "ark-ff 0.5.0", - "ark-serialize 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-serialize", + "ark-std", "arrayvec", "blake3", "ciborium", @@ -7727,9 +7404,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.1" +version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" +checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8" dependencies = [ "memchr", ] @@ -7762,7 +7439,7 @@ checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", "heck 0.5.0", - "indexmap 2.13.1", + "indexmap 2.13.0", "prettyplease", "syn 2.0.117", "wasm-metadata", @@ -7793,7 +7470,7 @@ checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", "bitflags 2.11.0", - "indexmap 2.13.1", + "indexmap 2.13.0", "log", "serde", "serde_derive", @@ -7812,9 +7489,9 @@ checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" dependencies = [ "anyhow", "id-arena", - "indexmap 2.13.1", + "indexmap 2.13.0", "log", - "semver 1.0.27", + "semver", "serde", "serde_derive", "serde_json", @@ -7824,9 +7501,9 @@ dependencies = [ [[package]] name = "writeable" -version = "0.6.3" +version = "0.6.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" +checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" [[package]] name = "wyz" @@ -7865,9 +7542,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" +checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -7876,9 +7553,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.2" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" +checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" dependencies = [ "proc-macro2", "quote", @@ -7888,18 +7565,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.48" +version = "0.8.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" +checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.48" +version = "0.8.42" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" +checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" dependencies = [ "proc-macro2", "quote", @@ -7908,18 +7585,18 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" +checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" +checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" dependencies = [ "proc-macro2", "quote", @@ -7949,9 +7626,9 @@ dependencies = [ [[package]] name = "zerotrie" -version = "0.2.4" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" +checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" dependencies = [ "displaydoc", "yoke", @@ -7960,9 +7637,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.6" +version = "0.11.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" +checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" dependencies = [ "yoke", "zerofrom", @@ -7971,9 +7648,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.3" +version = "0.11.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" +checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" dependencies = [ "proc-macro2", "quote", diff --git a/Cargo.toml b/Cargo.toml index 8f308d033..a2a1e3a24 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -133,7 +133,6 @@ rand = "0.9.1" rand08 = { package = "rand", version = "0.8" } rayon = "1.10.0" reqwest = "0.12.23" -ruint = { version = "1.12.3", features = ["num-traits", "rand"] } seq-macro = "0.3.6" serde = { version = "1.0", features = ["derive"] } serde_json = "1.0" diff --git a/provekit/common/Cargo.toml b/provekit/common/Cargo.toml index 50779d5ae..cdb94dac1 100644 --- a/provekit/common/Cargo.toml +++ b/provekit/common/Cargo.toml @@ -1,6 +1,8 @@ [package] name = "provekit-common" version = "1.0.0" +# Warns when both field features are on (silent BN254 precedence); see build.rs. +build = "build.rs" edition.workspace = true rust-version.workspace = true authors.workspace = true @@ -48,7 +50,6 @@ hex.workspace = true itertools.workspace = true postcard.workspace = true rayon.workspace = true -ruint.workspace = true serde.workspace = true serde_json.workspace = true blake3.workspace = true diff --git a/provekit/common/build.rs b/provekit/common/build.rs new file mode 100644 index 000000000..0e786d87a --- /dev/null +++ b/provekit/common/build.rs @@ -0,0 +1,27 @@ +//! Build script for `provekit-common`. +//! +//! Surfaces the one field-feature footgun the `compile_error!` in `src/lib.rs` +//! cannot catch. `bn254` wins cfg precedence over `goldilocks` (so the crate +//! builds as BN254 whenever both are on — the intended resolution under +//! `--all-features`, which CI uses). But several BN254-only features pull in +//! `bn254` transitively (`provekit_ntt`, and the prover's +//! `witness-generation`), so an explicit `--features goldilocks,` build +//! silently compiles as BN254 instead of Goldilocks. `compile_error!` only +//! fires when *no* field is selected, never here. +//! +//! A `cargo:warning` makes the override visible without failing the build +//! (a hard error would break the legitimate `--all-features` path). Build- +//! script warnings are advisory, so this is safe even under `-D warnings`. +fn main() { + let bn254 = std::env::var_os("CARGO_FEATURE_BN254").is_some(); + let goldilocks = std::env::var_os("CARGO_FEATURE_GOLDILOCKS").is_some(); + if bn254 && goldilocks { + println!( + "cargo:warning=provekit-common: both `bn254` and `goldilocks` features are enabled; \ + FieldElement is BN254 (bn254 takes precedence), so `goldilocks` is inert. For a real \ + Goldilocks build use `--no-default-features --features goldilocks` and drop any \ + feature that pulls in bn254 (provekit_ntt, the prover's witness-generation). This \ + warning is expected under --all-features." + ); + } +} diff --git a/provekit/prover/Cargo.toml b/provekit/prover/Cargo.toml index 889875905..939050a71 100644 --- a/provekit/prover/Cargo.toml +++ b/provekit/prover/Cargo.toml @@ -12,13 +12,17 @@ repository.workspace = true default = ["witness-generation", "parallel", "bn254"] # At least one field feature must be enabled; `bn254` takes precedence when # both are on. Pair `goldilocks` with `--no-default-features`. +# `provekit-verifier/` forwards the field selection to the dev-dep used +# by `roundtrip_tests`, so `cargo test -p provekit-prover` builds the verifier +# over the same field as common (it has no field feature of its own otherwise). bn254 = [ "provekit-common/bn254", "provekit-common/provekit_ntt", + "provekit-verifier/bn254", "dep:mavros-vm", "dep:mavros-artifacts", ] -goldilocks = ["provekit-common/goldilocks"] +goldilocks = ["provekit-common/goldilocks", "provekit-verifier/goldilocks"] witness-generation = ["bn254", "nargo", "bn254_blackbox_solver", "noir_artifact_cli"] parallel = ["provekit-common/parallel"] From a4dfffa47ddf63bbb0aa69e48a373485da3b9119 Mon Sep 17 00:00:00 2001 From: Yogesh Shahi Date: Thu, 11 Jun 2026 16:28:20 +0530 Subject: [PATCH 07/11] feat(common): hand-write HashConfig serde, add the Goldilocks binding hash, and guard field unification --- provekit/common/src/hash_config.rs | 156 +++++++++++++++++++++++++---- provekit/common/src/lib.rs | 32 ++++++ provekit/common/src/witness/mod.rs | 19 ++++ provekit/prover/src/lib.rs | 6 ++ provekit/verifier/src/lib.rs | 5 + provekit/verifier/src/whir_r1cs.rs | 6 ++ 6 files changed, 204 insertions(+), 20 deletions(-) diff --git a/provekit/common/src/hash_config.rs b/provekit/common/src/hash_config.rs index f382557f9..1c112e0c9 100644 --- a/provekit/common/src/hash_config.rs +++ b/provekit/common/src/hash_config.rs @@ -23,29 +23,68 @@ use { /// are BN254-only constructions and exist only under the `bn254` feature; /// the default is Skyscraper under `bn254` and [`Self::Sha256`] under /// `goldilocks`. -#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash, Serialize, Deserialize)] -#[serde(rename_all = "kebab-case")] +/// +/// Serialization is hand-written (see the `Serialize`/`Deserialize` impls +/// below) rather than derived: the derive numbers variants positionally, so +/// `#[cfg]`-gating Skyscraper/Poseidon2 out of a goldilocks build silently +/// shifts every remaining index (`Sha256` becomes `0` instead of `1`, etc.), +/// which would let a postcard/CBOR-encoded config written by one field build +/// decode as the wrong variant under the other. The manual impls route binary +/// formats through the field-independent [`Self::to_byte`]/[`Self::from_byte`] +/// (the same stable byte used in proof-file headers) and human-readable +/// formats through [`Self::name`]/[`Self::parse`]. +#[derive(Clone, Copy, Debug, Default, PartialEq, Eq, Hash)] pub enum HashConfig { #[cfg(feature = "bn254")] #[default] - #[serde(alias = "sky")] Skyscraper, #[cfg_attr(all(feature = "goldilocks", not(feature = "bn254")), default)] - #[serde(alias = "sha", alias = "sha-256")] Sha256, - #[serde(alias = "keccak-256", alias = "shake")] Keccak, - #[serde(alias = "blake-3", alias = "b3")] Blake3, #[cfg(feature = "bn254")] - #[serde(alias = "pos2", alias = "p2")] Poseidon2, } +impl Serialize for HashConfig { + /// Human-readable formats (JSON, …) get the canonical name string; binary + /// formats (postcard, CBOR, …) get the field-independent [`Self::to_byte`] + /// value. Under `bn254` both forms are byte-identical to the old derive, + /// so existing proofs/schemes are unaffected. + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + if serializer.is_human_readable() { + serializer.serialize_str(self.name()) + } else { + serializer.serialize_u8(self.to_byte()) + } + } +} + +impl<'de> Deserialize<'de> for HashConfig { + fn deserialize(deserializer: D) -> Result + where + D: serde::Deserializer<'de>, + { + use serde::de::Error as _; + if deserializer.is_human_readable() { + let name = String::deserialize(deserializer)?; + Self::parse(&name) + .ok_or_else(|| D::Error::custom(format!("unknown hash configuration: {name:?}"))) + } else { + let byte = u8::deserialize(deserializer)?; + Self::from_byte(byte) + .ok_or_else(|| D::Error::custom(format!("invalid hash configuration byte: {byte}"))) + } + } +} + /// Domain-separation tag for public-input instance binding. /// /// **Protocol-visible constant.** This string is absorbed into the SHA-256, @@ -224,23 +263,34 @@ fn digest_to_field(digest: &[u8]) -> FieldElement { FieldElement::from_le_bytes_mod_order(digest) } -/// Reduces a hash digest into a [`FieldElement`] by reducing into the -/// Goldilocks base field and embedding into the cubic extension. +/// Reduces a hash digest into a [`FieldElement`] by spreading it across all +/// three coordinates of the Goldilocks cubic extension. +/// +/// The digest is split into three contiguous chunks, each reduced mod the +/// ~64-bit Goldilocks base prime, so the image is the full ~192-bit cubic +/// extension rather than the ~64-bit base subfield a single reduction would +/// produce. This value is *both* the Fiat-Shamir instance tag and the absorbed +/// public-inputs hash the verifier recomputes and compares. /// -/// NOTE: the image lies in the base subfield — only ~64 bits of entropy in -/// the field representation. That is fine for public-input/DST *binding* -/// (collision resistance lives in the 256-bit digest; real public-input -/// soundness is the sumcheck public-eval check), but this value must NEVER -/// feed challenge derivation. Optional strengthening: split the digest into -/// 3 chunks via `from_base_prime_field_elems` for a ~192-bit image. +/// Why spread: the collision resistance of a binding hash is the birthday +/// bound over its image (~2^(bits/2)), not the image size. A base-subfield +/// image (~2⁶⁴ values) would give only ~2³² resistance; the full extension +/// (~2¹⁹²) gives ~2⁹⁶, itself bounded by the 256-bit digest's own ~2¹²⁸. ~2⁹⁶ +/// is still below the 128-bit WHIR target, but this tag is *defense-in-depth*, +/// not the sole binding: public-input binding is enforced independently by the +/// verifier's direct value check (`verify_public_input_binding`, soundness +/// error ~deg/|F|), so soundness does not rest on this hash's collision +/// resistance. Like the BN254 sibling, this is a binding hash, not a uniform +/// field sampler. #[cfg(all(feature = "goldilocks", not(feature = "bn254")))] #[inline] fn digest_to_field(digest: &[u8]) -> FieldElement { - use { - ark_ff::{Field, PrimeField}, - whir::algebra::fields::Field64, - }; - FieldElement::from_base_prime_field(Field64::from_le_bytes_mod_order(digest)) + use {ark_ff::PrimeField, whir::algebra::fields::Field64}; + let chunk = digest.len().div_ceil(3); + let c0 = Field64::from_le_bytes_mod_order(&digest[..chunk.min(digest.len())]); + let c1 = Field64::from_le_bytes_mod_order(digest.get(chunk..2 * chunk).unwrap_or(&[])); + let c2 = Field64::from_le_bytes_mod_order(digest.get(2 * chunk..).unwrap_or(&[])); + FieldElement::new(c0, c1, c2) } /// DST-tagged [`sha2::digest::Digest`] hash (SHA-256, Keccak-256) over @@ -307,6 +357,72 @@ mod tests { const ALL_VARIANTS: &[HashConfig] = &[HashConfig::Sha256, HashConfig::Keccak, HashConfig::Blake3]; + /// Binary serde must encode the field-independent [`HashConfig::to_byte`] + /// value, NOT serde's positional variant index. Otherwise cfg-gating + /// Skyscraper/Poseidon2 out of a goldilocks build shifts `Sha256` from 1 + /// to 0, silently colliding with Skyscraper's byte across field builds. + #[test] + fn binary_serde_is_field_independent_to_byte() { + for &v in ALL_VARIANTS { + let bytes = postcard::to_allocvec(&v).unwrap(); + assert_eq!( + bytes, + vec![v.to_byte()], + "{v:?}: postcard must equal to_byte()" + ); + let back: HashConfig = postcard::from_bytes(&bytes).unwrap(); + assert_eq!(back, v, "{v:?}: postcard roundtrip"); + } + // Pinned: these bytes must be identical in every field build. + assert_eq!(postcard::to_allocvec(&HashConfig::Sha256).unwrap(), vec![ + 1u8 + ]); + assert_eq!(postcard::to_allocvec(&HashConfig::Keccak).unwrap(), vec![ + 2u8 + ]); + assert_eq!(postcard::to_allocvec(&HashConfig::Blake3).unwrap(), vec![ + 3u8 + ]); + } + + /// Human-readable serde uses the canonical name string (stable across + /// fields) and round-trips, including the legacy aliases via `parse`. + #[test] + fn human_readable_serde_is_canonical_name() { + for &v in ALL_VARIANTS { + let json = serde_json::to_string(&v).unwrap(); + assert_eq!( + json, + format!("\"{}\"", v.name()), + "{v:?}: json must be name()" + ); + let back: HashConfig = serde_json::from_str(&json).unwrap(); + assert_eq!(back, v, "{v:?}: json roundtrip"); + } + assert_eq!( + serde_json::to_string(&HashConfig::Sha256).unwrap(), + "\"sha256\"" + ); + let aliased: HashConfig = serde_json::from_str("\"sha-256\"").unwrap(); + assert_eq!(aliased, HashConfig::Sha256, "legacy alias must still parse"); + } + + /// A goldilocks build must *reject* binary bytes for variants it does not + /// have (0 = Skyscraper, 4 = Poseidon2) rather than silently misdecode — + /// this is the cross-field-substitution guard the derive lacked. + #[cfg(all(feature = "goldilocks", not(feature = "bn254")))] + #[test] + fn binary_serde_rejects_bn254_only_bytes() { + assert!( + postcard::from_bytes::(&[0u8]).is_err(), + "byte 0 (Skyscraper) must be rejected, not decoded as Sha256" + ); + assert!( + postcard::from_bytes::(&[4u8]).is_err(), + "byte 4 (Poseidon2) must be rejected" + ); + } + #[test] fn from_byte_roundtrips_with_to_byte() { for &variant in ALL_VARIANTS { diff --git a/provekit/common/src/lib.rs b/provekit/common/src/lib.rs index b3e763015..ec7ab4738 100644 --- a/provekit/common/src/lib.rs +++ b/provekit/common/src/lib.rs @@ -46,6 +46,38 @@ use crate::{ pub use ark_bn254::Fr as FieldElement; #[cfg(all(feature = "goldilocks", not(feature = "bn254")))] pub use whir::algebra::fields::Field64_3 as FieldElement; + +/// Which field [`FieldElement`] resolved to in this build: `true` for the +/// BN254 scalar field, `false` for the Goldilocks cubic extension. Because +/// `bn254` wins precedence when both features are on, this tracks the actual +/// type — not merely whether `goldilocks` was requested. +/// +/// Downstream crates that carry their own `bn254`/`goldilocks` features assert +/// their intent against this via [`assert_field_matches_common`], so Cargo +/// feature unification (a sibling forcing `provekit-common/bn254` while the +/// crate was built for `goldilocks`) becomes a build error rather than silently +/// compiling field-gated code over the wrong `FieldElement`. +pub const FIELD_IS_BN254: bool = cfg!(feature = "bn254"); + +/// Compile-time guard that the invoking crate's field feature matches +/// [`FIELD_IS_BN254`] (i.e. `provekit-common`'s resolved [`FieldElement`]). +/// +/// Invoke once at crate root in any crate that has its own `bn254`/`goldilocks` +/// features and uses [`FieldElement`]. `cfg!(feature = "bn254")` is evaluated +/// in the caller, so a divergence introduced by feature unification fails the +/// build with a clear message instead of producing a wrong-field binary. +#[macro_export] +macro_rules! assert_field_matches_common { + () => { + const _: () = ::core::assert!( + ::core::cfg!(feature = "bn254") == $crate::FIELD_IS_BN254, + "this crate's field feature disagrees with provekit-common's resolved FieldElement: a \ + sibling crate likely enabled provekit-common/bn254 via Cargo feature unification \ + while this crate was built for goldilocks. Build every provekit crate in the \ + dependency graph over the same field.", + ); + }; +} #[cfg(feature = "bn254")] pub use { acir::FieldElement as NoirElement, diff --git a/provekit/common/src/witness/mod.rs b/provekit/common/src/witness/mod.rs index 603dcb987..96367a0be 100644 --- a/provekit/common/src/witness/mod.rs +++ b/provekit/common/src/witness/mod.rs @@ -213,6 +213,25 @@ mod tests { } } + /// Regression: the binding hash must span all three cubic-extension + /// coordinates, not collapse into the ~64-bit base subfield. A + /// base-subfield image leaves the upper 16 bytes (coords `c1`, `c2`) + /// zero and caps public-input binding collision resistance at ~2⁶⁴, + /// below the 128-bit security target. See `digest_to_field` in + /// `hash_config`. + #[cfg(all(feature = "goldilocks", not(feature = "bn254")))] + #[test] + fn goldilocks_binding_hash_spans_full_extension() { + for config in ALL_CONFIGS { + let bytes = field_to_bytes_le(pi(&[1, 2]).hash(config)); + assert_ne!( + bytes[8..24], + [0u8; 16], + "{config:?}: binding hash collapsed into the ~64-bit base subfield" + ); + } + } + // --- empty input --- #[cfg(feature = "bn254")] diff --git a/provekit/prover/src/lib.rs b/provekit/prover/src/lib.rs index 1826a0c47..983838390 100644 --- a/provekit/prover/src/lib.rs +++ b/provekit/prover/src/lib.rs @@ -49,6 +49,12 @@ pub mod whir_r1cs; #[cfg(feature = "bn254")] mod witness; +// Guard against Cargo feature unification building this prover's field-gated +// code (notably the goldilocks-only public `whir_r1cs` API) over the wrong +// `provekit_common::FieldElement` — e.g. when a sibling crate forces +// `provekit-common/bn254` while this prover is built for goldilocks. +provekit_common::assert_field_matches_common!(); + // Public re-exports for items used by integration tests and benchmarks. #[cfg(feature = "bn254")] pub use {ec_arith::ec_scalar_mul, r1cs::solve_witness_vec}; diff --git a/provekit/verifier/src/lib.rs b/provekit/verifier/src/lib.rs index 8c4b8fb47..9810a8b36 100644 --- a/provekit/verifier/src/lib.rs +++ b/provekit/verifier/src/lib.rs @@ -1,5 +1,10 @@ pub mod whir_r1cs; +// Guard against Cargo feature unification building this verifier over the wrong +// `provekit_common::FieldElement` (a sibling forcing `provekit-common/bn254` +// while this verifier is built for goldilocks). +provekit_common::assert_field_matches_common!(); + #[cfg(feature = "bn254")] use { crate::whir_r1cs::WhirR1CSVerifier, diff --git a/provekit/verifier/src/whir_r1cs.rs b/provekit/verifier/src/whir_r1cs.rs index 662475eee..822e183f2 100644 --- a/provekit/verifier/src/whir_r1cs.rs +++ b/provekit/verifier/src/whir_r1cs.rs @@ -43,6 +43,12 @@ impl WhirR1CSVerifier for WhirR1CSScheme { public_inputs: &PublicInputs, r1cs: &R1CS, ) -> Result<()> { + // Register the NTT/hash engines this verify path retrieves. The bn254 + // `Verify` wrapper also calls this, but under goldilocks that wrapper is + // gone and this is the sole (public) entry point; `register_ntt` is + // idempotent, so the double call under bn254 is a no-op. + provekit_common::register_ntt(); + let actual_r1cs_hash = r1cs.hash(); anyhow::ensure!( self.r1cs_hash == actual_r1cs_hash, From 5600d598f3524acf388f8a7e08dadbf004d6f949 Mon Sep 17 00:00:00 2001 From: Yogesh Shahi Date: Thu, 11 Jun 2026 16:28:27 +0530 Subject: [PATCH 08/11] refactor(common): make WhirR1CSSchemeBuilder constructors fallible --- provekit/common/src/whir_r1cs.rs | 50 ++++++++++++------- provekit/prover/src/roundtrip_tests.rs | 2 +- .../r1cs-compiler/src/noir_proof_scheme.rs | 4 +- 3 files changed, 34 insertions(+), 22 deletions(-) diff --git a/provekit/common/src/whir_r1cs.rs b/provekit/common/src/whir_r1cs.rs index 06acd0c10..6b4e96d0d 100644 --- a/provekit/common/src/whir_r1cs.rs +++ b/provekit/common/src/whir_r1cs.rs @@ -9,6 +9,7 @@ use { utils::{next_power_of_two, serde_hex}, FieldElement, HashConfig, R1CS, }, + anyhow::{ensure, Result}, serde::{Deserialize, Serialize}, whir::{ algebra::embedding::Identity, @@ -87,8 +88,11 @@ const MIN_SUMCHECK_NUM_VARIABLES: usize = 1; /// Constructors for [`WhirR1CSScheme`], sizing the WHIR configuration from an /// R1CS instance (or raw dimensions) and stamping the instance-binding /// `r1cs_hash`. -pub trait WhirR1CSSchemeBuilder { +pub trait WhirR1CSSchemeBuilder: Sized { /// Build a scheme for `r1cs`, stamping `r1cs_hash = r1cs.hash()`. + /// + /// Errors if `num_challenges != challenge_offsets.len()` or if `w1_size` + /// exceeds the R1CS witness count. fn new_for_r1cs( r1cs: &R1CS, w1_size: usize, @@ -96,9 +100,12 @@ pub trait WhirR1CSSchemeBuilder { challenge_offsets: Vec, has_public_inputs: bool, hash_config: HashConfig, - ) -> Self; + ) -> Result; /// Build a scheme from a Mavros R1CS, leaving `r1cs_hash` unset. + /// + /// Errors on the same dimension inconsistencies as + /// [`Self::new_from_dimensions`]. #[cfg(all(feature = "bn254", not(target_arch = "wasm32")))] fn new_from_mavros_r1cs( r1cs: &MavrosR1CS, @@ -107,9 +114,12 @@ pub trait WhirR1CSSchemeBuilder { challenge_offsets: Vec, has_public_inputs: bool, hash_config: HashConfig, - ) -> Self; + ) -> Result; /// Build a scheme from raw dimensions, leaving `r1cs_hash` unset. + /// + /// Errors if `num_challenges != challenge_offsets.len()` or if `w1_size` + /// exceeds `num_witnesses`. fn new_from_dimensions( num_witnesses: usize, num_constraints: usize, @@ -119,7 +129,7 @@ pub trait WhirR1CSSchemeBuilder { challenge_offsets: Vec, has_public_inputs: bool, hash_config: HashConfig, - ) -> Self; + ) -> Result; /// Build the WHIR ZK configuration for `num_variables` (clamped to the /// protocol minimum) and `num_polynomials`. @@ -138,17 +148,16 @@ impl WhirR1CSSchemeBuilder for WhirR1CSScheme { challenge_offsets: Vec, has_public_inputs: bool, hash_config: HashConfig, - ) -> Self { - assert_eq!( - num_challenges, - challenge_offsets.len(), + ) -> Result { + ensure!( + num_challenges == challenge_offsets.len(), "num_challenges ({num_challenges}) != challenge_offsets.len() ({})", challenge_offsets.len() ); let total_witnesses = r1cs.num_witnesses(); - assert!( + ensure!( w1_size <= total_witnesses, - "w1_size exceeds total witnesses" + "w1_size ({w1_size}) exceeds total witnesses ({total_witnesses})" ); let w2_size = total_witnesses - w1_size; @@ -164,7 +173,7 @@ impl WhirR1CSSchemeBuilder for WhirR1CSScheme { m_raw += 1; } - Self { + Ok(Self { m: m_raw, w1_size, m_0, @@ -175,7 +184,7 @@ impl WhirR1CSSchemeBuilder for WhirR1CSScheme { has_public_inputs, r1cs_hash: r1cs.hash(), hash_config, - } + }) } fn new_whir_zk_config_for_size( @@ -211,7 +220,7 @@ impl WhirR1CSSchemeBuilder for WhirR1CSScheme { challenge_offsets: Vec, has_public_inputs: bool, hash_config: HashConfig, - ) -> Self { + ) -> Result { let num_witnesses = r1cs.witness_layout.size(); let num_constraints = r1cs.constraints.len(); let a_num_entries: usize = r1cs.constraints.iter().map(|c| c.a.len()).sum(); @@ -237,13 +246,16 @@ impl WhirR1CSSchemeBuilder for WhirR1CSScheme { challenge_offsets: Vec, has_public_inputs: bool, hash_config: HashConfig, - ) -> Self { - debug_assert_eq!( - num_challenges, - challenge_offsets.len(), + ) -> Result { + ensure!( + num_challenges == challenge_offsets.len(), "num_challenges ({num_challenges}) != challenge_offsets.len() ({})", challenge_offsets.len() ); + ensure!( + w1_size <= num_witnesses, + "w1_size ({w1_size}) exceeds total witnesses ({num_witnesses})" + ); let m_raw = next_power_of_two(num_witnesses); let m0_raw = next_power_of_two(num_constraints); @@ -255,7 +267,7 @@ impl WhirR1CSSchemeBuilder for WhirR1CSScheme { m += 1; } - Self { + Ok(Self { m, m_0, a_num_terms: next_power_of_two(a_num_entries), @@ -266,7 +278,7 @@ impl WhirR1CSSchemeBuilder for WhirR1CSScheme { has_public_inputs, r1cs_hash: R1csHash::UNSET, hash_config, - } + }) } } diff --git a/provekit/prover/src/roundtrip_tests.rs b/provekit/prover/src/roundtrip_tests.rs index 75416bd71..cf07ba20e 100644 --- a/provekit/prover/src/roundtrip_tests.rs +++ b/provekit/prover/src/roundtrip_tests.rs @@ -52,7 +52,7 @@ fn prove( vec![], true, HASH, - ); + )?; let instance = public_inputs.hash_bytes(HASH); let ds = scheme.create_domain_separator().instance(&instance); diff --git a/provekit/r1cs-compiler/src/noir_proof_scheme.rs b/provekit/r1cs-compiler/src/noir_proof_scheme.rs index a1e176104..ff8214558 100644 --- a/provekit/r1cs-compiler/src/noir_proof_scheme.rs +++ b/provekit/r1cs-compiler/src/noir_proof_scheme.rs @@ -105,7 +105,7 @@ impl NoirCompiler { challenge_offsets, has_public_inputs, hash_config, - ); + )?; Ok(NoirProofScheme::Noir(NoirSchemeData { program: program.bytecode, @@ -178,7 +178,7 @@ impl MavrosCompiler { challenge_offsets, num_public_inputs > 0, hash_config, - ); + )?; whir_for_witness.r1cs_hash = r1cs.hash(); Ok(NoirProofScheme::Mavros(MavrosSchemeData { From cb2eb38ea1fbc4cf82ff41f11a7ebd055bfadb5e Mon Sep 17 00:00:00 2001 From: Yogesh Shahi Date: Mon, 15 Jun 2026 12:49:14 +0530 Subject: [PATCH 09/11] fix(common): size relocated new_from_dimensions off largest w1/w2 commitment The Mavros builder was relocated from r1cs-compiler into common before v2's fix landing, so new_from_dimensions still derived m from next_power_of_two( num_witnesses). v2 (PR #443) changed it to max(npot(w1_size), npot(w2_size)), since w1 and w2 are committed separately. Carry that split (already present in new_for_r1cs) into new_from_dimensions, the Mavros path, and port v2's four dimension tests, adapted for the now-fallible constructors. --- Cargo.lock | 846 +++++++++++++++++++++---------- provekit/common/src/whir_r1cs.rs | 78 ++- 2 files changed, 660 insertions(+), 264 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 6304dbf40..b1f19ea22 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,8 +29,8 @@ version = "1.0.0-beta.19" source = "git+https://github.com/noir-lang/noir?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" dependencies = [ "ark-bn254", - "ark-ff", - "ark-std", + "ark-ff 0.5.0", + "ark-std 0.5.0", "cfg-if", "hex", "num-bigint", @@ -45,7 +45,7 @@ dependencies = [ "acir", "acvm_blackbox_solver", "brillig_vm", - "indexmap 2.13.0", + "indexmap 2.13.1", "rustc-hash", "serde", "thiserror 1.0.69", @@ -66,7 +66,7 @@ dependencies = [ "keccak 0.2.0-rc.2", "log", "p256", - "sha2 0.11.0-rc.5", + "sha2 0.11.0", "thiserror 1.0.69", ] @@ -123,6 +123,16 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" +[[package]] +name = "alloy-rlp" +version = "0.3.15" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dc90b1e703d3c03f4ff7f48e82dd0bc1c8211ab7d079cd836a06fcfeb06651cb" +dependencies = [ + "arrayvec", + "bytes", +] + [[package]] name = "android_system_properties" version = "0.1.5" @@ -232,8 +242,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" dependencies = [ "ark-ec", - "ark-ff", - "ark-std", + "ark-ff 0.5.0", + "ark-std 0.5.0", ] [[package]] @@ -243,10 +253,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" dependencies = [ "ahash", - "ark-ff", + "ark-ff 0.5.0", "ark-poly", - "ark-serialize", - "ark-std", + "ark-serialize 0.5.0", + "ark-std 0.5.0", "educe", "fnv", "hashbrown 0.15.5", @@ -257,16 +267,54 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ark-ff" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" +dependencies = [ + "ark-ff-asm 0.3.0", + "ark-ff-macros 0.3.0", + "ark-serialize 0.3.0", + "ark-std 0.3.0", + "derivative", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.3.3", + "zeroize", +] + +[[package]] +name = "ark-ff" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" +dependencies = [ + "ark-ff-asm 0.4.2", + "ark-ff-macros 0.4.2", + "ark-serialize 0.4.2", + "ark-std 0.4.0", + "derivative", + "digest 0.10.7", + "itertools 0.10.5", + "num-bigint", + "num-traits", + "paste", + "rustc_version 0.4.1", + "zeroize", +] + [[package]] name = "ark-ff" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" dependencies = [ - "ark-ff-asm", - "ark-ff-macros", - "ark-serialize", - "ark-std", + "ark-ff-asm 0.5.0", + "ark-ff-macros 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", "arrayvec", "digest 0.10.7", "educe", @@ -277,6 +325,26 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ark-ff-asm" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" +dependencies = [ + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-asm" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" +dependencies = [ + "quote", + "syn 1.0.109", +] + [[package]] name = "ark-ff-asm" version = "0.5.0" @@ -287,6 +355,31 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "ark-ff-macros" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" +dependencies = [ + "num-bigint", + "num-traits", + "quote", + "syn 1.0.109", +] + +[[package]] +name = "ark-ff-macros" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" +dependencies = [ + "num-bigint", + "num-traits", + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "ark-ff-macros" version = "0.5.0" @@ -308,8 +401,8 @@ checksum = "ef677b59f5aff4123207c4dceb1c0ec8fdde2d4af7886f48be42ad864bfa0352" dependencies = [ "ark-bn254", "ark-ec", - "ark-ff", - "ark-std", + "ark-ff 0.5.0", + "ark-std 0.5.0", ] [[package]] @@ -319,14 +412,35 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" dependencies = [ "ahash", - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", "educe", "fnv", "hashbrown 0.15.5", ] +[[package]] +name = "ark-serialize" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" +dependencies = [ + "ark-std 0.3.0", + "digest 0.9.0", +] + +[[package]] +name = "ark-serialize" +version = "0.4.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" +dependencies = [ + "ark-std 0.4.0", + "digest 0.10.7", + "num-bigint", +] + [[package]] name = "ark-serialize" version = "0.5.0" @@ -334,7 +448,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" dependencies = [ "ark-serialize-derive", - "ark-std", + "ark-std 0.5.0", "arrayvec", "digest 0.10.7", "num-bigint", @@ -351,6 +465,26 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "ark-std" +version = "0.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + +[[package]] +name = "ark-std" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" +dependencies = [ + "num-traits", + "rand 0.8.5", +] + [[package]] name = "ark-std" version = "0.5.0" @@ -461,6 +595,17 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" +[[package]] +name = "auto_impl" +version = "1.3.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.117", +] + [[package]] name = "autocfg" version = "1.5.0" @@ -627,11 +772,11 @@ dependencies = [ [[package]] name = "blake2" -version = "0.11.0-rc.5" +version = "0.11.0-rc.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d52965399b470437fc7f4d4b51134668dbc96573fea6f1b83318a420e4605745" +checksum = "061f1a09225e328e1ffbb378d2d49923c0ca5fee19fb5ac1cc9c1e9d52b93690" dependencies = [ - "digest 0.11.2", + "digest 0.11.3", ] [[package]] @@ -682,12 +827,12 @@ name = "bn254-multiplier" version = "0.1.0" dependencies = [ "ark-bn254", - "ark-ff", + "ark-ff 0.5.0", "bn254-multiplier-codegen", "divan", "fp-rounding", "hla", - "primitive-types", + "primitive-types 0.13.1", "proptest", "rand 0.9.2", "seq-macro", @@ -709,7 +854,7 @@ dependencies = [ "acvm_blackbox_solver", "ark-bn254", "ark-ec", - "ark-ff", + "ark-ff 0.5.0", "ark-grumpkin", "hex", ] @@ -807,9 +952,9 @@ dependencies = [ [[package]] name = "cc" -version = "1.2.57" +version = "1.2.58" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a0dd1ca384932ff3641c8718a02769f1698e7563dc6974ffd03346116310423" +checksum = "e1e928d4b69e3077709075a938a05ffbedfa53a84c8f766efbf8220bb1ff60e1" dependencies = [ "find-msvc-tools", "jobserver", @@ -882,7 +1027,7 @@ version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "773f3b9af64447d2ce9850330c473515014aa235e6a783b02db81ff39e4a3dad" dependencies = [ - "crypto-common 0.1.7", + "crypto-common 0.1.6", "inout", ] @@ -949,9 +1094,9 @@ dependencies = [ [[package]] name = "cmov" -version = "0.5.2" +version = "0.5.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0758edba32d61d1fd9f4d69491b47604b91ee2f7e6b33de7e54ca4ebe55dc3" +checksum = "3f88a43d011fc4a6876cb7344703e297c71dda42494fee094d5f7c76bf13f746" [[package]] name = "cobs" @@ -1149,9 +1294,9 @@ checksum = "773648b94d0e5d620f64f280777445740e61fe701025087ec8b57f45c791888b" [[package]] name = "cpubits" -version = "0.1.0" +version = "0.1.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5ef0c543070d296ea414df2dd7625d1b24866ce206709d8a4a424f28377f5861" +checksum = "15b85f9c39137c3a891689859392b1bd49812121d0d61c9caf00d46ed5ce06ae" [[package]] name = "cpufeatures" @@ -1243,9 +1388,9 @@ checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5" [[package]] name = "crypto-bigint" -version = "0.7.1" +version = "0.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9fde2467e74147f492aebb834985186b2c74761927b8b9b3bd303bcb2e72199d" +checksum = "42a0d26b245348befa0c121944541476763dcc46ede886c88f9d12e1697d27c3" dependencies = [ "cpubits", "ctutils", @@ -1259,9 +1404,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.7" +version = "0.1.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "78c8292055d1c1df0cce5d180393dc8cce0abec0a7102adb6c7b1eef6016d60a" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", @@ -1301,9 +1446,9 @@ dependencies = [ [[package]] name = "ctutils" -version = "0.4.0" +version = "0.4.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1005a6d4446f5120ef475ad3d2af2b30c49c2c9c6904258e3bb30219bebed5e4" +checksum = "7d5515a3834141de9eafb9717ad39eea8247b5674e6066c404e8c4b365d2a29e" dependencies = [ "cmov", "subtle", @@ -1406,6 +1551,17 @@ dependencies = [ "serde_core", ] +[[package]] +name = "derivative" +version = "2.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" +dependencies = [ + "proc-macro2", + "quote", + "syn 1.0.109", +] + [[package]] name = "derive-where" version = "1.6.1" @@ -1417,6 +1573,15 @@ dependencies = [ "syn 2.0.117", ] +[[package]] +name = "digest" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" +dependencies = [ + "generic-array", +] + [[package]] name = "digest" version = "0.10.7" @@ -1425,15 +1590,15 @@ checksum = "9ed9a281f7bc9b7576e61468ba615a66a5c8cfdff42420a70aa82701a3b1e292" dependencies = [ "block-buffer 0.10.4", "const-oid 0.9.6", - "crypto-common 0.1.7", + "crypto-common 0.1.6", "subtle", ] [[package]] name = "digest" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4850db49bf08e663084f7fb5c87d202ef91a3907271aff24a94eb97ff039153c" +checksum = "f1dd6dbb5841937940781866fa1281a1ff7bd3bf827091440879f9994983d5c2" dependencies = [ "block-buffer 0.12.0", "const-oid 0.10.2", @@ -1548,16 +1713,16 @@ dependencies = [ [[package]] name = "ecdsa" -version = "0.17.0-rc.16" +version = "0.17.0-rc.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91bbdd377139884fafcad8dc43a760a3e1e681aa26db910257fa6535b70e1829" +checksum = "54fb064faabbee66e1fc8e5c5a9458d4269dc2d8b638fe86a425adb2510d1a96" dependencies = [ "der 0.8.0", - "digest 0.11.2", + "digest 0.11.3", "elliptic-curve", "rfc6979", - "signature 3.0.0-rc.10", - "spki 0.8.0-rc.4", + "signature 3.0.0", + "spki 0.8.0", "zeroize", ] @@ -1581,18 +1746,18 @@ checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719" [[package]] name = "elliptic-curve" -version = "0.14.0-rc.29" +version = "0.14.0-rc.32" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e84043d573efd4ac9d2d125817979a379204bf7e328b25a4a30487e8d100e618" +checksum = "cda94f31325c4275e9706adecbb6f0650dee2f904c915a98e3d81adaaaa757aa" dependencies = [ "base16ct", "crypto-bigint", "crypto-common 0.2.1", - "digest 0.11.2", + "digest 0.11.3", "hybrid-array", "once_cell", "pem-rfc7468 1.0.0", - "pkcs8 0.11.0-rc.11", + "pkcs8 0.11.0", "rand_core 0.10.0", "rustcrypto-ff", "rustcrypto-group", @@ -1656,9 +1821,9 @@ dependencies = [ [[package]] name = "env_filter" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a1c3cc8e57274ec99de65301228b537f1e4eedc1b8e0f9411c6caac8ae7308f" +checksum = "32e90c2accc4b07a8456ea0debdc2e7587bdd890680d71173a15d4ae604f6eef" dependencies = [ "log", "regex", @@ -1666,9 +1831,9 @@ dependencies = [ [[package]] name = "env_logger" -version = "0.11.9" +version = "0.11.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b2daee4ea451f429a58296525ddf28b45a3b64f1acf6587e2067437bb11e218d" +checksum = "0621c04f2196ac3f488dd583365b9c09be011a4ab8b9f37248ffcc8f6198b56a" dependencies = [ "env_filter", "log", @@ -1716,6 +1881,28 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" +[[package]] +name = "fastrlp" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + +[[package]] +name = "fastrlp" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ce8dba4714ef14b8274c371879b175aa55b16b30f269663f19d576f380018dc4" +dependencies = [ + "arrayvec", + "auto_impl", + "bytes", +] + [[package]] name = "fd-lock" version = "3.0.13" @@ -1753,7 +1940,7 @@ checksum = "f98844151eee8917efc50bd9e8318cb963ae8b297431495d3f758616ea5c57db" dependencies = [ "cfg-if", "libc", - "libredox 0.1.14", + "libredox 0.1.15", ] [[package]] @@ -1970,9 +2157,9 @@ dependencies = [ [[package]] name = "generic-array" -version = "0.14.7" +version = "0.14.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85649ca51fd72272d7821adaf274ad91c288277713d9c18820d8499a7ff69e9a" +checksum = "4bb6743198531e02858aeaea5398fcc883e71851fcbcb5a2f773e2fb6cb1edf2" dependencies = [ "typenum", "version_check", @@ -2039,7 +2226,7 @@ dependencies = [ "futures-core", "futures-sink", "http", - "indexmap 2.13.0", + "indexmap 2.13.1", "slab", "tokio", "tokio-util", @@ -2097,7 +2284,7 @@ checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" dependencies = [ "atomic-polyfill", "hash32", - "rustc_version", + "rustc_version 0.4.1", "serde", "spin 0.9.8", "stable_deref_trait", @@ -2144,11 +2331,11 @@ dependencies = [ [[package]] name = "hmac" -version = "0.13.0-rc.5" +version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ef451d73f36d8a3f93ad32c332ea01146c9650e1ec821a9b0e46c01277d544f8" +checksum = "6303bc9732ae41b04cb554b844a762b4115a61bfaa81e3e83050991eeb56863f" dependencies = [ - "digest 0.11.2", + "digest 0.11.3", ] [[package]] @@ -2198,9 +2385,9 @@ checksum = "df3b46402a9d5adb4c86a0cf463f42e19994e3ee891101b1841f30a545cb49a9" [[package]] name = "hybrid-array" -version = "0.4.8" +version = "0.4.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8655f91cd07f2b9d0c24137bd650fe69617773435ee5ec83022377777ce65ef1" +checksum = "08d46837a0ed51fe95bd3b05de33cd64a1ee88fc797477ca48446872504507c5" dependencies = [ "subtle", "typenum", @@ -2209,9 +2396,9 @@ dependencies = [ [[package]] name = "hyper" -version = "1.8.1" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2ab2d4f250c3d7b1c9fcdff1cece94ea4e2dfbec68614f7b87cb205f24ca9d11" +checksum = "6299f016b246a94207e63da54dbe807655bf9e00044f73ded42c3ac5305fbcca" dependencies = [ "atomic-waker", "bytes", @@ -2224,7 +2411,6 @@ dependencies = [ "httpdate", "itoa", "pin-project-lite", - "pin-utils", "smallvec", "tokio", "want", @@ -2314,12 +2500,13 @@ dependencies = [ [[package]] name = "icu_collections" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "4c6b649701667bbe825c3b7e6388cb521c23d88644678e83c0c4d0a621a34b43" +checksum = "2984d1cd16c883d7935b9e07e44071dca8d917fd52ecc02c04d5fa0b5a3f191c" dependencies = [ "displaydoc", "potential_utf", + "utf8_iter", "yoke", "zerofrom", "zerovec", @@ -2327,9 +2514,9 @@ dependencies = [ [[package]] name = "icu_locale_core" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "edba7861004dd3714265b4db54a3c390e880ab658fec5f7db895fae2046b5bb6" +checksum = "92219b62b3e2b4d88ac5119f8904c10f8f61bf7e95b640d25ba3075e6cac2c29" dependencies = [ "displaydoc", "litemap", @@ -2340,9 +2527,9 @@ dependencies = [ [[package]] name = "icu_normalizer" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5f6c8828b67bf8908d82127b2054ea1b4427ff0230ee9141c54251934ab1b599" +checksum = "c56e5ee99d6e3d33bd91c5d85458b6005a22140021cc324cea84dd0e72cff3b4" dependencies = [ "icu_collections", "icu_normalizer_data", @@ -2354,15 +2541,15 @@ dependencies = [ [[package]] name = "icu_normalizer_data" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7aedcccd01fc5fe81e6b489c15b247b8b0690feb23304303a9e560f37efc560a" +checksum = "da3be0ae77ea334f4da67c12f149704f19f81d1adf7c51cf482943e84a2bad38" [[package]] name = "icu_properties" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "020bfc02fe870ec3a66d93e677ccca0562506e5872c650f893269e08615d74ec" +checksum = "bee3b67d0ea5c2cca5003417989af8996f8604e34fb9ddf96208a033901e70de" dependencies = [ "icu_collections", "icu_locale_core", @@ -2374,15 +2561,15 @@ dependencies = [ [[package]] name = "icu_properties_data" -version = "2.1.2" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "616c294cf8d725c6afcd8f55abc17c56464ef6211f9ed59cccffe534129c77af" +checksum = "8e2bbb201e0c04f7b4b3e14382af113e17ba4f63e2c9d2ee626b720cbce54a14" [[package]] name = "icu_provider" -version = "2.1.1" +version = "2.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "85962cf0ce02e1e0a629cc34e7ca3e373ce20dda4c4d7294bbd0bf1fdb59e614" +checksum = "139c4cf31c8b5f33d7e199446eff9c1e02decfc2f0eec2c8d71f65befa45b421" dependencies = [ "displaydoc", "icu_locale_core", @@ -2441,6 +2628,15 @@ dependencies = [ "version_check", ] +[[package]] +name = "impl-codec" +version = "0.6.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" +dependencies = [ + "parity-scale-codec", +] + [[package]] name = "impl-codec" version = "0.7.1" @@ -2480,9 +2676,9 @@ dependencies = [ [[package]] name = "indexmap" -version = "2.13.0" +version = "2.13.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7714e70437a7dc3ac8eb7e6f8df75fd8eb422675fc7678aff7364301092b1017" +checksum = "45a8a2b9cb3e0b0c1803dbb0758ffac5de2f425b23c28f518faabd9d805342ff" dependencies = [ "equivalent", "hashbrown 0.16.1", @@ -2537,9 +2733,9 @@ checksum = "d98f6fed1fde3f8c21bc40a1abb88dd75e67924f9cffc3ef95607bad8017f8e2" [[package]] name = "iri-string" -version = "0.7.10" +version = "0.7.12" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c91338f0783edbd6195decb37bae672fd3b165faffb89bf7b9e6942f8b1a731a" +checksum = "25e659a4bb38e810ebc252e53b5814ff908a8c58c2a9ce2fae1bbec24cbf4e20" dependencies = [ "memchr", "serde", @@ -2596,9 +2792,9 @@ dependencies = [ [[package]] name = "itoa" -version = "1.0.17" +version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "92ecc6618181def0457392ccd0ee51198e065e016d1d527a7ac1b6dc7c1f09d2" +checksum = "8f42a60cbdf9a97f5d2305f08a87dc4e09308d1276d28c869c684d7777685682" [[package]] name = "jni" @@ -2609,7 +2805,7 @@ dependencies = [ "cesu8", "cfg-if", "combine", - "jni-sys", + "jni-sys 0.3.1", "log", "thiserror 1.0.69", "walkdir", @@ -2618,9 +2814,31 @@ dependencies = [ [[package]] name = "jni-sys" -version = "0.3.0" +version = "0.3.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8eaf4bc02d17cbdd7ff4c7438cafcdf7fb9a4613313ad11b4f8fefe7d3fa0130" +checksum = "41a652e1f9b6e0275df1f15b32661cf0d4b78d4d87ddec5e0c3c20f097433258" +dependencies = [ + "jni-sys 0.4.1", +] + +[[package]] +name = "jni-sys" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c6377a88cb3910bee9b0fa88d4f42e1d2da8e79915598f65fb0c7ee14c878af2" +dependencies = [ + "jni-sys-macros", +] + +[[package]] +name = "jni-sys-macros" +version = "0.4.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "38c0b942f458fe50cdac086d2f946512305e5631e720728f2a61aabcd47a6264" +dependencies = [ + "quote", + "syn 2.0.117", +] [[package]] name = "jobserver" @@ -2733,15 +2951,15 @@ checksum = "17ab85f84ca42c5ec520e6f3c9966ba1fd62909ce260f8837e248857d2560509" [[package]] name = "k256" -version = "0.14.0-rc.8" +version = "0.14.0-rc.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f7d2c6c227649d5ec80eaae541f1736232641a0bcdb3062a52b34edb42054158" +checksum = "1b382cbfd43caf55991a93850ce538aa1aa67bb264af367d22dfe7937c4e997d" dependencies = [ "cpubits", "ecdsa", "elliptic-curve", - "sha2 0.11.0-rc.5", - "signature 3.0.0-rc.10", + "sha2 0.11.0", + "signature 3.0.0", ] [[package]] @@ -2819,9 +3037,9 @@ checksum = "09edd9e8b54e49e587e4f6295a7d29c3ea94d469cb40ab8ca70b288248a81db2" [[package]] name = "libc" -version = "0.2.183" +version = "0.2.184" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b5b646652bf6661599e1da8901b3b9522896f01e736bad5f723fe7a3a27f899d" +checksum = "48f5d2a454e16a5ea0f4ced81bd44e4cfc7bd3a507b61887c99fd3538b28e4af" [[package]] name = "libm" @@ -2842,9 +3060,9 @@ dependencies = [ [[package]] name = "libredox" -version = "0.1.14" +version = "0.1.15" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1744e39d1d6a9948f4f388969627434e31128196de472883b39f148769bfe30a" +checksum = "7ddbf48fd451246b1f8c2610bd3b4ac0cc6e149d89832867093ab69a17194f08" dependencies = [ "bitflags 2.11.0", "libc", @@ -2866,9 +3084,9 @@ checksum = "32a66949e030da00e8c7d4434b251670a91556f4144941d37452769c25d58a53" [[package]] name = "litemap" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6373607a59f0be73a39b6fe456b8192fcc3585f602af20751600e974dd455e77" +checksum = "92daf443525c4cce67b150400bc2316076100ce0b3686209eb8cf3c31612e6f0" [[package]] name = "lock_api" @@ -2990,22 +3208,33 @@ checksum = "47e1ffaa40ddd1f3ed91f717a33c8c0ee23fff369e3aa8772b9605cc1d22f4c3" [[package]] name = "mavros-artifacts" version = "0.1.0" -source = "git+https://github.com/reilabs/mavros?rev=3e47fd58001a0109a0314bc080b5246fd807ba04#3e47fd58001a0109a0314bc080b5246fd807ba04" +source = "git+https://github.com/reilabs/mavros?rev=7550b42e03d35b44781ff37f15b50773eb2a6fa0#7550b42e03d35b44781ff37f15b50773eb2a6fa0" dependencies = [ "ark-bn254", - "ark-ff", + "ark-ff 0.5.0", "serde", "tracing", ] +[[package]] +name = "mavros-opcode-gen" +version = "0.1.0" +source = "git+https://github.com/reilabs/mavros?rev=7550b42e03d35b44781ff37f15b50773eb2a6fa0#7550b42e03d35b44781ff37f15b50773eb2a6fa0" +dependencies = [ + "proc-macro2", + "quote", + "stringcase", + "syn 2.0.117", +] + [[package]] name = "mavros-vm" version = "0.1.0" -source = "git+https://github.com/reilabs/mavros?rev=3e47fd58001a0109a0314bc080b5246fd807ba04#3e47fd58001a0109a0314bc080b5246fd807ba04" +source = "git+https://github.com/reilabs/mavros?rev=7550b42e03d35b44781ff37f15b50773eb2a6fa0#7550b42e03d35b44781ff37f15b50773eb2a6fa0" dependencies = [ - "ark-ff", + "ark-ff 0.5.0", "mavros-artifacts", - "opcode-gen", + "mavros-opcode-gen", "tracing", ] @@ -3060,9 +3289,9 @@ dependencies = [ [[package]] name = "mio" -version = "1.1.1" +version = "1.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a69bcab0ad47271a0234d9422b131806bf3968021e5dc9328caf2d4cd58557fc" +checksum = "50b7e5b27aa02a74bac8c3f23f448f8d87ff11f92d3aac1a6ed369ee08cc56c1" dependencies = [ "libc", "wasi", @@ -3196,7 +3425,7 @@ dependencies = [ "nargo", "noirc_driver", "noirc_frontend", - "semver", + "semver 1.0.27", "serde", "thiserror 1.0.69", "toml 0.7.8", @@ -3482,7 +3711,7 @@ dependencies = [ "chrono", "fm", "im", - "indexmap 2.13.0", + "indexmap 2.13.1", "iter-extended", "noirc_artifacts", "noirc_errors", @@ -3602,8 +3831,8 @@ name = "ntt" version = "0.1.0" dependencies = [ "ark-bn254", - "ark-ff", - "ark-std", + "ark-ff 0.5.0", + "ark-std 0.5.0", "bn254-multiplier", "divan", "proptest", @@ -3648,9 +3877,9 @@ dependencies = [ [[package]] name = "num-conv" -version = "0.2.0" +version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "cf97ec579c3c42f953ef76dbf8d55ac91fb219dde70e49aa4a6b7d74e9919050" +checksum = "c6673768db2d862beb9b39a78fdcb1a69439615d5794a1be50caa9bc92c81967" [[package]] name = "num-integer" @@ -3767,17 +3996,6 @@ version = "1.70.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "384b8ab6d37215f3c5301a95a4accb5d64aa607f1fcb26a11b5303878451b4fe" -[[package]] -name = "opcode-gen" -version = "0.1.0" -source = "git+https://github.com/reilabs/mavros?rev=3e47fd58001a0109a0314bc080b5246fd807ba04#3e47fd58001a0109a0314bc080b5246fd807ba04" -dependencies = [ - "proc-macro2", - "quote", - "stringcase", - "syn 2.0.117", -] - [[package]] name = "openssl" version = "0.10.76" @@ -3830,9 +4048,9 @@ checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" [[package]] name = "ordered-float" -version = "5.1.0" +version = "5.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f4779c6901a562440c3786d08192c6fbda7c1c2060edd10006b05ee35d10f2d" +checksum = "b7d950ca161dc355eaf28f82b11345ed76c6e1f6eb1f4f4479e0323b9e2fbd0e" dependencies = [ "num-traits", "rand 0.8.5", @@ -3847,15 +4065,15 @@ checksum = "d211803b9b6b570f68772237e415a029d5a50c65d382910b879fb19d3271f94d" [[package]] name = "p256" -version = "0.14.0-rc.8" +version = "0.14.0-rc.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "44f0a10fe314869359cb2901342b045f4e5a962ef9febc006f03d2a8c848fe4c" +checksum = "8b97e3bf0465157ae90975ff52dbeb1362ba618924878c9f74c25baa27a65f9a" dependencies = [ "ecdsa", "elliptic-curve", "primefield", "primeorder", - "sha2 0.11.0-rc.5", + "sha2 0.11.0", ] [[package]] @@ -4067,7 +4285,7 @@ dependencies = [ "anyhow", "argh", "ark-bn254", - "ark-ff", + "ark-ff 0.5.0", "base64", "chrono", "hex", @@ -4121,6 +4339,16 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" +[[package]] +name = "pest" +version = "2.8.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" +dependencies = [ + "memchr", + "ucd-trie", +] + [[package]] name = "petgraph" version = "0.8.3" @@ -4129,7 +4357,7 @@ checksum = "8701b58ea97060d5e5b155d383a69952a60943f0e6dfe30b04c287beb0b27455" dependencies = [ "fixedbitset", "hashbrown 0.15.5", - "indexmap 2.13.0", + "indexmap 2.13.1", "serde", ] @@ -4159,12 +4387,6 @@ version = "0.2.17" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a89322df9ebe1c1578d689c92318e070967d1042b512afbe49518723f4e6d5cd" -[[package]] -name = "pin-utils" -version = "0.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8b870d8c151b6f2fb93e84a13146138f05d02ed11c7e7c54f8826aaaf7c9f184" - [[package]] name = "pkcs1" version = "0.7.5" @@ -4188,12 +4410,12 @@ dependencies = [ [[package]] name = "pkcs8" -version = "0.11.0-rc.11" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "12922b6296c06eb741b02d7b5161e3aaa22864af38dfa025a1a3ba3f68c84577" +checksum = "451913da69c775a56034ea8d9003d27ee8948e12443eae7c038ba100a4f21cb7" dependencies = [ "der 0.8.0", - "spki 0.8.0-rc.4", + "spki 0.8.0", ] [[package]] @@ -4213,8 +4435,8 @@ name = "poseidon2" version = "0.1.0" dependencies = [ "ark-bn254", - "ark-ff", - "ark-std", + "ark-ff 0.5.0", + "ark-std 0.5.0", ] [[package]] @@ -4232,9 +4454,9 @@ dependencies = [ [[package]] name = "potential_utf" -version = "0.1.4" +version = "0.1.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b73949432f5e2a09657003c25bca5e19a0e9c84f8058ca374f49e0ebe605af77" +checksum = "0103b1cef7ec0cf76490e969665504990193874ea05c85ff9bab8b911d0a0564" dependencies = [ "zerovec", ] @@ -4280,9 +4502,9 @@ dependencies = [ [[package]] name = "primefield" -version = "0.14.0-rc.8" +version = "0.14.0-rc.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c6543f5eec854fbf74ba5ef651fbdc9408919b47c3e1526623687135c16d12e9" +checksum = "1b52e6ee42db392378a95622b463c9740631171d1efce43fa445a569c1600cb6" dependencies = [ "crypto-bigint", "crypto-common 0.2.1", @@ -4294,13 +4516,24 @@ dependencies = [ [[package]] name = "primeorder" -version = "0.14.0-rc.8" +version = "0.14.0-rc.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "569d9ad6ef822bb0322c7e7d84e5e286244050bd5246cac4c013535ae91c2c90" +checksum = "0556580e42c19833f5d232aca11a7687a503ee41f937b54f5ae1d50fc2a6a36a" dependencies = [ "elliptic-curve", ] +[[package]] +name = "primitive-types" +version = "0.12.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" +dependencies = [ + "fixed-hash", + "impl-codec 0.6.0", + "uint 0.9.5", +] + [[package]] name = "primitive-types" version = "0.13.1" @@ -4308,8 +4541,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d15600a7d856470b7d278b3fe0e311fe28c2526348549f8ef2ff7db3299c87f5" dependencies = [ "fixed-hash", - "impl-codec", - "uint", + "impl-codec 0.7.1", + "uint 0.10.0", ] [[package]] @@ -4318,7 +4551,7 @@ version = "3.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e67ba7e9b2b56446f1d419b1d807906278ffa1a658a8a5d8a39dcb1f5a78614f" dependencies = [ - "toml_edit 0.25.5+spec-1.1.0", + "toml_edit 0.25.10+spec-1.1.0", ] [[package]] @@ -4332,9 +4565,9 @@ dependencies = [ [[package]] name = "proptest" -version = "1.10.0" +version = "1.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "37566cb3fdacef14c0737f9546df7cfeadbfbc9fef10991038bf5015d0c80532" +checksum = "4b45fcc2344c680f5025fe57779faef368840d0bd1f42f216291f0dc4ace4744" dependencies = [ "bit-set", "bit-vec", @@ -4351,11 +4584,11 @@ dependencies = [ [[package]] name = "provekit-bench" -version = "1.0.0" +version = "0.1.0" dependencies = [ "acir", "anyhow", - "ark-ff", + "ark-ff 0.5.0", "divan", "nargo", "nargo_cli", @@ -4373,12 +4606,12 @@ dependencies = [ [[package]] name = "provekit-cli" -version = "1.0.0" +version = "0.1.0" dependencies = [ "acir", "anyhow", "argh", - "ark-ff", + "ark-ff 0.5.0", "base64", "hex", "nargo", @@ -4402,14 +4635,14 @@ dependencies = [ [[package]] name = "provekit-common" -version = "1.0.0" +version = "0.1.0" dependencies = [ "acir", "anyhow", "ark-bn254", - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", "base64", "blake3", "bytes", @@ -4425,6 +4658,7 @@ dependencies = [ "postcard", "proptest", "rayon", + "ruint", "serde", "serde_json", "sha2 0.10.9", @@ -4441,7 +4675,7 @@ dependencies = [ [[package]] name = "provekit-ffi" -version = "1.0.0" +version = "0.1.0" dependencies = [ "anyhow", "libc", @@ -4471,12 +4705,12 @@ dependencies = [ [[package]] name = "provekit-prover" -version = "1.0.0" +version = "0.1.0" dependencies = [ "acir", "anyhow", - "ark-ff", - "ark-std", + "ark-ff 0.5.0", + "ark-std 0.5.0", "bn254_blackbox_solver", "mavros-artifacts", "mavros-vm", @@ -4486,19 +4720,18 @@ dependencies = [ "num-bigint", "postcard", "provekit-common", - "provekit-verifier", "tracing", "whir", ] [[package]] name = "provekit-r1cs-compiler" -version = "1.0.0" +version = "0.1.0" dependencies = [ "acir", "anyhow", - "ark-ff", - "ark-std", + "ark-ff 0.5.0", + "ark-std 0.5.0", "bincode", "mavros-artifacts", "noirc_abi", @@ -4514,10 +4747,10 @@ dependencies = [ [[package]] name = "provekit-verifier" -version = "1.0.0" +version = "0.1.0" dependencies = [ "anyhow", - "ark-std", + "ark-std 0.5.0", "provekit-common", "rayon", "tracing", @@ -4834,7 +5067,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ba009ff324d1fc1b900bd1fdb31564febe58a8ccc8a6fdbb93b543d33b13ca43" dependencies = [ "getrandom 0.2.17", - "libredox 0.1.14", + "libredox 0.1.15", "thiserror 1.0.69", ] @@ -4845,7 +5078,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a4e608c6638b9c18977b00b475ac1f28d14e84b27d8d42f70e0bf1e3dec127ac" dependencies = [ "getrandom 0.2.17", - "libredox 0.1.14", + "libredox 0.1.15", "thiserror 2.0.18", ] @@ -4968,6 +5201,16 @@ dependencies = [ "windows-sys 0.52.0", ] +[[package]] +name = "rlp" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" +dependencies = [ + "bytes", + "rustc-hex", +] + [[package]] name = "rmp" version = "0.8.15" @@ -5008,6 +5251,40 @@ dependencies = [ "zeroize", ] +[[package]] +name = "ruint" +version = "1.17.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c141e807189ad38a07276942c6623032d3753c8859c146104ac2e4d68865945a" +dependencies = [ + "alloy-rlp", + "ark-ff 0.3.0", + "ark-ff 0.4.2", + "ark-ff 0.5.0", + "bytes", + "fastrlp 0.3.1", + "fastrlp 0.4.0", + "num-bigint", + "num-integer", + "num-traits", + "parity-scale-codec", + "primitive-types 0.12.2", + "proptest", + "rand 0.8.5", + "rand 0.9.2", + "rlp", + "ruint-macro", + "serde_core", + "valuable", + "zeroize", +] + +[[package]] +name = "ruint-macro" +version = "1.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" + [[package]] name = "rust-embed" version = "8.11.0" @@ -5050,9 +5327,9 @@ checksum = "b50b8869d9fc858ce7266cce0194bd74df58b9d0e3f6df3a9fc8eb470d95c09d" [[package]] name = "rustc-hash" -version = "2.1.1" +version = "2.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "357703d41365b4b27c590e3ed91eabb1b663f07c4c084095e60cbed4362dff0d" +checksum = "94300abf3f1ae2e2b8ffb7b58043de3d399c73fa6f4b73826402a5c457614dbe" [[package]] name = "rustc-hex" @@ -5066,20 +5343,29 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "781442f29170c5c93b7185ad559492601acdc71d5bb0706f5868094f45cfcd08" +[[package]] +name = "rustc_version" +version = "0.3.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" +dependencies = [ + "semver 0.11.0", +] + [[package]] name = "rustc_version" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver", + "semver 1.0.27", ] [[package]] name = "rustcrypto-ff" -version = "0.14.0-rc.0" +version = "0.14.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c5db129183b2c139d7d87d08be57cba626c715789db17aec65c8866bfd767d1f" +checksum = "fd2a8adb347447693cd2ba0d218c4b66c62da9b0a5672b17b981e4291ec65ff6" dependencies = [ "rand_core 0.10.0", "subtle", @@ -5087,9 +5373,9 @@ dependencies = [ [[package]] name = "rustcrypto-group" -version = "0.14.0-rc.0" +version = "0.14.0-rc.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "57c4b1463f274a3ff6fb2f44da43e576cb9424367bd96f185ead87b52fe00523" +checksum = "369f9b61aa45933c062c9f6b5c3c50ab710687eca83dd3802653b140b43f85ed" dependencies = [ "rand_core 0.10.0", "rustcrypto-ff", @@ -5196,9 +5482,9 @@ checksum = "f87165f0995f63a9fbeea62b64d10b4d9d8e78ec6d7d51fb2125fda7bb36788f" [[package]] name = "rustls-webpki" -version = "0.103.9" +version = "0.103.10" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d7df23109aa6c1567d1c575b9952556388da57401e4ace1d15f79eedad0d8f53" +checksum = "df33b2b81ac578cabaf06b89b0631153a3f416b0a886e8a7a1707fb51abbd1ef" dependencies = [ "ring", "rustls-pki-types", @@ -5375,9 +5661,9 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" [[package]] name = "sec1" -version = "0.8.0" +version = "0.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f46b9a5ab87780a3189a1d704766579517a04ad59de653b7aad7d38e8a15f7dc" +checksum = "d56d437c2f19203ce5f7122e507831de96f3d2d4d3be5af44a0b0a09d8a80e4d" dependencies = [ "base16ct", "ctutils", @@ -5410,12 +5696,30 @@ dependencies = [ "libc", ] +[[package]] +name = "semver" +version = "0.11.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" +dependencies = [ + "semver-parser", +] + [[package]] name = "semver" version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" +[[package]] +name = "semver-parser" +version = "0.10.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" +dependencies = [ + "pest", +] + [[package]] name = "seq-macro" version = "0.3.6" @@ -5538,7 +5842,7 @@ dependencies = [ "chrono", "hex", "indexmap 1.9.3", - "indexmap 2.13.0", + "indexmap 2.13.1", "schemars 0.9.0", "schemars 1.2.1", "serde_core", @@ -5573,13 +5877,13 @@ dependencies = [ [[package]] name = "sha2" -version = "0.11.0-rc.5" +version = "0.11.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7c5f3b1e2dc8aad28310d8410bd4d7e180eca65fca176c52ab00d364475d0024" +checksum = "446ba717509524cb3f22f17ecc096f10f4822d76ab5c0b9822c5f9c284e825f4" dependencies = [ "cfg-if", - "cpufeatures 0.2.17", - "digest 0.11.2", + "cpufeatures 0.3.0", + "digest 0.11.3", ] [[package]] @@ -5656,19 +5960,19 @@ dependencies = [ [[package]] name = "signature" -version = "3.0.0-rc.10" +version = "3.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7f1880df446116126965eeec169136b2e0251dba37c6223bcc819569550edea3" +checksum = "28d567dcbaf0049cb8ac2608a76cd95ff9e4412e1899d389ee400918ca7537f5" dependencies = [ - "digest 0.11.2", + "digest 0.11.3", "rand_core 0.10.0", ] [[package]] name = "simd-adler32" -version = "0.3.8" +version = "0.3.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e320a6c5ad31d271ad523dcf3ad13e2767ad8b1cb8f047f75a8aeaf8da139da2" +checksum = "703d5c7ef118737c72f1af64ad2f6f8c5e1921f818cdcb97b8fe6fc69bf66214" [[package]] name = "similar" @@ -5705,7 +6009,7 @@ name = "skyscraper" version = "0.1.0" dependencies = [ "ark-bn254", - "ark-ff", + "ark-ff 0.5.0", "bn254-multiplier", "divan", "fp-rounding", @@ -5825,9 +6129,9 @@ dependencies = [ [[package]] name = "spki" -version = "0.8.0-rc.4" +version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8baeff88f34ed0691978ec34440140e1572b68c7dd4a495fd14a3dc1944daa80" +checksum = "1d9efca8738c78ee9484207732f728b1ef517bbb1833d6fc0879ca898a522f6f" dependencies = [ "base64ct", "der 0.8.0", @@ -5838,8 +6142,8 @@ name = "spongefish" version = "1.0.0-rc1" source = "git+https://github.com/arkworks-rs/spongefish?rev=fcc277f8a857fdeeadd7cca92ab08de63b1ff1a1#fcc277f8a857fdeeadd7cca92ab08de63b1ff1a1" dependencies = [ - "ark-ff", - "ark-serialize", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", "blake3", "digest 0.10.7", "keccak 0.1.6", @@ -6028,12 +6332,12 @@ dependencies = [ [[package]] name = "terminal_size" -version = "0.4.3" +version = "0.4.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "60b8cb979cb11c32ce1603f8137b22262a9d131aaa5c37b5678025f22b8becd0" +checksum = "230a1b821ccbd75b185820a1f1ff7b14d21da1e442e22c0863ea5f08771a8874" dependencies = [ "rustix 1.1.4", - "windows-sys 0.60.2", + "windows-sys 0.61.2", ] [[package]] @@ -6194,9 +6498,9 @@ dependencies = [ [[package]] name = "tinystr" -version = "0.8.2" +version = "0.8.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "42d3e9c45c09de15d06dd8acf5f4e0e399e85927b7f00711024eb7ae10fa4869" +checksum = "c8323304221c2a851516f22236c5722a72eaa19749016521d6dff0824447d96d" dependencies = [ "displaydoc", "zerovec", @@ -6204,13 +6508,13 @@ dependencies = [ [[package]] name = "tokio" -version = "1.50.0" +version = "1.51.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "27ad5e34374e03cfffefc301becb44e9dc3c17584f414349ebe29ed26661822d" +checksum = "2bd1c4c0fc4a7ab90fc15ef6daaa3ec3b893f004f915f2392557ed23237820cd" dependencies = [ "bytes", "libc", - "mio 1.1.1", + "mio 1.2.0", "parking_lot", "pin-project-lite", "signal-hook-registry", @@ -6221,9 +6525,9 @@ dependencies = [ [[package]] name = "tokio-macros" -version = "2.6.1" +version = "2.7.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5c55a2eff8b69ce66c84f85e1da1c233edc36ceb85a2058d11b0d6a3c7e7569c" +checksum = "385a6cb71ab9ab790c5fe8d67f1645e6c450a7ce006a33de03daa956cf70a496" dependencies = [ "proc-macro2", "quote", @@ -6299,9 +6603,9 @@ dependencies = [ [[package]] name = "toml_datetime" -version = "1.0.1+spec-1.1.0" +version = "1.1.1+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b320e741db58cac564e26c607d3cc1fdc4a88fd36c879568c07856ed83ff3e9" +checksum = "3165f65f62e28e0115a00b2ebdd37eb6f3b641855f9d636d3cd4103767159ad7" dependencies = [ "serde_core", ] @@ -6312,7 +6616,7 @@ version = "0.19.15" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1b5bb770da30e5cbfde35a2d7b9b8a2c4b8ef89548a7a6aeab5c9a576e3e7421" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.13.1", "serde", "serde_spanned", "toml_datetime 0.6.11", @@ -6325,7 +6629,7 @@ version = "0.22.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "41fe8c660ae4257887cf66394862d21dbca4a6ddd26f04a3560410406a2f819a" dependencies = [ - "indexmap 2.13.0", + "indexmap 2.13.1", "serde", "serde_spanned", "toml_datetime 0.6.11", @@ -6335,23 +6639,23 @@ dependencies = [ [[package]] name = "toml_edit" -version = "0.25.5+spec-1.1.0" +version = "0.25.10+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8ca1a40644a28bce036923f6a431df0b34236949d111cc07cb6dca830c9ef2e1" +checksum = "a82418ca169e235e6c399a84e395ab6debeb3bc90edc959bf0f48647c6a32d1b" dependencies = [ - "indexmap 2.13.0", - "toml_datetime 1.0.1+spec-1.1.0", + "indexmap 2.13.1", + "toml_datetime 1.1.1+spec-1.1.0", "toml_parser", - "winnow 1.0.0", + "winnow 1.0.1", ] [[package]] name = "toml_parser" -version = "1.0.10+spec-1.1.0" +version = "1.1.2+spec-1.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7df25b4befd31c4816df190124375d5a20c6b6921e2cad937316de3fccd63420" +checksum = "a2abe9b86193656635d2411dc43050282ca48aa31c2451210f4202550afb7526" dependencies = [ - "winnow 1.0.0", + "winnow 1.0.1", ] [[package]] @@ -6570,15 +6874,15 @@ checksum = "9ea3136b675547379c4bd395ca6b938e5ad3c3d20fad76e7fe85f9e0d011419c" [[package]] name = "typenum" -version = "1.19.0" +version = "1.20.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "562d481066bde0658276a35467c4af00bdc6ee726305698a55b86e61d7ad82bb" +checksum = "40ce102ab67701b8526c123c1bab5cbe42d7040ccfd0f64af1a385808d2f43de" [[package]] name = "typewit" -version = "1.14.2" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f8c1ae7cc0fdb8b842d65d127cb981574b0d2b249b74d1c7a2986863dc134f71" +checksum = "06fee3a8df48c50c55ad646a4e03b00a370da6fe1850ebf467a8d0165dfcafae" dependencies = [ "typewit_proc_macros", ] @@ -6589,6 +6893,24 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" +[[package]] +name = "ucd-trie" +version = "0.1.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" + +[[package]] +name = "uint" +version = "0.9.5" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" +dependencies = [ + "byteorder", + "crunchy", + "hex", + "static_assertions", +] + [[package]] name = "uint" version = "0.10.0" @@ -6627,9 +6949,9 @@ checksum = "3b09c83c3c29d37506a3e260c08c03743a6bb66a9cd432c6934ab501a190571f" [[package]] name = "unicode-segmentation" -version = "1.12.0" +version = "1.13.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f6ccf251212114b54433ec949fd6a7841275f9ada20dddd2f29e9ceea4501493" +checksum = "9629274872b2bfaf8d66f5f15725007f635594914870f65218920345aa11aa8c" [[package]] name = "unicode-width" @@ -6676,9 +6998,9 @@ checksum = "06abde3611657adf66d383f00b093d7faecc7fa57071cce2578660c9f1010821" [[package]] name = "uuid" -version = "1.22.0" +version = "1.23.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a68d3c8f01c0cfa54a75291d83601161799e4a89a39e0929f4b0354d88757a37" +checksum = "5ac8b6f42ead25368cf5b098aeb3dc8a1a2c05a3eee8a9a1a68c640edbfc79d9" dependencies = [ "getrandom 0.4.2", ] @@ -6712,7 +7034,7 @@ dependencies = [ [[package]] name = "verifier-server" -version = "1.0.0" +version = "0.1.0" dependencies = [ "anyhow", "axum", @@ -6901,7 +7223,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "bb0e353e6a2fbdc176932bbaab493762eb1255a7900fe0fea1a2f96c296cc909" dependencies = [ "anyhow", - "indexmap 2.13.0", + "indexmap 2.13.1", "wasm-encoder", "wasmparser", ] @@ -6925,8 +7247,8 @@ checksum = "47b807c72e1bac69382b3a6fb3dbe8ea4c0ed87ff5629b8685ae6b9a611028fe" dependencies = [ "bitflags 2.11.0", "hashbrown 0.15.5", - "indexmap 2.13.0", - "semver", + "indexmap 2.13.1", + "semver 1.0.27", ] [[package]] @@ -6962,9 +7284,9 @@ name = "whir" version = "0.1.0" source = "git+https://github.com/WizardOfMenlo/whir/?rev=0aeaa7f337c743d9ddfcb9d909628d6491e3355c#0aeaa7f337c743d9ddfcb9d909628d6491e3355c" dependencies = [ - "ark-ff", - "ark-serialize", - "ark-std", + "ark-ff 0.5.0", + "ark-serialize 0.5.0", + "ark-std 0.5.0", "arrayvec", "blake3", "ciborium", @@ -7404,9 +7726,9 @@ dependencies = [ [[package]] name = "winnow" -version = "1.0.0" +version = "1.0.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a90e88e4667264a994d34e6d1ab2d26d398dcdca8b7f52bec8668957517fc7d8" +checksum = "09dac053f1cd375980747450bfc7250c264eaae0583872e845c0c7cd578872b5" dependencies = [ "memchr", ] @@ -7439,7 +7761,7 @@ checksum = "b7c566e0f4b284dd6561c786d9cb0142da491f46a9fbed79ea69cdad5db17f21" dependencies = [ "anyhow", "heck 0.5.0", - "indexmap 2.13.0", + "indexmap 2.13.1", "prettyplease", "syn 2.0.117", "wasm-metadata", @@ -7470,7 +7792,7 @@ checksum = "9d66ea20e9553b30172b5e831994e35fbde2d165325bec84fc43dbf6f4eb9cb2" dependencies = [ "anyhow", "bitflags 2.11.0", - "indexmap 2.13.0", + "indexmap 2.13.1", "log", "serde", "serde_derive", @@ -7489,9 +7811,9 @@ checksum = "ecc8ac4bc1dc3381b7f59c34f00b67e18f910c2c0f50015669dde7def656a736" dependencies = [ "anyhow", "id-arena", - "indexmap 2.13.0", + "indexmap 2.13.1", "log", - "semver", + "semver 1.0.27", "serde", "serde_derive", "serde_json", @@ -7501,9 +7823,9 @@ dependencies = [ [[package]] name = "writeable" -version = "0.6.2" +version = "0.6.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9edde0db4769d2dc68579893f2306b26c6ecfbe0ef499b013d731b7b9247e0b9" +checksum = "1ffae5123b2d3fc086436f8834ae3ab053a283cfac8fe0a0b8eaae044768a4c4" [[package]] name = "wyz" @@ -7542,9 +7864,9 @@ dependencies = [ [[package]] name = "yoke" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72d6e5c6afb84d73944e5cedb052c4680d5657337201555f9f2a16b7406d4954" +checksum = "abe8c5fda708d9ca3df187cae8bfb9ceda00dd96231bed36e445a1a48e66f9ca" dependencies = [ "stable_deref_trait", "yoke-derive", @@ -7553,9 +7875,9 @@ dependencies = [ [[package]] name = "yoke-derive" -version = "0.8.1" +version = "0.8.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b659052874eb698efe5b9e8cf382204678a0086ebf46982b79d6ca3182927e5d" +checksum = "de844c262c8848816172cef550288e7dc6c7b7814b4ee56b3e1553f275f1858e" dependencies = [ "proc-macro2", "quote", @@ -7565,18 +7887,18 @@ dependencies = [ [[package]] name = "zerocopy" -version = "0.8.42" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f2578b716f8a7a858b7f02d5bd870c14bf4ddbbcf3a4c05414ba6503640505e3" +checksum = "eed437bf9d6692032087e337407a86f04cd8d6a16a37199ed57949d415bd68e9" dependencies = [ "zerocopy-derive", ] [[package]] name = "zerocopy-derive" -version = "0.8.42" +version = "0.8.48" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e6cc098ea4d3bd6246687de65af3f920c430e236bee1e3bf2e441463f08a02f" +checksum = "70e3cd084b1788766f53af483dd21f93881ff30d7320490ec3ef7526d203bad4" dependencies = [ "proc-macro2", "quote", @@ -7585,18 +7907,18 @@ dependencies = [ [[package]] name = "zerofrom" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "50cc42e0333e05660c3587f3bf9d0478688e15d870fab3346451ce7f8c9fbea5" +checksum = "69faa1f2a1ea75661980b013019ed6687ed0e83d069bc1114e2cc74c6c04c4df" dependencies = [ "zerofrom-derive", ] [[package]] name = "zerofrom-derive" -version = "0.1.6" +version = "0.1.7" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d71e5d6e06ab090c67b5e44993ec16b72dcbaabc526db883a360057678b48502" +checksum = "11532158c46691caf0f2593ea8358fed6bbf68a0315e80aae9bd41fbade684a1" dependencies = [ "proc-macro2", "quote", @@ -7626,9 +7948,9 @@ dependencies = [ [[package]] name = "zerotrie" -version = "0.2.3" +version = "0.2.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a59c17a5562d507e4b54960e8569ebee33bee890c70aa3fe7b97e85a9fd7851" +checksum = "0f9152d31db0792fa83f70fb2f83148effb5c1f5b8c7686c3459e361d9bc20bf" dependencies = [ "displaydoc", "yoke", @@ -7637,9 +7959,9 @@ dependencies = [ [[package]] name = "zerovec" -version = "0.11.5" +version = "0.11.6" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6c28719294829477f525be0186d13efa9a3c602f7ec202ca9e353d310fb9a002" +checksum = "90f911cbc359ab6af17377d242225f4d75119aec87ea711a880987b18cd7b239" dependencies = [ "yoke", "zerofrom", @@ -7648,9 +7970,9 @@ dependencies = [ [[package]] name = "zerovec-derive" -version = "0.11.2" +version = "0.11.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "eadce39539ca5cb3985590102671f2567e659fca9666581ad3411d59207951f3" +checksum = "625dc425cab0dca6dc3c3319506e6593dcb08a9f387ea3b284dbd52a92c40555" dependencies = [ "proc-macro2", "quote", diff --git a/provekit/common/src/whir_r1cs.rs b/provekit/common/src/whir_r1cs.rs index 6b4e96d0d..d2a07d602 100644 --- a/provekit/common/src/whir_r1cs.rs +++ b/provekit/common/src/whir_r1cs.rs @@ -256,10 +256,15 @@ impl WhirR1CSSchemeBuilder for WhirR1CSScheme { w1_size <= num_witnesses, "w1_size ({w1_size}) exceeds total witnesses ({num_witnesses})" ); - let m_raw = next_power_of_two(num_witnesses); + // Size the witness commitment domain off the largest single commitment + // (w1 or w2), not the total witness count — Mavros commits w1 and w2 + // separately, so the domain only needs to hold the larger of the two. + let w2_size = num_witnesses - w1_size; + let m1_raw = next_power_of_two(w1_size); + let m2_raw = next_power_of_two(w2_size); let m0_raw = next_power_of_two(num_constraints); - let mut m = m_raw.max(MIN_WHIR_NUM_VARIABLES); + let mut m = m1_raw.max(m2_raw).max(MIN_WHIR_NUM_VARIABLES); let m_0 = m0_raw.max(MIN_SUMCHECK_NUM_VARIABLES); // Ensure w1's zero-padding has room for the blinding polynomial coefficients. @@ -343,4 +348,73 @@ mod tests { MIN_WHIR_NUM_VARIABLES ); } + + fn r1cs_with_dimensions(num_witnesses: usize, num_constraints: usize) -> R1CS { + let mut r1cs = R1CS::new(); + r1cs.grow_matrices(num_constraints, num_witnesses); + r1cs + } + + fn assert_dimension_builders( + num_witnesses: usize, + num_constraints: usize, + w1_size: usize, + expected_m: usize, + expected_m_0: usize, + ) { + let from_dimensions = WhirR1CSScheme::new_from_dimensions( + num_witnesses, + num_constraints, + 0, + w1_size, + 0, + vec![], + false, + HashConfig::Sha256, + ) + .unwrap(); + assert_eq!(from_dimensions.m, expected_m); + assert_eq!(from_dimensions.m_0, expected_m_0); + assert_eq!(from_dimensions.w1_size, w1_size); + + let r1cs = r1cs_with_dimensions(num_witnesses, num_constraints); + let from_r1cs = + WhirR1CSScheme::new_for_r1cs(&r1cs, w1_size, 0, vec![], false, HashConfig::Sha256) + .unwrap(); + assert_eq!(from_r1cs.m, expected_m); + assert_eq!(from_r1cs.m_0, expected_m_0); + assert_eq!(from_r1cs.w1_size, w1_size); + } + + #[test] + fn mavros_dimensions_use_largest_commitment_not_total_witnesses() { + let scheme = WhirR1CSScheme::new_from_dimensions( + 600_000, + 8, + 8, + 300_000, + 2, + vec![0, 1], + false, + HashConfig::Sha256, + ) + .unwrap(); + + assert_eq!(scheme.m, 19); + } + + #[test] + fn dimension_builders_handle_empty_w2() { + assert_dimension_builders(64, 8, 64, MIN_WHIR_NUM_VARIABLES, 3); + } + + #[test] + fn dimension_builders_handle_empty_w1() { + assert_dimension_builders(64, 8, 0, MIN_WHIR_NUM_VARIABLES, 3); + } + + #[test] + fn dimension_builders_bump_exact_power_of_two_w1_for_blinding_room() { + assert_dimension_builders(12_288, 2_048, 8_192, 14, 11); + } } From d9cd553d1f8a17744c13776a2d0e3c673c852468 Mon Sep 17 00:00:00 2001 From: Yogesh Shahi Date: Mon, 15 Jun 2026 12:49:14 +0530 Subject: [PATCH 10/11] chore(deps): regenerate Cargo.lock after rebase onto v2 --- Cargo.lock | 424 ++++++++--------------------------------------------- 1 file changed, 59 insertions(+), 365 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index b1f19ea22..8872d7d14 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -29,8 +29,8 @@ version = "1.0.0-beta.19" source = "git+https://github.com/noir-lang/noir?rev=v1.0.0-beta.19#74d6be658e1ad252f87943292ba09bdd4da80bd4" dependencies = [ "ark-bn254", - "ark-ff 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-std", "cfg-if", "hex", "num-bigint", @@ -123,16 +123,6 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" -[[package]] -name = "alloy-rlp" -version = "0.3.15" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc90b1e703d3c03f4ff7f48e82dd0bc1c8211ab7d079cd836a06fcfeb06651cb" -dependencies = [ - "arrayvec", - "bytes", -] - [[package]] name = "android_system_properties" version = "0.1.5" @@ -242,8 +232,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d69eab57e8d2663efa5c63135b2af4f396d66424f88954c21104125ab6b3e6bc" dependencies = [ "ark-ec", - "ark-ff 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-std", ] [[package]] @@ -253,10 +243,10 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "43d68f2d516162846c1238e755a7c4d131b892b70cc70c471a8e3ca3ed818fce" dependencies = [ "ahash", - "ark-ff 0.5.0", + "ark-ff", "ark-poly", - "ark-serialize 0.5.0", - "ark-std 0.5.0", + "ark-serialize", + "ark-std", "educe", "fnv", "hashbrown 0.15.5", @@ -267,54 +257,16 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ark-ff" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6b3235cc41ee7a12aaaf2c575a2ad7b46713a8a50bda2fc3b003a04845c05dd6" -dependencies = [ - "ark-ff-asm 0.3.0", - "ark-ff-macros 0.3.0", - "ark-serialize 0.3.0", - "ark-std 0.3.0", - "derivative", - "num-bigint", - "num-traits", - "paste", - "rustc_version 0.3.3", - "zeroize", -] - -[[package]] -name = "ark-ff" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ec847af850f44ad29048935519032c33da8aa03340876d351dfab5660d2966ba" -dependencies = [ - "ark-ff-asm 0.4.2", - "ark-ff-macros 0.4.2", - "ark-serialize 0.4.2", - "ark-std 0.4.0", - "derivative", - "digest 0.10.7", - "itertools 0.10.5", - "num-bigint", - "num-traits", - "paste", - "rustc_version 0.4.1", - "zeroize", -] - [[package]] name = "ark-ff" version = "0.5.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "a177aba0ed1e0fbb62aa9f6d0502e9b46dad8c2eab04c14258a1212d2557ea70" dependencies = [ - "ark-ff-asm 0.5.0", - "ark-ff-macros 0.5.0", - "ark-serialize 0.5.0", - "ark-std 0.5.0", + "ark-ff-asm", + "ark-ff-macros", + "ark-serialize", + "ark-std", "arrayvec", "digest 0.10.7", "educe", @@ -325,26 +277,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ark-ff-asm" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db02d390bf6643fb404d3d22d31aee1c4bc4459600aef9113833d17e786c6e44" -dependencies = [ - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-ff-asm" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3ed4aa4fe255d0bc6d79373f7e31d2ea147bcf486cba1be5ba7ea85abdb92348" -dependencies = [ - "quote", - "syn 1.0.109", -] - [[package]] name = "ark-ff-asm" version = "0.5.0" @@ -355,31 +287,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "ark-ff-macros" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db2fd794a08ccb318058009eefdf15bcaaaaf6f8161eb3345f907222bac38b20" -dependencies = [ - "num-bigint", - "num-traits", - "quote", - "syn 1.0.109", -] - -[[package]] -name = "ark-ff-macros" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7abe79b0e4288889c4574159ab790824d0033b9fdcb2a112a3182fac2e514565" -dependencies = [ - "num-bigint", - "num-traits", - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "ark-ff-macros" version = "0.5.0" @@ -401,8 +308,8 @@ checksum = "ef677b59f5aff4123207c4dceb1c0ec8fdde2d4af7886f48be42ad864bfa0352" dependencies = [ "ark-bn254", "ark-ec", - "ark-ff 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-std", ] [[package]] @@ -412,35 +319,14 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "579305839da207f02b89cd1679e50e67b4331e2f9294a57693e5051b7703fe27" dependencies = [ "ahash", - "ark-ff 0.5.0", - "ark-serialize 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-serialize", + "ark-std", "educe", "fnv", "hashbrown 0.15.5", ] -[[package]] -name = "ark-serialize" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1d6c2b318ee6e10f8c2853e73a83adc0ccb88995aa978d8a3408d492ab2ee671" -dependencies = [ - "ark-std 0.3.0", - "digest 0.9.0", -] - -[[package]] -name = "ark-serialize" -version = "0.4.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "adb7b85a02b83d2f22f89bd5cac66c9c89474240cb6207cb1efc16d098e822a5" -dependencies = [ - "ark-std 0.4.0", - "digest 0.10.7", - "num-bigint", -] - [[package]] name = "ark-serialize" version = "0.5.0" @@ -448,7 +334,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3f4d068aaf107ebcd7dfb52bc748f8030e0fc930ac8e360146ca54c1203088f7" dependencies = [ "ark-serialize-derive", - "ark-std 0.5.0", + "ark-std", "arrayvec", "digest 0.10.7", "num-bigint", @@ -465,26 +351,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "ark-std" -version = "0.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1df2c09229cbc5a028b1d70e00fdb2acee28b1055dfb5ca73eea49c5a25c4e7c" -dependencies = [ - "num-traits", - "rand 0.8.5", -] - -[[package]] -name = "ark-std" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94893f1e0c6eeab764ade8dc4c0db24caf4fe7cbbaafc0eba0a9030f447b5185" -dependencies = [ - "num-traits", - "rand 0.8.5", -] - [[package]] name = "ark-std" version = "0.5.0" @@ -595,17 +461,6 @@ version = "1.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1505bd5d3d116872e7271a6d4e16d81d0c8570876c8de68093a09ac269d8aac0" -[[package]] -name = "auto_impl" -version = "1.3.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ffdcb70bdbc4d478427380519163274ac86e52916e10f0a8889adf0f96d3fee7" -dependencies = [ - "proc-macro2", - "quote", - "syn 2.0.117", -] - [[package]] name = "autocfg" version = "1.5.0" @@ -827,12 +682,12 @@ name = "bn254-multiplier" version = "0.1.0" dependencies = [ "ark-bn254", - "ark-ff 0.5.0", + "ark-ff", "bn254-multiplier-codegen", "divan", "fp-rounding", "hla", - "primitive-types 0.13.1", + "primitive-types", "proptest", "rand 0.9.2", "seq-macro", @@ -854,7 +709,7 @@ dependencies = [ "acvm_blackbox_solver", "ark-bn254", "ark-ec", - "ark-ff 0.5.0", + "ark-ff", "ark-grumpkin", "hex", ] @@ -1551,17 +1406,6 @@ dependencies = [ "serde_core", ] -[[package]] -name = "derivative" -version = "2.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fcc3dd5e9e9c0b295d6e1e4d811fb6f157d5ffd784b8d202fc62eac8035a770b" -dependencies = [ - "proc-macro2", - "quote", - "syn 1.0.109", -] - [[package]] name = "derive-where" version = "1.6.1" @@ -1573,15 +1417,6 @@ dependencies = [ "syn 2.0.117", ] -[[package]] -name = "digest" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d3dd60d1080a57a05ab032377049e0591415d2b31afd7028356dbf3cc6dcb066" -dependencies = [ - "generic-array", -] - [[package]] name = "digest" version = "0.10.7" @@ -1881,28 +1716,6 @@ version = "2.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "37909eebbb50d72f9059c3b6d82c0463f2ff062c9e95845c43a6c9c0355411be" -[[package]] -name = "fastrlp" -version = "0.3.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "139834ddba373bbdd213dffe02c8d110508dcf1726c2be27e8d1f7d7e1856418" -dependencies = [ - "arrayvec", - "auto_impl", - "bytes", -] - -[[package]] -name = "fastrlp" -version = "0.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ce8dba4714ef14b8274c371879b175aa55b16b30f269663f19d576f380018dc4" -dependencies = [ - "arrayvec", - "auto_impl", - "bytes", -] - [[package]] name = "fd-lock" version = "3.0.13" @@ -2284,7 +2097,7 @@ checksum = "cdc6457c0eb62c71aac4bc17216026d8410337c4126773b9c5daba343f17964f" dependencies = [ "atomic-polyfill", "hash32", - "rustc_version 0.4.1", + "rustc_version", "serde", "spin 0.9.8", "stable_deref_trait", @@ -2628,15 +2441,6 @@ dependencies = [ "version_check", ] -[[package]] -name = "impl-codec" -version = "0.6.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ba6a270039626615617f3f36d15fc827041df3b78c439da2cadfa47455a77f2f" -dependencies = [ - "parity-scale-codec", -] - [[package]] name = "impl-codec" version = "0.7.1" @@ -3211,7 +3015,7 @@ version = "0.1.0" source = "git+https://github.com/reilabs/mavros?rev=7550b42e03d35b44781ff37f15b50773eb2a6fa0#7550b42e03d35b44781ff37f15b50773eb2a6fa0" dependencies = [ "ark-bn254", - "ark-ff 0.5.0", + "ark-ff", "serde", "tracing", ] @@ -3232,7 +3036,7 @@ name = "mavros-vm" version = "0.1.0" source = "git+https://github.com/reilabs/mavros?rev=7550b42e03d35b44781ff37f15b50773eb2a6fa0#7550b42e03d35b44781ff37f15b50773eb2a6fa0" dependencies = [ - "ark-ff 0.5.0", + "ark-ff", "mavros-artifacts", "mavros-opcode-gen", "tracing", @@ -3425,7 +3229,7 @@ dependencies = [ "nargo", "noirc_driver", "noirc_frontend", - "semver 1.0.27", + "semver", "serde", "thiserror 1.0.69", "toml 0.7.8", @@ -3831,8 +3635,8 @@ name = "ntt" version = "0.1.0" dependencies = [ "ark-bn254", - "ark-ff 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-std", "bn254-multiplier", "divan", "proptest", @@ -4285,7 +4089,7 @@ dependencies = [ "anyhow", "argh", "ark-bn254", - "ark-ff 0.5.0", + "ark-ff", "base64", "chrono", "hex", @@ -4339,16 +4143,6 @@ version = "2.3.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "9b4f627cb1b25917193a259e49bdad08f671f8d9708acfd5fe0a8c1455d87220" -[[package]] -name = "pest" -version = "2.8.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0848c601009d37dfa3430c4666e147e49cdcf1b92ecd3e63657d8a5f19da662" -dependencies = [ - "memchr", - "ucd-trie", -] - [[package]] name = "petgraph" version = "0.8.3" @@ -4435,8 +4229,8 @@ name = "poseidon2" version = "0.1.0" dependencies = [ "ark-bn254", - "ark-ff 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-std", ] [[package]] @@ -4523,17 +4317,6 @@ dependencies = [ "elliptic-curve", ] -[[package]] -name = "primitive-types" -version = "0.12.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0b34d9fd68ae0b74a41b21c03c2f62847aa0ffea044eee893b4c140b37e244e2" -dependencies = [ - "fixed-hash", - "impl-codec 0.6.0", - "uint 0.9.5", -] - [[package]] name = "primitive-types" version = "0.13.1" @@ -4541,8 +4324,8 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d15600a7d856470b7d278b3fe0e311fe28c2526348549f8ef2ff7db3299c87f5" dependencies = [ "fixed-hash", - "impl-codec 0.7.1", - "uint 0.10.0", + "impl-codec", + "uint", ] [[package]] @@ -4584,11 +4367,11 @@ dependencies = [ [[package]] name = "provekit-bench" -version = "0.1.0" +version = "1.0.0" dependencies = [ "acir", "anyhow", - "ark-ff 0.5.0", + "ark-ff", "divan", "nargo", "nargo_cli", @@ -4606,12 +4389,12 @@ dependencies = [ [[package]] name = "provekit-cli" -version = "0.1.0" +version = "1.0.0" dependencies = [ "acir", "anyhow", "argh", - "ark-ff 0.5.0", + "ark-ff", "base64", "hex", "nargo", @@ -4635,14 +4418,14 @@ dependencies = [ [[package]] name = "provekit-common" -version = "0.1.0" +version = "1.0.0" dependencies = [ "acir", "anyhow", "ark-bn254", - "ark-ff 0.5.0", - "ark-serialize 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-serialize", + "ark-std", "base64", "blake3", "bytes", @@ -4658,7 +4441,6 @@ dependencies = [ "postcard", "proptest", "rayon", - "ruint", "serde", "serde_json", "sha2 0.10.9", @@ -4675,7 +4457,7 @@ dependencies = [ [[package]] name = "provekit-ffi" -version = "0.1.0" +version = "1.0.0" dependencies = [ "anyhow", "libc", @@ -4705,12 +4487,12 @@ dependencies = [ [[package]] name = "provekit-prover" -version = "0.1.0" +version = "1.0.0" dependencies = [ "acir", "anyhow", - "ark-ff 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-std", "bn254_blackbox_solver", "mavros-artifacts", "mavros-vm", @@ -4720,18 +4502,19 @@ dependencies = [ "num-bigint", "postcard", "provekit-common", + "provekit-verifier", "tracing", "whir", ] [[package]] name = "provekit-r1cs-compiler" -version = "0.1.0" +version = "1.0.0" dependencies = [ "acir", "anyhow", - "ark-ff 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-std", "bincode", "mavros-artifacts", "noirc_abi", @@ -4747,10 +4530,10 @@ dependencies = [ [[package]] name = "provekit-verifier" -version = "0.1.0" +version = "1.0.0" dependencies = [ "anyhow", - "ark-std 0.5.0", + "ark-std", "provekit-common", "rayon", "tracing", @@ -5201,16 +4984,6 @@ dependencies = [ "windows-sys 0.52.0", ] -[[package]] -name = "rlp" -version = "0.5.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bb919243f34364b6bd2fc10ef797edbfa75f33c252e7998527479c6d6b47e1ec" -dependencies = [ - "bytes", - "rustc-hex", -] - [[package]] name = "rmp" version = "0.8.15" @@ -5251,40 +5024,6 @@ dependencies = [ "zeroize", ] -[[package]] -name = "ruint" -version = "1.17.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c141e807189ad38a07276942c6623032d3753c8859c146104ac2e4d68865945a" -dependencies = [ - "alloy-rlp", - "ark-ff 0.3.0", - "ark-ff 0.4.2", - "ark-ff 0.5.0", - "bytes", - "fastrlp 0.3.1", - "fastrlp 0.4.0", - "num-bigint", - "num-integer", - "num-traits", - "parity-scale-codec", - "primitive-types 0.12.2", - "proptest", - "rand 0.8.5", - "rand 0.9.2", - "rlp", - "ruint-macro", - "serde_core", - "valuable", - "zeroize", -] - -[[package]] -name = "ruint-macro" -version = "1.2.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "48fd7bd8a6377e15ad9d42a8ec25371b94ddc67abe7c8b9127bec79bebaaae18" - [[package]] name = "rust-embed" version = "8.11.0" @@ -5343,22 +5082,13 @@ version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "781442f29170c5c93b7185ad559492601acdc71d5bb0706f5868094f45cfcd08" -[[package]] -name = "rustc_version" -version = "0.3.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f0dfe2087c51c460008730de8b57e6a320782fbfb312e1f4d520e6c6fae155ee" -dependencies = [ - "semver 0.11.0", -] - [[package]] name = "rustc_version" version = "0.4.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "cfcb3a22ef46e85b45de6ee7e79d063319ebb6594faafcf1c225ea92ab6e9b92" dependencies = [ - "semver 1.0.27", + "semver", ] [[package]] @@ -5696,30 +5426,12 @@ dependencies = [ "libc", ] -[[package]] -name = "semver" -version = "0.11.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f301af10236f6df4160f7c3f04eec6dbc70ace82d23326abad5edee88801c6b6" -dependencies = [ - "semver-parser", -] - [[package]] name = "semver" version = "1.0.27" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "d767eb0aabc880b29956c35734170f26ed551a859dbd361d140cdbeca61ab1e2" -[[package]] -name = "semver-parser" -version = "0.10.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9900206b54a3527fdc7b8a938bffd94a568bac4f4aa8113b209df75a09c0dec2" -dependencies = [ - "pest", -] - [[package]] name = "seq-macro" version = "0.3.6" @@ -6009,7 +5721,7 @@ name = "skyscraper" version = "0.1.0" dependencies = [ "ark-bn254", - "ark-ff 0.5.0", + "ark-ff", "bn254-multiplier", "divan", "fp-rounding", @@ -6142,8 +5854,8 @@ name = "spongefish" version = "1.0.0-rc1" source = "git+https://github.com/arkworks-rs/spongefish?rev=fcc277f8a857fdeeadd7cca92ab08de63b1ff1a1#fcc277f8a857fdeeadd7cca92ab08de63b1ff1a1" dependencies = [ - "ark-ff 0.5.0", - "ark-serialize 0.5.0", + "ark-ff", + "ark-serialize", "blake3", "digest 0.10.7", "keccak 0.1.6", @@ -6893,24 +6605,6 @@ version = "1.8.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e36a83ea2b3c704935a01b4642946aadd445cea40b10935e3f8bd8052b8193d6" -[[package]] -name = "ucd-trie" -version = "0.1.7" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2896d95c02a80c6d6a5d6e953d479f5ddf2dfdb6a244441010e373ac0fb88971" - -[[package]] -name = "uint" -version = "0.9.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "76f64bba2c53b04fcab63c01a7d7427eadc821e3bc48c34dc9ba29c501164b52" -dependencies = [ - "byteorder", - "crunchy", - "hex", - "static_assertions", -] - [[package]] name = "uint" version = "0.10.0" @@ -7034,7 +6728,7 @@ dependencies = [ [[package]] name = "verifier-server" -version = "0.1.0" +version = "1.0.0" dependencies = [ "anyhow", "axum", @@ -7248,7 +6942,7 @@ dependencies = [ "bitflags 2.11.0", "hashbrown 0.15.5", "indexmap 2.13.1", - "semver 1.0.27", + "semver", ] [[package]] @@ -7284,9 +6978,9 @@ name = "whir" version = "0.1.0" source = "git+https://github.com/WizardOfMenlo/whir/?rev=0aeaa7f337c743d9ddfcb9d909628d6491e3355c#0aeaa7f337c743d9ddfcb9d909628d6491e3355c" dependencies = [ - "ark-ff 0.5.0", - "ark-serialize 0.5.0", - "ark-std 0.5.0", + "ark-ff", + "ark-serialize", + "ark-std", "arrayvec", "blake3", "ciborium", @@ -7813,7 +7507,7 @@ dependencies = [ "id-arena", "indexmap 2.13.1", "log", - "semver 1.0.27", + "semver", "serde", "serde_derive", "serde_json", From ea5a4d58e034c6bc4ae1accc8870e5f299358513 Mon Sep 17 00:00:00 2001 From: Yogesh Shahi Date: Tue, 16 Jun 2026 13:08:46 +0530 Subject: [PATCH 11/11] test(prover): consolidate roundtrip tests into goldilocks_fixtures with Tier-0 cases --- provekit/prover/Cargo.toml | 2 +- provekit/prover/src/goldilocks_fixtures.rs | 476 +++++++++++++++++++++ provekit/prover/src/lib.rs | 4 +- provekit/prover/src/roundtrip_tests.rs | 135 ------ 4 files changed, 479 insertions(+), 138 deletions(-) create mode 100644 provekit/prover/src/goldilocks_fixtures.rs delete mode 100644 provekit/prover/src/roundtrip_tests.rs diff --git a/provekit/prover/Cargo.toml b/provekit/prover/Cargo.toml index 939050a71..5a94f11e9 100644 --- a/provekit/prover/Cargo.toml +++ b/provekit/prover/Cargo.toml @@ -13,7 +13,7 @@ default = ["witness-generation", "parallel", "bn254"] # At least one field feature must be enabled; `bn254` takes precedence when # both are on. Pair `goldilocks` with `--no-default-features`. # `provekit-verifier/` forwards the field selection to the dev-dep used -# by `roundtrip_tests`, so `cargo test -p provekit-prover` builds the verifier +# by `goldilocks_fixtures`, so `cargo test -p provekit-prover` builds the verifier # over the same field as common (it has no field feature of its own otherwise). bn254 = [ "provekit-common/bn254", diff --git a/provekit/prover/src/goldilocks_fixtures.rs b/provekit/prover/src/goldilocks_fixtures.rs new file mode 100644 index 000000000..8ad51ef88 --- /dev/null +++ b/provekit/prover/src/goldilocks_fixtures.rs @@ -0,0 +1,476 @@ +//! Hand-built R1CS fixtures, runnable under `bn254` or `goldilocks`. +//! +//! Goldilocks gates out the compiler, so `R1CS::new` + `add_constraint` is the +//! only way to build one. Fixtures are plain-arithmetic (`num_challenges = 0`), +//! hash pinned to SHA-256 (no Skyscraper under goldilocks). Only +//! `goldilocks_field_size_is_192_bits` is field-gated. + +use { + crate::whir_r1cs::WhirR1CSProver, + ark_ff::{One, UniformRand}, + ark_std::rand::{rngs::StdRng, Rng, SeedableRng}, + provekit_common::{ + register_ntt, FieldElement, HashConfig, PublicInputs, TranscriptSponge, WhirR1CSProof, + WhirR1CSScheme, WhirR1CSSchemeBuilder, R1CS, + }, + provekit_verifier::whir_r1cs::WhirR1CSVerifier, + std::time::{Duration, Instant}, + whir::transcript::{ProverState, VerifierMessage}, +}; + +const HASH: HashConfig = HashConfig::Sha256; + +/// WHIR witness-domain floor (`MIN_WHIR_NUM_VARIABLES`): prover work is flat at +/// or below `2^13` on both axes. +const FOLD_FLOOR: usize = 8192; + +/// `(A·w) * (B·w) = C·w` for every row (the bn254-gated oracle is unavailable). +fn satisfies(r1cs: &R1CS, w: &[FieldElement]) -> bool { + (0..r1cs.num_constraints()).all(|row| { + let a: FieldElement = r1cs.a().iter_row(row).map(|(col, v)| v * w[col]).sum(); + let b: FieldElement = r1cs.b().iter_row(row).map(|(col, v)| v * w[col]).sum(); + let c: FieldElement = r1cs.c().iter_row(row).map(|(col, v)| v * w[col]).sum(); + a * b == c + }) +} + +/// `w[i]^2 = w[i+1]` chain: `depth` constraints, `depth + 2` witnesses, `x` +/// public. The size knob — `depth + 2 > 2^13` crosses the fold floor. +fn squaring_chain(x: u64, depth: usize) -> (R1CS, Vec) { + let mut r1cs = R1CS::new(); + r1cs.add_witnesses(depth + 2); + r1cs.num_public_inputs = 1; + let one = FieldElement::one(); + let mut w = vec![one, FieldElement::from(x)]; + for i in 1..=depth { + r1cs.add_constraint(&[(one, i)], &[(one, i)], &[(one, i + 1)]); + let sq = w[i] * w[i]; + w.push(sq); + } + (r1cs, w) +} + +/// `p0 * p1 = z` with two public inputs — exercises the binding loop at `N ≥ 2` +/// (PR #321 class), unreachable with one input. +fn two_public_inputs(p0: u64, p1: u64) -> (R1CS, Vec) { + let mut r1cs = R1CS::new(); + r1cs.add_witnesses(4); + r1cs.num_public_inputs = 2; + let one = FieldElement::one(); + r1cs.add_constraint(&[(one, 1)], &[(one, 2)], &[(one, 3)]); + let (a, b) = (FieldElement::from(p0), FieldElement::from(p1)); + let w = vec![one, a, b, a * b]; + (r1cs, w) +} + +/// `count` random `(coeff, col)` terms over `[0, cols)` (`count` may be 0). +fn random_terms(rng: &mut StdRng, cols: usize, count: usize) -> Vec<(FieldElement, usize)> { + (0..count) + .map(|_| { + let coeff = FieldElement::from(rng.gen_range(1u64..=7)); + let col = rng.gen_range(0..cols); + (coeff, col) + }) + .collect() +} + +/// A random 1–3 term linear combination. +fn random_lc(rng: &mut StdRng, cols: usize) -> Vec<(FieldElement, usize)> { + let count = rng.gen_range(1..=3usize.min(cols)); + random_terms(rng, cols, count) +} + +/// `Σ coeff·w[col]` (duplicate columns sum, matching `add_constraint`). +fn eval_lc(terms: &[(FieldElement, usize)], w: &[FieldElement]) -> FieldElement { + terms.iter().map(|&(coeff, col)| coeff * w[col]).sum() +} + +/// `num_gates` multiply gates over `num_inputs` random inputs, satisfiable by +/// construction; each gate's output holds `(A·w)·(B·w)`. First input is public. +fn random_satisfiable(seed: u64, num_inputs: usize, num_gates: usize) -> (R1CS, Vec) { + assert!( + num_inputs >= 1, + "need at least one input to expose as public" + ); + let mut rng = StdRng::seed_from_u64(seed); + let mut r1cs = R1CS::new(); + let total = 1 + num_inputs + num_gates; + r1cs.add_witnesses(total); + r1cs.num_public_inputs = 1; + let one = FieldElement::one(); + + let mut w = Vec::with_capacity(total); + w.push(one); + for _ in 0..num_inputs { + w.push(FieldElement::rand(&mut rng)); + } + for g in 0..num_gates { + let out = 1 + num_inputs + g; // == current w.len() + let a_row = random_lc(&mut rng, out); + let b_row = random_lc(&mut rng, out); + let product = eval_lc(&a_row, &w) * eval_lc(&b_row, &w); + w.push(product); + r1cs.add_constraint(&a_row, &b_row, &[(one, out)]); + } + (r1cs, w) +} + +/// Satisfiable synthetic R1CS of a target size + density, to proxy a real +/// circuit's (structural) prover cost. Density ≈ `complete_age_check`: +/// ~2.5/1/1.5 non-zeros per A/B/C row. `num_public_inputs = 0`. +fn sized_r1cs( + num_witnesses: usize, + num_constraints: usize, + seed: u64, +) -> (R1CS, Vec) { + assert!( + num_witnesses > num_constraints + 1, + "need room for input witnesses" + ); + let num_inputs = num_witnesses - num_constraints - 1; + let mut rng = StdRng::seed_from_u64(seed); + let mut r1cs = R1CS::new(); + r1cs.add_witnesses(num_witnesses); + r1cs.num_public_inputs = 0; + r1cs.reserve_constraints(num_constraints, num_constraints * 5); + let one = FieldElement::one(); + + let mut w = Vec::with_capacity(num_witnesses); + w.push(one); + for _ in 0..num_inputs { + // `from(u64)`, not `rand`: field-independent RNG → identical structure + // across fields. + w.push(FieldElement::from(rng.gen::())); + } + for g in 0..num_constraints { + let out = 1 + num_inputs + g; // == current w.len() + let na = rng.gen_range(1..=4usize); // A ~2.5/row + let a_row = random_terms(&mut rng, out, na); + let b_row = random_terms(&mut rng, out, 1); // B 1/row + let nc = rng.gen_range(0..=1usize); // C ~1.5/row + let extra = random_terms(&mut rng, out, nc); + // pick `out` so C·w = out + Σ(extra·w) == (A·w)·(B·w) + let out_val = eval_lc(&a_row, &w) * eval_lc(&b_row, &w) - eval_lc(&extra, &w); + w.push(out_val); + let mut c_row = vec![(one, out)]; + c_row.extend(extra); + r1cs.add_constraint(&a_row, &b_row, &c_row); + } + (r1cs, w) +} + +/// Single-commitment prove (no challenge phase). +fn prove( + r1cs: &R1CS, + full_witness: Vec, + public_inputs: &PublicInputs, +) -> anyhow::Result<(WhirR1CSScheme, WhirR1CSProof)> { + register_ntt(); + let scheme = WhirR1CSScheme::new_for_r1cs( + r1cs, + full_witness.len(), // w1_size: everything in w1, num_challenges = 0 + 0, + vec![], + true, + HASH, + )?; + + let instance = public_inputs.hash_bytes(HASH); + let ds = scheme.create_domain_separator().instance(&instance); + let mut merlin = ProverState::new(&ds, TranscriptSponge::from_config(HASH)); + + let commitment = scheme.commit( + &mut merlin, + r1cs.num_witnesses(), + r1cs.num_constraints(), + full_witness.clone(), + true, + )?; + let proof = scheme.prove_noir( + merlin, + r1cs.clone(), + vec![commitment], + full_witness, + public_inputs, + )?; + Ok((scheme, proof)) +} + +/// Prove then verify, asserting both succeed. +fn prove_and_verify(r1cs: &R1CS, witness: Vec, public_inputs: &PublicInputs) { + let (scheme, proof) = prove(r1cs, witness, public_inputs).expect("proving failed"); + scheme + .verify(&proof, public_inputs, r1cs) + .expect("verification failed"); +} + +#[test] +fn oracle_accepts_satisfying_and_rejects_broken() { + let (r1cs, w) = squaring_chain(3, 6); + assert!(satisfies(&r1cs, &w)); + + let mut broken = w.clone(); + let last = broken.len() - 1; + broken[last] += FieldElement::one(); + assert!(!satisfies(&r1cs, &broken)); +} + +#[test] +fn squaring_chain_small_roundtrip() { + let (r1cs, w) = squaring_chain(3, 8); // depth 8: m = 13 floor + let public_inputs = PublicInputs::from_vec(vec![w[1]]); + assert!(satisfies(&r1cs, &w)); + prove_and_verify(&r1cs, w, &public_inputs); +} + +#[test] +fn two_public_inputs_roundtrip() { + let (r1cs, w) = two_public_inputs(6, 7); + let public_inputs = PublicInputs::from_vec(vec![w[1], w[2]]); + assert!(satisfies(&r1cs, &w)); + prove_and_verify(&r1cs, w, &public_inputs); +} + +/// Blinding-room bump: 8192 = `2^13` witnesses bump `m: 13 -> 14` via the +/// `(2^m - w1_size) < 4·m_0` padding check, not floor-crossing. +#[test] +fn blinding_bump_roundtrip() { + let depth = FOLD_FLOOR - 2; + let (r1cs, w) = squaring_chain(2, depth); + assert_eq!(r1cs.num_witnesses(), FOLD_FLOOR); + + let scheme = WhirR1CSScheme::new_for_r1cs(&r1cs, w.len(), 0, vec![], true, HASH) + .expect("scheme construction"); + assert_eq!(scheme.m, 14); + + let public_inputs = PublicInputs::from_vec(vec![w[1]]); + assert!(satisfies(&r1cs, &w)); + prove_and_verify(&r1cs, w, &public_inputs); +} + +/// `≥ 2^14` scale check (m = 15, m_0 = 14): past the fold floor. ~0.13s +/// release, runs in CI. +#[test] +fn milestone_2pow14_roundtrip() { + let depth = 16_384; + let (r1cs, w) = squaring_chain(2, depth); + assert!(r1cs.num_witnesses() >= 16_384 && r1cs.num_constraints() >= 16_384); + let public_inputs = PublicInputs::from_vec(vec![w[1]]); + assert!(satisfies(&r1cs, &w)); + prove_and_verify(&r1cs, w, &public_inputs); +} + +// Three distinct rejection paths. `prove` never checks satisfaction (always +// returns a proof), so `.expect()` keeps the verify-rejection assert live. + +/// Path 1 — R1CS satisfaction: a broken witness must not verify. +#[test] +fn corrupted_witness_is_rejected() { + let (r1cs, mut w) = squaring_chain(3, 8); + let last = w.len() - 1; + w[last] += FieldElement::one(); + let public_inputs = PublicInputs::from_vec(vec![w[1]]); + assert!(!satisfies(&r1cs, &w)); + + let (scheme, proof) = prove(&r1cs, w, &public_inputs) + .expect("prover produces a proof even for a non-satisfying witness"); + assert!(scheme.verify(&proof, &public_inputs, &r1cs).is_err()); +} + +/// Path 2 — instance binding: a proof must not verify against public inputs +/// substituted after proving. +#[test] +fn tampered_public_input_is_rejected() { + let (r1cs, w) = squaring_chain(3, 8); + let public_inputs = PublicInputs::from_vec(vec![w[1]]); + assert!(satisfies(&r1cs, &w)); + let (scheme, proof) = prove(&r1cs, w, &public_inputs).expect("proving failed"); + + let tampered = PublicInputs::from_vec(vec![FieldElement::from(999u64)]); + assert!(scheme.verify(&proof, &tampered, &r1cs).is_err()); +} + +/// Path 3 — public-input binding (PR #321): `witness[1] != public[0]` must not +/// verify though the R1CS is satisfied. Unlike path 2, prove and verify agree +/// on the wrong input, so the binding is what rejects. +#[test] +fn mismatched_public_input_binding_is_rejected() { + let (r1cs, w) = squaring_chain(3, 8); + assert!(satisfies(&r1cs, &w)); + + let wrong = PublicInputs::from_vec(vec![w[1] + FieldElement::one()]); + let (scheme, proof) = + prove(&r1cs, w, &wrong).expect("proving succeeds; the binding is checked at verify time"); + assert!(scheme.verify(&proof, &wrong, &r1cs).is_err()); +} + +/// PR #321 at `N = 2`: corrupting only the second public input must still +/// reject (the binding loop is non-trivial here, unlike `N = 1`). +#[test] +fn two_public_inputs_binding_mismatch_is_rejected() { + let (r1cs, w) = two_public_inputs(6, 7); + assert!(satisfies(&r1cs, &w)); + + let wrong = PublicInputs::from_vec(vec![w[1], w[2] + FieldElement::one()]); + let (scheme, proof) = + prove(&r1cs, w, &wrong).expect("proving succeeds; the binding is checked at verify time"); + assert!(scheme.verify(&proof, &wrong, &r1cs).is_err()); +} + +/// Per seed: the instance proves+verifies, and a perturbed output breaks +/// satisfaction. +#[test] +fn random_satisfiable_proves_and_perturbation_rejects() { + for seed in 0..8u64 { + let (r1cs, w) = random_satisfiable(seed, 4, 8); + assert!(satisfies(&r1cs, &w), "seed {seed}: must satisfy its R1CS"); + + let mut broken = w.clone(); + *broken.last_mut().unwrap() += FieldElement::one(); + assert!( + !satisfies(&r1cs, &broken), + "seed {seed}: perturbation must break a constraint" + ); + + let public_inputs = PublicInputs::from_vec(vec![w[1]]); + let (scheme, proof) = prove(&r1cs, w, &public_inputs).expect("proving failed"); + assert!( + scheme.verify(&proof, &public_inputs, &r1cs).is_ok(), + "seed {seed}: honest proof must verify" + ); + } +} + +/// Goldilocks must be the ~192-bit cubic extension (clears the 128-bit floor). +#[cfg(all(feature = "goldilocks", not(feature = "bn254")))] +#[test] +fn goldilocks_field_size_is_192_bits() { + use whir::algebra::fields::FieldWithSize; + let bits = ::field_size_bits(); + assert!( + (190.0..=194.0).contains(&bits), + "expected ~192-bit field, got {bits}" + ); + assert!(bits >= 128.0, "below the 128-bit security floor"); +} + +// Proving-time benchmark: a synthetic R1CS sized to `complete_age_check`. Cost +// is structural, so same-size proxies real proving time. `#[ignore]`d; run +// under each field and compare the printed durations. + +/// `complete_age_check`: 711,664 constraints · 1,247,227 witnesses · w1 ≈ 50% +/// (m = 20) · 118 challenges · ~3.55M non-zeros · 0 public inputs. +const AGE_CHECK_WITNESSES: usize = 1_247_227; +const AGE_CHECK_CONSTRAINTS: usize = 711_664; +const AGE_CHECK_W1: usize = 620_627; +const AGE_CHECK_CHALLENGES: usize = 118; + +/// Same shape at m ≈ 16 — fast smoke for the dual-commit path. +const SCALED_WITNESSES: usize = 90_000; +const SCALED_CONSTRAINTS: usize = 51_000; +const SCALED_W1: usize = 45_000; + +/// Time a dual-commit (`num_challenges > 0`) prove from a precomputed witness. +/// We draw the challenges directly (the real flow does it inside the gated +/// solver) so the path is field-agnostic. Timing-only: w2 is the witness tail, +/// not challenge-derived, so it won't verify; it also omits the subdominant w2 +/// solve (LogUp inversion), so absolutes slightly under-count (ratio +/// unaffected). +fn time_dual_commit_prove( + r1cs: &R1CS, + full_witness: Vec, + w1_size: usize, + num_challenges: usize, +) -> Duration { + register_ntt(); + let challenge_offsets: Vec = (w1_size..w1_size + num_challenges).collect(); + let scheme = WhirR1CSScheme::new_for_r1cs( + r1cs, + w1_size, + num_challenges, + challenge_offsets, + false, + HASH, + ) + .expect("scheme construction"); + + let num_witnesses = r1cs.num_witnesses(); + let num_constraints = r1cs.num_constraints(); + let w1 = full_witness[..w1_size].to_vec(); + let w2 = full_witness[w1_size..num_witnesses].to_vec(); + let public = PublicInputs::from_vec(vec![]); + let instance = public.hash_bytes(HASH); + let ds = scheme.create_domain_separator().instance(&instance); + + // Clone outside the timer — `prove_noir` consumes it, but the copy isn't + // proving work. + let r1cs_owned = r1cs.clone(); + + let start = Instant::now(); + let mut merlin = ProverState::new(&ds, TranscriptSponge::from_config(HASH)); + let c1 = scheme + .commit(&mut merlin, num_witnesses, num_constraints, w1, true) + .expect("commit w1"); + // Challenge draws (the real flow does these in `solve_witness_vec`). + let _challenges: Vec = merlin.verifier_message_vec(num_challenges); + let c2 = scheme + .commit(&mut merlin, num_witnesses, num_constraints, w2, false) + .expect("commit w2"); + scheme + .prove_noir(merlin, r1cs_owned, vec![c1, c2], full_witness, &public) + .expect("prove"); + start.elapsed() +} + +/// Build, validate, time, and print one sized bench. +fn run_sized_bench( + label: &str, + witnesses: usize, + constraints: usize, + w1: usize, + challenges: usize, +) { + let field = if cfg!(feature = "bn254") { + "bn254" + } else { + "goldilocks" + }; + let (r1cs, w) = sized_r1cs(witnesses, constraints, 0x0a6e_c4ec); + // Validate the generator (cheap, outside the timer). + assert!( + satisfies(&r1cs, &w), + "[{label}] generated R1CS must be satisfiable" + ); + let nnz = r1cs.a().iter().count() + r1cs.b().iter().count() + r1cs.c().iter().count(); + let dur = time_dual_commit_prove(&r1cs, w, w1, challenges); + println!( + "[{label}] field={field} witnesses={} constraints={} w1={w1} challenges={challenges} \ + nnz={nnz} prove={dur:?}", + r1cs.num_witnesses(), + r1cs.num_constraints(), + ); +} + +#[test] +#[ignore = "scaled (m~16) smoke for the dual-commit benchmark path; run with --nocapture"] +fn bench_age_check_sized_scaled() { + run_sized_bench( + "scaled", + SCALED_WITNESSES, + SCALED_CONSTRAINTS, + SCALED_W1, + AGE_CHECK_CHALLENGES, + ); +} + +#[test] +#[ignore = "full complete_age_check-sized proving-time benchmark; run --release --nocapture"] +fn bench_age_check_sized_full() { + run_sized_bench( + "age-check", + AGE_CHECK_WITNESSES, + AGE_CHECK_CONSTRAINTS, + AGE_CHECK_W1, + AGE_CHECK_CHALLENGES, + ); +} diff --git a/provekit/prover/src/lib.rs b/provekit/prover/src/lib.rs index 983838390..bf1f457b3 100644 --- a/provekit/prover/src/lib.rs +++ b/provekit/prover/src/lib.rs @@ -31,14 +31,14 @@ use { pub(crate) mod bigint_mod; #[cfg(feature = "bn254")] pub(crate) mod ec_arith; +#[cfg(test)] +mod goldilocks_fixtures; #[cfg(all(feature = "bn254", not(target_arch = "wasm32")))] pub mod input_utils; #[cfg(feature = "bn254")] mod logging; #[cfg(feature = "bn254")] pub(crate) mod r1cs; -#[cfg(test)] -mod roundtrip_tests; // Private under bn254 (the `Prove` trait is the public entry point); public // under goldilocks, where `WhirR1CSProver` is the only proving API for // hand-built R1CS instances. diff --git a/provekit/prover/src/roundtrip_tests.rs b/provekit/prover/src/roundtrip_tests.rs deleted file mode 100644 index cf07ba20e..000000000 --- a/provekit/prover/src/roundtrip_tests.rs +++ /dev/null @@ -1,135 +0,0 @@ -//! End-to-end toy-circuit roundtrip tests, runnable under either field -//! feature (`bn254` or `goldilocks`). -//! -//! The circuit is a single constraint `x * y = z` with `z` public. The -//! witness layout is load-bearing: `witness[0]` is the constant `1`, -//! public inputs occupy `1..=num_public_inputs`, so the full witness is -//! `[1, z, x, y]`. The hash configuration is pinned to SHA-256 because the -//! BN254 default (Skyscraper) does not exist in goldilocks builds. - -use { - crate::whir_r1cs::WhirR1CSProver, - ark_ff::One, - provekit_common::{ - register_ntt, FieldElement, HashConfig, PublicInputs, TranscriptSponge, WhirR1CSProof, - WhirR1CSScheme, WhirR1CSSchemeBuilder, R1CS, - }, - provekit_verifier::whir_r1cs::WhirR1CSVerifier, - whir::transcript::ProverState, -}; - -const HASH: HashConfig = HashConfig::Sha256; - -/// Build the toy R1CS for `x * y = z` over witness layout `[1, z, x, y]`. -fn toy_r1cs() -> R1CS { - let mut r1cs = R1CS::new(); - r1cs.add_witnesses(4); - r1cs.num_public_inputs = 1; - let one = FieldElement::one(); - // A·w = x (index 2), B·w = y (index 3), C·w = z (index 1) - r1cs.add_constraint(&[(one, 2)], &[(one, 3)], &[(one, 1)]); - r1cs -} - -/// Full witness `[1, z, x, y]` for given x, y (z computed). -fn toy_witness(x: u64, y: u64) -> Vec { - let xf = FieldElement::from(x); - let yf = FieldElement::from(y); - vec![FieldElement::one(), xf * yf, xf, yf] -} - -/// Prove the toy circuit with the given full witness and public inputs. -fn prove( - r1cs: &R1CS, - full_witness: Vec, - public_inputs: &PublicInputs, -) -> anyhow::Result<(WhirR1CSScheme, WhirR1CSProof)> { - register_ntt(); - let scheme = WhirR1CSScheme::new_for_r1cs( - r1cs, - full_witness.len(), // w1_size: everything in w1, no challenge phase - 0, - vec![], - true, - HASH, - )?; - - let instance = public_inputs.hash_bytes(HASH); - let ds = scheme.create_domain_separator().instance(&instance); - let mut merlin = ProverState::new(&ds, TranscriptSponge::from_config(HASH)); - - let commitment = scheme.commit( - &mut merlin, - r1cs.num_witnesses(), - r1cs.num_constraints(), - full_witness.clone(), - true, - )?; - let proof = scheme.prove_noir( - merlin, - r1cs.clone(), - vec![commitment], - full_witness, - public_inputs, - )?; - Ok((scheme, proof)) -} - -#[test] -fn toy_roundtrip_proves_and_verifies() { - let r1cs = toy_r1cs(); - let witness = toy_witness(3, 5); - let public_inputs = PublicInputs::from_vec(vec![witness[1]]); - - let (scheme, proof) = prove(&r1cs, witness, &public_inputs).expect("proving failed"); - scheme - .verify(&proof, &public_inputs, &r1cs) - .expect("verification failed"); -} - -#[test] -fn corrupted_witness_is_rejected() { - let r1cs = toy_r1cs(); - let mut witness = toy_witness(3, 5); - // Break the constraint: z stays 15 but y becomes 6. - witness[3] = FieldElement::from(6u64); - let public_inputs = PublicInputs::from_vec(vec![witness[1]]); - - // Proving may fail outright; if it mechanically succeeds, the proof - // must not verify. - if let Ok((scheme, proof)) = prove(&r1cs, witness, &public_inputs) { - assert!( - scheme.verify(&proof, &public_inputs, &r1cs).is_err(), - "proof over a non-satisfying witness must not verify" - ); - } -} - -#[test] -fn tampered_public_input_is_rejected() { - let r1cs = toy_r1cs(); - let witness = toy_witness(3, 5); - let public_inputs = PublicInputs::from_vec(vec![witness[1]]); - - let (scheme, proof) = prove(&r1cs, witness, &public_inputs).expect("proving failed"); - - let tampered = PublicInputs::from_vec(vec![FieldElement::from(16u64)]); - assert!( - scheme.verify(&proof, &tampered, &r1cs).is_err(), - "verification must fail when public inputs are tampered after proving" - ); -} - -/// The goldilocks field must be the ~192-bit cubic extension and clear the -/// 128-bit security floor the WHIR parameters assume. -#[cfg(all(feature = "goldilocks", not(feature = "bn254")))] -#[test] -fn goldilocks_field_size_is_192_bits() { - use whir::algebra::fields::FieldWithSize; - let bits = ::field_size_bits(); - assert!( - (190.0..=194.0).contains(&bits), - "expected ~192-bit field, got {bits}" - ); - assert!(bits >= 128.0, "below the 128-bit security floor"); -}