Skip to content

Add DeriveKeyPair API#2070

Merged
SWilson4 merged 13 commits intomainfrom
sw-mlkem-derand
Mar 18, 2025
Merged

Add DeriveKeyPair API#2070
SWilson4 merged 13 commits intomainfrom
sw-mlkem-derand

Conversation

@SWilson4
Copy link
Member

@SWilson4 SWilson4 commented Feb 7, 2025

Based on the work of @Eddy-M-K in #1877.

Closes #1206.

  • Does this PR change the input/output behaviour of a cryptographic algorithm (i.e., does it change known answer test values)? (If so, a version bump will be required from x.y.z to x.(y+1).0.)
  • Does this PR change the list of algorithms available -- either adding, removing, or renaming? Does this PR otherwise change an API? (If so, PRs in fully supported downstream projects dependent on these, i.e., oqs-provider will also need to be ready for review and merge by the time this is merged.)

Copy link

@bifurcation bifurcation left a comment

Choose a reason for hiding this comment

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

Overall, this looks right to me. Couple of minor naming things and questions.

@bifurcation
Copy link

This PR seems pretty mature. What still needs to be done to merge it?

@dstebila dstebila added this to the 0.13.0 milestone Feb 19, 2025
@baentsch
Copy link
Member

This PR seems pretty mature. What still needs to be done to merge it?

Well, for one, all CI should pass. Then review should be requested. Finally, there's the question whether, how and where this should be added to some application layer to prove actual utility. Any input on that @SWilson4 ?

@dstebila
Copy link
Member

In terms of naming, I think "seed" is better than "coins" since that's the term used in FIPS 203. As for whether to call the function _internal or _derand or _deterministic: I don't think _internal is very descriptive, even though that's the FIPS 203 term; so I'd go with _derand or _deterministic, but don't have a strong preference between them.

@SWilson4
Copy link
Member Author

Marking as "Ready for Review" now that CI passes.

This PR exposes the ML-KEM "internal" keygen function via a new OQS KEM API for derandomized key generation.

My main intent with this PR is to enable experimentation with post-quantum crypto in protocols that require the HPKE interface, which includes a "DeriveKeyPair" function that is essentially derandomized key generation (see RFC 9180 and draft-connolly-cfrg-hpke-mlkem). It turns out that this also allows users of liboqs to work with ML-KEM seeds (derandomized keygen converts a seed into an expanded keypair).

I've called the API "keypair_derand" since that was the name in the ML-KEM and Kyber codebases, but I'm open to changing this ("keypair_deterministic"? "keypair_derive"? "keypair_from_seed"?)

Currently, calls to the new API will fail for algorithms other than ML-KEM.

@SWilson4 SWilson4 marked this pull request as ready for review February 27, 2025 18:55
@SWilson4
Copy link
Member Author

Well, for one, all CI should pass. Then review should be requested. Finally, there's the question whether, how and where this should be added to some application layer to prove actual utility. Any input on that @SWilson4 ?

@bifurcation Do you have any work on post-quantum MLS to point to here?

@baentsch
Copy link
Member

Currently, calls to the new API will fail for algorithms other than ML-KEM.

This statement I think is worth while documenting with higher visibility (README? Web site?): OQS by now clearly has pretty different levels of support for PQC algorithms also at the API level that I think users should be more prominently made aware of

  • APIs only implemented for ML-DSA and ML-KEM
  • A generally implemented API supported for all algorithms -- with some caveats:
    • other standardized algorithms are only included at a non-standard implementation level (Sphincs+/SLH-DSA, Falcon)
    • other standardized algorithms with some APIs disabled by default (XMSS, LMS)
    • "adjunct standard" algorithms (better wording welcome) like Frodo, Bike (?)
    • legacy algorithms like ntruprime, Kyber, Dilithium, HQC with limited update support
    • new standards-track proposals at different implementation levels like Cross, Mayo, hopefully UOV

The more I think about it, this seems worthy of a separate issue: This PR only contributes to an incoherence/deviation from the original OQS promise to support all PQC algorithms at equal measure that started earlier and goes deeper than just for this new API.

@dstebila
Copy link
Member

The more I think about it, this seems worthy of a separate issue: This PR only contributes to an incoherence/deviation from the original OQS promise to support all PQC algorithms at equal measure that started earlier and goes deeper than just for this new API.

I don't agree that OQS has such a promise. There are many examples in liboqs where different algorithms have had different support or treatment: e.g., how far they are through the standards process (selections/alternates), constant-time support, platform support, large-stack usage. We recently introduced the sign-with-context API because ML-DSA needed it. We shouldn't do this without thought, but I think it is quite reasonable that the more important algorithms (ML-KEM and ML-DSA) merit special treatment. I think it may be more true that consumers of liboqs (OQS Provider, the language wrappers) have taken more of the approach you mentioned.

We have an action item from the last TSC to document algorithm support, similar to PLATFORMS.md.

@bifurcation
Copy link

Well, for one, all CI should pass. Then review should be requested. Finally, there's the question whether, how and where this should be added to some application layer to prove actual utility. Any input on that @SWilson4 ?

@bifurcation Do you have any work on post-quantum MLS to point to here?

About a year ago, I did a prototype of XWing + MLS based on just copy/pasting the BoringSSL Kyber implementation into MLSpp. I'm eager to do a more proper version of that using libOQS (ideally using OpenSSL, but I can go direct as an intermediate step). This issue has been the major blocker on that.

@baentsch
Copy link
Member

I don't agree that OQS has such a promise.

I do recall very vividly hearing very regularly that "OQS does not pick winners" whenever I suggested dropping some support (e.g., testing, platform-specific optimizations, profiling support) for some algorithms: Did I dream this? This may, well, actually must, have changed in light of the apparent drop in community contributions towards OQS. But I don't think this (whether change or not) is goodness and a more impartial support for all possible PQC algorithms would be goodness for OQS to enable true apple-to-apples comparisons between PQC algs.

We have an action item from the last TSC to document algorithm support, similar to PLATFORMS.md.

True. Would be good to resolve. Maybe my list above could serve to deliver a top-line summary/starting point for that?

@baentsch
Copy link
Member

a prototype of XWing + MLS based on just copy/pasting the BoringSSL Kyber implementation into MLSpp.

That confuses me: According to its documentation, MLSpp is an

Implementation of the proposed Messaging Layer Security protocol in C++. Depends on C++17, STL for data structures, and OpenSSL or BoringSSL for crypto.

As both OpenSSL and BoringSSL support ML-KEM "natively" by now, what additional work is needed? What does liboqs add?

@dstebila
Copy link
Member

I don't agree that OQS has such a promise.

I do recall very vividly hearing very regularly that "OQS does not pick winners" whenever I suggested dropping some support (e.g., testing, platform-specific optimizations, profiling support) for some algorithms: Did I dream this? This may, well, actually must, have changed in light of the apparent drop in community contributions towards OQS. But I don't think this (whether change or not) is goodness and a more impartial support for all possible PQC algorithms would be goodness for OQS to enable true apple-to-apples comparisons between PQC algs.

Indeed we don't pick winners; that language is still in our README. But other people have picked winners, and I am in favour of giving the needs of those algorithms special consideration.

@SWilson4
Copy link
Member Author

Thank you @SWilson4 for adding this useful API. The integration looks good to me.

I do have one question: Is there a specific reason why this API has been added only for KEMs and not for Signatures? I'm asking because there is also the use case of generating the key from a seed in the IETF draft for ML-DSA signatures.

The original PR was only to support HPKE / MLS, and was made before the ML-KEM final standard was released (and all the discussion about seeds started in earnest). I imagine it would be straightforward to extend it to signatures (albeit only to ML-DSA for now) as well, if people would use the functionality. Does the use case from the IETF draft necessitate going through oqs-provider?

@Dimidroll1989
Copy link

Thank you @SWilson4 for adding this useful API. The integration looks good to me.
I do have one question: Is there a specific reason why this API has been added only for KEMs and not for Signatures? I'm asking because there is also the use case of generating the key from a seed in the IETF draft for ML-DSA signatures.

The original PR was only to support HPKE / MLS, and was made before the ML-KEM final standard was released (and all the discussion about seeds started in earnest). I imagine it would be straightforward to extend it to signatures (albeit only to ML-DSA for now) as well, if people would use the functionality. Does the use case from the IETF draft necessitate going through oqs-provider?

@SWilson4 thank you for adding this API. Regarding signatures I want to mention the use case from Post-Quantum PGP RFC where both ML-KEM and ML-DSA share same serialization format

@bhess
Copy link
Member

bhess commented Mar 18, 2025

The original PR was only to support HPKE / MLS, and was made before the ML-KEM final standard was released (and all the discussion about seeds started in earnest). I imagine it would be straightforward to extend it to signatures (albeit only to ML-DSA for now) as well, if people would use the functionality. Does the use case from the IETF draft necessitate going through oqs-provider?

I believe the key encoding/decoding functionality would be implemented in the oqs-provider, while liboqs would still need to provide an API for (re-)generating the keys from the seed. However, I think it's fine to proceed with merging this PR as is focusing only on the KEM API.

Eddy-M-K and others added 10 commits March 18, 2025 11:35
Signed-off-by: Eddy Kim <Eddy.M.Kim@outlook.com>
Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>

Add pqcrystals-ml_kem_ipd.patch

Signed-off-by: Eddy Kim <Eddy.M.Kim@outlook.com>
Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>

Fix encaps key in scheme and revert whitespace changes

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>

Hopefully corrected patch file

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>

Corrected missing derand in kem_scheme

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>

Fix indentation

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>

Run copy_from_upstream

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>

derand testing tentative changes

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>

Add missing function declarations

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>

Add template for avx2 derand functions

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>

Run copy_from_upstream

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>

WIP: Add changes for coin length

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>

Update patch to include coin lengths

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Bootstrap

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Conditional copy

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Run copy_from_upstream

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Separate coins variable into two distinct variables

Signed-off-by: Eddy Kim <Eddy.M.Kim@outlook.com>
Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Add derand fixes

- Add support for BIKE, FrodoKEM, sntrup
- Add hooks for testing
- Add missing kem comment to documentation
- Don't run decaps() in test_kem_derand if encaps_derand() fails
- Add markdown documentation changes

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

WIP trying to fix build errors

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Fix remaining build issues

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Resolve unused parameter issues for BIKE

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Resolve unused paramter issues for FrodoKEM

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Fix whitespace inconsistency

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Fix whitepace issue

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Insert unused attributes

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Void all unused parameters

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Use tab instead of spaces in kem_scheme

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Run copy_from_upstream

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Fix kem_derand python tests

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>

Initialize coins in test_kem_derand

Signed-off-by: Eddy Kim <e84kim@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>
@SWilson4
Copy link
Member Author

I've done a rebase to clean up the git history a little and run the extended tests. Once those pass, I will hit the "merge" button.

Regarding naming of the new API: in the absence of a strong consensus, I prefer "derand" as that has been in use by ML-KEM / Kyber implementations for some time and matches the naming conventions of our upstream sources.

Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>
Signed-off-by: Spencer Wilson <spencer.wilson@uwaterloo.ca>
@SWilson4 SWilson4 merged commit 3ca1a36 into main Mar 18, 2025
162 checks passed
@SWilson4 SWilson4 deleted the sw-mlkem-derand branch March 18, 2025 18:40
mkannwischer added a commit to pq-code-package/mlkem-native that referenced this pull request Apr 2, 2025
This updates liboqs to the most recent commit in main:
https://github.com/open-quantum-safe/liboqs/tree/6337a8424deae09aa835ddd920faff83a8f0e1d7

open-quantum-safe/liboqs#2070
reintroduced patching for mlkem-native to expose the keypair_derand functions.
This patching is no longer needed since
#886 got merged.
This commit hence adds to the liboqs test in CI the removal of the patch
in the copy_from_upstream.yml.

Signed-off-by: Matthias J. Kannwischer <matthias@kannwischer.eu>
mkannwischer added a commit to pq-code-package/mlkem-native that referenced this pull request Apr 2, 2025
This updates liboqs to the most recent commit in main:
https://github.com/open-quantum-safe/liboqs/tree/6337a8424deae09aa835ddd920faff83a8f0e1d7

open-quantum-safe/liboqs#2070
reintroduced patching for mlkem-native to expose the keypair_derand functions.
This patching is no longer needed since
#886 got merged.
This commit hence adds to the liboqs test in CI the removal of the patch
in the copy_from_upstream.yml.

Signed-off-by: Matthias J. Kannwischer <matthias@kannwischer.eu>
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.

Adding a DeriveKeyPair functionality

8 participants