Skip to content

Commit f45201a

Browse files
authored
Merge pull request #84 from GiacomoPope/mlkem
align ML-KEM to FIPS 203 (final)
2 parents d167493 + 7965605 commit f45201a

22 files changed

+4556
-33210
lines changed

README.md

+13-21
Original file line numberDiff line numberDiff line change
@@ -16,20 +16,16 @@ applications.** :warning:
1616
1717
This repository contains a pure python implementation of both:
1818

19-
1. **CRYSTALS-Kyber**: following (at the time of writing) the most recent
19+
1. **ML-KEM**: The NIST Module-Lattice-Based Key-Encapsulation Mechanism
20+
Standard following the [FIPS 203](https://csrc.nist.gov/pubs/fips/203/final)
21+
to the NIST post-quantum cryptography project.
22+
2. **CRYSTALS-Kyber**: following (at the time of writing) the most recent
2023
[specification](https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf)
2124
(v3.02)
22-
2. **ML-KEM**: The NIST Module-Lattice-Based Key-Encapsulation Mechanism
23-
Standard following the [FIPS 203 (Initial Public
24-
Draft)](https://csrc.nist.gov/pubs/fips/203/ipd) based off the Kyber submission
25-
to the NIST post-quantum cryptography project.
26-
27-
The API is not stable, significant changes to it may occur until
28-
FIPS 203 is finalized.
2925

3026
**Note**: This project accompanies
3127
[`dilithium-py`](https://github.com/GiacomoPope/dilithium-py) which is a
32-
pure-python implementation of CRYSTALS-Dilithium and ML-DSA and shares a lot of
28+
pure-python implementation of ML-DSA and CRYSTALS-Dilithium and shares a lot of
3329
the lower-level code of this implementation.
3430

3531
## Disclaimer
@@ -39,8 +35,8 @@ to learn about how Kyber works, and to try and create a clean, well commented
3935
implementation which people can learn from.
4036

4137
This code is not constant time, or written to be performant. Rather, it was
42-
written so that the python code closely follows Algorithms 1-9 in the original
43-
[specification](https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf).
38+
written so that the python code closely follows the Kyber specification
39+
[specification](https://pq-crystals.org/kyber/data/kyber-specification-round3-20210804.pdf) and [FIPS 203](https://csrc.nist.gov/pubs/fips/203/final). To cryptographic guarantees are made of this work.
4440

4541
## History of this Repository
4642

@@ -64,7 +60,7 @@ The KAT files were either downloaded or generated:
6460
repository](https://github.com/pq-crystals/kyber/) and are included in
6561
`assets/PQCLkemKAT_*.rsp`
6662
2. For **ML-KEM**, the KAT files were download from the GitHub repository
67-
[post-quantum-cryptography/KAT](https://github.com/post-quantum-cryptography/KAT/tree/main/MLKEM) and are included in `assets/kat_MLKEM_*.rsp`
63+
[usnistgov/ACVP-Server/](https://github.com/usnistgov/ACVP-Server/releases/tag/v1.1.0.35) release 1.1.0.35, and are included in `assets/ML-KEM-*` directories.
6864

6965
**Note**: for Kyber v3.02, there is a discrepancy between the specification and
7066
reference implementation. To ensure all KATs pass, one has to generate the
@@ -91,15 +87,15 @@ use:
9187

9288
- `ML_KEM.keygen()`: generate a keypair `(ek, dk)`
9389
- `ML_KEM.encaps(ek)`: generate a key and ciphertext pair `(key, ct)`
94-
- `ML_KEM.decaps(ct, dk)`: generate the shared key `key`
90+
- `ML_KEM.decaps(dk, ct)`: generate the shared key `key`
9591

9692
#### Example
9793

9894
```python
9995
>>> from kyber_py.ml_kem import ML_KEM_512
10096
>>> ek, dk = ML_KEM_512.keygen()
10197
>>> key, ct = ML_KEM_512.encaps(ek)
102-
>>> _key = ML_KEM_512.decaps(ct, dk)
98+
>>> _key = ML_KEM_512.decaps(dk, ct)
10399
>>> assert key == _key
104100
```
105101

@@ -122,15 +118,15 @@ use:
122118

123119
- `Kyber.keygen()`: generate a keypair `(pk, sk)`
124120
- `Kyber.encaps(pk)`: generate shared key and challenge `(key, c)`
125-
- `Kyber.decaps(c, sk)`: generate the shared key `key`
121+
- `Kyber.decaps(sk, c)`: generate the shared key `key`
126122

127123
#### Example
128124

129125
```python
130126
>>> from kyber_py.kyber import Kyber512
131127
>>> pk, sk = Kyber512.keygen()
132128
>>> key, c = Kyber512.encaps(pk)
133-
>>> _key = Kyber512.decaps(c, sk)
129+
>>> _key = Kyber512.decaps(sk, c)
134130
>>> assert key == _key
135131
```
136132

@@ -157,7 +153,7 @@ currently only support $q = 3329$ and $n = 256$.
157153

158154
All times recorded using a Intel Core i7-9750H CPU and averaged over 1000 runs.
159155

160-
## Documentation (under active development)
156+
## Documentation
161157

162158
- https://kyber-py.readthedocs.io/en/latest/
163159

@@ -243,10 +239,6 @@ function on every polynomial.
243239
computing `f.compress(d).decompress(d)`. They are however *close*. See the
244240
specification for more information.
245241

246-
### Number Theoretic Transform
247-
248-
**TODO**: it would be good to write something more detailed here.
249-
250242
### Modules
251243

252244
Building on `polynomials_generic.py` we also include a file

assets/ML-KEM-encapDecap-FIPS203/expectedResults.json

+534
Large diffs are not rendered by default.

assets/ML-KEM-encapDecap-FIPS203/internalProjection.json

+1,023
Large diffs are not rendered by default.

assets/ML-KEM-encapDecap-FIPS203/prompt.json

+555
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
{
2+
"vsId": 42,
3+
"algorithm": "ML-KEM",
4+
"mode": "encapDecap",
5+
"revision": "FIPS203",
6+
"isSample": true,
7+
"parameterSets": [
8+
"ML-KEM-512",
9+
"ML-KEM-768",
10+
"ML-KEM-1024"
11+
],
12+
"functions": [
13+
"encapsulation",
14+
"decapsulation"
15+
]
16+
}

0 commit comments

Comments
 (0)