| ... | @@ -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 currently | 4 | //! 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 draft | 6 | //! |
| 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 | }; |
| 176 | | 174 | |
| 177 | pub const ml_kem_01 = struct { | 175 | pub const ml_kem_01 = @compileError("deprecated: final version of the specification has been published, use ml_kem instead"); |
| | 176 | |
| | 177 | pub 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 | }; |
| 214 | const h_length: usize = 32; | 214 | const h_length: usize = 32; |
| 215 | const inner_seed_length: usize = 32; | 215 | const 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 on | 514 | pk.aT = M.uniform(pk.rho, false); // Expand ρ to A; we'll transpose later on |