Skip to content

Add and implement KEM traits #1053

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

Open
wants to merge 10 commits into
base: main
Choose a base branch
from
Open

Add and implement KEM traits #1053

wants to merge 10 commits into from

Conversation

keks
Copy link
Member

@keks keks commented Jul 8, 2025

This PR adds a number of KEM traits and implements them for all our KEMs. All of them are derand-style.

Traits:

  • libcrux-traits::kem::arrayref::Kem: has const generics for all the lengths. Contains associated functions (i.e. methods have no receiver). Functions take referenves to arrays of the correct length as arguments. Outputs are written to mutable references.
  • libcrux-traits::kem::slice::Kem: has no const generics. Generally similar to the arrayref variant, but takes slices instead of array references. Error types contain variants for length mismatches.
  • libcrux-traits::kem::owned::Kem: similar to arrayref, but instead of writing to mutable references, outputs are returned as arrays. Has a blanket impl for all arrayref::Kem.
  • libcrux-traits::kem::secrets::Kem: similar to owned, but also classifies all returned values and consumes classified values. This is a step to get closer to secret independence. Has a blanket impl for all owned.

slice does not have a blanket impl for all arrayref because that doesn't work:

  • the const generics needed to describe the arrayref::Kem are not use in the type or the slice::Kem
  • there could be multiple implementations for arrayref::Kem, and we can only impl slice::Kem once

That's why there is a macro that impls slice::Kem for any type that impls arrayref::Kem.

What is not in here (but maybe should?)

  • This PR does not change or remove existing code/APIs
  • There are no randomized APIs, but we should be able to add randomized traits and blanket impl them for these traits
    • Maybe this won't work for similar reasons as with slice, but with the RAND const generics. in that case we'll have to do macros again.
  • Some generic test suite generated by macros that checks that the kem impl at least works

This might still be a little bit messy and not super well documented, but I hope it's good enough for a first look.

@keks keks force-pushed the keks/kem-trait branch from 1b6c739 to 4fff1a7 Compare July 8, 2025 11:06
@keks keks marked this pull request as ready for review July 8, 2025 11:09
@keks keks requested review from a team as code owners July 8, 2025 11:09
@keks keks requested a review from jschneider-bensch July 8, 2025 11:09
@keks keks linked an issue Jul 8, 2025 that may be closed by this pull request
9 tasks
Copy link
Collaborator

@jschneider-bensch jschneider-bensch left a comment

Choose a reason for hiding this comment

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

I think the traits look pretty good, I have mostly minor comments.
But indeed, as you mentioned it would be good to have more documentation in the traits crate, as well as tests that exercise the impls.

@keks keks requested a review from jschneider-bensch July 14, 2025 06:37
@github-actions github-actions bot dismissed jschneider-bensch’s stale review July 14, 2025 06:38

Review re-requested

Copy link
Collaborator

@jschneider-bensch jschneider-bensch left a comment

Choose a reason for hiding this comment

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

I think it looks pretty good!
But could you still add some uses of the generic test in the KEM crates?

Copy link
Collaborator

Choose a reason for hiding this comment

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

Nice! But we're not using it anywhere at the moment, right?

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 inject it in the macro for implementing the slice variant. Not super clean, but it did the trick...

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 could put it into a second macro or rename the macro, not sure what the best way to do that is.

dk: &mut [u8; SECRET_KEY_SIZE],
rand: &[u8; KEY_GENERATION_SEED_SIZE],
) -> Result<(), libcrux_traits::kem::owned::KeyGenError> {
if rand.iter().fold(0, crate::or) == 0 {
Copy link
Collaborator

Choose a reason for hiding this comment

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

In curve25519 we disallow zero randomness because it results in a bad key, but in ML-KEM I don't think there's a reason to disallow all zero randomness for keygen or encaps.

Copy link
Member Author

Choose a reason for hiding this comment

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

Hm, I figured zero randomness is always a problem because it suggests that no randomness has been generated. If the zero key itself is the problem, then we should first clamp and then check that the key is valid eg here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

KEM trait
2 participants