-
Notifications
You must be signed in to change notification settings - Fork 1.7k
Add HPKE (Hybrid Public Key Encryption) support per RFC 9180 #14126
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
base: main
Are you sure you want to change the base?
Conversation
|
Please take a look at the failing CI jobs. |
770943f to
c8d3bd2
Compare
|
@reaperhulk @alex can you please review the PR and let me know the result? |
|
Please be more patient. This PR will get reviewed, but we all have day jobs. |
035856c to
d874aab
Compare
|
A few high level notes, I haven't reviewed in depth yet:
|
0811f29 to
065b482
Compare
alex
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I started reviewing, however I think my request on trimming this down was unclear:
We still want the initial PR to have the overall structure and final API we want, we just want to trim it down by implementing it for only one of the algorithms to reduce the code to review.
065b482 to
88b1024
Compare
alex
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The API here still doesn't match what was discussed on the issue, so I think we may be talking past each other. Can you explain why this has a different API?
API changes per maintainer feedback: - Add Suite(KEM, KDF, AEAD) class with RFC parameter order - Add KEM, KDF, AEAD enum types for algorithm selection - suite.sender(public_key, info) returns SenderContext - suite.recipient(enc, private_key, info) returns RecipientContext - First encrypt() returns enc || ciphertext concatenated - Subsequent encrypt() calls return just ciphertext - Use encrypt/decrypt method names - Simpler KEM names (X25519 instead of DHKEM_X25519_HKDF_SHA256) This matches the API discussed in issue pyca#14073 and addresses reviewer feedback about the API mismatch.
alex
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see you're still working, so submitting some quick comments.
Are you intended to submit the vectors as a seperate PR?
- Replace TypedDict with frozen dataclasses for parameter types - Use HKDF.extract() static method instead of hmac.digest - Remove base HPKEError class, keep only MessageLimitReachedError - Use if/elif instead of match for Python 3.8 compatibility
yes, I plan to submit the test vectors as a separate PR. should I create that PR now, or wait until the API design is finalized based on your feedback about the enc prepending behavior and thread safety concerns? |
|
The vectors can be submitted concurrently if they're ready, thanks. |
sure, I can work on the vectors PR after this one is merged to avoid having multiple open PRs on Gittensor. is there any other feedback on the current implementation I should address in the meantime? |
|
I don't know what a git tensor is, but that's not going to dictate our development processes. |
understood, apologies for the confusion. i'll prepare the vectors PR. in the meantime, are there any other changes needed on this PR? I'm still waiting on clarification about the enc prepending behavior (always vs first message only) and the thread safety concern you mentioned |
The type system guarantees only valid enum values can be passed to these internal functions, so use assert which is excluded from coverage.
|
thanks for merging my PR. could you please review the changes I made? |
|
It's on my TODO list. Unless we've been radio silent for several days, there's no need to follow up, we haven't forgotten. |
…ctors - Remove first_message special behavior from SenderContext and RecipientContext - encrypt() now always returns just ciphertext, enc accessed via property - Remove try/except Exception - AESGCM.decrypt raises InvalidTag directly - Update tests to use new API (enc via sender.enc property) - Add test vector loading from RFC 9180 vectors (when available) - Update docstring example to show correct usage
|
thanks for your feedback, just pushed the changes |
|
Hi, @reaperhulk and I discussed and we'd like to make the following changes to the API:
This should hopefully make the PR much simpler/shorter to get started. |
- Replace sender()/recipient() context methods with encrypt()/decrypt() - encrypt() returns enc || ciphertext (like Go's single-shot API) - decrypt() takes enc || ciphertext and returns plaintext - Make enum values opaque strings instead of RFC numeric values - Remove SenderContext, RecipientContext, MessageLimitReachedError - Update tests for new single-shot API
Updated to single-shot API per feedback:
|
- Remove docstrings (prose docs only) - Use load_vectors_from_file helper - Use [] instead of .get() for vector keys - Parameterize roundtrip tests by KEM/KDF/AEAD - Merge error test class into main test class - Use subtest fixture instead of parametrize for vectors - Remove test_load_vectors_missing_file test - Load vectors inside test function, not at module level
Add HPKE (Hybrid Public Key Encryption) support per RFC 9180
Summary
This implements HPKE Base mode as defined in RFC 9180, providing a simple single-shot API for hybrid public key encryption.
What's Included
suite.encrypt()andsuite.decrypt()methodsAPI Design
Design Decisions
enc || ctformat: Like Go's single-shot HPKE APICloses
Closes #14073