1 //! The `mulX_POLYVAL()` function.
2 
3 use crate::Block;
4 
5 /// The `mulX_POLYVAL()` function as defined in [RFC 8452 Appendix A][1].
6 ///
7 /// Performs a doubling (a.k.a. "multiply by x") over GF(2^128).
8 /// This is useful for implementing GHASH in terms of POLYVAL.
9 ///
10 /// [1]: https://tools.ietf.org/html/rfc8452#appendix-A
mulx(block: &Block) -> Block11 pub fn mulx(block: &Block) -> Block {
12     let mut v = u128::from_le_bytes((*block).into());
13     let v_hi = v >> 127;
14 
15     v <<= 1;
16     v ^= v_hi ^ (v_hi << 127) ^ (v_hi << 126) ^ (v_hi << 121);
17     v.to_le_bytes().into()
18 }
19 
20 #[cfg(test)]
21 mod tests {
22     use super::{mulx, Block};
23     use hex_literal::hex;
24 
25     /// Test vector given in RFC 8452 Appendix A.
26     ///
27     /// NOTE: the vector in the RFC actually contains a typo which has been
28     /// reported (and accepted) as RFC errata, so we use the vector from the
29     /// errata instead:
30     ///
31     /// <https://www.rfc-editor.org/errata_search.php?rfc=8452>
32     #[test]
rfc8452_vector()33     fn rfc8452_vector() {
34         let input = Block::from(hex!("9c98c04df9387ded828175a92ba652d8"));
35         let expected_output = Block::from(hex!("3931819bf271fada0503eb52574ca572"));
36         let actual_output = mulx(&input);
37         assert_eq!(expected_output, actual_output);
38     }
39 
40     /// Test against the `MULX_TEST_VECTORS` given below, which cover the full
41     /// size of a POLYVAL field element.
42     #[test]
mulx_vectors()43     fn mulx_vectors() {
44         // One
45         let mut r = Block::from(hex!("01000000000000000000000000000000"));
46 
47         for vector in MULX_TEST_VECTORS {
48             r = mulx(&r);
49             assert_eq!(&r, Block::from_slice(vector));
50         }
51     }
52 
53     /// `mulX_POLYVAL()` test vectors.
54     ///
55     /// These were generated by this crate when in a known-correct state,
56     /// verified by a GHASH implementation based on a POLYVAL core successfully
57     /// passing the NIST test vectors.
58     const MULX_TEST_VECTORS: &[[u8; 16]] = &[
59         hex!("02000000000000000000000000000000"),
60         hex!("04000000000000000000000000000000"),
61         hex!("08000000000000000000000000000000"),
62         hex!("10000000000000000000000000000000"),
63         hex!("20000000000000000000000000000000"),
64         hex!("40000000000000000000000000000000"),
65         hex!("80000000000000000000000000000000"),
66         hex!("00010000000000000000000000000000"),
67         hex!("00020000000000000000000000000000"),
68         hex!("00040000000000000000000000000000"),
69         hex!("00080000000000000000000000000000"),
70         hex!("00100000000000000000000000000000"),
71         hex!("00200000000000000000000000000000"),
72         hex!("00400000000000000000000000000000"),
73         hex!("00800000000000000000000000000000"),
74         hex!("00000100000000000000000000000000"),
75         hex!("00000200000000000000000000000000"),
76         hex!("00000400000000000000000000000000"),
77         hex!("00000800000000000000000000000000"),
78         hex!("00001000000000000000000000000000"),
79         hex!("00002000000000000000000000000000"),
80         hex!("00004000000000000000000000000000"),
81         hex!("00008000000000000000000000000000"),
82         hex!("00000001000000000000000000000000"),
83         hex!("00000002000000000000000000000000"),
84         hex!("00000004000000000000000000000000"),
85         hex!("00000008000000000000000000000000"),
86         hex!("00000010000000000000000000000000"),
87         hex!("00000020000000000000000000000000"),
88         hex!("00000040000000000000000000000000"),
89         hex!("00000080000000000000000000000000"),
90         hex!("00000000010000000000000000000000"),
91         hex!("00000000020000000000000000000000"),
92         hex!("00000000040000000000000000000000"),
93         hex!("00000000080000000000000000000000"),
94         hex!("00000000100000000000000000000000"),
95         hex!("00000000200000000000000000000000"),
96         hex!("00000000400000000000000000000000"),
97         hex!("00000000800000000000000000000000"),
98         hex!("00000000000100000000000000000000"),
99         hex!("00000000000200000000000000000000"),
100         hex!("00000000000400000000000000000000"),
101         hex!("00000000000800000000000000000000"),
102         hex!("00000000001000000000000000000000"),
103         hex!("00000000002000000000000000000000"),
104         hex!("00000000004000000000000000000000"),
105         hex!("00000000008000000000000000000000"),
106         hex!("00000000000001000000000000000000"),
107         hex!("00000000000002000000000000000000"),
108         hex!("00000000000004000000000000000000"),
109         hex!("00000000000008000000000000000000"),
110         hex!("00000000000010000000000000000000"),
111         hex!("00000000000020000000000000000000"),
112         hex!("00000000000040000000000000000000"),
113         hex!("00000000000080000000000000000000"),
114         hex!("00000000000000010000000000000000"),
115         hex!("00000000000000020000000000000000"),
116         hex!("00000000000000040000000000000000"),
117         hex!("00000000000000080000000000000000"),
118         hex!("00000000000000100000000000000000"),
119         hex!("00000000000000200000000000000000"),
120         hex!("00000000000000400000000000000000"),
121         hex!("00000000000000800000000000000000"),
122         hex!("00000000000000000100000000000000"),
123         hex!("00000000000000000200000000000000"),
124         hex!("00000000000000000400000000000000"),
125         hex!("00000000000000000800000000000000"),
126         hex!("00000000000000001000000000000000"),
127         hex!("00000000000000002000000000000000"),
128         hex!("00000000000000004000000000000000"),
129         hex!("00000000000000008000000000000000"),
130         hex!("00000000000000000001000000000000"),
131         hex!("00000000000000000002000000000000"),
132         hex!("00000000000000000004000000000000"),
133         hex!("00000000000000000008000000000000"),
134         hex!("00000000000000000010000000000000"),
135         hex!("00000000000000000020000000000000"),
136         hex!("00000000000000000040000000000000"),
137         hex!("00000000000000000080000000000000"),
138         hex!("00000000000000000000010000000000"),
139         hex!("00000000000000000000020000000000"),
140         hex!("00000000000000000000040000000000"),
141         hex!("00000000000000000000080000000000"),
142         hex!("00000000000000000000100000000000"),
143         hex!("00000000000000000000200000000000"),
144         hex!("00000000000000000000400000000000"),
145         hex!("00000000000000000000800000000000"),
146         hex!("00000000000000000000000100000000"),
147         hex!("00000000000000000000000200000000"),
148         hex!("00000000000000000000000400000000"),
149         hex!("00000000000000000000000800000000"),
150         hex!("00000000000000000000001000000000"),
151         hex!("00000000000000000000002000000000"),
152         hex!("00000000000000000000004000000000"),
153         hex!("00000000000000000000008000000000"),
154         hex!("00000000000000000000000001000000"),
155         hex!("00000000000000000000000002000000"),
156         hex!("00000000000000000000000004000000"),
157         hex!("00000000000000000000000008000000"),
158         hex!("00000000000000000000000010000000"),
159         hex!("00000000000000000000000020000000"),
160         hex!("00000000000000000000000040000000"),
161         hex!("00000000000000000000000080000000"),
162         hex!("00000000000000000000000000010000"),
163         hex!("00000000000000000000000000020000"),
164         hex!("00000000000000000000000000040000"),
165         hex!("00000000000000000000000000080000"),
166         hex!("00000000000000000000000000100000"),
167         hex!("00000000000000000000000000200000"),
168         hex!("00000000000000000000000000400000"),
169         hex!("00000000000000000000000000800000"),
170         hex!("00000000000000000000000000000100"),
171         hex!("00000000000000000000000000000200"),
172         hex!("00000000000000000000000000000400"),
173         hex!("00000000000000000000000000000800"),
174         hex!("00000000000000000000000000001000"),
175         hex!("00000000000000000000000000002000"),
176         hex!("00000000000000000000000000004000"),
177         hex!("00000000000000000000000000008000"),
178         hex!("00000000000000000000000000000001"),
179         hex!("00000000000000000000000000000002"),
180         hex!("00000000000000000000000000000004"),
181         hex!("00000000000000000000000000000008"),
182         hex!("00000000000000000000000000000010"),
183         hex!("00000000000000000000000000000020"),
184         hex!("00000000000000000000000000000040"),
185         hex!("00000000000000000000000000000080"),
186         hex!("010000000000000000000000000000c2"),
187     ];
188 }
189