Skip to content

Commit 672d1a4

Browse files
committed
Add comprehensive Poseidon/Poseidon2 support for BN254 and BLS12-381
- Add poseidon_hash<N>() matching circom implementation - Add poseidon2_hash<N>() matching noir/barretenberg implementation - Add Poseidon parameters (MDS, RC) for BN254 t=3, BLS12-381 t=2,3,4 - Add Poseidon2 parameters (MAT_DIAG, RC) for BN254/BLS12-381 t=2,3,4 - Add PoseidonConfig/Poseidon2Config for flexible parameter selection - Add comprehensive test coverage validated against: - circomlib (BN254 Poseidon) - poseidon-bls12381-circom (BLS12-381 Poseidon) - barretenberg (BN254 Poseidon2) - Reference Sage scripts for parameter generation
1 parent b23e7d5 commit 672d1a4

File tree

6 files changed

+13551
-874
lines changed

6 files changed

+13551
-874
lines changed

soroban-sdk/src/crypto.rs

Lines changed: 11 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,8 @@ pub(crate) mod poseidon_params;
1414
pub mod poseidon_sponge;
1515
pub(crate) mod utils;
1616
pub use bn254::Fr as BnScalar;
17-
pub use poseidon2_sponge::Poseidon2Sponge;
18-
pub use poseidon_sponge::PoseidonSponge;
17+
pub use poseidon2_sponge::{Poseidon2Config, Poseidon2Sponge};
18+
pub use poseidon_sponge::{PoseidonConfig, PoseidonSponge};
1919

2020
/// A `BytesN<N>` generated by a cryptographic hash function.
2121
///
@@ -199,26 +199,17 @@ impl Crypto {
199199
bn254::Bn254::new(self.env())
200200
}
201201

202-
/// Performs a Poseidon hash using a sponge construction
203-
pub fn poseidon_hash(&self, inputs: &Vec<U256>, field: Symbol) -> U256 {
204-
// The initial value for the capacity element initialized with 0 for standard Poseidon
205-
let iv = U256::from_u32(&self.env, 0);
206-
let mut sponge = PoseidonSponge::new(&self.env, iv, field);
207-
for input in inputs.iter() {
208-
sponge.absorb(input);
209-
}
210-
sponge.squeeze()
202+
/// Performs a Poseidon hash using a sponge construction that matches circom's [implementation](https://github.com/iden3/circomlib/blob/35e54ea21da3e8762557234298dbb553c175ea8d/circuits/poseidon.circom)
203+
pub fn poseidon_hash<const N: usize>(&self, field_type: Symbol, inputs: &[U256; N]) -> U256 {
204+
let config = PoseidonConfig::new(&self.env, field_type, N as u32);
205+
poseidon_sponge::hash(&self.env, inputs, config)
211206
}
212207

213-
/// Performs a poseidon2 hash with a sponge construction equivalent to the one in the Barretenberg proving system
214-
pub fn poseidon2_hash(&self, inputs: &Vec<U256>, field: Symbol) -> U256 {
215-
// The initial value for the capacity element initialized with `input.len() * 2^24` for Poseidon2
216-
let iv = U256::from_u128(&self.env, (inputs.len() as u128) << 64);
217-
let mut sponge = Poseidon2Sponge::new(&self.env, iv, field);
218-
for input in inputs.iter() {
219-
sponge.absorb(input);
220-
}
221-
sponge.squeeze()
208+
/// Performs a poseidon2 hash with a sponge construction that matches noir's implementation.
209+
/// Uses rate=3 (t=4) to match the noir/barretenberg [implementation](https://github.com/noir-lang/noir/blob/abfee1f54b20984172ba23482f4af160395cfba5/noir_stdlib/src/hash/poseidon2.nr).
210+
pub fn poseidon2_hash<const N: usize>(&self, field_type: Symbol, inputs: &[U256; N]) -> U256 {
211+
let config = Poseidon2Config::new(&self.env, field_type, 3);
212+
poseidon2_sponge::hash(&self.env, inputs, config)
222213
}
223214
}
224215

0 commit comments

Comments
 (0)