KMAC submission - #221
KMAC submission#221hoxxep wants to merge 1 commit into
Conversation
e22c7bb to
86f8839
Compare
|
Sorry we haven't taken a look at this yet. We're trying to wrap up our next stable release series and will have time after that |
|
No worries at all, thank you Tony! |
|
@newpavlov Thank you for the review, the implementation is significantly cleaner with a trait-based I've had to add the |
b80b3f1 to
fa9b52d
Compare
| impl<Rate: BlockSizes + sealed::KmacParams> MacMarker for Kmac<Rate> {} | ||
|
|
||
| impl<Rate: BlockSizes + sealed::KmacParams> OutputSizeUser for Kmac<Rate> { | ||
| type OutputSize = <Rate as sealed::KmacParams>::OutputSize; |
There was a problem hiding this comment.
We could use this instead:
use digest::array::typenum::Diff;
use core::ops::Sub;
impl<Rate: BlockSizes> OutputSizeUser for Kmac<Rate>
where
U200: Sub<Rate>,
Diff<U200, Rate>: ArraySize,
{
type OutputSize = Diff<U200, Rate>;
}It would be more "generic" and allow to remove the sealed trait, but with a bit more annoying trait bounds, so I am not sure whether it's worth the trouble.
There was a problem hiding this comment.
Unfortunately, the Rust compiler is not "smart" enough for Rate: IsLess<U200, Output = True> to be sufficient.
There was a problem hiding this comment.
Edit: the new code now opts for the following, as I believe this is the most straightforward way to link the const-generics to OutputSize and KeySize.
pub struct Kmac<const RATE: usize> {
cshake: CShake<RATE>,
}
pub type Kmac128 = Kmac<168>;
pub type Kmac256 = Kmac<136>;
impl OutputSizeUser for Kmac128 {
type OutputSize = U32;
}
impl OutputSizeUser for Kmac256 {
type OutputSize = U64;
}
impl KeySizeUser for Kmac128 {
type KeySize = U168;
}
impl KeySizeUser for Kmac256 {
type KeySize = U136;
}|
@newpavlov I've ported kmac to the latest cshake const-generic based API, thanks! |
3ba9721 to
220b993
Compare
Implements KMAC128, KMAC256, KMACXOF128, and KMACXOF256 as defined in NIST SP 800-185, built on the `cshake` crate.
220b993 to
26f318a
Compare
|
I've updated this PR to match the latest master and now:
|
I have tried to follow the RustCrypto MACs workflow, and used the traits as best I can.
This implements KMAC128, KMAC256, KMACXOF128, and KMACXOF256.
Key deviations from the existing mac traits:
Mac::finalize()outputs a 32-bit digest for KMAC128, and 64-bit for KMAC256 following the NIST default MAC output length guidance in section 8.4.Kmac*::finalize_into_buf(out: &mut [u8])is a generic finalize method for any fixed output size, following section 4.3 of NIST SP 800-185. I wasn't aware of a suitable trait to express this.FixedOutput::finalize_into, but it's limited to the Mac-defined output sizeOutput<Self>. This implementation allows for runtime determined output sizes.ExtendableOutput::finalize_xof()is used to implement KMACXOF128 and KMACXOF256. We could add an ExtendableMac trait to incorporate ExtendableOutput?Kmac*::new_customization(secret: &[u8], customization: &[u8])is used to initialize with a customization string, and again I wasn't aware of any suitable existing trait to express this.I'd be happy to try to add traits for this, if you believe this is the right direction? The crate should already be useful in it's current form though, and we could add traits later.
An alternate design could separate Kmac128, Kmac256, KmacXof128, and KmacXof256 types. This PR combines the fixed and XOF outputs into the same type, with different finalization methods for each output.
Happy to hear any feedback!
Related issues: