| ... | ... | @@ -1,15 +1,8 @@ |
| 1 | 1 | //! Implementation of the IND-CCA2 post-quantum secure key encapsulation mechanism (KEM) |
| 2 | 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 |
| 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. |
| 4 | //! The namespace `d00` refers to the version currently implemented, in accordance with the CFRG draft. |
| 5 | //! The `nist` namespace refers to the FIPS-203 publication. |
| 13 | 6 | //! |
| 14 | 7 | //! Quoting from the CFRG I-D: |
| 15 | 8 | //! |
| ... | ... | @@ -148,7 +141,7 @@ const Params = struct { |
| 148 | 141 | dv: u8, |
| 149 | 142 | }; |
| 150 | 143 | |
| 151 | | pub const kyber_d00 = struct { |
| 144 | pub const d00 = struct { |
| 152 | 145 | pub const Kyber512 = Kyber(.{ |
| 153 | 146 | .name = "Kyber512", |
| 154 | 147 | .k = 2, |
| ... | ... | @@ -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 | 171 | pub const MLKem512 = Kyber(.{ |
| 179 | 172 | .name = "ML-KEM-512", |
| 180 | 173 | .ml_kem = true, |
| ... | ... | @@ -204,12 +197,12 @@ pub const ml_kem_01 = struct { |
| 204 | 197 | }; |
| 205 | 198 | |
| 206 | 199 | const modes = [_]type{ |
| 207 | | kyber_d00.Kyber512, |
| 208 | | kyber_d00.Kyber768, |
| 209 | | kyber_d00.Kyber1024, |
| 210 | | ml_kem_01.MLKem512, |
| 211 | | ml_kem_01.MLKem768, |
| 212 | | ml_kem_01.MLKem1024, |
| 200 | d00.Kyber512, |
| 201 | d00.Kyber768, |
| 202 | d00.Kyber1024, |
| 203 | nist.MLKem512, |
| 204 | nist.MLKem768, |
| 205 | nist.MLKem1024, |
| 213 | 206 | }; |
| 214 | 207 | const h_length: usize = 32; |
| 215 | 208 | const inner_seed_length: usize = 32; |
| ... | ... | @@ -505,7 +498,10 @@ fn Kyber(comptime p: Params) type { |
| 505 | 498 | // Derives inner PKE keypair from given seed. |
| 506 | 499 | fn innerKeyFromSeed(seed: [inner_seed_length]u8, pk: *InnerPk, sk: *InnerSk) void { |
| 507 | 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 | 505 | pk.rho = expanded_seed[0..32].*; |
| 510 | 506 | const sigma = expanded_seed[32..64]; |
| 511 | 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 | 1718 | |
| 1723 | 1719 | test "NIST KAT test" { |
| 1724 | 1720 | inline for (.{ |
| 1725 | | .{ kyber_d00.Kyber512, "e9c2bd37133fcb40772f81559f14b1f58dccd1c816701be9ba6214d43baf4547" }, |
| 1726 | | .{ kyber_d00.Kyber1024, "89248f2f33f7f4f7051729111f3049c409a933ec904aedadf035f30fa5646cd5" }, |
| 1727 | | .{ kyber_d00.Kyber768, "a1e122cad3c24bc51622e4c242d8b8acbcd3f618fee4220400605ca8f9ea02c2" }, |
| 1721 | .{ d00.Kyber512, "e9c2bd37133fcb40772f81559f14b1f58dccd1c816701be9ba6214d43baf4547" }, |
| 1722 | .{ d00.Kyber1024, "89248f2f33f7f4f7051729111f3049c409a933ec904aedadf035f30fa5646cd5" }, |
| 1723 | .{ d00.Kyber768, "a1e122cad3c24bc51622e4c242d8b8acbcd3f618fee4220400605ca8f9ea02c2" }, |
| 1728 | 1724 | }) |modeHash| { |
| 1729 | 1725 | const mode = modeHash[0]; |
| 1730 | 1726 | var seed: [48]u8 = undefined; |