1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109
//! **POLYVAL** is a GHASH-like universal hash over GF(2^128) useful for //! implementing [AES-GCM-SIV] or [AES-GCM/GMAC]. //! //! From [RFC 8452 Section 3] which defines POLYVAL for use in AES-GCM-SIV: //! //! > "POLYVAL, like GHASH (the authenticator in AES-GCM; ...), operates in a //! > binary field of size 2^128. The field is defined by the irreducible //! > polynomial x^128 + x^127 + x^126 + x^121 + 1." //! //! By multiplying (in the finite field sense) a sequence of 128-bit blocks of //! input data data by a field element `H`, POLYVAL can be used to authenticate //! the message sequence as powers (in the finite field sense) of `H`. //! //! # Minimum Supported Rust Version //! Rust **1.49** or higher. //! //! In the future the minimum supported Rust version may be changed, but it //! be will be accompanied with a minor version bump. //! //! # Supported backends //! This crate provides multiple backends including a portable pure Rust //! backend as well as ones based on CPU intrinsics. //! //! ## "soft" portable backend //! As a baseline implementation, this crate provides a constant-time pure Rust //! implementation based on [BearSSL], which is a straightforward and //! compact implementation which uses a clever but simple technique to avoid //! carry-spilling. //! //! ## ARMv8 intrinsics (`PMULL`, nightly-only) //! On `aarch64` targets including `aarch64-apple-darwin` (Apple M1) and Linux //! targets such as `aarch64-unknown-linux-gnu` and `aarch64-unknown-linux-musl`, //! support for using the `PMULL` instructions in ARMv8's Cryptography Extensions //! is available when using the nightly compiler, and can be enabled using the //! `armv8` crate feature. //! //! On Linux and macOS, when the `armv8` feature is enabled support for AES //! intrinsics is autodetected at runtime. On other platforms the `crypto` //! target feature must be enabled via RUSTFLAGS. //! //! ## `x86`/`x86_64` intrinsics (`CMLMUL`) //! By default this crate uses runtime detection on `i686`/`x86_64` targets //! in order to determine if `CLMUL` is available, and if it is not, it will //! fallback to using a constant-time software implementation. //! //! For optimal performance, set `target-cpu` in `RUSTFLAGS` to `sandybridge` //! or newer: //! //! Example: //! //! ```text //! $ RUSTFLAGS="-Ctarget-cpu=sandybridge" cargo bench //! ``` //! //! # Relationship to GHASH //! POLYVAL can be thought of as the little endian equivalent of GHASH, which //! affords it a small performance advantage over GHASH when used on little //! endian architectures. //! //! It has also been designed so it can also be used to compute GHASH and with //! it GMAC, the Message Authentication Code (MAC) used by AES-GCM. //! //! From [RFC 8452 Appendix A]: //! //! > "GHASH and POLYVAL both operate in GF(2^128), although with different //! > irreducible polynomials: POLYVAL works modulo x^128 + x^127 + x^126 + //! > x^121 + 1 and GHASH works modulo x^128 + x^7 + x^2 + x + 1. Note //! > that these irreducible polynomials are the 'reverse' of each other." //! //! [AES-GCM-SIV]: https://en.wikipedia.org/wiki/AES-GCM-SIV //! [AES-GCM/GMAC]: https://en.wikipedia.org/wiki/Galois/Counter_Mode //! [BearSSL]: https://www.bearssl.org/constanttime.html#ghash-for-gcm //! [RFC 8452 Section 3]: https://tools.ietf.org/html/rfc8452#section-3 //! [RFC 8452 Appendix A]: https://tools.ietf.org/html/rfc8452#appendix-A #![no_std] #![cfg_attr(docsrs, feature(doc_cfg))] #![cfg_attr( all(feature = "armv8", target_arch = "aarch64"), feature(stdsimd, aarch64_target_feature) )] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg", html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/meta/master/logo.svg" )] #![warn(missing_docs, rust_2018_idioms)] mod backend; mod mulx; pub use crate::{backend::Polyval, mulx::mulx}; pub use universal_hash; opaque_debug::implement!(Polyval); /// Size of a POLYVAL block in bytes pub const BLOCK_SIZE: usize = 16; /// Size of a POLYVAL key in bytes pub const KEY_SIZE: usize = 16; /// POLYVAL keys (16-bytes) pub type Key = universal_hash::Key<Polyval>; /// POLYVAL blocks (16-bytes) pub type Block = universal_hash::Block<Polyval>; /// POLYVAL tags (16-bytes) pub type Tag = universal_hash::Output<Polyval>;