1use p3_field::PrimeCharacteristicRing;
19use p3_monty_31::{
20 GenericPoseidon2LinearLayersMonty31, InternalLayerBaseParameters, InternalLayerParameters,
21 Poseidon2ExternalLayerMonty31, Poseidon2InternalLayerMonty31,
22};
23use p3_poseidon2::{ExternalLayerConstants, Poseidon2};
24
25use crate::{BABYBEAR_S_BOX_DEGREE, BabyBear, BabyBearParameters};
26
27pub type Poseidon2InternalLayerBabyBear<const WIDTH: usize> =
28 Poseidon2InternalLayerMonty31<BabyBearParameters, WIDTH, BabyBearInternalLayerParameters>;
29
30pub type Poseidon2ExternalLayerBabyBear<const WIDTH: usize> =
31 Poseidon2ExternalLayerMonty31<BabyBearParameters, WIDTH>;
32
33pub const BABYBEAR_POSEIDON2_HALF_FULL_ROUNDS: usize = 4;
38
39pub const BABYBEAR_POSEIDON2_PARTIAL_ROUNDS_16: usize = 13;
48
49pub const BABYBEAR_POSEIDON2_PARTIAL_ROUNDS_24: usize = 21;
57
58pub const BABYBEAR_POSEIDON2_PARTIAL_ROUNDS_32: usize = 30;
63
64const _: () =
65 assert!(BABYBEAR_POSEIDON2_RC_16_EXTERNAL_INITIAL.len() == BABYBEAR_POSEIDON2_HALF_FULL_ROUNDS);
66const _: () =
67 assert!(BABYBEAR_POSEIDON2_RC_16_EXTERNAL_FINAL.len() == BABYBEAR_POSEIDON2_HALF_FULL_ROUNDS);
68const _: () =
69 assert!(BABYBEAR_POSEIDON2_RC_16_INTERNAL.len() == BABYBEAR_POSEIDON2_PARTIAL_ROUNDS_16);
70const _: () =
71 assert!(BABYBEAR_POSEIDON2_RC_24_EXTERNAL_INITIAL.len() == BABYBEAR_POSEIDON2_HALF_FULL_ROUNDS);
72const _: () =
73 assert!(BABYBEAR_POSEIDON2_RC_24_EXTERNAL_FINAL.len() == BABYBEAR_POSEIDON2_HALF_FULL_ROUNDS);
74const _: () =
75 assert!(BABYBEAR_POSEIDON2_RC_24_INTERNAL.len() == BABYBEAR_POSEIDON2_PARTIAL_ROUNDS_24);
76const _: () =
77 assert!(BABYBEAR_POSEIDON2_RC_32_EXTERNAL_INITIAL.len() == BABYBEAR_POSEIDON2_HALF_FULL_ROUNDS);
78const _: () =
79 assert!(BABYBEAR_POSEIDON2_RC_32_EXTERNAL_FINAL.len() == BABYBEAR_POSEIDON2_HALF_FULL_ROUNDS);
80const _: () =
81 assert!(BABYBEAR_POSEIDON2_RC_32_INTERNAL.len() == BABYBEAR_POSEIDON2_PARTIAL_ROUNDS_32);
82
83pub type Poseidon2BabyBear<const WIDTH: usize> = Poseidon2<
88 BabyBear,
89 Poseidon2ExternalLayerBabyBear<WIDTH>,
90 Poseidon2InternalLayerBabyBear<WIDTH>,
91 WIDTH,
92 BABYBEAR_S_BOX_DEGREE,
93>;
94
95pub type GenericPoseidon2LinearLayersBabyBear =
101 GenericPoseidon2LinearLayersMonty31<BabyBearParameters, BabyBearInternalLayerParameters>;
102
103pub const BABYBEAR_POSEIDON2_RC_16_EXTERNAL_INITIAL: [[BabyBear; 16]; 4] =
112 BabyBear::new_2d_array([
113 [
114 0x69cbb6af, 0x46ad93f9, 0x60a00f4e, 0x6b1297cd, 0x23189afe, 0x732e7bef, 0x72c246de,
115 0x2c941900, 0x0557eede, 0x1580496f, 0x3a3ea77b, 0x54f3f271, 0x0f49b029, 0x47872fe1,
116 0x221e2e36, 0x1ab7202e,
117 ],
118 [
119 0x487779a6, 0x3851c9d8, 0x38dc17c0, 0x209f8849, 0x268dcee8, 0x350c48da, 0x5b9ad32e,
120 0x0523272b, 0x3f89055b, 0x01e894b2, 0x13ddedde, 0x1b2ef334, 0x7507d8b4, 0x6ceeb94e,
121 0x52eb6ba2, 0x50642905,
122 ],
123 [
124 0x05453f3f, 0x06349efc, 0x6922787c, 0x04bfff9c, 0x768c714a, 0x3e9ff21a, 0x15737c9c,
125 0x2229c807, 0x0d47f88c, 0x097e0ecc, 0x27eadba0, 0x2d7d29e4, 0x3502aaa0, 0x0f475fd7,
126 0x29fbda49, 0x018afffd,
127 ],
128 [
129 0x0315b618, 0x6d4497d1, 0x1b171d9e, 0x52861abd, 0x2e5d0501, 0x3ec8646c, 0x6e5f250a,
130 0x148ae8e6, 0x17f5fa4a, 0x3e66d284, 0x0051aa3b, 0x483f7913, 0x2cfe5f15, 0x023427ca,
131 0x2cc78315, 0x1e36ea47,
132 ],
133 ]);
134
135pub const BABYBEAR_POSEIDON2_RC_16_EXTERNAL_FINAL: [[BabyBear; 16]; 4] = BabyBear::new_2d_array([
144 [
145 0x7290a80d, 0x6f7e5329, 0x598ec8a8, 0x76a859a0, 0x6559e868, 0x657b83af, 0x13271d3f,
146 0x1f876063, 0x0aeeae37, 0x706e9ca6, 0x46400cee, 0x72a05c26, 0x2c589c9e, 0x20bd37a7,
147 0x6a2d3d10, 0x20523767,
148 ],
149 [
150 0x5b8fe9c4, 0x2aa501d6, 0x1e01ac3e, 0x1448bc54, 0x5ce5ad1c, 0x4918a14d, 0x2c46a83f,
151 0x4fcf6876, 0x61d8d5c8, 0x6ddf4ff9, 0x11fda4d3, 0x02933a8f, 0x170eaf81, 0x5a9c314f,
152 0x49a12590, 0x35ec52a1,
153 ],
154 [
155 0x58eb1611, 0x5e481e65, 0x367125c9, 0x0eba33ba, 0x1fc28ded, 0x066399ad, 0x0cbec0ea,
156 0x75fd1af0, 0x50f5bf4e, 0x643d5f41, 0x6f4fe718, 0x5b3cbbde, 0x1e3afb3e, 0x296fb027,
157 0x45e1547b, 0x4a8db2ab,
158 ],
159 [
160 0x59986d19, 0x30bcdfa3, 0x1db63932, 0x1d7c2824, 0x53b33681, 0x0673b747, 0x038a98a3,
161 0x2c5bce60, 0x351979cd, 0x5008fb73, 0x547bca78, 0x711af481, 0x3f93bf64, 0x644d987b,
162 0x3c8bcd87, 0x608758b8,
163 ],
164]);
165
166pub const BABYBEAR_POSEIDON2_RC_16_INTERNAL: [BabyBear; 13] = BabyBear::new_array([
175 0x5a8053c0, 0x693be639, 0x3858867d, 0x19334f6b, 0x128f0fd8, 0x4e2b1ccb, 0x61210ce0, 0x3c318939,
176 0x0b5b2f22, 0x2edb11d5, 0x213effdf, 0x0cac4606, 0x241af16d,
177]);
178
179pub fn default_babybear_poseidon2_16() -> Poseidon2BabyBear<16> {
181 Poseidon2::new(
182 ExternalLayerConstants::new(
183 BABYBEAR_POSEIDON2_RC_16_EXTERNAL_INITIAL.to_vec(),
184 BABYBEAR_POSEIDON2_RC_16_EXTERNAL_FINAL.to_vec(),
185 ),
186 BABYBEAR_POSEIDON2_RC_16_INTERNAL.to_vec(),
187 )
188}
189
190pub const BABYBEAR_POSEIDON2_RC_24_EXTERNAL_INITIAL: [[BabyBear; 24]; 4] =
199 BabyBear::new_2d_array([
200 [
201 0x0fa20c37, 0x0795bb97, 0x12c60b9c, 0x0eabd88e, 0x096485ca, 0x07093527, 0x1b1d4e50,
202 0x30a01ace, 0x3bd86f5a, 0x69af7c28, 0x3f94775f, 0x731560e8, 0x465a0ecd, 0x574ef807,
203 0x62fd4870, 0x52ccfe44, 0x14772b14, 0x4dedf371, 0x260acd7c, 0x1f51dc58, 0x75125532,
204 0x686a4d7b, 0x54bac179, 0x31947706,
205 ],
206 [
207 0x29799d3b, 0x6e01ae90, 0x203a7a64, 0x4f7e25be, 0x72503f77, 0x45bd3b69, 0x769bd6b4,
208 0x5a867f08, 0x4fdba082, 0x251c4318, 0x28f06201, 0x6788c43a, 0x4c6d6a99, 0x357784a8,
209 0x2abaf051, 0x770f7de6, 0x1794b784, 0x4796c57a, 0x724b7a10, 0x449989a7, 0x64935cf1,
210 0x59e14aac, 0x0e620bb8, 0x3af5a33b,
211 ],
212 [
213 0x4465cc0e, 0x019df68f, 0x4af8d068, 0x08784f82, 0x0cefdeae, 0x6337a467, 0x32fa7a16,
214 0x486f62d6, 0x386a7480, 0x20f17c4a, 0x54e50da8, 0x2012cf03, 0x5fe52950, 0x09afb6cd,
215 0x2523044e, 0x5c54d0ef, 0x71c01f3c, 0x60b2c4fb, 0x4050b379, 0x5e6a70a5, 0x418543f5,
216 0x71debe56, 0x1aad2994, 0x3368a483,
217 ],
218 [
219 0x07a86f3a, 0x5ea43ff1, 0x2443780e, 0x4ce444f7, 0x146f9882, 0x3132b089, 0x197ea856,
220 0x667030c3, 0x2317d5dc, 0x0c2c48a7, 0x56b2df66, 0x67bd81e9, 0x4fcdfb19, 0x4baaef32,
221 0x0328d30a, 0x6235760d, 0x12432912, 0x0a49e258, 0x030e1b70, 0x48caeb03, 0x49e4d9e9,
222 0x1051b5c6, 0x6a36dbbe, 0x4cff27a5,
223 ],
224 ]);
225
226pub const BABYBEAR_POSEIDON2_RC_24_EXTERNAL_FINAL: [[BabyBear; 24]; 4] = BabyBear::new_2d_array([
235 [
236 0x032959ad, 0x2b18af6a, 0x55d3dc8c, 0x43bd26c8, 0x0c41595f, 0x7048d2e2, 0x00db8983,
237 0x2af563d7, 0x6e84758f, 0x611d64e1, 0x1f9977e2, 0x64163a0a, 0x5c5fc27b, 0x02e22561,
238 0x3a2d75db, 0x1ba7b71a, 0x34343f64, 0x7406b35d, 0x19df8299, 0x6ff4480a, 0x514a81c8,
239 0x57ab52ce, 0x6ad69f52, 0x3e0c0e0d,
240 ],
241 [
242 0x48126114, 0x2a9d62cc, 0x17441f23, 0x485762bb, 0x2f218674, 0x06fdc64a, 0x0861b7f2,
243 0x3b36eee6, 0x70a11040, 0x04b31737, 0x3722a872, 0x2a351c63, 0x623560dc, 0x62584ab2,
244 0x382c7c04, 0x3bf9edc7, 0x0e38fe51, 0x376f3b10, 0x5381e178, 0x3afc61c7, 0x5c1bcb4d,
245 0x6643ce1f, 0x2d0af1c1, 0x08f583cc,
246 ],
247 [
248 0x5d6ff60f, 0x6324c1e5, 0x74412fb7, 0x70c0192e, 0x0b72f141, 0x4067a111, 0x57388c4f,
249 0x351009ec, 0x0974c159, 0x539a58b3, 0x038c0cff, 0x476c0392, 0x3f7bc15f, 0x4491dd2c,
250 0x4d1fef55, 0x04936ae3, 0x58214dd4, 0x683c6aad, 0x1b42f16b, 0x6dc79135, 0x2d4e71ec,
251 0x3e2946ea, 0x59dce8db, 0x6cee892a,
252 ],
253 [
254 0x47f07350, 0x7106ce93, 0x3bd4a7a9, 0x2bfe636a, 0x430011e9, 0x001cd66a, 0x307faf5b,
255 0x0d9ef3fe, 0x6d40043a, 0x2e8f470c, 0x1b6865e8, 0x0c0e6c01, 0x4d41981f, 0x423b9d3d,
256 0x410408cc, 0x263f0884, 0x5311bbd0, 0x4dae58d8, 0x30401cea, 0x09afa575, 0x4b3d5b42,
257 0x63ac0b37, 0x5fe5bb14, 0x5244e9d4,
258 ],
259]);
260
261pub const BABYBEAR_POSEIDON2_RC_24_INTERNAL: [BabyBear; 21] = BabyBear::new_array([
270 0x1da78ec2, 0x730b0924, 0x3eb56cf3, 0x5bd93073, 0x37204c97, 0x51642d89, 0x66e943e8, 0x1a3e72de,
271 0x70beb1e9, 0x30ff3b3f, 0x4240d1c4, 0x12647b8d, 0x65d86965, 0x49ef4d7c, 0x47785697, 0x46b3969f,
272 0x5c7b7a0e, 0x7078fc60, 0x4f22d482, 0x482a9aee, 0x6beb839d,
273]);
274
275pub fn default_babybear_poseidon2_24() -> Poseidon2BabyBear<24> {
277 Poseidon2::new(
278 ExternalLayerConstants::new(
279 BABYBEAR_POSEIDON2_RC_24_EXTERNAL_INITIAL.to_vec(),
280 BABYBEAR_POSEIDON2_RC_24_EXTERNAL_FINAL.to_vec(),
281 ),
282 BABYBEAR_POSEIDON2_RC_24_INTERNAL.to_vec(),
283 )
284}
285
286pub const BABYBEAR_POSEIDON2_RC_32_EXTERNAL_INITIAL: [[BabyBear; 32]; 4] =
295 BabyBear::new_2d_array([
296 [
297 0x6710e381, 0x01ab3dad, 0x49bdc51f, 0x41c98c65, 0x23885d8a, 0x24ea7d7c, 0x6b65fc6d,
298 0x6106615a, 0x084957f3, 0x157c3634, 0x4dada10f, 0x6cdfa46d, 0x1bf208be, 0x5bd22fac,
299 0x4c8bcbdf, 0x27f79490, 0x70495412, 0x2a41844e, 0x51bb69f1, 0x3215dc21, 0x67114819,
300 0x27aa6a09, 0x5f4d3cad, 0x5fd6c724, 0x1b4c108d, 0x5799d04d, 0x568c212f, 0x680821db,
301 0x62073729, 0x229ee780, 0x3b4f94c3, 0x17a3ac54,
302 ],
303 [
304 0x6c388279, 0x4876fe55, 0x3170f20a, 0x33703e4e, 0x03980ab1, 0x012fb0fa, 0x145ee8db,
305 0x49815b30, 0x46ad879c, 0x52bc503d, 0x586530d7, 0x5c36f9e5, 0x028e6503, 0x08310368,
306 0x75546646, 0x732516f1, 0x33483e5a, 0x04a0842c, 0x1a3135d9, 0x537b2eb1, 0x5baf4f77,
307 0x4b78cd6d, 0x5aed2c4a, 0x66c893e1, 0x3c5493a6, 0x46c62bfc, 0x564e591a, 0x52ded7a7,
308 0x00d1032d, 0x2b30d801, 0x101dabf7, 0x2efb21cd,
309 ],
310 [
311 0x4a361c39, 0x49eff572, 0x2e13caf4, 0x016e6799, 0x1b5cdb44, 0x17ca2dc6, 0x0e500ee0,
312 0x0141ca9b, 0x279b2376, 0x6647c40b, 0x0dcaee3c, 0x16e7fcf9, 0x59e6d65c, 0x1eb730c9,
313 0x28607848, 0x45727f9c, 0x4e543ffb, 0x03ee2550, 0x010cd54b, 0x02dc4b76, 0x2b3a9a3c,
314 0x2eabb2d9, 0x06928553, 0x2d23b3f5, 0x6da322b1, 0x1527ec07, 0x0e450b7a, 0x53961612,
315 0x20f16b10, 0x16f00c60, 0x4c39d50f, 0x41d59d76,
316 ],
317 [
318 0x5253f822, 0x3b53d381, 0x1b7f470a, 0x5e3d895c, 0x52658125, 0x012190d3, 0x65563b80,
319 0x1d0faa47, 0x3575b3c9, 0x4c0d9d20, 0x18cff09f, 0x64a7da5c, 0x2f140b25, 0x139f9e31,
320 0x66e36bd5, 0x6442c811, 0x58879bce, 0x5fcc87c6, 0x6807ae0c, 0x4111c657, 0x633c8929,
321 0x74962971, 0x3fc18eb8, 0x456cf288, 0x31f6c8d2, 0x6c3a31a8, 0x6d82df50, 0x3d432793,
322 0x4195a297, 0x6bce9b95, 0x3c822af0, 0x7629e5b3,
323 ],
324 ]);
325
326pub const BABYBEAR_POSEIDON2_RC_32_EXTERNAL_FINAL: [[BabyBear; 32]; 4] = BabyBear::new_2d_array([
335 [
336 0x77cc4657, 0x39005c27, 0x48cd8089, 0x267cfcbb, 0x1c41ca85, 0x41b3943f, 0x20e7727a,
337 0x64ad78f3, 0x13dd4413, 0x1042e3dc, 0x74adeb2c, 0x2dcdd3c7, 0x06006fbc, 0x35a609e9,
338 0x0daf273c, 0x3a4f694f, 0x59fd101d, 0x27d2112b, 0x1937b69f, 0x2e8880bc, 0x40c12429,
339 0x067965a6, 0x6ea1b36d, 0x6e01476e, 0x29cd718a, 0x5406c693, 0x51de2e9a, 0x6ddc388a,
340 0x53763473, 0x17a25cbf, 0x1f2982cd, 0x19ca5afd,
341 ],
342 [
343 0x2d703c93, 0x0c2840e4, 0x2cda82cd, 0x5c7f51e0, 0x1db58806, 0x3cb62bd1, 0x2b45461b,
344 0x6204ba50, 0x6857f0bc, 0x4af2a368, 0x32c146f4, 0x1acfdd93, 0x2dc39570, 0x0dbdeb4e,
345 0x50bef84d, 0x6f83a22c, 0x434c3741, 0x2060e160, 0x68f58f0b, 0x2529b2bd, 0x112c4768,
346 0x70409ce2, 0x1b57460e, 0x21dc818c, 0x5f6b5330, 0x443f8fba, 0x211a90de, 0x591d4a30,
347 0x5b5a3e75, 0x635c333a, 0x1efd6a70, 0x5d35445f,
348 ],
349 [
350 0x5637cf22, 0x6e9ba8b1, 0x10b54e2c, 0x04291eb8, 0x2d4ea543, 0x720a5c61, 0x1a5b6323,
351 0x68e176e7, 0x26149775, 0x58f30beb, 0x450402ab, 0x24928255, 0x32c59955, 0x2b5b7261,
352 0x6279779f, 0x599b6a8e, 0x70d145d3, 0x3786c4d1, 0x11363460, 0x22ff2181, 0x4d06fc50,
353 0x27a8a3df, 0x647df984, 0x3a748cc3, 0x4aa91ea2, 0x21ead2a1, 0x50cd5d8d, 0x06d6ffc6,
354 0x5bc51117, 0x45f848bc, 0x12c3d5f1, 0x487f9065,
355 ],
356 [
357 0x1617243c, 0x5c8774e4, 0x76bcd3ec, 0x349c8a4b, 0x265d6a36, 0x39fc652e, 0x246831a8,
358 0x488058fc, 0x0a5c75d6, 0x760d4eed, 0x2d2957ad, 0x6188b6fe, 0x2084c575, 0x67c5ff60,
359 0x3d6d899b, 0x2759464a, 0x1e4319d2, 0x09fef836, 0x305660e4, 0x2437e398, 0x698e8bad,
360 0x51a1c08a, 0x6f6b42ea, 0x4e7a622c, 0x3359b875, 0x6fc9bf1d, 0x349ecd95, 0x402affed,
361 0x0e7d1f4a, 0x7568ff95, 0x6d26f65b, 0x527b8ff5,
362 ],
363]);
364
365pub const BABYBEAR_POSEIDON2_RC_32_INTERNAL: [BabyBear; 30] = BabyBear::new_array([
374 0x3dddd04e, 0x5a3d0558, 0x763e6c75, 0x676f1d88, 0x77b82255, 0x25df8a51, 0x697c3b10, 0x03cf6edf,
375 0x12b54f78, 0x6633d534, 0x426fbcb7, 0x554665dc, 0x5689bdb2, 0x12e747de, 0x60c28745, 0x11ca4ba5,
376 0x3f0f9583, 0x56c7d993, 0x20f6875f, 0x69e597c8, 0x3c911573, 0x29c7f702, 0x1a58e115, 0x29113198,
377 0x776b289f, 0x1e922ee2, 0x2165fbf0, 0x28ccaf78, 0x1983287d, 0x492b22e0,
378]);
379
380pub fn default_babybear_poseidon2_32() -> Poseidon2BabyBear<32> {
382 Poseidon2::new(
383 ExternalLayerConstants::new(
384 BABYBEAR_POSEIDON2_RC_32_EXTERNAL_INITIAL.to_vec(),
385 BABYBEAR_POSEIDON2_RC_32_EXTERNAL_FINAL.to_vec(),
386 ),
387 BABYBEAR_POSEIDON2_RC_32_INTERNAL.to_vec(),
388 )
389}
390
391#[derive(Debug, Clone, Default)]
393pub struct BabyBearInternalLayerParameters;
394
395impl InternalLayerBaseParameters<BabyBearParameters, 16> for BabyBearInternalLayerParameters {
396 fn internal_layer_mat_mul<R: PrimeCharacteristicRing>(state: &mut [R; 16], sum: R) {
399 state[1] += sum.dup();
402 state[2] = state[2].double() + sum.dup();
403 state[3] = state[3].halve() + sum.dup();
404 state[4] = sum.dup() + state[4].double() + state[4].dup();
405 state[5] = sum.dup() + state[5].double().double();
406 state[6] = sum.dup() - state[6].halve();
407 state[7] = sum.dup() - (state[7].double() + state[7].dup());
408 state[8] = sum.dup() - state[8].double().double();
409 state[9] = state[9].div_2exp_u64(8) + sum.dup();
410 state[10] = state[10].div_2exp_u64(2) + sum.dup();
411 state[11] = state[11].div_2exp_u64(3) + sum.dup();
412 state[12] = state[12].div_2exp_u64(27) + sum.dup();
413 state[13] = sum.dup() - state[13].div_2exp_u64(8);
414 state[14] = sum.dup() - state[14].div_2exp_u64(4);
415 state[15] = sum - state[15].div_2exp_u64(27);
416 }
417}
418
419impl InternalLayerBaseParameters<BabyBearParameters, 24> for BabyBearInternalLayerParameters {
420 fn internal_layer_mat_mul<R: PrimeCharacteristicRing>(state: &mut [R; 24], sum: R) {
423 state[1] += sum.dup();
426 state[2] = state[2].double() + sum.dup();
427 state[3] = state[3].halve() + sum.dup();
428 state[4] = sum.dup() + state[4].double() + state[4].dup();
429 state[5] = sum.dup() + state[5].double().double();
430 state[6] = sum.dup() - state[6].halve();
431 state[7] = sum.dup() - (state[7].double() + state[7].dup());
432 state[8] = sum.dup() - state[8].double().double();
433 state[9] = state[9].div_2exp_u64(8) + sum.dup();
434 state[10] = state[10].div_2exp_u64(2) + sum.dup();
435 state[11] = state[11].div_2exp_u64(3) + sum.dup();
436 state[12] = state[12].div_2exp_u64(4) + sum.dup();
437 state[13] = state[13].div_2exp_u64(7) + sum.dup();
438 state[14] = state[14].div_2exp_u64(9) + sum.dup();
439 state[15] = state[15].div_2exp_u64(27) + sum.dup();
440 state[16] = sum.dup() - state[16].div_2exp_u64(8);
441 state[17] = sum.dup() - state[17].div_2exp_u64(2);
442 state[18] = sum.dup() - state[18].div_2exp_u64(3);
443 state[19] = sum.dup() - state[19].div_2exp_u64(4);
444 state[20] = sum.dup() - state[20].div_2exp_u64(5);
445 state[21] = sum.dup() - state[21].div_2exp_u64(6);
446 state[22] = sum.dup() - state[22].div_2exp_u64(7);
447 state[23] = sum - state[23].div_2exp_u64(27);
448 }
449}
450
451impl InternalLayerBaseParameters<BabyBearParameters, 32> for BabyBearInternalLayerParameters {
452 fn internal_layer_mat_mul<R: PrimeCharacteristicRing>(state: &mut [R; 32], sum: R) {
455 state[1] += sum.dup();
460 state[2] = state[2].double() + sum.dup();
461 state[3] = state[3].halve() + sum.dup();
462 state[4] = sum.dup() + state[4].double() + state[4].dup();
463 state[5] = sum.dup() + state[5].double().double();
464 state[6] = sum.dup() - state[6].halve();
465 state[7] = sum.dup() - (state[7].double() + state[7].dup());
466 state[8] = sum.dup() - state[8].double().double();
467 state[9] = state[9].div_2exp_u64(8) + sum.dup();
468 state[10] = state[10].div_2exp_u64(2) + sum.dup();
469 state[11] = state[11].div_2exp_u64(3) + sum.dup();
470 state[12] = state[12].div_2exp_u64(4) + sum.dup();
471 state[13] = state[13].div_2exp_u64(5) + sum.dup();
472 state[14] = state[14].div_2exp_u64(6) + sum.dup();
473 state[15] = state[15].div_2exp_u64(7) + sum.dup();
474 state[16] = state[16].div_2exp_u64(9) + sum.dup();
475 state[17] = state[17].div_2exp_u64(10) + sum.dup();
476 state[18] = state[18].div_2exp_u64(12) + sum.dup();
477 state[19] = state[19].div_2exp_u64(27) + sum.dup();
478 state[20] = sum.dup() - state[20].div_2exp_u64(8);
479 state[21] = sum.dup() - state[21].div_2exp_u64(2);
480 state[22] = sum.dup() - state[22].div_2exp_u64(3);
481 state[23] = sum.dup() - state[23].div_2exp_u64(4);
482 state[24] = sum.dup() - state[24].div_2exp_u64(5);
483 state[25] = sum.dup() - state[25].div_2exp_u64(6);
484 state[26] = sum.dup() - state[26].div_2exp_u64(7);
485 state[27] = sum.dup() - state[27].div_2exp_u64(9);
486 state[28] = sum.dup() - state[28].div_2exp_u64(10);
487 state[29] = sum.dup() - state[29].div_2exp_u64(12);
488 state[30] = sum.dup() - state[30].div_2exp_u64(14);
489 state[31] = sum - state[31].div_2exp_u64(27);
490 }
491}
492
493impl InternalLayerParameters<BabyBearParameters, 16> for BabyBearInternalLayerParameters {}
494impl InternalLayerParameters<BabyBearParameters, 24> for BabyBearInternalLayerParameters {}
495impl InternalLayerParameters<BabyBearParameters, 32> for BabyBearInternalLayerParameters {}
496
497#[cfg(test)]
498mod tests {
499 use p3_symmetric::Permutation;
500 use rand::{RngExt, SeedableRng};
501 use rand_xoshiro::Xoroshiro128Plus;
502
503 use super::*;
504
505 type F = BabyBear;
506
507 #[test]
512 fn test_poseidon2_width_16_random() {
513 let mut input: [F; 16] = BabyBear::new_array([
514 894848333, 1437655012, 1200606629, 1690012884, 71131202, 1749206695, 1717947831,
515 120589055, 19776022, 42382981, 1831865506, 724844064, 171220207, 1299207443, 227047920,
516 1783754913,
517 ]);
518
519 let expected: [F; 16] = BabyBear::new_array([
520 1255099308, 941729227, 93609187, 112406640, 492658670, 1824768948, 812517469,
521 1055381989, 670973674, 1407235524, 891397172, 1003245378, 1381303998, 1564172645,
522 1399931635, 1005462965,
523 ]);
524
525 let mut rng = Xoroshiro128Plus::seed_from_u64(1);
526 let perm = Poseidon2BabyBear::new_from_rng_128(&mut rng);
527
528 perm.permute_mut(&mut input);
529 assert_eq!(input, expected);
530 }
531
532 #[test]
537 fn test_poseidon2_width_24_random() {
538 let mut input: [F; 24] = BabyBear::new_array([
539 886409618, 1327899896, 1902407911, 591953491, 648428576, 1844789031, 1198336108,
540 355597330, 1799586834, 59617783, 790334801, 1968791836, 559272107, 31054313,
541 1042221543, 474748436, 135686258, 263665994, 1962340735, 1741539604, 449439011,
542 1131357108, 50869465, 1589724894,
543 ]);
544
545 let expected: [F; 24] = BabyBear::new_array([
546 249424342, 562262148, 757431114, 354243402, 57767055, 976981973, 1393169022,
547 1774550827, 1527742125, 1019514605, 1776327602, 266236737, 1412355182, 1070239213,
548 426390978, 1775539440, 1527732214, 1101406020, 1417710778, 1699632661, 413672313,
549 820348291, 1067197851, 1669055675,
550 ]);
551
552 let mut rng = Xoroshiro128Plus::seed_from_u64(1);
553 let perm = Poseidon2BabyBear::new_from_rng_128(&mut rng);
554
555 perm.permute_mut(&mut input);
556
557 assert_eq!(input, expected);
558 }
559
560 #[test]
563 fn test_generic_internal_linear_layer_16() {
564 let mut rng = Xoroshiro128Plus::seed_from_u64(1);
565 let mut input1: [F; 16] = rng.random();
566 let mut input2 = input1;
567
568 let part_sum: F = input1[1..].iter().copied().sum();
569 let full_sum = part_sum + input1[0];
570
571 input1[0] = part_sum - input1[0];
572
573 BabyBearInternalLayerParameters::internal_layer_mat_mul(&mut input1, full_sum);
574 BabyBearInternalLayerParameters::generic_internal_linear_layer(&mut input2);
575
576 assert_eq!(input1, input2);
577 }
578
579 #[test]
582 fn test_generic_internal_linear_layer_24() {
583 let mut rng = Xoroshiro128Plus::seed_from_u64(1);
584 let mut input1: [F; 24] = rng.random();
585 let mut input2 = input1;
586
587 let part_sum: F = input1[1..].iter().copied().sum();
588 let full_sum = part_sum + input1[0];
589
590 input1[0] = part_sum - input1[0];
591
592 BabyBearInternalLayerParameters::internal_layer_mat_mul(&mut input1, full_sum);
593 BabyBearInternalLayerParameters::generic_internal_linear_layer(&mut input2);
594
595 assert_eq!(input1, input2);
596 }
597
598 #[test]
599 fn test_default_babybear_poseidon2_width_16() {
600 let mut input: [F; 16] = BabyBear::new_array([
601 894848333, 1437655012, 1200606629, 1690012884, 71131202, 1749206695, 1717947831,
602 120589055, 19776022, 42382981, 1831865506, 724844064, 171220207, 1299207443, 227047920,
603 1783754913,
604 ]);
605
606 let expected: [F; 16] = BabyBear::new_array([
607 516096821, 90309867, 1101817252, 1660784290, 360715097, 1789519026, 1788910906,
608 563338433, 319524748, 1741414159, 1650859320, 894311162, 1121347488, 1692793758,
609 1052633829, 1344246938,
610 ]);
611
612 let perm = default_babybear_poseidon2_16();
613 perm.permute_mut(&mut input);
614
615 assert_eq!(input, expected);
616 }
617
618 #[test]
619 fn test_default_babybear_poseidon2_width_24() {
620 let mut input: [F; 24] = BabyBear::new_array([
621 886409618, 1327899896, 1902407911, 591953491, 648428576, 1844789031, 1198336108,
622 355597330, 1799586834, 59617783, 790334801, 1968791836, 559272107, 31054313,
623 1042221543, 474748436, 135686258, 263665994, 1962340735, 1741539604, 2026927696,
624 449439011, 1131357108, 50869465,
625 ]);
626
627 let expected: [F; 24] = BabyBear::new_array([
628 882297297, 1264077610, 512812497, 782602970, 867738552, 1251075457, 309180082,
629 340784773, 524041877, 351272188, 404451680, 15001466, 322926653, 1773004150,
630 1718440818, 674682955, 1154713225, 1719133502, 324232301, 1005243141, 443371079,
631 268735940, 770060019, 718377682,
632 ]);
633
634 let perm = default_babybear_poseidon2_24();
635 perm.permute_mut(&mut input);
636
637 assert_eq!(input, expected);
638 }
639
640 #[test]
641 fn test_default_babybear_poseidon2_width_32() {
642 let mut input: [F; 32] = BabyBear::new_array([
643 377682961, 1957793603, 980981814, 6565119, 1583211709, 176593168, 1672635515,
644 226854190, 1096634172, 1317773742, 1472230830, 1621534427, 559807320, 1484241910,
645 1847825942, 3491998, 950152427, 1935451636, 275759400, 227625951, 1271142011,
646 1492341973, 1502961189, 147694103, 1939834518, 1449972249, 1822424048, 1518111482,
647 714203295, 383863563, 411489861, 1253612091,
648 ]);
649
650 let expected: [F; 32] = BabyBear::new_array([
651 303440672, 985419733, 780962554, 1395263823, 188752116, 1348917749, 677984158,
652 667170017, 97281439, 178741618, 1770541242, 1894441262, 847173187, 1374453653,
653 1242356754, 1485142795, 1019698843, 334329175, 540395852, 918117757, 1288401072,
654 508687761, 996827321, 1660764537, 546969284, 1848510002, 334793951, 736596659,
655 1928951999, 1444080616, 55017699, 1832626373,
656 ]);
657
658 let perm = default_babybear_poseidon2_32();
659 perm.permute_mut(&mut input);
660
661 assert_eq!(input, expected);
662 }
663
664 #[test]
667 fn test_generic_internal_linear_layer_32() {
668 let mut rng = Xoroshiro128Plus::seed_from_u64(1);
669 let mut input1: [F; 32] = rng.random();
670 let mut input2 = input1;
671
672 let part_sum: F = input1[1..].iter().copied().sum();
673 let full_sum = part_sum + input1[0];
674
675 input1[0] = part_sum - input1[0];
676
677 BabyBearInternalLayerParameters::internal_layer_mat_mul(&mut input1, full_sum);
678 BabyBearInternalLayerParameters::generic_internal_linear_layer(&mut input2);
679
680 assert_eq!(input1, input2);
681 }
682}