anemoi/bls12_381/anemoi_4_3/
hasher.rs1#[cfg(not(feature = "std"))]
4use alloc::vec::Vec;
5
6use super::digest::AnemoiDigest;
7use super::{AnemoiBls12_381_4_3, Jive, Sponge};
8use super::{DIGEST_SIZE, NUM_COLUMNS, RATE_WIDTH, STATE_WIDTH};
9use crate::traits::Anemoi;
10use ark_ff::PrimeField;
11
12use super::Felt;
13use super::{One, Zero};
14
15impl Sponge<Felt> for AnemoiBls12_381_4_3 {
16 type Digest = AnemoiDigest;
17
18 fn hash(bytes: &[u8]) -> Self::Digest {
19 let num_elements = if bytes.len() % 47 == 0 {
22 bytes.len() / 47
23 } else {
24 bytes.len() / 47 + 1
25 };
26
27 let sigma = if num_elements % RATE_WIDTH == 0 {
28 Felt::one()
29 } else {
30 Felt::zero()
31 };
32
33 let mut state = [Felt::zero(); STATE_WIDTH];
35
36 let mut i = 0;
43 let mut num_hashed = 0;
44 let mut buf = [0u8; 48];
45 for chunk in bytes.chunks(47) {
46 if num_hashed + i < num_elements - 1 {
47 buf[..47].copy_from_slice(chunk);
48 } else {
49 let chunk_len = chunk.len();
54 buf = [0u8; 48];
55 buf[..chunk_len].copy_from_slice(chunk);
56 if chunk_len < 47 {
58 buf[chunk_len] = 1;
59 }
60 }
61
62 state[i] += Felt::from_le_bytes_mod_order(&buf[..]);
66 i += 1;
67 if i % RATE_WIDTH == 0 {
68 AnemoiBls12_381_4_3::permutation(&mut state);
69 i = 0;
70 num_hashed += RATE_WIDTH;
71 }
72 }
73
74 state[STATE_WIDTH - 1] += sigma;
76
77 if sigma.is_zero() {
83 state[i] += Felt::one();
84 AnemoiBls12_381_4_3::permutation(&mut state);
85 }
86
87 Self::Digest::new(state[..DIGEST_SIZE].try_into().unwrap())
91 }
92
93 fn hash_field(elems: &[Felt]) -> Self::Digest {
94 let mut state = [Felt::zero(); STATE_WIDTH];
96
97 let sigma = if elems.len() % RATE_WIDTH == 0 {
98 Felt::one()
99 } else {
100 Felt::zero()
101 };
102
103 let mut i = 0;
104 for &element in elems.iter() {
105 state[i] += element;
106 i += 1;
107 if i % RATE_WIDTH == 0 {
108 AnemoiBls12_381_4_3::permutation(&mut state);
109 i = 0;
110 }
111 }
112
113 state[STATE_WIDTH - 1] += sigma;
115
116 if sigma.is_zero() {
122 state[i] += Felt::one();
123 AnemoiBls12_381_4_3::permutation(&mut state);
124 }
125
126 Self::Digest::new(state[..DIGEST_SIZE].try_into().unwrap())
129 }
130
131 fn merge(digests: &[Self::Digest; 2]) -> Self::Digest {
132 let mut state = [Felt::zero(); STATE_WIDTH];
134
135 state[0..DIGEST_SIZE].copy_from_slice(digests[0].as_elements());
138 state[DIGEST_SIZE..2 * DIGEST_SIZE].copy_from_slice(digests[0].as_elements());
139
140 AnemoiBls12_381_4_3::permutation(&mut state);
142
143 Self::Digest::new(state[..DIGEST_SIZE].try_into().unwrap())
144 }
145}
146
147impl Jive<Felt> for AnemoiBls12_381_4_3 {
148 fn compress(elems: &[Felt]) -> Vec<Felt> {
149 assert!(elems.len() == STATE_WIDTH);
150
151 let mut state = elems.to_vec();
152 AnemoiBls12_381_4_3::permutation(&mut state);
153
154 let mut result = [Felt::zero(); NUM_COLUMNS];
155 for (i, r) in result.iter_mut().enumerate() {
156 *r = elems[i] + elems[i + NUM_COLUMNS] + state[i] + state[i + NUM_COLUMNS];
157 }
158
159 result.to_vec()
160 }
161
162 fn compress_k(elems: &[Felt], k: usize) -> Vec<Felt> {
163 assert!(elems.len() == STATE_WIDTH);
164 assert!(STATE_WIDTH % k == 0);
165 assert!(k % 2 == 0);
166
167 let mut state = elems.to_vec();
168 AnemoiBls12_381_4_3::permutation(&mut state);
169
170 let mut result = vec![Felt::zero(); STATE_WIDTH / k];
171 let c = result.len();
172 for (i, r) in result.iter_mut().enumerate() {
173 for j in 0..k {
174 *r += elems[i + c * j] + state[i + c * j];
175 }
176 }
177
178 result
179 }
180}
181
182#[cfg(test)]
183mod tests {
184 #[cfg(not(feature = "std"))]
185 use alloc::vec;
186
187 use super::super::MontFp;
188 use super::*;
189 use ark_ff::BigInteger;
190
191 #[test]
192 fn test_anemoi_hash() {
193 let input_data = [
195 vec![Felt::zero(), Felt::zero(), Felt::zero(), Felt::zero()],
196 vec![Felt::one(), Felt::one(), Felt::one(), Felt::one()],
197 vec![Felt::zero(), Felt::zero(), Felt::one(), Felt::one()],
198 vec![Felt::one(), Felt::one(), Felt::zero(), Felt::zero()],
199 vec![
200 MontFp!("3478190366645077329062387911759857236499263186749383695250484804369076098962408026507385944138785122527147895559085"
201 )],
202 vec![
203 MontFp!(
204 "1204757022733618702245695022362210673090184180289461640964393670508762664913657763815285216675013204672855455968166"
205 ),
206 MontFp!("229264651799887865578273118032416158552374500069538974023134241671888891566565325016261970533772885892514131522324"
207 ),
208 ],
209 vec![
210 MontFp!(
211 "177717861685121075852882639397771234670672217624656643704253853166625554591784186707288011666580142027095461219927"
212 ),
213 MontFp!("2664159978722322727411461850719183495029060572269930286611223738648050026900916021701195336148073915673920578139515"
214 ),
215 MontFp!("3168897365696464751089641952623368003358434783685755752721979882688778293819456233336426355170181665478528538972725"
216 ),
217 ],
218 vec![
219 MontFp!(
220 "529423574900204087999767742321637746109193723419458908707428479135997266319072674410850341834328721890278957792618"
221 ),
222 MontFp!("3148159782614182473118320567803373093488104354203130300286617668600785071681974546798837662949302481963079067906680"
223 ),
224 MontFp!("1083645939082345614904425670523907746448517423057464053705787555890054715287719463530138543606015991452224492494731"
225 ),
226 MontFp!("2807268919105297081646910924341136067920274853031997221954508076679997895846027148765771991535533447647305434261916"
227 ),
228 ],
229 vec![
230 MontFp!(
231 "3942124505372145879707769758437029629242473037070041756829399827985529317490119201593294288730321858969168795882591"
232 ),
233 MontFp!("2948389218971913142595299953737210328251053567408899560831733646698737436722062772042039437496555401586890558844020"
234 ),
235 MontFp!("1951166782335181494088937508317393496993611622685086968055175772193804505322387296392690938471020669718383975309532"
236 ),
237 MontFp!("3159957546857530858381811628455870492082054267240750742256782466302933919683184838401730844715872139634403069726858"
238 ),
239 MontFp!("2862834010401599898219710787596316847120613900794954135737067214558874858756329396400855600235963759882747786540404"
240 ),
241 ],
242 vec![
243 MontFp!(
244 "442383683928193282947541811118171577253029396096980687266816333308650666919596182616073814966705645577455262083516"
245 ),
246 MontFp!("3474343543165004187936129993054631267742133607255083236479107754787485302127789221230133641816397320407994932786163"
247 ),
248 MontFp!("3380527423356682362307992583106461603599581627552321227216704820347353004760999228306110918204127470701240112195941"
249 ),
250 MontFp!("3112951976232687026802036550687130608286117306290466630678325309622306021784306332142592082742828936853603170941922"
251 ),
252 MontFp!("2611204297476868862193359640196948819406140961326550374402004429141754814188552985163011279977823062470634807546903"
253 ),
254 MontFp!("2889443312718009524459939344276095701899215302717389345365446369440025952961431535196040082429742136085575408972705"),],];
255
256 let output_data = [
257[
258 MontFp!("2940668067266832030903300713880139151173275526618596596954076114821895049272625792093682693181482523953691902365663"),],
259 [MontFp!("3342678617705459012287997353144186876092786389171849821793537400751167280639654962279805649671173411894902355858415"),],
260 [MontFp!("897668485411151016252063836411911079925767629775867831728887685001424286000176738706190210972231148728580437604935"),],
261 [MontFp!("261101949137956463543477394252410370931502266322987592818386276127634601896308935037921959975558135101361870359258"),],[MontFp!("2245100416982495102199387963939381924471363148632927465707066694849817699597209269935143147911791023854903195819366"),],[MontFp!("1992338069801663438012219224631570563826476479512040972197716217632689222758336302238924878425504523764403629814367"),],[MontFp!("877634473926936284841537119546245960890683255565853010165732801201337279756927477938178482170744533435377368968730"),],[MontFp!("3724599954884844853806409306911120960065460889492714025286924052647248345170780173516192322273128534317365723099745"),],[MontFp!("3200113069035622902050861397550093524076250368151123518340606353448676370384783100112330409231625375189488417196918"),],[MontFp!("2149147613891947510381404926601049758232543207193560917871022051839987633002652770226667468663320442620171354349106"),],];
262
263 for (input, expected) in input_data.iter().zip(output_data) {
264 assert_eq!(
265 expected,
266 AnemoiBls12_381_4_3::hash_field(input).to_elements()
267 );
268 }
269 }
270
271 #[test]
272 fn test_anemoi_hash_bytes() {
273 let input_data = [
275 vec![Felt::zero(); 4],
276 vec![Felt::one(); 4],
277 vec![Felt::zero(), Felt::zero(), Felt::one(), Felt::one()],
278 vec![Felt::one(), Felt::one(), Felt::zero(), Felt::zero()],
279 ];
280
281 let output_data = [
282 [
283 MontFp!("2940668067266832030903300713880139151173275526618596596954076114821895049272625792093682693181482523953691902365663"),],
284 [MontFp!("3342678617705459012287997353144186876092786389171849821793537400751167280639654962279805649671173411894902355858415"),],
285 [MontFp!("897668485411151016252063836411911079925767629775867831728887685001424286000176738706190210972231148728580437604935"),],
286 [MontFp!("261101949137956463543477394252410370931502266322987592818386276127634601896308935037921959975558135101361870359258"),],
287 ];
288
289 for (input, expected) in input_data.iter().zip(output_data) {
293 let mut bytes = [0u8; 188];
294 bytes[0..47].copy_from_slice(&input[0].into_bigint().to_bytes_le()[0..47]);
295 bytes[47..94].copy_from_slice(&input[1].into_bigint().to_bytes_le()[0..47]);
296 bytes[94..141].copy_from_slice(&input[2].into_bigint().to_bytes_le()[0..47]);
297 bytes[141..188].copy_from_slice(&input[3].into_bigint().to_bytes_le()[0..47]);
298
299 assert_eq!(expected, AnemoiBls12_381_4_3::hash(&bytes).to_elements());
300 }
301 }
302
303 #[test]
304 fn test_anemoi_jive() {
305 let input_data = [
307 vec![Felt::zero(), Felt::zero(), Felt::zero(), Felt::zero()],
308 vec![Felt::one(), Felt::one(), Felt::one(), Felt::one()],
309 vec![Felt::zero(), Felt::zero(), Felt::one(), Felt::one()],
310 vec![Felt::one(), Felt::one(), Felt::zero(), Felt::zero()],
311 ];
312
313 let output_data = [
314[MontFp!("2182431290704436788418060634803748513006487864594071940133967216764562185869534818587870671419244594946258111655196"
315 ),
316 MontFp!("3584595477211783622630741012615941601587793370526228493195173031759026796058440775701817784781446148722285618960524"),],[MontFp!("3672701981707521318101679600213368747520920180417563081581162373949359365624895815123347476885913853820192970903029"
317 ),
318 MontFp!("2732651319344478048053404620785574688197427271909258305324791677897765083343328257136423854703039232453649848191428"),],[MontFp!("415713322322912545564193907405043626868156318882288129485197572128572554556771681528610943606168452623797653150692"
319 ),
320 MontFp!("2147536765737237170190209707679202535424442288937096923239685310680933052450050052160892705170564924404241540745120"),],[MontFp!("662760424293721908696422562222349787646979058578262140084405067201215405511285978285590137403678759847721259276360"
321 ),
322 MontFp!("1078728456415669970181374549496070873178175088025952973371266916547380812535592884145986873667653821102411901837124"),],];
323
324 for (input, expected) in input_data.iter().zip(output_data) {
325 assert_eq!(expected.to_vec(), AnemoiBls12_381_4_3::compress(input));
326 }
327
328 for (input, expected) in input_data.iter().zip(output_data) {
329 assert_eq!(expected.to_vec(), AnemoiBls12_381_4_3::compress_k(input, 2));
330 }
331
332 let input_data = [
333 vec![Felt::zero(), Felt::zero(), Felt::zero(), Felt::zero()],
334 vec![Felt::one(), Felt::one(), Felt::one(), Felt::one()],
335 vec![Felt::zero(), Felt::zero(), Felt::one(), Felt::one()],
336 vec![Felt::one(), Felt::one(), Felt::zero(), Felt::zero()],
337 ];
338
339 let output_data = [
340[MontFp!("1764617212694553017631011821683785958037398415181292547997082112399557331437137729847000827071675079630649458055933"),],[MontFp!("2402943745830331972737294395263039279161464632387813501573895915723092798477386207817083702459937422235948546534670"),],[MontFp!("2563250088060149715754403615084246162292598607819385052724882882809505607006821733689503648776733377028039193895812"),],[MontFp!("1741488880709391878877797111718420660825154146604215113455671983748596218046878862431577011071332580950133161113484"),],];
341
342 for (input, expected) in input_data.iter().zip(output_data) {
343 assert_eq!(expected.to_vec(), AnemoiBls12_381_4_3::compress_k(input, 4));
344 }
345 }
346}