Repository navigation
Dev - #45
Merged
Merged
Dev#45
Conversation
You can now decapsulate with your own custom private key. ```python shared_secret = pykyber.Kyber768.decapsulate(ciphertext, secret_key) ```
In the new versions I added the dataclass to make the usage of the lib more verbose. This broke the usage of lower versions, so I made it such that even if you use it like the older versions it will still work. ```python public_key, secret_key = pykyber.Kyber1024() ciphertext, shared_secret = keypair.encapsulate() ```
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
All four file kinds (seed decapsulation, encapsulation, key generation from a seed, semi-expanded decapsulation) for the three parameter sets, pinned to a commit and a SHA-256 per file in the manifest. The result rule of the schema is applied as written. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
A dev-only differential test (ml-kem 0.3.3, FIPS 203 final) over a fixed-seed generator: keygen from a seed, encaps with a given m, decaps of valid, bit-flipped and random ciphertexts, decaps under a changed dk_PKE or z, and the modulus and hash checks after random byte changes. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The mask built from a message bit in the legacy poly_frommsg is the pattern behind CVE-2024-37880 (Clangover), where a compiler turned it into a branch. Route the bit and the mask through core::hint::black_box. Output is unchanged; the golden vectors pass. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Route the accumulated difference, the flag and the select mask through core::hint::black_box, the same idea as mlkem::ct, so the compiler cannot prove the mask is 0 or 0xff and turn the select into a branch. The release disassembly shows setne/cset and a vector select with no branch on the compare result. Output is unchanged; the golden vectors pass. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Key generation and encapsulation in the Python bindings used thread_rng(). Use rand::rngs::OsRng, call try_fill_bytes in the legacy KEM functions, and return KyberError::RandomBytesGeneration when the generator fails instead of panicking. Wipe the half-built secret key when the second draw (z) fails and hold the partly filled seed in Zeroizing. The Python wrappers keep the RandomnessError subclass instead of re-wrapping it. Seeded paths and the golden vectors are unchanged; the random-fill order and sizes are as before. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Hold m', the KDF input and the re-encrypted ciphertext of crypto_kem_dec* in Zeroizing so they are wiped on every exit, unwinding included, and keep the implicit-rejection flag in Zeroizing<u8>. The PRF output buffers in poly_getnoise_* are the secret noise (the key in key generation, r in encryption) and were never wiped; wipe them too. The release disassembly shows the wipe of the flag and the buffers on both the normal and the cleanup path. Add a test for the implicit-rejection output, derived from z and H(c), for all three levels; it also passes on the commit before this series. Output is unchanged and the golden vectors pass. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…the secret key Kyber512/768/1024.from_keys accepted any public key and secret key of the right sizes, so a pair from two different key pairs built a keypair whose decapsulate silently returned a different secret than encapsulate had produced. The round-3 secret key embeds the public key (sk_pke || pk || H(pk) || z), so compare the two (both are public) and raise KyberError on a mismatch. The offset comes from named constants. A wrong-size secret key keeps its existing size error at use. Approved by the maintainer in the discussion on issue #18; ML_KEM_*.from_keys is not changed. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The legacy bindings returned secret keys and shared secrets as Vec<u8>, which PyO3 turns into bytes and then frees with the secret still in the allocation. Hand them over as a SecretBytes wrapper that builds the bytes object and then wipes the Rust buffer, and wipe the fixed-size copy from the safe API. The Python object itself cannot be wiped. Output is unchanged. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
The seeded derive path hands the KEM code a stand-in generator that is never asked for bytes. Now that the legacy code draws randomness through try_fill_bytes, make that method return an error, so a future change that reaches it gets RandomBytesGeneration and not a panic. No path from Python reaches it today. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ation functions crypto_kem_keypair* and crypto_kem_enc* indexed caller-supplied pk, sk, ct, ss and seed slices without checking their lengths, unlike decapsulation, so a Rust caller with a short buffer panicked. Return InvalidInput instead. The Python bindings already size every buffer, so no Python path reaches this. Output is unchanged; the golden vectors pass. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Lockfile-only patch bump of an existing dependency. The advisory needs the log feature, which pykyber does not enable, so it was not reachable here; the legacy bindings no longer use thread_rng at all. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…TY.md Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CXWjkNs3Htog36snV9FcXb
The old benchmark parsed the Kyber performance tests only and its figures came from a debug build. benchmark.py now times ML_KEM_* and Kyber* directly (median of 7 rounds of 500 calls), writes results.json, and draws two charts that replace the four old ones. make benchmark builds the release extension first. The chart dependency is in performance-tests/requirements.txt, not in requirements-dev.txt. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CXWjkNs3Htog36snV9FcXb
Same facts, fewer words: install, quick start, a shorter class tour, sizes, errors, the Kyber deprecation, security status and the new benchmark table and charts. Every Python block in it was run, and the error message it shows is the real one. The performance section now says what was measured and on what. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CXWjkNs3Htog36snV9FcXb
Adds LICENSE-MIT and LICENSE-APACHE (the Apache text is the apache.org file, 11358 bytes, SHA-256 cfc7749b...523d30) and removes LICENSE. Sets license = "MIT OR Apache-2.0" in Cargo.toml and pyproject.toml, with license-files, and drops the Public Domain classifier. The built wheel's METADATA has License-Expression: MIT OR Apache-2.0 and ships both files. Releases up to 1.0.5 stay under the Unlicense; the README, CONTRIBUTING.md, the changelog and the agent notes say so. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01CXWjkNs3Htog36snV9FcXb
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
…ents file Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com>
main holds the 1.0.x release history; dev already contains all of its content (including the Android CI fixes) plus the 2.0 work, so the tree is unchanged. This only joins the histories so the dev -> main PR merges cleanly.
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.
No description provided.