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