//! The `mulX_POLYVAL()` function. use crate::Block; /// The `mulX_POLYVAL()` function as defined in [RFC 8452 Appendix A][1]. /// /// Performs a doubling (a.k.a. "multiply by x") over GF(2^128). /// This is useful for implementing GHASH in terms of POLYVAL. /// /// [1]: https://tools.ietf.org/html/rfc8452#appendix-A pub fn mulx(block: &Block) -> Block { let mut v = u128::from_le_bytes((*block).into()); let v_hi = v >> 127; v <<= 1; v ^= v_hi ^ (v_hi << 127) ^ (v_hi << 126) ^ (v_hi << 121); v.to_le_bytes().into() } #[cfg(test)] mod tests { use super::{mulx, Block}; use hex_literal::hex; /// Test vector given in RFC 8452 Appendix A. /// /// NOTE: the vector in the RFC actually contains a typo which has been /// reported (and accepted) as RFC errata, so we use the vector from the /// errata instead: /// /// #[test] fn rfc8452_vector() { let input = Block::from(hex!("9c98c04df9387ded828175a92ba652d8")); let expected_output = Block::from(hex!("3931819bf271fada0503eb52574ca572")); let actual_output = mulx(&input); assert_eq!(expected_output, actual_output); } /// Test against the `MULX_TEST_VECTORS` given below, which cover the full /// size of a POLYVAL field element. #[test] fn mulx_vectors() { // One let mut r = Block::from(hex!("01000000000000000000000000000000")); for vector in MULX_TEST_VECTORS { r = mulx(&r); assert_eq!(&r, Block::from_slice(vector)); } } /// `mulX_POLYVAL()` test vectors. /// /// These were generated by this crate when in a known-correct state, /// verified by a GHASH implementation based on a POLYVAL core successfully /// passing the NIST test vectors. const MULX_TEST_VECTORS: &[[u8; 16]] = &[ hex!("02000000000000000000000000000000"), hex!("04000000000000000000000000000000"), hex!("08000000000000000000000000000000"), hex!("10000000000000000000000000000000"), hex!("20000000000000000000000000000000"), hex!("40000000000000000000000000000000"), hex!("80000000000000000000000000000000"), hex!("00010000000000000000000000000000"), hex!("00020000000000000000000000000000"), hex!("00040000000000000000000000000000"), hex!("00080000000000000000000000000000"), hex!("00100000000000000000000000000000"), hex!("00200000000000000000000000000000"), hex!("00400000000000000000000000000000"), hex!("00800000000000000000000000000000"), hex!("00000100000000000000000000000000"), hex!("00000200000000000000000000000000"), hex!("00000400000000000000000000000000"), hex!("00000800000000000000000000000000"), hex!("00001000000000000000000000000000"), hex!("00002000000000000000000000000000"), hex!("00004000000000000000000000000000"), hex!("00008000000000000000000000000000"), hex!("00000001000000000000000000000000"), hex!("00000002000000000000000000000000"), hex!("00000004000000000000000000000000"), hex!("00000008000000000000000000000000"), hex!("00000010000000000000000000000000"), hex!("00000020000000000000000000000000"), hex!("00000040000000000000000000000000"), hex!("00000080000000000000000000000000"), hex!("00000000010000000000000000000000"), hex!("00000000020000000000000000000000"), hex!("00000000040000000000000000000000"), hex!("00000000080000000000000000000000"), hex!("00000000100000000000000000000000"), hex!("00000000200000000000000000000000"), hex!("00000000400000000000000000000000"), hex!("00000000800000000000000000000000"), hex!("00000000000100000000000000000000"), hex!("00000000000200000000000000000000"), hex!("00000000000400000000000000000000"), hex!("00000000000800000000000000000000"), hex!("00000000001000000000000000000000"), hex!("00000000002000000000000000000000"), hex!("00000000004000000000000000000000"), hex!("00000000008000000000000000000000"), hex!("00000000000001000000000000000000"), hex!("00000000000002000000000000000000"), hex!("00000000000004000000000000000000"), hex!("00000000000008000000000000000000"), hex!("00000000000010000000000000000000"), hex!("00000000000020000000000000000000"), hex!("00000000000040000000000000000000"), hex!("00000000000080000000000000000000"), hex!("00000000000000010000000000000000"), hex!("00000000000000020000000000000000"), hex!("00000000000000040000000000000000"), hex!("00000000000000080000000000000000"), hex!("00000000000000100000000000000000"), hex!("00000000000000200000000000000000"), hex!("00000000000000400000000000000000"), hex!("00000000000000800000000000000000"), hex!("00000000000000000100000000000000"), hex!("00000000000000000200000000000000"), hex!("00000000000000000400000000000000"), hex!("00000000000000000800000000000000"), hex!("00000000000000001000000000000000"), hex!("00000000000000002000000000000000"), hex!("00000000000000004000000000000000"), hex!("00000000000000008000000000000000"), hex!("00000000000000000001000000000000"), hex!("00000000000000000002000000000000"), hex!("00000000000000000004000000000000"), hex!("00000000000000000008000000000000"), hex!("00000000000000000010000000000000"), hex!("00000000000000000020000000000000"), hex!("00000000000000000040000000000000"), hex!("00000000000000000080000000000000"), hex!("00000000000000000000010000000000"), hex!("00000000000000000000020000000000"), hex!("00000000000000000000040000000000"), hex!("00000000000000000000080000000000"), hex!("00000000000000000000100000000000"), hex!("00000000000000000000200000000000"), hex!("00000000000000000000400000000000"), hex!("00000000000000000000800000000000"), hex!("00000000000000000000000100000000"), hex!("00000000000000000000000200000000"), hex!("00000000000000000000000400000000"), hex!("00000000000000000000000800000000"), hex!("00000000000000000000001000000000"), hex!("00000000000000000000002000000000"), hex!("00000000000000000000004000000000"), hex!("00000000000000000000008000000000"), hex!("00000000000000000000000001000000"), hex!("00000000000000000000000002000000"), hex!("00000000000000000000000004000000"), hex!("00000000000000000000000008000000"), hex!("00000000000000000000000010000000"), hex!("00000000000000000000000020000000"), hex!("00000000000000000000000040000000"), hex!("00000000000000000000000080000000"), hex!("00000000000000000000000000010000"), hex!("00000000000000000000000000020000"), hex!("00000000000000000000000000040000"), hex!("00000000000000000000000000080000"), hex!("00000000000000000000000000100000"), hex!("00000000000000000000000000200000"), hex!("00000000000000000000000000400000"), hex!("00000000000000000000000000800000"), hex!("00000000000000000000000000000100"), hex!("00000000000000000000000000000200"), hex!("00000000000000000000000000000400"), hex!("00000000000000000000000000000800"), hex!("00000000000000000000000000001000"), hex!("00000000000000000000000000002000"), hex!("00000000000000000000000000004000"), hex!("00000000000000000000000000008000"), hex!("00000000000000000000000000000001"), hex!("00000000000000000000000000000002"), hex!("00000000000000000000000000000004"), hex!("00000000000000000000000000000008"), hex!("00000000000000000000000000000010"), hex!("00000000000000000000000000000020"), hex!("00000000000000000000000000000040"), hex!("00000000000000000000000000000080"), hex!("010000000000000000000000000000c2"), ]; }