]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Encoders and Decoders for ML-KEM
authorViktor Dukhovni <openssl-users@dukhovni.org>
Thu, 9 Jan 2025 03:35:03 +0000 (14:35 +1100)
committerTomas Mraz <tomas@openssl.org>
Fri, 14 Feb 2025 09:50:58 +0000 (10:50 +0100)
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: Tim Hudson <tjh@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26341)

22 files changed:
crypto/err/openssl.txt
crypto/ml_kem/ml_kem.c
doc/man7/EVP_PKEY-ML-KEM.pod
include/crypto/ml_kem.h
include/openssl/proverr.h
providers/common/provider_err.c
providers/decoders.inc
providers/encoders.inc
providers/fips/self_test_kats.c
providers/implementations/encode_decode/decode_der2key.c
providers/implementations/encode_decode/encode_key2any.c
providers/implementations/encode_decode/encode_key2text.c
providers/implementations/include/prov/implementations.h
providers/implementations/include/prov/names.h
providers/implementations/keymgmt/ml_kem_kmgmt.c
providers/implementations/keymgmt/mlx_kmgmt.c
test/endecode_test.c
test/evp_extra_test.c
test/evp_test.c
test/ml_kem_evp_extra_test.c
test/ml_kem_internal_test.c
util/perl/OpenSSL/paramnames.pm

index 35f7480cec3ea8bcdf41bcc07072586e8a304bd2..a796cf48e687d458cedcb829ac54217061d413dc 100644 (file)
@@ -1174,6 +1174,8 @@ PROV_R_UNABLE_TO_INITIALISE_CIPHERS:208:unable to initialise ciphers
 PROV_R_UNABLE_TO_LOAD_SHA256:147:unable to load sha256
 PROV_R_UNABLE_TO_LOCK_PARENT:201:unable to lock parent
 PROV_R_UNABLE_TO_RESEED:204:unable to reseed
+PROV_R_UNEXPECTED_KEY_OID:249:unexpected key oid
+PROV_R_UNEXPECTED_KEY_PARAMETERS:250:unexpected key parameters
 PROV_R_UNSUPPORTED_CEK_ALG:145:unsupported cek alg
 PROV_R_UNSUPPORTED_KEY_SIZE:153:unsupported key size
 PROV_R_UNSUPPORTED_MAC_TYPE:137:unsupported mac type
index 8960bf2f471a270439500c703551462b922db911..a81fe8df5cb7ad964f3a13e65dc416c3cb0858b3 100644 (file)
@@ -188,7 +188,7 @@ static const ML_KEM_VINFO vinfo_map[3] = {
         CTEXT_BYTES(512),
         VECTOR_BYTES(512),
         U_VECTOR_BYTES(512),
-        ML_KEM_512_VARIANT,
+        NID_ML_KEM_512,
         ML_KEM_512_BITS,
         ML_KEM_512_RANK,
         ML_KEM_512_DU,
@@ -204,7 +204,7 @@ static const ML_KEM_VINFO vinfo_map[3] = {
         CTEXT_BYTES(768),
         VECTOR_BYTES(768),
         U_VECTOR_BYTES(768),
-        ML_KEM_768_VARIANT,
+        NID_ML_KEM_768,
         ML_KEM_768_BITS,
         ML_KEM_768_RANK,
         ML_KEM_768_DU,
@@ -220,7 +220,7 @@ static const ML_KEM_VINFO vinfo_map[3] = {
         CTEXT_BYTES(1024),
         VECTOR_BYTES(1024),
         U_VECTOR_BYTES(1024),
-        ML_KEM_1024_VARIANT,
+        NID_ML_KEM_1024,
         ML_KEM_1024_BITS,
         ML_KEM_1024_RANK,
         ML_KEM_1024_DU,
@@ -1182,7 +1182,7 @@ int gencbd_vector_ntt(scalar *out, CBD_FUNC cbd, uint8_t *counter,
 }
 
 /* The |ETA1| value for ML-KEM-512 is 3, the rest and all ETA2 values are 2. */
-static CBD_FUNC const cbd1[ML_KEM_1024_VARIANT + 1] = { cbd_3, cbd_2, cbd_2 };
+#define CBD1(evp_type)  ((evp_type) == NID_ML_KEM_512 ? cbd_3 : cbd_2)
 
 /*
  * FIPS 203, Section 5.2, Algorithm 14: K-PKE.Encrypt.
@@ -1207,7 +1207,7 @@ int encrypt_cpa(uint8_t out[ML_KEM_SHARED_SECRET_BYTES],
                 EVP_MD_CTX *mdctx, const ML_KEM_KEY *key)
 {
     const ML_KEM_VINFO *vinfo = key->vinfo;
-    CBD_FUNC cbd_1 = cbd1[vinfo->variant];
+    CBD_FUNC cbd_1 = CBD1(vinfo->evp_type);
     int rank = vinfo->rank;
     /* We can use tmp[0..rank-1] as storage for |y|, then |e1|, ... */
     scalar *y = &tmp[0], *e1 = y, *e2 = y;
@@ -1395,7 +1395,7 @@ int genkey(const uint8_t d[ML_KEM_RANDOM_BYTES],
     const uint8_t *const sigma = hashed + ML_KEM_RANDOM_BYTES;
     uint8_t augmented_seed[ML_KEM_RANDOM_BYTES + 1];
     const ML_KEM_VINFO *vinfo = key->vinfo;
-    CBD_FUNC cbd_1 = cbd1[vinfo->variant];
+    CBD_FUNC cbd_1 = CBD1(vinfo->evp_type);
     int rank = vinfo->rank;
     uint8_t counter = 0;
 
@@ -1567,17 +1567,23 @@ free_storage(ML_KEM_KEY *key)
  */
 
 /* Retrieve the parameters of one of the ML-KEM variants */
-const ML_KEM_VINFO *ossl_ml_kem_get_vinfo(int variant)
+const ML_KEM_VINFO *ossl_ml_kem_get_vinfo(int evp_type)
 {
-    if (variant > ML_KEM_1024_VARIANT)
-        return NULL;
-    return &vinfo_map[variant];
+    switch (evp_type) {
+    case NID_ML_KEM_512:
+        return &vinfo_map[0];
+    case NID_ML_KEM_768:
+        return &vinfo_map[1];
+    case NID_ML_KEM_1024:
+        return &vinfo_map[2];
+    }
+    return NULL;
 }
 
 ML_KEM_KEY *ossl_ml_kem_key_new(OSSL_LIB_CTX *libctx, const char *properties,
-                                int variant)
+                                int evp_type)
 {
-    const ML_KEM_VINFO *vinfo = ossl_ml_kem_get_vinfo(variant);
+    const ML_KEM_VINFO *vinfo = ossl_ml_kem_get_vinfo(evp_type);
     ML_KEM_KEY *key;
 
     if (vinfo == NULL)
@@ -1694,6 +1700,17 @@ int ossl_ml_kem_encode_private_key(uint8_t *out, size_t len,
     return 1;
 }
 
+int ossl_ml_kem_encode_key_seed(uint8_t *out, size_t len,
+                                const ML_KEM_KEY *key)
+{
+    if (key == NULL || key->d == NULL || len != ML_KEM_SEED_BYTES)
+        return 0;
+    memcpy(out, key->d, ML_KEM_RANDOM_BYTES);
+    out += ML_KEM_RANDOM_BYTES;
+    memcpy(out, key->z, ML_KEM_RANDOM_BYTES);
+    return 1;
+}
+
 /* Parse input as a public key */
 int ossl_ml_kem_parse_public_key(const uint8_t *in, size_t len, ML_KEM_KEY *key)
 {
@@ -1834,15 +1851,15 @@ int ossl_ml_kem_encap_seed(uint8_t *ctext, size_t clen,
      * each) vectors, that are never retained on return from this function.
      * We stack-allocate these.
      */
-#   define case_encap_seed(bits) \
-    case ML_KEM_##bits##_VARIANT: \
-        { \
-            scalar tmp[2 * ML_KEM_##bits##_RANK]; \
-                                                                         \
-            ret = encap(ctext, shared_secret, entropy, tmp, mdctx, key); \
-            break; \
+#   define case_encap_seed(bits)                                            \
+    case NID_ML_KEM_##bits:                                                 \
+        {                                                                   \
+            scalar tmp[2 * ML_KEM_##bits##_RANK];                           \
+                                                                            \
+            ret = encap(ctext, shared_secret, entropy, tmp, mdctx, key);    \
+            break;                                                          \
         }
-    switch (vinfo->variant) {
+    switch (vinfo->evp_type) {
     case_encap_seed(512);
     case_encap_seed(768);
     case_encap_seed(1024);
@@ -1914,7 +1931,7 @@ int ossl_ml_kem_decap(uint8_t *shared_secret, size_t slen,
      * We stack-allocate these.
      */
 #   define case_decap(bits)                                             \
-    case ML_KEM_##bits##_VARIANT:                                       \
+    case NID_ML_KEM_##bits:                                             \
         {                                                               \
             uint8_t cbuf[CTEXT_BYTES(bits)];                            \
             scalar tmp[2 * ML_KEM_##bits##_RANK];                       \
@@ -1922,7 +1939,7 @@ int ossl_ml_kem_decap(uint8_t *shared_secret, size_t slen,
             ret = decap(shared_secret, ctext, cbuf, tmp, mdctx, key);   \
             break;                                                      \
         }
-    switch (vinfo->variant) {
+    switch (vinfo->evp_type) {
     case_decap(512);
     case_decap(768);
     case_decap(1024);
index 13fc39a5741686827ca136d1d3c48808bb199642..7a4cb8f11d632d77be81d5f2596a1e00922b98c4 100644 (file)
@@ -56,25 +56,48 @@ The public key value.
 
 This parameter is used when importing or exporting the public key value with
 the EVP_PKEY_fromdata() and EVP_PKEY_todata() functions.  The same underlying
-FIPS 203 public key format is used for import, import, get and set operations.
+FIPS 203 (Algorithm 16: B<ML-KEM.KeyGen_internal>) B<ek> public key format is
+used for import, export, get and set operations.
 
 =item "priv" (B<OSSL_PKEY_PARAM_PRIV_KEY>) <octet string>
 
-The private key value.
+The private key, in seed form when available.
 
 This parameter is used when importing or exporting the private key value with
 the EVP_PKEY_fromdata() and EVP_PKEY_todata() functions.
-The key format is that of B<dk> in FIPS 203, Algorithm 16:
-B<ML-KEM.KeyGen_internal>.
+On import, the private key key length is used to infer the key format.
+If the key length is 64 bytes, the key format is assumed to be the 64-byte
+input seed of FIPS 203, Algorithm 16: B<ML-KEM.KeyGen_internal>, with the B<d>
+and B<z> values concatenated in that order.
+If, on the other hand, the key length is that of the FIPS 203 (Algorithm 16:
+B<ML-KEM.KeyGen_internal>) B<dk> private key for the given ML-KEM variant, then
+the key is assumed to be in that format.
+
+Keys originally imported in the B<dk> FIPS 203 form cannot be exported in seed
+form as the B<d> seed is not available in that case, and the exported key will
+then be the FIPS 203 B<dk> format in which the key was imported.
+Generated keys retain the seed value, and are exported in seed form.
 
 =item "encoded-pub-key" (B<OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY>) <octet string>
 
 Used for getting and setting the encoding of a public key.
 The key format is that of B<ek> in FIPS 203, Algorithm 16:
 B<ML-KEM.KeyGen_internal>.
+Updates of the public and private key components are only allowed on keys that
+are empty.
+Once a public or private key component is set, no further changes are allowed.
 
 This parameter is gettable and settable.
 
+=item "encoded-priv-key" (B<PKEY_PARAM_ENCODED_PRIVATE_KEY>) <octet string>
+
+Used for getting the I<expanded> encoding of a private key.
+The key format is that of B<dk> in FIPS 203, Algorithm 16: B<ML-KEM.KeyGen_internal>.
+The private key format returned from key export is the B<(d, z)> seed, when
+available, but is otherwise the same as the encoded form.
+
+This parameter is only gettable.
+
 =back
 
 =head1 CONFORMING TO
index fafaa98b726d3ca27c36e0170fbd75bc3201525b..d3ea0aba033e8172b364ded6a903865a9f934af9 100644 (file)
@@ -85,7 +85,7 @@
  * Variant-specific constants and structures
  * -----------------------------------------
  */
-# define ML_KEM_512_VARIANT     0
+# define EVP_PKEY_ML_KEM_512    NID_ML_KEM_512
 # define ML_KEM_512_BITS        512
 # define ML_KEM_512_RANK        2
 # define ML_KEM_512_ETA1        3
@@ -94,7 +94,7 @@
 # define ML_KEM_512_DV          4
 # define ML_KEM_512_SECBITS     128
 
-# define ML_KEM_768_VARIANT     1
+# define EVP_PKEY_ML_KEM_768    NID_ML_KEM_768
 # define ML_KEM_768_BITS        768
 # define ML_KEM_768_RANK        3
 # define ML_KEM_768_ETA1        2
 # define ML_KEM_768_DV          4
 # define ML_KEM_768_SECBITS     192
 
-# define ML_KEM_1024_VARIANT    2
+# define EVP_PKEY_ML_KEM_1024   NID_ML_KEM_1024
 # define ML_KEM_1024_BITS       1024
 # define ML_KEM_1024_RANK       4
 # define ML_KEM_1024_ETA1       2
@@ -126,7 +126,7 @@ typedef struct {
     size_t ctext_bytes;
     size_t vector_bytes;
     size_t u_vector_bytes;
-    int variant;
+    int evp_type;
     int bits;
     int rank;
     int du;
@@ -135,7 +135,7 @@ typedef struct {
 } ML_KEM_VINFO;
 
 /* Retrive global variant-specific parameters */
-const ML_KEM_VINFO *ossl_ml_kem_get_vinfo(int variant);
+const ML_KEM_VINFO *ossl_ml_kem_get_vinfo(int evp_type);
 
 /* Known as ML_KEM_KEY via crypto/types.h */
 typedef struct ossl_ml_kem_key_st {
@@ -171,9 +171,10 @@ typedef struct ossl_ml_kem_key_st {
 } ML_KEM_KEY;
 
 /* The public key is always present, when the private is */
-# define ossl_ml_kem_key_vinfo(key)        ((key)->vinfo)
-# define ossl_ml_kem_have_pubkey(key)      ((key)->t != NULL)
-# define ossl_ml_kem_have_prvkey(key)      ((key)->s != NULL)
+# define ossl_ml_kem_key_vinfo(key)         ((key)->vinfo)
+# define ossl_ml_kem_have_pubkey(key)       ((key)->t != NULL)
+# define ossl_ml_kem_have_prvkey(key)       ((key)->s != NULL)
+# define ossl_ml_kem_have_seed(key)         ((key)->d != NULL)
 
 /*
  * ----- ML-KEM key lifecycle
@@ -185,7 +186,7 @@ typedef struct ossl_ml_kem_key_st {
  */
 ML_KEM_KEY *ossl_ml_kem_key_new(OSSL_LIB_CTX *libctx,
                                 const char *properties,
-                                int variant);
+                                int evp_type);
 /* Deallocate the key */
 void ossl_ml_kem_key_free(ML_KEM_KEY *key);
 /*
@@ -227,6 +228,9 @@ int ossl_ml_kem_encode_public_key(uint8_t *out, size_t len,
 __owur
 int ossl_ml_kem_encode_private_key(uint8_t *out, size_t len,
                                    const ML_KEM_KEY *key);
+__owur
+int ossl_ml_kem_encode_key_seed(uint8_t *out, size_t len,
+                                const ML_KEM_KEY *key);
 
 __owur
 int ossl_ml_kem_encap_seed(uint8_t *ctext, size_t clen,
index 1ac4f59f0d480f8658544ed3e8ca8dcf26c1d643..79c57e3f7ab1382ca79f29c37bff50be5f976af7 100644 (file)
 # define PROV_R_UNABLE_TO_LOAD_SHA256                     147
 # define PROV_R_UNABLE_TO_LOCK_PARENT                     201
 # define PROV_R_UNABLE_TO_RESEED                          204
+# define PROV_R_UNEXPECTED_KEY_OID                        249
+# define PROV_R_UNEXPECTED_KEY_PARAMETERS                 250
 # define PROV_R_UNSUPPORTED_CEK_ALG                       145
 # define PROV_R_UNSUPPORTED_KEY_SIZE                      153
 # define PROV_R_UNSUPPORTED_MAC_TYPE                      137
index 301c5707893a00d244e31c6bc5899851f51eb42c..54ee700abef5b9ce692428900fe51869c9b6915c 100644 (file)
@@ -219,6 +219,10 @@ static const ERR_STRING_DATA PROV_str_reasons[] = {
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_LOCK_PARENT),
      "unable to lock parent"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNABLE_TO_RESEED), "unable to reseed"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNEXPECTED_KEY_OID),
+     "unexpected key oid"},
+    {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNEXPECTED_KEY_PARAMETERS),
+     "unexpected key parameters"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_CEK_ALG),
      "unsupported cek alg"},
     {ERR_PACK(ERR_LIB_PROV, 0, PROV_R_UNSUPPORTED_KEY_SIZE),
index 49ac67194276a5f237457bae56ef84baa8ad0094..ae94042b828821a04a22bca3f99dabcdb235fa02 100644 (file)
@@ -74,6 +74,14 @@ DECODER_w_structure("SM2", der, SubjectPublicKeyInfo, sm2, no),
 DECODER_w_structure("SM2", der, type_specific_no_pub, sm2, no),
 # endif
 #endif
+#ifndef OPENSSL_NO_ML_KEM
+DECODER_w_structure("ML-KEM-512", der, PrivateKeyInfo, ml_kem_512, yes),
+DECODER_w_structure("ML-KEM-512", der, SubjectPublicKeyInfo, ml_kem_512, yes),
+DECODER_w_structure("ML-KEM-768", der, PrivateKeyInfo, ml_kem_768, yes),
+DECODER_w_structure("ML-KEM-768", der, SubjectPublicKeyInfo, ml_kem_768, yes),
+DECODER_w_structure("ML-KEM-1024", der, PrivateKeyInfo, ml_kem_1024, yes),
+DECODER_w_structure("ML-KEM-1024", der, SubjectPublicKeyInfo, ml_kem_1024, yes),
+#endif
 DECODER_w_structure("RSA", der, PrivateKeyInfo, rsa, yes),
 DECODER_w_structure("RSA", der, SubjectPublicKeyInfo, rsa, yes),
 DECODER_w_structure("RSA", der, type_specific_keypair, rsa, yes),
index 76f0b73545a79686e31a9f815e062cabdc1c477e..74931909440fd943868a09554bff88c03becdc2f 100644 (file)
@@ -67,6 +67,11 @@ ENCODER_TEXT("X448", x448, yes),
 ENCODER_TEXT("SM2", sm2, no),
 # endif
 #endif
+#ifndef OPENSSL_NO_ML_KEM
+ENCODER_TEXT("ML-KEM-512", ml_kem_512, yes),
+ENCODER_TEXT("ML-KEM-768", ml_kem_768, yes),
+ENCODER_TEXT("ML-KEM-1024", ml_kem_1024, yes),
+#endif
 
 # ifndef OPENSSL_NO_ML_DSA
 ENCODER_TEXT("ML-DSA-44", ml_dsa_44, yes),
@@ -189,6 +194,16 @@ ENCODER_w_structure("EC", ec, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("EC", ec, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("EC", ec, yes, pem, SubjectPublicKeyInfo),
 
+# ifndef OPENSSL_NO_SM2
+ENCODER_w_structure("SM2", sm2, no, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("SM2", sm2, no, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("SM2", sm2, no, der, PrivateKeyInfo),
+ENCODER_w_structure("SM2", sm2, no, pem, PrivateKeyInfo),
+ENCODER_w_structure("SM2", sm2, no, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("SM2", sm2, no, pem, SubjectPublicKeyInfo),
+# endif
+#endif
+
 #ifndef OPENSSL_NO_ECX
 ENCODER_w_structure("X25519", x25519, yes, der, EncryptedPrivateKeyInfo),
 ENCODER_w_structure("X25519", x25519, yes, pem, EncryptedPrivateKeyInfo),
@@ -217,16 +232,29 @@ ENCODER_w_structure("ED448", ed448, yes, der, PrivateKeyInfo),
 ENCODER_w_structure("ED448", ed448, yes, pem, PrivateKeyInfo),
 ENCODER_w_structure("ED448", ed448, yes, der, SubjectPublicKeyInfo),
 ENCODER_w_structure("ED448", ed448, yes, pem, SubjectPublicKeyInfo),
-# endif
+#endif
 
-# ifndef OPENSSL_NO_SM2
-ENCODER_w_structure("SM2", sm2, no, der, EncryptedPrivateKeyInfo),
-ENCODER_w_structure("SM2", sm2, no, pem, EncryptedPrivateKeyInfo),
-ENCODER_w_structure("SM2", sm2, no, der, PrivateKeyInfo),
-ENCODER_w_structure("SM2", sm2, no, pem, PrivateKeyInfo),
-ENCODER_w_structure("SM2", sm2, no, der, SubjectPublicKeyInfo),
-ENCODER_w_structure("SM2", sm2, no, pem, SubjectPublicKeyInfo),
-# endif
+#ifndef OPENSSL_NO_ML_KEM
+ENCODER_w_structure("ML-KEM-512", ml_kem_512, yes, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("ML-KEM-512", ml_kem_512, yes, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("ML-KEM-512", ml_kem_512, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("ML-KEM-512", ml_kem_512, yes, pem, PrivateKeyInfo),
+ENCODER_w_structure("ML-KEM-512", ml_kem_512, yes, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("ML-KEM-512", ml_kem_512, yes, pem, SubjectPublicKeyInfo),
+
+ENCODER_w_structure("ML-KEM-768", ml_kem_768, yes, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("ML-KEM-768", ml_kem_768, yes, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("ML-KEM-768", ml_kem_768, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("ML-KEM-768", ml_kem_768, yes, pem, PrivateKeyInfo),
+ENCODER_w_structure("ML-KEM-768", ml_kem_768, yes, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("ML-KEM-768", ml_kem_768, yes, pem, SubjectPublicKeyInfo),
+
+ENCODER_w_structure("ML-KEM-1024", ml_kem_1024, yes, der, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("ML-KEM-1024", ml_kem_1024, yes, pem, EncryptedPrivateKeyInfo),
+ENCODER_w_structure("ML-KEM-1024", ml_kem_1024, yes, der, PrivateKeyInfo),
+ENCODER_w_structure("ML-KEM-1024", ml_kem_1024, yes, pem, PrivateKeyInfo),
+ENCODER_w_structure("ML-KEM-1024", ml_kem_1024, yes, der, SubjectPublicKeyInfo),
+ENCODER_w_structure("ML-KEM-1024", ml_kem_1024, yes, pem, SubjectPublicKeyInfo),
 #endif
 
 # ifndef OPENSSL_NO_ML_DSA
index 06e06a89ecfecf6e765003794b81294862ebab61..10ed646d0401218ec5d2d15ea20efe1a271cb69a 100644 (file)
@@ -772,8 +772,8 @@ static EVP_PKEY *self_test_kem_keygen(const ST_KAT_KEM *t, OSSL_SELF_TEST *st,
         goto err;
 
     /* Compare outputs */
-    *params = OSSL_PARAM_construct_octet_string(OSSL_PKEY_PARAM_PRIV_KEY,
-                                                buf, s);
+    *params = OSSL_PARAM_construct_octet_string(
+        OSSL_PKEY_PARAM_ENCODED_PRIVATE_KEY, buf, s);
     if (!EVP_PKEY_get_params(r, params))
         goto err;
     OSSL_SELF_TEST_oncorrupt_byte(st, buf);
index b77690a77347cc872ecde1003855f88b787cc544..4ae31ad18dd277a99b4b9259cfe3b664a0d3832a 100644 (file)
@@ -13,6 +13,8 @@
  */
 #include "internal/deprecated.h"
 
+#include <openssl/asn1t.h>
+#include <openssl/byteorder.h>
 #include <openssl/core_dispatch.h>
 #include <openssl/core_names.h>
 #include <openssl/core_object.h>
 #include "crypto/rsa.h"
 #include "crypto/ml_dsa.h"
 #include "crypto/x509.h"
+#include "crypto/ml_kem.h"
+#include "openssl/obj_mac.h"
 #include "prov/bio.h"
 #include "prov/implementations.h"
 #include "endecoder_local.h"
 #include "internal/nelem.h"
 #include "ml_dsa_codecs.h"
 
+#ifndef OPENSSL_NO_ML_KEM
+typedef struct {
+    ASN1_OBJECT *oid;
+} BARE_ALGOR;
+
+typedef struct {
+    BARE_ALGOR algor;
+    ASN1_BIT_STRING *pubkey;
+} BARE_PUBKEY;
+
+ASN1_SEQUENCE(BARE_ALGOR) = {
+    ASN1_SIMPLE(BARE_ALGOR, oid, ASN1_OBJECT),
+} static_ASN1_SEQUENCE_END(BARE_ALGOR)
+
+ASN1_SEQUENCE(BARE_PUBKEY) = {
+    ASN1_EMBED(BARE_PUBKEY, algor, BARE_ALGOR),
+    ASN1_SIMPLE(BARE_PUBKEY, pubkey, ASN1_BIT_STRING)
+} static_ASN1_SEQUENCE_END(BARE_PUBKEY)
+#endif
+
 struct der2key_ctx_st;           /* Forward declaration */
 typedef int check_key_fn(void *, struct der2key_ctx_st *ctx);
 typedef void adjust_key_fn(void *, struct der2key_ctx_st *ctx);
@@ -552,6 +576,234 @@ static void *sm2_d2i_PKCS8(const unsigned char **der, long der_len,
                              (key_from_pkcs8_t *)ossl_ec_key_from_pkcs8);
 }
 # endif
+
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+#ifndef OPENSSL_NO_ML_KEM
+
+/* For lengths between 256 and 65535 the DER encoding is 4 bytes longer */
+#define ML_KEM_OCTET_STRING_OVERHEAD   4
+
+/*-
+ * The DER ASN.1 encoding of ML-KEM and ML-DSA public keys prepends 22 bytes to
+ * the encoded public key:
+ *
+ * - 4 byte outer sequence tag and length
+ * -  2 byte algorithm sequence tag and length
+ * -    2 byte algorithm OID tag and length
+ * -      9 byte algorithm OID (from NIST CSOR OID arc)
+ * -  4 byte bit string tag and length
+ * -    1 bitstring lead byte
+ */
+#define ML_KEM_SPKI_OVERHEAD   22
+
+/*
+ * The accepted private key format is either the 64-bytes (d, z) seed pair, or
+ * else the optionally DER wrapped octet-string encoding  (one byte tag, three
+ * byte length) of the FIPS 203 expanded |dk| key, optionally concatenated with
+ * the public |ek|.  We don't need to worry about whether the public key is or
+ * isn't appended, those are just ignored bytes at the end of an input buffer.
+ */
+typedef enum {
+    NONE_FMT,   /* Unknown or unsupported format */
+    SEED_FMT,   /* Just the seed, no DER wrapping */
+    LONG_FMT,   /* Key(s), no octet-string DER wrapping */
+    ASN1_FMT    /* Key(s), octet-string DER wrapped */
+} ML_KEM_PRIV_FMT;
+
+static void *
+ml_kem_d2i_PKCS8(const uint8_t **der, long der_len, struct der2key_ctx_st *ctx)
+{
+    const ML_KEM_VINFO *vinfo;
+    ML_KEM_KEY *key = NULL, *ret = NULL;
+    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
+    PKCS8_PRIV_KEY_INFO *p8inf = NULL;
+    const unsigned char *p;
+    const X509_ALGOR *alg = NULL;
+    ML_KEM_PRIV_FMT fmt;
+    int plen, ptype, privlen, pairlen;
+    uint16_t keylen;
+
+    /* Extract the key OID and any parameters (we want none of those) */
+    if ((p8inf = d2i_PKCS8_PRIV_KEY_INFO(NULL, der, der_len)) == NULL)
+        return 0;
+    if (!PKCS8_pkey_get0(NULL, &p, &plen, &alg, p8inf))
+        goto end;
+
+    /* Bail out early if this is some other key type. */
+    if (OBJ_obj2nid(alg->algorithm) != ctx->desc->evp_type)
+        goto end;
+    vinfo = ossl_ml_kem_get_vinfo(ctx->desc->evp_type);
+
+    /* Parameters must be absent. */
+    X509_ALGOR_get0(NULL, &ptype, NULL, alg);
+    if (ptype != V_ASN1_UNDEF) {
+        ERR_raise_data(ERR_LIB_PROV, PROV_R_UNEXPECTED_KEY_PARAMETERS,
+                       "unexpected parameters with a PKCS#8 %s private key",
+                       vinfo->algorithm_name);
+        goto end;
+    }
+    privlen = (int) vinfo->prvkey_bytes;
+    pairlen = (int) (vinfo->prvkey_bytes + vinfo->pubkey_bytes);
+
+    if (plen == ML_KEM_SEED_BYTES)
+        fmt = SEED_FMT;
+    else if (plen == privlen || plen == pairlen)
+        fmt = LONG_FMT;
+    else if (plen == ML_KEM_OCTET_STRING_OVERHEAD + privlen
+             || plen == ML_KEM_OCTET_STRING_OVERHEAD + pairlen)
+        fmt = ASN1_FMT;
+    else
+        fmt = NONE_FMT;
+
+    switch (fmt) {
+    case NONE_FMT:
+        ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH,
+                       "unexpected PKCS#8 private key length: %d", plen);
+        break;
+    case SEED_FMT:
+        if ((key = ossl_ml_kem_key_new(libctx, ctx->propq,
+                                       ctx->desc->evp_type)) != NULL
+            && ossl_ml_kem_genkey(p, p + ML_KEM_RANDOM_BYTES, NULL, 0, key))
+            ret = key;
+        else
+            ERR_raise_data(ERR_LIB_PROV, PROV_R_GENERATE_ERROR,
+                           "error generating %s private key from seed",
+                           vinfo->algorithm_name);
+        break;
+    case ASN1_FMT:
+        if (*p++ != V_ASN1_OCTET_STRING || *p++ != 0x82)
+            break;
+        p = OPENSSL_load_u16_be(&keylen, p);
+        if (keylen != (plen -= ML_KEM_OCTET_STRING_OVERHEAD))
+            break;
+        /* fallthrough */
+    case LONG_FMT:
+        /* Check public key consistency if provided? */
+        if ((key = ossl_ml_kem_key_new(libctx, ctx->propq,
+                                       ctx->desc->evp_type)) != NULL
+            && ossl_ml_kem_parse_private_key(p, vinfo->prvkey_bytes, key))
+            ret = key;
+        else
+            ERR_raise_data(ERR_LIB_PROV, PROV_R_INVALID_KEY,
+                           "error parsing %s private key",
+                           vinfo->algorithm_name);
+        break;
+    }
+
+  end:
+    PKCS8_PRIV_KEY_INFO_free(p8inf);
+    if (ret == NULL)
+        ossl_ml_kem_key_free(key);
+    return ret;
+}
+
+static ossl_inline void *
+ml_kem_d2i_PUBKEY(const uint8_t **der, long der_len,
+                  struct der2key_ctx_st *ctx)
+{
+    const ML_KEM_VINFO *vinfo = ossl_ml_kem_get_vinfo(ctx->desc->evp_type);
+    OSSL_LIB_CTX *libctx = PROV_LIBCTX_OF(ctx->provctx);
+    ML_KEM_KEY *ret = NULL;
+    BARE_PUBKEY *spki;
+    const uint8_t *end = *der;
+
+    /*
+     * Not our NID!  Is there a sensible error to report here?  Why was this
+     * decoder called?
+     */
+    if (vinfo == NULL)
+        return NULL;
+
+    /*
+     * Check that we have the right OID, the bit string has no "bits left" and
+     * that we consume all the input exactly.
+     */
+    if (der_len != ML_KEM_SPKI_OVERHEAD + (long) vinfo->pubkey_bytes) {
+        ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_ENCODING,
+                       "unexpected %s public key length: %ld != %ld",
+                       vinfo->algorithm_name, der_len,
+                       ML_KEM_SPKI_OVERHEAD + (long) vinfo->pubkey_bytes);
+        return NULL;
+    }
+
+    if ((spki = OPENSSL_zalloc(sizeof(*spki))) == NULL)
+        return NULL;
+
+    /* The spki storage is freed on error */
+    if (ASN1_item_d2i_ex((ASN1_VALUE **)&spki, &end, der_len,
+                            ASN1_ITEM_rptr(BARE_PUBKEY), NULL, NULL) == NULL) {
+        ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_ENCODING,
+                       "malformed %s public key ASN.1 encoding",
+                       vinfo->algorithm_name);
+        return NULL;
+    }
+
+    /* The spki structure now owns some memory */
+    if ((spki->pubkey->flags & 0x7) != 0 || end != *der + der_len) {
+        ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_ENCODING,
+                       "malformed %s public key ASN.1 encoding",
+                       vinfo->algorithm_name);
+        goto end;
+    }
+    if (OBJ_cmp(OBJ_nid2obj(ctx->desc->evp_type), spki->algor.oid) != 0) {
+        ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_ENCODING,
+                       "unexpected algorithm OID for an %s public key",
+                       vinfo->algorithm_name);
+        goto end;
+    }
+
+    ret = ossl_ml_kem_key_new(libctx, ctx->propq, ctx->desc->evp_type);
+    if (ret == NULL
+        || !ossl_ml_kem_parse_public_key(spki->pubkey->data,
+                                         spki->pubkey->length, ret)) {
+        ossl_ml_kem_key_free(ret);
+        ret = NULL;
+        ERR_raise_data(ERR_LIB_PROV, PROV_R_BAD_ENCODING,
+                       "failed to parse %s public key from the input data",
+                       vinfo->algorithm_name);
+    }
+
+  end:
+    ASN1_OBJECT_free(spki->algor.oid);
+    ASN1_BIT_STRING_free(spki->pubkey);
+    OPENSSL_free(spki);
+    return ret;
+}
+
+
+# define ml_kem_512_evp_type                EVP_PKEY_ML_KEM_512
+# define ml_kem_512_d2i_private_key         NULL
+# define ml_kem_512_d2i_public_key          NULL
+# define ml_kem_512_d2i_key_params          NULL
+# define ml_kem_512_d2i_PUBKEY              ml_kem_d2i_PUBKEY
+# define ml_kem_512_d2i_PKCS8               ml_kem_d2i_PKCS8
+# define ml_kem_512_free                    (free_key_fn *)ossl_ml_kem_key_free
+# define ml_kem_512_check                   NULL
+# define ml_kem_512_adjust                  NULL
+
+# define ml_kem_768_evp_type                EVP_PKEY_ML_KEM_768
+# define ml_kem_768_d2i_private_key         NULL
+# define ml_kem_768_d2i_public_key          NULL
+# define ml_kem_768_d2i_key_params          NULL
+# define ml_kem_768_d2i_PUBKEY              ml_kem_d2i_PUBKEY
+# define ml_kem_768_d2i_PKCS8               ml_kem_d2i_PKCS8
+# define ml_kem_768_free                    (free_key_fn *)ossl_ml_kem_key_free
+# define ml_kem_768_check                   NULL
+# define ml_kem_768_adjust                  NULL
+
+# define ml_kem_1024_evp_type               EVP_PKEY_ML_KEM_1024
+# define ml_kem_1024_d2i_private_key        NULL
+# define ml_kem_1024_d2i_public_key         NULL
+# define ml_kem_1024_d2i_PUBKEY             ml_kem_d2i_PUBKEY
+# define ml_kem_1024_d2i_PKCS8              ml_kem_d2i_PKCS8
+# define ml_kem_1024_d2i_key_params         NULL
+# define ml_kem_1024_free                   (free_key_fn *)ossl_ml_kem_key_free
+# define ml_kem_1024_check                  NULL
+# define ml_kem_1024_adjust                 NULL
+
 #endif
 
 /* ---------------------------------------------------------------------- */
@@ -925,6 +1177,14 @@ MAKE_DECODER("SM2", sm2, ec, SubjectPublicKeyInfo);
 MAKE_DECODER("SM2", sm2, sm2, type_specific_no_pub);
 # endif
 #endif
+#ifndef OPENSSL_NO_ML_KEM
+MAKE_DECODER("ML-KEM-512", ml_kem_512, ml_kem_512, PrivateKeyInfo);
+MAKE_DECODER("ML-KEM-512", ml_kem_512, ml_kem_512, SubjectPublicKeyInfo);
+MAKE_DECODER("ML-KEM-768", ml_kem_768, ml_kem_768, PrivateKeyInfo);
+MAKE_DECODER("ML-KEM-768", ml_kem_768, ml_kem_768, SubjectPublicKeyInfo);
+MAKE_DECODER("ML-KEM-1024", ml_kem_1024, ml_kem_1024, PrivateKeyInfo);
+MAKE_DECODER("ML-KEM-1024", ml_kem_1024, ml_kem_1024, SubjectPublicKeyInfo);
+#endif
 MAKE_DECODER("RSA", rsa, rsa, PrivateKeyInfo);
 MAKE_DECODER("RSA", rsa, rsa, SubjectPublicKeyInfo);
 MAKE_DECODER("RSA", rsa, rsa, type_specific_keypair);
index 9f43b17f840bc40bb74dced4ac6120d0ef099672..837f14626b5e20da978678c2ba2afc251e368e80 100644 (file)
@@ -29,6 +29,7 @@
 #include "internal/passphrase.h"
 #include "internal/cryptlib.h"
 #include "crypto/ecx.h"
+#include "crypto/ml_kem.h"
 #include "crypto/rsa.h"
 #include "crypto/ml_dsa.h"
 #include "prov/implementations.h"
@@ -877,6 +878,83 @@ static int ml_dsa_pki_priv_to_der(const void *vkey, unsigned char **pder,
 
 /* ---------------------------------------------------------------------- */
 
+#ifndef OPENSSL_NO_ML_KEM
+
+static int ml_kem_spki_pub_to_der(const void *vkey, unsigned char **pder,
+                                  ossl_unused void *ctx)
+{
+    const ML_KEM_KEY *key = vkey;
+    size_t publen;
+
+    if (!ossl_ml_kem_have_pubkey(key)) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    publen = key->vinfo->pubkey_bytes;
+
+    if (pder != NULL
+        && ((*pder = OPENSSL_malloc(publen)) == NULL
+            || !ossl_ml_kem_encode_public_key(*pder, publen, key)))
+        return 0;
+
+    return publen;
+}
+
+static int ml_kem_pki_priv_to_der(const void *vkey, unsigned char **pder,
+                                  ossl_unused void *ctx)
+{
+    const ML_KEM_KEY *key = vkey;
+    int len = ML_KEM_SEED_BYTES;
+
+    if (!ossl_ml_kem_have_prvkey(key)) {
+        ERR_raise_data(ERR_LIB_PROV, PROV_R_MISSING_KEY,
+                       "no %s private key data available",
+                       key->vinfo->algorithm_name);
+        return 0;
+    }
+
+    /*
+     * Output the seed bytes directly when available, but otherwise, be
+     * compatible with Bouncy Castle's non-seed "long" output format, which is
+     * just the FIPS 203 |dk| private key bytes sans DER octet-string wrapping.
+     */
+    if (ossl_ml_kem_have_seed(key))
+        len = ML_KEM_SEED_BYTES;
+    else
+        len = key->vinfo->prvkey_bytes;
+
+    if (pder == NULL)
+        return len;
+
+    if ((*pder = OPENSSL_malloc(len)) == NULL)
+        return 0;
+
+    if (ossl_ml_kem_have_seed(key)) {
+        if (ossl_ml_kem_encode_key_seed(*pder, len, key))
+            return len;
+    } else {
+        if (ossl_ml_kem_encode_private_key(*pder, len, key))
+            return len;
+    }
+
+    OPENSSL_free(*pder);
+    return 0;
+}
+
+# define ml_kem_epki_priv_to_der ml_kem_pki_priv_to_der
+# define prepare_ml_kem_params   NULL
+# define ml_kem_check_key_type   NULL
+
+# define ml_kem_512_evp_type        EVP_PKEY_ML_KEM_512
+# define ml_kem_512_pem_type        "ML-KEM-512"
+# define ml_kem_768_evp_type        EVP_PKEY_ML_KEM_768
+# define ml_kem_768_pem_type        "ML-KEM-768"
+# define ml_kem_1024_evp_type       EVP_PKEY_ML_KEM_1024
+# define ml_kem_1024_pem_type       "ML-KEM-1024"
+#endif
+
+/* ---------------------------------------------------------------------- */
+
 /*
  * Helper functions to prepare RSA-PSS params for encoding.  We would
  * have simply written the whole AlgorithmIdentifier, but existing libcrypto
@@ -1478,6 +1556,29 @@ MAKE_ENCODER(x448, ecx, SubjectPublicKeyInfo, pem);
 # endif
 #endif
 
+#ifndef OPENSSL_NO_ML_KEM
+MAKE_ENCODER(ml_kem_512, ml_kem, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(ml_kem_512, ml_kem, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(ml_kem_512, ml_kem, PrivateKeyInfo, der);
+MAKE_ENCODER(ml_kem_512, ml_kem, PrivateKeyInfo, pem);
+MAKE_ENCODER(ml_kem_512, ml_kem, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(ml_kem_512, ml_kem, SubjectPublicKeyInfo, pem);
+
+MAKE_ENCODER(ml_kem_768, ml_kem, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(ml_kem_768, ml_kem, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(ml_kem_768, ml_kem, PrivateKeyInfo, der);
+MAKE_ENCODER(ml_kem_768, ml_kem, PrivateKeyInfo, pem);
+MAKE_ENCODER(ml_kem_768, ml_kem, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(ml_kem_768, ml_kem, SubjectPublicKeyInfo, pem);
+
+MAKE_ENCODER(ml_kem_1024, ml_kem, EncryptedPrivateKeyInfo, der);
+MAKE_ENCODER(ml_kem_1024, ml_kem, EncryptedPrivateKeyInfo, pem);
+MAKE_ENCODER(ml_kem_1024, ml_kem, PrivateKeyInfo, der);
+MAKE_ENCODER(ml_kem_1024, ml_kem, PrivateKeyInfo, pem);
+MAKE_ENCODER(ml_kem_1024, ml_kem, SubjectPublicKeyInfo, der);
+MAKE_ENCODER(ml_kem_1024, ml_kem, SubjectPublicKeyInfo, pem);
+#endif
+
 /*
  * Support for key type specific output formats.  Not all key types have
  * this, we only aim to duplicate what is available in 1.1.1 as
index e50eff4c205dc90aa8c153d1d94266b8556bfead..9c7a59f45f3e1c8c311df80c44ae28f84fd07d71 100644 (file)
@@ -23,6 +23,7 @@
 #include "crypto/dsa.h"          /* ossl_dsa_get0_params() */
 #include "crypto/ec.h"           /* ossl_ec_key_get_libctx */
 #include "crypto/ecx.h"          /* ECX_KEY, etc... */
+#include "crypto/ml_kem.h"       /* ML_KEM_KEY, etc... */
 #include "crypto/rsa.h"          /* RSA_PSS_PARAMS_30, etc... */
 #include "crypto/ml_dsa.h"
 #include "prov/bio.h"
@@ -430,7 +431,74 @@ static int ecx_to_text(BIO *out, const void *key, int selection)
 
     return 1;
 }
+#endif
+
+/* ---------------------------------------------------------------------- */
+
+#ifndef OPENSSL_NO_ML_KEM
+static int ml_kem_to_text(BIO *out, const void *vkey, int selection)
+{
+    const ML_KEM_KEY *key = vkey;
+    uint8_t seed[ML_KEM_SEED_BYTES], *prvenc = NULL, *pubenc = NULL;
+    size_t publen, prvlen;
+    const char *type_label = NULL;
+    int ret = 0;
+
+    if (out == NULL || key == NULL) {
+        ERR_raise(ERR_LIB_PROV, ERR_R_PASSED_NULL_PARAMETER);
+        return 0;
+    }
+    type_label = key->vinfo->algorithm_name;
+    publen = key->vinfo->pubkey_bytes;
+    prvlen = key->vinfo->prvkey_bytes;
+
+    if (!ossl_ml_kem_have_pubkey(key)) {
+        ERR_raise_data(ERR_LIB_PROV, PROV_R_MISSING_KEY,
+                       "no %s key material available",
+                       type_label);
+        return 0;
+    }
+
+    if ((selection & OSSL_KEYMGMT_SELECT_PRIVATE_KEY) != 0) {
+        if (!ossl_ml_kem_have_prvkey(key)) {
+            ERR_raise_data(ERR_LIB_PROV, PROV_R_MISSING_KEY,
+                           "no %s private key material available",
+                           key->vinfo->algorithm_name);
+            return 0;
+        }
+        if (BIO_printf(out, "%s Private-Key:\n", type_label) <= 0)
+            return 0;
+
+        if ((prvenc = OPENSSL_malloc(prvlen)) == NULL)
+            return 0;
+
+        if (ossl_ml_kem_have_seed(key)) {
+            if (!ossl_ml_kem_encode_key_seed(seed, sizeof(seed), key))
+                goto end;
+            if (!ossl_bio_print_labeled_buf(out, "seed:", seed, sizeof(seed)))
+                goto end;
+        }
+
+        if (!ossl_ml_kem_encode_private_key(prvenc, prvlen, key))
+            goto end;
+        if (!ossl_bio_print_labeled_buf(out, "dk:", prvenc, prvlen))
+            goto end;
 
+    } else if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
+        if (BIO_printf(out, "%s Public-Key:\n", type_label) <= 0)
+            goto end;
+    }
+
+    pubenc = OPENSSL_malloc(key->vinfo->pubkey_bytes);
+    if (pubenc != NULL)
+        ret = ossl_ml_kem_encode_public_key(pubenc, publen, key)
+            && ossl_bio_print_labeled_buf(out, "ek:", pubenc, publen);
+
+  end:
+    OPENSSL_free(pubenc);
+    OPENSSL_free(prvenc);
+    return ret;
+}
 #endif
 
 /* ---------------------------------------------------------------------- */
@@ -689,6 +757,11 @@ MAKE_TEXT_ENCODER(x25519, ecx);
 MAKE_TEXT_ENCODER(x448, ecx);
 # endif
 #endif
+#ifndef OPENSSL_NO_ML_KEM
+MAKE_TEXT_ENCODER(ml_kem_512, ml_kem);
+MAKE_TEXT_ENCODER(ml_kem_768, ml_kem);
+MAKE_TEXT_ENCODER(ml_kem_1024, ml_kem);
+#endif
 MAKE_TEXT_ENCODER(rsa, rsa);
 MAKE_TEXT_ENCODER(rsapss, rsa);
 
index 79ee0628c9ac51cc3adb5c662aee13a518624211..06d1b3304a7fc67040b8b1b9e51fc3404499620d 100644 (file)
@@ -627,6 +627,38 @@ extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ed25519_decoder_func
 extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_ed448_decoder_functions[];
 extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ed448_decoder_functions[];
 
+#ifndef OPENSSL_NO_ML_KEM
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_ml_kem_512_decoder_functions[];
+extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ml_kem_512_decoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_512_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_512_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_512_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_512_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_512_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_512_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_512_to_text_encoder_functions[];
+
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_ml_kem_768_decoder_functions[];
+extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ml_kem_768_decoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_768_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_768_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_768_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_768_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_768_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_768_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_768_to_text_encoder_functions[];
+
+extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_ml_kem_1024_decoder_functions[];
+extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_ml_kem_1024_decoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_1024_to_EncryptedPrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_1024_to_EncryptedPrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_1024_to_PrivateKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_1024_to_PrivateKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_1024_to_SubjectPublicKeyInfo_der_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_1024_to_SubjectPublicKeyInfo_pem_encoder_functions[];
+extern const OSSL_DISPATCH ossl_ml_kem_1024_to_text_encoder_functions[];
+#endif
+
 #ifndef OPENSSL_NO_SM2
 extern const OSSL_DISPATCH ossl_PrivateKeyInfo_der_to_sm2_decoder_functions[];
 extern const OSSL_DISPATCH ossl_SubjectPublicKeyInfo_der_to_sm2_decoder_functions[];
index 0bd64fe3fe3a477836c5151eb7fa71e45be77596..9fc31947776b51f57d9789be32c55fa6444953c0 100644 (file)
 #define PROV_DESCS_ML_DSA_65 "OpenSSL ML-DSA-65 implementation"
 #define PROV_NAMES_ML_DSA_87 "ML-DSA-87:2.16.840.1.101.3.4.3.19:id-ml-dsa-87"
 #define PROV_DESCS_ML_DSA_87 "OpenSSL ML-DSA-87 implementation"
-#define PROV_NAMES_ML_KEM_512 "ML-KEM-512:MLKEM512"
+#define PROV_NAMES_ML_KEM_512 "ML-KEM-512:MLKEM512:2.16.840.1.101.3.4.4.1"
 #define PROV_DESCS_ML_KEM_512 "OpenSSL ML-KEM-512 implementation"
-#define PROV_NAMES_ML_KEM_768 "ML-KEM-768:MLKEM768"
+#define PROV_NAMES_ML_KEM_768 "ML-KEM-768:MLKEM768:2.16.840.1.101.3.4.4.2"
 #define PROV_DESCS_ML_KEM_768 "OpenSSL ML-KEM-768 implementation"
-#define PROV_NAMES_ML_KEM_1024 "ML-KEM-1024:MLKEM1024"
+#define PROV_NAMES_ML_KEM_1024 "ML-KEM-1024:MLKEM1024:2.16.840.1.101.3.4.4.3"
 #define PROV_DESCS_ML_KEM_1024 "OpenSSL ML-KEM-1024 implementation"
 #define PROV_NAMES_X25519MLKEM768 "X25519MLKEM768"
 #define PROV_DESCS_X25519MLKEM768 "X25519+ML-KEM-768 TLS hybrid implementation"
index 01f76123714d27831ca34e205d021eb7734b72bf..e27823163682c89fc9645682ab5689a48a293525 100644 (file)
@@ -32,6 +32,9 @@ static OSSL_FUNC_keymgmt_gen_init_fn ml_kem_1024_gen_init;
 static OSSL_FUNC_keymgmt_gen_cleanup_fn ml_kem_gen_cleanup;
 static OSSL_FUNC_keymgmt_gen_set_params_fn ml_kem_gen_set_params;
 static OSSL_FUNC_keymgmt_gen_settable_params_fn ml_kem_gen_settable_params;
+#ifndef FIPS_MODULE
+static OSSL_FUNC_keymgmt_load_fn ml_kem_load;
+#endif
 static OSSL_FUNC_keymgmt_get_params_fn ml_kem_get_params;
 static OSSL_FUNC_keymgmt_gettable_params_fn ml_kem_gettable_params;
 static OSSL_FUNC_keymgmt_set_params_fn ml_kem_set_params;
@@ -51,7 +54,7 @@ typedef struct ml_kem_gen_ctx_st {
     OSSL_LIB_CTX *libctx;
     char *propq;
     int selection;
-    int variant;
+    int evp_type;
     uint8_t seedbuf[ML_KEM_SEED_BYTES];
     uint8_t *seed;
 } PROV_ML_KEM_GEN_CTX;
@@ -122,11 +125,11 @@ err:
 }
 #endif  /* FIPS_MODULE */
 
-static void *ml_kem_new(OSSL_LIB_CTX *libctx, char *propq, int variant)
+static void *ml_kem_new(OSSL_LIB_CTX *libctx, char *propq, int evp_type)
 {
     if (!ossl_prov_is_running())
         return NULL;
-    return ossl_ml_kem_key_new(libctx, propq, variant);
+    return ossl_ml_kem_key_new(libctx, propq, evp_type);
 }
 
 static int ml_kem_has(const void *vkey, int selection)
@@ -171,6 +174,7 @@ static int ml_kem_export(void *vkey, int selection, OSSL_CALLBACK *param_cb,
     uint8_t *pubenc = NULL;
     uint8_t *prvenc = NULL;
     const ML_KEM_VINFO *v;
+    size_t prvlen = 0;
     int ret = 0;
 
     if (!ossl_prov_is_running() || key == NULL)
@@ -188,7 +192,8 @@ static int ml_kem_export(void *vkey, int selection, OSSL_CALLBACK *param_cb,
 
     if ((selection & OSSL_KEYMGMT_SELECT_PUBLIC_KEY) != 0) {
         pubenc = OPENSSL_malloc(v->pubkey_bytes);
-        if (pubenc == NULL)
+        if (pubenc == NULL
+            || !ossl_ml_kem_encode_public_key(pubenc, v->pubkey_bytes, key))
             goto err;
     }
 
@@ -199,9 +204,17 @@ static int ml_kem_export(void *vkey, int selection, OSSL_CALLBACK *param_cb,
          * ossl_param_build_set_octet_string(), which will then also use the
          * secure heap.
          */
-        prvenc = OPENSSL_secure_zalloc(v->prvkey_bytes);
-        if (prvenc == NULL)
-            goto err;
+        if (ossl_ml_kem_have_seed(key)) {
+            prvlen = ML_KEM_SEED_BYTES;
+            if ((prvenc = OPENSSL_secure_zalloc(prvlen)) == NULL
+                || !ossl_ml_kem_encode_key_seed(prvenc, prvlen, key))
+                goto err;
+        } else {
+            prvlen = v->prvkey_bytes;
+            if ((prvenc = OPENSSL_secure_zalloc(prvlen)) == NULL
+                || !ossl_ml_kem_encode_private_key(prvenc, prvlen, key))
+                goto err;
+        }
     }
 
     tmpl = OSSL_PARAM_BLD_new();
@@ -209,19 +222,18 @@ static int ml_kem_export(void *vkey, int selection, OSSL_CALLBACK *param_cb,
         goto err;
 
     /* The public key on request; it is always available when either is */
-    if (pubenc != NULL)
-        if (!ossl_ml_kem_encode_public_key(pubenc, v->pubkey_bytes, key)
-            || !ossl_param_build_set_octet_string(
-                   tmpl, params, OSSL_PKEY_PARAM_PUB_KEY,
-                   pubenc, v->pubkey_bytes))
+    if (pubenc != NULL
+        && !ossl_param_build_set_octet_string(
+               tmpl, params, OSSL_PKEY_PARAM_PUB_KEY, pubenc, v->pubkey_bytes))
             goto err;
 
-    /* The private key on request */
-    if (prvenc != NULL && ossl_ml_kem_have_prvkey(key))
-        if (!ossl_ml_kem_encode_private_key(prvenc, v->prvkey_bytes, key)
-            || !ossl_param_build_set_octet_string(
-                    tmpl, params, OSSL_PKEY_PARAM_PRIV_KEY,
-                    prvenc, v->prvkey_bytes))
+    /*-
+     * The private key on request, in the (d, z) seed format, when available,
+     * otherwise in the FIPS 203 |dk| format.
+     */
+    if (prvenc != NULL
+        && !ossl_param_build_set_octet_string(
+                tmpl, params, OSSL_PKEY_PARAM_PRIV_KEY, prvenc, prvlen))
             goto err;
 
     params = OSSL_PARAM_BLD_to_param(tmpl);
@@ -233,7 +245,7 @@ static int ml_kem_export(void *vkey, int selection, OSSL_CALLBACK *param_cb,
 
 err:
     OSSL_PARAM_BLD_free(tmpl);
-    OPENSSL_secure_clear_free(prvenc, v->prvkey_bytes);
+    OPENSSL_secure_clear_free(prvenc, prvlen);
     OPENSSL_free(pubenc);
     return ret;
 }
@@ -255,7 +267,8 @@ static int ml_kem_key_fromdata(ML_KEM_KEY *key,
                                const OSSL_PARAM params[],
                                int include_private)
 {
-    const OSSL_PARAM *param_prv_key = NULL, *param_pub_key;
+    const OSSL_PARAM *p = NULL;
+    const uint8_t *d = NULL, *z = NULL;
     const void *pubenc = NULL, *prvenc = NULL;
     size_t publen = 0, prvlen = 0;
     const ML_KEM_VINFO *v;
@@ -266,17 +279,34 @@ static int ml_kem_key_fromdata(ML_KEM_KEY *key,
     v = ossl_ml_kem_key_vinfo(key);
 
     /* What does the caller want to set? */
-    param_pub_key = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
-    if (param_pub_key != NULL &&
-        OSSL_PARAM_get_octet_string_ptr(param_pub_key, &pubenc, &publen) != 1)
-        return 0;
-    if (include_private)
-        param_prv_key = OSSL_PARAM_locate_const(params,
-                                                OSSL_PKEY_PARAM_PRIV_KEY);
-    if (param_prv_key != NULL &&
-        OSSL_PARAM_get_octet_string_ptr(param_prv_key, &prvenc, &prvlen) != 1)
+    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PUB_KEY);
+    if (p != NULL &&
+        OSSL_PARAM_get_octet_string_ptr(p, &pubenc, &publen) != 1)
         return 0;
 
+    /*
+     * Accept private keys in either expanded or seed form, distinguished by
+     * length alone.  Accept either the "raw" or "encoded" parameters as the
+     * input source, preferring the raw, which is expected to be the seed if
+     * the caller supports seeds as a key format.
+     */
+    if (include_private) {
+        p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_PRIV_KEY);
+        if (p == NULL)
+            p = OSSL_PARAM_locate_const(params,
+                                        OSSL_PKEY_PARAM_ENCODED_PRIVATE_KEY);
+        if (p != NULL
+            && OSSL_PARAM_get_octet_string_ptr(p, &prvenc, &prvlen) != 1)
+            return 0;
+        if (prvlen == ML_KEM_SEED_BYTES) {
+            d = (uint8_t *)prvenc;
+            z = d + ML_KEM_RANDOM_BYTES;
+        } else if (prvlen != 0 && prvlen != v->prvkey_bytes) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
+            return 0;
+        }
+    }
+
     /* The caller MUST specify at least one of the public or private keys. */
     if (publen == 0 && prvlen == 0) {
         ERR_raise(ERR_LIB_PROV, PROV_R_MISSING_KEY);
@@ -292,15 +322,14 @@ static int ml_kem_key_fromdata(ML_KEM_KEY *key,
         ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
         return 0;
     }
-    if (prvlen != 0 && prvlen != v->prvkey_bytes) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY_LENGTH);
-        return 0;
-    }
 
     /*
      * If the private key is given, we'll ignore the public key data, taking
-     * the embedded public key as authoritative.
+     * the embedded public key as authoritative.  For import, the private key
+     * is in either (d, z) seed format or the FIPS 203 expanded format.
      */
+    if (d != NULL)
+        return ossl_ml_kem_genkey(d, z, NULL, 0, key);
     if (prvlen != 0)
         return ossl_ml_kem_parse_private_key(prvenc, prvlen, key);
     return ossl_ml_kem_parse_public_key(pubenc, publen, key);
@@ -336,13 +365,29 @@ static const OSSL_PARAM *ml_kem_gettable_params(void *provctx)
         OSSL_PARAM_int(OSSL_PKEY_PARAM_SECURITY_BITS, NULL),
         OSSL_PARAM_int(OSSL_PKEY_PARAM_MAX_SIZE, NULL),
         OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
-        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_PRIV_KEY, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PRIVATE_KEY, NULL, 0),
         OSSL_PARAM_END
     };
 
     return arr;
 }
 
+#ifndef FIPS_MODULE
+void *ml_kem_load(const void *reference, size_t reference_sz)
+{
+    ML_KEM_KEY *key = NULL;
+
+    if (ossl_prov_is_running() && reference_sz == sizeof(key)) {
+        /* The contents of the reference is the address to our object */
+        key = *(ML_KEM_KEY **)reference;
+        /* We grabbed, so we detach it */
+        *(ML_KEM_KEY **)reference = NULL;
+        return key;
+    }
+    return NULL;
+}
+#endif
+
 /*
  * It is assumed the key is guaranteed non-NULL here, and is from this provider
  */
@@ -380,7 +425,7 @@ static int ml_kem_get_params(void *vkey, OSSL_PARAM params[])
         }
     }
 
-    p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_PRIV_KEY);
+    p = OSSL_PARAM_locate(params, OSSL_PKEY_PARAM_ENCODED_PRIVATE_KEY);
     if (p != NULL && ossl_ml_kem_have_prvkey(key)) {
         if (p->data_type != OSSL_PARAM_OCTET_STRING)
             return 0;
@@ -392,6 +437,7 @@ static int ml_kem_get_params(void *vkey, OSSL_PARAM params[])
                 return 0;
         }
     }
+
     return 1;
 }
 
@@ -399,6 +445,7 @@ static const OSSL_PARAM *ml_kem_settable_params(void *provctx)
 {
     static const OSSL_PARAM arr[] = {
         OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY, NULL, 0),
+        OSSL_PARAM_octet_string(OSSL_PKEY_PARAM_ENCODED_PRIVATE_KEY, NULL, 0),
         OSSL_PARAM_END
     };
 
@@ -408,16 +455,32 @@ static const OSSL_PARAM *ml_kem_settable_params(void *provctx)
 static int ml_kem_set_params(void *vkey, const OSSL_PARAM params[])
 {
     ML_KEM_KEY *key = vkey;
-    const ML_KEM_VINFO *v = ossl_ml_kem_key_vinfo(key);
     const OSSL_PARAM *p;
-    const void *pubenc = NULL;
-    size_t publen = 0;
+    const void *pubenc = NULL, *prvenc = NULL;
+    size_t publen = 0, prvlen = 0;
 
     if (ossl_param_is_empty(params))
         return 1;
 
-    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
-    if (p == NULL)
+    p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PRIVATE_KEY);
+    if (p != NULL
+        && (OSSL_PARAM_get_octet_string_ptr(p, &prvenc, &prvlen) != 1
+            || prvlen != key->vinfo->prvkey_bytes)) {
+        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
+        return 0;
+    }
+
+    if (prvlen == 0) {
+        p = OSSL_PARAM_locate_const(params, OSSL_PKEY_PARAM_ENCODED_PUBLIC_KEY);
+        if (p != NULL
+            && (OSSL_PARAM_get_octet_string_ptr(p, &pubenc, &publen) != 1
+                || publen != key->vinfo->pubkey_bytes)) {
+            ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
+            return 0;
+        }
+    }
+
+    if (publen == 0 && prvlen == 0)
         return 1;
 
     /* Key mutation is reportedly generally not allowed */
@@ -427,16 +490,11 @@ static int ml_kem_set_params(void *vkey, const OSSL_PARAM params[])
                        "ML-KEM keys cannot be mutated");
         return 0;
     }
-    /* An unlikely failure mode is the parameter having some unexpected type */
-    if (!OSSL_PARAM_get_octet_string_ptr(p, &pubenc, &publen))
-        return 0;
-
-    if (publen != v->pubkey_bytes) {
-        ERR_raise(ERR_LIB_PROV, PROV_R_INVALID_KEY);
-        return 0;
-    }
 
-    return ossl_ml_kem_parse_public_key(pubenc, publen, key);
+    if (prvlen)
+        return ossl_ml_kem_parse_private_key(prvenc, prvlen, key);
+    else
+        return ossl_ml_kem_parse_public_key(pubenc, publen, key);
 }
 
 static int ml_kem_gen_set_params(void *vgctx, const OSSL_PARAM params[])
@@ -476,7 +534,7 @@ static int ml_kem_gen_set_params(void *vgctx, const OSSL_PARAM params[])
 }
 
 static void *ml_kem_gen_init(void *provctx, int selection,
-                             const OSSL_PARAM params[], int variant)
+                             const OSSL_PARAM params[], int evp_type)
 {
     PROV_ML_KEM_GEN_CTX *gctx = NULL;
 
@@ -490,7 +548,7 @@ static void *ml_kem_gen_init(void *provctx, int selection,
         return NULL;
 
     gctx->selection = selection;
-    gctx->variant = variant;
+    gctx->evp_type = evp_type;
     if (provctx != NULL)
         gctx->libctx = PROV_LIBCTX_OF(provctx);
     if (ml_kem_gen_set_params(gctx, params))
@@ -523,7 +581,7 @@ static void *ml_kem_gen(void *vgctx, OSSL_CALLBACK *osslcb, void *cbarg)
     if (gctx == NULL
         || (gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) ==
             OSSL_KEYMGMT_SELECT_PUBLIC_KEY
-        || (key = ml_kem_new(gctx->libctx, gctx->propq, gctx->variant)) == NULL)
+        || (key = ml_kem_new(gctx->libctx, gctx->propq, gctx->evp_type)) == NULL)
         return NULL;
 
     if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
@@ -571,16 +629,23 @@ static void *ml_kem_dup(const void *vkey, int selection)
     return ossl_ml_kem_key_dup(key, selection);
 }
 
+#ifndef FIPS_MODULE
+# define DISPATCH_LOAD_FN \
+        { OSSL_FUNC_KEYMGMT_LOAD, (OSSL_FUNC) ml_kem_load },
+#else
+# define DISPATCH_LOAD_FN   /* Non-FIPS only */
+#endif
+
 #define DECLARE_VARIANT(bits) \
     static void *ml_kem_##bits##_new(void *provctx) \
     { \
         return ml_kem_new(provctx == NULL ? NULL : PROV_LIBCTX_OF(provctx), \
-                          NULL, ML_KEM_##bits##_VARIANT); \
+                          NULL, NID_ML_KEM_##bits); \
     } \
     static void *ml_kem_##bits##_gen_init(void *provctx, int selection, \
                                           const OSSL_PARAM params[]) \
     { \
-        return ml_kem_gen_init(provctx, selection, params, ML_KEM_##bits##_VARIANT); \
+        return ml_kem_gen_init(provctx, selection, params, NID_ML_KEM_##bits); \
     } \
     const OSSL_DISPATCH ossl_ml_kem_##bits##_keymgmt_functions[] = { \
         { OSSL_FUNC_KEYMGMT_NEW, (OSSL_FUNC) ml_kem_##bits##_new }, \
@@ -596,6 +661,7 @@ static void *ml_kem_dup(const void *vkey, int selection)
         { OSSL_FUNC_KEYMGMT_GEN_SETTABLE_PARAMS, (OSSL_FUNC) ml_kem_gen_settable_params }, \
         { OSSL_FUNC_KEYMGMT_GEN, (OSSL_FUNC) ml_kem_gen }, \
         { OSSL_FUNC_KEYMGMT_GEN_CLEANUP, (OSSL_FUNC) ml_kem_gen_cleanup }, \
+        DISPATCH_LOAD_FN \
         { OSSL_FUNC_KEYMGMT_DUP, (OSSL_FUNC) ml_kem_dup }, \
         { OSSL_FUNC_KEYMGMT_IMPORT, (OSSL_FUNC) ml_kem_import }, \
         { OSSL_FUNC_KEYMGMT_IMPORT_TYPES, (OSSL_FUNC) ml_kem_imexport_types }, \
index d0dce6202c543973c280e3e24cfb48aad096b8b8..efd766bb79bc52d6040716ec4bfb48e6ecd7293b 100644 (file)
@@ -44,11 +44,11 @@ static const int minimal_selection = OSSL_KEYMGMT_SELECT_DOMAIN_PARAMETERS
 
 /* Must match DECLARE_DISPATCH invocations at the end of the file */
 static const ECDH_VINFO hybrid_vtable[] = {
-    { "EC",  "P-256", 65, 32, 32, 1, ML_KEM_768_VARIANT },
-    { "EC",  "P-384", 97, 48, 48, 1, ML_KEM_1024_VARIANT },
+    { "EC",  "P-256", 65, 32, 32, 1, NID_ML_KEM_768 },
+    { "EC",  "P-384", 97, 48, 48, 1, NID_ML_KEM_1024 },
 #if !defined(OPENSSL_NO_ECX)
-    { "X25519", NULL, 32, 32, 32, 0, ML_KEM_768_VARIANT },
-    { "X448",   NULL, 56, 56, 56, 0, ML_KEM_1024_VARIANT },
+    { "X25519", NULL, 32, 32, 32, 0, NID_ML_KEM_768 },
+    { "X448",   NULL, 56, 56, 56, 0, NID_ML_KEM_1024 },
 #endif
 };
 
@@ -56,7 +56,7 @@ typedef struct mlx_kem_gen_ctx_st {
     OSSL_LIB_CTX *libctx;
     char *propq;
     int selection;
-    unsigned int variant;
+    unsigned int evp_type;
 } PROV_ML_KEM_GEN_CTX;
 
 static void mlx_kem_key_free(void *vkey)
@@ -648,8 +648,8 @@ static int mlx_kem_gen_set_params(void *vgctx, const OSSL_PARAM params[])
     return 1;
 }
 
-static void *mlx_kem_gen_init(int v, OSSL_LIB_CTX *libctx, int selection,
-                              const OSSL_PARAM params[])
+static void *mlx_kem_gen_init(int evp_type, OSSL_LIB_CTX *libctx,
+                              int selection, const OSSL_PARAM params[])
 {
     PROV_ML_KEM_GEN_CTX *gctx = NULL;
 
@@ -662,7 +662,7 @@ static void *mlx_kem_gen_init(int v, OSSL_LIB_CTX *libctx, int selection,
         || (gctx = OPENSSL_zalloc(sizeof(*gctx))) == NULL)
         return NULL;
 
-    gctx->variant = v;
+    gctx->evp_type = evp_type;
     gctx->libctx = libctx;
     gctx->selection = selection;
     if (mlx_kem_gen_set_params(gctx, params))
@@ -696,7 +696,7 @@ static void *mlx_kem_gen(void *vgctx, OSSL_CALLBACK *osslcb, void *cbarg)
 
     /* Lose ownership of propq */
     gctx->propq = NULL;
-    if ((key = mlx_kem_key_new(gctx->variant, gctx->libctx, propq)) == NULL)
+    if ((key = mlx_kem_key_new(gctx->evp_type, gctx->libctx, propq)) == NULL)
         return NULL;
 
     if ((gctx->selection & OSSL_KEYMGMT_SELECT_KEYPAIR) == 0)
index e730ac4ca528c474fe1e93cd387efa12a825418b..0ec10f5ae6eac260aac93e7d3682a77c81513e2f 100644 (file)
@@ -106,8 +106,11 @@ static EVP_PKEY *make_template(const char *type, OSSL_PARAM *genparams)
 }
 #endif
 
-#if !defined(OPENSSL_NO_DH) || !defined(OPENSSL_NO_DSA) \
-    || !defined(OPENSSL_NO_EC) || !defined(OPENSSL_NO_ML_DSA)
+#if !defined(OPENSSL_NO_DH) || \
+    !defined(OPENSSL_NO_DSA) || \
+    !defined(OPENSSL_NO_EC) || \
+    !defined(OPENSSL_NO_ML_DSA) || \
+    !defined(OPENSSL_NO_ML_KEM)
 static EVP_PKEY *make_key(const char *type, EVP_PKEY *template,
                           OSSL_PARAM *genparams)
 {
@@ -1038,6 +1041,12 @@ IMPLEMENT_TEST_SUITE_LEGACY(ECExplicitTri2G, "EC")
 KEYS(SM2);
 IMPLEMENT_TEST_SUITE(SM2, "SM2", 0)
 # endif
+#endif
+#ifndef OPENSSL_NO_ECX
+/*
+ * ED25519, ED448, X25519 and X448 have no support for
+ * PEM_write_bio_PrivateKey_traditional(), so no legacy tests.
+ */
 KEYS(ED25519);
 IMPLEMENT_TEST_SUITE(ED25519, "ED25519", 1)
 KEYS(ED448);
@@ -1046,10 +1055,19 @@ KEYS(X25519);
 IMPLEMENT_TEST_SUITE(X25519, "X25519", 1)
 KEYS(X448);
 IMPLEMENT_TEST_SUITE(X448, "X448", 1)
+#endif
+#ifndef OPENSSL_NO_ML_KEM
 /*
- * ED25519, ED448, X25519 and X448 have no support for
- * PEM_write_bio_PrivateKey_traditional(), so no legacy tests.
+ * ML-KEM has no support for PEM_write_bio_PrivateKey_traditional(), so no
+ * legacy tests.
+ * TODO(ML-KEM): FIPS
  */
+KEYS(ML_KEM_512);
+IMPLEMENT_TEST_SUITE(ML_KEM_512, "ML-KEM-512", 1)
+KEYS(ML_KEM_768);
+IMPLEMENT_TEST_SUITE(ML_KEM_768, "ML-KEM-768", 1)
+KEYS(ML_KEM_1024);
+IMPLEMENT_TEST_SUITE(ML_KEM_1024, "ML-KEM-1024", 1)
 #endif
 KEYS(RSA);
 IMPLEMENT_TEST_SUITE(RSA, "RSA", 1)
@@ -1415,6 +1433,8 @@ int setup_tests(void)
 # ifndef OPENSSL_NO_SM2
     MAKE_KEYS(SM2, "SM2", NULL);
 # endif
+#endif
+#ifndef OPENSSL_NO_ECX
     MAKE_KEYS(ED25519, "ED25519", NULL);
     MAKE_KEYS(ED448, "ED448", NULL);
     MAKE_KEYS(X25519, "X25519", NULL);
@@ -1427,6 +1447,11 @@ int setup_tests(void)
         MAKE_KEYS(ML_DSA_87, "ML-DSA-87", NULL);
     }
 #endif /* OPENSSL_NO_ML_DSA */
+#ifndef OPENSSL_NO_ML_KEM
+    MAKE_KEYS(ML_KEM_512, "ML-KEM-512", NULL);
+    MAKE_KEYS(ML_KEM_768, "ML-KEM-768", NULL);
+    MAKE_KEYS(ML_KEM_1024, "ML-KEM-1024", NULL);
+#endif
 
     TEST_info("Loading RSA key...");
     ok = ok && TEST_ptr(key_RSA = load_pkey_pem(rsa_file, keyctx));
@@ -1475,15 +1500,22 @@ int setup_tests(void)
             ADD_TEST_SUITE(SM2);
         }
 # endif
+#endif
+#ifndef OPENSSL_NO_ECX
         ADD_TEST_SUITE(ED25519);
         ADD_TEST_SUITE(ED448);
         ADD_TEST_SUITE(X25519);
         ADD_TEST_SUITE(X448);
+#endif
+#ifndef OPENSSL_NO_ML_KEM
+        ADD_TEST_SUITE(ML_KEM_512);
+        ADD_TEST_SUITE(ML_KEM_768);
+        ADD_TEST_SUITE(ML_KEM_1024);
+#endif
         /*
          * ED25519, ED448, X25519 and X448 have no support for
          * PEM_write_bio_PrivateKey_traditional(), so no legacy tests.
          */
-#endif
         ADD_TEST_SUITE(RSA);
         ADD_TEST_SUITE_LEGACY(RSA);
         ADD_TEST_SUITE(RSA_PSS);
@@ -1543,10 +1575,17 @@ void cleanup_tests(void)
 # ifndef OPENSSL_NO_SM2
     FREE_KEYS(SM2);
 # endif
+#endif
+#ifndef OPENSSL_NO_ECX
     FREE_KEYS(ED25519);
     FREE_KEYS(ED448);
     FREE_KEYS(X25519);
     FREE_KEYS(X448);
+#endif
+#ifndef OPENSSL_NO_ML_KEM
+    FREE_KEYS(ML_KEM_512);
+    FREE_KEYS(ML_KEM_768);
+    FREE_KEYS(ML_KEM_1024);
 #endif
     FREE_KEYS(RSA);
     FREE_KEYS(RSA_PSS);
index 1b5e5495188493d40a212309fb5c9f85b858dd94..20db61826fe46112744bf93cb611108a52dfb931 100644 (file)
@@ -2575,6 +2575,14 @@ done:
 #endif
 
 #ifndef OPENSSL_NO_ML_KEM
+static const uint8_t ml_kem_prvkey[] = {
+  0x7c, 0x99, 0x35, 0xa0, 0xb0, 0x76, 0x94, 0xaa, 0x0c, 0x6d, 0x10, 0xe4,
+  0xdb, 0x6b, 0x1a, 0xdd, 0x2f, 0xd8, 0x1a, 0x25, 0xcc, 0xb1, 0x48, 0x03,
+  0x2d, 0xcd, 0x73, 0x99, 0x36, 0x73, 0x7f, 0x2d, 0x86, 0x26, 0xed, 0x79,
+  0xd4, 0x51, 0x14, 0x08, 0x00, 0xe0, 0x3b, 0x59, 0xb9, 0x56, 0xf8, 0x21,
+  0x0e, 0x55, 0x60, 0x67, 0x40, 0x7d, 0x13, 0xdc, 0x90, 0xfa, 0x9e, 0x8b,
+  0x87, 0x2b, 0xfb, 0x8f
+};
 static const uint8_t ml_kem_512_pubkey[] = {
   0x40, 0x08, 0x65, 0xed, 0x10, 0xb6, 0x19, 0xaa, 0x58, 0x11, 0x13, 0x9b,
   0xc0, 0x86, 0x82, 0x57, 0x82, 0xb2, 0xb7, 0x12, 0x4f, 0x75, 0x7c, 0x83,
@@ -2644,144 +2652,6 @@ static const uint8_t ml_kem_512_pubkey[] = {
   0x4b, 0xc1, 0xa2, 0x42, 0xce, 0x99, 0x21, 0xaa, 0x9e, 0x22, 0x44, 0x88,
   0x19, 0x58, 0x5d, 0xea, 0x30, 0x8e, 0xb0, 0x39
 };
-static const uint8_t ml_kem_512_prvkey[] = {
-  0x9c, 0xda, 0x16, 0x86, 0xa3, 0x39, 0x6a, 0x7c, 0x10, 0x9b, 0x41, 0x52,
-  0x89, 0xf5, 0x6a, 0x9e, 0xc4, 0x4c, 0xd5, 0xb9, 0xb6, 0x74, 0xc3, 0x8a,
-  0x3b, 0xba, 0xb3, 0x0a, 0x2c, 0x90, 0xf0, 0x04, 0x37, 0xa2, 0x64, 0xb0,
-  0xbe, 0x9a, 0x1e, 0x8b, 0xa8, 0x87, 0xd3, 0xc3, 0xb1, 0x00, 0x89, 0x80,
-  0x54, 0x27, 0x2f, 0x94, 0x1c, 0x88, 0xa1, 0xf2, 0x08, 0xf1, 0xc9, 0x14,
-  0xf9, 0x64, 0xc1, 0xaa, 0xd6, 0x13, 0xa6, 0xa8, 0x4f, 0x88, 0xe4, 0x2d,
-  0x35, 0x56, 0x83, 0x5f, 0xb1, 0x61, 0xfd, 0xc5, 0xcd, 0x15, 0xa3, 0xbc,
-  0x7e, 0x74, 0xb6, 0xf2, 0x61, 0x2f, 0xa8, 0x27, 0x1c, 0x7e, 0xa1, 0x12,
-  0xb0, 0x5c, 0x2a, 0x36, 0xcc, 0x70, 0x7c, 0xe3, 0x8d, 0x5d, 0x1a, 0xcc,
-  0x51, 0x15, 0x46, 0x2a, 0x8c, 0x1a, 0xab, 0xf0, 0x72, 0x76, 0xc7, 0x23,
-  0x18, 0x33, 0x7f, 0x74, 0xb5, 0xcb, 0xef, 0xea, 0x7a, 0x80, 0x37, 0x90,
-  0xbc, 0x03, 0x93, 0xf3, 0xa5, 0x4c, 0x72, 0x4a, 0x57, 0x65, 0xa4, 0x8f,
-  0x29, 0x6b, 0x03, 0xf4, 0x84, 0x37, 0x60, 0x23, 0x62, 0x69, 0x30, 0x22,
-  0x27, 0x04, 0xc0, 0x8f, 0xd3, 0xbc, 0x72, 0x93, 0x15, 0xd1, 0xfc, 0x70,
-  0xeb, 0x79, 0x75, 0xa9, 0x7b, 0x9d, 0xee, 0xd1, 0x62, 0xf4, 0x86, 0xbb,
-  0xc6, 0x4a, 0x09, 0x71, 0x11, 0x95, 0x2d, 0x89, 0xb5, 0x7d, 0x76, 0x5e,
-  0x8a, 0x99, 0x1a, 0x2e, 0x56, 0x42, 0x06, 0xea, 0x7b, 0xf5, 0xe4, 0x00,
-  0x7a, 0x66, 0x35, 0x88, 0x31, 0xca, 0x0e, 0x34, 0xb2, 0xf6, 0xa8, 0x4d,
-  0x10, 0xf7, 0x9c, 0x47, 0x7c, 0xb6, 0x6a, 0x8a, 0x95, 0x25, 0x69, 0x36,
-  0x73, 0x88, 0x13, 0x0d, 0x7b, 0x97, 0x4a, 0x63, 0xaa, 0x51, 0x99, 0x6c,
-  0x97, 0x70, 0x9b, 0xb8, 0xea, 0xbc, 0x94, 0xe6, 0xa5, 0x35, 0xd7, 0x92,
-  0xd2, 0x90, 0x54, 0x74, 0x95, 0x2d, 0x6b, 0x8c, 0x22, 0x22, 0xb2, 0xae,
-  0x56, 0xdc, 0x66, 0xfb, 0x04, 0x61, 0x19, 0x20, 0x66, 0xcd, 0xdb, 0x43,
-  0xec, 0x05, 0x98, 0x4f, 0xb4, 0x98, 0x26, 0x49, 0x77, 0x13, 0x97, 0xc6,
-  0xa8, 0x37, 0x9f, 0x3b, 0x56, 0x43, 0x06, 0x98, 0x48, 0x87, 0x59, 0x19,
-  0xe8, 0x9c, 0xc4, 0x39, 0xa3, 0xbe, 0x2f, 0x08, 0x14, 0x90, 0xf3, 0x41,
-  0xbd, 0x12, 0x40, 0xad, 0xd8, 0x0d, 0xdb, 0x8c, 0x99, 0x63, 0xb4, 0x7a,
-  0x2a, 0x09, 0x92, 0x29, 0x03, 0x38, 0xda, 0x9c, 0x3b, 0x72, 0x5c, 0x6d,
-  0xa4, 0x47, 0x18, 0xc0, 0x10, 0x46, 0x81, 0x25, 0x62, 0xaf, 0xb0, 0x84,
-  0x83, 0x7a, 0xcb, 0x3c, 0x57, 0x5e, 0x4f, 0x93, 0x93, 0x6c, 0x35, 0x2a,
-  0xc0, 0xe7, 0x0a, 0xa3, 0x84, 0x5e, 0xe4, 0x85, 0x29, 0x6e, 0x6b, 0x02,
-  0xde, 0x0b, 0x47, 0xb5, 0xc4, 0xc9, 0x6b, 0x0b, 0x7c, 0xf9, 0x4c, 0x4a,
-  0xbe, 0x95, 0x48, 0x61, 0x53, 0x11, 0x8e, 0x43, 0xc2, 0xb9, 0xc8, 0x4d,
-  0x9d, 0xa9, 0x1c, 0x6c, 0x5a, 0xcd, 0x5a, 0x57, 0x00, 0x2d, 0x05, 0x84,
-  0x97, 0x99, 0x27, 0x99, 0xe5, 0xba, 0x1c, 0xe6, 0xc2, 0x5e, 0xb2, 0x98,
-  0x44, 0xd8, 0x58, 0xba, 0x1c, 0x37, 0x85, 0x0c, 0x0c, 0x2f, 0x57, 0xc6,
-  0x0d, 0xe3, 0x7f, 0x77, 0xc0, 0x82, 0xec, 0x14, 0x49, 0x4e, 0xba, 0x28,
-  0x8a, 0x65, 0x91, 0x51, 0x16, 0xc2, 0x0a, 0x32, 0x5d, 0xe3, 0x1a, 0xaa,
-  0xdd, 0x68, 0x0d, 0xb1, 0x9c, 0x0c, 0xfc, 0xc3, 0x46, 0x0f, 0x0a, 0xa0,
-  0x1a, 0x87, 0xa6, 0xa5, 0x80, 0xc6, 0xca, 0x29, 0x1f, 0xae, 0xf0, 0xcc,
-  0xc4, 0x9b, 0x76, 0xa8, 0xda, 0xc4, 0xf9, 0xd4, 0x16, 0x40, 0x50, 0x9d,
-  0xbd, 0x0b, 0x40, 0x45, 0xc1, 0x53, 0x0e, 0xd3, 0x47, 0x55, 0xd4, 0x74,
-  0x62, 0x70, 0x0f, 0x2a, 0x8c, 0xaf, 0x96, 0x80, 0xa6, 0xd7, 0xe3, 0x8a,
-  0x7e, 0x2a, 0x63, 0xe9, 0x37, 0x65, 0x0a, 0x23, 0x30, 0x6d, 0x85, 0x5d,
-  0xa2, 0xa2, 0xb7, 0xef, 0x50, 0x5c, 0xa5, 0x96, 0xab, 0x04, 0x85, 0x01,
-  0x3e, 0xa9, 0x27, 0xc7, 0x34, 0x23, 0x43, 0x61, 0x36, 0x43, 0xba, 0x40,
-  0x07, 0xd6, 0xc8, 0x74, 0xb9, 0x80, 0xc7, 0x9c, 0x3a, 0xa1, 0xc7, 0x4f,
-  0x85, 0x81, 0xc3, 0x48, 0x49, 0xb3, 0x6e, 0xa7, 0x98, 0x15, 0xfb, 0xb4,
-  0xcc, 0xf9, 0x61, 0x05, 0x83, 0x08, 0x1d, 0x7c, 0x5b, 0x44, 0x09, 0xb8,
-  0xd0, 0x53, 0x1c, 0x04, 0xbc, 0xaf, 0x7c, 0xc7, 0x51, 0x10, 0x3a, 0x5f,
-  0xd1, 0xba, 0x44, 0x70, 0x83, 0x3e, 0x89, 0x77, 0x5a, 0xde, 0xd9, 0x70,
-  0xb5, 0x47, 0x18, 0x59, 0x25, 0x0f, 0xe7, 0x26, 0x71, 0x05, 0x83, 0x5f,
-  0x39, 0x00, 0x30, 0xc5, 0xe7, 0xcd, 0x3f, 0x96, 0x10, 0x19, 0xea, 0xae,
-  0xa2, 0x37, 0x77, 0xd3, 0x47, 0xbb, 0x2a, 0xdc, 0xb6, 0x73, 0xc0, 0x20,
-  0x34, 0xf3, 0x94, 0x34, 0x22, 0x71, 0xbc, 0xea, 0x64, 0x14, 0xe5, 0x46,
-  0xc3, 0xb2, 0x0b, 0xd5, 0x74, 0x81, 0xc7, 0xea, 0x14, 0xc7, 0x7c, 0x38,
-  0x8c, 0xc8, 0x62, 0x51, 0xc1, 0x25, 0x58, 0xb1, 0x00, 0xf8, 0xc5, 0xb3,
-  0xd0, 0x3c, 0xa2, 0xc7, 0x07, 0x13, 0x90, 0x96, 0x59, 0xc8, 0xba, 0x26,
-  0xd0, 0xd1, 0x76, 0x5e, 0x0b, 0xc8, 0x23, 0xd6, 0x8c, 0xa5, 0x57, 0x0d,
-  0xe6, 0x00, 0xcd, 0x09, 0x41, 0x72, 0x5d, 0x38, 0x6e, 0x14, 0xc1, 0x01,
-  0x2d, 0xf5, 0x95, 0x1b, 0xeb, 0x8d, 0x82, 0x81, 0xa4, 0xf6, 0x81, 0x5d,
-  0x37, 0x60, 0xb7, 0x64, 0x29, 0x5a, 0xd0, 0x40, 0x6c, 0x2b, 0xf7, 0x92,
-  0x8a, 0xd6, 0x50, 0x32, 0xb6, 0x5f, 0x14, 0xb7, 0x7c, 0xcb, 0x89, 0x17,
-  0xc9, 0x3a, 0x29, 0xd6, 0x28, 0x7d, 0x8a, 0x60, 0x62, 0x39, 0x9c, 0xb6,
-  0x40, 0x08, 0x65, 0xed, 0x10, 0xb6, 0x19, 0xaa, 0x58, 0x11, 0x13, 0x9b,
-  0xc0, 0x86, 0x82, 0x57, 0x82, 0xb2, 0xb7, 0x12, 0x4f, 0x75, 0x7c, 0x83,
-  0xae, 0x79, 0x44, 0x44, 0xbc, 0x78, 0xa4, 0x78, 0x96, 0xac, 0xf1, 0x26,
-  0x2c, 0x81, 0x35, 0x10, 0x77, 0x89, 0x3b, 0xfc, 0x56, 0xf9, 0x04, 0x49,
-  0xc2, 0xfa, 0x5f, 0x6e, 0x58, 0x6d, 0xd3, 0x7c, 0x0b, 0x9b, 0x58, 0x19,
-  0x92, 0x63, 0x8c, 0xb7, 0xe7, 0xbc, 0xbb, 0xb9, 0x9a, 0xfe, 0x47, 0x81,
-  0xd8, 0x0a, 0x50, 0xe6, 0x94, 0x63, 0xfb, 0xd9, 0x88, 0x72, 0x2c, 0x36,
-  0x35, 0x42, 0x3e, 0x27, 0x46, 0x6c, 0x71, 0xdc, 0xc6, 0x74, 0x52, 0x7c,
-  0xcd, 0x72, 0x89, 0x68, 0xcb, 0xcd, 0xc0, 0x0c, 0x5c, 0x90, 0x35, 0xbb,
-  0x0a, 0xf2, 0xc9, 0x92, 0x2c, 0x78, 0x81, 0xa4, 0x1d, 0xd2, 0x87, 0x52,
-  0x73, 0x92, 0x51, 0x31, 0x23, 0x0f, 0x6c, 0xa5, 0x9e, 0x91, 0x36, 0xb3,
-  0x9f, 0x95, 0x6c, 0x93, 0xb3, 0xb2, 0xd1, 0x4c, 0x64, 0x1b, 0x08, 0x9e,
-  0x07, 0xd0, 0xa8, 0x40, 0xc8, 0x93, 0xec, 0xd7, 0x6b, 0xbf, 0x92, 0xc8,
-  0x05, 0x45, 0x66, 0x68, 0xd0, 0x7c, 0x62, 0x14, 0x91, 0xc5, 0xc0, 0x54,
-  0x99, 0x1a, 0x65, 0x6f, 0x51, 0x16, 0x19, 0x55, 0x6e, 0xb9, 0x77, 0x82,
-  0xe2, 0x7a, 0x3c, 0x78, 0x51, 0x24, 0xc7, 0x0b, 0x0d, 0xab, 0xa6, 0xc6,
-  0x24, 0xd1, 0x8e, 0x0f, 0x97, 0x93, 0xf9, 0x6b, 0xa9, 0xe1, 0x59, 0x9b,
-  0x17, 0xb3, 0x0d, 0xcc, 0xc0, 0xb4, 0xf3, 0x76, 0x6a, 0x07, 0xb2, 0x3b,
-  0x25, 0x73, 0x09, 0xcd, 0x76, 0xab, 0xa0, 0x72, 0xc2, 0xb9, 0xc9, 0x74,
-  0x43, 0x94, 0xc6, 0xab, 0x9c, 0xb6, 0xc5, 0x4a, 0x97, 0xb5, 0xc5, 0x78,
-  0x61, 0xa5, 0x8d, 0xc0, 0xa0, 0x35, 0x19, 0x83, 0x2e, 0xe3, 0x2a, 0x07,
-  0x65, 0x4a, 0x07, 0x0c, 0x0c, 0x8c, 0x4e, 0x86, 0x48, 0xad, 0xdc, 0x35,
-  0x5f, 0x27, 0x4f, 0xc6, 0xb9, 0x2a, 0x08, 0x7b, 0x3f, 0x97, 0x51, 0x92,
-  0x3e, 0x44, 0x27, 0x4f, 0x85, 0x8c, 0x49, 0xca, 0xba, 0x72, 0xb6, 0x58,
-  0x51, 0xb3, 0xad, 0xc4, 0x89, 0x36, 0x95, 0x50, 0x97, 0xca, 0xd9, 0x55,
-  0x3f, 0x5a, 0x26, 0x3f, 0x18, 0x44, 0xb5, 0x2a, 0x02, 0x0f, 0xf7, 0xca,
-  0x89, 0xe8, 0x81, 0xa0, 0x1b, 0x95, 0xd9, 0x57, 0xa3, 0x15, 0x3c, 0x0a,
-  0x5e, 0x0a, 0x1c, 0xcd, 0x66, 0xb1, 0x82, 0x1a, 0x2b, 0x86, 0x32, 0x54,
-  0x6e, 0x24, 0xc7, 0xcb, 0xbc, 0x4c, 0xb0, 0x88, 0x08, 0xca, 0xc3, 0x7f,
-  0x7d, 0xa6, 0xb1, 0x6f, 0x8a, 0xce, 0xd0, 0x52, 0xcd, 0xb2, 0x56, 0x49,
-  0x48, 0xf1, 0xab, 0x0f, 0x76, 0x8a, 0x0d, 0x32, 0x86, 0xcc, 0xc7, 0xc3,
-  0x74, 0x9c, 0x63, 0xc7, 0x81, 0x53, 0x0f, 0xa1, 0xae, 0x67, 0x05, 0x42,
-  0x85, 0x50, 0x04, 0xa6, 0x45, 0xb5, 0x22, 0x88, 0x1e, 0xc1, 0x41, 0x2b,
-  0xda, 0xe3, 0x42, 0x08, 0x5a, 0x9d, 0xd5, 0xf8, 0x12, 0x6a, 0xf9, 0x6b,
-  0xbd, 0xb0, 0xc1, 0xaf, 0x69, 0xa1, 0x55, 0x62, 0xcb, 0x2a, 0x15, 0x5a,
-  0x10, 0x03, 0x09, 0xd1, 0xb6, 0x41, 0xd0, 0x8b, 0x2d, 0x4e, 0xd1, 0x7b,
-  0xfb, 0xf0, 0xbc, 0x04, 0x26, 0x5f, 0x9b, 0x10, 0xc1, 0x08, 0xf8, 0x50,
-  0x30, 0x95, 0x04, 0xd7, 0x72, 0x81, 0x1b, 0xba, 0x8e, 0x2b, 0xe1, 0x62,
-  0x49, 0xaa, 0x73, 0x7d, 0x87, 0x9f, 0xc7, 0xfb, 0x25, 0x5e, 0xe7, 0xa6,
-  0xa0, 0xa7, 0x53, 0xbd, 0x93, 0x74, 0x1c, 0x61, 0x65, 0x8e, 0xc0, 0x74,
-  0xf6, 0xe0, 0x02, 0xb0, 0x19, 0x34, 0x57, 0x69, 0x11, 0x3c, 0xc0, 0x13,
-  0xff, 0x74, 0x94, 0xba, 0x83, 0x78, 0xb1, 0x1a, 0x17, 0x22, 0x60, 0xaa,
-  0xa5, 0x34, 0x21, 0xbd, 0xe0, 0x3a, 0x35, 0x58, 0x9d, 0x57, 0xe3, 0x22,
-  0xfe, 0xfa, 0x41, 0x00, 0xa4, 0x74, 0x39, 0x26, 0xab, 0x7d, 0x62, 0x25,
-  0x8b, 0x87, 0xb3, 0x1c, 0xcb, 0xb5, 0xe6, 0xb8, 0x9c, 0xb1, 0x0b, 0x27,
-  0x1a, 0xa0, 0x5d, 0x99, 0x4b, 0xb5, 0x70, 0x8b, 0x23, 0xab, 0x32, 0x7e,
-  0xcb, 0x93, 0xc0, 0xf3, 0x15, 0x68, 0x69, 0xf0, 0x88, 0x3d, 0xa2, 0x06,
-  0x4f, 0x79, 0x5e, 0x0e, 0x2a, 0xb7, 0xd3, 0xc6, 0x4d, 0x61, 0xd2, 0x30,
-  0x3f, 0xc3, 0xa2, 0x9e, 0x16, 0x19, 0x92, 0x3c, 0xa8, 0x01, 0xe5, 0x9f,
-  0xd7, 0x52, 0xca, 0x6e, 0x76, 0x49, 0xd3, 0x03, 0xc9, 0xd2, 0x07, 0x88,
-  0xe1, 0x21, 0x46, 0x51, 0xb0, 0x69, 0x95, 0xeb, 0x26, 0x0c, 0x92, 0x9a,
-  0x13, 0x44, 0xa8, 0x49, 0xb2, 0x5c, 0xa0, 0xa0, 0x1f, 0x1e, 0xb5, 0x29,
-  0x13, 0x68, 0x6b, 0xba, 0x61, 0x9e, 0x23, 0x71, 0x44, 0x64, 0x03, 0x1a,
-  0x78, 0x43, 0x92, 0x87, 0xfc, 0xa7, 0x8f, 0x4c, 0x04, 0x76, 0x22, 0x3e,
-  0xea, 0x61, 0xb7, 0xf2, 0x5a, 0x7c, 0xe4, 0x2c, 0xca, 0x90, 0x1b, 0x2a,
-  0xea, 0x12, 0x98, 0x17, 0x89, 0x4b, 0xa3, 0x47, 0x08, 0x23, 0x85, 0x4f,
-  0x3e, 0x5b, 0x28, 0xd8, 0x6b, 0xa9, 0x79, 0xe5, 0x46, 0x71, 0x86, 0x2d,
-  0x90, 0x47, 0x0b, 0x1e, 0x78, 0x38, 0x97, 0x2a, 0x81, 0xa4, 0x81, 0x07,
-  0xd6, 0xac, 0x06, 0x11, 0x40, 0x6b, 0x21, 0xfb, 0xcc, 0xe1, 0xdb, 0x77,
-  0x02, 0xea, 0x9d, 0xd6, 0xba, 0x6e, 0x40, 0x52, 0x7b, 0x9d, 0xc6, 0x63,
-  0xf3, 0xc9, 0x3b, 0xad, 0x05, 0x6d, 0xc2, 0x85, 0x11, 0xf6, 0x6c, 0x3e,
-  0x0b, 0x92, 0x8d, 0xb8, 0x87, 0x9d, 0x22, 0xc5, 0x92, 0x68, 0x5c, 0xc7,
-  0x75, 0xa6, 0xcd, 0x57, 0x4a, 0xc3, 0xbc, 0xe3, 0xb2, 0x75, 0x91, 0xc8,
-  0x21, 0x92, 0x90, 0x76, 0x35, 0x8a, 0x22, 0x00, 0xb3, 0x77, 0x36, 0x5f,
-  0x7e, 0xfb, 0x9e, 0x40, 0xc3, 0xbf, 0x0f, 0xf0, 0x43, 0x29, 0x86, 0xae,
-  0x4b, 0xc1, 0xa2, 0x42, 0xce, 0x99, 0x21, 0xaa, 0x9e, 0x22, 0x44, 0x88,
-  0x19, 0x58, 0x5d, 0xea, 0x30, 0x8e, 0xb0, 0x39, 0x50, 0xc8, 0xdd, 0x15,
-  0x2a, 0x45, 0x31, 0xaa, 0xb5, 0x60, 0xd2, 0xfc, 0x7c, 0xa9, 0xa4, 0x0a,
-  0xd8, 0xaf, 0x25, 0xad, 0x1d, 0xd0, 0x8c, 0x6d, 0x79, 0xaf, 0xe4, 0xdd,
-  0x4d, 0x1e, 0xee, 0x5a, 0x86, 0x26, 0xed, 0x79, 0xd4, 0x51, 0x14, 0x08,
-  0x00, 0xe0, 0x3b, 0x59, 0xb9, 0x56, 0xf8, 0x21, 0x0e, 0x55, 0x60, 0x67,
-  0x40, 0x7d, 0x13, 0xdc, 0x90, 0xfa, 0x9e, 0x8b, 0x87, 0x2b, 0xfb, 0x8f
-};
 static const uint8_t ml_kem_768_pubkey[] = {
   0xa8, 0xe6, 0x51, 0xa1, 0xe6, 0x85, 0xf2, 0x24, 0x78, 0xa8, 0x95, 0x4f,
   0x00, 0x7b, 0xc7, 0x71, 0x1b, 0x93, 0x07, 0x72, 0xc7, 0x8f, 0x09, 0x2e,
@@ -2883,208 +2753,6 @@ static const uint8_t ml_kem_768_pubkey[] = {
   0x3f, 0xe8, 0xcb, 0x1d, 0xc4, 0xe8, 0x31, 0x5f, 0x2a, 0xf0, 0xd3, 0x2f,
   0x00, 0x17, 0xae, 0x13, 0x6e, 0x19, 0xf0, 0x28
 };
-static const uint8_t ml_kem_768_prvkey[] = {
-  0xda, 0x0a, 0xc7, 0xb6, 0x60, 0x40, 0x4e, 0x61, 0x3a, 0xa1, 0xf9, 0x80,
-  0x38, 0x0c, 0xb3, 0x6d, 0xba, 0x18, 0xd2, 0x32, 0x56, 0xc7, 0x26, 0x7a,
-  0x00, 0xa6, 0x7b, 0xa6, 0xc2, 0xa2, 0xb1, 0x4c, 0x41, 0x42, 0x39, 0x66,
-  0x2f, 0x68, 0xbd, 0x44, 0x6c, 0x8e, 0xfd, 0xf3, 0x66, 0x56, 0xa0, 0x89,
-  0x1a, 0x3c, 0xc6, 0x23, 0xfc, 0x68, 0xb6, 0x57, 0x2f, 0x7b, 0x29, 0xa6,
-  0xde, 0x12, 0x80, 0x14, 0x41, 0x1e, 0xe4, 0x19, 0x06, 0xd0, 0x80, 0x71,
-  0xf9, 0x48, 0x56, 0xe3, 0x6a, 0x83, 0x2b, 0x40, 0x33, 0x8d, 0x74, 0x35,
-  0x16, 0x65, 0x9b, 0xd2, 0x58, 0x79, 0xc0, 0x07, 0xa5, 0x2b, 0xc9, 0x58,
-  0x6f, 0x79, 0x87, 0x6a, 0xfa, 0xc6, 0xc9, 0xa3, 0x0d, 0x8f, 0xac, 0x24,
-  0x3b, 0xd2, 0x24, 0x25, 0xd6, 0xad, 0xce, 0x42, 0xab, 0x7e, 0xd3, 0x90,
-  0x14, 0x75, 0x7a, 0x95, 0x8b, 0xc8, 0xa7, 0x45, 0x65, 0xf0, 0x19, 0x23,
-  0x4f, 0xf0, 0x4b, 0x34, 0x89, 0x3e, 0xd6, 0xd0, 0x55, 0x01, 0xc3, 0x72,
-  0x55, 0x23, 0x9a, 0xae, 0x2a, 0xc1, 0x9f, 0x8c, 0x75, 0xac, 0x59, 0x00,
-  0xda, 0xe8, 0x30, 0x0d, 0xbb, 0xa7, 0x10, 0xdc, 0x2c, 0xaa, 0xe1, 0xbc,
-  0xa3, 0xa3, 0x8c, 0x58, 0x34, 0x2b, 0x28, 0x6b, 0x85, 0x18, 0xf1, 0x36,
-  0xad, 0x15, 0xb9, 0xf7, 0xbc, 0xbb, 0x06, 0xa5, 0x60, 0x7d, 0xb3, 0x75,
-  0xdb, 0xe9, 0x76, 0x45, 0x7c, 0x26, 0xc6, 0x59, 0x82, 0x57, 0x53, 0x1b,
-  0x2c, 0xfb, 0x6e, 0xe7, 0xf5, 0x15, 0x91, 0x84, 0x08, 0x04, 0xc3, 0x83,
-  0x88, 0x37, 0x6c, 0x27, 0x14, 0x84, 0x13, 0xda, 0x9e, 0x92, 0x92, 0x0b,
-  0xfd, 0x9a, 0x06, 0x9e, 0x01, 0x8b, 0xd2, 0x72, 0x05, 0x3d, 0xa8, 0x77,
-  0x5c, 0x0b, 0x73, 0x9f, 0x76, 0x1d, 0xb2, 0x10, 0x7c, 0xf3, 0x5a, 0x43,
-  0x4d, 0x69, 0xb0, 0x7e, 0x5b, 0xcd, 0xb8, 0x74, 0x34, 0x13, 0x8b, 0x0c,
-  0xb5, 0x56, 0x76, 0x1b, 0xa5, 0x22, 0xa5, 0x74, 0x7b, 0x28, 0x74, 0x7d,
-  0x80, 0xeb, 0x9d, 0x6c, 0xc6, 0x73, 0xbe, 0xe5, 0x76, 0x93, 0x77, 0xb9,
-  0x96, 0xd3, 0x6c, 0xeb, 0x0c, 0x0c, 0x7e, 0xd9, 0xa6, 0x58, 0x53, 0x33,
-  0x24, 0x86, 0x9c, 0x18, 0xa1, 0xa3, 0x6f, 0x31, 0x47, 0x0f, 0x14, 0xc5,
-  0xae, 0x49, 0xab, 0x07, 0x05, 0x07, 0xf8, 0x24, 0x9c, 0xe4, 0x04, 0xb4,
-  0x9c, 0x0a, 0x8c, 0x3e, 0xe4, 0x2f, 0xea, 0x96, 0x31, 0xfa, 0x1a, 0x0d,
-  0x10, 0xd8, 0x6b, 0x93, 0xf9, 0x86, 0xe0, 0xe3, 0xa8, 0x2e, 0x70, 0x3b,
-  0x74, 0xe5, 0xae, 0x61, 0x01, 0x24, 0x24, 0x21, 0xa8, 0x9a, 0xa0, 0x7f,
-  0xe6, 0x85, 0x88, 0x46, 0x0b, 0xaa, 0x36, 0x87, 0x86, 0x48, 0x6a, 0x72,
-  0xe4, 0xf2, 0x4d, 0x2d, 0xd7, 0x6c, 0xfc, 0x03, 0xb6, 0x94, 0xa5, 0xba,
-  0x91, 0xa7, 0x55, 0xa0, 0xb9, 0x8f, 0x3b, 0xf9, 0x33, 0x07, 0xc0, 0xab,
-  0x64, 0x63, 0x9a, 0xea, 0x7a, 0x64, 0x98, 0xa3, 0xc3, 0xdd, 0xc5, 0x71,
-  0x14, 0x1a, 0xbc, 0xa4, 0x67, 0x8c, 0xd2, 0xe2, 0xb8, 0x57, 0xfb, 0x88,
-  0xf6, 0x00, 0xca, 0xa5, 0x96, 0xb4, 0x4b, 0xc4, 0x22, 0x25, 0x0b, 0x28,
-  0x19, 0xe0, 0x51, 0x5f, 0x04, 0x72, 0x39, 0x18, 0x53, 0x70, 0x0b, 0x01,
-  0xef, 0xf9, 0x45, 0x3f, 0xd1, 0x18, 0x76, 0xb7, 0xc7, 0x59, 0xa0, 0x7d,
-  0xd8, 0x45, 0xca, 0xba, 0x45, 0x55, 0x26, 0x4a, 0x82, 0x76, 0x51, 0x93,
-  0xfd, 0xf8, 0x1b, 0x62, 0x0a, 0x1e, 0x1f, 0x92, 0x3f, 0xb2, 0x44, 0x42,
-  0xcd, 0x1c, 0xbe, 0x94, 0x17, 0x50, 0x03, 0xec, 0x06, 0xce, 0x77, 0xa3,
-  0xc6, 0x44, 0x93, 0xc1, 0x99, 0x98, 0x7a, 0x30, 0x0c, 0x95, 0xc5, 0x3c,
-  0x00, 0x89, 0xb5, 0xd6, 0x5c, 0x92, 0xea, 0x97, 0x1b, 0x2f, 0xfa, 0x93,
-  0xb5, 0x2a, 0x46, 0x1e, 0xa2, 0xac, 0x8c, 0x19, 0x9c, 0x2f, 0x4c, 0x2b,
-  0x70, 0x42, 0x97, 0xce, 0x3c, 0x39, 0x49, 0xe0, 0x73, 0x5e, 0xa8, 0xa1,
-  0x4a, 0xa5, 0x9e, 0x8d, 0xec, 0x0c, 0x87, 0x83, 0x99, 0xff, 0x70, 0x74,
-  0x7a, 0xb2, 0x44, 0xce, 0x46, 0xb5, 0xf2, 0x23, 0x04, 0x73, 0x32, 0x3d,
-  0x25, 0xc6, 0x6f, 0xe6, 0xb4, 0x19, 0xb1, 0xf4, 0xa1, 0x12, 0xe5, 0x21,
-  0x40, 0x35, 0x25, 0x6b, 0xc4, 0x3f, 0xfd, 0x2b, 0x6b, 0x7b, 0x37, 0x87,
-  0x69, 0xa6, 0xb4, 0x70, 0x00, 0xbf, 0xb6, 0x35, 0x7d, 0x45, 0x81, 0x4b,
-  0xae, 0xf3, 0x85, 0x7d, 0x37, 0x9e, 0x2f, 0xb8, 0xb5, 0xe5, 0x20, 0x1a,
-  0xb2, 0x62, 0x74, 0xbb, 0x1b, 0x70, 0xad, 0x32, 0x2c, 0xd0, 0x43, 0x9b,
-  0x2d, 0xb1, 0x09, 0xcf, 0xf0, 0xa2, 0xf8, 0xe6, 0x00, 0x99, 0x55, 0x71,
-  0xff, 0xc3, 0x8c, 0x59, 0x0b, 0xc4, 0xc7, 0x61, 0x5c, 0x69, 0xd0, 0xc9,
-  0x8e, 0xf4, 0x30, 0xf3, 0x08, 0x61, 0xa7, 0x72, 0x38, 0xff, 0xc0, 0x70,
-  0x61, 0xe4, 0x75, 0xd6, 0xa3, 0x0a, 0xd1, 0xb4, 0x7f, 0xd0, 0x39, 0xc3,
-  0xa4, 0x47, 0x76, 0x2d, 0xb2, 0x21, 0x1d, 0xc3, 0x1d, 0x0a, 0xca, 0xcf,
-  0xd5, 0x58, 0x90, 0xa5, 0x82, 0x47, 0x98, 0xf9, 0xae, 0xad, 0x74, 0x13,
-  0xdf, 0xe0, 0x28, 0xb1, 0x01, 0x2b, 0xe8, 0xb6, 0xca, 0x10, 0x26, 0x66,
-  0x6a, 0xc6, 0xbc, 0x94, 0x40, 0xa4, 0x49, 0xb5, 0x1a, 0xd8, 0xbb, 0xa7,
-  0xb0, 0x92, 0x1d, 0xd4, 0xd8, 0xb4, 0xa5, 0x78, 0x13, 0x6d, 0x1a, 0x05,
-  0xdb, 0x38, 0xcc, 0x85, 0x84, 0x37, 0xb2, 0x51, 0x61, 0xd1, 0xc3, 0xc2,
-  0x8e, 0xe0, 0x7b, 0xbc, 0xf2, 0xb2, 0x49, 0x11, 0x0d, 0x22, 0x78, 0x1d,
-  0xc3, 0x05, 0x0d, 0x8c, 0xc0, 0x09, 0x00, 0x96, 0xb3, 0x8a, 0x85, 0x06,
-  0x96, 0xf8, 0x6e, 0x9e, 0x6b, 0xab, 0x32, 0x52, 0x71, 0xb2, 0x24, 0x86,
-  0x75, 0x01, 0x19, 0x68, 0x50, 0x28, 0x81, 0x09, 0x04, 0x97, 0xfa, 0xc0,
-  0xaf, 0x84, 0x3c, 0x1a, 0xea, 0x76, 0xdd, 0x81, 0xcf, 0x29, 0xc0, 0x12,
-  0xc6, 0x62, 0x27, 0xb7, 0xf0, 0x6d, 0x99, 0x61, 0x30, 0x9b, 0x02, 0x62,
-  0xf7, 0x32, 0xc9, 0xa4, 0xd0, 0xbb, 0xd0, 0x67, 0x27, 0xab, 0xb8, 0x37,
-  0x1f, 0xf2, 0xc1, 0x18, 0x99, 0xa0, 0x98, 0x37, 0x5c, 0x46, 0x05, 0x16,
-  0xb2, 0xcc, 0x88, 0xbc, 0xf6, 0x28, 0xed, 0xe3, 0x7d, 0x8f, 0x3b, 0x33,
-  0x42, 0xe4, 0x49, 0x0a, 0x85, 0x60, 0x6e, 0xc0, 0x3d, 0xa2, 0x9b, 0x02,
-  0x56, 0x27, 0x53, 0x82, 0xa3, 0x31, 0x3d, 0xc0, 0x41, 0x11, 0x48, 0x01,
-  0x03, 0x2c, 0x51, 0x9f, 0x35, 0x0c, 0x3e, 0x6a, 0xba, 0xc3, 0xe3, 0x3b,
-  0x93, 0xb4, 0xa1, 0x9f, 0x7c, 0x54, 0x66, 0xe5, 0x8c, 0xb1, 0xdc, 0x14,
-  0xb4, 0xa9, 0x6c, 0x47, 0x57, 0x29, 0xf9, 0x71, 0xbd, 0xf1, 0x73, 0xcd,
-  0xf3, 0x54, 0x82, 0x4d, 0x01, 0x94, 0x27, 0xf9, 0x5b, 0x3b, 0x4a, 0x4a,
-  0x4a, 0x95, 0x8e, 0x47, 0x6a, 0x6e, 0x69, 0x91, 0xce, 0x6f, 0x06, 0xcb,
-  0x5d, 0xfc, 0xa7, 0xd4, 0x38, 0x0c, 0x3d, 0x92, 0x0b, 0x57, 0x11, 0xac,
-  0x1f, 0xcb, 0xaf, 0x4b, 0x9a, 0xc8, 0x00, 0xb9, 0x76, 0xd1, 0xec, 0x76,
-  0x6a, 0x62, 0x6c, 0xc1, 0x90, 0x0b, 0x66, 0xb3, 0xa9, 0xdc, 0x62, 0xc5,
-  0xc1, 0x44, 0x52, 0x7a, 0x29, 0x6b, 0xaf, 0x70, 0x43, 0x3b, 0xf6, 0x57,
-  0xc0, 0x43, 0x7f, 0x87, 0x59, 0x7b, 0xd7, 0xc8, 0xbb, 0xbe, 0x9a, 0xbc,
-  0x37, 0x05, 0x09, 0x31, 0xa4, 0xa8, 0x69, 0x82, 0xa2, 0x02, 0x8a, 0x74,
-  0x45, 0x4c, 0x9b, 0x81, 0x0c, 0x88, 0xd1, 0x70, 0x1c, 0x8c, 0xc9, 0x8a,
-  0x1d, 0x4c, 0xa1, 0x07, 0xa6, 0xb2, 0x5e, 0x96, 0x2f, 0xe4, 0xb6, 0xb0,
-  0x3c, 0x95, 0x45, 0x32, 0x60, 0xb8, 0x07, 0x22, 0x86, 0x37, 0xcc, 0x9e,
-  0xb1, 0x2a, 0xcc, 0x09, 0x54, 0x95, 0x9a, 0x52, 0xae, 0x54, 0xd1, 0x97,
-  0x73, 0x00, 0xab, 0xa0, 0xba, 0x2c, 0x14, 0x60, 0x9b, 0xb2, 0x8c, 0x11,
-  0xd5, 0xfa, 0xc5, 0xca, 0xc8, 0x82, 0x97, 0x60, 0x32, 0x83, 0xe8, 0x67,
-  0xa3, 0x64, 0x83, 0x66, 0xc7, 0x24, 0xd9, 0x35, 0x4c, 0xd7, 0xa1, 0x96,
-  0xdb, 0xd9, 0x80, 0x2f, 0x7b, 0x88, 0xd3, 0xfa, 0x00, 0x1f, 0x9c, 0x97,
-  0x73, 0x22, 0x54, 0x62, 0x23, 0x5e, 0x91, 0x35, 0x2a, 0x20, 0x79, 0x1f,
-  0xd8, 0xb8, 0x7f, 0xe3, 0x37, 0x7e, 0xc6, 0xa3, 0x94, 0x0b, 0x11, 0x30,
-  0xa0, 0xbb, 0x04, 0xe7, 0x41, 0x0a, 0x34, 0xe2, 0x58, 0x0d, 0x07, 0x1d,
-  0x6c, 0x56, 0x20, 0x20, 0x86, 0x78, 0x7a, 0x65, 0x90, 0xf8, 0x43, 0x93,
-  0xa8, 0xe6, 0x51, 0xa1, 0xe6, 0x85, 0xf2, 0x24, 0x78, 0xa8, 0x95, 0x4f,
-  0x00, 0x7b, 0xc7, 0x71, 0x1b, 0x93, 0x07, 0x72, 0xc7, 0x8f, 0x09, 0x2e,
-  0x82, 0x87, 0x8e, 0x3e, 0x93, 0x7f, 0x36, 0x79, 0x67, 0x53, 0x29, 0x13,
-  0xa8, 0xd5, 0x3d, 0xfd, 0xf4, 0xbf, 0xb1, 0xf8, 0x84, 0x67, 0x46, 0x59,
-  0x67, 0x05, 0xcf, 0x34, 0x51, 0x42, 0xb9, 0x72, 0xa3, 0xf1, 0x63, 0x25,
-  0xc4, 0x0c, 0x29, 0x52, 0xa3, 0x7b, 0x25, 0x89, 0x7e, 0x5e, 0xf3, 0x5f,
-  0xba, 0xeb, 0x73, 0xa4, 0xac, 0xbe, 0xb6, 0xa0, 0xb8, 0x99, 0x42, 0xce,
-  0xb1, 0x95, 0x53, 0x1c, 0xfc, 0x0a, 0x07, 0x99, 0x39, 0x54, 0x48, 0x3e,
-  0x6c, 0xbc, 0x87, 0xc0, 0x6a, 0xa7, 0x4f, 0xf0, 0xca, 0xc5, 0x20, 0x7e,
-  0x53, 0x5b, 0x26, 0x0a, 0xa9, 0x8d, 0x11, 0x98, 0xc0, 0x7d, 0xa6, 0x05,
-  0xc4, 0xd1, 0x10, 0x20, 0xf6, 0xc9, 0xf7, 0xbb, 0x68, 0xbb, 0x34, 0x56,
-  0xc7, 0x3a, 0x01, 0xb7, 0x10, 0xbc, 0x99, 0xd1, 0x77, 0x39, 0xa5, 0x17,
-  0x16, 0xaa, 0x01, 0x66, 0x0c, 0x8b, 0x62, 0x8b, 0x2f, 0x56, 0x02, 0xba,
-  0x65, 0xf0, 0x7e, 0xa9, 0x93, 0x33, 0x6e, 0x89, 0x6e, 0x83, 0xf2, 0xc5,
-  0x73, 0x1b, 0xbf, 0x03, 0x46, 0x0c, 0x5b, 0x6c, 0x8a, 0xfe, 0xcb, 0x74,
-  0x8e, 0xe3, 0x91, 0xe9, 0x89, 0x34, 0xa2, 0xc5, 0x7d, 0x4d, 0x06, 0x9f,
-  0x50, 0xd8, 0x8b, 0x30, 0xd6, 0x96, 0x6f, 0x38, 0xc3, 0x7b, 0xc6, 0x49,
-  0xb8, 0x26, 0x34, 0xce, 0x77, 0x22, 0x64, 0x5c, 0xcd, 0x62, 0x50, 0x63,
-  0x36, 0x46, 0x46, 0xd6, 0xd6, 0x99, 0xdb, 0x57, 0xb4, 0x5e, 0xb6, 0x74,
-  0x65, 0xe1, 0x6d, 0xe4, 0xd4, 0x06, 0xa8, 0x18, 0xb9, 0xea, 0xe1, 0xca,
-  0x91, 0x6a, 0x25, 0x94, 0x48, 0x97, 0x08, 0xa4, 0x3c, 0xea, 0x88, 0xb0,
-  0x2a, 0x4c, 0x03, 0xd0, 0x9b, 0x44, 0x81, 0x5c, 0x97, 0x10, 0x1c, 0xaf,
-  0x50, 0x48, 0xbb, 0xcb, 0x24, 0x7a, 0xe2, 0x36, 0x6c, 0xdc, 0x25, 0x4b,
-  0xa2, 0x21, 0x29, 0xf4, 0x5b, 0x3b, 0x0e, 0xb3, 0x99, 0xca, 0x91, 0xa3,
-  0x03, 0x40, 0x28, 0x30, 0xec, 0x01, 0xdb, 0x7b, 0x2c, 0xa4, 0x80, 0xcf,
-  0x35, 0x04, 0x09, 0xb2, 0x16, 0x09, 0x4b, 0x7b, 0x0c, 0x3a, 0xe3, 0x3c,
-  0xe1, 0x0a, 0x91, 0x24, 0xe8, 0x96, 0x51, 0xab, 0x90, 0x1e, 0xa2, 0x53,
-  0xc8, 0x41, 0x5b, 0xd7, 0x82, 0x5f, 0x02, 0xbb, 0x22, 0x93, 0x69, 0xaf,
-  0x97, 0x20, 0x28, 0xf2, 0x28, 0x75, 0xea, 0x55, 0xaf, 0x16, 0xd3, 0xbc,
-  0x69, 0xf7, 0x0c, 0x2e, 0xe8, 0xb7, 0x5f, 0x28, 0xb4, 0x7d, 0xd3, 0x91,
-  0xf9, 0x89, 0xad, 0xe3, 0x14, 0x72, 0x9c, 0x33, 0x1f, 0xa0, 0x4c, 0x19,
-  0x17, 0xb2, 0x78, 0xc3, 0xeb, 0x60, 0x28, 0x68, 0x51, 0x28, 0x21, 0xad,
-  0xc8, 0x25, 0xc6, 0x45, 0x77, 0xce, 0x1e, 0x63, 0xb1, 0xd9, 0x64, 0x4a,
-  0x61, 0x29, 0x48, 0xa3, 0x48, 0x3c, 0x7f, 0x1b, 0x9a, 0x25, 0x80, 0x00,
-  0xe3, 0x01, 0x96, 0x94, 0x4a, 0x40, 0x36, 0x27, 0x60, 0x9c, 0x76, 0xc7,
-  0xea, 0x6b, 0x5d, 0xe0, 0x17, 0x64, 0xd2, 0x43, 0x79, 0x11, 0x7b, 0x9e,
-  0xa2, 0x98, 0x48, 0xdc, 0x55, 0x5c, 0x45, 0x4b, 0xce, 0xae, 0x1b, 0xa5,
-  0xcc, 0x72, 0xc7, 0x4a, 0xb9, 0x6b, 0x9c, 0x91, 0xb9, 0x10, 0xd2, 0x6b,
-  0x88, 0xb2, 0x56, 0x39, 0xd4, 0x77, 0x8a, 0xe2, 0x6c, 0x7c, 0x61, 0x51,
-  0xa1, 0x9c, 0x6c, 0xd7, 0x93, 0x84, 0x54, 0x37, 0x24, 0x65, 0xe4, 0xc5,
-  0xec, 0x29, 0x24, 0x5a, 0xcb, 0x3d, 0xb5, 0x37, 0x9d, 0xe3, 0xda, 0xbf,
-  0xa6, 0x29, 0xa7, 0xc0, 0x4a, 0x83, 0x53, 0xa8, 0x53, 0x0c, 0x95, 0xac,
-  0xb7, 0x32, 0xbb, 0x4b, 0xb8, 0x19, 0x32, 0xbb, 0x2c, 0xa7, 0xa8, 0x48,
-  0xcd, 0x36, 0x68, 0x01, 0x44, 0x4a, 0xbe, 0x23, 0xc8, 0x3b, 0x36, 0x6a,
-  0x87, 0xd6, 0xa3, 0xcf, 0x36, 0x09, 0x24, 0xc0, 0x02, 0xba, 0xe9, 0x0a,
-  0xf6, 0x5c, 0x48, 0x06, 0x0b, 0x37, 0x52, 0xf2, 0xba, 0xdf, 0x1a, 0xb2,
-  0x72, 0x20, 0x72, 0x55, 0x4a, 0x50, 0x59, 0x75, 0x35, 0x94, 0xe6, 0xa7,
-  0x02, 0x76, 0x1f, 0xc9, 0x76, 0x84, 0xc8, 0xc4, 0xa7, 0x54, 0x0a, 0x6b,
-  0x07, 0xfb, 0xc9, 0xde, 0x87, 0xc9, 0x74, 0xaa, 0x88, 0x09, 0xd9, 0x28,
-  0xc7, 0xf4, 0xcb, 0xbf, 0x80, 0x45, 0xae, 0xa5, 0xbc, 0x66, 0x78, 0x25,
-  0xfd, 0x05, 0xa5, 0x21, 0xf1, 0xa4, 0xbf, 0x53, 0x92, 0x10, 0xc7, 0x11,
-  0x3b, 0xc3, 0x7b, 0x3e, 0x58, 0xb0, 0xcb, 0xfc, 0x53, 0xc8, 0x41, 0xcb,
-  0xb0, 0x37, 0x1d, 0xe2, 0xe5, 0x11, 0xb9, 0x89, 0xcb, 0x7c, 0x70, 0xc0,
-  0x23, 0x36, 0x6d, 0x78, 0xf9, 0xc3, 0x7e, 0xf0, 0x47, 0xf8, 0x72, 0x0b,
-  0xe1, 0xc7, 0x59, 0xa8, 0xd9, 0x6b, 0x93, 0xf6, 0x5a, 0x94, 0x11, 0x4f,
-  0xfa, 0xf6, 0x0d, 0x9a, 0x81, 0x79, 0x5e, 0x99, 0x5c, 0x71, 0x15, 0x2a,
-  0x46, 0x91, 0xa5, 0xa6, 0x02, 0xa9, 0xe1, 0xf3, 0x59, 0x9e, 0x37, 0xc7,
-  0x68, 0xc7, 0xbc, 0x10, 0x89, 0x94, 0xc0, 0x66, 0x9f, 0x3a, 0xdc, 0x95,
-  0x7d, 0x46, 0xb4, 0xb6, 0x25, 0x69, 0x68, 0xe2, 0x90, 0xd7, 0x89, 0x2e,
-  0xa8, 0x54, 0x64, 0xee, 0x7a, 0x75, 0x0f, 0x39, 0xc5, 0xe3, 0x15, 0x2c,
-  0x2d, 0xfc, 0x56, 0xd8, 0xb0, 0xc9, 0x24, 0xba, 0x8a, 0x95, 0x9a, 0x68,
-  0x09, 0x65, 0x47, 0xf6, 0x64, 0x23, 0xc8, 0x38, 0x98, 0x2a, 0x57, 0x94,
-  0xb9, 0xe1, 0x53, 0x37, 0x71, 0x33, 0x1a, 0x9a, 0x65, 0x6c, 0x28, 0x82,
-  0x8b, 0xeb, 0x91, 0x26, 0xa6, 0x0e, 0x95, 0xe8, 0xc5, 0xd9, 0x06, 0x83,
-  0x2c, 0x77, 0x10, 0x70, 0x55, 0x76, 0xb1, 0xfb, 0x95, 0x07, 0x26, 0x9d,
-  0xda, 0xf8, 0xc9, 0x5c, 0xe9, 0x71, 0x9b, 0x2c, 0xa8, 0xdd, 0x11, 0x2b,
-  0xe1, 0x0b, 0xcc, 0x9f, 0x4a, 0x37, 0xbd, 0x1b, 0x1e, 0xee, 0xb3, 0x3e,
-  0xcd, 0xa7, 0x6a, 0xe9, 0xf6, 0x9a, 0x5d, 0x4b, 0x29, 0x23, 0xa8, 0x69,
-  0x57, 0x67, 0x1d, 0x61, 0x93, 0x35, 0xbe, 0x1c, 0x4c, 0x2c, 0x77, 0xce,
-  0x87, 0xc4, 0x1f, 0x98, 0xa8, 0xcc, 0x46, 0x64, 0x60, 0xfa, 0x30, 0x0a,
-  0xaf, 0x5b, 0x30, 0x1f, 0x0a, 0x1d, 0x09, 0xc8, 0x8e, 0x65, 0xda, 0x4d,
-  0x8e, 0xe6, 0x4f, 0x68, 0xc0, 0x21, 0x89, 0xbb, 0xb3, 0x58, 0x4b, 0xaf,
-  0xf7, 0x16, 0xc8, 0x5d, 0xb6, 0x54, 0x04, 0x8a, 0x00, 0x43, 0x33, 0x48,
-  0x93, 0x93, 0xa0, 0x74, 0x27, 0xcd, 0x3e, 0x21, 0x7e, 0x6a, 0x34, 0x5f,
-  0x6c, 0x2c, 0x2b, 0x13, 0xc2, 0x7b, 0x33, 0x72, 0x71, 0xc0, 0xb2, 0x7b,
-  0x2d, 0xba, 0xa0, 0x0d, 0x23, 0x76, 0x00, 0xb5, 0xb5, 0x94, 0xe8, 0xcf,
-  0x2d, 0xd6, 0x25, 0xea, 0x76, 0xcf, 0x0e, 0xd8, 0x99, 0x12, 0x2c, 0x97,
-  0x96, 0xb4, 0xb0, 0x18, 0x70, 0x04, 0x25, 0x80, 0x49, 0xa4, 0x77, 0xcd,
-  0x11, 0xd6, 0x8c, 0x49, 0xb9, 0xa0, 0xe7, 0xb0, 0x0b, 0xce, 0x8c, 0xac,
-  0x78, 0x64, 0xcb, 0xb3, 0x75, 0x14, 0x00, 0x84, 0x74, 0x4c, 0x93, 0x06,
-  0x26, 0x94, 0xca, 0x79, 0x5c, 0x4f, 0x40, 0xe7, 0xac, 0xc9, 0xc5, 0xa1,
-  0x88, 0x40, 0x72, 0xd8, 0xc3, 0x8d, 0xaf, 0xb5, 0x01, 0xee, 0x41, 0x84,
-  0xdd, 0x5a, 0x81, 0x9e, 0xc2, 0x4e, 0xc1, 0x65, 0x12, 0x61, 0xf9, 0x62,
-  0xb1, 0x7a, 0x72, 0x15, 0xaa, 0x4a, 0x74, 0x8c, 0x15, 0x83, 0x6c, 0x38,
-  0x91, 0x37, 0x67, 0x82, 0x04, 0x83, 0x8d, 0x71, 0x95, 0xa8, 0x5b, 0x4f,
-  0x98, 0xa1, 0xb5, 0x74, 0xc4, 0xcd, 0x79, 0x09, 0xcd, 0x1f, 0x83, 0x3e,
-  0xff, 0xd1, 0x48, 0x55, 0x43, 0x22, 0x9d, 0x37, 0x48, 0xd9, 0xb5, 0xcd,
-  0x6c, 0x17, 0xb9, 0xb3, 0xb8, 0x4a, 0xef, 0x8b, 0xce, 0x13, 0xe6, 0x83,
-  0x73, 0x36, 0x59, 0xc7, 0x95, 0x42, 0xd6, 0x15, 0x78, 0x2a, 0x71, 0xcd,
-  0xee, 0xe7, 0x92, 0xba, 0xb5, 0x1b, 0xdc, 0x4b, 0xbf, 0xe8, 0x30, 0x8e,
-  0x66, 0x31, 0x44, 0xed, 0xe8, 0x49, 0x18, 0x30, 0xad, 0x98, 0xb4, 0x63,
-  0x4f, 0x64, 0xab, 0xa8, 0xb9, 0xc0, 0x42, 0x27, 0x26, 0x53, 0x92, 0x0f,
-  0x38, 0x0c, 0x1a, 0x17, 0xca, 0x87, 0xce, 0xd7, 0xaa, 0xc4, 0x1c, 0x82,
-  0x88, 0x87, 0x93, 0x18, 0x1a, 0x6f, 0x76, 0xe1, 0x97, 0xb7, 0xb9, 0x0e,
-  0xf9, 0x09, 0x43, 0xbb, 0x38, 0x44, 0x91, 0x29, 0x11, 0xd8, 0x55, 0x1e,
-  0x54, 0x66, 0xc5, 0x76, 0x7a, 0xb0, 0xbc, 0x61, 0xa1, 0xa3, 0xf7, 0x36,
-  0x16, 0x2e, 0xc0, 0x98, 0xa9, 0x00, 0xb1, 0x2d, 0xd8, 0xfa, 0xbb, 0xfb,
-  0x3f, 0xe8, 0xcb, 0x1d, 0xc4, 0xe8, 0x31, 0x5f, 0x2a, 0xf0, 0xd3, 0x2f,
-  0x00, 0x17, 0xae, 0x13, 0x6e, 0x19, 0xf0, 0x28, 0xf5, 0x72, 0x62, 0x66,
-  0x13, 0x58, 0xcd, 0xe8, 0xd3, 0xeb, 0xf9, 0x90, 0xe5, 0xfd, 0x1d, 0x5b,
-  0x89, 0x6c, 0x99, 0x2c, 0xcf, 0xaa, 0xdb, 0x52, 0x56, 0xb6, 0x8b, 0xbf,
-  0x59, 0x43, 0xb1, 0x32, 0x86, 0x26, 0xed, 0x79, 0xd4, 0x51, 0x14, 0x08,
-  0x00, 0xe0, 0x3b, 0x59, 0xb9, 0x56, 0xf8, 0x21, 0x0e, 0x55, 0x60, 0x67,
-  0x40, 0x7d, 0x13, 0xdc, 0x90, 0xfa, 0x9e, 0x8b, 0x87, 0x2b, 0xfb, 0x8f
-};
 static const uint8_t ml_kem_1024_pubkey[] = {
   0x53, 0x79, 0x11, 0x95, 0x7c, 0x12, 0x51, 0x48, 0xa8, 0x7f, 0x41, 0x58,
   0x9c, 0xb2, 0x22, 0xd0, 0xd1, 0x92, 0x29, 0xe2, 0xcb, 0x55, 0xe1, 0xa0,
@@ -3218,272 +2886,6 @@ static const uint8_t ml_kem_1024_pubkey[] = {
   0xba, 0xd1, 0x07, 0x38, 0xad, 0x04, 0xcc, 0x75, 0x2b, 0xc2, 0x0c, 0x39,
   0x47, 0x46, 0x85, 0x0e, 0x0c, 0x48, 0x47, 0xdb
 };
-static const uint8_t ml_kem_1024_prvkey[] = {
-  0x43, 0x3a, 0x70, 0xee, 0x69, 0x50, 0xf9, 0x88, 0x2a, 0xcd, 0xd5, 0xa4,
-  0x78, 0x20, 0xa6, 0xa8, 0x16, 0x37, 0x08, 0xf0, 0x4d, 0x45, 0x7c, 0x77,
-  0x99, 0x79, 0xb8, 0x3f, 0xe1, 0x17, 0x22, 0x47, 0x01, 0x49, 0x08, 0x30,
-  0x38, 0x66, 0x37, 0xda, 0x33, 0x2e, 0x74, 0xb1, 0xae, 0xda, 0x0b, 0x2f,
-  0x81, 0xca, 0x4f, 0x9b, 0xb2, 0xc2, 0xb0, 0x2b, 0x0c, 0xfd, 0x68, 0x0c,
-  0x11, 0x48, 0x2f, 0x33, 0x5a, 0xcf, 0x7b, 0x91, 0x39, 0xb5, 0xb8, 0x8a,
-  0x34, 0xe3, 0x54, 0x2c, 0x68, 0x61, 0x37, 0x75, 0x45, 0x98, 0x33, 0x43,
-  0xcd, 0x82, 0x94, 0x14, 0xe4, 0x78, 0x64, 0x21, 0x2e, 0x78, 0xf8, 0x55,
-  0xf5, 0x23, 0x90, 0x37, 0x9a, 0xcc, 0x3a, 0x62, 0x95, 0x31, 0x31, 0xb6,
-  0x3e, 0xe8, 0x32, 0xad, 0xb3, 0xbf, 0x4b, 0xf5, 0x8e, 0x24, 0x73, 0x49,
-  0xb5, 0xe0, 0x97, 0xe5, 0x5a, 0xbe, 0x49, 0x7b, 0x15, 0x98, 0x23, 0x73,
-  0xae, 0x73, 0x2e, 0x04, 0x39, 0xac, 0x67, 0xd0, 0x5c, 0x7f, 0x03, 0x7c,
-  0x8a, 0x73, 0x9b, 0x18, 0x14, 0x0e, 0x14, 0x4c, 0x85, 0x1d, 0xc9, 0x61,
-  0x1f, 0x4b, 0xcf, 0x04, 0xf3, 0xa2, 0x09, 0x3c, 0x19, 0x7b, 0xd6, 0x3b,
-  0xb5, 0xe6, 0x19, 0x01, 0x00, 0x54, 0x5f, 0xf8, 0x1d, 0xb7, 0xfc, 0xcd,
-  0xdd, 0x9a, 0x32, 0x4b, 0x0b, 0xac, 0x3c, 0x2c, 0x23, 0x82, 0x28, 0x40,
-  0x58, 0xf0, 0x8b, 0x96, 0x19, 0x52, 0xc0, 0x94, 0x01, 0x9c, 0x10, 0xbe,
-  0x37, 0xa5, 0x3d, 0x5a, 0xc7, 0x94, 0xc0, 0x10, 0xa9, 0xd0, 0x82, 0x1f,
-  0x15, 0x02, 0x7a, 0x1c, 0x41, 0x9c, 0x3c, 0x71, 0xc9, 0xa1, 0xd2, 0x8a,
-  0xed, 0x02, 0x59, 0x7a, 0xb7, 0x9b, 0x87, 0x53, 0x94, 0x62, 0x6b, 0xa3,
-  0x9a, 0xdc, 0x09, 0x0c, 0x3a, 0x90, 0xcf, 0x75, 0x87, 0x1a, 0x65, 0x27,
-  0x5e, 0xb1, 0xc5, 0xb0, 0x33, 0x72, 0xe1, 0x3a, 0x1a, 0x23, 0xd0, 0xcf,
-  0x93, 0x74, 0x11, 0x1f, 0x80, 0xcc, 0x83, 0xa9, 0x05, 0x62, 0x2b, 0x83,
-  0xfc, 0x51, 0x39, 0x71, 0xec, 0x84, 0x19, 0xf0, 0x88, 0x0c, 0x30, 0x67,
-  0x63, 0x36, 0x71, 0xb0, 0x9b, 0x54, 0x56, 0xab, 0x60, 0x57, 0x93, 0x6d,
-  0x19, 0xa4, 0xa2, 0xa2, 0x67, 0x91, 0x1b, 0x00, 0x0a, 0x13, 0x95, 0x6f,
-  0xbd, 0x49, 0x38, 0x21, 0xda, 0x07, 0x2c, 0x04, 0x64, 0x2b, 0x0c, 0x20,
-  0xda, 0x6c, 0xc0, 0xd9, 0xd8, 0x64, 0xa3, 0x93, 0x65, 0xdf, 0xd6, 0x4f,
-  0x10, 0x18, 0x78, 0x25, 0xfa, 0x33, 0x25, 0x07, 0x49, 0xcb, 0xc0, 0xc9,
-  0x05, 0xd7, 0xb1, 0xff, 0x3c, 0xae, 0x24, 0x12, 0xbf, 0x86, 0xb8, 0x1a,
-  0x81, 0x7b, 0x86, 0xba, 0xa3, 0x0e, 0xdf, 0x78, 0x62, 0xe5, 0xf6, 0xba,
-  0xc9, 0x87, 0x26, 0xe5, 0x6b, 0x3c, 0xec, 0x60, 0x66, 0x4c, 0xaa, 0x2a,
-  0x7d, 0xf6, 0x70, 0xc5, 0xe2, 0x07, 0xdf, 0xac, 0x03, 0x82, 0x4c, 0x89,
-  0x89, 0x7c, 0xb4, 0x90, 0xea, 0xa7, 0x65, 0x21, 0x22, 0x2c, 0x86, 0x20,
-  0x51, 0x69, 0xc9, 0x1c, 0x32, 0x9c, 0x4a, 0x18, 0x4d, 0x78, 0x72, 0x1a,
-  0xf8, 0x36, 0xad, 0x4d, 0xb0, 0xca, 0x78, 0x46, 0x4d, 0x41, 0x71, 0x47,
-  0x30, 0x12, 0xb7, 0xd1, 0x83, 0xba, 0xfa, 0x62, 0x75, 0x85, 0xc6, 0x4b,
-  0xe3, 0x80, 0x9d, 0x7e, 0x60, 0x04, 0xcb, 0xdc, 0x79, 0xa5, 0x46, 0x0f,
-  0x0a, 0xd6, 0x77, 0xcb, 0x71, 0x65, 0x12, 0x40, 0x7d, 0x3a, 0x61, 0x9a,
-  0xd0, 0x95, 0x43, 0xb7, 0x39, 0x54, 0x74, 0x72, 0xa7, 0x06, 0xb3, 0x17,
-  0xa5, 0x09, 0xbe, 0x5d, 0x86, 0x1f, 0xd6, 0x6c, 0x7d, 0x0e, 0xd9, 0x4c,
-  0xd5, 0x00, 0x47, 0x95, 0xc1, 0x81, 0x59, 0xe3, 0xa3, 0x3d, 0x79, 0x87,
-  0x11, 0x52, 0x5f, 0x16, 0x35, 0xa6, 0x84, 0x28, 0x17, 0x29, 0x23, 0x24,
-  0x96, 0x35, 0xaa, 0xd0, 0x32, 0xb9, 0xe5, 0x66, 0x64, 0xbd, 0xd4, 0x8e,
-  0xd2, 0x4a, 0xc7, 0x5c, 0x64, 0x68, 0xd1, 0x90, 0x3e, 0x47, 0x10, 0x86,
-  0xc5, 0xf1, 0x56, 0x7e, 0x83, 0x1a, 0x05, 0x08, 0xc5, 0x39, 0x63, 0x25,
-  0x91, 0xab, 0x57, 0x7d, 0x32, 0x4a, 0x82, 0x42, 0x97, 0x25, 0x80, 0x99,
-  0x50, 0x76, 0x1d, 0x84, 0x34, 0x28, 0x8c, 0x14, 0x03, 0x4f, 0x1c, 0x06,
-  0xc1, 0xd0, 0xaa, 0xe0, 0x9a, 0x71, 0xc7, 0x40, 0xa5, 0x57, 0x01, 0xc2,
-  0x8f, 0xf8, 0x44, 0x99, 0xf2, 0xbb, 0x18, 0xb6, 0x62, 0x8c, 0xaa, 0xa3,
-  0xfe, 0x75, 0xac, 0x4d, 0xe0, 0x4c, 0x6f, 0x91, 0x39, 0x00, 0xd8, 0x6c,
-  0x88, 0x12, 0x62, 0x52, 0xa1, 0x7c, 0x4d, 0x30, 0x39, 0x91, 0xdb, 0x02,
-  0x87, 0x12, 0x08, 0x81, 0xbb, 0x88, 0x47, 0x8a, 0xaa, 0x9a, 0xf9, 0xbc,
-  0x53, 0xd3, 0x72, 0x98, 0x43, 0x85, 0x8f, 0xdb, 0x46, 0x48, 0x05, 0x9c,
-  0xac, 0x82, 0xc1, 0xa1, 0x08, 0x78, 0xba, 0x39, 0x82, 0x3b, 0x04, 0x1b,
-  0xd0, 0xe2, 0x58, 0x48, 0x7b, 0x56, 0xcc, 0x8a, 0x32, 0x20, 0xc1, 0xa5,
-  0x8b, 0xf6, 0x6a, 0x17, 0x2b, 0x5b, 0x9a, 0x0c, 0x63, 0x2d, 0x67, 0x4e,
-  0xae, 0x88, 0x5a, 0x01, 0x5c, 0x4e, 0x37, 0xba, 0x07, 0x36, 0x80, 0xbe,
-  0xde, 0x75, 0x34, 0xf3, 0xe3, 0x4b, 0x60, 0x50, 0xc8, 0x6b, 0x21, 0xc3,
-  0xc0, 0x90, 0x94, 0x1f, 0x23, 0xb7, 0xf6, 0x73, 0x1e, 0x2b, 0xda, 0x0e,
-  0x6e, 0xa4, 0x64, 0x67, 0x71, 0xce, 0xc5, 0x72, 0xb9, 0x8c, 0xa0, 0xa1,
-  0x58, 0x91, 0x9a, 0xdb, 0xeb, 0x84, 0xce, 0x58, 0x5f, 0xf9, 0xf2, 0x5e,
-  0xbd, 0xda, 0x6c, 0xb6, 0xf0, 0x7a, 0x8f, 0x81, 0x12, 0x32, 0x60, 0x7e,
-  0x72, 0x17, 0xbb, 0x03, 0x9b, 0xab, 0xd0, 0xd9, 0x19, 0x34, 0xa8, 0x59,
-  0x40, 0x59, 0xc9, 0x68, 0x77, 0x23, 0xc0, 0x43, 0x81, 0xbf, 0xd6, 0x27,
-  0xa1, 0x05, 0x17, 0xf5, 0xf4, 0xbf, 0xc7, 0x77, 0x77, 0xaa, 0x26, 0x71,
-  0xae, 0x12, 0x4f, 0x2b, 0x7a, 0x5f, 0x4d, 0x56, 0x14, 0x02, 0x91, 0x97,
-  0xe6, 0x58, 0x6f, 0xa8, 0xc1, 0x7e, 0x0a, 0xd9, 0x07, 0x81, 0xbc, 0x7b,
-  0xb1, 0x9a, 0x77, 0x2d, 0x5a, 0x4e, 0xfe, 0x32, 0xca, 0xc8, 0x9b, 0x76,
-  0xc4, 0x2a, 0x5e, 0xde, 0x9b, 0xcc, 0x20, 0xc1, 0x89, 0x8c, 0x08, 0xa5,
-  0xb0, 0xc0, 0x7e, 0x47, 0x8b, 0x1b, 0xbc, 0x22, 0x6e, 0xfa, 0xd1, 0x5f,
-  0x2a, 0xc7, 0x37, 0x51, 0x4b, 0x8c, 0x61, 0x49, 0x81, 0x07, 0x79, 0x22,
-  0x24, 0x16, 0x53, 0x7e, 0xd0, 0x0d, 0xae, 0xab, 0x17, 0x7e, 0x90, 0x3e,
-  0xad, 0x6b, 0x4a, 0xc4, 0x23, 0x70, 0xaf, 0x1b, 0x1f, 0x50, 0xeb, 0xaf,
-  0xaa, 0x1c, 0x6e, 0x64, 0x7b, 0xba, 0xcc, 0xe7, 0x2c, 0x7d, 0x0b, 0x88,
-  0xae, 0xb0, 0xb0, 0x6f, 0xc1, 0xa4, 0x54, 0x57, 0xa9, 0xc1, 0x87, 0x57,
-  0x9b, 0xf1, 0x84, 0x57, 0x9c, 0xc3, 0x51, 0xc4, 0x3d, 0xff, 0x94, 0x26,
-  0x05, 0xaa, 0x56, 0x04, 0xfc, 0x85, 0xfc, 0x55, 0x83, 0xf6, 0xf1, 0x49,
-  0x6f, 0xe6, 0x1d, 0x70, 0xd6, 0xcd, 0xe2, 0x32, 0x7f, 0xee, 0x71, 0x3d,
-  0x86, 0xf2, 0x9b, 0x3a, 0xfc, 0xbb, 0x54, 0xe9, 0xa9, 0x2a, 0x33, 0xa6,
-  0xc1, 0xea, 0x6f, 0xfa, 0x30, 0x95, 0x66, 0xb0, 0x68, 0x62, 0x33, 0xc0,
-  0xf3, 0xb1, 0xc3, 0x14, 0x48, 0x90, 0xe4, 0xf0, 0x82, 0x9a, 0x60, 0x99,
-  0xc5, 0x74, 0x9c, 0xde, 0xc8, 0x43, 0x28, 0xec, 0x2c, 0xb6, 0x4a, 0x73,
-  0x85, 0xa7, 0x61, 0xd6, 0x4b, 0x3a, 0x23, 0xc4, 0x89, 0x34, 0x33, 0x43,
-  0xb9, 0x77, 0x23, 0xae, 0x78, 0xc7, 0xd8, 0x05, 0x45, 0x8e, 0x16, 0x20,
-  0xf0, 0x29, 0x28, 0x97, 0x69, 0x17, 0x04, 0xcb, 0x76, 0xe3, 0xb0, 0xb2,
-  0x81, 0xa8, 0x3c, 0xf6, 0x44, 0x90, 0x49, 0x8c, 0xbc, 0xaf, 0x04, 0x80,
-  0x24, 0x16, 0xb3, 0x3c, 0x56, 0x51, 0x71, 0xd7, 0x72, 0xd3, 0xb9, 0x35,
-  0x40, 0x37, 0x58, 0x76, 0x29, 0xae, 0x14, 0xa5, 0xc5, 0x03, 0x1a, 0xc3,
-  0x66, 0x71, 0xa0, 0xd0, 0xc9, 0x1c, 0xc0, 0xb4, 0xcd, 0x69, 0xd8, 0x40,
-  0x2e, 0x33, 0xb9, 0xbc, 0xc2, 0xbb, 0xaf, 0x6b, 0x97, 0x1e, 0x30, 0x3f,
-  0xa1, 0x37, 0xbe, 0x23, 0x25, 0x98, 0xa4, 0x99, 0x9b, 0xc0, 0x12, 0x57,
-  0x4c, 0x81, 0x65, 0x1b, 0x38, 0xb3, 0x83, 0x96, 0xc1, 0xc3, 0x65, 0x30,
-  0x3a, 0xd2, 0x5d, 0x49, 0xfc, 0x6b, 0x68, 0x99, 0x51, 0xa1, 0xcc, 0x4c,
-  0x60, 0x07, 0x61, 0x30, 0x65, 0x49, 0x5f, 0x97, 0x91, 0x0f, 0x97, 0x35,
-  0xd4, 0xea, 0x4e, 0x44, 0x2a, 0xcb, 0x2f, 0xab, 0xae, 0xcf, 0xe1, 0xad,
-  0xef, 0x06, 0x67, 0xba, 0x42, 0x2c, 0x95, 0x4a, 0x05, 0xd1, 0xb6, 0x16,
-  0x7a, 0x26, 0x3e, 0x12, 0x75, 0xc6, 0xad, 0xa8, 0x38, 0x59, 0x65, 0x30,
-  0x4b, 0x30, 0x32, 0x40, 0x40, 0x54, 0x2c, 0xf5, 0xa4, 0x51, 0xbc, 0xaf,
-  0xc7, 0x47, 0x88, 0xbe, 0x3b, 0x9b, 0x9f, 0xcc, 0x45, 0xd4, 0x79, 0x0e,
-  0x2d, 0x73, 0x35, 0xc6, 0x0a, 0x14, 0xf0, 0xa4, 0x9d, 0x13, 0x05, 0x3f,
-  0x26, 0x26, 0xa6, 0x27, 0xca, 0x19, 0x55, 0x3c, 0xb3, 0x36, 0xa2, 0xcb,
-  0x4a, 0x45, 0x5d, 0x8e, 0xf3, 0x98, 0x94, 0x91, 0x47, 0x2b, 0xa0, 0x05,
-  0x1e, 0xf7, 0x41, 0x6e, 0x0b, 0xbf, 0x1a, 0x61, 0x08, 0xfa, 0x07, 0xc1,
-  0x61, 0x54, 0x8e, 0x7c, 0x62, 0x33, 0x1a, 0xe5, 0xa2, 0xb4, 0xe4, 0xa1,
-  0x08, 0xa5, 0x10, 0x93, 0xd3, 0x15, 0x08, 0x21, 0xa2, 0xfb, 0x54, 0x71,
-  0x70, 0xa1, 0xb7, 0x3c, 0x43, 0xc5, 0x50, 0xc6, 0x55, 0x7a, 0x40, 0x48,
-  0xa5, 0x8a, 0x2c, 0xd7, 0x7a, 0x24, 0x42, 0x34, 0xb2, 0x23, 0x51, 0x75,
-  0xa0, 0x89, 0x7d, 0x50, 0x61, 0xb4, 0x61, 0x34, 0x82, 0xdc, 0x13, 0x64,
-  0x14, 0x04, 0x8c, 0x11, 0xdb, 0x37, 0xea, 0xe0, 0xa5, 0xdf, 0x87, 0xc1,
-  0x93, 0x14, 0xb0, 0xe8, 0x23, 0x97, 0xa0, 0xd3, 0x38, 0xdc, 0x21, 0x53,
-  0x8a, 0xf3, 0x61, 0x49, 0xd9, 0x3f, 0x8b, 0x1a, 0x11, 0xc5, 0x3b, 0xb5,
-  0xde, 0xf8, 0xb7, 0xa2, 0xcc, 0xa3, 0x36, 0x2b, 0x7f, 0xe3, 0xa1, 0x40,
-  0x8a, 0x25, 0x47, 0xe2, 0x09, 0x05, 0x8c, 0x67, 0x3a, 0x75, 0x66, 0xc2,
-  0x61, 0x23, 0xa6, 0xd8, 0xb6, 0x92, 0xa5, 0xf3, 0x3e, 0xbd, 0xcb, 0x26,
-  0x24, 0xb7, 0x9d, 0x87, 0x7b, 0xce, 0x5f, 0xa1, 0x4e, 0x42, 0xe8, 0x3f,
-  0xaa, 0xd8, 0x2e, 0x99, 0x00, 0x55, 0x3a, 0x3c, 0x60, 0x45, 0xca, 0x32,
-  0x9f, 0xea, 0x4a, 0x50, 0x65, 0x58, 0xc4, 0x91, 0xb6, 0xa6, 0x16, 0xc6,
-  0xfd, 0x40, 0x0b, 0x42, 0x13, 0x6f, 0x44, 0xcb, 0x0d, 0x02, 0x57, 0x65,
-  0x08, 0x19, 0x01, 0x8d, 0x3c, 0x56, 0x8e, 0xf6, 0xc6, 0x0c, 0x6c, 0x40,
-  0x9e, 0x70, 0xa8, 0x29, 0x28, 0x71, 0x08, 0xc1, 0xb6, 0xa4, 0xd3, 0x2f,
-  0x76, 0xe5, 0xcc, 0x4d, 0x10, 0x4b, 0x02, 0x43, 0x8e, 0xf7, 0xa4, 0x67,
-  0x91, 0x23, 0x98, 0xea, 0x9c, 0x7c, 0xbd, 0x99, 0x81, 0x58, 0x9a, 0x34,
-  0x18, 0x97, 0x68, 0x7b, 0x51, 0x6a, 0x13, 0x30, 0x7d, 0x66, 0xc0, 0x68,
-  0xc4, 0x44, 0xb4, 0xb9, 0x49, 0xa1, 0x74, 0x12, 0x41, 0x33, 0x15, 0xcc,
-  0xf4, 0x9b, 0x99, 0x98, 0x00, 0x34, 0xb5, 0xb8, 0xcf, 0xde, 0xc4, 0xa6,
-  0x0b, 0x9c, 0x1e, 0x74, 0x55, 0xaa, 0xfb, 0xf3, 0xa7, 0x57, 0x34, 0x69,
-  0x90, 0xcc, 0x32, 0xb0, 0x59, 0x9b, 0xa2, 0x17, 0xa6, 0xc5, 0xfc, 0x39,
-  0x53, 0x79, 0x11, 0x95, 0x7c, 0x12, 0x51, 0x48, 0xa8, 0x7f, 0x41, 0x58,
-  0x9c, 0xb2, 0x22, 0xd0, 0xd1, 0x92, 0x29, 0xe2, 0xcb, 0x55, 0xe1, 0xa0,
-  0x44, 0x79, 0x1e, 0x7c, 0xa6, 0x11, 0x92, 0xa4, 0x64, 0x60, 0xc3, 0x18,
-  0x3d, 0x2b, 0xcd, 0x6d, 0xe0, 0x8a, 0x5e, 0x76, 0x51, 0x60, 0x3a, 0xcc,
-  0x34, 0x9c, 0xa1, 0x6c, 0xba, 0x18, 0xab, 0xb2, 0x3a, 0x3e, 0x8c, 0x33,
-  0x0d, 0x74, 0x21, 0x59, 0x8a, 0x62, 0x78, 0xec, 0x7e, 0xbf, 0xab, 0xca,
-  0x0e, 0xf4, 0x88, 0xb2, 0x29, 0x05, 0x54, 0x75, 0x34, 0x99, 0xc0, 0x45,
-  0x2e, 0x45, 0x38, 0x15, 0x30, 0x99, 0x55, 0xb8, 0x15, 0x0f, 0xa1, 0xa1,
-  0xe3, 0x93, 0x38, 0x6d, 0xc1, 0x2f, 0xdb, 0x27, 0xb3, 0x8c, 0x67, 0x45,
-  0xf2, 0x94, 0x40, 0x16, 0xec, 0x45, 0x7f, 0x39, 0xb1, 0x8d, 0x60, 0x4a,
-  0x07, 0xa1, 0xab, 0xe0, 0x7b, 0xc8, 0x44, 0x05, 0x0f, 0xfa, 0x8a, 0x06,
-  0xfa, 0x15, 0x4a, 0x49, 0xd8, 0x8f, 0xac, 0x77, 0x54, 0x52, 0xd6, 0xa7,
-  0xc0, 0xe5, 0x89, 0xbf, 0xb5, 0xc3, 0x70, 0xc2, 0xc4, 0xb6, 0x20, 0x1d,
-  0xda, 0x80, 0xc9, 0xab, 0x20, 0x76, 0xec, 0xc0, 0x8b, 0x44, 0x52, 0x2f,
-  0xda, 0x33, 0x26, 0xf0, 0x33, 0x80, 0x6d, 0xd2, 0x69, 0x3f, 0x31, 0x97,
-  0x39, 0xf4, 0x0c, 0x4f, 0x42, 0xb2, 0x4a, 0xca, 0x70, 0x98, 0xfb, 0x8f,
-  0xf5, 0xf9, 0xac, 0x20, 0x29, 0x2d, 0x02, 0xb5, 0x6a, 0xc7, 0x46, 0x80,
-  0x1a, 0xcc, 0xcc, 0x84, 0x86, 0x3d, 0xee, 0x32, 0x87, 0x84, 0x97, 0xb6,
-  0x94, 0x38, 0xbf, 0x99, 0x17, 0x76, 0x28, 0x66, 0x50, 0x48, 0x2c, 0x8d,
-  0x9d, 0x95, 0x87, 0xbc, 0x6a, 0x55, 0xb8, 0x5c, 0x4d, 0x7f, 0xa7, 0x4d,
-  0x02, 0x65, 0x6b, 0x42, 0x1c, 0x9e, 0x23, 0xe0, 0x3a, 0x48, 0xd4, 0xb7,
-  0x44, 0x25, 0xc2, 0x6e, 0x4a, 0x20, 0xdd, 0x95, 0x62, 0xa4, 0xda, 0x07,
-  0x93, 0xf3, 0xa3, 0x52, 0xcc, 0xc0, 0xf1, 0x82, 0x17, 0xd8, 0x68, 0xc7,
-  0xf5, 0x00, 0x2a, 0xbe, 0x76, 0x8b, 0x1f, 0xc7, 0x3f, 0x05, 0x74, 0x4e,
-  0x7c, 0xc2, 0x8f, 0x10, 0x34, 0x40, 0x62, 0xc1, 0x0e, 0x08, 0xec, 0xcc,
-  0xed, 0x3c, 0x1f, 0x7d, 0x39, 0x2c, 0x01, 0xd9, 0x79, 0xdd, 0x71, 0x8d,
-  0x83, 0x98, 0x37, 0x46, 0x65, 0xa1, 0x6a, 0x98, 0x70, 0x58, 0x5c, 0x39,
-  0xd5, 0x58, 0x9a, 0x50, 0xe1, 0x33, 0x38, 0x9c, 0x9b, 0x9a, 0x27, 0x6c,
-  0x02, 0x42, 0x60, 0xd9, 0xfc, 0x77, 0x11, 0xc8, 0x1b, 0x63, 0x37, 0xb5,
-  0x7d, 0xa3, 0xc3, 0x76, 0xd0, 0xcd, 0x74, 0xe1, 0x4c, 0x73, 0x72, 0x7b,
-  0x27, 0x66, 0x56, 0xb9, 0xd8, 0xa4, 0xeb, 0x71, 0x89, 0x6f, 0xf5, 0x89,
-  0xd4, 0xb8, 0x93, 0xe7, 0x11, 0x0f, 0x3b, 0xb9, 0x48, 0xec, 0xe2, 0x91,
-  0xdd, 0x86, 0xc0, 0xb7, 0x46, 0x8a, 0x67, 0x8c, 0x74, 0x69, 0x80, 0xc1,
-  0x2a, 0xa6, 0xb9, 0x5e, 0x2b, 0x0c, 0xbe, 0x43, 0x31, 0xbb, 0x24, 0xa3,
-  0x3a, 0x27, 0x01, 0x53, 0xaa, 0x47, 0x2c, 0x47, 0x31, 0x23, 0x82, 0xca,
-  0x36, 0x5c, 0x5f, 0x35, 0x25, 0x9d, 0x02, 0x57, 0x46, 0xfc, 0x65, 0x95,
-  0xfe, 0x63, 0x6c, 0x76, 0x75, 0x10, 0xa6, 0x9c, 0x1e, 0x8a, 0x17, 0x6b,
-  0x79, 0x49, 0x95, 0x8f, 0x26, 0x97, 0x39, 0x94, 0x97, 0xa2, 0xfc, 0x73,
-  0x64, 0xa1, 0x2c, 0x81, 0x98, 0x29, 0x52, 0x39, 0xc8, 0x26, 0xcb, 0x50,
-  0x82, 0x08, 0x60, 0x77, 0x28, 0x2e, 0xd6, 0x28, 0x65, 0x1f, 0xc0, 0x4c,
-  0x63, 0x9b, 0x43, 0x85, 0x22, 0xa9, 0xde, 0x30, 0x9b, 0x14, 0xb0, 0x86,
-  0xd6, 0xe9, 0x23, 0xc5, 0x51, 0x62, 0x3b, 0xd7, 0x2a, 0x73, 0x3c, 0xb0,
-  0xda, 0xbc, 0x54, 0xa9, 0x41, 0x6a, 0x99, 0xe7, 0x2c, 0x9f, 0xda, 0x1c,
-  0xb3, 0xfb, 0x9b, 0xa0, 0x6b, 0x8a, 0xdb, 0x24, 0x22, 0xd6, 0x8c, 0xad,
-  0xc5, 0x53, 0xc9, 0x82, 0x02, 0xa1, 0x76, 0x56, 0x47, 0x8a, 0xc0, 0x44,
-  0xef, 0x34, 0x56, 0x37, 0x8a, 0xbc, 0xe9, 0x99, 0x1e, 0x01, 0x41, 0xba,
-  0x79, 0x09, 0x4f, 0xa8, 0xf7, 0x7a, 0x30, 0x08, 0x05, 0xd2, 0xd3, 0x2f,
-  0xfc, 0x62, 0xbf, 0x0c, 0xa4, 0x55, 0x4c, 0x33, 0x0c, 0x2b, 0xb7, 0x04,
-  0x2d, 0xb3, 0x51, 0x02, 0xf6, 0x8b, 0x1a, 0x00, 0x62, 0x58, 0x38, 0x65,
-  0x38, 0x1c, 0x74, 0xdd, 0x91, 0x3a, 0xf7, 0x0b, 0x26, 0xcf, 0x09, 0x23,
-  0xd0, 0xc4, 0xcb, 0x97, 0x16, 0x92, 0x22, 0x25, 0x52, 0xa8, 0xf4, 0xb7,
-  0x88, 0xb4, 0xaf, 0xd1, 0x34, 0x1a, 0x9d, 0xf4, 0x15, 0xcf, 0x20, 0x39,
-  0x00, 0xf5, 0xcc, 0xf7, 0xf6, 0x59, 0x88, 0x94, 0x9a, 0x75, 0x58, 0x0d,
-  0x04, 0x96, 0x39, 0x85, 0x31, 0x00, 0x85, 0x4b, 0x21, 0xf4, 0x01, 0x80,
-  0x03, 0x50, 0x2b, 0xb1, 0xba, 0x95, 0xf5, 0x56, 0xa5, 0xd6, 0x7c, 0x7e,
-  0xb5, 0x24, 0x10, 0xeb, 0xa2, 0x88, 0xa6, 0xd0, 0x63, 0x5c, 0xa8, 0xa4,
-  0xf6, 0xd6, 0x96, 0xd0, 0xa0, 0x20, 0xc8, 0x26, 0x93, 0x8d, 0x34, 0x94,
-  0x3c, 0x38, 0x08, 0xc7, 0x9c, 0xc0, 0x07, 0x76, 0x85, 0x33, 0x21, 0x6b,
-  0xc1, 0xb2, 0x9d, 0xa6, 0xc8, 0x12, 0xef, 0xf3, 0x34, 0x0b, 0xaa, 0x8d,
-  0x2e, 0x65, 0x34, 0x4f, 0x09, 0xbd, 0x47, 0x89, 0x4f, 0x5a, 0x3a, 0x41,
-  0x18, 0x71, 0x5b, 0x3c, 0x50, 0x20, 0x67, 0x93, 0x27, 0xf9, 0x18, 0x9f,
-  0x7e, 0x10, 0x85, 0x6b, 0x23, 0x8b, 0xb9, 0xb0, 0xab, 0x4c, 0xa8, 0x5a,
-  0xbf, 0x4b, 0x21, 0xf5, 0xc7, 0x6b, 0xcc, 0xd7, 0x18, 0x50, 0xb2, 0x2e,
-  0x04, 0x59, 0x28, 0x27, 0x6a, 0x0f, 0x2e, 0x95, 0x1d, 0xb0, 0x70, 0x7c,
-  0x6a, 0x11, 0x6d, 0xc1, 0x91, 0x13, 0xfa, 0x76, 0x2d, 0xc5, 0xf2, 0x0b,
-  0xd5, 0xd2, 0xab, 0x5b, 0xe7, 0x17, 0x44, 0xdc, 0x9c, 0xbd, 0xb5, 0x1e,
-  0xa7, 0x57, 0x96, 0x3a, 0xac, 0x56, 0xa9, 0x0a, 0x0d, 0x80, 0x23, 0xbe,
-  0xd1, 0xf5, 0xca, 0xe8, 0xa6, 0x4d, 0xa0, 0x47, 0x27, 0x9b, 0x35, 0x3a,
-  0x09, 0x6a, 0x83, 0x5b, 0x0b, 0x2b, 0x02, 0x3b, 0x6a, 0xa0, 0x48, 0x98,
-  0x92, 0x33, 0x07, 0x9a, 0xeb, 0x46, 0x7e, 0x52, 0x2f, 0xa2, 0x7a, 0x58,
-  0x22, 0x92, 0x1e, 0x5c, 0x55, 0x1b, 0x4f, 0x53, 0x75, 0x36, 0xe4, 0x6f,
-  0x3a, 0x6a, 0x97, 0xe7, 0x2c, 0x3b, 0x06, 0x31, 0x04, 0xe0, 0x9a, 0x04,
-  0x05, 0x98, 0x94, 0x0d, 0x87, 0x2f, 0x6d, 0x87, 0x1f, 0x5e, 0xf9, 0xb4,
-  0x35, 0x50, 0x73, 0xb5, 0x47, 0x69, 0xe4, 0x54, 0x54, 0xe6, 0xa0, 0x81,
-  0x95, 0x99, 0x40, 0x86, 0x21, 0xab, 0x44, 0x13, 0xb3, 0x55, 0x07, 0xb0,
-  0xdf, 0x57, 0x8c, 0xe2, 0xd5, 0x11, 0xd5, 0x20, 0x58, 0xd5, 0x74, 0x9d,
-  0xf3, 0x8b, 0x29, 0xd6, 0xcc, 0x58, 0x87, 0x0c, 0xaf, 0x92, 0xf6, 0x9a,
-  0x75, 0x16, 0x14, 0x06, 0xe7, 0x1c, 0x5f, 0xf9, 0x24, 0x51, 0xa7, 0x75,
-  0x22, 0xb8, 0xb2, 0x96, 0x7a, 0x2d, 0x58, 0xa4, 0x9a, 0x81, 0x66, 0x1a,
-  0xa6, 0x5a, 0xc0, 0x9b, 0x08, 0xc9, 0xfe, 0x45, 0xab, 0xc3, 0x85, 0x1f,
-  0x99, 0xc7, 0x30, 0xc4, 0x50, 0x03, 0xac, 0xa2, 0xbf, 0x0f, 0x84, 0x24,
-  0xa1, 0x9b, 0x74, 0x08, 0xa5, 0x37, 0xd5, 0x41, 0xc1, 0x6f, 0x56, 0x82,
-  0xbf, 0xe3, 0xa7, 0xfa, 0xea, 0x56, 0x4f, 0x12, 0x98, 0x61, 0x1a, 0x7f,
-  0x5f, 0x60, 0x92, 0x2b, 0xa1, 0x9d, 0xe7, 0x3b, 0x19, 0x17, 0xf1, 0x85,
-  0x32, 0x73, 0x55, 0x51, 0x99, 0xa6, 0x49, 0x31, 0x8b, 0x50, 0x77, 0x33,
-  0x45, 0xc9, 0x97, 0x46, 0x08, 0x56, 0x97, 0x2a, 0xcb, 0x43, 0xfc, 0x81,
-  0xab, 0x63, 0x21, 0xb1, 0xc3, 0x3c, 0x2b, 0xb5, 0x09, 0x8b, 0xd4, 0x89,
-  0xd6, 0x96, 0xa0, 0xf7, 0x06, 0x79, 0xc1, 0x21, 0x38, 0x73, 0xd0, 0x8b,
-  0xda, 0xd4, 0x28, 0x44, 0x92, 0x72, 0x16, 0x04, 0x72, 0x05, 0x63, 0x32,
-  0x12, 0x31, 0x0e, 0xe9, 0xa0, 0x6c, 0xb1, 0x00, 0x16, 0xc8, 0x05, 0x50,
-  0x3c, 0x34, 0x1a, 0x36, 0xd8, 0x7e, 0x56, 0x07, 0x2e, 0xab, 0xe2, 0x37,
-  0x31, 0xe3, 0x4a, 0xf7, 0xe2, 0x32, 0x8f, 0x85, 0xcd, 0xb3, 0x70, 0xcc,
-  0xaf, 0x00, 0x51, 0x5b, 0x64, 0xc9, 0xc5, 0x4b, 0xc8, 0x37, 0x57, 0x84,
-  0x47, 0xaa, 0xcf, 0xae, 0xd5, 0x96, 0x9a, 0xa3, 0x51, 0xe7, 0xda, 0x4e,
-  0xfa, 0x7b, 0x11, 0x5c, 0x4c, 0x51, 0xf4, 0xa6, 0x99, 0x77, 0x98, 0x50,
-  0x29, 0x5c, 0xa7, 0x2d, 0x78, 0x1a, 0xd4, 0x1b, 0xc6, 0x80, 0x53, 0x2b,
-  0x89, 0xe7, 0x10, 0xe2, 0x18, 0x9e, 0xb3, 0xc5, 0x08, 0x17, 0xba, 0x25,
-  0x5c, 0x74, 0x74, 0xc9, 0x5c, 0xa9, 0x11, 0x0c, 0xc4, 0x3b, 0x8b, 0xa8,
-  0xe6, 0x82, 0xc7, 0xfb, 0x7b, 0x0f, 0xdc, 0x26, 0x5c, 0x04, 0x83, 0xa6,
-  0x5c, 0xa4, 0x51, 0x4e, 0xe4, 0xb8, 0x32, 0xaa, 0xc5, 0x80, 0x0c, 0x3b,
-  0x08, 0xe7, 0x4f, 0x56, 0x39, 0x51, 0xc1, 0xfb, 0xb2, 0x10, 0x35, 0x3e,
-  0xfa, 0x1a, 0xa8, 0x66, 0x85, 0x6b, 0xc1, 0xe0, 0x34, 0x73, 0x3b, 0x04,
-  0x85, 0xda, 0xb1, 0xd0, 0x20, 0xc6, 0xbf, 0x76, 0x5f, 0xf6, 0x0b, 0x3b,
-  0x80, 0x19, 0x84, 0xa9, 0x0c, 0x2f, 0xe9, 0x70, 0xbf, 0x1d, 0xe9, 0x70,
-  0x04, 0xa6, 0xcf, 0x44, 0xb4, 0x98, 0x4a, 0xb5, 0x82, 0x58, 0xb4, 0xaf,
-  0x71, 0x22, 0x1c, 0xd1, 0x75, 0x30, 0xa7, 0x00, 0xc3, 0x29, 0x59, 0xc9,
-  0x43, 0x63, 0x44, 0xb5, 0x31, 0x6f, 0x09, 0xcc, 0xca, 0x70, 0x29, 0xa2,
-  0x30, 0xd6, 0x39, 0xdc, 0xb0, 0x22, 0xd8, 0xba, 0x79, 0xba, 0x91, 0xcd,
-  0x6a, 0xb1, 0x2a, 0xe1, 0x57, 0x9c, 0x50, 0xc7, 0xbb, 0x10, 0xe3, 0x03,
-  0x01, 0xa6, 0x5c, 0xae, 0x31, 0x01, 0xd4, 0x0c, 0x7b, 0xa9, 0x27, 0xbb,
-  0x55, 0x31, 0x48, 0xd1, 0x64, 0x70, 0x24, 0xd4, 0xa0, 0x6c, 0x81, 0x66,
-  0xd0, 0xb0, 0xb8, 0x12, 0x69, 0xb7, 0xd5, 0xf4, 0xb3, 0x4f, 0xb0, 0x22,
-  0xf6, 0x91, 0x52, 0xf5, 0x14, 0x00, 0x4a, 0x7c, 0x68, 0x53, 0x68, 0x55,
-  0x23, 0x43, 0xbb, 0x60, 0x36, 0x0f, 0xbb, 0x99, 0x45, 0xed, 0xf4, 0x46,
-  0xd3, 0x45, 0xbd, 0xca, 0xa7, 0x45, 0x5c, 0x74, 0xba, 0x0a, 0x55, 0x1e,
-  0x18, 0x46, 0x20, 0xfe, 0xf9, 0x76, 0x88, 0x77, 0x3d, 0x50, 0xb6, 0x43,
-  0x3c, 0xa7, 0xa7, 0xac, 0x5c, 0xb6, 0xb7, 0xf6, 0x71, 0xa1, 0x53, 0x76,
-  0xe5, 0xa6, 0x74, 0x7a, 0x62, 0x3f, 0xa7, 0xbc, 0x66, 0x30, 0x37, 0x3f,
-  0x5b, 0x1b, 0x51, 0x26, 0x90, 0xa6, 0x61, 0x37, 0x78, 0x70, 0xa6, 0x0a,
-  0x7a, 0x18, 0x96, 0x83, 0xf9, 0xb0, 0xcf, 0x04, 0x66, 0xe1, 0xf7, 0x50,
-  0x76, 0x26, 0x31, 0xc4, 0xab, 0x09, 0xf5, 0x05, 0xc4, 0x2d, 0xd2, 0x86,
-  0x33, 0x56, 0x94, 0x72, 0x73, 0x54, 0x42, 0x85, 0x1e, 0x32, 0x16, 0x16,
-  0xd4, 0x00, 0x98, 0x10, 0x77, 0x7b, 0x6b, 0xd4, 0x6f, 0xa7, 0x22, 0x44,
-  0x61, 0xa5, 0xcc, 0x27, 0x40, 0x5d, 0xfb, 0xac, 0x0d, 0x39, 0xb0, 0x02,
-  0xca, 0xb3, 0x34, 0x33, 0xf2, 0xa8, 0x6e, 0xb8, 0xce, 0x91, 0xc1, 0x34,
-  0xa6, 0x38, 0x6f, 0x86, 0x0a, 0x19, 0x94, 0xeb, 0x4b, 0x68, 0x75, 0xa4,
-  0x6d, 0x19, 0x55, 0x81, 0xd1, 0x73, 0x85, 0x4b, 0x53, 0xd2, 0x29, 0x3d,
-  0xf3, 0xe9, 0xa8, 0x22, 0x75, 0x6c, 0xd8, 0xf2, 0x12, 0xb3, 0x25, 0xca,
-  0x29, 0xb4, 0xf9, 0xf8, 0xcf, 0xba, 0xdf, 0x2e, 0x41, 0x86, 0x9a, 0xbf,
-  0xba, 0xd1, 0x07, 0x38, 0xad, 0x04, 0xcc, 0x75, 0x2b, 0xc2, 0x0c, 0x39,
-  0x47, 0x46, 0x85, 0x0e, 0x0c, 0x48, 0x47, 0xdb, 0xeb, 0xbe, 0x41, 0xcd,
-  0x4d, 0xea, 0x48, 0x9d, 0xed, 0xd0, 0x0e, 0x76, 0xae, 0x0b, 0xcf, 0x54,
-  0xaa, 0x85, 0x50, 0x20, 0x29, 0x20, 0xeb, 0x64, 0xd5, 0x89, 0x2a, 0xd0,
-  0x2b, 0x13, 0xf2, 0xe5, 0x86, 0x26, 0xed, 0x79, 0xd4, 0x51, 0x14, 0x08,
-  0x00, 0xe0, 0x3b, 0x59, 0xb9, 0x56, 0xf8, 0x21, 0x0e, 0x55, 0x60, 0x67,
-  0x40, 0x7d, 0x13, 0xdc, 0x90, 0xfa, 0x9e, 0x8b, 0x87, 0x2b, 0xfb, 0x8f
-};
 #endif
 
 static struct keys_st {
@@ -3544,14 +2946,14 @@ static struct keys_st {
 #endif
 #ifndef OPENSSL_NO_ML_KEM
     {
-        NID_undef, ml_kem_512_prvkey, ml_kem_512_pubkey,
-        "ML-KEM-512", sizeof(ml_kem_512_prvkey), sizeof(ml_kem_512_pubkey)
+        NID_undef, ml_kem_prvkey, ml_kem_512_pubkey,
+        "ML-KEM-512", ML_KEM_SEED_BYTES, sizeof(ml_kem_512_pubkey)
     }, {
-        NID_undef, ml_kem_768_prvkey, ml_kem_768_pubkey,
-        "ML-KEM-768", sizeof(ml_kem_768_prvkey), sizeof(ml_kem_768_pubkey)
+        NID_undef, ml_kem_prvkey, ml_kem_768_pubkey,
+        "ML-KEM-768", ML_KEM_SEED_BYTES, sizeof(ml_kem_768_pubkey)
     }, {
-        NID_undef, ml_kem_1024_prvkey, ml_kem_1024_pubkey,
-        "ML-KEM-1024", sizeof(ml_kem_1024_prvkey), sizeof(ml_kem_1024_pubkey)
+        NID_undef, ml_kem_prvkey, ml_kem_1024_pubkey,
+        "ML-KEM-1024", ML_KEM_SEED_BYTES, sizeof(ml_kem_1024_pubkey)
     },
 #endif
 };
index 56ae79cd7198a298fed0206c8f7f19a72a026a3b..05040884066be851169116fbd0e328792f75309b 100644 (file)
@@ -4379,17 +4379,14 @@ static int keygen_test_run(EVP_TEST *t)
         private_keys = key;
         rv = 1;
     } else if (keygen->seed != NULL) {
+        const char *prvparam = OSSL_PKEY_PARAM_ENCODED_PRIVATE_KEY;
         rv = 0;
-        if (!TEST_int_eq(EVP_PKEY_get_octet_string_param(pkey,
-                                                         OSSL_PKEY_PARAM_PRIV_KEY,
-                                                         NULL, 0, &priv_len), 1)
+        if (!TEST_int_eq(EVP_PKEY_get_octet_string_param(pkey, prvparam, NULL,
+                                                         0, &priv_len), 1)
             || !TEST_ptr(enc_priv_key = OPENSSL_zalloc(priv_len))
-            || !TEST_int_eq(EVP_PKEY_get_octet_string_param(pkey,
-                                                            OSSL_PKEY_PARAM_PRIV_KEY,
+            || !TEST_int_eq(EVP_PKEY_get_octet_string_param(pkey, prvparam,
                                                             enc_priv_key,
-                                                            priv_len,
-                                                            NULL),
-                            1))
+                                                            priv_len, NULL), 1))
             goto err;
 
         if (!TEST_size_t_gt((pub_len = EVP_PKEY_get1_encoded_public_key(pkey,
index 1ffeb6fc2092509bdfe6074957e9b6dfa4ce21ae..f55e1cf48e1e312f2e8df573581b5b9c89e84f1a 100644 (file)
@@ -217,7 +217,7 @@ static int test_ml_kem(void)
 
 static int test_non_derandomised_ml_kem(void)
 {
-    static const char *alg[3] = { "ML-KEM-512", "ML-KEM-768", "ML-KEM-1024" };
+    static const int alg[3] = { NID_ML_KEM_512, NID_ML_KEM_768, NID_ML_KEM_1024 };
     EVP_RAND_CTX *privctx;
     EVP_RAND_CTX *pubctx;
     EVP_MD *sha256;
@@ -230,7 +230,7 @@ static int test_non_derandomised_ml_kem(void)
     if (!TEST_ptr(sha256 = EVP_MD_fetch(NULL, "sha256", NULL)))
         return 0;
 
-    for (i = ML_KEM_512_VARIANT; i < ML_KEM_1024_VARIANT; ++i) {
+    for (i = 0; i < (int) OSSL_NELEM(alg); ++i) {
         const ML_KEM_VINFO *v;
         OSSL_PARAM params[3], *p;
         uint8_t hash[32];
@@ -244,6 +244,9 @@ static int test_non_derandomised_ml_kem(void)
         unsigned char c;
         int res = -1;
 
+        if ((v = ossl_ml_kem_get_vinfo(alg[i])) == NULL)
+            goto done;
+
         /* Configure the private RNG to output just the keygen seed */
         p = params;
         *p++ = OSSL_PARAM_construct_octet_string(OSSL_RAND_PARAM_TEST_ENTROPY,
@@ -255,13 +258,10 @@ static int test_non_derandomised_ml_kem(void)
 
         res = -2;
         /* Generate Alice's key */
-        akey = EVP_PKEY_Q_keygen(testctx, NULL, alg[i]);
+        akey = EVP_PKEY_Q_keygen(testctx, NULL, v->algorithm_name);
         if (!TEST_ptr(akey))
             goto done;
 
-        if ((v = ossl_ml_kem_get_vinfo(i)) == NULL)
-            goto done;
-
         /* Check that no more entropy is available! */
         if (!TEST_int_le(RAND_priv_bytes(&c, 1), 0))
             goto done;
index 54440313527d805a318bd0d008b8032324a45899..0f847a12d40fdd538740dde1fd4a722ba74d07c6 100644 (file)
@@ -92,6 +92,7 @@ static uint8_t ml_kem_expected_shared_secret[3][32] = {
 
 static int sanity_test(void)
 {
+    static const int alg[3] = { NID_ML_KEM_512, NID_ML_KEM_768, NID_ML_KEM_1024 };
     EVP_RAND_CTX *privctx;
     EVP_RAND_CTX *pubctx;
     EVP_MD *sha256 = EVP_MD_fetch(NULL, "sha256", NULL);
@@ -107,7 +108,7 @@ static int sanity_test(void)
 
     decap_entropy = ml_kem_public_entropy + ML_KEM_RANDOM_BYTES;
 
-    for (i = ML_KEM_512_VARIANT; i < ML_KEM_1024_VARIANT; ++i) {
+    for (i = 0; i < (int) OSSL_NELEM(alg); ++i) {
         OSSL_PARAM params[3];
         uint8_t hash[32];
         uint8_t shared_secret[ML_KEM_SHARED_SECRET_BYTES];
@@ -132,8 +133,8 @@ static int sanity_test(void)
         if (!TEST_true(EVP_RAND_CTX_set_params(privctx, params)))
             return 0;
 
-        public_key = ossl_ml_kem_key_new(NULL, NULL, i);
-        private_key = ossl_ml_kem_key_new(NULL, NULL, i);
+        public_key = ossl_ml_kem_key_new(NULL, NULL, alg[i]);
+        private_key = ossl_ml_kem_key_new(NULL, NULL, alg[i]);
         if (private_key == NULL || public_key == NULL
             || (v = ossl_ml_kem_key_vinfo(public_key)) == NULL)
             goto done;
index 92813dea03842c1a1d895e1f127aeef8ec54a599..3918d80d770cd9bcb85c343a8baee853b69e8248 100644 (file)
@@ -299,6 +299,7 @@ my %params = (
     'PKEY_PARAM_MGF1_DIGEST' =>         "mgf1-digest",
     'PKEY_PARAM_MGF1_PROPERTIES' =>     "mgf1-properties",
     'PKEY_PARAM_ENCODED_PUBLIC_KEY' =>  "encoded-pub-key",
+    'PKEY_PARAM_ENCODED_PRIVATE_KEY' => "encoded-priv-key",
     'PKEY_PARAM_GROUP_NAME' =>          "group",
     'PKEY_PARAM_DIST_ID' =>             "distid",
     'PKEY_PARAM_PUB_KEY' =>             "pub",