| ... | @@ -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 | }; |
| 150 | | 143 | |
| 151 | pub const kyber_d00 = struct { | 144 | pub 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 | }; |
| 176 | | 169 | |
| 177 | pub const ml_kem_01 = struct { | 170 | pub 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 | }; |
| 205 | | 198 | |
| 206 | const modes = [_]type{ | 199 | const 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 | }; |
| 214 | const h_length: usize = 32; | 207 | const h_length: usize = 32; |
| 215 | const inner_seed_length: usize = 32; | 208 | const 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 on | 507 | 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; |
| 1722 | | 1718 | |
| 1723 | test "NIST KAT test" { | 1719 | test "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; |