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
2 changes: 1 addition & 1 deletion crates/fs/src/definitions/algorithms.rs
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ pub trait FoldingSchemeProver<const M: usize, const N: usize>: FoldingSchemeDef
ws: &[impl Borrow<Self::IW>; N],
us: &[impl Borrow<Self::IU>; N],
rng: impl RngCore,
) -> Result<(Self::RW, Self::RU, Self::Proof<M, N>, Self::Challenge), Error>;
) -> Result<(Self::RW, Self::RU, Self::Proof<M, N>), Error>;
}

/// [`FoldingSchemeVerifier`] is the trait for folding scheme verifier.
Expand Down
2 changes: 1 addition & 1 deletion crates/fs/src/definitions/circuits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ pub trait FoldingSchemePartialVerifierGadget<const M: usize, const N: usize>:
Us: [&Self::RU; M],
us: [&Self::IU; N],
proof: &Self::Proof<M, N>,
) -> Result<(Self::RU, Self::Challenge), SynthesisError>;
) -> Result<Self::RU, SynthesisError>;
}

/// [`FoldingSchemeFullVerifierGadget`] is the full in-circuit verifier.
Expand Down
6 changes: 3 additions & 3 deletions crates/fs/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -94,8 +94,8 @@ mod tests {

let config = Arc::new(GriffinParams::new(16, 5, 9));

let mut transcript_p = GriffinSponge::new(&config);
let mut transcript_v = GriffinSponge::new(&config);
let mut transcript_p = GriffinSponge::new(config.clone());
let mut transcript_v = GriffinSponge::new(config);

for assignments in assignments_vec {
let mut ws = vec![];
Expand All @@ -113,7 +113,7 @@ mod tests {
let ws = ws.try_into().unwrap();
let us = us.try_into().unwrap();

let (WW, UU, pi, _) = FS::prove(pk, &mut transcript_p, &Ws, &Us, &ws, &us, &mut rng)?;
let (WW, UU, pi) = FS::prove(pk, &mut transcript_p, &Ws, &Us, &ws, &us, &mut rng)?;
FS::decide_running(&dk, &WW, &UU)?;
assert_eq!(FS::verify(vk, &mut transcript_v, &Us, &us, &pi)?, UU);

Expand Down
8 changes: 4 additions & 4 deletions crates/fs/src/nova/algorithms/prover.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@ impl<CM: GroupBasedCommitment, TF: SonobeField, const B: usize> FoldingSchemePro
ws: &[impl Borrow<Self::IW>; 1],
us: &[impl Borrow<Self::IU>; 1],
rng: impl RngCore,
) -> Result<(Self::RW, Self::RU, Self::Proof<1, 1>, Self::Challenge), Error> {
) -> Result<(Self::RW, Self::RU, Self::Proof<1, 1>), Error> {
let (W, U) = (Ws[0].borrow(), Us[0].borrow());
let (w, u) = (ws[0].borrow(), us[0].borrow());

Expand Down Expand Up @@ -94,7 +94,7 @@ impl<CM: GroupBasedCommitment, TF: SonobeField, const B: usize> FoldingSchemePro
.map(|(a, b)| rho * b + a)
.collect(),
};
Ok((WW, UU, cm_t, rho_bits.try_into().unwrap()))
Ok((WW, UU, cm_t))
}
}

Expand All @@ -110,7 +110,7 @@ impl<CM: GroupBasedCommitment, TF: SonobeField, const B: usize> FoldingSchemePro
_: &[impl Borrow<Self::IW>; 0],
_: &[impl Borrow<Self::IU>; 0],
rng: impl RngCore,
) -> Result<(Self::RW, Self::RU, Self::Proof<2, 0>, Self::Challenge), Error> {
) -> Result<(Self::RW, Self::RU, Self::Proof<2, 0>), Error> {
let (W1, U1) = (W1.borrow(), U1.borrow());
let (W2, U2) = (W2.borrow(), U2.borrow());

Expand Down Expand Up @@ -146,6 +146,6 @@ impl<CM: GroupBasedCommitment, TF: SonobeField, const B: usize> FoldingSchemePro
.map(|(a, b)| rho * b + a)
.collect(),
};
Ok((WW, UU, cm_t, rho_bits.try_into().unwrap()))
Ok((WW, UU, cm_t))
}
}
110 changes: 49 additions & 61 deletions crates/fs/src/nova/circuits/verifier.rs
Original file line number Diff line number Diff line change
Expand Up @@ -23,42 +23,33 @@ where
[U]: [&Self::RU; 1],
[u]: [&Self::IU; 1],
proof: &Self::Proof<1, 1>,
) -> Result<(Self::RU, Self::Challenge), SynthesisError> {
) -> Result<Self::RU, SynthesisError> {
let rho_bits = transcript.add(&U)?.add(&u)?.add(proof)?.challenge_bits(B)?;
let rho = CM::ScalarVar::from_bits_le(&rho_bits)?;

if U.x.len() != u.x.len() {
return Err(SynthesisError::Unsatisfiable);
}

Ok((
Self::RU {
u: (U.u.clone() + &rho)
.try_into()
.map_err(|_| SynthesisError::Unsatisfiable)?,
cm_e: CM::CommitmentVar::new_witness(
U.cm_e.cs().or(proof.cs()).or(rho.cs()),
|| {
Ok(U.cm_e.value().unwrap_or_default()
+ proof.value().unwrap_or_default() * rho.value().unwrap_or_default())
},
)?,
cm_w: CM::CommitmentVar::new_witness(
U.cm_w.cs().or(u.cm_w.cs()).or(rho.cs()),
|| {
Ok(U.cm_w.value().unwrap_or_default()
+ u.cm_w.value().unwrap_or_default() * rho.value().unwrap_or_default())
},
)?,
x: U.x
.iter()
.zip(&u.x)
.map(|(a, b)| (b.clone() * &rho + a).try_into())
.collect::<Result<_, _>>()
.map_err(|_| SynthesisError::Unsatisfiable)?,
},
rho_bits.try_into().unwrap(),
))
Ok(Self::RU {
u: (U.u.clone() + &rho)
.try_into()
.map_err(|_| SynthesisError::Unsatisfiable)?,
cm_e: CM::CommitmentVar::new_witness(U.cm_e.cs().or(proof.cs()).or(rho.cs()), || {
Ok(U.cm_e.value().unwrap_or_default()
+ proof.value().unwrap_or_default() * rho.value().unwrap_or_default())
})?,
cm_w: CM::CommitmentVar::new_witness(U.cm_w.cs().or(u.cm_w.cs()).or(rho.cs()), || {
Ok(U.cm_w.value().unwrap_or_default()
+ u.cm_w.value().unwrap_or_default() * rho.value().unwrap_or_default())
})?,
x: U.x
.iter()
.zip(&u.x)
.map(|(a, b)| (b.clone() * &rho + a).try_into())
.collect::<Result<_, _>>()
.map_err(|_| SynthesisError::Unsatisfiable)?,
})
}
}

Expand All @@ -73,45 +64,42 @@ where
[U1, U2]: [&Self::RU; 2],
_: [&Self::IU; 0],
proof: &Self::Proof<2, 0>,
) -> Result<(Self::RU, Self::Challenge), SynthesisError> {
) -> Result<Self::RU, SynthesisError> {
let rho_bits = transcript.add(&(U1, U2))?.add(proof)?.challenge_bits(B)?;
let rho = CM::ScalarVar::from_bits_le(&rho_bits)?;

if U1.x.len() != U2.x.len() {
return Err(SynthesisError::Unsatisfiable);
}

Ok((
Self::RU {
u: (U2.u.clone() * &rho + &U1.u)
.try_into()
.map_err(|_| SynthesisError::Unsatisfiable)?,
cm_e: CM::CommitmentVar::new_witness(
U1.cm_e.cs().or(U2.cm_e.cs()).or(proof.cs()).or(rho.cs()),
|| {
let rho = rho.value().unwrap_or_default();
Ok(U1.cm_e.value().unwrap_or_default()
+ proof.value().unwrap_or_default() * rho
+ U2.cm_e.value().unwrap_or_default() * rho * rho)
},
)?,
cm_w: CM::CommitmentVar::new_witness(
U1.cm_w.cs().or(U2.cm_w.cs()).or(rho.cs()),
|| {
Ok(U1.cm_w.value().unwrap_or_default()
+ U2.cm_w.value().unwrap_or_default() * rho.value().unwrap_or_default())
},
)?,
x: U1
.x
.iter()
.zip(&U2.x)
.map(|(a, b)| (b.clone() * &rho + a).try_into())
.collect::<Result<_, _>>()
.map_err(|_| SynthesisError::Unsatisfiable)?,
},
rho_bits.try_into().unwrap(),
))
Ok(Self::RU {
u: (U2.u.clone() * &rho + &U1.u)
.try_into()
.map_err(|_| SynthesisError::Unsatisfiable)?,
cm_e: CM::CommitmentVar::new_witness(
U1.cm_e.cs().or(U2.cm_e.cs()).or(proof.cs()).or(rho.cs()),
|| {
let rho = rho.value().unwrap_or_default();
Ok(U1.cm_e.value().unwrap_or_default()
+ proof.value().unwrap_or_default() * rho
+ U2.cm_e.value().unwrap_or_default() * rho * rho)
},
)?,
cm_w: CM::CommitmentVar::new_witness(
U1.cm_w.cs().or(U2.cm_w.cs()).or(rho.cs()),
|| {
Ok(U1.cm_w.value().unwrap_or_default()
+ U2.cm_w.value().unwrap_or_default() * rho.value().unwrap_or_default())
},
)?,
x: U1
.x
.iter()
.zip(&U2.x)
.map(|(a, b)| (b.clone() * &rho + a).try_into())
.collect::<Result<_, _>>()
.map_err(|_| SynthesisError::Unsatisfiable)?,
})
}
}

Expand Down
30 changes: 18 additions & 12 deletions crates/ivc/src/compilers/cyclefold/adapters/nova.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,11 @@ use sonobe_primitives::{
},
circuits::WitnessToPublic,
commitments::GroupBasedCommitment,
traits::{CF2, SonobeCurve},
traits::{CF1, CF2, SonobeCurve},
transcripts::{
Transcript, TranscriptGadget,
replay::{ReplayTranscript, ReplayTranscriptVar},
},
};

use crate::compilers::cyclefold::{
Expand Down Expand Up @@ -68,15 +72,16 @@ impl<CM: GroupBasedCommitment, const CHALLENGE_BITS: usize> FoldingSchemeCycleFo
[U]: &[impl Borrow<Self::RU>; 1],
[u]: &[impl Borrow<Self::IU>; 1],
proof: &Self::Proof<1, 1>,
rho: Self::Challenge,
mut transcript: ReplayTranscript<CF1<CM::Commitment>>,
) -> Vec<Self::CFCircuit> {
let rho = transcript.challenge_bits(CHALLENGE_BITS);
vec![
NovaCycleFoldCircuit {
r: rho.into(),
r: rho.clone(),
points: vec![U.borrow().cm_e, *proof],
},
NovaCycleFoldCircuit {
r: rho.into(),
r: rho,
points: vec![U.borrow().cm_w, u.borrow().cm_w],
},
]
Expand All @@ -88,9 +93,9 @@ impl<CM: GroupBasedCommitment, const CHALLENGE_BITS: usize> FoldingSchemeCycleFo
[u]: [<Self::Gadget as FoldingSchemeDefGadget>::IU; 1],
UU: <Self::Gadget as FoldingSchemeDefGadget>::RU,
proof: <Self::Gadget as FoldingSchemeDefGadget>::Proof<1, 1>,
rho: <Self::Gadget as FoldingSchemeDefGadget>::Challenge,
mut transcript: ReplayTranscriptVar<CF1<CM::Commitment>>,
) -> Result<Vec<Vec<EmulatedFieldVar<CM::Scalar, CF2<CM::Commitment>>>>, SynthesisError> {
let mut rho = rho.to_vec();
let mut rho = transcript.challenge_bits(CHALLENGE_BITS)?;
rho.resize(
CF2::<CM::Commitment>::MODULUS_BIT_SIZE as usize,
Boolean::FALSE,
Expand Down Expand Up @@ -130,20 +135,21 @@ impl<CM: GroupBasedCommitment, const CHALLENGE_BITS: usize> FoldingSchemeCycleFo
[U1, U2]: &[impl Borrow<Self::RU>; 2],
_: &[impl Borrow<Self::IU>; 0],
proof: &Self::Proof<2, 0>,
rho_bits: Self::Challenge,
mut transcript: ReplayTranscript<CF1<CM::Commitment>>,
) -> Vec<Self::CFCircuit> {
let rho_bits = transcript.challenge_bits(CHALLENGE_BITS);
let rho = CM::Scalar::from_bits_le(&rho_bits);
vec![
NovaCycleFoldCircuit {
r: rho_bits.into(),
r: rho_bits.clone(),
points: vec![*proof, U2.borrow().cm_e],
},
NovaCycleFoldCircuit {
r: rho_bits.into(),
r: rho_bits.clone(),
points: vec![U1.borrow().cm_e, U2.borrow().cm_e * rho + proof],
},
NovaCycleFoldCircuit {
r: rho_bits.into(),
r: rho_bits,
points: vec![U1.borrow().cm_w, U2.borrow().cm_w],
},
]
Expand All @@ -155,9 +161,9 @@ impl<CM: GroupBasedCommitment, const CHALLENGE_BITS: usize> FoldingSchemeCycleFo
_: [<Self::Gadget as FoldingSchemeDefGadget>::IU; 0],
UU: <Self::Gadget as FoldingSchemeDefGadget>::RU,
proof: <Self::Gadget as FoldingSchemeDefGadget>::Proof<2, 0>,
rho_bits: <Self::Gadget as FoldingSchemeDefGadget>::Challenge,
mut transcript: ReplayTranscriptVar<CF1<CM::Commitment>>,
) -> Result<Vec<Vec<EmulatedFieldVar<CM::Scalar, CF2<CM::Commitment>>>>, SynthesisError> {
let mut rho_bits = rho_bits.to_vec();
let mut rho_bits = transcript.challenge_bits(CHALLENGE_BITS)?;
rho_bits.resize(
CF2::<CM::Commitment>::MODULUS_BIT_SIZE as usize,
Boolean::FALSE,
Expand Down
21 changes: 11 additions & 10 deletions crates/ivc/src/compilers/cyclefold/circuits.rs
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ use sonobe_primitives::{
circuits::{FCircuit, WitnessToPublic},
commitments::CommitmentDef,
traits::{Dummy, SonobeCurve},
transcripts::{Transcript, TranscriptGadget},
transcripts::{TranscriptGadget, recording::RecordingTranscriptVar},
};

use crate::compilers::cyclefold::FoldingSchemeCycleFoldExt;
Expand All @@ -31,7 +31,7 @@ pub struct AugmentedCircuit<
FS1: GroupBasedFoldingSchemePrimary<1, 1>,
FS2: GroupBasedFoldingSchemeSecondary<1, 1>,
FC: FCircuit,
T: Transcript<FC::Field>,
T: TranscriptGadget<FC::Field>,
> {
_fs: PhantomData<(FS1, FS2)>,
hash_config: &'a T::Config,
Expand All @@ -45,7 +45,7 @@ where
FS1: GroupBasedFoldingSchemePrimary<1, 1>,
FS2: GroupBasedFoldingSchemeSecondary<1, 1>,
FC: FCircuit,
T: Transcript<FC::Field>,
T: TranscriptGadget<FC::Field>,
{
/// [`AugmentedCircuit::new`] creates an instance of the augmented circuit
/// for the given step circuit.
Expand Down Expand Up @@ -84,7 +84,7 @@ where
>,
>,
FC: FCircuit<Field = <FS1::CM as CommitmentDef>::Scalar>,
T: Transcript<FC::Field>,
T: TranscriptGadget<FC::Field>,
{
/// [`AugmentedCircuit::compute_next_state`] invokes the step circuit on the
/// current state and external inputs to compute the next state and external
Expand All @@ -105,12 +105,13 @@ where
cf_us: Vec<FS2::IU>,
cf_proofs: Vec<FS2::Proof<1, 1>>,
) -> Result<(FC::State, FC::ExternalOutputs), SynthesisError> {
let hash = T::Gadget::new_with_pp_hash(
self.hash_config,
let hash = T::new_with_pp_hash(
self.hash_config.clone(),
&FpVar::new_witness(cs.clone(), || Ok(pp_hash))?,
)?;
let sponge = hash.separate_domain("sponge".as_ref())?;
let mut transcript = hash.separate_domain("transcript".as_ref())?;
let mut transcript =
RecordingTranscriptVar::new(hash.separate_domain("transcript".as_ref())?);

let i = FpVar::new_witness(cs.clone(), || Ok(FC::Field::from(i as u64)))?;
let ii = &i + FpVar::one();
Expand Down Expand Up @@ -152,7 +153,7 @@ where
// 1.c. Fold the primary running instance `U` and incoming instance `u`
// using the provided proof to obtain the next running instance
// `UU`.
let (UU, rho) = FS1::Gadget::verify_hinted(&(), &mut transcript, [&U], [&u], &proof)?;
let UU = FS1::Gadget::verify_hinted(&(), &mut transcript, [&U], [&u], &proof)?;
// 1.d. If this is the base case (`i = 0`), then we should instead use
// the dummy running instance as the next running instance.
let actual_UU = is_basecase.select(&U_dummy, &UU)?;
Expand All @@ -161,7 +162,7 @@ where
// 2.a. Derive the public inputs to the secondary (CycleFold)
// circuits in the `i`-th step, which are obtained by calling
// the implementation of `FoldingSchemeCycleFoldExt`.
let cf_u_xs = FS1::to_cyclefold_inputs([U], [u], UU, proof, rho)?;
let cf_u_xs = FS1::to_cyclefold_inputs([U], [u], UU, proof, transcript.clone().into())?;
if [cf_us.len(), cf_u_xs.len(), cf_proofs.len()] != [FS1::N_CYCLEFOLDS; 3] {
return Err(SynthesisError::Unsatisfiable);
}
Expand Down Expand Up @@ -224,7 +225,7 @@ where
>,
>,
FC: FCircuit<Field = <FS1::CM as CommitmentDef>::Scalar>,
T: Transcript<FC::Field>,
T: TranscriptGadget<FC::Field>,
{
fn generate_constraints(
self,
Expand Down
Loading
Loading