1
1
// Code ported from the the implementation from pathfinder here:
2
2
// https://github.com/eqlabs/pathfinder/blob/00a1a74a90a7b8a7f1d07ac3e616be1cb39cf8f1/crates/stark_poseidon/src/lib.rs
3
3
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 } ;
8
5
9
6
/// A hasher for Starknet Poseidon hash.
10
7
///
@@ -27,7 +24,7 @@ impl PoseidonHasher {
27
24
Some ( previous_message) => {
28
25
self . state [ 0 ] += previous_message;
29
26
self . state [ 1 ] += msg;
30
- poseidon_permute_comp ( & mut self . state ) ;
27
+ Poseidon :: hades_permutation ( & mut self . state ) ;
31
28
}
32
29
None => {
33
30
self . buffer = Some ( msg) ;
@@ -47,7 +44,7 @@ impl PoseidonHasher {
47
44
self . state [ 0 ] += Felt :: ONE ;
48
45
}
49
46
}
50
- poseidon_permute_comp ( & mut self . state ) ;
47
+ Poseidon :: hades_permutation ( & mut self . state ) ;
51
48
52
49
self . state [ 0 ]
53
50
}
@@ -56,15 +53,15 @@ impl PoseidonHasher {
56
53
/// Computes the Starknet Poseidon hash of x and y.
57
54
pub fn poseidon_hash ( x : Felt , y : Felt ) -> Felt {
58
55
let mut state = [ x, y, Felt :: TWO ] ;
59
- poseidon_permute_comp ( & mut state) ;
56
+ Poseidon :: hades_permutation ( & mut state) ;
60
57
61
58
state[ 0 ]
62
59
}
63
60
64
61
/// Computes the Starknet Poseidon hash of a single [`Felt`].
65
62
pub fn poseidon_hash_single ( x : Felt ) -> Felt {
66
63
let mut state = [ x, Felt :: ZERO , Felt :: ONE ] ;
67
- poseidon_permute_comp ( & mut state) ;
64
+ Poseidon :: hades_permutation ( & mut state) ;
68
65
69
66
state[ 0 ]
70
67
}
@@ -93,63 +90,17 @@ pub fn poseidon_hash_many<'a, I: IntoIterator<Item = &'a Felt>>(msgs: I) -> Felt
93
90
}
94
91
}
95
92
96
- poseidon_permute_comp ( & mut state) ;
93
+ Poseidon :: hades_permutation ( & mut state) ;
97
94
}
98
- poseidon_permute_comp ( & mut state) ;
95
+ Poseidon :: hades_permutation ( & mut state) ;
99
96
100
97
state[ 0 ]
101
98
}
102
99
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
-
151
100
#[ cfg( test) ]
152
101
mod tests {
102
+ use starknet_types_core:: hash:: StarkHash ;
103
+
153
104
use super :: * ;
154
105
155
106
#[ test]
@@ -176,7 +127,7 @@ mod tests {
176
127
] ;
177
128
178
129
for ( x, y, hash) in test_data {
179
- assert_eq ! ( poseidon_hash ( x, y) , hash) ;
130
+ assert_eq ! ( Poseidon :: hash ( & x, & y) , hash) ;
180
131
}
181
132
}
182
133
@@ -200,7 +151,9 @@ mod tests {
200
151
] ;
201
152
202
153
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) ;
204
157
}
205
158
}
206
159
@@ -253,7 +206,7 @@ mod tests {
253
206
254
207
for ( input, hash) in test_data {
255
208
// Direct function call
256
- assert_eq ! ( poseidon_hash_many ( & input) , hash) ;
209
+ assert_eq ! ( Poseidon :: hash_array ( & input) , hash) ;
257
210
258
211
// With hasher
259
212
let mut hasher = PoseidonHasher :: new ( ) ;
0 commit comments