Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

digest: add implementations of the AssociatedOid trait #1098

Merged
merged 12 commits into from
Sep 16, 2022
27 changes: 24 additions & 3 deletions .github/workflows/digest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
strategy:
matrix:
rust:
- 1.41.0 # MSRV
# - 1.41.0 # MSRV
- stable
steps:
- uses: actions/checkout@v2
Expand All @@ -60,12 +60,33 @@ jobs:
toolchain: ${{ matrix.rust }}
override: true
profile: minimal
# Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates
- run: rm ../Cargo.toml
- run: cargo check --all-features
- run: cargo test --no-default-features
- run: cargo test
- run: cargo test --features dev
- run: cargo test --features alloc
- run: cargo test --features std
- run: cargo test --all-features

# The `oid` feature bumps MSRV to 1.57, so we temporarily split this job.
test-msrv:
runs-on: ubuntu-latest
strategy:
matrix:
rust:
- 1.41.0 # MSRV
steps:
- uses: actions/checkout@v2
- uses: RustCrypto/actions/cargo-cache@master
- uses: actions-rs/toolchain@v1
with:
toolchain: ${{ matrix.rust }}
override: true
profile: minimal
# Isolate this crate from workspace which is otherwise MSRV 1.56 due to 2021 edition crates
- run: rm ../Cargo.toml
- run: cargo test --no-default-features
- run: cargo test
- run: cargo test --features dev
- run: cargo test --features alloc
- run: cargo test --features std
43 changes: 22 additions & 21 deletions Cargo.lock

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

7 changes: 7 additions & 0 deletions digest/CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@ All notable changes to this project will be documented in this file.
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).

## 0.10.4 (2022-09-16)
### Added
- Feature-gated implementation of the `const_oid::AssociatedOid` trait
for the core wrappers. ([#1098])

[#1098]: https://github.com/RustCrypto/traits/pull/1098

## 0.10.3 (2022-02-16)
### Fixed
- Minimal versions build ([#940])
Expand Down
4 changes: 3 additions & 1 deletion digest/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
[package]
name = "digest"
description = "Traits for cryptographic hash functions"
version = "0.10.3" # Also update html_root_url in lib.rs when bumping this
version = "0.10.4"
authors = ["RustCrypto Developers"]
license = "MIT OR Apache-2.0"
readme = "README.md"
Expand All @@ -18,12 +18,14 @@ crypto-common = { version = "0.1.3", path = "../crypto-common" }
block-buffer = { version = "0.10", optional = true }
subtle = { version = "=2.4", default-features = false, optional = true }
blobby = { version = "0.3", optional = true }
const-oid = { version = "0.9", optional = true }

[features]
default = ["core-api"]
core-api = ["block-buffer"] # Enable Core API traits
mac = ["subtle"] # Enable MAC traits
rand_core = ["crypto-common/rand_core"] # Enable random key generation methods
oid = ["const-oid"] # OID support. WARNING: Bumps MSRV to 1.57
alloc = []
std = ["alloc", "crypto-common/std"]
dev = ["blobby"]
Expand Down
61 changes: 49 additions & 12 deletions digest/src/core_api/ct_variable.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,17 +5,24 @@ use super::{
use crate::HashMarker;
#[cfg(feature = "mac")]
use crate::MacMarker;
#[cfg(feature = "oid")]
use const_oid::{AssociatedOid, ObjectIdentifier};
use core::{fmt, marker::PhantomData};
use crypto_common::{
generic_array::{ArrayLength, GenericArray},
typenum::{IsLess, IsLessOrEqual, Le, LeEq, NonZero, U256},
Block, BlockSizeUser, OutputSizeUser,
};

/// Dummy type used with [`CtVariableCoreWrapper`] in cases when
/// resulting hash does not have a known OID.
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct NoOid;

/// Wrapper around [`VariableOutputCore`] which selects output size
/// at compile time.
#[derive(Clone)]
pub struct CtVariableCoreWrapper<T, OutSize>
pub struct CtVariableCoreWrapper<T, OutSize, O = NoOid>
Copy link
Member

@tarcieri tarcieri Sep 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Instead of using an extra generic type here, could CtVariableCoreWrapper have an impl of AssociatedOid which delegates to inner, and is bounded on inner having an impl of AssociatedOid?

That would avoid complicating the type signature and eliminate the need for NoOid.

Ditto for CoreWrapper.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If I understand you correctly, then no, it will not work. See the SHA-224 vs SHA-256 issue raised in my earlier comment. They have the same core (i.e. the same inner type), so with such solution they can not have different OIDs.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ugh, ok. That's really rather unfortunate.

Copy link
Member Author

@newpavlov newpavlov Sep 13, 2022

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we would use const OID: Option<ObjectIdentifier> instead of the O parameter with AssociatedOid impl bounded on OID being Some, but, as you know, const generics are not powerful enough for that and will not be in the mid term future.

where
T: VariableOutputCore,
OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
Expand All @@ -24,10 +31,10 @@ where
Le<T::BlockSize, U256>: NonZero,
{
inner: T,
_out: PhantomData<OutSize>,
_out: PhantomData<(OutSize, O)>,
}

impl<T, OutSize> HashMarker for CtVariableCoreWrapper<T, OutSize>
impl<T, OutSize, O> HashMarker for CtVariableCoreWrapper<T, OutSize, O>
where
T: VariableOutputCore + HashMarker,
OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
Expand All @@ -38,7 +45,7 @@ where
}

#[cfg(feature = "mac")]
impl<T, OutSize> MacMarker for CtVariableCoreWrapper<T, OutSize>
impl<T, OutSize, O> MacMarker for CtVariableCoreWrapper<T, OutSize, O>
where
T: VariableOutputCore + MacMarker,
OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
Expand All @@ -48,7 +55,7 @@ where
{
}

impl<T, OutSize> BlockSizeUser for CtVariableCoreWrapper<T, OutSize>
impl<T, OutSize, O> BlockSizeUser for CtVariableCoreWrapper<T, OutSize, O>
where
T: VariableOutputCore,
OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
Expand All @@ -59,7 +66,7 @@ where
type BlockSize = T::BlockSize;
}

impl<T, OutSize> UpdateCore for CtVariableCoreWrapper<T, OutSize>
impl<T, OutSize, O> UpdateCore for CtVariableCoreWrapper<T, OutSize, O>
where
T: VariableOutputCore,
OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
Expand All @@ -73,7 +80,7 @@ where
}
}

impl<T, OutSize> OutputSizeUser for CtVariableCoreWrapper<T, OutSize>
impl<T, OutSize, O> OutputSizeUser for CtVariableCoreWrapper<T, OutSize, O>
where
T: VariableOutputCore,
OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize> + 'static,
Expand All @@ -84,7 +91,7 @@ where
type OutputSize = OutSize;
}

impl<T, OutSize> BufferKindUser for CtVariableCoreWrapper<T, OutSize>
impl<T, OutSize, O> BufferKindUser for CtVariableCoreWrapper<T, OutSize, O>
where
T: VariableOutputCore,
OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
Expand All @@ -95,7 +102,7 @@ where
type BufferKind = T::BufferKind;
}

impl<T, OutSize> FixedOutputCore for CtVariableCoreWrapper<T, OutSize>
impl<T, OutSize, O> FixedOutputCore for CtVariableCoreWrapper<T, OutSize, O>
where
T: VariableOutputCore,
OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize> + 'static,
Expand All @@ -120,7 +127,7 @@ where
}
}

impl<T, OutSize> Default for CtVariableCoreWrapper<T, OutSize>
impl<T, OutSize, O> Default for CtVariableCoreWrapper<T, OutSize, O>
where
T: VariableOutputCore,
OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
Expand All @@ -137,7 +144,7 @@ where
}
}

impl<T, OutSize> Reset for CtVariableCoreWrapper<T, OutSize>
impl<T, OutSize, O> Reset for CtVariableCoreWrapper<T, OutSize, O>
where
T: VariableOutputCore,
OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
Expand All @@ -151,7 +158,7 @@ where
}
}

impl<T, OutSize> AlgorithmName for CtVariableCoreWrapper<T, OutSize>
impl<T, OutSize, O> AlgorithmName for CtVariableCoreWrapper<T, OutSize, O>
where
T: VariableOutputCore + AlgorithmName,
OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
Expand All @@ -165,3 +172,33 @@ where
write!(f, "{}", OutSize::USIZE)
}
}

#[cfg(feature = "oid")]
#[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
impl<T, OutSize, O> AssociatedOid for CtVariableCoreWrapper<T, OutSize, O>
where
T: VariableOutputCore,
O: AssociatedOid,
OutSize: ArrayLength<u8> + IsLessOrEqual<T::OutputSize>,
LeEq<OutSize, T::OutputSize>: NonZero,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
const OID: ObjectIdentifier = O::OID;
}

/// Implement dummy type with hidden docs which is used to "carry" hasher
/// OID for [`CtVariableCoreWrapper`].
#[macro_export]
macro_rules! impl_oid_carrier {
($name:ident, $oid:literal) => {
#[doc(hidden)]
#[derive(Copy, Clone, Debug, Eq, PartialEq, Hash)]
pub struct $name;

#[cfg(feature = "oid")]
impl AssociatedOid for $name {
const OID: ObjectIdentifier = ObjectIdentifier::new_unwrap($oid);
}
};
}
13 changes: 13 additions & 0 deletions digest/src/core_api/wrapper.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ use crypto_common::{

#[cfg(feature = "mac")]
use crate::MacMarker;
#[cfg(feature = "oid")]
use const_oid::{AssociatedOid, ObjectIdentifier};

/// Wrapper around [`BufferKindUser`].
///
Expand Down Expand Up @@ -227,6 +229,17 @@ where
}
}

#[cfg(feature = "oid")]
#[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
impl<T> AssociatedOid for CoreWrapper<T>
where
T: BufferKindUser + AssociatedOid,
T::BlockSize: IsLess<U256>,
Le<T::BlockSize, U256>: NonZero,
{
const OID: ObjectIdentifier = T::OID;
}

#[cfg(feature = "std")]
#[cfg_attr(docsrs, doc(cfg(feature = "std")))]
impl<T> std::io::Write for CoreWrapper<T>
Expand Down
Loading