Skip to main content

binius_field/
packed_aes.rs

1// Copyright 2024-2025 Irreducible Inc.
2// Copyright 2026 The Binius Developers
3
4use crate::{
5	aes_field::AESTowerField8b,
6	arch::{
7		AesInvert1x, AesInvert16x, AesInvert32x, AesInvert64x, AesSquare1x, AesSquare16x,
8		AesSquare32x, AesSquare64x, AesWideMul1x, AesWideMul16x, AesWideMul32x, AesWideMul64x,
9		M128, M256, M512, MulFromWideMul,
10		portable::packed_macros::{portable_macros::*, *},
11	},
12};
13
14define_packed_binary_field!(
15	PackedAESBinaryField1x8b,
16	AESTowerField8b,
17	u8,
18	(MulFromWideMul),
19	(AesSquare1x),
20	(AesInvert1x),
21	(AesWideMul1x)
22);
23define_packed_binary_field!(
24	PackedAESBinaryField16x8b,
25	AESTowerField8b,
26	M128,
27	(MulFromWideMul),
28	(AesSquare16x),
29	(AesInvert16x),
30	(AesWideMul16x)
31);
32define_packed_binary_field!(
33	PackedAESBinaryField32x8b,
34	AESTowerField8b,
35	M256,
36	(MulFromWideMul),
37	(AesSquare32x),
38	(AesInvert32x),
39	(AesWideMul32x)
40);
41define_packed_binary_field!(
42	PackedAESBinaryField64x8b,
43	AESTowerField8b,
44	M512,
45	(MulFromWideMul),
46	(AesSquare64x),
47	(AesInvert64x),
48	(AesWideMul64x)
49);
50
51#[cfg(test)]
52mod test_utils {
53	/// Test if `mult_func` operation is a valid multiply operation on the given values for
54	/// all possible packed fields defined on 8-512 bits.
55	macro_rules! define_multiply_tests {
56		($mult_func:path, $constraint:ty) => {
57			$crate::packed_binary_field::test_utils::define_check_packed_mul!(
58				$mult_func,
59				$constraint
60			);
61
62			proptest! {
63				#[test]
64				fn test_mul_packed_8(a_val in any::<u8>(), b_val in any::<u8>()) {
65					TestMult::<$crate::PackedAESBinaryField1x8b>::test_mul(
66						a_val.into(),
67						b_val.into(),
68					);
69				}
70
71				#[test]
72				fn test_mul_packed_128(a_val in any::<u128>(), b_val in any::<u128>()) {
73					TestMult::<$crate::PackedAESBinaryField16x8b>::test_mul(
74						a_val.into(),
75						b_val.into(),
76					);
77				}
78
79				#[test]
80				fn test_mul_packed_256(a_val in any::<[u128; 2]>(), b_val in any::<[u128; 2]>()) {
81					TestMult::<$crate::PackedAESBinaryField32x8b>::test_mul(
82						a_val.into(),
83						b_val.into(),
84					);
85				}
86
87				#[test]
88				fn test_mul_packed_512(a_val in any::<[u128; 4]>(), b_val in any::<[u128; 4]>()) {
89					TestMult::<$crate::PackedAESBinaryField64x8b>::test_mul(
90						a_val.into(),
91						b_val.into(),
92					);
93				}
94			}
95		};
96	}
97
98	/// Test if `square_func` operation is a valid square operation on the given value for
99	/// all possible packed fields.
100	macro_rules! define_square_tests {
101		($square_func:path, $constraint:ident) => {
102			$crate::packed_binary_field::test_utils::define_check_packed_square!(
103				$square_func,
104				$constraint
105			);
106
107			proptest! {
108				#[test]
109				fn test_square_packed_8(a_val in any::<u8>()) {
110					TestSquare::<$crate::PackedAESBinaryField1x8b>::test_square(a_val.into());
111				}
112
113				#[test]
114				fn test_square_packed_128(a_val in any::<u128>()) {
115					TestSquare::<$crate::PackedAESBinaryField16x8b>::test_square(a_val.into());
116				}
117
118				#[test]
119				fn test_square_packed_256(a_val in any::<[u128; 2]>()) {
120					TestSquare::<$crate::PackedAESBinaryField32x8b>::test_square(a_val.into());
121				}
122
123				#[test]
124				fn test_square_packed_512(a_val in any::<[u128; 4]>()) {
125					TestSquare::<$crate::PackedAESBinaryField64x8b>::test_square(a_val.into());
126				}
127			}
128		};
129	}
130
131	/// Test if `invert_func` operation is a valid invert operation on the given value for
132	/// all possible packed fields.
133	macro_rules! define_invert_tests {
134		($invert_func:path, $constraint:ident) => {
135			$crate::packed_binary_field::test_utils::define_check_packed_inverse!(
136				$invert_func,
137				$constraint
138			);
139
140			proptest! {
141				#[test]
142				fn test_invert_packed_8(a_val in any::<u8>()) {
143					TestSquare::<$crate::PackedAESBinaryField1x8b>::test_invert(a_val.into());
144				}
145
146				#[test]
147				fn test_invert_packed_128(a_val in any::<u128>()) {
148					TestInvert::<$crate::PackedAESBinaryField16x8b>::test_invert(a_val.into());
149				}
150
151				#[test]
152				fn test_invert_packed_256(a_val in any::<[u128; 2]>()) {
153					TestInvert::<$crate::PackedAESBinaryField32x8b>::test_invert(a_val.into());
154				}
155
156				#[test]
157				fn test_invert_packed_512(a_val in any::<[u128; 4]>()) {
158					TestInvert::<$crate::PackedAESBinaryField64x8b>::test_invert(a_val.into());
159				}
160			}
161		};
162	}
163
164	pub(crate) use define_invert_tests;
165	pub(crate) use define_multiply_tests;
166	pub(crate) use define_square_tests;
167}
168
169#[cfg(test)]
170mod tests {
171	use std::ops::Mul;
172
173	use proptest::prelude::*;
174
175	use super::test_utils::{define_invert_tests, define_multiply_tests, define_square_tests};
176	use crate::{
177		PackedField,
178		arithmetic_traits::{InvertOrZero, Square},
179	};
180
181	define_multiply_tests!(Mul::mul, PackedField);
182
183	define_square_tests!(Square::square, PackedField);
184
185	define_invert_tests!(InvertOrZero::invert_or_zero, PackedField);
186}