authorgravatar for andrew@ziglang.orgAndrew Kelley <andrew@ziglang.org> 2024-08-22 12:54:40-07:00
committergravatar for noreply@github.comGitHub <noreply@github.com> 2024-08-22 12:54:40-07:00
log205e17a73cd6c0d30bab1e232ef872f75bfc0035
treec16a9aad677d78098e451e751fa043353be4becc
parentfebfcbd49d0a4713dee9db38816c163fa1926ed4
parentb131b6dd3639ff4c449c73978ddc77f51161fd9b
signaturebadge-check Signed by PGP key B5690EEEBB952194

Merge pull request #21161 from jedisct1/mlkem-update

Update ML-KEM to the final specification

2 files changed, 20 insertions(+), 23 deletions(-)

lib/std/crypto.zig+3-2
...@@ -74,8 +74,9 @@ pub const dh = struct {...@@ -74,8 +74,9 @@ pub const dh = struct {
7474
75/// Key Encapsulation Mechanisms.75/// Key Encapsulation Mechanisms.
76pub const kem = struct {76pub const kem = struct {
77 pub const kyber_d00 = @import("crypto/ml_kem.zig").kyber_d00;77 pub const kyber_d00 = @import("crypto/ml_kem.zig").d00;
78 pub const ml_kem_01 = @import("crypto/ml_kem.zig").ml_kem_01;78 pub const ml_kem = @import("crypto/ml_kem.zig").nist;
79 pub const ml_kem_01 = @compileError("deprecated: final version of the specification has been published, use ml_kem instead");
79};80};
8081
81/// Elliptic-curve arithmetic.82/// Elliptic-curve arithmetic.
lib/std/crypto/ml_kem.zig+17-21
...@@ -1,15 +1,8 @@...@@ -1,15 +1,8 @@
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.4//! The namespace `d00` refers to the version currently implemented, in accordance with the CFRG draft.
5//!5//! The `nist` namespace refers to the FIPS-203 publication.
6//! The Kyber namespace suffix (currently `_d00`) refers to the version currently
7//! implemented, in accordance with the draft.
8//! The ML-KEM namespace suffix (currently `_01`) refers to the NIST FIPS-203 draft
9//! published on August 24, 2023, with the unintentional transposition of  having been reverted.
10//!
11//! 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.
13//!6//!
14//! Quoting from the CFRG I-D:7//! Quoting from the CFRG I-D:
15//!8//!
...@@ -148,7 +141,7 @@ const Params = struct {...@@ -148,7 +141,7 @@ const Params = struct {
148 dv: u8,141 dv: u8,
149};142};
150143
151pub const kyber_d00 = struct {144pub const d00 = struct {
152 pub const Kyber512 = Kyber(.{145 pub const Kyber512 = Kyber(.{
153 .name = "Kyber512",146 .name = "Kyber512",
154 .k = 2,147 .k = 2,
...@@ -174,7 +167,7 @@ pub const kyber_d00 = struct {...@@ -174,7 +167,7 @@ pub const kyber_d00 = struct {
174 });167 });
175};168};
176169
177pub const ml_kem_01 = struct {170pub const nist = struct {
178 pub const MLKem512 = Kyber(.{171 pub const MLKem512 = Kyber(.{
179 .name = "ML-KEM-512",172 .name = "ML-KEM-512",
180 .ml_kem = true,173 .ml_kem = true,
...@@ -204,12 +197,12 @@ pub const ml_kem_01 = struct {...@@ -204,12 +197,12 @@ pub const ml_kem_01 = struct {
204};197};
205198
206const modes = [_]type{199const modes = [_]type{
207 kyber_d00.Kyber512,200 d00.Kyber512,
208 kyber_d00.Kyber768,201 d00.Kyber768,
209 kyber_d00.Kyber1024,202 d00.Kyber1024,
210 ml_kem_01.MLKem512,203 nist.MLKem512,
211 ml_kem_01.MLKem768,204 nist.MLKem768,
212 ml_kem_01.MLKem1024,205 nist.MLKem1024,
213};206};
214const h_length: usize = 32;207const h_length: usize = 32;
215const inner_seed_length: usize = 32;208const inner_seed_length: usize = 32;
...@@ -505,7 +498,10 @@ fn Kyber(comptime p: Params) type {...@@ -505,7 +498,10 @@ fn Kyber(comptime p: Params) type {
505 // Derives inner PKE keypair from given seed.498 // Derives inner PKE keypair from given seed.
506 fn innerKeyFromSeed(seed: [inner_seed_length]u8, pk: *InnerPk, sk: *InnerSk) void {499 fn innerKeyFromSeed(seed: [inner_seed_length]u8, pk: *InnerPk, sk: *InnerSk) void {
507 var expanded_seed: [64]u8 = undefined;500 var expanded_seed: [64]u8 = undefined;
508 sha3.Sha3_512.hash(&seed, &expanded_seed, .{});501 var h = sha3.Sha3_512.init(.{});
502 if (p.ml_kem) h.update(&[1]u8{p.k});
503 h.update(&seed);
504 h.final(&expanded_seed);
509 pk.rho = expanded_seed[0..32].*;505 pk.rho = expanded_seed[0..32].*;
510 const sigma = expanded_seed[32..64];506 const sigma = expanded_seed[32..64];
511 pk.aT = M.uniform(pk.rho, false); // Expand ρ to A; we'll transpose later on507 pk.aT = M.uniform(pk.rho, false); // Expand ρ to A; we'll transpose later on
...@@ -1722,9 +1718,9 @@ const sha2 = crypto.hash.sha2;...@@ -1722,9 +1718,9 @@ const sha2 = crypto.hash.sha2;
17221718
1723test "NIST KAT test" {1719test "NIST KAT test" {
1724 inline for (.{1720 inline for (.{
1725 .{ kyber_d00.Kyber512, "e9c2bd37133fcb40772f81559f14b1f58dccd1c816701be9ba6214d43baf4547" },1721 .{ d00.Kyber512, "e9c2bd37133fcb40772f81559f14b1f58dccd1c816701be9ba6214d43baf4547" },
1726 .{ kyber_d00.Kyber1024, "89248f2f33f7f4f7051729111f3049c409a933ec904aedadf035f30fa5646cd5" },1722 .{ d00.Kyber1024, "89248f2f33f7f4f7051729111f3049c409a933ec904aedadf035f30fa5646cd5" },
1727 .{ kyber_d00.Kyber768, "a1e122cad3c24bc51622e4c242d8b8acbcd3f618fee4220400605ca8f9ea02c2" },1723 .{ d00.Kyber768, "a1e122cad3c24bc51622e4c242d8b8acbcd3f618fee4220400605ca8f9ea02c2" },
1728 }) |modeHash| {1724 }) |modeHash| {
1729 const mode = modeHash[0];1725 const mode = modeHash[0];
1730 var seed: [48]u8 = undefined;1726 var seed: [48]u8 = undefined;