-
Notifications
You must be signed in to change notification settings - Fork 36
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
kmac: Towards an implementation #133
Comments
This is a great synopsis of the issue and a lot of great feedback on trait design. My high-level suggestion is to implement the existing traits and then we can separately work towards ones that are a better fit for KMAC. |
I agree that we probably should start with the fixed output size traits and work on improving our traits after that. As for API design, @tarcieri |
Thank you both for your valuable feedback. You can now find a proof-of-concept implementation for Implementations for the following traits are fully generic and deemed complete:
On the other hand, the following traits are implemented by hand for only
By fixing Aside: I duplicated |
Because Using Using I then updated With all the ingredients in place, I arrived at a compiling KMACXOF implementation. Now, for what’s missing… The six test vectors include explicitly requested output lengths. Because I coded only KMACXOF (and thus the right-encoded output length is not incorporated when finalizing the reader) none of the tests pass. But by hard-coding an output length of 256 and 512 bits, I can get the KMAC128 and KMAC256 tests passing, respectively. This makes me more confident that the remainder of the implementation is working as expected. The tests could be made to pass if I had I didn’t introduce any verification methods to Finally, I have to import Thank you for your patience, @tarcieri and @newpavlov. |
I've given the implementation of KMAC within the RustCrypto ecosystem some thought. My ideas, reproduced below, are informed by the NIST SP 800-185 recommendation and the
hmac
andsha3
crates.I'm willing to do any/all of the work described below. However, I'm not a cryptographer or security researcher, so all my work would have to be scrutinized tirelessly by the more qualified.
User experience
In keeping with the principle of least astonishment, I want to be able to use KMAC objects like other existing RustCrypto MAC objects:
We should first consider the
digest::Mac
trait imported in this example. The automatic implementation ofMac
is helpful for augmenting a typeT
(here,Kmac128
) with such methods asnew
,update
,finalize
andverify
, to name a few. This mechanism provides a consistent user experience with little extra development effort across different types of MAC.This mechanism doesn't support KMAC because it requires inappropriate traits. For example,
digest::KeyInit
supports initialization from only a key, whereas KMAC must also permit a customization string. Moreover, KMAC is defined in terms of CSHAKE (an extendable-output function) and thus shouldn't implementdigest::FixedOutput
, a trait required for the automatic implementation ofMac
. These limitations shape the implementation strategies I identify below.Implementing KMAC
Using
keccak
Prepare two core types of fixed security strength,
Kmac128Core
andKmac256Core
, that manage their own state and are implemented in terms of KECCAK[c] as described in Appendix B of NIST SP 800-185. The public API, similar to what we would expect if we were to importMac
, is implemented by hand. This is the cheaper approach but it violates the principle of least astonishment both internally (divergence of implementation strategy) and externally (users don't import a convenience trait). Moreover, it involves the duplication of private code insha3
.Using
sha3
Prepare a core generic type,
KmacCore<D>
, that wraps a hash function satisfying certain traits, e.g.,ExtendableOutputCore
. Implement the remaining traits as needed. Optionally, construct theKmac128
andKmac256
types, each aCoreWrapper<KmacCore<D>>
whereD
is asha3::CShake128
andsha3::CShake256
, respectively.Implement a convenience trait in
digest
that feels likeMac
but requires a distinct set of methods. For example, this new trait should rely ondigest::ExtendableOutput
rather thanFixedOutput
. Thus, I'll call itMacXof
in this post, but I note that this name doesn't capture all the key differences withMac
. In particular,MacXof
must also support initialization with both a key and, optionally, a customization string. (The closest trait I can find that enables this behavior iscrypto_common::KeyIvInit
. However, theiv
parameter is indicated for nonces and I'm unsure whether this is appropriate in this context.)I've identified one concrete obstacle in relation to implementing traits on
KmacCore
. Consider the following code inhmac
(edited for brevity):Here, the state can be initialized because the expectation is that
D::Core
implementsDefault
. CSHAKE types insha3
don't implementDefault
and we would need to fill this gap. However, instead ofDefault
, it would be more appropriate to implement an initialization trait—anIvInit
of sorts—so that the customization string passed to aKmac128
/Kmac256
constructor can be forwarded to the underlyingCShake128
/CShake256
constructor call.In addition, the CSHAKE implementations in
sha3
don't store their security strength. I don't see an easy way to prepare the expected algorithm names for KMAC (Kmac128
andKmac256
) without manipulating the CSHAKE type names directly, which I find undesirable.Overall, this approach requires more development effort. It involves extending the
digest
API with one or more new traits, and implementing at least one trait on CSHAKE types insha3
. However, I'm in favor of this approach because it preserves both the user experience as well as the existing implementation style for MACs.Testing
To test MAC implementations, RustCrypto serializes Project Wycheproof test vectors into binary blobs using the
blobby
crate. In turn, these are consumed by such macros asdigest::new_mac_test
. But there are no Wycheproof KMAC test vectors, nor does today's Wycheproof MAC schema support specification of the output length. So, we have no straightforward manner of leveraging the MAC test suite for KMAC.I haven't found any official and public-facing KMAC test vectors. The NIST Cryptographic Algorithm Validation Program page currently provides only HMAC test vectors. There's a collection of KMAC test vectors that appears to be at a legitimate NIST domain (csrc.nist.gov); I'm inclined to use these as the basis for a handwritten test. The Legion of the Bouncy Castle uses these samples in their KMAC tests.
All this aside, my sincere thanks go to the RustCrypto contributors for your work over the years!
The text was updated successfully, but these errors were encountered: