feat: [NET-1445] quantum resistant key exchange using ML-KEM#3060
Merged
feat: [NET-1445] quantum resistant key exchange using ML-KEM#3060
Conversation
teogeb
reviewed
Apr 2, 2025
Contributor
teogeb
left a comment
There was a problem hiding this comment.
Looks good! 👍 We should keep the EncryptedGroupKey type in the exports.ts, otherwise all ok.
jtakalai
reviewed
Apr 2, 2025
teogeb
approved these changes
Apr 3, 2025
jtakalai
pushed a commit
that referenced
this pull request
May 20, 2025
## Summary This PR introduces the ability to use (and to require the use of) `ML-KEM` for key exchange instead of `RSA`. The former is considered quantum resistant, while the latter is not. This PR does not change the defaults, but introduces a new config option to enable the use of the new quantum resistant algorithm. Implementing the new algorithm itself was straight forward, but certain refactoring was necessary to use it. Most of the line changes in this PR are actually related to that refactoring instead of the core feature itself. **Backwards compatibility** The change is backwards compatible with the default settings, ie. the change is not breaking as such. However, the new feature can obviously only be used if both the publisher and subscriber have the new version. Backwards compatibility with the previous version was tested manually, and the results are as expected - ie. key exchange works with default (non-quantum-secure) settings, but fails if `requireQuantumResistantKeyExchange` is `true`, as the other side running the old version doesn't support the new algorithm. ## Changes - Implement encryption and decryption using `ML-KEM` in `EncryptionUtil` - Refactor interfaces in `EncryptionUtil` to be unified across different algorithms - Add a new `StreamrClient` config option under the `encryption` block: `requireQuantumResistantKeyExchange: <boolean>` (default: false) - Update `SubscriberKeyExchange` and `PublisherKeyExchange` to read that config option and act accordingly - Add to `GroupKeyRequest` and `GroupKeyResponse` protobuf messages an `encryptionType` field, the value of which is an `AsymmetricEncryptionType` enum. For backwards compatibility, the absence of this field is interpreted to imply RSA. - Refactor away the technical debt of `OldGroupKeyRequest` and `OldGroupKeyResponse` vs. `NewGroupKeyRequest` and `NewGroupKeyResponse` mess and get rid of `GroupKeyRequestTranslator`. Now, the "new" group key classes (generated from protobuf) are used everywhere, and the old hand-rolled ones have been deleted. - Add unit test cases for `EncryptionUtil` and integration test cases for `SubscriberKeyExchange` and `PublisherKeyExchange` - Add a section to the end-to-end encryption page in the docs, describing the new feature - Add a `--quantum` flag to the CLI tool to flip on the new switch ## Limitations and future improvements - Refactoring away the `OldStreamMessage` / `NewStreamMessage` / `StreamMessageTranslator` debt is out of scope, the old vs. new classes issue was only cleaned up in relation to the group key classes, as only they were relevant to the feature. - In the future, encryption preferences could come from stream metadata by default, instead of explicit local config ## Checklist before requesting a review - [x] Is this a breaking change? If it is, be clear in summary. **-> (No)** - [x] Read through code myself one more time. - [x] Make sure any and all `TODO` comments left behind are meant to be left in. - [x] Has reasonable passing test coverage? - [x] Updated changelog if applicable. - [x] Updated documentation if applicable.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
This PR introduces the ability to use (and to require the use of)
ML-KEMfor key exchange instead ofRSA. The former is considered quantum resistant, while the latter is not. This PR does not change the defaults, but introduces a new config option to enable the use of the new quantum resistant algorithm.Implementing the new algorithm itself was straight forward, but certain refactoring was necessary to use it. Most of the line changes in this PR are actually related to that refactoring instead of the core feature itself.
Backwards compatibility
The change is backwards compatible with the default settings, ie. the change is not breaking as such. However, the new feature can obviously only be used if both the publisher and subscriber have the new version.
Backwards compatibility with the previous version was tested manually, and the results are as expected - ie. key exchange works with default (non-quantum-secure) settings, but fails if
requireQuantumResistantKeyExchangeistrue, as the other side running the old version doesn't support the new algorithm.Changes
ML-KEMinEncryptionUtilEncryptionUtilto be unified across different algorithmsStreamrClientconfig option under theencryptionblock:requireQuantumResistantKeyExchange: <boolean>(default: false)SubscriberKeyExchangeandPublisherKeyExchangeto read that config option and act accordinglyGroupKeyRequestandGroupKeyResponseprotobuf messages anencryptionTypefield, the value of which is anAsymmetricEncryptionTypeenum. For backwards compatibility, the absence of this field is interpreted to imply RSA.OldGroupKeyRequestandOldGroupKeyResponsevs.NewGroupKeyRequestandNewGroupKeyResponsemess and get rid ofGroupKeyRequestTranslator. Now, the "new" group key classes (generated from protobuf) are used everywhere, and the old hand-rolled ones have been deleted.EncryptionUtiland integration test cases forSubscriberKeyExchangeandPublisherKeyExchange--quantumflag to the CLI tool to flip on the new switchLimitations and future improvements
OldStreamMessage/NewStreamMessage/StreamMessageTranslatordebt is out of scope, the old vs. new classes issue was only cleaned up in relation to the group key classes, as only they were relevant to the feature.Checklist before requesting a review
TODOcomments left behind are meant to be left in.