-
Notifications
You must be signed in to change notification settings - Fork 17.8k
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
crypto/mlkem: new package #70122
Comments
Related Issues and Documentation (Emoji vote if this was helpful or unhelpful; more detailed feedback welcome in this discussion.) |
@FiloSottile Does |
Maybe not, but I have rarely regretted adding an error, and very often regretted not adding one. I convinced myself not to return an error from |
What about having two separate packages with the same API names in both? E.g.,
@rolandshoemaker mentioned that we may want to add an interface in the future to wrap these, but the fact that this method returns a concrete type would interfere with that. (Maybe we could use an interface type parameterized over the encapsulation key type, but it's not clear that such an interface would be any more useful than the concrete types.) |
Another option would be that these types don't directly implement any interface, but that they have some method that returns an interface version implemented by some unexported type. |
Not enthusiastic about it, it makes it harder to reuse code across them, and they share quite a bit. Also the only precedent is x/crypto/blake2b and x/crypto/blake2s which differ by more than key size, but still always felt a bit confusing to me.
I like that! It might also be a solution for #69982 and #61477 (comment), where we were wondering how to make a concrete sha3 type easy to use with hmac and hkdf which take |
Returning an unexported type (inside an interface) is not always great, especially seeing the recent move out of these in crypto proposals (#69982, #61477 (comment)) |
@mateusz834 what I think @aclements is suggesting is that once we have a |
@FiloSottile I might be missing some part, but AFAICT this can be made differently and simpler. func (dk *DecapsulationKey768) EncapsulationKey() *EncapsulationKey768
func (dk *DecapsulationKey768) KEM() crypto.KEM { return dk.EncapsulationKey() }
var _ crypto.KEM = &EncapsulationKey768{} // *EncapsulationKey768 implements crypto.KEM. Same as |
I'm not sure I see how this solves the issue with
I guess it depends on what the interfaces need to capture. You're right that we could have one interface for |
Sounds like we have enough options to retrofit interfaces in the future, once we know better what we want to use them for.
Fair, there the analogous answer would be to just add |
Another possible option: would it work to have EncapsulationKey and DecapsulationKey both be parameterized over some type T, where there's a T for 768 and a T for 1024? The public methods on EncapsulationKey and DecapsulationKey could dispatch to unexported methods on T if necessary. I'm not sure if this would be a problem for the (*DecapsulationKey).EncapsulationKey method. |
This proposal has been added to the active column of the proposals project |
Change https://go.dev/cl/621983 mentions this issue: |
FWIW the generics seem like overkill to me. These are typically specialized anyway, so that they can have optimized implementations. It seems okay to me to have the different sizes. |
Fair enough. We at least have a path forward for creating common interfaces for these if the need arises. |
Decided to automatically duplicate the high-level code to avoid growing the ML-KEM-768 data structures. For #70122 Change-Id: I5c705b71ee1e23adba9113d5cf6b6e505c028967 Reviewed-on: https://go-review.googlesource.com/c/go/+/621983 Auto-Submit: Filippo Valsorda <[email protected]> Reviewed-by: Roland Shoemaker <[email protected]> Reviewed-by: Daniel McCarney <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
Based on the discussion above, this proposal seems like a likely accept. The proposal is to add a |
Change https://go.dev/cl/630240 mentions this issue: |
This commit exposes the crypto/internal/mlkem package as a public crypto package based on the linked proposal. Since we've already implemented this internal to the FIPS boundary this largely defers to that implementation. Updates #70122 Change-Id: I5ec9c2783c4d44583244c6d16597704a51e9b738 Reviewed-on: https://go-review.googlesource.com/c/go/+/630240 Reviewed-by: Filippo Valsorda <[email protected]> Reviewed-by: Roland Shoemaker <[email protected]> Auto-Submit: Filippo Valsorda <[email protected]> LUCI-TryBot-Result: Go LUCI <[email protected]> Reviewed-by: Dmitri Shuralyov <[email protected]>
No change in consensus, so accepted. 🎉 The proposal is to add a |
Done in CL 630240. |
The order of return values in As specified, the expected order of return values is shared secret key and then ciphertext:
It seems like the original pre-NIST Kyber spec (from round 3) did have the ciphertext first:
Because both return types are For reference, RFC 9180 (HPKE) also specifies it's KEMs to return secret first. (I'm not sure if this deserves a new issue or not). |
@FiloSottile @rsc @aclements Just want to make sure my comment above (#70122 (comment)) doesn't get missed. Leaving our return value ordering different from the actual spec feels like a real mistake to me. |
@tmthrgd hmm, now I wonder where I got this ordering from, since I did the implementation from the NIST ipd. Anyway, comments on closed issues fall off the radar, can you open a new issue and we'll flag it release-blocker? |
ML-KEM (FIPS 203, formerly Kyber) is a postquantum (#64537) key exchange method that was recently standardized and is being deployed across the industry. We already have an implementation in the Go tree as part of #67061.
I propose we expose a new package implementing ML-KEM-768 and ML-KEM-1024. Ideally we'd implement only ML-KEM-768, because it's what's being deployed in most settings and because playing the "security levels" game is an obsolete concept, but alas CNSA 2.0 requires ML-KEM-1024 across the board. We have seen no deployments of ML-KEM-512, so we are leaving that out at least for now. This happens to match what BoringSSL implemented. We also only support seeds as the decapsulation key format. This should match the direction the IETF is taking.
The proposed API uses separate types for -768 and -1024 to avoid making the -768 values unnecessarily large. I'm not a big fan of the numeric suffixes, and I'm especially unhappy that 1024 sorts before 768 in godoc, but couldn't find better names.
We are not proposing a KEM interface yet, but note that the methods should be general enough to allow one in the future.
The text was updated successfully, but these errors were encountered: