Skip to content

digest: add implementations of the AssociatedOid trait #1098

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

Merged
merged 12 commits into from
Sep 16, 2022
Merged
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .github/workflows/digest.yml
Original file line number Diff line number Diff line change
Expand Up @@ -68,4 +68,5 @@ jobs:
- 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
# - run: cargo test --all-features
Copy link
Member Author

Choose a reason for hiding this comment

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

I wonder how can we handle it better.

Copy link
Member

Choose a reason for hiding this comment

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

You can split out a separate job for it with a comment to re-unify them when MSRV is bumped.

17 changes: 9 additions & 8 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).

## UNRELEASED
### 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: 4 additions & 0 deletions digest/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,16 @@ 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 }
# Enable implementation of the `AssociatedOid` trait for the core wrappers.
# Enabling this feature bumps MSRV to 1.57.
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
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
3 changes: 3 additions & 0 deletions digest/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,9 @@ mod mac;
#[cfg(feature = "core-api")]
#[cfg_attr(docsrs, doc(cfg(feature = "core-api")))]
pub use block_buffer;
#[cfg(feature = "oid")]
#[cfg_attr(docsrs, doc(cfg(feature = "oid")))]
pub use const_oid;
pub use crypto_common;

pub use crate::digest::{Digest, DynDigest, HashMarker};
Expand Down