Commit 8a82e3a754 for openssl.org
commit 8a82e3a7548e6a7091fbb746dae2094590c4dd5a
Author: Viktor Dukhovni <openssl-users@dukhovni.org>
Date: Tue Mar 3 19:24:23 2026 +1100
Deuglify ML-KEM code after reformat
Fix up format of NTT tables, which format nicely when the values
are converted to 12-bit hex.
Also slightly clean up the code for better readability.
Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com>
Reviewed-by: Paul Dale <paul.dale@oracle.com>
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
MergeDate: Wed Mar 4 17:46:54 2026
(Merged from https://github.com/openssl/openssl/pull/30245)
diff --git a/crypto/ml_kem/ml_kem.c b/crypto/ml_kem/ml_kem.c
index 53952a9116..852d9fe71c 100644
--- a/crypto/ml_kem/ml_kem.c
+++ b/crypto/ml_kem/ml_kem.c
@@ -259,134 +259,22 @@ static const uint16_t kInverseDegree = INVERSE_DEGREE;
* kNTTRoots = [pow(17, bitreverse(i), p) for i in range(128)]
*/
static const uint16_t kNTTRoots[128] = {
- 1,
- 1729,
- 2580,
- 3289,
- 2642,
- 630,
- 1897,
- 848,
- 1062,
- 1919,
- 193,
- 797,
- 2786,
- 3260,
- 569,
- 1746,
- 296,
- 2447,
- 1339,
- 1476,
- 3046,
- 56,
- 2240,
- 1333,
- 1426,
- 2094,
- 535,
- 2882,
- 2393,
- 2879,
- 1974,
- 821,
- 289,
- 331,
- 3253,
- 1756,
- 1197,
- 2304,
- 2277,
- 2055,
- 650,
- 1977,
- 2513,
- 632,
- 2865,
- 33,
- 1320,
- 1915,
- 2319,
- 1435,
- 807,
- 452,
- 1438,
- 2868,
- 1534,
- 2402,
- 2647,
- 2617,
- 1481,
- 648,
- 2474,
- 3110,
- 1227,
- 910,
- 17,
- 2761,
- 583,
- 2649,
- 1637,
- 723,
- 2288,
- 1100,
- 1409,
- 2662,
- 3281,
- 233,
- 756,
- 2156,
- 3015,
- 3050,
- 1703,
- 1651,
- 2789,
- 1789,
- 1847,
- 952,
- 1461,
- 2687,
- 939,
- 2308,
- 2437,
- 2388,
- 733,
- 2337,
- 268,
- 641,
- 1584,
- 2298,
- 2037,
- 3220,
- 375,
- 2549,
- 2090,
- 1645,
- 1063,
- 319,
- 2773,
- 757,
- 2099,
- 561,
- 2466,
- 2594,
- 2804,
- 1092,
- 403,
- 1026,
- 1143,
- 2150,
- 2775,
- 886,
- 1722,
- 1212,
- 1874,
- 1029,
- 2110,
- 2935,
- 885,
- 2154,
+ 0x001, 0x6c1, 0xa14, 0xcd9, 0xa52, 0x276, 0x769, 0x350,
+ 0x426, 0x77f, 0x0c1, 0x31d, 0xae2, 0xcbc, 0x239, 0x6d2,
+ 0x128, 0x98f, 0x53b, 0x5c4, 0xbe6, 0x038, 0x8c0, 0x535,
+ 0x592, 0x82e, 0x217, 0xb42, 0x959, 0xb3f, 0x7b6, 0x335,
+ 0x121, 0x14b, 0xcb5, 0x6dc, 0x4ad, 0x900, 0x8e5, 0x807,
+ 0x28a, 0x7b9, 0x9d1, 0x278, 0xb31, 0x021, 0x528, 0x77b,
+ 0x90f, 0x59b, 0x327, 0x1c4, 0x59e, 0xb34, 0x5fe, 0x962,
+ 0xa57, 0xa39, 0x5c9, 0x288, 0x9aa, 0xc26, 0x4cb, 0x38e,
+ 0x011, 0xac9, 0x247, 0xa59, 0x665, 0x2d3, 0x8f0, 0x44c,
+ 0x581, 0xa66, 0xcd1, 0x0e9, 0x2f4, 0x86c, 0xbc7, 0xbea,
+ 0x6a7, 0x673, 0xae5, 0x6fd, 0x737, 0x3b8, 0x5b5, 0xa7f,
+ 0x3ab, 0x904, 0x985, 0x954, 0x2dd, 0x921, 0x10c, 0x281,
+ 0x630, 0x8fa, 0x7f5, 0xc94, 0x177, 0x9f5, 0x82a, 0x66d,
+ 0x427, 0x13f, 0xad5, 0x2f5, 0x833, 0x231, 0x9a2, 0xa22,
+ 0xaf4, 0x444, 0x193, 0x402, 0x477, 0x866, 0xad7, 0x376,
+ 0x6ba, 0x4bc, 0x752, 0x405, 0x83e, 0xb77, 0x375, 0x86a
};
/*
@@ -396,134 +284,22 @@ static const uint16_t kNTTRoots[128] = {
* 0, 64, 65, ..., 127, 32, 33, ..., 63, 16, 17, ..., 31, 8, 9, ...
*/
static const uint16_t kInverseNTTRoots[128] = {
- 1,
- 1175,
- 2444,
- 394,
- 1219,
- 2300,
- 1455,
- 2117,
- 1607,
- 2443,
- 554,
- 1179,
- 2186,
- 2303,
- 2926,
- 2237,
- 525,
- 735,
- 863,
- 2768,
- 1230,
- 2572,
- 556,
- 3010,
- 2266,
- 1684,
- 1239,
- 780,
- 2954,
- 109,
- 1292,
- 1031,
- 1745,
- 2688,
- 3061,
- 992,
- 2596,
- 941,
- 892,
- 1021,
- 2390,
- 642,
- 1868,
- 2377,
- 1482,
- 1540,
- 540,
- 1678,
- 1626,
- 279,
- 314,
- 1173,
- 2573,
- 3096,
- 48,
- 667,
- 1920,
- 2229,
- 1041,
- 2606,
- 1692,
- 680,
- 2746,
- 568,
- 3312,
- 2419,
- 2102,
- 219,
- 855,
- 2681,
- 1848,
- 712,
- 682,
- 927,
- 1795,
- 461,
- 1891,
- 2877,
- 2522,
- 1894,
- 1010,
- 1414,
- 2009,
- 3296,
- 464,
- 2697,
- 816,
- 1352,
- 2679,
- 1274,
- 1052,
- 1025,
- 2132,
- 1573,
- 76,
- 2998,
- 3040,
- 2508,
- 1355,
- 450,
- 936,
- 447,
- 2794,
- 1235,
- 1903,
- 1996,
- 1089,
- 3273,
- 283,
- 1853,
- 1990,
- 882,
- 3033,
- 1583,
- 2760,
- 69,
- 543,
- 2532,
- 3136,
- 1410,
- 2267,
- 2481,
- 1432,
- 2699,
- 687,
- 40,
- 749,
- 1600,
+ 0x001, 0x497, 0x98c, 0x18a, 0x4c3, 0x8fc, 0x5af, 0x845,
+ 0x647, 0x98b, 0x22a, 0x49b, 0x88a, 0x8ff, 0xb6e, 0x8bd,
+ 0x20d, 0x2df, 0x35f, 0xad0, 0x4ce, 0xa0c, 0x22c, 0xbc2,
+ 0x8da, 0x694, 0x4d7, 0x30c, 0xb8a, 0x06d, 0x50c, 0x407,
+ 0x6d1, 0xa80, 0xbf5, 0x3e0, 0xa24, 0x3ad, 0x37c, 0x3fd,
+ 0x956, 0x282, 0x74c, 0x949, 0x5ca, 0x604, 0x21c, 0x68e,
+ 0x65a, 0x117, 0x13a, 0x495, 0xa0d, 0xc18, 0x030, 0x29b,
+ 0x780, 0x8b5, 0x411, 0xa2e, 0x69c, 0x2a8, 0xaba, 0x238,
+ 0xcf0, 0x973, 0x836, 0x0db, 0x357, 0xa79, 0x738, 0x2c8,
+ 0x2aa, 0x39f, 0x703, 0x1cd, 0x763, 0xb3d, 0x9da, 0x766,
+ 0x3f2, 0x586, 0x7d9, 0xce0, 0x1d0, 0xa89, 0x330, 0x548,
+ 0xa77, 0x4fa, 0x41c, 0x401, 0x854, 0x625, 0x04c, 0xbb6,
+ 0xbe0, 0x9cc, 0x54b, 0x1c2, 0x3a8, 0x1bf, 0xaea, 0x4d3,
+ 0x76f, 0x7cc, 0x441, 0xcc9, 0x11b, 0x73d, 0x7c6, 0x372,
+ 0xbd9, 0x62f, 0xac8, 0x045, 0x21f, 0x9e4, 0xc40, 0x582,
+ 0x8db, 0x9b1, 0x598, 0xa8b, 0x2af, 0x028, 0x2ed, 0x640
};
/*
@@ -532,134 +308,22 @@ static const uint16_t kInverseNTTRoots[128] = {
* ModRoots = [pow(17, 2*bitreverse(i) + 1, p) for i in range(128)]
*/
static const uint16_t kModRoots[128] = {
- 17,
- 3312,
- 2761,
- 568,
- 583,
- 2746,
- 2649,
- 680,
- 1637,
- 1692,
- 723,
- 2606,
- 2288,
- 1041,
- 1100,
- 2229,
- 1409,
- 1920,
- 2662,
- 667,
- 3281,
- 48,
- 233,
- 3096,
- 756,
- 2573,
- 2156,
- 1173,
- 3015,
- 314,
- 3050,
- 279,
- 1703,
- 1626,
- 1651,
- 1678,
- 2789,
- 540,
- 1789,
- 1540,
- 1847,
- 1482,
- 952,
- 2377,
- 1461,
- 1868,
- 2687,
- 642,
- 939,
- 2390,
- 2308,
- 1021,
- 2437,
- 892,
- 2388,
- 941,
- 733,
- 2596,
- 2337,
- 992,
- 268,
- 3061,
- 641,
- 2688,
- 1584,
- 1745,
- 2298,
- 1031,
- 2037,
- 1292,
- 3220,
- 109,
- 375,
- 2954,
- 2549,
- 780,
- 2090,
- 1239,
- 1645,
- 1684,
- 1063,
- 2266,
- 319,
- 3010,
- 2773,
- 556,
- 757,
- 2572,
- 2099,
- 1230,
- 561,
- 2768,
- 2466,
- 863,
- 2594,
- 735,
- 2804,
- 525,
- 1092,
- 2237,
- 403,
- 2926,
- 1026,
- 2303,
- 1143,
- 2186,
- 2150,
- 1179,
- 2775,
- 554,
- 886,
- 2443,
- 1722,
- 1607,
- 1212,
- 2117,
- 1874,
- 1455,
- 1029,
- 2300,
- 2110,
- 1219,
- 2935,
- 394,
- 885,
- 2444,
- 2154,
- 1175,
+ 0x011, 0xcf0, 0xac9, 0x238, 0x247, 0xaba, 0xa59, 0x2a8,
+ 0x665, 0x69c, 0x2d3, 0xa2e, 0x8f0, 0x411, 0x44c, 0x8b5,
+ 0x581, 0x780, 0xa66, 0x29b, 0xcd1, 0x030, 0x0e9, 0xc18,
+ 0x2f4, 0xa0d, 0x86c, 0x495, 0xbc7, 0x13a, 0xbea, 0x117,
+ 0x6a7, 0x65a, 0x673, 0x68e, 0xae5, 0x21c, 0x6fd, 0x604,
+ 0x737, 0x5ca, 0x3b8, 0x949, 0x5b5, 0x74c, 0xa7f, 0x282,
+ 0x3ab, 0x956, 0x904, 0x3fd, 0x985, 0x37c, 0x954, 0x3ad,
+ 0x2dd, 0xa24, 0x921, 0x3e0, 0x10c, 0xbf5, 0x281, 0xa80,
+ 0x630, 0x6d1, 0x8fa, 0x407, 0x7f5, 0x50c, 0xc94, 0x06d,
+ 0x177, 0xb8a, 0x9f5, 0x30c, 0x82a, 0x4d7, 0x66d, 0x694,
+ 0x427, 0x8da, 0x13f, 0xbc2, 0xad5, 0x22c, 0x2f5, 0xa0c,
+ 0x833, 0x4ce, 0x231, 0xad0, 0x9a2, 0x35f, 0xa22, 0x2df,
+ 0xaf4, 0x20d, 0x444, 0x8bd, 0x193, 0xb6e, 0x402, 0x8ff,
+ 0x477, 0x88a, 0x866, 0x49b, 0xad7, 0x22a, 0x376, 0x98b,
+ 0x6ba, 0x647, 0x4bc, 0x845, 0x752, 0x5af, 0x405, 0x8fc,
+ 0x83e, 0x4c3, 0xb77, 0x18a, 0x375, 0x98c, 0x86a, 0x497
};
/*
@@ -2271,17 +1935,22 @@ int ossl_ml_kem_encap_seed(uint8_t *ctext, size_t clen,
* We stack-allocate these.
*/
#define case_encap_seed(bits) \
- case EVP_PKEY_ML_KEM_##bits: { \
+ { \
scalar tmp[2 * ML_KEM_##bits##_RANK]; \
\
ret = encap(ctext, shared_secret, entropy, tmp, mdctx, key); \
OPENSSL_cleanse((void *)tmp, sizeof(tmp)); \
- break; \
}
switch (vinfo->evp_type) {
+ case EVP_PKEY_ML_KEM_512:
case_encap_seed(512);
+ break;
+ case EVP_PKEY_ML_KEM_768:
case_encap_seed(768);
+ break;
+ case EVP_PKEY_ML_KEM_1024:
case_encap_seed(1024);
+ break;
}
#undef case_encap_seed
@@ -2320,7 +1989,7 @@ int ossl_ml_kem_decap(uint8_t *shared_secret, size_t slen,
EVP_MD_CTX *mdctx;
int ret = 0;
#if defined(OPENSSL_CONSTANT_TIME_VALIDATION)
- int classify_bytes;
+ int classify_bytes = 2 * sizeof(scalar) + ML_KEM_RANDOM_BYTES;
#endif
/* Need a private key here */
@@ -2335,14 +2004,11 @@ int ossl_ml_kem_decap(uint8_t *shared_secret, size_t slen,
ML_KEM_SHARED_SECRET_BYTES, vinfo->secbits);
return 0;
}
-#if defined(OPENSSL_CONSTANT_TIME_VALIDATION)
/*
* Data derived from |s| and |z| defaults secret, and to avoid side-channel
* leaks should not influence control flow.
*/
- classify_bytes = 2 * sizeof(scalar) + ML_KEM_RANDOM_BYTES;
CONSTTIME_SECRET(key->s, classify_bytes);
-#endif
/*-
* This avoids the need to handle allocation failures for two (max 2KB
@@ -2351,19 +2017,25 @@ int ossl_ml_kem_decap(uint8_t *shared_secret, size_t slen,
* We stack-allocate these.
*/
#define case_decap(bits) \
- case EVP_PKEY_ML_KEM_##bits: { \
+ { \
uint8_t cbuf[CTEXT_BYTES(bits)]; \
scalar tmp[2 * ML_KEM_##bits##_RANK]; \
\
ret = decap(shared_secret, ctext, cbuf, tmp, mdctx, key); \
OPENSSL_cleanse((void *)tmp, sizeof(tmp)); \
- break; \
}
switch (vinfo->evp_type) {
+ case EVP_PKEY_ML_KEM_512:
case_decap(512);
+ break;
+ case EVP_PKEY_ML_KEM_768:
case_decap(768);
+ break;
+ case EVP_PKEY_ML_KEM_1024:
case_decap(1024);
+ break;
}
+#undef case_decap
/* Declassify secret inputs and derived outputs before returning control */
CONSTTIME_DECLASSIFY(key->s, classify_bytes);
@@ -2371,7 +2043,6 @@ int ossl_ml_kem_decap(uint8_t *shared_secret, size_t slen,
EVP_MD_CTX_free(mdctx);
return ret;
-#undef case_decap
}
int ossl_ml_kem_pubkey_cmp(const ML_KEM_KEY *key1, const ML_KEM_KEY *key2)