1use binius_field::BinaryField128bGhash as Ghash;
4
5pub const M: usize = 6;
6
7pub const BYTES_PER_GHASH: usize = 16;
8
9pub const NUM_ROUNDS: usize = 8;
10
11pub static B_FWD_COEFFS: [Ghash; 4] = [
12 Ghash::new(0xb0b849b207a0f1c74c29e4d892ca33dd),
13 Ghash::new(0xf2240891aac3c3a5855eeb8ce24c9523),
14 Ghash::new(0xb017e96797ef1fbe9d79908388dd768d),
15 Ghash::new(0x2bf9f0b94c2b2ceb00dbb86a2cb472bb),
16];
17
18pub static B_INV_COEFFS: [Ghash; 1 + 128] = [
19 Ghash::new(0x1d124529af098017d515f025b2107a04),
20 Ghash::new(0xb2733aa187f5954a397b9985012327dc),
21 Ghash::new(0xf9ed22a697f45e3fac28266a3c9c8bf9),
22 Ghash::new(0xb2563578203d5df23ed37df5274f9b62),
23 Ghash::new(0x9f60ca3b6e570f9bb35f672c4cc71e78),
24 Ghash::new(0x2b7839e6c8c6f35c4cfe4dd6ed9988bf),
25 Ghash::new(0xd7e470d53c8a1441335c0e39f8e825ba),
26 Ghash::new(0xc2a0d87c2f6de7f3656d51ee118d93ca),
27 Ghash::new(0xb80cb728430ce418d8763ad073d43c72),
28 Ghash::new(0xf1424d16f8ff5ad20c172fa0bce84a66),
29 Ghash::new(0xf27af010f636dd9d8b47d92989d38c91),
30 Ghash::new(0xeebb7636921fdc8bb35172c4f2904488),
31 Ghash::new(0xf17407875a9069991c532b85716f8278),
32 Ghash::new(0x72032c6e2ef39011b80918ec4884682e),
33 Ghash::new(0xa93dd016787f32dafb792593a1c0664c),
34 Ghash::new(0x2a72f7f35410abe48bf86284d7153568),
35 Ghash::new(0x539206fa82bb0fd3fc257acfd85198cf),
36 Ghash::new(0x6325125ff725e1435f66efa328075c4b),
37 Ghash::new(0x73abb6e9157b3791bc1a05a15a0ba8e2),
38 Ghash::new(0x3447131e361d3a430e26535b49f37884),
39 Ghash::new(0xeeeb383e8b2e366b3b5d33b416320285),
40 Ghash::new(0xa6ef061627c8b7d6b5ea5ddf3b3ceeee),
41 Ghash::new(0x3f97a996898ed33fb4c0b023284209b7),
42 Ghash::new(0xbdf02af9a8b31ed299580c95f214d5a3),
43 Ghash::new(0xfded88f14050f0fc196849074ce0f9ad),
44 Ghash::new(0x6c8b4d18e1ba055c6b631b36bde8d60c),
45 Ghash::new(0x1027cad9488ab75d6741c4f5b9026779),
46 Ghash::new(0x9f1c5193f4762dcadac6b8979fd40e1d),
47 Ghash::new(0x7af3e53f8f00a454d215ee466e50388c),
48 Ghash::new(0x5e3227be2a589427f2870f655f41ef5b),
49 Ghash::new(0xd964ed03293469753b504cb624c60228),
50 Ghash::new(0x43c3a9698d3135080fe4f57716b03036),
51 Ghash::new(0x922b2fb49b13518ec3895e0eb37085b0),
52 Ghash::new(0xaa09df0da87a0fceb212105e5b297b5a),
53 Ghash::new(0x790c7ca5f5905488e82bd9d875c8715a),
54 Ghash::new(0x369411c407a9ef883133bc16aceb21a2),
55 Ghash::new(0xd577819f72b6158c1eca19e57d2e1e95),
56 Ghash::new(0xac4d176698af651f201efd2cfea05ab6),
57 Ghash::new(0x268f4c40a4553eb3a2afbde2b10df863),
58 Ghash::new(0x8749898084983a777debda3686b5e752),
59 Ghash::new(0xc723199815bae544773110e7054256a0),
60 Ghash::new(0x960b23bc674dd468d75ff82b164067b4),
61 Ghash::new(0xb94130b0a65d36009150e505b5e4a818),
62 Ghash::new(0x742b2c52bba058cc8c9a364c0985136b),
63 Ghash::new(0xdf298fbb15e6e58f9edb384f5c34673c),
64 Ghash::new(0x4fdbc95e71fe2bdbcc6bee273caad844),
65 Ghash::new(0x19d487689fe24e3a3eceabdefdcef9e5),
66 Ghash::new(0xb01bf42d575ca9a0df60e3e99d4a4450),
67 Ghash::new(0xe8a777b48d74755f5091a9d460f80660),
68 Ghash::new(0x9f435ce2ff626ba06cb1ee4478a1356f),
69 Ghash::new(0x6804034746f7cca00180116ebfe5b33a),
70 Ghash::new(0xaef4cc5aa39d8f6957c15f9b173601eb),
71 Ghash::new(0x97d15c1e09df82180a062c5268804182),
72 Ghash::new(0x3109fb44aa8caba5fb41f60a49ab9f99),
73 Ghash::new(0x67ff3e7094682c2c7ae9258280b00f7d),
74 Ghash::new(0xbf6a8f87c80acf09f9456b27b9c44a04),
75 Ghash::new(0x4cd2646e793fd4eab1319cb89fb72054),
76 Ghash::new(0x076e92092b1f43709e7b9b2856ed53a9),
77 Ghash::new(0xb987929f99110f41f4f44c08b778e929),
78 Ghash::new(0x09b1c58023e9c9c267451053eed4b989),
79 Ghash::new(0xb27b2fa5789c2749058ebed7e489d0a1),
80 Ghash::new(0xcf9a22da173d17c475c43a59ed45535f),
81 Ghash::new(0x77df29bf03c18bbd103431cf69e35840),
82 Ghash::new(0x2a746d8aec21318be6985ff6dfa5d116),
83 Ghash::new(0x3411ccb789ac3dfc5bbd1c8b967559f6),
84 Ghash::new(0xd6faab5c3e02915dc279b22dbbf81919),
85 Ghash::new(0x2b9a29fd7e4775061fbb90c2033f304d),
86 Ghash::new(0x8a78a5986d399576aade221e1a4a4759),
87 Ghash::new(0x8cc9cb6657270a712b2c776b7f231214),
88 Ghash::new(0xa4206fef28f9fad8b05707b515fa176b),
89 Ghash::new(0x71984ef63a6a49ddefa6b9cb6b8832c4),
90 Ghash::new(0x2347fdcc33e95ee2a1bb2c4edc8da6a9),
91 Ghash::new(0xc63f0aaf33ca8b99a03decedc48b2e94),
92 Ghash::new(0x3237cb90cca2283888cb5729283a8b4d),
93 Ghash::new(0xbe8d8bbd445bf3e3e2947257afff2516),
94 Ghash::new(0xe7524df886b9fd83a2d4bdcfdb252124),
95 Ghash::new(0x6cb5512f7bdd181f675d059cf05799ff),
96 Ghash::new(0xc56e3f62ddedbabb35a200087a5640ce),
97 Ghash::new(0xba0a5c1d5ce94e53f9efb731c6634b44),
98 Ghash::new(0x4280ae86e53b14eb0202f4c147a6d14a),
99 Ghash::new(0xb4dffae679af530c397b2d07ac62d79a),
100 Ghash::new(0xd0311963a7fafcafd3660af96cc461e1),
101 Ghash::new(0x7d4f16aea2ce0d4e4c8c545d4d0040dc),
102 Ghash::new(0xda8304eff41a3ae357f1ec94fe9e062b),
103 Ghash::new(0x1b7c9a9f3666986912070ec52f99f801),
104 Ghash::new(0x004ccc9ddf6ca951f20c1b0ac31fa008),
105 Ghash::new(0x14f6a26f68c0ffd76f8f5fd65aa79542),
106 Ghash::new(0xd31406666953d392634f0e80af43fe0e),
107 Ghash::new(0x020c264e630f8bf516200218fb1d1a0e),
108 Ghash::new(0xdd5a2efdde3cae83465d1315d7af0852),
109 Ghash::new(0x055702e27b6a93676389c452c5e4b41a),
110 Ghash::new(0xc4684448e291abeeaa305e6c0e6af873),
111 Ghash::new(0xd2c1419f07a837e617a10b6ac6d1f275),
112 Ghash::new(0x8c605a36b3ecdd16edfc7c499e550871),
113 Ghash::new(0xe034129a3ccbfd6590ebaa430dcad339),
114 Ghash::new(0x5cb6429235829cdcdfc6a221725c755c),
115 Ghash::new(0x5737eb97111ca259d691ae13f5763345),
116 Ghash::new(0x755cd247d4267e960075f86302a39702),
117 Ghash::new(0xb12a9aa970a91097fa8ad2f2bdfb1b20),
118 Ghash::new(0x0dc789e36c5547c0571e479d7fd9a75f),
119 Ghash::new(0x919900cb8cbe4e756f19ab79df7196ee),
120 Ghash::new(0xbebfc69ba65f89dfecd241385602e25f),
121 Ghash::new(0xcac2967113753aaa7f3d8b4c9df4b9aa),
122 Ghash::new(0xf97eff95e366110b9b47509e730fd04f),
123 Ghash::new(0xf939cdd3b4d28d6f3e30aeb60f0346a0),
124 Ghash::new(0x982a7c68b7e0ae1603e324d5453d2b1d),
125 Ghash::new(0x1a589c0f209aeca97224c0c9db79142b),
126 Ghash::new(0x5219c08df0734e2b98dd90d13bc83d8f),
127 Ghash::new(0x95f1c0b71be50da58a8f752a0724e53b),
128 Ghash::new(0x8c494d44cb21e64e58401414631f3666),
129 Ghash::new(0x07b5f194eaa7cf3c96287d6aaedd3051),
130 Ghash::new(0x12e5008f6b6b3dd1d640a0a72a6c6d42),
131 Ghash::new(0x3329d9133fa80c1e6aba028e9255256c),
132 Ghash::new(0xb859b9f70c7d3da6cb8bc0127316f7ad),
133 Ghash::new(0xc31f1a1e3e98194053a0c5759aba5125),
134 Ghash::new(0x6f7deb6cd260c52090fa62f4b170cc55),
135 Ghash::new(0x991089b8d80963ddcf856990b5b55a89),
136 Ghash::new(0x36ebdacdc017e6cd38a1ccedfa6799d6),
137 Ghash::new(0x6ee345c84ddb46a42c8139c52ef87729),
138 Ghash::new(0x31bc991954d18dfb00a0e9f1c8177027),
139 Ghash::new(0x576056edf9e7f6f349740dffa8adc7d5),
140 Ghash::new(0xd7861327edc091fa6b27b5447b05255e),
141 Ghash::new(0x1ad33492132898f582444df642286e8c),
142 Ghash::new(0xfabef4a4b044b301e6d8a3ed7fd754a2),
143 Ghash::new(0x03dbd4cca837cf33b42622b75fec035a),
144 Ghash::new(0xbb8da06ec7ec3a9c2867a57e2cde5cc6),
145 Ghash::new(0x7f0dfc7829c9ecef117778448e04cc6c),
146 Ghash::new(0x128da4c873150f44e7e43bf88921c090),
147 Ghash::new(0xd9bc6edaf1b4a689ba169b5554228af8),
148];
149
150pub const ROUND_CONSTANTS: [[Ghash; M]; 1 + 2 * NUM_ROUNDS] = [
151 [
152 Ghash::new(0xd0e015190f5e0795f4a1d28234ffdf87),
153 Ghash::new(0x6111731acd9a89f6b93ec3a23ec7681b),
154 Ghash::new(0x15da8de707ee3f3918a34a96728b8d29),
155 Ghash::new(0x2ea920e89fbb13a1ed2a216b1d232bfb),
156 Ghash::new(0x1cac9af051191d2c8ef96344bc8cbd0f),
157 Ghash::new(0x3ceb350e8c2d2f4d4750ab0a854c3a4d),
158 ],
159 [
160 Ghash::new(0xe8e46b76a404c4b9fb9ccc257eebb52c),
161 Ghash::new(0xe12be62f399ab7f6f0d391aa43d111f),
162 Ghash::new(0x8cd24d620049a85e9fca7f1a82b24575),
163 Ghash::new(0x9134196e2a4f6643d720e7e17d5d6155),
164 Ghash::new(0x801a72226c1bb12fc5fa2ca648ab4389),
165 Ghash::new(0xcc930a049d59a9f159eed487b2b1db41),
166 ],
167 [
168 Ghash::new(0x377785252c619dafa7c6f70050db5eba),
169 Ghash::new(0xd8c470279b2f60e703297d3a48f34781),
170 Ghash::new(0x6d07ea9a9e22d6ca035c6f84c216797),
171 Ghash::new(0xc41bfc3f4b22043bca9a33cc6a6aae00),
172 Ghash::new(0x55dcc5f6e50336ed4bcdad6a23bc4a5d),
173 Ghash::new(0xd9642daf0fbb53ee0976778ee009e681),
174 ],
175 [
176 Ghash::new(0xa13280fd8c7d7e2150894cb4a0a0dd96),
177 Ghash::new(0xa4b51297ac45514d432a00dc34c2a8cc),
178 Ghash::new(0x1e45b8cb510bc51faa3dc225cc36dba6),
179 Ghash::new(0x1979585fb152fd8fc6967e9422868fd2),
180 Ghash::new(0x2e04baf1b1566acadc9b1d5b2942c2c8),
181 Ghash::new(0xffd35b46d1c35c53b28522b43b660159),
182 ],
183 [
184 Ghash::new(0xb02df026790e55cc69b823a2b7dfd3ba),
185 Ghash::new(0xec66a8fac8862b2c45843a2b7a9b29af),
186 Ghash::new(0xa9e560ef4d3c0076cf8d6b94bdfb0898),
187 Ghash::new(0xc56e1ed6dea993ece4f564b4ec5a434),
188 Ghash::new(0x60e546921e56307c250f8a0735064af6),
189 Ghash::new(0x85cc8b97f2d3f384866096f91bd627b5),
190 ],
191 [
192 Ghash::new(0x2f936e61dcf44a719ce2d4997752c552),
193 Ghash::new(0xea100b89ea4dbea306104f6cbcaf7730),
194 Ghash::new(0x78ee9d4dde1866f1be20fc5d3225a471),
195 Ghash::new(0xed9364d3d4072597d49449ccdd74196b),
196 Ghash::new(0xc0c48365b28688406b77f700ee0a7a15),
197 Ghash::new(0x3bf2f14a632d1dbc83779737f7f4ca43),
198 ],
199 [
200 Ghash::new(0xf8f790e955a2e979c6268179afd19a9b),
201 Ghash::new(0x2224b54c57b488fcd7a43440a4cbbe97),
202 Ghash::new(0x3b8e1338408771be189ac7c8cbf21463),
203 Ghash::new(0x6547c511c5a77ad2ea728ee6204ac283),
204 Ghash::new(0x753e6ed7ce73c0f1697db0399d9b0973),
205 Ghash::new(0xa99266d737016f4fd16b0f23a838050b),
206 ],
207 [
208 Ghash::new(0xe6ff2ec311c6722e3f60fd9efe1fb28a),
209 Ghash::new(0x28dad9ef1797cd06c15e4e8a1cf0bcdc),
210 Ghash::new(0x44444b925bea2192fe04f2d8854cde64),
211 Ghash::new(0xc53dec23ad61e0db3c2af60fc4f47e7e),
212 Ghash::new(0x484cc2cb23ddfbccd8e90f3143d132d2),
213 Ghash::new(0xf717e5e43240cea2f506653013c41123),
214 ],
215 [
216 Ghash::new(0xd25ab18ab153ac32527e793a74aafa07),
217 Ghash::new(0x8a3ec34a5ef348b7686caffae59ffc9d),
218 Ghash::new(0xc560c870b90f45d21d4607f56ebd7721),
219 Ghash::new(0xe39414d28ca4b425ccf80c31abd8ae2d),
220 Ghash::new(0x9c2a85dcc4048127b435c0199b3b29ff),
221 Ghash::new(0xadaa409205e183e1ac95e6f92f1d43d0),
222 ],
223 [
224 Ghash::new(0xa53431abb1c8ebdad01e00eda12c466b),
225 Ghash::new(0xa66273bde8debca0e822591ab1496b5),
226 Ghash::new(0x72b8bba8b48f2485ac98313e10212a73),
227 Ghash::new(0x48fd620807602baea745b3bd12feca1c),
228 Ghash::new(0xcf4a6a04386ee4222dc8ffc3a4d562e6),
229 Ghash::new(0x96dc648bb3119c91f113d51194a85820),
230 ],
231 [
232 Ghash::new(0x66c470d06e5f7211f98a9c68c1fa17c),
233 Ghash::new(0xc7614b3d5a97fa5f7879a309878a9dd8),
234 Ghash::new(0x53e1050f5bdf4b7eae0195ad35dbaeaa),
235 Ghash::new(0x8385c9ec48e14fd5ec230e8974ab0c65),
236 Ghash::new(0xa977ac08c7e6b5b3e6948d24d81da15),
237 Ghash::new(0x29253ebc78e9261c58cc3140c7581355),
238 ],
239 [
240 Ghash::new(0x5f31289e38eef8ff80e98d29e000ea37),
241 Ghash::new(0x4f8c759141e50d8438f488de2679f820),
242 Ghash::new(0xf4dc8a27ea07f3d4feb34a32e61eaaf2),
243 Ghash::new(0xc8b283172ea7de37ee97b4112ec8e22f),
244 Ghash::new(0xcb13d7b37ba1c466f6094884d3469da2),
245 Ghash::new(0x4bae7acd67ba3de4e5f6b6ea6d4c6bac),
246 ],
247 [
248 Ghash::new(0x3f47078acec655bc33272905c9d750f4),
249 Ghash::new(0xa58fef1654a01bcf630804c8c27910e1),
250 Ghash::new(0x923c97fc1029185b06a109e1be6924c5),
251 Ghash::new(0x2eedb745d45085a746a15c1fb5e2ae1e),
252 Ghash::new(0x144e4497996ff1c99d7a03410a443422),
253 Ghash::new(0x40ec3d5a6112778c8997de4ae7f7d82e),
254 ],
255 [
256 Ghash::new(0x4577e50a3e827e9f3e73893b21e58ced),
257 Ghash::new(0x7a370d0173a2c0541593ed813c4174f8),
258 Ghash::new(0x87394d70d4ae0f6828e7a93875a68b92),
259 Ghash::new(0xc1560cbda08dd31b936373127702c481),
260 Ghash::new(0xf5fee9656ca1bc3c2b813e558d15e83a),
261 Ghash::new(0xeec0f749f981c7f621dceee24b4c0db8),
262 ],
263 [
264 Ghash::new(0x4180e8ff79cda2b4ccb01a124d07a773),
265 Ghash::new(0x6db908873ac7627985498d9d64418458),
266 Ghash::new(0x734a0331ccc7b06a54dc33cb191ff5a6),
267 Ghash::new(0x578e478c6b4d4625d8d5a1a7e99c8a98),
268 Ghash::new(0x1f01a86286bd8078d9143ef0e1bfd6d2),
269 Ghash::new(0x8f831a4d9a0e5685ed3a2ab4ec1492dd),
270 ],
271 [
272 Ghash::new(0x5c3f7446fd05199857a7061949601cae),
273 Ghash::new(0x3c62d0ca7faef4745a8646a4497084d2),
274 Ghash::new(0x5fe18dbc6e5f7ae8bae52881bc87b32b),
275 Ghash::new(0x836cc41840685efc5f821768fa5a7a0b),
276 Ghash::new(0x9fa4c5dca8677c17b3cc1aa5bf35831f),
277 Ghash::new(0x32b3cb0dd6c40e007188d1544c941d02),
278 ],
279 [
280 Ghash::new(0x9ff1ff4417b1c815f9dbff4f62d07ebd),
281 Ghash::new(0x7f0b5b1123fc8a30c3fab6efe18d2f0a),
282 Ghash::new(0xe6f9119237bea8838e7553928d5cbe51),
283 Ghash::new(0x2ed980b39d9ee4af6bda8599ee17f39c),
284 Ghash::new(0x79ee6ad7ccca965879b31429e31f3689),
285 Ghash::new(0x286668e58f3dc1de9369fb0ff898ed83),
286 ],
287];
288
289#[cfg(test)]
290pub mod tests {
291 use binius_field::{Field, Random, arithmetic_traits::Square};
292 use binius_math::batch_invert::BatchInversion;
293 use rand::{SeedableRng, rngs::StdRng};
294
295 use super::{
296 super::{
297 linear_tables::{LINEAR_B_FWD_TABLE, LINEAR_B_INV_TABLE},
298 permutation::{
299 b_fwd_transform, b_inv_transform, constants_add, linearized_transform_scalar,
300 mds_mul, sbox,
301 },
302 },
303 *,
304 };
305
306 pub fn matrix_mul(matrix: &[Ghash; M * M], vector: &[Ghash; M]) -> [Ghash; M] {
307 std::array::from_fn(|i| {
308 matrix[i * M..(i + 1) * M]
310 .iter()
311 .zip(vector.iter())
312 .map(|(&m_ij, &v_j)| m_ij * v_j)
313 .sum()
314 })
315 }
316
317 pub static INITIAL_CONSTANT: [Ghash; M] = [
318 Ghash::new(0xd0e015190f5e0795f4a1d28234ffdf87),
319 Ghash::new(0x6111731acd9a89f6b93ec3a23ec7681b),
320 Ghash::new(0x15da8de707ee3f3918a34a96728b8d29),
321 Ghash::new(0x2ea920e89fbb13a1ed2a216b1d232bfb),
322 Ghash::new(0x1cac9af051191d2c8ef96344bc8cbd0f),
323 Ghash::new(0x3ceb350e8c2d2f4d4750ab0a854c3a4d),
324 ];
325
326 pub static CONSTANTS_MATRIX: [Ghash; M * M] = [
327 Ghash::new(0x09cc78f7eafef94d8e092e899156946b),
328 Ghash::new(0x1d1ad17c8c7ee715a3d58f7eedb30dbb),
329 Ghash::new(0x06bee572113950b3dd0cdae9dff5dfc5),
330 Ghash::new(0x4799c3743a3560428b4bfa1a5cd3d295),
331 Ghash::new(0x516883bf97b07fcf4cb89ac6bf636d0b),
332 Ghash::new(0x0b681d1621d6aa1fdf1a9113b04d755b),
333 Ghash::new(0xe9ba2f01051f6b4b3ddfe74c125e99e5),
334 Ghash::new(0x1f58efc5ecf2e1b933e31cfb26b916d1),
335 Ghash::new(0x36da671249b5444cf67efc573241fe19),
336 Ghash::new(0x056cae18b867d486615a130556e5eb99),
337 Ghash::new(0x1d8645dd4b1e46b78dd9df84956bcf11),
338 Ghash::new(0x3efa34e48e3b218395efe6255339375b),
339 Ghash::new(0x79bf44bae0d2379397d0812db56c5eff),
340 Ghash::new(0x7fb3b7fce84776e39e538151daddae85),
341 Ghash::new(0x0d42981a71a7c2e493ca17e6bb10203f),
342 Ghash::new(0x9ceed672ccb7030fca17ed48e18717b9),
343 Ghash::new(0x0cec5c463024f2ba95c6ecdb4a349d15),
344 Ghash::new(0xa46023576301b995990418f3a23e3c99),
345 Ghash::new(0x6227628fea1dc5465d33ae5d97eb83af),
346 Ghash::new(0x2ef550b7cda1e2856d94bf331473f6f1),
347 Ghash::new(0x375f4232fa7ca41a698bc6ae2e3a8499),
348 Ghash::new(0x2d2f859caba39ed7012b9ab22c303529),
349 Ghash::new(0x5672a0afa29cac300d0bf7b6399257b7),
350 Ghash::new(0xebd30b6903f1fe11f3ae1aee7aa41593),
351 Ghash::new(0x39c54aa0738c373a6f66f0ef2f18bd8d),
352 Ghash::new(0x083a52acda7952eab89afcd0d6a1a9f9),
353 Ghash::new(0x07c782c6beef83babafc31f177df4359),
354 Ghash::new(0x1ed204d4affa05b8e5ca6278e76adc93),
355 Ghash::new(0x5ce4a5c3be5e0bc5a543ee1ec99323cb),
356 Ghash::new(0xd54d1bf8ea15dafe5f49f51af3c2df7),
357 Ghash::new(0x22510fa8fffa288adc4e99bc400b9fa9),
358 Ghash::new(0x78ca292f525f6a68f8135f4f4b2b4491),
359 Ghash::new(0x0ef5f99b1b4a36e979afa9e365bfa159),
360 Ghash::new(0x7a999d6e5f0b133d3a2f3f77630cffa1),
361 Ghash::new(0xb1ae2573d4a15bb6d21d9ad73aef8469),
362 Ghash::new(0x9c348d3213f5a0782535d2146c4869e1),
363 ];
364
365 pub static CONSTANTS_CONSTANT: [Ghash; M] = [
366 Ghash::new(0xabd5e3e6c590952db4ee8dd307ef621f),
367 Ghash::new(0x22681ba7c4bf168c2cf0fc6f51bedceb),
368 Ghash::new(0x41baa8130ac4ddf61a74f42c784257a1),
369 Ghash::new(0x26f2ab43dac65cb011ac77cfb11d7ccd),
370 Ghash::new(0x29218b482b8935fa1552b09907e977e3),
371 Ghash::new(0x1cb764573d0acdfe818a702d07fb9d),
372 ];
373
374 fn compute_round_constants() -> [[Ghash; M]; 1 + 2 * NUM_ROUNDS] {
375 let mut round_keys = [[Ghash::ZERO; M]; 1 + 2 * NUM_ROUNDS];
376 round_keys[0] = INITIAL_CONSTANT;
377
378 let mut key_state = INITIAL_CONSTANT;
379 let mut key_injection = INITIAL_CONSTANT;
380
381 let mut round_key_index = 1;
382 let mut inverter = BatchInversion::<Ghash>::new(M);
383 for _ in 0..NUM_ROUNDS {
384 for transform in [b_inv_transform, b_fwd_transform] {
385 key_injection = matrix_mul(&CONSTANTS_MATRIX, &key_injection);
386 constants_add(&mut key_injection, &CONSTANTS_CONSTANT);
387
388 sbox(&mut key_state, transform, &mut inverter);
389 mds_mul(&mut key_state);
390 constants_add(&mut key_state, &key_injection);
391
392 round_keys[round_key_index] = key_state;
393 round_key_index += 1;
394 }
395 }
396
397 round_keys
398 }
399
400 #[test]
401 fn test_round_constants() {
402 let round_constants = compute_round_constants();
403 assert_eq!(round_constants, ROUND_CONSTANTS);
404 }
405
406 fn evaluate_b_fwd_linear(input: Ghash) -> Ghash {
407 B_FWD_COEFFS[1] * input
409 + B_FWD_COEFFS[2] * input.square()
410 + B_FWD_COEFFS[3] * input.square().square()
411 }
412
413 fn evaluate_b_fwd_affine(input: Ghash) -> Ghash {
414 B_FWD_COEFFS[0] + evaluate_b_fwd_linear(input)
415 }
416
417 fn evaluate_b_inv_linear(input: Ghash) -> Ghash {
418 let mut result = Ghash::ZERO;
419 let mut x_power = input; for i in 0..128 {
424 result += B_INV_COEFFS[i + 1] * x_power;
425 x_power = x_power.square(); }
427
428 result
429 }
430
431 fn evaluate_b_inv_affine(input: Ghash) -> Ghash {
432 B_INV_COEFFS[0] + evaluate_b_inv_linear(input)
433 }
434
435 #[test]
436 fn test_linear_table_consistency() {
437 let mut rng = StdRng::seed_from_u64(0);
438 let input = Ghash::random(&mut rng);
439
440 let mut b_fwd_result = input;
441 linearized_transform_scalar(&mut b_fwd_result, &LINEAR_B_FWD_TABLE);
442 let expected_b_fwd_result = evaluate_b_fwd_linear(input);
443 assert_eq!(b_fwd_result, expected_b_fwd_result);
444
445 let mut b_inv_result = input;
446 linearized_transform_scalar(&mut b_inv_result, &LINEAR_B_INV_TABLE);
447 let expected_b_inv_result = evaluate_b_inv_linear(input);
448 assert_eq!(b_inv_result, expected_b_inv_result);
449 }
450
451 #[test]
452 fn test_b_inverse_coeffs() {
453 let mut rng = StdRng::seed_from_u64(0);
454 let input = Ghash::random(&mut rng);
455
456 let b_result = evaluate_b_fwd_affine(input);
457 let recovered_input = evaluate_b_inv_affine(b_result);
458 assert_eq!(recovered_input, input, "B_inverse verification failed: B_inv(B(x)) != x");
459 }
460}