Skip to content

Commit d2f4ed1

Browse files
authored
Allow the creation of custom Poseidon configs (#212)
* Poseidon custom config * Clarify the difference between poseidon configs on C1 and C2
1 parent 8912049 commit d2f4ed1

File tree

3 files changed

+54
-26
lines changed

3 files changed

+54
-26
lines changed

folding-schemes/src/folding/nova/decider.rs

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,7 +19,7 @@ use crate::folding::traits::{
1919
CommittedInstanceOps, Dummy, Inputize, InputizeNonNative, WitnessOps,
2020
};
2121
use crate::frontend::FCircuit;
22-
use crate::transcript::poseidon::poseidon_canonical_config;
22+
use crate::transcript::poseidon::poseidon_custom_config;
2323
use crate::{Curve, Error};
2424
use crate::{Decider as DeciderTrait, FoldingScheme};
2525

@@ -148,18 +148,32 @@ where
148148
>>::VerifierParam = vp.into();
149149
let pp_hash = nova_vp.pp_hash()?;
150150

151+
let poseidon_config1 = nova_vp.poseidon_config;
152+
// Create a poseidon config on `C2`'s scalar field for `circuit2`, with
153+
// the same parameters (`full_rounds` etc.) as `circuit1` to ensure the
154+
// security level is the same.
155+
// Note: `ark` and `mds` will be different because they depend on the
156+
// field, but they will not affect the security level.
157+
let poseidon_config2 = poseidon_custom_config(
158+
poseidon_config1.full_rounds,
159+
poseidon_config1.partial_rounds,
160+
poseidon_config1.alpha,
161+
poseidon_config1.rate,
162+
poseidon_config1.capacity,
163+
);
164+
151165
let circuit1 = DeciderCircuit1::<C1, C2>::dummy((
152166
nova_vp.r1cs,
153167
&nova_vp.cf_r1cs,
154-
nova_vp.poseidon_config,
168+
poseidon_config1,
155169
(),
156170
(),
157171
state_len,
158172
2, // Nova's running CommittedInstance contains 2 commitments
159173
));
160174
let circuit2 = DeciderCircuit2::<C2>::dummy((
161175
nova_vp.cf_r1cs,
162-
poseidon_canonical_config::<C2::ScalarField>(),
176+
poseidon_config2,
163177
2, // Nova's running CommittedInstance contains 2 commitments
164178
));
165179

folding-schemes/src/folding/nova/decider_circuits.rs

Lines changed: 14 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,16 +12,16 @@ use super::{
1212
nifs::{nova::NIFS, NIFSTrait},
1313
CommittedInstance, Nova, Witness,
1414
};
15+
use crate::commitment::CommitmentScheme;
1516
use crate::folding::{circuits::CF1, traits::WitnessOps};
16-
use crate::frontend::FCircuit;
1717
use crate::{
1818
arith::r1cs::{circuits::R1CSMatricesVar, R1CS},
1919
folding::circuits::decider::{
2020
off_chain::{GenericOffchainDeciderCircuit1, GenericOffchainDeciderCircuit2},
2121
EvalGadget, KZGChallengesGadget,
2222
},
2323
};
24-
use crate::{commitment::CommitmentScheme, transcript::poseidon::poseidon_canonical_config};
24+
use crate::{frontend::FCircuit, transcript::poseidon::poseidon_custom_config};
2525
use crate::{Curve, Error};
2626

2727
/// Circuit that implements part of the in-circuit checks needed for the offchain verification over
@@ -117,9 +117,18 @@ impl<
117117
type Error = Error;
118118

119119
fn try_from(nova: Nova<C1, C2, FC, CS1, CS2, H>) -> Result<Self, Error> {
120-
// compute the Commitment Scheme challenges of the CycleFold instance commitments, used as
121-
// inputs in the circuit
122-
let poseidon_config = poseidon_canonical_config::<C2::ScalarField>();
120+
// Create a poseidon config on `C2`'s scalar field for `circuit2`, with
121+
// the same parameters (`full_rounds` etc.) as `circuit1` to ensure the
122+
// security level is the same.
123+
// Note: `ark` and `mds` will be different because they depend on the
124+
// field, but they will not affect the security level.
125+
let poseidon_config = poseidon_custom_config(
126+
nova.poseidon_config.full_rounds,
127+
nova.poseidon_config.partial_rounds,
128+
nova.poseidon_config.alpha,
129+
nova.poseidon_config.rate,
130+
nova.poseidon_config.capacity,
131+
);
123132
let mut transcript = PoseidonSponge::<C2::ScalarField>::new(&poseidon_config);
124133
let pp_hash_Fq =
125134
C2::ScalarField::from_le_bytes_mod_order(&nova.pp_hash.into_bigint().to_bytes_le());

folding-schemes/src/transcript/poseidon.rs

Lines changed: 23 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
use ark_crypto_primitives::sponge::{
22
constraints::CryptographicSpongeVar,
3-
poseidon::{constraints::PoseidonSpongeVar, PoseidonConfig, PoseidonSponge},
3+
poseidon::{
4+
constraints::PoseidonSpongeVar, find_poseidon_ark_and_mds, PoseidonConfig, PoseidonSponge,
5+
},
46
Absorb, CryptographicSponge,
57
};
68
use ark_ec::{AffineRepr, CurveGroup};
@@ -79,6 +81,25 @@ impl<F: PrimeField> TranscriptVar<F, PoseidonSponge<F>> for PoseidonSpongeVar<F>
7981
}
8082
}
8183

84+
/// This Poseidon configuration generator produces a Poseidon configuration with custom parameters
85+
pub fn poseidon_custom_config<F: PrimeField>(
86+
full_rounds: usize,
87+
partial_rounds: usize,
88+
alpha: u64,
89+
rate: usize,
90+
capacity: usize,
91+
) -> PoseidonConfig<F> {
92+
let (ark, mds) = find_poseidon_ark_and_mds::<F>(
93+
F::MODULUS_BIT_SIZE as u64,
94+
rate,
95+
full_rounds as u64,
96+
partial_rounds as u64,
97+
0,
98+
);
99+
100+
PoseidonConfig::new(full_rounds, partial_rounds, alpha, mds, ark, rate, capacity)
101+
}
102+
82103
/// This Poseidon configuration generator agrees with Circom's Poseidon(4) in the case of BN254's scalar field
83104
pub fn poseidon_canonical_config<F: PrimeField>() -> PoseidonConfig<F> {
84105
// 120 bit security target as in
@@ -90,23 +111,7 @@ pub fn poseidon_canonical_config<F: PrimeField>() -> PoseidonConfig<F> {
90111
let alpha = 5;
91112
let rate = 4;
92113

93-
let (ark, mds) = ark_crypto_primitives::sponge::poseidon::find_poseidon_ark_and_mds::<F>(
94-
F::MODULUS_BIT_SIZE as u64,
95-
rate,
96-
full_rounds,
97-
partial_rounds,
98-
0,
99-
);
100-
101-
PoseidonConfig::new(
102-
full_rounds as usize,
103-
partial_rounds as usize,
104-
alpha,
105-
mds,
106-
ark,
107-
rate,
108-
1,
109-
)
114+
poseidon_custom_config(full_rounds, partial_rounds, alpha, rate, 1)
110115
}
111116

112117
#[cfg(test)]

0 commit comments

Comments
 (0)