From 3375792d1672b965136dcf87b298219a68995dd5 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sun, 17 Apr 2022 20:01:08 +0200 Subject: [PATCH 1/3] Migrate to `universal-hash 0.5` This commit just switches to the new traits, and pretends that the ideal number of parallel blocks is 1 (i.e. no faster than before). --- Cargo.lock | 20 +++++++--- ghash/benches/ghash.rs | 2 +- ghash/src/lib.rs | 60 ++++++++++++++++++++++-------- ghash/tests/lib.rs | 7 ++-- poly1305/Cargo.toml | 7 +++- poly1305/benches/poly1305.rs | 2 +- poly1305/src/backend/autodetect.rs | 31 +++++++++------ poly1305/src/backend/avx2.rs | 29 +++++++++++---- poly1305/src/backend/soft.rs | 43 +++++++++++++++++---- poly1305/src/fuzz.rs | 11 ++---- poly1305/src/lib.rs | 28 +++++++------- poly1305/tests/lib.rs | 28 +++++++------- polyval/Cargo.toml | 7 +++- polyval/benches/polyval.rs | 2 +- polyval/src/backend/autodetect.rs | 52 +++++++++++--------------- polyval/src/backend/clmul.rs | 34 ++++++++++------- polyval/src/backend/pmull.rs | 34 ++++++++++------- polyval/src/backend/soft32.rs | 37 ++++++++++++------ polyval/src/backend/soft64.rs | 37 ++++++++++++------ polyval/src/lib.rs | 2 +- polyval/tests/lib.rs | 7 ++-- 21 files changed, 305 insertions(+), 175 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 0cf7b28..497a55c 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -17,6 +17,15 @@ dependencies = [ "libc", ] +[[package]] +name = "crypto-common" +version = "0.1.4" +source = "git+https://github.com/RustCrypto/traits?rev=74ce6e7a9ab1243f574b6c37e747a6e54c01f376#74ce6e7a9ab1243f574b6c37e747a6e54c01f376" +dependencies = [ + "generic-array", + "typenum", +] + [[package]] name = "generic-array" version = "0.14.4" @@ -86,17 +95,16 @@ checksum = "6bdef32e8150c2a081110b42772ffe7d7c9032b606bc226c8260fd97e0976601" [[package]] name = "typenum" -version = "1.13.0" +version = "1.15.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "879f6906492a7cd215bfa4cf595b600146ccfac0c79bcbd1f3000162af5e8b06" +checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "universal-hash" -version = "0.4.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9f214e8f697e925001e66ec2c6e37a4ef93f0f78c2eed7814394e10c62025b05" +version = "0.5.0" +source = "git+https://github.com/RustCrypto/traits?rev=74ce6e7a9ab1243f574b6c37e747a6e54c01f376#74ce6e7a9ab1243f574b6c37e747a6e54c01f376" dependencies = [ - "generic-array", + "crypto-common", "subtle", ] diff --git a/ghash/benches/ghash.rs b/ghash/benches/ghash.rs index 4427b1a..f1a2ee5 100644 --- a/ghash/benches/ghash.rs +++ b/ghash/benches/ghash.rs @@ -3,7 +3,7 @@ extern crate test; use ghash::{ - universal_hash::{NewUniversalHash, UniversalHash}, + universal_hash::{KeyInit, UniversalHash}, GHash, }; use test::Bencher; diff --git a/ghash/src/lib.rs b/ghash/src/lib.rs index 2c8fba2..8521ea3 100644 --- a/ghash/src/lib.rs +++ b/ghash/src/lib.rs @@ -33,7 +33,11 @@ pub use polyval::universal_hash; use polyval::Polyval; -use universal_hash::{consts::U16, NewUniversalHash, UniversalHash}; +use universal_hash::{ + consts::U16, + crypto_common::{BlockSizeUser, KeySizeUser, ParBlocksSizeUser}, + KeyInit, UhfBackend, UhfClosure, UniversalHash, +}; #[cfg(feature = "zeroize")] use zeroize::Zeroize; @@ -45,7 +49,7 @@ pub type Key = universal_hash::Key; pub type Block = universal_hash::Block; /// GHASH tags (16-bytes) -pub type Tag = universal_hash::Output; +pub type Tag = universal_hash::Block; /// **GHASH**: universal hash over GF(2^128) used by AES-GCM. /// @@ -54,9 +58,11 @@ pub type Tag = universal_hash::Output; #[derive(Clone)] pub struct GHash(Polyval); -impl NewUniversalHash for GHash { +impl KeySizeUser for GHash { type KeySize = U16; +} +impl KeyInit for GHash { /// Initialize GHASH with the given `H` field element #[inline] fn new(h: &Key) -> Self { @@ -79,29 +85,51 @@ impl NewUniversalHash for GHash { } } -impl UniversalHash for GHash { - type BlockSize = U16; +struct GHashBackend<'b, B: UhfBackend>(&'b mut B); - /// Input a field element `X` to be authenticated - #[inline] - fn update(&mut self, x: &Block) { - let mut x = *x; +impl<'b, B: UhfBackend> BlockSizeUser for GHashBackend<'b, B> { + type BlockSize = B::BlockSize; +} + +impl<'b, B: UhfBackend> ParBlocksSizeUser for GHashBackend<'b, B> { + type ParBlocksSize = B::ParBlocksSize; +} + +impl<'b, B: UhfBackend> UhfBackend for GHashBackend<'b, B> { + fn proc_block(&mut self, x: &universal_hash::Block) { + let mut x = x.clone(); x.reverse(); - self.0.update(&x); + self.0.proc_block(&x); } +} - /// Reset internal state - #[inline] - fn reset(&mut self) { - self.0.reset(); +impl BlockSizeUser for GHash { + type BlockSize = U16; +} + +impl UniversalHash for GHash { + fn update_with_backend(&mut self, f: impl UhfClosure) { + struct GHashClosure(C); + + impl BlockSizeUser for GHashClosure { + type BlockSize = C::BlockSize; + } + + impl UhfClosure for GHashClosure { + fn call>(self, backend: &mut B) { + self.0.call(&mut GHashBackend(backend)); + } + } + + self.0.update_with_backend(GHashClosure(f)); } /// Get GHASH output #[inline] fn finalize(self) -> Tag { - let mut output = self.0.finalize().into_bytes(); + let mut output = self.0.finalize(); output.reverse(); - Tag::new(output) + output } } diff --git a/ghash/tests/lib.rs b/ghash/tests/lib.rs index 2a4a74d..6490028 100644 --- a/ghash/tests/lib.rs +++ b/ghash/tests/lib.rs @@ -1,5 +1,5 @@ use ghash::{ - universal_hash::{NewUniversalHash, UniversalHash}, + universal_hash::{KeyInit, UniversalHash}, GHash, }; use hex_literal::hex; @@ -19,9 +19,8 @@ const GHASH_RESULT: [u8; 16] = hex!("bd9b3997046731fb96251b91f9c99d7a"); #[test] fn ghash_test_vector() { let mut ghash = GHash::new(&H.into()); - ghash.update(&X_1.into()); - ghash.update(&X_2.into()); + ghash.update(&[X_1.into(), X_2.into()]); let result = ghash.finalize(); - assert_eq!(&GHASH_RESULT[..], result.into_bytes().as_slice()); + assert_eq!(&GHASH_RESULT[..], result.as_slice()); } diff --git a/poly1305/Cargo.toml b/poly1305/Cargo.toml index 3b5d634..22484f2 100644 --- a/poly1305/Cargo.toml +++ b/poly1305/Cargo.toml @@ -14,12 +14,17 @@ edition = "2021" [dependencies] opaque-debug = "0.3" -universal-hash = { version = "0.4", default-features = false } +#universal-hash = { version = "0.5", default-features = false } zeroize = { version = "1", optional = true, default-features = false } [target.'cfg(any(target_arch = "x86_64", target_arch = "x86"))'.dependencies] cpufeatures = "0.2" +[dependencies.universal-hash] +git = "https://github.com/RustCrypto/traits" +rev = "74ce6e7a9ab1243f574b6c37e747a6e54c01f376" +default-features = false + [dev-dependencies] hex-literal = "0.3" diff --git a/poly1305/benches/poly1305.rs b/poly1305/benches/poly1305.rs index a28d8aa..f7981e7 100644 --- a/poly1305/benches/poly1305.rs +++ b/poly1305/benches/poly1305.rs @@ -3,7 +3,7 @@ extern crate test; use poly1305::{ - universal_hash::{NewUniversalHash, UniversalHash}, + universal_hash::{KeyInit, UniversalHash}, Poly1305, }; use test::Bencher; diff --git a/poly1305/src/backend/autodetect.rs b/poly1305/src/backend/autodetect.rs index 5078caf..5f015e6 100644 --- a/poly1305/src/backend/autodetect.rs +++ b/poly1305/src/backend/autodetect.rs @@ -1,6 +1,8 @@ //! Autodetection support for AVX2 CPU intrinsics on x86 CPUs, with fallback //! to the "soft" backend when it's unavailable. +use universal_hash::{consts::U16, crypto_common::BlockSizeUser, UniversalHash}; + use crate::{backend, Block, Key, Tag}; use core::mem::ManuallyDrop; @@ -16,6 +18,10 @@ union Inner { soft: ManuallyDrop, } +impl BlockSizeUser for State { + type BlockSize = U16; +} + impl State { /// Initialize Poly1305 [`State`] with the given key #[inline] @@ -35,33 +41,36 @@ impl State { Self { inner, token } } - /// Reset internal state + /// Compute a Poly1305 block #[inline] - pub(crate) fn reset(&mut self) { + pub(crate) fn compute_block(&mut self, block: &Block, partial: bool) { if self.token.get() { - unsafe { (*self.inner.avx2).reset() } + unsafe { (*self.inner.avx2).compute_block(block, partial) } } else { - unsafe { (*self.inner.soft).reset() } + unsafe { (*self.inner.soft).compute_block(block, partial) } } } +} - /// Compute a Poly1305 block - #[inline] - pub(crate) fn compute_block(&mut self, block: &Block, partial: bool) { +impl UniversalHash for State { + fn update_with_backend( + &mut self, + f: impl universal_hash::UhfClosure, + ) { if self.token.get() { - unsafe { (*self.inner.avx2).compute_block(block, partial) } + unsafe { f.call(&mut *self.inner.avx2) } } else { - unsafe { (*self.inner.soft).compute_block(block, partial) } + unsafe { f.call(&mut *self.inner.soft) } } } /// Finalize output producing a [`Tag`] #[inline] - pub(crate) fn finalize(&mut self) -> Tag { + fn finalize(mut self) -> Tag { if self.token.get() { unsafe { (*self.inner.avx2).finalize() } } else { - unsafe { (*self.inner.soft).finalize() } + unsafe { (*self.inner.soft).finalize_mut() } } } } diff --git a/poly1305/src/backend/avx2.rs b/poly1305/src/backend/avx2.rs index adcc782..f6d9704 100644 --- a/poly1305/src/backend/avx2.rs +++ b/poly1305/src/backend/avx2.rs @@ -15,7 +15,12 @@ // optimisations provided by Bhattacharyya and Sarkar. The latter require the message // length to be known, which is incompatible with the streaming API of UniversalHash. -use universal_hash::generic_array::GenericArray; +use universal_hash::{ + consts::{U1, U16}, + crypto_common::{BlockSizeUser, ParBlocksSizeUser}, + generic_array::GenericArray, + UhfBackend, +}; use crate::{Block, Key, Tag}; @@ -60,12 +65,6 @@ impl State { } } - /// Reset internal state - pub(crate) fn reset(&mut self) { - self.initialized = None; - self.num_cached_blocks = 0; - } - /// Compute a Poly1305 block #[target_feature(enable = "avx2")] pub(crate) unsafe fn compute_block(&mut self, block: &Block, partial: bool) { @@ -152,6 +151,20 @@ impl State { }; tag_int.write(tag.as_mut_slice()); - Tag::new(tag) + tag + } +} + +impl BlockSizeUser for State { + type BlockSize = U16; +} + +impl ParBlocksSizeUser for State { + type ParBlocksSize = U1; +} + +impl UhfBackend for State { + fn proc_block(&mut self, block: &Block) { + unsafe { self.compute_block(block, false) }; } } diff --git a/poly1305/src/backend/soft.rs b/poly1305/src/backend/soft.rs index c31a43f..595ed02 100644 --- a/poly1305/src/backend/soft.rs +++ b/poly1305/src/backend/soft.rs @@ -12,6 +12,12 @@ // ...and was originally a port of Andrew Moons poly1305-donna // https://github.com/floodyberry/poly1305-donna +use universal_hash::{ + consts::{U1, U16}, + crypto_common::{BlockSizeUser, ParBlocksSizeUser}, + UhfBackend, UniversalHash, +}; + use crate::{Block, Key, Tag}; #[derive(Clone, Default)] @@ -41,11 +47,6 @@ impl State { poly } - /// Reset internal state - pub(crate) fn reset(&mut self) { - self.h = Default::default(); - } - /// Compute a Poly1305 block pub(crate) fn compute_block(&mut self, block: &Block, partial: bool) { let hibit = if partial { 0 } else { 1 << 24 }; @@ -139,7 +140,7 @@ impl State { } /// Finalize output producing a [`Tag`] - pub(crate) fn finalize(&mut self) -> Tag { + pub(crate) fn finalize_mut(&mut self) -> Tag { // fully carry h let mut h0 = self.h[0]; let mut h1 = self.h[1]; @@ -227,7 +228,7 @@ impl State { tag[8..12].copy_from_slice(&h2.to_le_bytes()); tag[12..16].copy_from_slice(&h3.to_le_bytes()); - Tag::new(tag) + tag } } @@ -240,3 +241,31 @@ impl Drop for State { self.pad.zeroize(); } } + +impl BlockSizeUser for State { + type BlockSize = U16; +} + +impl ParBlocksSizeUser for State { + type ParBlocksSize = U1; +} + +impl UhfBackend for State { + fn proc_block(&mut self, block: &Block) { + self.compute_block(block, false); + } +} + +impl UniversalHash for State { + fn update_with_backend( + &mut self, + f: impl universal_hash::UhfClosure, + ) { + f.call(self); + } + + /// Finalize output producing a [`Tag`] + fn finalize(mut self) -> Tag { + self.finalize_mut() + } +} diff --git a/poly1305/src/fuzz.rs b/poly1305/src/fuzz.rs index fa5777b..f4ee91e 100644 --- a/poly1305/src/fuzz.rs +++ b/poly1305/src/fuzz.rs @@ -1,4 +1,4 @@ -use universal_hash::generic_array::GenericArray; +use universal_hash::{generic_array::GenericArray, UniversalHash}; use crate::{backend, Block, Key, BLOCK_SIZE}; @@ -29,15 +29,12 @@ pub fn fuzz_avx2(key: &Key, data: &[u8]) { // When fuzzing, we skip this check, and just look at the end. #[cfg(test)] assert_eq!( - (_i + 1, unsafe { avx2.clone().finalize().into_bytes() }), - (_i + 1, soft.clone().finalize().into_bytes()), + (_i + 1, unsafe { avx2.clone().finalize() }), + (_i + 1, soft.clone().finalize()), ); } - assert_eq!( - unsafe { avx2.finalize().into_bytes() }, - soft.finalize().into_bytes() - ); + assert_eq!(unsafe { avx2.finalize() }, soft.finalize()); } fn avx2_fuzzer_test_case(data: &[u8]) { diff --git a/poly1305/src/lib.rs b/poly1305/src/lib.rs index 8c9940b..2696882 100644 --- a/poly1305/src/lib.rs +++ b/poly1305/src/lib.rs @@ -56,8 +56,9 @@ pub use universal_hash; use universal_hash::{ consts::{U16, U32}, + crypto_common::{BlockSizeUser, KeySizeUser}, generic_array::GenericArray, - NewUniversalHash, UniversalHash, + KeyInit, UniversalHash, }; mod backend; @@ -95,7 +96,7 @@ pub type Key = universal_hash::Key; pub type Block = universal_hash::Block; /// Poly1305 tags (16-bytes) -pub type Tag = universal_hash::Output; +pub type Tag = universal_hash::Block; /// The Poly1305 universal hash function. /// @@ -108,9 +109,11 @@ pub struct Poly1305 { state: State, } -impl NewUniversalHash for Poly1305 { +impl KeySizeUser for Poly1305 { type KeySize = U32; +} +impl KeyInit for Poly1305 { /// Initialize Poly1305 with the given key fn new(key: &Key) -> Poly1305 { Poly1305 { @@ -119,21 +122,20 @@ impl NewUniversalHash for Poly1305 { } } -impl UniversalHash for Poly1305 { +impl BlockSizeUser for Poly1305 { type BlockSize = U16; +} - /// Input data into the Poly1305 universal hash function - fn update(&mut self, block: &Block) { - self.state.compute_block(block, false); - } - - /// Reset internal state - fn reset(&mut self) { - self.state.reset(); +impl UniversalHash for Poly1305 { + fn update_with_backend( + &mut self, + f: impl universal_hash::UhfClosure, + ) { + self.state.update_with_backend(f); } /// Get the hashed output - fn finalize(mut self) -> Tag { + fn finalize(self) -> Tag { self.state.finalize() } } diff --git a/poly1305/tests/lib.rs b/poly1305/tests/lib.rs index 2d531f4..7877763 100644 --- a/poly1305/tests/lib.rs +++ b/poly1305/tests/lib.rs @@ -1,7 +1,7 @@ use hex_literal::hex; use poly1305::{ - universal_hash::{NewUniversalHash, UniversalHash}, - Poly1305, BLOCK_SIZE, KEY_SIZE, + universal_hash::{KeyInit, UniversalHash}, + Block, Poly1305, BLOCK_SIZE, KEY_SIZE, }; use std::iter::repeat; @@ -24,7 +24,7 @@ fn test_nacl_vector() { let expected = hex!("f3ffc7703f9400e52a7dfb4b3d3305d9"); let result1 = Poly1305::new(key.as_ref().into()).compute_unpadded(&msg); - assert_eq!(&expected[..], result1.into_bytes().as_slice()); + assert_eq!(&expected[..], result1.as_slice()); } #[test] @@ -43,8 +43,8 @@ fn donna_self_test1() { let expected = hex!("03000000000000000000000000000000"); let mut poly = Poly1305::new(key.as_ref().into()); - poly.update(msg.as_ref().into()); - assert_eq!(&expected[..], poly.finalize().into_bytes().as_slice()); + poly.update(&[Block::clone_from_slice(msg.as_ref())]); + assert_eq!(&expected[..], poly.finalize().as_slice()); } #[test] @@ -60,10 +60,10 @@ fn donna_self_test2() { let msg: Vec = repeat(i as u8).take(256).collect(); let tag = Poly1305::new(key.as_ref().into()).compute_unpadded(&msg[..i]); - tpoly.update(&tag.into_bytes()); + tpoly.update(&[tag.into()]); } - assert_eq!(&total_mac[..], tpoly.finalize().into_bytes().as_slice()); + assert_eq!(&total_mac[..], tpoly.finalize().as_slice()); } #[test] @@ -75,11 +75,13 @@ fn test_tls_vectors() { let mut poly = Poly1305::new(key.as_ref().into()); - for chunk in msg.chunks(BLOCK_SIZE) { - poly.update(chunk.into()); - } + let blocks = msg + .chunks(BLOCK_SIZE) + .map(|chunk| Block::clone_from_slice(chunk)) + .collect::>(); + poly.update(&blocks); - assert_eq!(&expected[..], poly.finalize().into_bytes().as_slice()); + assert_eq!(&expected[..], poly.finalize().as_slice()); } #[test] @@ -90,7 +92,7 @@ fn test_rfc7539_vector() { let expected = hex!("a8061dc1305136c6c22b8baf0c0127a9"); let result = Poly1305::new(key.as_ref().into()).compute_unpadded(&msg); - assert_eq!(&expected[..], result.into_bytes().as_slice()); + assert_eq!(&expected[..], result.as_slice()); } #[test] @@ -102,5 +104,5 @@ fn padded_input() { let mut poly = Poly1305::new(key.as_ref().into()); poly.update_padded(&msg); - assert_eq!(&expected[..], poly.finalize().into_bytes().as_slice()); + assert_eq!(&expected[..], poly.finalize().as_slice()); } diff --git a/polyval/Cargo.toml b/polyval/Cargo.toml index 3f311f6..c84725c 100644 --- a/polyval/Cargo.toml +++ b/polyval/Cargo.toml @@ -18,12 +18,17 @@ edition = "2021" [dependencies] cfg-if = "1" opaque-debug = "0.3" -universal-hash = { version = "0.4", default-features = false } +#universal-hash = { version = "0.5", default-features = false } zeroize = { version = "1", optional = true, default-features = false } [target.'cfg(any(target_arch = "aarch64", target_arch = "x86_64", target_arch = "x86"))'.dependencies] cpufeatures = "0.2" +[dependencies.universal-hash] +git = "https://github.com/RustCrypto/traits" +rev = "74ce6e7a9ab1243f574b6c37e747a6e54c01f376" +default-features = false + [dev-dependencies] hex-literal = "0.3" diff --git a/polyval/benches/polyval.rs b/polyval/benches/polyval.rs index 2a9a951..11b2c58 100644 --- a/polyval/benches/polyval.rs +++ b/polyval/benches/polyval.rs @@ -3,7 +3,7 @@ extern crate test; use polyval::{ - universal_hash::{NewUniversalHash, UniversalHash}, + universal_hash::{KeyInit, UniversalHash}, Polyval, }; use test::Bencher; diff --git a/polyval/src/backend/autodetect.rs b/polyval/src/backend/autodetect.rs index 9cee2ae..d70e7fa 100644 --- a/polyval/src/backend/autodetect.rs +++ b/polyval/src/backend/autodetect.rs @@ -1,9 +1,13 @@ //! Autodetection for CPU intrinsics, with fallback to the "soft" backend when //! they are unavailable. -use crate::{backend::soft, Block, Key}; +use crate::{backend::soft, Key, Tag}; use core::mem::ManuallyDrop; -use universal_hash::{consts::U16, NewUniversalHash, Output, UniversalHash}; +use universal_hash::{ + consts::U16, + crypto_common::{BlockSizeUser, KeySizeUser}, + KeyInit, UniversalHash, +}; #[cfg(all(target_arch = "aarch64", feature = "armv8"))] use super::pmull as intrinsics; @@ -28,9 +32,11 @@ union Inner { soft: ManuallyDrop, } -impl NewUniversalHash for Polyval { +impl KeySizeUser for Polyval { type KeySize = U16; +} +impl KeyInit for Polyval { /// Initialize POLYVAL with the given `H` field element fn new(h: &Key) -> Self { let (token, has_intrinsics) = mul_intrinsics::init_get(); @@ -49,45 +55,31 @@ impl NewUniversalHash for Polyval { } } -impl UniversalHash for Polyval { +impl BlockSizeUser for Polyval { type BlockSize = U16; +} - /// Input a field element `X` to be authenticated - #[inline] - fn update(&mut self, x: &Block) { - if self.token.get() { - unsafe { (*self.inner.intrinsics).update(x) } - } else { - unsafe { (*self.inner.soft).update(x) } - } - } - - /// Reset internal state - fn reset(&mut self) { +impl UniversalHash for Polyval { + fn update_with_backend( + &mut self, + f: impl universal_hash::UhfClosure, + ) { if self.token.get() { - unsafe { (*self.inner.intrinsics).reset() } + unsafe { f.call(&mut *self.inner.intrinsics) } } else { - unsafe { (*self.inner.soft).reset() } + unsafe { f.call(&mut *self.inner.soft) } } } /// Get POLYVAL result (i.e. computed `S` field element) - fn finalize(self) -> Output { + fn finalize(self) -> Tag { let output_bytes = if self.token.get() { - unsafe { - ManuallyDrop::into_inner(self.inner.intrinsics) - .finalize() - .into_bytes() - } + unsafe { ManuallyDrop::into_inner(self.inner.intrinsics).finalize() } } else { - unsafe { - ManuallyDrop::into_inner(self.inner.soft) - .finalize() - .into_bytes() - } + unsafe { ManuallyDrop::into_inner(self.inner.soft).finalize() } }; - Output::new(output_bytes) + output_bytes } } diff --git a/polyval/src/backend/clmul.rs b/polyval/src/backend/clmul.rs index df20cd1..bbfea86 100644 --- a/polyval/src/backend/clmul.rs +++ b/polyval/src/backend/clmul.rs @@ -1,8 +1,12 @@ //! Intel `CLMUL`-accelerated implementation for modern x86/x86_64 CPUs //! (i.e. Intel Sandy Bridge-compatible or newer) -use crate::{Block, Key}; -use universal_hash::{consts::U16, NewUniversalHash, Output, UniversalHash}; +use crate::{Block, Key, Tag}; +use universal_hash::{ + consts::{U1, U16}, + crypto_common::{BlockSizeUser, KeySizeUser, ParBlocksSizeUser}, + KeyInit, UhfBackend, +}; #[cfg(target_arch = "x86")] use core::arch::x86::*; @@ -16,9 +20,11 @@ pub struct Polyval { y: __m128i, } -impl NewUniversalHash for Polyval { +impl KeySizeUser for Polyval { type KeySize = U16; +} +impl KeyInit for Polyval { /// Initialize POLYVAL with the given `H` field element fn new(h: &Key) -> Self { unsafe { @@ -32,25 +38,25 @@ impl NewUniversalHash for Polyval { } } -impl UniversalHash for Polyval { +impl BlockSizeUser for Polyval { type BlockSize = U16; +} - #[inline] - fn update(&mut self, x: &Block) { - unsafe { - self.mul(x); - } - } +impl ParBlocksSizeUser for Polyval { + type ParBlocksSize = U1; +} - /// Reset internal state - fn reset(&mut self) { +impl UhfBackend for Polyval { + fn proc_block(&mut self, x: &Block) { unsafe { - self.y = _mm_setzero_si128(); + self.mul(x); } } +} +impl Polyval { /// Get GHASH output - fn finalize(self) -> Output { + pub(crate) fn finalize(self) -> Tag { unsafe { core::mem::transmute(self.y) } } } diff --git a/polyval/src/backend/pmull.rs b/polyval/src/backend/pmull.rs index 01d3626..cbdcf1b 100644 --- a/polyval/src/backend/pmull.rs +++ b/polyval/src/backend/pmull.rs @@ -11,9 +11,13 @@ //! - //! - -use crate::{Block, Key}; +use crate::{Block, Key, Tag}; use core::{arch::aarch64::*, mem}; -use universal_hash::{consts::U16, NewUniversalHash, Output, UniversalHash}; +use universal_hash::{ + consts::{U1, U16}, + crypto_common::{BlockSizeUser, KeySizeUser, ParBlocksSizeUser}, + KeyInit, UhfBackend, +}; /// **POLYVAL**: GHASH-like universal hash over GF(2^128). #[derive(Clone)] @@ -22,9 +26,11 @@ pub struct Polyval { y: uint8x16_t, } -impl NewUniversalHash for Polyval { +impl KeySizeUser for Polyval { type KeySize = U16; +} +impl KeyInit for Polyval { /// Initialize POLYVAL with the given `H` field element fn new(h: &Key) -> Self { unsafe { @@ -36,25 +42,25 @@ impl NewUniversalHash for Polyval { } } -impl UniversalHash for Polyval { +impl BlockSizeUser for Polyval { type BlockSize = U16; +} - #[inline] - fn update(&mut self, x: &Block) { - unsafe { - self.mul(x); - } - } +impl ParBlocksSizeUser for Polyval { + type ParBlocksSize = U1; +} - /// Reset internal state - fn reset(&mut self) { +impl UhfBackend for Polyval { + fn proc_block(&mut self, x: &Block) { unsafe { - self.y = vdupq_n_u8(0); + self.mul(x); } } +} +impl Polyval { /// Get GHASH output - fn finalize(self) -> Output { + pub(crate) fn finalize(self) -> Tag { unsafe { mem::transmute(self.y) } } } diff --git a/polyval/src/backend/soft32.rs b/polyval/src/backend/soft32.rs index 709596f..d963505 100644 --- a/polyval/src/backend/soft32.rs +++ b/polyval/src/backend/soft32.rs @@ -25,12 +25,16 @@ //! In other words, if we bit-reverse (over 32 bits) the operands, then we //! bit-reverse (over 64 bits) the result. -use crate::{Block, Key}; +use crate::{Block, Key, Tag}; use core::{ num::Wrapping, ops::{Add, Mul}, }; -use universal_hash::{consts::U16, NewUniversalHash, Output, UniversalHash}; +use universal_hash::{ + consts::{U1, U16}, + crypto_common::{BlockSizeUser, KeySizeUser, ParBlocksSizeUser}, + KeyInit, UhfBackend, UniversalHash, +}; #[cfg(feature = "zeroize")] use zeroize::Zeroize; @@ -45,9 +49,11 @@ pub struct Polyval { s: U32x4, } -impl NewUniversalHash for Polyval { +impl KeySizeUser for Polyval { type KeySize = U16; +} +impl KeyInit for Polyval { /// Initialize POLYVAL with the given `H` field element fn new(h: &Key) -> Self { Self { @@ -57,22 +63,31 @@ impl NewUniversalHash for Polyval { } } -impl UniversalHash for Polyval { +impl BlockSizeUser for Polyval { type BlockSize = U16; +} - /// Input a field element `X` to be authenticated - fn update(&mut self, x: &Block) { +impl ParBlocksSizeUser for Polyval { + type ParBlocksSize = U1; +} + +impl UhfBackend for Polyval { + fn proc_block(&mut self, x: &Block) { let x = U32x4::from(x); self.s = (self.s + x) * self.h; } +} - /// Reset internal state - fn reset(&mut self) { - self.s = U32x4::default(); +impl UniversalHash for Polyval { + fn update_with_backend( + &mut self, + f: impl universal_hash::UhfClosure, + ) { + f.call(self); } /// Get POLYVAL result (i.e. computed `S` field element) - fn finalize(self) -> Output { + fn finalize(self) -> Tag { let mut block = Block::default(); for (chunk, i) in block @@ -82,7 +97,7 @@ impl UniversalHash for Polyval { chunk.copy_from_slice(&i.to_le_bytes()); } - Output::new(block) + block } } diff --git a/polyval/src/backend/soft64.rs b/polyval/src/backend/soft64.rs index a043b51..9ae1c8a 100644 --- a/polyval/src/backend/soft64.rs +++ b/polyval/src/backend/soft64.rs @@ -5,12 +5,16 @@ //! //! Copyright (c) 2016 Thomas Pornin -use crate::{Block, Key}; +use crate::{Block, Key, Tag}; use core::{ num::Wrapping, ops::{Add, Mul}, }; -use universal_hash::{consts::U16, NewUniversalHash, Output, UniversalHash}; +use universal_hash::{ + consts::{U1, U16}, + crypto_common::{BlockSizeUser, KeySizeUser, ParBlocksSizeUser}, + KeyInit, UhfBackend, UniversalHash, +}; #[cfg(feature = "zeroize")] use zeroize::Zeroize; @@ -25,9 +29,11 @@ pub struct Polyval { s: U64x2, } -impl NewUniversalHash for Polyval { +impl KeySizeUser for Polyval { type KeySize = U16; +} +impl KeyInit for Polyval { /// Initialize POLYVAL with the given `H` field element fn new(h: &Key) -> Self { Self { @@ -37,29 +43,38 @@ impl NewUniversalHash for Polyval { } } -impl UniversalHash for Polyval { +impl BlockSizeUser for Polyval { type BlockSize = U16; +} - /// Input a field element `X` to be authenticated - fn update(&mut self, x: &Block) { +impl ParBlocksSizeUser for Polyval { + type ParBlocksSize = U1; +} + +impl UhfBackend for Polyval { + fn proc_block(&mut self, x: &Block) { let x = U64x2::from(x); self.s = (self.s + x) * self.h; } +} - /// Reset internal state - fn reset(&mut self) { - self.s = U64x2::default(); +impl UniversalHash for Polyval { + fn update_with_backend( + &mut self, + f: impl universal_hash::UhfClosure, + ) { + f.call(self); } /// Get POLYVAL result (i.e. computed `S` field element) - fn finalize(self) -> Output { + fn finalize(self) -> Tag { let mut block = Block::default(); for (chunk, i) in block.chunks_mut(8).zip(&[self.s.0, self.s.1]) { chunk.copy_from_slice(&i.to_le_bytes()); } - Output::new(block) + block } } diff --git a/polyval/src/lib.rs b/polyval/src/lib.rs index 420013a..9ae90d3 100644 --- a/polyval/src/lib.rs +++ b/polyval/src/lib.rs @@ -104,4 +104,4 @@ pub type Key = universal_hash::Key; pub type Block = universal_hash::Block; /// POLYVAL tags (16-bytes) -pub type Tag = universal_hash::Output; +pub type Tag = universal_hash::Block; diff --git a/polyval/tests/lib.rs b/polyval/tests/lib.rs index fdb98d2..adfadb5 100644 --- a/polyval/tests/lib.rs +++ b/polyval/tests/lib.rs @@ -1,6 +1,6 @@ use hex_literal::hex; use polyval::{ - universal_hash::{NewUniversalHash, UniversalHash}, + universal_hash::{KeyInit, UniversalHash}, Polyval, BLOCK_SIZE, }; @@ -19,9 +19,8 @@ const POLYVAL_RESULT: [u8; BLOCK_SIZE] = hex!("f7a3b47b846119fae5b7866cf5e5b77e" #[test] fn polyval_test_vector() { let mut poly = Polyval::new(&H.into()); - poly.update(&X_1.into()); - poly.update(&X_2.into()); + poly.update(&[X_1.into(), X_2.into()]); let result = poly.finalize(); - assert_eq!(&POLYVAL_RESULT[..], result.into_bytes().as_slice()); + assert_eq!(&POLYVAL_RESULT[..], result.as_slice()); } From 2d315ab548e02dbe8df112f3f3092e37718258f4 Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Sun, 17 Apr 2022 21:39:32 +0200 Subject: [PATCH 2/3] poly1305: Expose 4-block processing on the AVX2 backend If the Poly1305 state is unaligned (a previous update left the AVX2 backend with 1-3 cached blocks), this falls back to the single-block API that incurs an additional copy per block. --- poly1305/src/backend/avx2.rs | 39 ++++++++++++++++++++++++---- poly1305/src/backend/avx2/helpers.rs | 34 +++++++++++++++++++----- 2 files changed, 61 insertions(+), 12 deletions(-) diff --git a/poly1305/src/backend/avx2.rs b/poly1305/src/backend/avx2.rs index f6d9704..f1783f4 100644 --- a/poly1305/src/backend/avx2.rs +++ b/poly1305/src/backend/avx2.rs @@ -16,7 +16,7 @@ // length to be known, which is incompatible with the streaming API of UniversalHash. use universal_hash::{ - consts::{U1, U16}, + consts::{U16, U4}, crypto_common::{BlockSizeUser, ParBlocksSizeUser}, generic_array::GenericArray, UhfBackend, @@ -27,6 +27,9 @@ use crate::{Block, Key, Tag}; mod helpers; use self::helpers::*; +/// Four Poly1305 blocks (64-bytes) +type ParBlocks = universal_hash::ParBlocks; + #[derive(Copy, Clone)] struct Initialized { p: Aligned4x130, @@ -65,6 +68,15 @@ impl State { } } + /// Process four Poly1305 blocks at once. + #[target_feature(enable = "avx2")] + pub(crate) unsafe fn compute_par_blocks(&mut self, blocks: &ParBlocks) { + assert!(self.partial_block.is_none()); + assert_eq!(self.num_cached_blocks, 0); + + self.process_blocks(Aligned4x130::from_par_blocks(blocks)); + } + /// Compute a Poly1305 block #[target_feature(enable = "avx2")] pub(crate) unsafe fn compute_block(&mut self, block: &Block, partial: bool) { @@ -83,13 +95,18 @@ impl State { self.num_cached_blocks = 0; } + self.process_blocks(Aligned4x130::from_blocks(&self.cached_blocks)); + } + + /// Compute a Poly1305 block + #[target_feature(enable = "avx2")] + unsafe fn process_blocks(&mut self, blocks: Aligned4x130) { if let Some(inner) = &mut self.initialized { // P <-- R^4 * P + blocks - inner.p = - (&inner.p * inner.r4).reduce() + Aligned4x130::from_blocks(&self.cached_blocks); + inner.p = (&inner.p * inner.r4).reduce() + blocks; } else { // Initialize the polynomial. - let p = Aligned4x130::from_blocks(&self.cached_blocks); + let p = blocks; // Initialize the multiplier (used to merge down the polynomial during // finalization). @@ -160,11 +177,23 @@ impl BlockSizeUser for State { } impl ParBlocksSizeUser for State { - type ParBlocksSize = U1; + type ParBlocksSize = U4; } impl UhfBackend for State { fn proc_block(&mut self, block: &Block) { unsafe { self.compute_block(block, false) }; } + + fn proc_par_blocks(&mut self, blocks: &ParBlocks) { + if self.num_cached_blocks == 0 { + // Fast path. + unsafe { self.compute_par_blocks(blocks) }; + } else { + // We are unaligned; use the slow fallback. + for block in blocks { + self.proc_block(block); + } + } + } } diff --git a/poly1305/src/backend/avx2/helpers.rs b/poly1305/src/backend/avx2/helpers.rs index ca30b9c..dc92bcf 100644 --- a/poly1305/src/backend/avx2/helpers.rs +++ b/poly1305/src/backend/avx2/helpers.rs @@ -8,6 +8,7 @@ use core::arch::x86::*; #[cfg(target_arch = "x86_64")] use core::arch::x86_64::*; +use super::ParBlocks; use crate::{Block, Key}; const fn set02(x3: u8, x2: u8, x1: u8, x0: u8) -> i32 { @@ -964,15 +965,37 @@ impl Aligned4x130 { /// Panics if `src.len() < 64`. #[target_feature(enable = "avx2")] pub(super) unsafe fn from_blocks(src: &[Block; 4]) -> Self { + let (lo, hi) = src.split_at(2); + let blocks_23 = _mm256_loadu_si256(hi.as_ptr() as *const _); + let blocks_01 = _mm256_loadu_si256(lo.as_ptr() as *const _); + + Self::from_loaded_blocks(blocks_01, blocks_23) + } + + /// Aligns four 16-byte Poly1305 blocks at 26-bit boundaries within 32-bit words, and + /// sets the high bit for each block. + #[target_feature(enable = "avx2")] + pub(super) unsafe fn from_par_blocks(src: &ParBlocks) -> Self { + let (lo, hi) = src.split_at(2); + let blocks_23 = _mm256_loadu_si256(hi.as_ptr() as *const _); + let blocks_01 = _mm256_loadu_si256(lo.as_ptr() as *const _); + + Self::from_loaded_blocks(blocks_01, blocks_23) + } + + /// Aligns four 16-byte Poly1305 blocks at 26-bit boundaries within 32-bit words, and + /// sets the high bit for each block. + /// + /// The four blocks must be in the following 32-bit word layout: + /// [b33, b32, b31, b30, b23, b22, b21, b20] + /// [b13, b12, b11, b10, b03, b02, b01, b00] + #[target_feature(enable = "avx2")] + unsafe fn from_loaded_blocks(blocks_01: __m256i, blocks_23: __m256i) -> Self { // 26-bit mask on each 32-bit word. let mask_26 = _mm256_set1_epi32(0x3ffffff); // Sets bit 24 of each 32-bit word. let set_hibit = _mm256_set1_epi32(1 << 24); - // - Load the four blocks into the following 32-bit word layout: - // [b33, b32, b31, b30, b23, b22, b21, b20] - // [b13, b12, b11, b10, b03, b02, b01, b00] - // // - Unpack the upper and lower 64 bits: // [b33, b32, b13, b12, b23, b22, b03, b02] // [b31, b30, b11, b10, b21, b20, b01, b00] @@ -980,9 +1003,6 @@ impl Aligned4x130 { // - Swap the middle two 64-bit words: // a0 = [b33, b32, b23, b22, b13, b12, b03, b02] // a1 = [b31, b30, b21, b20, b11, b10, b01, b00] - let (lo, hi) = src.split_at(2); - let blocks_23 = _mm256_loadu_si256(hi.as_ptr() as *const _); - let blocks_01 = _mm256_loadu_si256(lo.as_ptr() as *const _); let a0 = _mm256_permute4x64_epi64( _mm256_unpackhi_epi64(blocks_01, blocks_23), set02(3, 1, 2, 0), From 99668328f51019c00c560b1a08ded3e9b857a6c3 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sun, 17 Jul 2022 08:50:07 -0600 Subject: [PATCH 3/3] Use `universal-hash` v0.5.0-pre; bump crate versions to `-pre` --- .github/workflows/poly1305.yml | 11 +---------- .github/workflows/polyval.yml | 11 +---------- Cargo.lock | 16 +++++++++------- ghash/Cargo.toml | 4 ++-- ghash/src/lib.rs | 3 +-- poly1305/Cargo.toml | 9 ++------- poly1305/src/lib.rs | 3 +-- polyval/Cargo.toml | 13 ++++--------- polyval/src/lib.rs | 3 +-- 9 files changed, 22 insertions(+), 51 deletions(-) diff --git a/.github/workflows/poly1305.yml b/.github/workflows/poly1305.yml index 768fde5..2d7bc34 100644 --- a/.github/workflows/poly1305.yml +++ b/.github/workflows/poly1305.yml @@ -153,17 +153,8 @@ jobs: strategy: matrix: include: - # ARM64 - target: aarch64-unknown-linux-gnu - rust: 1.56.1 # MSRV - - target: aarch64-unknown-linux-gnu - rust: stable - - # PPC32 - target: powerpc-unknown-linux-gnu - rust: 1.56.1 # MSRV - - target: powerpc-unknown-linux-gnu - rust: stable runs-on: ubuntu-latest steps: @@ -171,7 +162,7 @@ jobs: - run: ${{ matrix.deps }} - uses: actions-rs/toolchain@v1 with: - toolchain: ${{ matrix.rust }} + toolchain: stable target: ${{ matrix.target }} profile: minimal override: true diff --git a/.github/workflows/polyval.yml b/.github/workflows/polyval.yml index 35c1788..c42101e 100644 --- a/.github/workflows/polyval.yml +++ b/.github/workflows/polyval.yml @@ -154,17 +154,8 @@ jobs: strategy: matrix: include: - # ARM64 - target: aarch64-unknown-linux-gnu - rust: 1.56.1 # MSRV - - target: aarch64-unknown-linux-gnu - rust: stable - - # PPC32 - target: powerpc-unknown-linux-gnu - rust: 1.56.1 # MSRV - - target: powerpc-unknown-linux-gnu - rust: stable runs-on: ubuntu-latest steps: @@ -172,7 +163,7 @@ jobs: - run: ${{ matrix.deps }} - uses: actions-rs/toolchain@v1 with: - toolchain: ${{ matrix.rust }} + toolchain: stable target: ${{ matrix.target }} profile: minimal override: true diff --git a/Cargo.lock b/Cargo.lock index 497a55c..13c9656 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -19,8 +19,9 @@ dependencies = [ [[package]] name = "crypto-common" -version = "0.1.4" -source = "git+https://github.com/RustCrypto/traits?rev=74ce6e7a9ab1243f574b6c37e747a6e54c01f376#74ce6e7a9ab1243f574b6c37e747a6e54c01f376" +version = "0.1.6" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", "typenum", @@ -38,7 +39,7 @@ dependencies = [ [[package]] name = "ghash" -version = "0.4.4" +version = "0.5.0-pre" dependencies = [ "hex-literal", "opaque-debug", @@ -66,7 +67,7 @@ checksum = "624a8340c38c1b80fd549087862da4ba43e08858af025b236e509b6649fc13d5" [[package]] name = "poly1305" -version = "0.7.2" +version = "0.8.0-pre" dependencies = [ "cpufeatures", "hex-literal", @@ -77,7 +78,7 @@ dependencies = [ [[package]] name = "polyval" -version = "0.5.3" +version = "0.6.0-pre" dependencies = [ "cfg-if", "cpufeatures", @@ -101,8 +102,9 @@ checksum = "dcf81ac59edc17cc8697ff311e8f5ef2d99fcbd9817b34cec66f90b6c3dfd987" [[package]] name = "universal-hash" -version = "0.5.0" -source = "git+https://github.com/RustCrypto/traits?rev=74ce6e7a9ab1243f574b6c37e747a6e54c01f376#74ce6e7a9ab1243f574b6c37e747a6e54c01f376" +version = "0.5.0-pre" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c522efbb0229d4c6d11db2a36565aa4a447402d27d27b97e5eda49f872400518" dependencies = [ "crypto-common", "subtle", diff --git a/ghash/Cargo.toml b/ghash/Cargo.toml index 2e1b7be..3126528 100644 --- a/ghash/Cargo.toml +++ b/ghash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "ghash" -version = "0.4.4" # Also update html_root_url in lib.rs when bumping this +version = "0.5.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = """ @@ -17,7 +17,7 @@ edition = "2021" [dependencies] opaque-debug = "0.3" -polyval = { version = "0.5.1", path = "../polyval" } +polyval = { version = "=0.6.0-pre", path = "../polyval" } # optional dependencies zeroize = { version = "1", optional = true, default-features = false } diff --git a/ghash/src/lib.rs b/ghash/src/lib.rs index 8521ea3..a38328d 100644 --- a/ghash/src/lib.rs +++ b/ghash/src/lib.rs @@ -25,8 +25,7 @@ #![no_std] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/ghash/0.4.3" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![warn(missing_docs, rust_2018_idioms)] diff --git a/poly1305/Cargo.toml b/poly1305/Cargo.toml index 22484f2..4fa17e8 100644 --- a/poly1305/Cargo.toml +++ b/poly1305/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "poly1305" -version = "0.7.2" # Also update html_root_url in lib.rs when bumping this +version = "0.8.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = "The Poly1305 universal hash function and message authentication code" @@ -14,17 +14,12 @@ edition = "2021" [dependencies] opaque-debug = "0.3" -#universal-hash = { version = "0.5", default-features = false } +universal-hash = { version = "=0.5.0-pre", default-features = false } zeroize = { version = "1", optional = true, default-features = false } [target.'cfg(any(target_arch = "x86_64", target_arch = "x86"))'.dependencies] cpufeatures = "0.2" -[dependencies.universal-hash] -git = "https://github.com/RustCrypto/traits" -rev = "74ce6e7a9ab1243f574b6c37e747a6e54c01f376" -default-features = false - [dev-dependencies] hex-literal = "0.3" diff --git a/poly1305/src/lib.rs b/poly1305/src/lib.rs index 2696882..33f4abd 100644 --- a/poly1305/src/lib.rs +++ b/poly1305/src/lib.rs @@ -44,8 +44,7 @@ #![no_std] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/poly1305/0.7.1" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![warn(missing_docs, rust_2018_idioms)] diff --git a/polyval/Cargo.toml b/polyval/Cargo.toml index c84725c..035315f 100644 --- a/polyval/Cargo.toml +++ b/polyval/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "polyval" -version = "0.5.3" # Also update html_root_url in lib.rs when bumping this +version = "0.6.0-pre" # Also update html_root_url in lib.rs when bumping this authors = ["RustCrypto Developers"] license = "Apache-2.0 OR MIT" description = """ @@ -18,23 +18,18 @@ edition = "2021" [dependencies] cfg-if = "1" opaque-debug = "0.3" -#universal-hash = { version = "0.5", default-features = false } +universal-hash = { version = "=0.5.0-pre", default-features = false } zeroize = { version = "1", optional = true, default-features = false } [target.'cfg(any(target_arch = "aarch64", target_arch = "x86_64", target_arch = "x86"))'.dependencies] cpufeatures = "0.2" -[dependencies.universal-hash] -git = "https://github.com/RustCrypto/traits" -rev = "74ce6e7a9ab1243f574b6c37e747a6e54c01f376" -default-features = false - [dev-dependencies] hex-literal = "0.3" [features] -std = ["universal-hash/std"] -armv8 = [] # Enable nightly-only ARMv8 intrinsics support +std = ["universal-hash/std"] +armv8 = [] # Enable nightly-only ARMv8 intrinsics support force-soft = [] # Disable support for hardware intrinsics [package.metadata.docs.rs] diff --git a/polyval/src/lib.rs b/polyval/src/lib.rs index 9ae90d3..801b04e 100644 --- a/polyval/src/lib.rs +++ b/polyval/src/lib.rs @@ -78,8 +78,7 @@ #![cfg_attr(all(feature = "armv8", target_arch = "aarch64"), feature(stdsimd))] #![doc( html_logo_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg", - html_root_url = "https://docs.rs/polyval/0.5.3" + html_favicon_url = "https://raw.githubusercontent.com/RustCrypto/media/8f1a9894/logo.svg" )] #![warn(missing_docs, rust_2018_idioms)]