Skip to content

Commit 7bd20db

Browse files
committed
Rework API based on split-sponge refactor in our fork.
This uses the API changes from: - https://github.com/arkworks-rs/sponge/issues/29 - arkworks-rs/sponge#30 to avoid working through the Arkworks sponge interface, and do hashing using the permutation directly.
1 parent df1746d commit 7bd20db

6 files changed

Lines changed: 262 additions & 3559 deletions

File tree

Cargo.toml

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ license = "MIT OR Apache-2.0"
99
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
1010

1111
[dependencies]
12+
once_cell = "1.8"
1213
ark-ff = "0.3"
13-
ark-sponge = { git = "https://github.com/arkworks-rs/sponge", rev = "51d6fc9aac1fa69f44a04839202b5de828584ed8" }
14+
ark-sponge = { git = "https://github.com/penumbra-zone/sponge", branch = "split-sponge" }
1415
ark-ed-on-bls12-377 = "0.3"

src/hash.rs

Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
use crate::{Fq, State};
2+
3+
/// Hash a single [`Fq`] element with the provided `domain_separator`.
4+
pub fn hash_1(domain_separator: &Fq, value: Fq) -> Fq {
5+
let mut state = State::from(crate::RATE_1_PARAMS.clone());
6+
7+
// Use the domain separator as the sponge's capacity element
8+
state[0] = domain_separator.clone();
9+
state[1] = value;
10+
11+
state.permute();
12+
state[1]
13+
}
14+
15+
/// Hash two [`Fq`] elements with the provided `domain_separator`.
16+
pub fn hash_2(domain_separator: &Fq, value: (Fq, Fq)) -> Fq {
17+
let mut state = State::from(crate::RATE_2_PARAMS.clone());
18+
19+
// Use the domain separator as the sponge's capacity element
20+
state[0] = domain_separator.clone();
21+
state[1] = value.0;
22+
state[2] = value.1;
23+
24+
state.permute();
25+
state[1]
26+
}
27+
28+
/// Hash four [`Fq`] elements with the provided `domain_separator`.
29+
pub fn hash_4(domain_separator: &Fq, value: (Fq, Fq, Fq, Fq)) -> Fq {
30+
let mut state = State::from(crate::RATE_4_PARAMS.clone());
31+
32+
// Use the domain separator as the sponge's capacity element
33+
state[0] = domain_separator.clone();
34+
state[1] = value.0;
35+
state[2] = value.1;
36+
state[3] = value.2;
37+
state[4] = value.3;
38+
39+
state.permute();
40+
state[1]
41+
}
42+
43+
/// Hash five [`Fq`] elements with the provided `domain_separator`.
44+
pub fn hash_5(domain_separator: &Fq, value: (Fq, Fq, Fq, Fq, Fq)) -> Fq {
45+
let mut state = State::from(crate::RATE_5_PARAMS.clone());
46+
47+
// Use the domain separator as the sponge's capacity element
48+
state[0] = domain_separator.clone();
49+
state[1] = value.0;
50+
state[2] = value.1;
51+
state[3] = value.2;
52+
state[4] = value.3;
53+
state[5] = value.4;
54+
55+
state.permute();
56+
state[1]
57+
}

src/lib.rs

Lines changed: 15 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,20 @@
1-
mod sponge;
1+
//! An instantiation of Poseidon for the BLS12-377 scalar field.
22
3-
pub mod params;
3+
use once_cell::sync::Lazy;
44

5-
// Since we depend on a git version of ark-sponge, re-exporting it here means
6-
// our deps can access it without having to keep git revisions in sync.
7-
//
8-
// Going forward, this re-export should be removed and the functionality our
9-
// deps need from direct use of ark-sponge should be folded into this crate.
10-
// However, it's faster to iterate on required functionality without imposing
11-
// hard compartmentalization boundaries from the start.
12-
pub use ark_sponge;
5+
mod hash;
6+
mod params;
137

14-
#[cfg(test)]
15-
mod tests {
16-
use super::*;
8+
pub use hash::{hash_1, hash_2, hash_4, hash_5};
179

18-
#[test]
19-
fn it_works() {
20-
use ark_ed_on_bls12_377::Fq; // lazy import, fix
21-
use ark_ff::{One, Zero};
22-
use ark_sponge::{
23-
poseidon::PoseidonSponge, CryptographicSponge, DuplexSpongeMode,
24-
FieldBasedCryptographicSponge,
25-
};
10+
/// Parameters for the rate-1 instance of Poseidon.
11+
pub const RATE_1_PARAMS: Lazy<Parameters<Fq>> = Lazy::new(params::rate_1);
12+
/// Parameters for the rate-2 instance of Poseidon.
13+
pub const RATE_2_PARAMS: Lazy<Parameters<Fq>> = Lazy::new(params::rate_2);
14+
/// Parameters for the rate-4 instance of Poseidon.
15+
pub const RATE_4_PARAMS: Lazy<Parameters<Fq>> = Lazy::new(params::rate_4);
16+
/// Parameters for the rate-5 instance of Poseidon.
17+
pub const RATE_5_PARAMS: Lazy<Parameters<Fq>> = Lazy::new(params::rate_5);
2618

27-
// Current API has a `new()` method as part of the `CryptographicSponge`
28-
// trait, but this method doesn't allow setting the initial state
29-
// manually. Instead, the fields can be set manually.
30-
// Slightly inconvenient that we have to initialize the mode.
31-
let mut sponge = PoseidonSponge {
32-
parameters: params::rate_2(),
33-
state: vec![Fq::zero(); 3],
34-
mode: DuplexSpongeMode::Absorbing {
35-
next_absorb_index: 0,
36-
},
37-
};
38-
39-
sponge.absorb(&Fq::one());
40-
sponge.absorb(&Fq::one());
41-
42-
let output = sponge.squeeze_native_field_elements(1);
43-
dbg!(output);
44-
}
45-
}
19+
pub use ark_ed_on_bls12_377::Fq;
20+
pub use ark_sponge::poseidon::{Parameters, State};

0 commit comments

Comments
 (0)