From a92cf0d2f62b3e572c0780ab53c302fdf138bf25 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 11 Nov 2023 21:08:06 -0700 Subject: [PATCH 1/2] universal-hash: bump crypto-common to v0.2.0-pre; MSRV 1.65 Replaces `generic-array` with `hybrid-array`, which is built on a combination of `typenum` and const generics, providing a degree of interoperability between the two systems. --- .github/workflows/universal-hash.yml | 13 +++++++------ Cargo.lock | 12 ++++++------ Cargo.toml | 2 +- crypto/Cargo.toml | 2 +- universal-hash/Cargo.toml | 4 ++-- universal-hash/src/lib.rs | 20 +++++++++++--------- 6 files changed, 28 insertions(+), 25 deletions(-) diff --git a/.github/workflows/universal-hash.yml b/.github/workflows/universal-hash.yml index f00cfe0f8..76a17285f 100644 --- a/.github/workflows/universal-hash.yml +++ b/.github/workflows/universal-hash.yml @@ -22,7 +22,7 @@ jobs: strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable target: - thumbv7em-none-eabi @@ -36,17 +36,18 @@ jobs: targets: ${{ matrix.target }} - run: cargo build --no-default-features --release --target ${{ matrix.target }} - minimal-versions: - uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master - with: - working-directory: ${{ github.workflow }} + # TODO(tarcieri): re-enable after next `crypto-common` release + # minimal-versions: + # uses: RustCrypto/actions/.github/workflows/minimal-versions.yml@master + # with: + # working-directory: ${{ github.workflow }} test: runs-on: ubuntu-latest strategy: matrix: rust: - - 1.56.0 # MSRV + - 1.65.0 # MSRV - stable steps: - uses: actions/checkout@v4 diff --git a/Cargo.lock b/Cargo.lock index a9cbef675..c1d47c16b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -860,7 +860,7 @@ checksum = "8159bd90725d2df49889a078b54f4f79e87f1f8a8444194cdca81d38f5393abf" dependencies = [ "cpufeatures", "opaque-debug", - "universal-hash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "universal-hash 0.5.1", ] [[package]] @@ -872,7 +872,7 @@ dependencies = [ "cfg-if", "cpufeatures", "opaque-debug", - "universal-hash 0.5.1 (registry+https://github.com/rust-lang/crates.io-index)", + "universal-hash 0.5.1", ] [[package]] @@ -1207,6 +1207,8 @@ checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" [[package]] name = "universal-hash" version = "0.5.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" dependencies = [ "crypto-common 0.1.6", "subtle", @@ -1214,11 +1216,9 @@ dependencies = [ [[package]] name = "universal-hash" -version = "0.5.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fc1de2c688dc15305988b563c3854064043356019f97a4b46276fe734c4f07ea" +version = "0.6.0-pre" dependencies = [ - "crypto-common 0.1.6", + "crypto-common 0.2.0-pre", "subtle", ] diff --git a/Cargo.toml b/Cargo.toml index e4cda3420..90727b25a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -9,12 +9,12 @@ members = [ "elliptic-curve", "kem", "password-hash", + "universal-hash", ] # TODO: re-add to `members` when MSRV has been bumped to 1.60+ exclude = [ "signature", "signature/async", - "universal-hash", ] [patch.crates-io] diff --git a/crypto/Cargo.toml b/crypto/Cargo.toml index c3968eda1..95db1199a 100644 --- a/crypto/Cargo.toml +++ b/crypto/Cargo.toml @@ -22,7 +22,7 @@ digest = { version = "0.10", optional = true, features = ["mac"] } elliptic-curve = { version = "0.13", optional = true, path = "../elliptic-curve" } password-hash = { version = "0.5", optional = true, path = "../password-hash" } signature = { version = "2", optional = true, default-features = false, path = "../signature" } -universal-hash = { version = "0.5", optional = true, path = "../universal-hash" } +universal-hash = { version = "0.5", optional = true } [features] std = [ diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 2cae13be1..0a8c7b4e8 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -1,6 +1,6 @@ [package] name = "universal-hash" -version = "0.5.1" +version = "0.6.0-pre" description = "Traits which describe the functionality of universal hash functions (UHFs)" authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" @@ -13,7 +13,7 @@ keywords = ["crypto", "mac"] categories = ["cryptography", "no-std"] [dependencies] -crypto-common = "0.1.6" +crypto-common = "=0.2.0-pre" subtle = { version = "2.4", default-features = false } [features] diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 87c963a4f..5d34bbe42 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -30,14 +30,16 @@ extern crate std; pub use crypto_common::{ - self, generic_array, + self, array, typenum::{self, consts}, Block, Key, KeyInit, ParBlocks, Reset, }; use core::slice; -use crypto_common::{BlockSizeUser, ParBlocksSizeUser}; -use generic_array::{ArrayLength, GenericArray}; +use crypto_common::{ + array::{Array, ArraySize}, + BlockSizeUser, BlockSizes, ParBlocksSizeUser, +}; use subtle::ConstantTimeEq; use typenum::Unsigned; @@ -79,15 +81,15 @@ pub trait UniversalHash: BlockSizeUser + Sized { /// Update hash function state with the provided block. #[inline] fn update(&mut self, blocks: &[Block]) { - struct Ctx<'a, BS: ArrayLength> { + struct Ctx<'a, BS: BlockSizes> { blocks: &'a [Block], } - impl<'a, BS: ArrayLength> BlockSizeUser for Ctx<'a, BS> { + impl<'a, BS: BlockSizes> BlockSizeUser for Ctx<'a, BS> { type BlockSize = BS; } - impl<'a, BS: ArrayLength> UhfClosure for Ctx<'a, BS> { + impl<'a, BS: BlockSizes> UhfClosure for Ctx<'a, BS> { #[inline(always)] fn call>(self, backend: &mut B) { let pb = B::ParBlocksSize::USIZE; @@ -123,7 +125,7 @@ pub trait UniversalHash: BlockSizeUser + Sized { self.update(blocks); if !tail.is_empty() { - let mut padded_block = GenericArray::default(); + let mut padded_block = Array::default(); padded_block[..tail.len()].copy_from_slice(tail); self.update(slice::from_ref(&padded_block)); } @@ -177,10 +179,10 @@ impl std::error::Error for Error {} /// Split message into slice of blocks and leftover tail. // TODO: replace with `slice::as_chunks` on migration to const generics #[inline(always)] -fn to_blocks>(data: &[T]) -> (&[GenericArray], &[T]) { +fn to_blocks(data: &[T]) -> (&[Array], &[T]) { let nb = data.len() / N::USIZE; let (left, right) = data.split_at(nb * N::USIZE); - let p = left.as_ptr() as *const GenericArray; + let p = left.as_ptr() as *const Array; // SAFETY: we guarantee that `blocks` does not point outside of `data` // and `p` is valid for reads #[allow(unsafe_code)] From bf10e4ba67a46897bfd4ea0ee2fbb229a1575b54 Mon Sep 17 00:00:00 2001 From: Tony Arcieri Date: Sat, 11 Nov 2023 21:18:42 -0700 Subject: [PATCH 2/2] Use hybrid_array::slice_as_chunks --- Cargo.lock | 8 +++---- universal-hash/Cargo.lock | 49 --------------------------------------- universal-hash/Cargo.toml | 2 +- universal-hash/README.md | 4 ++-- universal-hash/src/lib.rs | 49 ++++++--------------------------------- 5 files changed, 14 insertions(+), 98 deletions(-) delete mode 100644 universal-hash/Cargo.lock diff --git a/Cargo.lock b/Cargo.lock index c1d47c16b..363715652 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -135,7 +135,7 @@ dependencies = [ [[package]] name = "block-buffer" version = "0.11.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#b755f1a29b074d8b0a6fc5fda5744312a11632c7" +source = "git+https://github.com/RustCrypto/utils.git#708aa72b9ebde06a02e862368e890fb3ddcb2fb9" dependencies = [ "crypto-common 0.2.0-pre", ] @@ -152,7 +152,7 @@ dependencies = [ [[package]] name = "block-padding" version = "0.4.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#b755f1a29b074d8b0a6fc5fda5744312a11632c7" +source = "git+https://github.com/RustCrypto/utils.git#708aa72b9ebde06a02e862368e890fb3ddcb2fb9" dependencies = [ "hybrid-array", ] @@ -698,7 +698,7 @@ dependencies = [ [[package]] name = "hybrid-array" version = "0.2.0-pre.5" -source = "git+https://github.com/RustCrypto/utils.git#b755f1a29b074d8b0a6fc5fda5744312a11632c7" +source = "git+https://github.com/RustCrypto/utils.git#708aa72b9ebde06a02e862368e890fb3ddcb2fb9" dependencies = [ "typenum", ] @@ -716,7 +716,7 @@ dependencies = [ [[package]] name = "inout" version = "0.2.0-pre" -source = "git+https://github.com/RustCrypto/utils.git#b755f1a29b074d8b0a6fc5fda5744312a11632c7" +source = "git+https://github.com/RustCrypto/utils.git#708aa72b9ebde06a02e862368e890fb3ddcb2fb9" dependencies = [ "block-padding 0.4.0-pre", "hybrid-array", diff --git a/universal-hash/Cargo.lock b/universal-hash/Cargo.lock deleted file mode 100644 index 2542bc3d6..000000000 --- a/universal-hash/Cargo.lock +++ /dev/null @@ -1,49 +0,0 @@ -# This file is automatically @generated by Cargo. -# It is not intended for manual editing. -version = 3 - -[[package]] -name = "crypto-common" -version = "0.1.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" -dependencies = [ - "generic-array", - "typenum", -] - -[[package]] -name = "generic-array" -version = "0.14.4" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "501466ecc8a30d1d3b7fc9229b122b2ce8ed6e9d9223f1138d4babb253e51817" -dependencies = [ - "typenum", - "version_check", -] - -[[package]] -name = "subtle" -version = "2.4.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e81da0851ada1f3e9d4312c704aa4f8806f0f9d69faaf8df2f3464b4a9437c2" - -[[package]] -name = "typenum" -version = "1.14.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b63708a265f51345575b27fe43f9500ad611579e764c79edbc2037b1121959ec" - -[[package]] -name = "universal-hash" -version = "0.5.1" -dependencies = [ - "crypto-common", - "subtle", -] - -[[package]] -name = "version_check" -version = "0.9.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "45d3d553fd9413fffe7147a20171d640eda0ad4c070acd7d0c885a21bcd2e8b7" diff --git a/universal-hash/Cargo.toml b/universal-hash/Cargo.toml index 0a8c7b4e8..a2786ecc9 100644 --- a/universal-hash/Cargo.toml +++ b/universal-hash/Cargo.toml @@ -5,7 +5,7 @@ description = "Traits which describe the functionality of universal hash functio authors = ["RustCrypto Developers"] license = "MIT OR Apache-2.0" edition = "2021" -rust-version = "1.56" +rust-version = "1.65" readme = "README.md" documentation = "https://docs.rs/universal-hash" repository = "https://github.com/RustCrypto/traits" diff --git a/universal-hash/README.md b/universal-hash/README.md index 9fd55a0cf..3bc9d0977 100644 --- a/universal-hash/README.md +++ b/universal-hash/README.md @@ -15,7 +15,7 @@ See [RustCrypto/universal-hashes] for implementations which use this trait. ## Minimum Supported Rust Version -Rust **1.56** or higher. +Rust **1.65** or higher. Minimum supported Rust version can be changed in the future, but it will be done with a minor version bump. @@ -47,7 +47,7 @@ dual licensed as above, without any additional terms or conditions. [docs-image]: https://docs.rs/universal-hash/badge.svg [docs-link]: https://docs.rs/universal-hash/ [license-image]: https://img.shields.io/badge/license-Apache2.0/MIT-blue.svg -[rustc-image]: https://img.shields.io/badge/rustc-1.56+-blue.svg +[rustc-image]: https://img.shields.io/badge/rustc-1.65+-blue.svg [chat-image]: https://img.shields.io/badge/zulip-join_chat-blue.svg [chat-link]: https://rustcrypto.zulipchat.com/#narrow/stream/260051-universal-hashes [build-image]: https://github.com/RustCrypto/traits/workflows/universal-hash/badge.svg?branch=master&event=push diff --git a/universal-hash/src/lib.rs b/universal-hash/src/lib.rs index 5d34bbe42..5fef8a6b4 100644 --- a/universal-hash/src/lib.rs +++ b/universal-hash/src/lib.rs @@ -1,29 +1,11 @@ -//! Traits for [Universal Hash Functions]. -//! -//! # About universal hashes -//! -//! Universal hash functions provide a "universal family" of possible -//! hash functions where a given member of a family is selected by a key. -//! -//! They are well suited to the purpose of "one time authenticators" for a -//! sequence of bytestring inputs, as their construction has a number of -//! desirable properties such as pairwise independence as well as amenability -//! to efficient implementations, particularly when implemented using SIMD -//! instructions. -//! -//! When combined with a cipher, such as in Galois/Counter Mode (GCM) or the -//! Salsa20 family AEAD constructions, they can provide the core functionality -//! for a Message Authentication Code (MAC). -//! -//! [Universal Hash Functions]: https://en.wikipedia.org/wiki/Universal_hashing - #![no_std] +#![cfg_attr(docsrs, feature(doc_auto_cfg))] +#![doc = include_str!("../README.md")] #![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" )] -#![cfg_attr(docsrs, feature(doc_auto_cfg))] -#![deny(unsafe_code)] +#![forbid(unsafe_code)] #![warn(missing_docs, rust_2018_idioms)] #[cfg(feature = "std")] @@ -36,10 +18,7 @@ pub use crypto_common::{ }; use core::slice; -use crypto_common::{ - array::{Array, ArraySize}, - BlockSizeUser, BlockSizes, ParBlocksSizeUser, -}; +use crypto_common::{array::Array, BlockSizeUser, BlockSizes, ParBlocksSizeUser}; use subtle::ConstantTimeEq; use typenum::Unsigned; @@ -94,7 +73,7 @@ pub trait UniversalHash: BlockSizeUser + Sized { fn call>(self, backend: &mut B) { let pb = B::ParBlocksSize::USIZE; if pb > 1 { - let (par_blocks, tail) = to_blocks(self.blocks); + let (par_blocks, tail) = array::slice_as_chunks(self.blocks); for par_block in par_blocks { backend.proc_par_blocks(par_block); } @@ -120,7 +99,7 @@ pub trait UniversalHash: BlockSizeUser + Sized { /// Message Authentication Codes (MACs) based on universal hashing. #[inline] fn update_padded(&mut self, data: &[u8]) { - let (blocks, tail) = to_blocks(data); + let (blocks, tail) = array::slice_as_chunks(data); self.update(blocks); @@ -134,7 +113,7 @@ pub trait UniversalHash: BlockSizeUser + Sized { /// Retrieve result and consume hasher instance. fn finalize(self) -> Block; - /// Obtain the [`Output`] of a [`UniversalHash`] computation and reset it back + /// Obtain the output of a [`UniversalHash`] computation and reset it back /// to its initial state. #[inline] fn finalize_reset(&mut self) -> Block @@ -175,17 +154,3 @@ impl core::fmt::Display for Error { #[cfg(feature = "std")] impl std::error::Error for Error {} - -/// Split message into slice of blocks and leftover tail. -// TODO: replace with `slice::as_chunks` on migration to const generics -#[inline(always)] -fn to_blocks(data: &[T]) -> (&[Array], &[T]) { - let nb = data.len() / N::USIZE; - let (left, right) = data.split_at(nb * N::USIZE); - let p = left.as_ptr() as *const Array; - // SAFETY: we guarantee that `blocks` does not point outside of `data` - // and `p` is valid for reads - #[allow(unsafe_code)] - let blocks = unsafe { slice::from_raw_parts(p, nb) }; - (blocks, right) -}