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