Switch ML-KEM private key format to seed-only instead of semi-expanded
enhancement
Currently, the ML-KEM implementation uses the semi-expanded private key format (includes `sk`, `pk`, `H(pk)`, `z`), as defined by [FIPS 203](https://csrc.nist.gov/pubs/fips/203/final). While compliant, this format introduces unnecessary complexity and opens the door to subtle misbinding attacks.
## Why switch to seeds
- **Compact:**
For ML-KEM-1024:
- Semi-expanded private key = **3168 bytes**
- Seed format (`d || z`) = **64 bytes**
- **Safe:**
Avoids attacks like `MAL-BIND-K-PK` and `MAL-BIND-K-CT` [1]
- **Clean:**
No need to validate hash consistency (`H(pk)` check), field element bounds, or serialization correctness.
- **Consensus forming:**
RustCrypto [2], Go stdlib [3], and IETF participants [4] are already converging on seed-only formats for simplicity and safety.
## Plan
This affects MLA new key format currently opened PR (https://github.com/ANSSI-FR/MLA/pull/317). We have to:
- [ ] Replace semi-expanded key format with `(d || z)` seed
- [ ] Derive full key with `KeyGen(seed)` internally
- [ ] Drop support for expanded key deserialization
- [ ] Ensure test vectors (e.g. Wycheproof, CCTV) are compatible or regenerated using seeds
## References
[1] [Attack breakdown : Unbindable Kemmy Schmidt](https://keymaterial.net/2024/09/14/unbindable-kemmy-schmidt/)
[2] [RustCrypto discussion](https://github.com/RustCrypto/signatures/issues/908#issuecomment-3079686882)
[3] [Filippo’s call to action](https://words.filippo.io/ml-kem-seeds/)
[4] [Serialization pitfalls](https://keymaterial.net/2025/02/19/how-not-to-format-a-private-key/)
关闭于 2025-07-24 1 条评论