Skip to content

Commit f6d339c

Browse files
feat: replace poseidon impl with type-rs (#630)
1 parent a8ee4e2 commit f6d339c

File tree

2 files changed

+15
-64
lines changed

2 files changed

+15
-64
lines changed

starknet-crypto/src/lib.rs

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,7 @@ pub use starknet_types_core::felt::Felt;
2020

2121
pub use pedersen_hash::pedersen_hash;
2222

23-
pub use poseidon_hash::{
24-
poseidon_hash, poseidon_hash_many, poseidon_hash_single, poseidon_permute_comp, PoseidonHasher,
25-
};
23+
pub use poseidon_hash::{poseidon_hash, poseidon_hash_many, poseidon_hash_single, PoseidonHasher};
2624

2725
pub use ecdsa::{get_public_key, recover, sign, verify, ExtendedSignature, Signature};
2826

starknet-crypto/src/poseidon_hash.rs

Lines changed: 14 additions & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,7 @@
11
// Code ported from the the implementation from pathfinder here:
22
// https://github.com/eqlabs/pathfinder/blob/00a1a74a90a7b8a7f1d07ac3e616be1cb39cf8f1/crates/stark_poseidon/src/lib.rs
33

4-
use starknet_crypto_codegen::poseidon_consts;
5-
use starknet_types_core::felt::Felt;
6-
7-
poseidon_consts!();
4+
use starknet_types_core::{felt::Felt, hash::Poseidon};
85

96
/// A hasher for Starknet Poseidon hash.
107
///
@@ -27,7 +24,7 @@ impl PoseidonHasher {
2724
Some(previous_message) => {
2825
self.state[0] += previous_message;
2926
self.state[1] += msg;
30-
poseidon_permute_comp(&mut self.state);
27+
Poseidon::hades_permutation(&mut self.state);
3128
}
3229
None => {
3330
self.buffer = Some(msg);
@@ -47,7 +44,7 @@ impl PoseidonHasher {
4744
self.state[0] += Felt::ONE;
4845
}
4946
}
50-
poseidon_permute_comp(&mut self.state);
47+
Poseidon::hades_permutation(&mut self.state);
5148

5249
self.state[0]
5350
}
@@ -56,15 +53,15 @@ impl PoseidonHasher {
5653
/// Computes the Starknet Poseidon hash of x and y.
5754
pub fn poseidon_hash(x: Felt, y: Felt) -> Felt {
5855
let mut state = [x, y, Felt::TWO];
59-
poseidon_permute_comp(&mut state);
56+
Poseidon::hades_permutation(&mut state);
6057

6158
state[0]
6259
}
6360

6461
/// Computes the Starknet Poseidon hash of a single [`Felt`].
6562
pub fn poseidon_hash_single(x: Felt) -> Felt {
6663
let mut state = [x, Felt::ZERO, Felt::ONE];
67-
poseidon_permute_comp(&mut state);
64+
Poseidon::hades_permutation(&mut state);
6865

6966
state[0]
7067
}
@@ -93,63 +90,17 @@ pub fn poseidon_hash_many<'a, I: IntoIterator<Item = &'a Felt>>(msgs: I) -> Felt
9390
}
9491
}
9592

96-
poseidon_permute_comp(&mut state);
93+
Poseidon::hades_permutation(&mut state);
9794
}
98-
poseidon_permute_comp(&mut state);
95+
Poseidon::hades_permutation(&mut state);
9996

10097
state[0]
10198
}
10299

103-
/// Poseidon permutation function.
104-
pub fn poseidon_permute_comp(state: &mut [Felt; 3]) {
105-
let mut idx = 0;
106-
107-
// Full rounds
108-
for _ in 0..(FULL_ROUNDS / 2) {
109-
round_comp(state, idx, true);
110-
idx += 3;
111-
}
112-
113-
// Partial rounds
114-
for _ in 0..PARTIAL_ROUNDS {
115-
round_comp(state, idx, false);
116-
idx += 1;
117-
}
118-
119-
// Full rounds
120-
for _ in 0..(FULL_ROUNDS / 2) {
121-
round_comp(state, idx, true);
122-
idx += 3;
123-
}
124-
}
125-
126-
/// Linear layer for MDS matrix M = ((3,1,1), (1,-1,1), (1,1,2))
127-
/// Given state vector x, it returns Mx, optimized by precomputing t.
128-
#[inline(always)]
129-
fn mix(state: &mut [Felt; 3]) {
130-
let t = state[0] + state[1] + state[2];
131-
state[0] = t + state[0].double();
132-
state[1] = t - state[1].double();
133-
state[2] = t - Felt::THREE * state[2];
134-
}
135-
136-
#[inline]
137-
fn round_comp(state: &mut [Felt; 3], idx: usize, full: bool) {
138-
if full {
139-
state[0] += POSEIDON_COMP_CONSTS[idx];
140-
state[1] += POSEIDON_COMP_CONSTS[idx + 1];
141-
state[2] += POSEIDON_COMP_CONSTS[idx + 2];
142-
state[0] = state[0] * state[0] * state[0];
143-
state[1] = state[1] * state[1] * state[1];
144-
} else {
145-
state[2] += POSEIDON_COMP_CONSTS[idx];
146-
}
147-
state[2] = state[2] * state[2] * state[2];
148-
mix(state);
149-
}
150-
151100
#[cfg(test)]
152101
mod tests {
102+
use starknet_types_core::hash::StarkHash;
103+
153104
use super::*;
154105

155106
#[test]
@@ -176,7 +127,7 @@ mod tests {
176127
];
177128

178129
for (x, y, hash) in test_data {
179-
assert_eq!(poseidon_hash(x, y), hash);
130+
assert_eq!(Poseidon::hash(&x, &y), hash);
180131
}
181132
}
182133

@@ -200,7 +151,9 @@ mod tests {
200151
];
201152

202153
for (x, hash) in test_data {
203-
assert_eq!(poseidon_hash_single(x), hash);
154+
let mut state = [x, Felt::ZERO, Felt::ONE];
155+
Poseidon::hades_permutation(&mut state);
156+
assert_eq!(state[0], hash);
204157
}
205158
}
206159

@@ -253,7 +206,7 @@ mod tests {
253206

254207
for (input, hash) in test_data {
255208
// Direct function call
256-
assert_eq!(poseidon_hash_many(&input), hash);
209+
assert_eq!(Poseidon::hash_array(&input), hash);
257210

258211
// With hasher
259212
let mut hasher = PoseidonHasher::new();

0 commit comments

Comments
 (0)