binius_field/
packed_ghash.rs1use crate::{
5 Ghash128b,
6 arch::{
7 GhashInvert1x, GhashInvert2x, GhashInvert4x, GhashSquare1x, GhashSquare2x, GhashSquare4x,
8 GhashWideMul1x, GhashWideMul2x, GhashWideMul4x, M128, M256, M512, MulFromWideMul,
9 portable::packed_macros::{portable_macros::*, *},
10 },
11};
12
13define_packed_binary_field!(
14 PackedBinaryGhash1x128b,
15 Ghash128b,
16 M128,
17 (MulFromWideMul),
18 (GhashSquare1x),
19 (GhashInvert1x),
20 (GhashWideMul1x)
21);
22
23define_packed_binary_field!(
24 PackedBinaryGhash2x128b,
25 Ghash128b,
26 M256,
27 (MulFromWideMul),
28 (GhashSquare2x),
29 (GhashInvert2x),
30 (GhashWideMul2x)
31);
32
33define_packed_binary_field!(
34 PackedBinaryGhash4x128b,
35 Ghash128b,
36 M512,
37 (MulFromWideMul),
38 (GhashSquare4x),
39 (GhashInvert4x),
40 (GhashWideMul4x)
41);
42
43#[cfg(test)]
44mod tests {
45 use proptest::{arbitrary::any, proptest};
46
47 use super::*;
48 use crate::{
49 Ghash128b, PackedField, packed_binary_field::test_utils::packed_field_tests,
50 underlier::WithUnderlier,
51 };
52
53 fn check_get_set<const WIDTH: usize, PT>(a: [u128; WIDTH], b: [u128; WIDTH])
54 where
55 PT: PackedField<Scalar = Ghash128b> + WithUnderlier<Underlier: From<[u128; WIDTH]>>,
56 {
57 let mut val = PT::from_underlier(a.into());
58 for i in 0..WIDTH {
59 assert_eq!(val.get(i), Ghash128b::from(a[i]));
60 val.set(i, Ghash128b::from(b[i]));
61 assert_eq!(val.get(i), Ghash128b::from(b[i]));
62 }
63 }
64
65 proptest! {
66 #[test]
67 fn test_get_set_256(a in any::<[u128; 2]>(), b in any::<[u128; 2]>()) {
68 check_get_set::<2, PackedBinaryGhash2x128b>(a, b);
69 }
70
71 #[test]
72 fn test_get_set_512(a in any::<[u128; 4]>(), b in any::<[u128; 4]>()) {
73 check_get_set::<4, PackedBinaryGhash4x128b>(a, b);
74 }
75 }
76
77 packed_field_tests!(ghash_1x128b, PackedBinaryGhash1x128b);
78 packed_field_tests!(ghash_2x128b, PackedBinaryGhash2x128b);
79 packed_field_tests!(ghash_4x128b, PackedBinaryGhash4x128b);
80
81 #[test]
82 fn test_wide_mul_zero_inputs() {
83 use super::PackedBinaryGhash1x128b as P;
84 use crate::{WideMul, field::FieldOps};
85
86 let zero = P::default();
87 let one = P::one();
88
89 assert_eq!(P::reduce(P::wide_mul(zero, zero)), zero);
90 assert_eq!(P::reduce(P::wide_mul(zero, one)), zero);
91 assert_eq!(P::reduce(P::wide_mul(one, zero)), zero);
92 assert_eq!(P::reduce(P::wide_mul(one, one)), one);
93
94 let wide_zero = <P as WideMul>::Output::default();
95 assert_eq!(P::reduce(wide_zero), zero);
96 }
97
98 #[test]
99 fn test_wide_mul_single_accumulation() {
100 use rand::{SeedableRng, rngs::StdRng};
101
102 use super::PackedBinaryGhash1x128b as P;
103 use crate::{Random, WideMul};
104
105 let mut rng = StdRng::seed_from_u64(77);
106 let a = P::random(&mut rng);
107 let b = P::random(&mut rng);
108
109 let wide = P::wide_mul(a, b);
110 let sum = wide + <P as WideMul>::Output::default();
111 assert_eq!(P::reduce(sum), a * b);
112 }
113}