From 067ae04e0b34bfba9bdb192705731fbf9801e69f Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Thu, 22 Aug 2024 01:00:12 +0200 Subject: [PATCH 1/2] 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. --- lib/std/crypto/ml_kem.zig | 23 +++++++++++++---------- 1 file changed, 13 insertions(+), 10 deletions(-) diff --git a/lib/std/crypto/ml_kem.zig b/lib/std/crypto/ml_kem.zig index 00eade1c71..bbea58e254 100644 --- a/lib/std/crypto/ml_kem.zig +++ b/lib/std/crypto/ml_kem.zig @@ -1,12 +1,10 @@ //! Implementation of the IND-CCA2 post-quantum secure key encapsulation mechanism (KEM) //! ML-KEM (NIST FIPS-203 publication) and CRYSTALS-Kyber (v3.02/"draft00" CFRG draft). //! -//! The schemes are not finalized yet, and are still subject to breaking changes. -//! //! The Kyber namespace suffix (currently `_d00`) refers to the version currently -//! implemented, in accordance with the draft. -//! The ML-KEM namespace suffix (currently `_01`) refers to the NIST FIPS-203 draft -//! published on August 24, 2023, with the unintentional transposition of  having been reverted. +//! implemented, in accordance with the CFRG draft. +//! +//! The ML-KEM namespace refers to the FIPS-203 publication. //! //! Suffixes may not be updated if new versions of the documents only include editorial changes. //! The suffixes will be removed once the schemes are finalized. @@ -174,7 +172,9 @@ pub const kyber_d00 = struct { }); }; -pub const ml_kem_01 = struct { +pub const ml_kem_01 = @compileError("deprecated: final version of the specification has been published, use ml_kem instead"); + +pub const ml_kem = struct { pub const MLKem512 = Kyber(.{ .name = "ML-KEM-512", .ml_kem = true, @@ -207,9 +207,9 @@ const modes = [_]type{ kyber_d00.Kyber512, kyber_d00.Kyber768, kyber_d00.Kyber1024, - ml_kem_01.MLKem512, - ml_kem_01.MLKem768, - ml_kem_01.MLKem1024, + ml_kem.MLKem512, + ml_kem.MLKem768, + ml_kem.MLKem1024, }; const h_length: usize = 32; const inner_seed_length: usize = 32; @@ -505,7 +505,10 @@ fn Kyber(comptime p: Params) type { // Derives inner PKE keypair from given seed. fn innerKeyFromSeed(seed: [inner_seed_length]u8, pk: *InnerPk, sk: *InnerSk) void { var expanded_seed: [64]u8 = undefined; - sha3.Sha3_512.hash(&seed, &expanded_seed, .{}); + var h = sha3.Sha3_512.init(.{}); + if (p.ml_kem) h.update(&[1]u8{p.k}); + h.update(&seed); + h.final(&expanded_seed); pk.rho = expanded_seed[0..32].*; const sigma = expanded_seed[32..64]; pk.aT = M.uniform(pk.rho, false); // Expand ρ to A; we'll transpose later on From b131b6dd3639ff4c449c73978ddc77f51161fd9b Mon Sep 17 00:00:00 2001 From: Frank Denis Date: Thu, 22 Aug 2024 07:54:12 +0200 Subject: [PATCH 2/2] Rename the namespace for ml_kem variants of Kyber to nist --- lib/std/crypto.zig | 5 +++-- lib/std/crypto/ml_kem.zig | 33 +++++++++++++-------------------- 2 files changed, 16 insertions(+), 22 deletions(-) diff --git a/lib/std/crypto.zig b/lib/std/crypto.zig index 186f287fdd..aa524fa2c2 100644 --- a/lib/std/crypto.zig +++ b/lib/std/crypto.zig @@ -74,8 +74,9 @@ pub const dh = struct { /// Key Encapsulation Mechanisms. pub const kem = struct { - pub const kyber_d00 = @import("crypto/ml_kem.zig").kyber_d00; - pub const ml_kem_01 = @import("crypto/ml_kem.zig").ml_kem_01; + pub const kyber_d00 = @import("crypto/ml_kem.zig").d00; + pub const ml_kem = @import("crypto/ml_kem.zig").nist; + pub const ml_kem_01 = @compileError("deprecated: final version of the specification has been published, use ml_kem instead"); }; /// Elliptic-curve arithmetic. diff --git a/lib/std/crypto/ml_kem.zig b/lib/std/crypto/ml_kem.zig index bbea58e254..9a3a35492c 100644 --- a/lib/std/crypto/ml_kem.zig +++ b/lib/std/crypto/ml_kem.zig @@ -1,13 +1,8 @@ //! Implementation of the IND-CCA2 post-quantum secure key encapsulation mechanism (KEM) //! ML-KEM (NIST FIPS-203 publication) and CRYSTALS-Kyber (v3.02/"draft00" CFRG draft). //! -//! The Kyber namespace suffix (currently `_d00`) refers to the version currently -//! implemented, in accordance with the CFRG draft. -//! -//! The ML-KEM namespace refers to the FIPS-203 publication. -//! -//! Suffixes may not be updated if new versions of the documents only include editorial changes. -//! The suffixes will be removed once the schemes are finalized. +//! The namespace `d00` refers to the version currently implemented, in accordance with the CFRG draft. +//! The `nist` namespace refers to the FIPS-203 publication. //! //! Quoting from the CFRG I-D: //! @@ -146,7 +141,7 @@ const Params = struct { dv: u8, }; -pub const kyber_d00 = struct { +pub const d00 = struct { pub const Kyber512 = Kyber(.{ .name = "Kyber512", .k = 2, @@ -172,9 +167,7 @@ pub const kyber_d00 = struct { }); }; -pub const ml_kem_01 = @compileError("deprecated: final version of the specification has been published, use ml_kem instead"); - -pub const ml_kem = struct { +pub const nist = struct { pub const MLKem512 = Kyber(.{ .name = "ML-KEM-512", .ml_kem = true, @@ -204,12 +197,12 @@ pub const ml_kem = struct { }; const modes = [_]type{ - kyber_d00.Kyber512, - kyber_d00.Kyber768, - kyber_d00.Kyber1024, - ml_kem.MLKem512, - ml_kem.MLKem768, - ml_kem.MLKem1024, + d00.Kyber512, + d00.Kyber768, + d00.Kyber1024, + nist.MLKem512, + nist.MLKem768, + nist.MLKem1024, }; const h_length: usize = 32; const inner_seed_length: usize = 32; @@ -1725,9 +1718,9 @@ const sha2 = crypto.hash.sha2; test "NIST KAT test" { inline for (.{ - .{ kyber_d00.Kyber512, "e9c2bd37133fcb40772f81559f14b1f58dccd1c816701be9ba6214d43baf4547" }, - .{ kyber_d00.Kyber1024, "89248f2f33f7f4f7051729111f3049c409a933ec904aedadf035f30fa5646cd5" }, - .{ kyber_d00.Kyber768, "a1e122cad3c24bc51622e4c242d8b8acbcd3f618fee4220400605ca8f9ea02c2" }, + .{ d00.Kyber512, "e9c2bd37133fcb40772f81559f14b1f58dccd1c816701be9ba6214d43baf4547" }, + .{ d00.Kyber1024, "89248f2f33f7f4f7051729111f3049c409a933ec904aedadf035f30fa5646cd5" }, + .{ d00.Kyber768, "a1e122cad3c24bc51622e4c242d8b8acbcd3f618fee4220400605ca8f9ea02c2" }, }) |modeHash| { const mode = modeHash[0]; var seed: [48]u8 = undefined;