authorgravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2024-08-22 01:00:12+02:00
committergravatar for 124872+jedisct1@users.noreply.github.comFrank Denis <124872+jedisct1@users.noreply.github.com> 2024-08-22 01:00:12+02:00
log067ae04e0b34bfba9bdb192705731fbf9801e69f
tree679af89fe447a340743263596b72f5e3be831b8d
parent5bf9dc3850117c85fb124cc481d4a284e2c8504d

Update ML-KEM to the final specification

NIST has published the final specification of ML-KEM, which adds domain separation to the seed used to create the inner secret key.

1 files changed, 13 insertions(+), 10 deletions(-)

lib/std/crypto/ml_kem.zig+13-10
...@@ -1,12 +1,10 @@...@@ -1,12 +1,10 @@
1//! Implementation of the IND-CCA2 post-quantum secure key encapsulation mechanism (KEM)1//! Implementation of the IND-CCA2 post-quantum secure key encapsulation mechanism (KEM)
2//! ML-KEM (NIST FIPS-203 publication) and CRYSTALS-Kyber (v3.02/"draft00" CFRG draft).2//! ML-KEM (NIST FIPS-203 publication) and CRYSTALS-Kyber (v3.02/"draft00" CFRG draft).
3//!3//!
4//! The schemes are not finalized yet, and are still subject to breaking changes.
5//!
6//! The Kyber namespace suffix (currently `_d00`) refers to the version currently4//! The Kyber namespace suffix (currently `_d00`) refers to the version currently
7//! implemented, in accordance with the draft.5//! implemented, in accordance with the CFRG draft.
8//! The ML-KEM namespace suffix (currently `_01`) refers to the NIST FIPS-203 draft6//!
9//! published on August 24, 2023, with the unintentional transposition of  having been reverted.7//! The ML-KEM namespace refers to the FIPS-203 publication.
10//!8//!
11//! Suffixes may not be updated if new versions of the documents only include editorial changes.9//! Suffixes may not be updated if new versions of the documents only include editorial changes.
12//! The suffixes will be removed once the schemes are finalized.10//! The suffixes will be removed once the schemes are finalized.
...@@ -174,7 +172,9 @@ pub const kyber_d00 = struct {...@@ -174,7 +172,9 @@ pub const kyber_d00 = struct {
174 });172 });
175};173};
176174
177pub const ml_kem_01 = struct {175pub const ml_kem_01 = @compileError("deprecated: final version of the specification has been published, use ml_kem instead");
176
177pub const ml_kem = struct {
178 pub const MLKem512 = Kyber(.{178 pub const MLKem512 = Kyber(.{
179 .name = "ML-KEM-512",179 .name = "ML-KEM-512",
180 .ml_kem = true,180 .ml_kem = true,
...@@ -207,9 +207,9 @@ const modes = [_]type{...@@ -207,9 +207,9 @@ const modes = [_]type{
207 kyber_d00.Kyber512,207 kyber_d00.Kyber512,
208 kyber_d00.Kyber768,208 kyber_d00.Kyber768,
209 kyber_d00.Kyber1024,209 kyber_d00.Kyber1024,
210 ml_kem_01.MLKem512,210 ml_kem.MLKem512,
211 ml_kem_01.MLKem768,211 ml_kem.MLKem768,
212 ml_kem_01.MLKem1024,212 ml_kem.MLKem1024,
213};213};
214const h_length: usize = 32;214const h_length: usize = 32;
215const inner_seed_length: usize = 32;215const inner_seed_length: usize = 32;
...@@ -505,7 +505,10 @@ fn Kyber(comptime p: Params) type {...@@ -505,7 +505,10 @@ fn Kyber(comptime p: Params) type {
505 // Derives inner PKE keypair from given seed.505 // Derives inner PKE keypair from given seed.
506 fn innerKeyFromSeed(seed: [inner_seed_length]u8, pk: *InnerPk, sk: *InnerSk) void {506 fn innerKeyFromSeed(seed: [inner_seed_length]u8, pk: *InnerPk, sk: *InnerSk) void {
507 var expanded_seed: [64]u8 = undefined;507 var expanded_seed: [64]u8 = undefined;
508 sha3.Sha3_512.hash(&seed, &expanded_seed, .{});508 var h = sha3.Sha3_512.init(.{});
509 if (p.ml_kem) h.update(&[1]u8{p.k});
510 h.update(&seed);
511 h.final(&expanded_seed);
509 pk.rho = expanded_seed[0..32].*;512 pk.rho = expanded_seed[0..32].*;
510 const sigma = expanded_seed[32..64];513 const sigma = expanded_seed[32..64];
511 pk.aT = M.uniform(pk.rho, false); // Expand ρ to A; we'll transpose later on514 pk.aT = M.uniform(pk.rho, false); // Expand ρ to A; we'll transpose later on