polyval/
mulx.rs

1//! The `mulX_POLYVAL()` function.
2
3use 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
11pub 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)]
21mod 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]
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]
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}