Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 9 additions & 9 deletions crates/spartan-prover/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -76,8 +76,8 @@ type ProverMerkleProver<F, ParallelMerkleHasher, ParallelMerkleCompress> =
/// providing the core proving logic independent of the specific IOP compilation strategy.
/// Most users should use [`Prover`] instead, which wraps this with a BaseFold compiler.
#[derive(Debug)]
pub struct IOPProver {
constraint_system: ConstraintSystemPadded,
pub struct IOPProver<F: Field> {
constraint_system: ConstraintSystemPadded<F>,
wiring_transpose: WiringTranspose,
}

Expand All @@ -92,7 +92,7 @@ where
ParallelMerkleHasher: ParallelDigest<Digest: Digest + BlockSizeUser + FixedOutputReset>,
ParallelMerkleCompress: ParallelPseudoCompression<Output<ParallelMerkleHasher::Digest>, 2>,
{
iop_prover: IOPProver,
iop_prover: IOPProver<P::Scalar>,
#[allow(clippy::type_complexity)]
basefold_compiler: BaseFoldZKProverCompiler<
P,
Expand All @@ -101,9 +101,9 @@ where
>,
}

impl IOPProver {
impl<F: Field> IOPProver<F> {
/// Constructs an IOP prover for a constraint system.
pub fn new(constraint_system: ConstraintSystemPadded) -> Self {
pub fn new(constraint_system: ConstraintSystemPadded<F>) -> Self {
let wiring_transpose = WiringTranspose::transpose(
constraint_system.size(),
constraint_system.mul_constraints(),
Expand All @@ -114,7 +114,7 @@ impl IOPProver {
}
}

pub fn constraint_system(&self) -> &ConstraintSystemPadded {
pub fn constraint_system(&self) -> &ConstraintSystemPadded<F> {
&self.constraint_system
}

Expand All @@ -129,7 +129,7 @@ impl IOPProver {
/// * `rng` - Random number generator for blinding
/// * `channel` - The IOP prover channel (public input must be observed on transcript before
/// creating the channel)
pub fn prove<F, P, Channel>(
pub fn prove<P, Channel>(
&self,
witness: &[F],
mut rng: impl CryptoRng,
Expand Down Expand Up @@ -265,7 +265,7 @@ where
}

/// Returns a reference to the IOP prover.
pub fn iop_prover(&self) -> &IOPProver {
pub fn iop_prover(&self) -> &IOPProver<P::Scalar> {
&self.iop_prover
}

Expand Down Expand Up @@ -305,7 +305,7 @@ where

// Create ZK channel (owns the RNG for mask generation) and delegate to IOP prover
let channel = self.basefold_compiler.create_channel(transcript, &mut rng);
self.iop_prover.prove::<F, P, _>(witness, rng, channel)
self.iop_prover.prove::<P, _>(witness, rng, channel)
}
}

Expand Down
73 changes: 38 additions & 35 deletions crates/spartan-prover/src/wrapper/zk_wrapped_prover_channel.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
//! [`ReplayChannel`]: binius_spartan_verifier::wrapper::ReplayChannel
//! [`finish`]: ZKWrappedProverChannel::finish

use binius_field::{BinaryField128bGhash as B128, PackedExtension, PackedField};
use binius_field::{BinaryField, PackedExtension, PackedField};
use binius_iop::{channel::OracleSpec, merkle_tree::MerkleTreeScheme};
use binius_iop_prover::{
basefold_zk_channel::{BaseFoldZKOracle, BaseFoldZKProverChannel},
Expand All @@ -39,26 +39,27 @@ use crate::IOPProver;
/// witness, and generate the outer proof.
pub struct ZKWrappedProverChannel<'a, P, NTT, MTProver, Challenger_>
where
P: PackedField<Scalar = B128>,
NTT: AdditiveNTT<Field = B128> + Sync,
MTProver: MerkleTreeProver<B128>,
P: PackedField<Scalar: BinaryField>,
NTT: AdditiveNTT<Field = P::Scalar> + Sync,
MTProver: MerkleTreeProver<P::Scalar>,
Challenger_: Challenger,
{
inner_channel: BaseFoldZKProverChannel<'a, B128, P, NTT, MTProver, Challenger_>,
outer_prover: &'a IOPProver,
inner_verifier: &'a IOPVerifier,
outer_layout: &'a WitnessLayout<B128>,
interaction: Vec<B128>,
inner_channel: BaseFoldZKProverChannel<'a, P::Scalar, P, NTT, MTProver, Challenger_>,
outer_prover: &'a IOPProver<P::Scalar>,
inner_verifier: &'a IOPVerifier<P::Scalar>,
outer_layout: &'a WitnessLayout<P::Scalar>,
interaction: Vec<P::Scalar>,
n_outer_oracles: usize,
}

impl<'a, P, NTT, MTScheme, MTProver, Challenger_>
impl<'a, F, P, NTT, MTScheme, MTProver, Challenger_>
ZKWrappedProverChannel<'a, P, NTT, MTProver, Challenger_>
where
P: PackedField<Scalar = B128> + PackedExtension<B128>,
NTT: AdditiveNTT<Field = B128> + Sync,
MTScheme: MerkleTreeScheme<B128, Digest: SerializeBytes>,
MTProver: MerkleTreeProver<B128, Scheme = MTScheme>,
F: BinaryField,
P: PackedField<Scalar = F> + PackedExtension<F>,
NTT: AdditiveNTT<Field = F> + Sync,
MTScheme: MerkleTreeScheme<F, Digest: SerializeBytes>,
MTProver: MerkleTreeProver<F, Scheme = MTScheme>,
Challenger_: Challenger,
{
/// Creates a new ZK-wrapped prover channel.
Expand All @@ -71,10 +72,10 @@ where
/// * `inner_verifier` - The IOP verifier for the inner constraint system (used for replay)
/// * `outer_layout` - The witness layout for the outer constraint system
pub fn new(
inner_channel: BaseFoldZKProverChannel<'a, B128, P, NTT, MTProver, Challenger_>,
outer_prover: &'a IOPProver,
inner_verifier: &'a IOPVerifier,
outer_layout: &'a WitnessLayout<B128>,
inner_channel: BaseFoldZKProverChannel<'a, F, P, NTT, MTProver, Challenger_>,
outer_prover: &'a IOPProver<F>,
inner_verifier: &'a IOPVerifier<F>,
outer_layout: &'a WitnessLayout<F>,
) -> Self {
let outer_oracle_specs =
IOPVerifier::new(outer_prover.constraint_system().clone()).oracle_specs();
Expand Down Expand Up @@ -122,7 +123,7 @@ where
// Extract inner public values from the initial events.
let inner_cs = inner_verifier.constraint_system();
let inner_public_size = 1 << inner_cs.log_public();
let public: Vec<B128> = interaction[..inner_public_size].to_vec();
let public: Vec<F> = interaction[..inner_public_size].to_vec();

// Replay the inner verification through the outer witness generator.
// First observe the public input (mirrors the prover-side observe_many).
Expand All @@ -140,54 +141,56 @@ where
// Validate and generate the outer proof.
let outer_cs = outer_prover.constraint_system();
outer_cs.validate(&witness);
outer_prover.prove::<B128, P, _>(&witness, rng, inner_channel)?;
outer_prover.prove::<P, _>(&witness, rng, inner_channel)?;
Ok(())
}
}

impl<P, NTT, MTScheme, MTProver, Challenger_> IPProverChannel<B128>
impl<F, P, NTT, MTScheme, MTProver, Challenger_> IPProverChannel<F>
for &mut ZKWrappedProverChannel<'_, P, NTT, MTProver, Challenger_>
where
P: PackedField<Scalar = B128> + PackedExtension<B128>,
NTT: AdditiveNTT<Field = B128> + Sync,
MTScheme: MerkleTreeScheme<B128, Digest: SerializeBytes>,
MTProver: MerkleTreeProver<B128, Scheme = MTScheme>,
F: BinaryField,
P: PackedField<Scalar = F> + PackedExtension<F>,
NTT: AdditiveNTT<Field = F> + Sync,
MTScheme: MerkleTreeScheme<F, Digest: SerializeBytes>,
MTProver: MerkleTreeProver<F, Scheme = MTScheme>,
Challenger_: Challenger,
{
fn send_one(&mut self, elem: B128) {
fn send_one(&mut self, elem: F) {
self.inner_channel.send_one(elem);
self.interaction.push(elem);
}

fn send_many(&mut self, elems: &[B128]) {
fn send_many(&mut self, elems: &[F]) {
self.inner_channel.send_many(elems);
self.interaction.extend_from_slice(elems);
}

fn observe_one(&mut self, val: B128) {
fn observe_one(&mut self, val: F) {
self.inner_channel.observe_one(val);
self.interaction.push(val);
}

fn observe_many(&mut self, vals: &[B128]) {
fn observe_many(&mut self, vals: &[F]) {
self.inner_channel.observe_many(vals);
self.interaction.extend_from_slice(vals);
}

fn sample(&mut self) -> B128 {
fn sample(&mut self) -> F {
let val = self.inner_channel.sample();
self.interaction.push(val);
val
}
}

impl<P, NTT, MTScheme, MTProver, Challenger_> IOPProverChannel<P>
impl<F, P, NTT, MTScheme, MTProver, Challenger_> IOPProverChannel<P>
for &mut ZKWrappedProverChannel<'_, P, NTT, MTProver, Challenger_>
where
P: PackedField<Scalar = B128> + PackedExtension<B128>,
NTT: AdditiveNTT<Field = B128> + Sync,
MTScheme: MerkleTreeScheme<B128, Digest: SerializeBytes>,
MTProver: MerkleTreeProver<B128, Scheme = MTScheme>,
F: BinaryField,
P: PackedField<Scalar = F> + PackedExtension<F>,
NTT: AdditiveNTT<Field = F> + Sync,
MTScheme: MerkleTreeScheme<F, Digest: SerializeBytes>,
MTProver: MerkleTreeProver<F, Scheme = MTScheme>,
Challenger_: Challenger,
{
type Oracle = BaseFoldZKOracle;
Expand Down
2 changes: 1 addition & 1 deletion crates/spartan-prover/tests/wrapper_integration_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ fn test_zk_wrapped_prove_verify() {

// Run the inner proof through the wrapped channel.
inner_iop_prover
.prove::<B128, OptimalPackedB128, _>(&inner_witness, &mut rng, &mut wrapped_prover_channel)
.prove::<OptimalPackedB128, _>(&inner_witness, &mut rng, &mut wrapped_prover_channel)
.expect("inner prove failed");

// Finish runs the outer proof.
Expand Down
8 changes: 4 additions & 4 deletions crates/spartan-verifier/src/constraint_system.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2025 Irreducible Inc.
// Copyright 2026 The Binius Developers

use binius_field::{BinaryField128bGhash as B128, Field};
use binius_field::Field;
pub use binius_spartan_frontend::constraint_system::BlindingInfo;
use binius_spartan_frontend::constraint_system::{
ConstraintSystem, MulConstraint, Operand, WitnessIndex,
Expand All @@ -15,7 +15,7 @@ use binius_verifier::protocols::mlecheck::mask_buffer_dimensions;
/// number of constraints to a power of two (required by the prover's multilinear extension
/// protocol).
#[derive(Debug, Clone)]
pub struct ConstraintSystemPadded<F: Field = B128> {
pub struct ConstraintSystemPadded<F: Field> {
inner: ConstraintSystem<F>,
log_size: u32,
blinding_info: BlindingInfo,
Expand Down Expand Up @@ -131,15 +131,15 @@ impl<F: Field> ConstraintSystemPadded<F> {
self.mask_dims
}

pub fn validate(&self, witness: &[B128]) {
pub fn validate(&self, witness: &[F]) {
assert_eq!(witness.len(), self.size());

let operand_val = |operand: &Operand<WitnessIndex>| {
operand
.wires()
.iter()
.map(|idx| witness[idx.0 as usize])
.sum::<B128>()
.sum::<F>()
};

for MulConstraint { a, b, c } in &self.mul_constraints {
Expand Down
28 changes: 14 additions & 14 deletions crates/spartan-verifier/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ pub mod constraint_system;
pub mod wiring;
pub mod wrapper;

use binius_field::{BinaryField, BinaryField128bGhash as B128, field::FieldOps};
use binius_field::{BinaryField, Field, field::FieldOps};
use binius_iop::{
basefold_compiler::BaseFoldZKVerifierCompiler,
channel::{IOPVerifierChannel, OracleLinearRelation, OracleSpec},
Expand Down Expand Up @@ -76,8 +76,8 @@ pub struct MulcheckOutput<F> {
/// independent of the specific IOP compilation strategy. Most users should use [`Verifier`]
/// instead, which wraps this with a BaseFold compiler.
#[derive(Debug, Clone)]
pub struct IOPVerifier {
constraint_system: ConstraintSystemPadded,
pub struct IOPVerifier<F: Field> {
constraint_system: ConstraintSystemPadded<F>,
}

/// Struct for verifying instances of a particular constraint system.
Expand All @@ -91,19 +91,19 @@ where
MerkleHash: Digest + BlockSizeUser,
MerkleCompress: PseudoCompressionFunction<Output<MerkleHash>, 2>,
{
iop_verifier: IOPVerifier,
iop_verifier: IOPVerifier<F>,
/// BaseFold ZK compiler for creating verifier channels.
basefold_compiler:
BaseFoldZKVerifierCompiler<F, BinaryMerkleTreeScheme<F, MerkleHash, MerkleCompress>>,
}

impl IOPVerifier {
impl<F: Field> IOPVerifier<F> {
/// Constructs an IOP verifier for a constraint system.
pub fn new(constraint_system: ConstraintSystemPadded) -> Self {
pub fn new(constraint_system: ConstraintSystemPadded<F>) -> Self {
Self { constraint_system }
}

pub fn constraint_system(&self) -> &ConstraintSystemPadded {
pub fn constraint_system(&self) -> &ConstraintSystemPadded<F> {
&self.constraint_system
}

Expand Down Expand Up @@ -139,7 +139,7 @@ impl IOPVerifier {
/// # Returns
///
/// `Ok(())` if the proof is valid, `Err(_)` otherwise.
pub fn verify<F, Channel>(
pub fn verify<Channel>(
&self,
public: Vec<Channel::Elem>,
channel: &mut Channel,
Expand Down Expand Up @@ -228,7 +228,7 @@ where
///
/// See [`Verifier`] struct documentation for details.
pub fn setup(
constraint_system: ConstraintSystem<B128>,
constraint_system: ConstraintSystem<F>,
log_inv_rate: usize,
compression: MerkleCompress,
) -> Result<Self, Error> {
Expand Down Expand Up @@ -262,11 +262,11 @@ where
}

/// Returns a reference to the IOP verifier.
pub fn iop_verifier(&self) -> &IOPVerifier {
pub fn iop_verifier(&self) -> &IOPVerifier<F> {
&self.iop_verifier
}

pub fn constraint_system(&self) -> &ConstraintSystemPadded {
pub fn constraint_system(&self) -> &ConstraintSystemPadded<F> {
self.iop_verifier.constraint_system()
}

Expand Down Expand Up @@ -302,7 +302,7 @@ where
}

fn verify_mulcheck<F, C>(
cs: &ConstraintSystemPadded,
cs: &ConstraintSystemPadded<F>,
channel: &mut C,
) -> Result<MulcheckOutput<C::Elem>, Error>
where
Expand Down Expand Up @@ -339,8 +339,8 @@ where
}

/// Returns a closure that evaluates the mask transparent polynomial at a given point.
fn mask_transparent<'a, E: FieldOps + 'a>(
cs: &ConstraintSystemPadded,
fn mask_transparent<'a, F: Field, E: FieldOps + 'a>(
cs: &ConstraintSystemPadded<F>,
r_x: &[E],
) -> binius_iop::channel::TransparentEvalFn<'a, E> {
let (_m_n, m_d) = cs.mask_dims();
Expand Down
6 changes: 3 additions & 3 deletions crates/spartan-verifier/src/wiring.rs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ pub struct WiringClaim<F> {
/// Samples the batching challenges and computes the batched claim from the
/// evaluation claims and public input evaluation.
pub fn compute_claim<F, C>(
_constraint_system: &ConstraintSystemPadded,
_constraint_system: &ConstraintSystemPadded<F>,
_r_public: &[C::Elem],
eval_claims: &[C::Elem],
public_eval: C::Elem,
Expand Down Expand Up @@ -61,8 +61,8 @@ where
///
/// The returned closure computes the expected evaluation of the wiring MLE batched with the
/// public input equality check, given a challenge point from the BaseFold opening.
pub fn eval_transparent<'a, F: FieldOps + 'a>(
constraint_system: &ConstraintSystemPadded,
pub fn eval_transparent<'a, G: Field, F: FieldOps + 'a>(
constraint_system: &ConstraintSystemPadded<G>,
r_public: &[F],
r_x: &[F],
lambda: F,
Expand Down
Loading
Loading