anemoi/bls12_381/anemoi_2_1/
hasher.rs1#[cfg(not(feature = "std"))]
4use alloc::vec::Vec;
5
6use super::digest::AnemoiDigest;
7use super::{AnemoiBls12_381_2_1, Jive, Sponge};
8use super::{DIGEST_SIZE, 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_2_1 {
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 mut state = [Felt::zero(); STATE_WIDTH];
29
30 let mut buf = [0u8; 48];
37 for (i, chunk) in bytes.chunks(47).enumerate() {
38 if i < num_elements - 1 {
39 buf[0..47].copy_from_slice(chunk);
40 } else {
41 let chunk_len = chunk.len();
46 buf = [0u8; 48];
47 buf[..chunk_len].copy_from_slice(chunk);
48 if chunk_len < 47 {
50 buf[chunk_len] = 1;
51 }
52 }
53
54 state[0] += Felt::from_le_bytes_mod_order(&buf[..]);
58 AnemoiBls12_381_2_1::permutation(&mut state);
59 }
60 state[STATE_WIDTH - 1] += Felt::one();
61
62 Self::Digest::new(state[..DIGEST_SIZE].try_into().unwrap())
66 }
67
68 fn hash_field(elems: &[Felt]) -> Self::Digest {
69 let mut state = [Felt::zero(); STATE_WIDTH];
71
72 for &element in elems.iter() {
75 state[0] += element;
76 AnemoiBls12_381_2_1::permutation(&mut state);
77 }
78
79 state[STATE_WIDTH - 1] += Felt::one();
80
81 Self::Digest::new(state[..DIGEST_SIZE].try_into().unwrap())
85 }
86
87 fn merge(digests: &[Self::Digest; 2]) -> Self::Digest {
88 let result = Self::compress(&Self::Digest::digests_to_elements(digests));
91 Self::Digest::new(result.try_into().unwrap())
92 }
93}
94
95impl Jive<Felt> for AnemoiBls12_381_2_1 {
96 fn compress(elems: &[Felt]) -> Vec<Felt> {
97 assert!(elems.len() == STATE_WIDTH);
98
99 let mut state = elems.to_vec();
100 AnemoiBls12_381_2_1::permutation(&mut state);
101
102 vec![state[0] + state[1] + elems[0] + elems[1]]
103 }
104
105 fn compress_k(elems: &[Felt], k: usize) -> Vec<Felt> {
106 assert!(k == 2);
108
109 Self::compress(elems)
110 }
111}
112
113#[cfg(test)]
114mod tests {
115 #[cfg(not(feature = "std"))]
116 use alloc::vec;
117
118 use super::super::MontFp;
119 use super::*;
120 use ark_ff::BigInteger;
121
122 #[test]
123 fn test_anemoi_hash() {
124 let input_data = [
126 vec![Felt::zero(), Felt::zero()],
127 vec![Felt::one(), Felt::one()],
128 vec![Felt::zero(), Felt::one()],
129 vec![Felt::one(), Felt::zero()],
130 vec![MontFp!(
131 "3830311086848849888236431976110302247116143110896873177609502790121170427286440444824651043474707388926317147242998"
132 )],
133 vec![
134 MontFp!(
135 "1724675944989629274545203806912510407614247173442012446934556163001278695817727182442175312153616433074255922703832"
136 ),
137 MontFp!("3105146794553518502095497824949882888889680326951826917122755101075932697139414494188338481262964404838634130364755"
138 ),
139 ],
140 vec![
141 MontFp!(
142 "350492308445544793552494864949788846839916342308595111620239094560542916422774935668417321560437725412255000974728"
143 ),
144 MontFp!("1725309941267812667675900676635576215123627147507130530667608213130494035120812807635577850015904982632428754346146"
145 ),
146 MontFp!("2312947547030282178092241201149116938180736364300301327043058201125277110757024339134164864808561362997575042255525"
147 ),
148 ],
149 vec![
150 MontFp!(
151 "3636407125870859276435295141718539694027483654558256793971395008553891302813361556095695045118168186186809341860437"
152 ),
153 MontFp!("1394179633736664718629986299474681395660571356666052573125212216562117078458807048111125315791237011833872591487687"
154 ),
155 MontFp!("3000192289890877131066307906160796735894710747067802082952862583101732077656564864996804222836453117161416409451060"
156 ),
157 MontFp!("2064900497271051602050546834876568795558276926185454314976506949213452504584265729843506251928443518977086936047522"
158 ),
159 ],
160 vec![
161 MontFp!(
162 "605052123655532251743639038404178558281286158572543759898583863142120387035833720039011317858867488262299677045948"
163 ),
164 MontFp!("1378646499724679273279330327531363802830770406492481700661528470796382880277680062911887140309185106460282485023138"
165 ),
166 MontFp!("1632789037231732221874565879516499749343606218784801731743384108930268889394243187732723538359946499168567705027090"
167 ),
168 MontFp!("329592553648563403858723137432007556870910416840415359696339423598921411929428890497411782460237276991297868386396"
169 ),
170 MontFp!("1195876680499641105595204824797249899369568299490932910431218696161934043072334617503409121187788565077168019563184"
171 ),
172 ],
173 vec![
174 MontFp!(
175 "3075190921122359950664934703601648556085420058671951436958011401587534690551115717377111396274988564198237304353666"
176 ),
177 MontFp!("3419326986335584916312489712000516327290696677572970766585889391616104705346363375577222750937246008867925423482798"
178 ),
179 MontFp!("1378948475731859253682901417906582577745453964942678637296873800370897690266489687583065871730347771936433732173956"
180 ),
181 MontFp!("434819213209834856425262399894697513386422854458119916389578950785921826099147747092122973654613949117993887158169"
182 ),
183 MontFp!("2959811739045932941263291579672134993493582127052200852956262762274535462648144476602886585403619686645783651792211"
184 ),
185 MontFp!("2002518377401644274294207739192197222547494224748071260569678901651938265396145032803394648935423898359933682789880"),],];
186
187 let output_data = [
188[MontFp!("3044496648238508402971476696005782461598801178368833793411335711455208110605169771916004504371572228154710324741161"),],
189[MontFp!("2908793991367076052361840957762986139066526738758775834650765236473336488638852269315020736340802721910347134703704"),],
190[MontFp!("2944094137414315537156609151358641099704493279307534425028271048135173488544687230539814152428883365064015829820463"),],
191[MontFp!("2868958625495483458583620051234160973380283203362973188133402396622476242457329234265515602902085044122040631694899"),],[MontFp!("1866033995575078117872271638683543620649307607095016362529898258120178575148148641617480439242769826709240970576077"),],[MontFp!("718258795897765944758177208463485114194620088839955789078982618553526798718502557788643069426154127435845854471100"),],[MontFp!("2286698192191934508507293243065494603958433091556657060465591121808349675884095770128733564548760243177375970842740"),],[MontFp!("1873646942936659856912960773765807616353120774536672458029128234873732160402675620321975596948087041724675387375220"),],[MontFp!("214854368678843434181525108886989867124405520390579022106184552736389572975439870185673104599101705970513292871653"),],[MontFp!("3625784097092860341146015211036247185380543997103305980159712597275345478788335407338478610702273655584618860197247"),],];
192
193 for (input, expected) in input_data.iter().zip(output_data) {
194 assert_eq!(
195 expected,
196 AnemoiBls12_381_2_1::hash_field(input).to_elements()
197 );
198 }
199 }
200
201 #[test]
202 fn test_anemoi_hash_bytes() {
203 let input_data = [
205 vec![Felt::zero(), Felt::zero()],
206 vec![Felt::one(), Felt::one()],
207 vec![Felt::zero(), Felt::one()],
208 vec![Felt::one(), Felt::zero()],
209 ];
210
211 let output_data = [
212 [MontFp!("3044496648238508402971476696005782461598801178368833793411335711455208110605169771916004504371572228154710324741161"),],
213[MontFp!("2908793991367076052361840957762986139066526738758775834650765236473336488638852269315020736340802721910347134703704"),],
214[MontFp!("2944094137414315537156609151358641099704493279307534425028271048135173488544687230539814152428883365064015829820463"),],
215[MontFp!("2868958625495483458583620051234160973380283203362973188133402396622476242457329234265515602902085044122040631694899"),],
216 ];
217
218 for (input, expected) in input_data.iter().zip(output_data) {
222 let mut bytes = [0u8; 94];
223 bytes[0..47].copy_from_slice(&input[0].into_bigint().to_bytes_le()[0..47]);
224 bytes[47..94].copy_from_slice(&input[1].into_bigint().to_bytes_le()[0..47]);
225
226 assert_eq!(expected, AnemoiBls12_381_2_1::hash(&bytes).to_elements());
227 }
228 }
229
230 #[test]
231 fn test_anemoi_jive() {
232 let input_data = [
234 vec![Felt::zero(), Felt::zero()],
235 vec![Felt::one(), Felt::one()],
236 vec![Felt::zero(), Felt::one()],
237 vec![Felt::one(), Felt::zero()],
238 ];
239
240 let output_data = [
241[MontFp!("2403587970030648969605860549704915622710356578540224073435388894943352899101850938559087153461043348245106307692021"),],[MontFp!("3338092111784861946006125665732871699018939986325206562704758912134694966085752607725062142754026064165834984422908"),],[MontFp!("1985125909818301697005337958894654664774949870969130453343225221846235685271877058212539274671736851151869436601343"),],[MontFp!("3251723048147411152374473396236461385859897497022721086334583719384662681448082382905053326928560538637353089836071"),],];
242
243 for (input, expected) in input_data.iter().zip(output_data) {
244 assert_eq!(expected.to_vec(), AnemoiBls12_381_2_1::compress(input));
245 }
246
247 for (input, expected) in input_data.iter().zip(output_data) {
248 assert_eq!(expected.to_vec(), AnemoiBls12_381_2_1::compress_k(input, 2));
249 }
250
251 for (input, expected) in input_data.iter().zip(output_data) {
252 assert_eq!(
253 expected,
254 AnemoiBls12_381_2_1::merge(&[
255 AnemoiDigest::new([input[0]]),
256 AnemoiDigest::new([input[1]])
257 ])
258 .to_elements()
259 );
260 }
261 }
262}