Skip to content

Commit

Permalink
crypto-common: migrate to hybrid-array; MSRV 1.65
Browse files Browse the repository at this point in the history
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.

`hybrid-array` is designed to be a largely drop-in replacement, and the
number of changes required to switch are relatively minimal aside from
some idiosyncracies.
  • Loading branch information
tarcieri committed Oct 26, 2023
1 parent 81ab91b commit 3ada46b
Show file tree
Hide file tree
Showing 5 changed files with 39 additions and 44 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/crypto-common.yml
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ jobs:
strategy:
matrix:
rust:
- 1.56.0 # MSRV
- 1.65.0 # MSRV
- stable
target:
- thumbv7em-none-eabi
Expand All @@ -46,7 +46,7 @@ jobs:
strategy:
matrix:
rust:
- 1.56.0 # MSRV
- 1.65.0 # MSRV
- stable
steps:
- uses: actions/checkout@v4
Expand Down
12 changes: 10 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 1 addition & 2 deletions crypto-common/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,7 @@ keywords = ["crypto", "traits"]
categories = ["cryptography", "no-std"]

[dependencies]
generic-array = { version = "0.14.6", features = ["more_lengths"] }
typenum = "1.14" # earlier versions of typenum don't satisfy the 'static bound on U* types
hybrid-array = "=0.2.0-pre.5"

# optional dependencies
rand_core = { version = "0.6.4", optional = true }
Expand Down
6 changes: 3 additions & 3 deletions crypto-common/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@

[![crate][crate-image]][crate-link]
[![Docs][docs-image]][docs-link]
[![Build Status][build-image]][build-link]
![Apache2/MIT licensed][license-image]
![Rust Version][rustc-image]
[![Project Chat][chat-image]][chat-link]
[![Build Status][build-image]][build-link]

Common traits used by cryptographic algorithms. Users should generally use
higher-level trait crates instead of this one.
Expand All @@ -14,7 +14,7 @@ higher-level trait crates instead of this one.

## 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.
Expand Down Expand Up @@ -46,7 +46,7 @@ dual licensed as above, without any additional terms or conditions.
[docs-image]: https://docs.rs/crypto-common/badge.svg
[docs-link]: https://docs.rs/crypto-common/
[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/260041-hashes
[build-image]: https://github.com/RustCrypto/traits/workflows/crypto-common/badge.svg?branch=master&event=push
Expand Down
58 changes: 23 additions & 35 deletions crypto-common/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,28 +15,28 @@ extern crate std;
#[cfg(feature = "rand_core")]
pub use rand_core;

pub use generic_array;
pub use generic_array::typenum;
pub use hybrid_array as array;
pub use hybrid_array::typenum;

use core::fmt;
use generic_array::{typenum::Unsigned, ArrayLength, GenericArray};
use hybrid_array::{typenum::Unsigned, Array, ArraySize, ByteArray};
#[cfg(feature = "rand_core")]
use rand_core::CryptoRngCore;

/// Block on which [`BlockSizeUser`] implementors operate.
pub type Block<B> = GenericArray<u8, <B as BlockSizeUser>::BlockSize>;
pub type Block<B> = ByteArray<<B as BlockSizeUser>::BlockSize>;

/// Parallel blocks on which [`ParBlocksSizeUser`] implementors operate.
pub type ParBlocks<T> = GenericArray<Block<T>, <T as ParBlocksSizeUser>::ParBlocksSize>;
pub type ParBlocks<T> = Array<Block<T>, <T as ParBlocksSizeUser>::ParBlocksSize>;

/// Output array of [`OutputSizeUser`] implementors.
pub type Output<T> = GenericArray<u8, <T as OutputSizeUser>::OutputSize>;
pub type Output<T> = ByteArray<<T as OutputSizeUser>::OutputSize>;

/// Key used by [`KeySizeUser`] implementors.
pub type Key<B> = GenericArray<u8, <B as KeySizeUser>::KeySize>;
pub type Key<B> = ByteArray<<B as KeySizeUser>::KeySize>;

/// Initialization vector (nonce) used by [`IvSizeUser`] implementors.
pub type Iv<B> = GenericArray<u8, <B as IvSizeUser>::IvSize>;
pub type Iv<B> = ByteArray<<B as IvSizeUser>::IvSize>;

/// Types which process data in blocks.
pub trait BlockSizeUser {
Expand All @@ -59,12 +59,12 @@ impl<T: BlockSizeUser> BlockSizeUser for &mut T {
}

/// Trait implemented for supported block sizes, i.e. for types from `U1` to `U255`.
pub trait BlockSizes: ArrayLength<u8> + sealed::BlockSizes + 'static {}
pub trait BlockSizes: ArraySize + sealed::BlockSizes + 'static {}

impl<T: ArrayLength<u8> + sealed::BlockSizes> BlockSizes for T {}
impl<T: ArraySize + sealed::BlockSizes> BlockSizes for T {}

mod sealed {
use generic_array::typenum::{Gr, IsGreater, IsLess, Le, NonZero, Unsigned, U1, U256};
use crate::typenum::{Gr, IsGreater, IsLess, Le, NonZero, Unsigned, U1, U256};

pub trait BlockSizes {}

Expand All @@ -80,13 +80,13 @@ mod sealed {
/// Types which can process blocks in parallel.
pub trait ParBlocksSizeUser: BlockSizeUser {
/// Number of blocks which can be processed in parallel.
type ParBlocksSize: ArrayLength<Block<Self>>;
type ParBlocksSize: ArraySize;
}

/// Types which return data with the given size.
pub trait OutputSizeUser {
/// Size of the output in bytes.
type OutputSize: ArrayLength<u8> + 'static;
type OutputSize: ArraySize + 'static;

/// Return output size in bytes.
#[inline(always)]
Expand All @@ -100,7 +100,7 @@ pub trait OutputSizeUser {
/// Generally it's used indirectly via [`KeyInit`] or [`KeyIvInit`].
pub trait KeySizeUser {
/// Key size in bytes.
type KeySize: ArrayLength<u8> + 'static;
type KeySize: ArraySize + 'static;

/// Return key size in bytes.
#[inline(always)]
Expand All @@ -114,7 +114,7 @@ pub trait KeySizeUser {
/// Generally it's used indirectly via [`KeyIvInit`] or [`InnerIvInit`].
pub trait IvSizeUser {
/// Initialization vector size in bytes.
type IvSize: ArrayLength<u8> + 'static;
type IvSize: ArraySize + 'static;

/// Return IV size in bytes.
#[inline(always)]
Expand Down Expand Up @@ -151,11 +151,9 @@ pub trait KeyInit: KeySizeUser + Sized {
/// Create new value from variable size key.
#[inline]
fn new_from_slice(key: &[u8]) -> Result<Self, InvalidLength> {
if key.len() != Self::KeySize::to_usize() {
Err(InvalidLength)
} else {
Ok(Self::new(Key::<Self>::from_slice(key)))
}
<&Key<Self>>::try_from(key)
.map(Self::new)
.map_err(|_| InvalidLength)
}

/// Generate random key using the provided [`CryptoRngCore`].
Expand All @@ -177,16 +175,9 @@ pub trait KeyIvInit: KeySizeUser + IvSizeUser + Sized {
/// Create new value from variable length key and nonce.
#[inline]
fn new_from_slices(key: &[u8], iv: &[u8]) -> Result<Self, InvalidLength> {
let key_len = Self::KeySize::USIZE;
let iv_len = Self::IvSize::USIZE;
if key.len() != key_len || iv.len() != iv_len {
Err(InvalidLength)
} else {
Ok(Self::new(
Key::<Self>::from_slice(key),
Iv::<Self>::from_slice(iv),
))
}
let key = <&Key<Self>>::try_from(key).map_err(|_| InvalidLength)?;
let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
Ok(Self::new(key, iv))
}

/// Generate random key using the provided [`CryptoRngCore`].
Expand Down Expand Up @@ -237,11 +228,8 @@ pub trait InnerIvInit: InnerUser + IvSizeUser + Sized {
/// Initialize value using `inner` and `iv` slice.
#[inline]
fn inner_iv_slice_init(inner: Self::Inner, iv: &[u8]) -> Result<Self, InvalidLength> {
if iv.len() != Self::IvSize::to_usize() {
Err(InvalidLength)
} else {
Ok(Self::inner_iv_init(inner, Iv::<Self>::from_slice(iv)))
}
let iv = <&Iv<Self>>::try_from(iv).map_err(|_| InvalidLength)?;
Ok(Self::inner_iv_init(inner, iv))
}

/// Generate random IV using the provided [`CryptoRngCore`].
Expand Down

0 comments on commit 3ada46b

Please sign in to comment.