Skip to content

Commit 484eb25

Browse files
committed
improve mlkem-ot-protocol
1 parent dc4561f commit 484eb25

File tree

1 file changed

+10
-12
lines changed

1 file changed

+10
-12
lines changed

cryprot-ot/docs/mlkem-ot-protocol.md

Lines changed: 10 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
# ML-KEM OT Protocol
22

3-
Based on MR19 (Masny-Rindal, ePrint 2019/706), Figure 8, instantiated with ML-KEM per Section D.3.
3+
Based on MR19 (Masny-Rindal, ePrint 2019/706), Figure 8, instantiated with ML-KEM instead of Crystals-Kyber, as per Section D.3.
44

5-
Reference implementation: [libOTe KyberOT]([](https://github.com/osu-crypto/libOTe/blob/d0e499206d1d4d16c6b4ca6c0e712490e0632f80/thirdparty/KyberOT/KyberOT.c#L40-L41)).
5+
Reference implementation: [libOTe KyberOT](https://github.com/osu-crypto/libOTe/blob/d0e499206d1d4d16c6b4ca6c0e712490e0632f80/thirdparty/KyberOT/KyberOT.c#L40-L41).
66

7-
ML-KEM implementation: [ML-KEM]([](https://github.com/RustCrypto/KEMs/blob/5a7f3ab7af5420cacca9befc9212532e4c7f6ca1/ml-kem/src/)).
7+
ML-KEM implementation: [ML-KEM](https://github.com/RustCrypto/KEMs/blob/5a7f3ab7af5420cacca9befc9212532e4c7f6ca1/ml-kem/src/).
88

99
## Notation
1010

@@ -30,7 +30,7 @@ where:
3030
- `t_hat` is an `NttVector<k>`: the public key vector in NTT domain (`t_hat = A_hat * s + e` in NTT form)
3131
- `rho` is a 32-byte seed used to derive the public matrix `A_hat`
3232

33-
Note that the ML-KEM encapsulation key is the same as the K-PKE encryption key in our simplified outline above.
33+
Note that the ML-KEM encapsulation key is the same as the K-PKE encryption key (FIPS 203, Section 5).
3434

3535
The serialized form is:
3636

@@ -65,16 +65,14 @@ for j in 0..k:
6565
```
6666

6767
Each call uses different index bytes `(j, 0)` in FIPS 203 Algorithm 7 for domain separation.
68-
In libOTe, this corresponds to `randomPK`, where it instead generates `A_hat` and takes a single
69-
row or column from it.
68+
In libOTe, this corresponds to `randomPK`, where it instead generates `A_hat` and takes the first row from it.
7069

7170
Output: `(t_hat, rho)`. The `rho` is passed through unchanged.
7271

7372
**`H(ek) -> (h, ek.rho)`**
7473

7574
Hash-to-key (corresponds to libOTe's `pkHash`). Maps an encapsulation key to another
76-
encapsulation key. Takes an element of `T_q^k`, hashes it
77-
to a 32-byte seed, and uses that seed to sample a new element of `T_q^k`.
75+
encapsulation key. Takes an element of `T_q^k`, hashes it to a 32-byte seed, and uses that seed to sample a new element of `T_q^k`.
7876

7977
Given an encapsulation key `ek = (t_hat, rho)`:
8078

@@ -85,7 +83,7 @@ h = SampleNTTVector(seed, ek.rho) // sample a new NttVector<k> from t
8583

8684
Output: `(h, ek.rho)` where `h` is an `NttVector<k>` in `T_q^k`.
8785

88-
**`RandomEK(seed, rho) -> (r_hat, rho)`**
86+
**`RandomEK(seed, rho) -> (t_hat, rho)`**
8987

9088
Generate a random encapsulation key from the given random 32 byte `seed` and `rho`:
9189

@@ -140,7 +138,7 @@ component only. The `rho` component is always the same across all keys in a sing
140138
```
141139
Each `ss_j` is a 32-byte ML-KEM shared secret. Each `ct_j` is an ML-KEM ciphertext.
142140

143-
8. **Derive OT output keys**
141+
8. **Derive OT output keys**
144142

145143
Hashing each shared secret down to a 128-bit `Block`:
146144
```
@@ -168,7 +166,7 @@ component only. The `rho` component is always the same across all keys in a sing
168166
```
169167
key_b = RO(domain_sep || ss_b || i)
170168
```
171-
The receiver stores `ots[i] = key_b` — one OT output key for OT `i` batch in the batch.
169+
The receiver stores `ots[i] = key_b` — one OT output key for the `i`-th OT in the batch.
172170
173171
## Why This Works
174172
@@ -199,7 +197,7 @@ cancel with `H(r_{1-b})`. The result `ek_{1-b}` is an unrelated key for which th
199197
receiver does not have a decapsulation key `dk`, so they cannot decapsulate `ct_{1-b}`.
200198
201199
The choice bit `b` is hidden because `r_b = ek - H(r_{1-b})`. Since `ek` is
202-
indistinguishable from uniform under MLWE, and `H(r_{1-b})` is determined by the
200+
indistinguishable from uniform under the MLWE assumption, and `H(r_{1-b})` is determined by the
203201
already-public `r_{1-b}`, subtracting it from a uniform value still yields a uniform
204202
value. So both `r_0` and `r_1` appear uniform to the sender — neither reveals which
205203
is the real key.

0 commit comments

Comments
 (0)