ml_kem.h 10 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281
  1. /*
  2. * Copyright 2024-2025 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. #ifndef OPENSSL_HEADER_ML_KEM_H
  10. # define OPENSSL_HEADER_ML_KEM_H
  11. # pragma once
  12. # include <openssl/e_os2.h>
  13. # include <openssl/bio.h>
  14. # include <openssl/core_dispatch.h>
  15. # include <crypto/evp.h>
  16. # define ML_KEM_DEGREE 256
  17. /*
  18. * With (q-1) an odd multiple of 256, and 17 ("zeta") as a primitive 256th root
  19. * of unity, the polynomial (X^256+1) splits in Z_q[X] into 128 irreducible
  20. * quadratic factors of the form (X^2 - zeta^(2i + 1)). This is used to
  21. * implement efficient multiplication in the ring R_q via the "NTT" transform.
  22. */
  23. # define ML_KEM_PRIME (ML_KEM_DEGREE * 13 + 1)
  24. /*
  25. * Various ML-KEM primitives need random input, 32-bytes at a time. Key
  26. * generation consumes two random values (d, z) with "d" plus the rank (domain
  27. * separation) further expanded to two derived seeds "rho" and "sigma", with
  28. * "rho" used to generate the public matrix "A", and sigma to generate the
  29. * private vector "s" and error vector "e".
  30. *
  31. * Encapsulation also consumes one random value m, that is 32-bytes long. The
  32. * resulting shared secret "K" (also 32 bytes) and an internal random value "r"
  33. * are derived from "m" concatenated with a digest of the received public key.
  34. * Use of the public key hash means that the derived shared secret is
  35. * "contributary", it uses randomness from both parties.
  36. *
  37. * The seed "rho" is appended to the public key and allows the recipient of the
  38. * public key to re-compute the matrix "A" when performing encapsulation.
  39. *
  40. * Note that the matrix "m" we store in the public key is the transpose of the
  41. * "A" matrix from FIPS 203!
  42. */
  43. # define ML_KEM_RANDOM_BYTES 32 /* rho, sigma, ... */
  44. # define ML_KEM_SEED_BYTES (ML_KEM_RANDOM_BYTES * 2) /* Keygen (d, z) */
  45. # define ML_KEM_PKHASH_BYTES 32 /* Salts the shared-secret */
  46. # define ML_KEM_SHARED_SECRET_BYTES 32
  47. # if ML_KEM_PKHASH_BYTES != ML_KEM_RANDOM_BYTES
  48. # error "unexpected ML-KEM public key hash size"
  49. # endif
  50. /*-
  51. * The ML-KEM specification can be found in
  52. * https://nvlpubs.nist.gov/nistpubs/FIPS/NIST.FIPS.203.pdf
  53. *
  54. * Section 8, Table 2, lists the parameters for the three variants:
  55. *
  56. * Variant n q k eta1 eta2 du dv secbits
  57. * ---------- --- ---- - ---- ---- -- -- -------
  58. * ML-KEM-512 256 3329 2 3 2 10 4 128
  59. * ML-KEM-768 256 3329 3 2 2 10 4 192
  60. * ML-KEM-1024 256 3329 4 2 2 11 5 256
  61. *
  62. * where:
  63. *
  64. * - "n" (ML_KEM_DEGREE above) is the fixed degree of the quotient polynomial
  65. * in the ring: "R_q" = Z[X]/(X^n + 1).
  66. * - "q" (ML_KEM_PRIME above) is the fixed prime (256 * 13 + 1 = 3329) used in
  67. * all ML-KEM variants.
  68. * - "k" is the row rank of the square matrix "A", with entries in R_q, that
  69. * defines the "noisy" linear equations: t = A * s + e. Also the rank of
  70. * of the associated vectors.
  71. * - "eta1" determines the amplitude of "s" and "e" vectors in key generation
  72. * and the "y" vector in ML-KEM encapsulation (K-PKE encryption).
  73. * - "eta2" determines the amplitude of "e1" and "e2" noise terms in ML-KEM
  74. * encapsulation (K-PKE encryption).
  75. * - "du" determines how many bits of each coefficient are retained in the
  76. * compressed form of the "u" vector in the encapsulation ciphertext.
  77. * - "dv" determines how many bits of each coefficient are retained in the
  78. * compressed form of the "v" value in encapsulation ciphertext
  79. * - "secbits" is required security strength of the RNG for the random inputs.
  80. */
  81. /*
  82. * Variant-specific constants and structures
  83. * -----------------------------------------
  84. */
  85. # define EVP_PKEY_ML_KEM_512 NID_ML_KEM_512
  86. # define ML_KEM_512_BITS 512
  87. # define ML_KEM_512_RANK 2
  88. # define ML_KEM_512_ETA1 3
  89. # define ML_KEM_512_ETA2 2
  90. # define ML_KEM_512_DU 10
  91. # define ML_KEM_512_DV 4
  92. # define ML_KEM_512_SECBITS 128
  93. # define EVP_PKEY_ML_KEM_768 NID_ML_KEM_768
  94. # define ML_KEM_768_BITS 768
  95. # define ML_KEM_768_RANK 3
  96. # define ML_KEM_768_ETA1 2
  97. # define ML_KEM_768_ETA2 2
  98. # define ML_KEM_768_DU 10
  99. # define ML_KEM_768_DV 4
  100. # define ML_KEM_768_SECBITS 192
  101. # define EVP_PKEY_ML_KEM_1024 NID_ML_KEM_1024
  102. # define ML_KEM_1024_BITS 1024
  103. # define ML_KEM_1024_RANK 4
  104. # define ML_KEM_1024_ETA1 2
  105. # define ML_KEM_1024_ETA2 2
  106. # define ML_KEM_1024_DU 11
  107. # define ML_KEM_1024_DV 5
  108. # define ML_KEM_1024_SECBITS 256
  109. # define ML_KEM_KEY_RANDOM_PCT (1 << 0)
  110. # define ML_KEM_KEY_FIXED_PCT (1 << 1)
  111. # define ML_KEM_KEY_PREFER_SEED (1 << 2)
  112. # define ML_KEM_KEY_RETAIN_SEED (1 << 3)
  113. /* Mask to check whether PCT on import is enabled */
  114. # define ML_KEM_KEY_PCT_TYPE \
  115. (ML_KEM_KEY_RANDOM_PCT | ML_KEM_KEY_FIXED_PCT)
  116. /* Default provider flags */
  117. # define ML_KEM_KEY_PROV_FLAGS_DEFAULT \
  118. (ML_KEM_KEY_RANDOM_PCT | ML_KEM_KEY_PREFER_SEED | ML_KEM_KEY_RETAIN_SEED)
  119. /*
  120. * External variant-specific API
  121. * -----------------------------
  122. */
  123. typedef struct {
  124. const char *algorithm_name;
  125. size_t prvkey_bytes;
  126. size_t prvalloc;
  127. size_t pubkey_bytes;
  128. size_t puballoc;
  129. size_t ctext_bytes;
  130. size_t vector_bytes;
  131. size_t u_vector_bytes;
  132. int evp_type;
  133. int bits;
  134. int rank;
  135. int du;
  136. int dv;
  137. int secbits;
  138. } ML_KEM_VINFO;
  139. /* Retrive global variant-specific parameters */
  140. const ML_KEM_VINFO *ossl_ml_kem_get_vinfo(int evp_type);
  141. /* Known as ML_KEM_KEY via crypto/types.h */
  142. typedef struct ossl_ml_kem_key_st {
  143. /* Variant metadata, for one of ML-KEM-{512,768,1024} */
  144. const ML_KEM_VINFO *vinfo;
  145. /*
  146. * Library context, initially used to fetch the SHA3 MDs, and later for
  147. * random number generation.
  148. */
  149. OSSL_LIB_CTX *libctx;
  150. /* Pre-fetched SHA3 */
  151. EVP_MD *shake128_md;
  152. EVP_MD *shake256_md;
  153. EVP_MD *sha3_256_md;
  154. EVP_MD *sha3_512_md;
  155. /*
  156. * Pointers into variable size storage, initially all NULL. Appropriate
  157. * storage is allocated once a public or private key is specified, at
  158. * which point the key becomes immutable.
  159. */
  160. uint8_t *rho; /* Public matrix seed */
  161. uint8_t *pkhash; /* Public key hash */
  162. struct ossl_ml_kem_scalar_st *t; /* Public key vector */
  163. struct ossl_ml_kem_scalar_st *m; /* Pre-computed pubkey matrix */
  164. struct ossl_ml_kem_scalar_st *s; /* Private key secret vector */
  165. uint8_t *z; /* Private key FO failure secret */
  166. uint8_t *d; /* Private key seed */
  167. int prov_flags; /* prefer/retain seed and PCT flags */
  168. /*
  169. * Fixed-size built-in buffer, which holds the |rho| and the public key
  170. * |pkhash| in that order, once we have expanded key material.
  171. * With seed-only keys, that are not yet expanded, this instead holds the
  172. * |z| and |d| components in that order.
  173. */
  174. uint8_t seedbuf[64]; /* |rho| + |pkhash| / |z| + |d| */
  175. uint8_t *encoded_dk; /* Unparsed P8 private key */
  176. } ML_KEM_KEY;
  177. /* The public key is always present, when the private is */
  178. # define ossl_ml_kem_key_vinfo(key) ((key)->vinfo)
  179. # define ossl_ml_kem_have_pubkey(key) ((key)->t != NULL)
  180. # define ossl_ml_kem_have_prvkey(key) ((key)->s != NULL)
  181. # define ossl_ml_kem_have_seed(key) ((key)->d != NULL)
  182. # define ossl_ml_kem_have_dkenc(key) ((key)->encoded_dk != NULL)
  183. # define ossl_ml_kem_decoded_key(key) ((key)->encoded_dk != NULL \
  184. || ((key)->s == NULL && (key)->d != NULL))
  185. /*
  186. * ----- ML-KEM key lifecycle
  187. */
  188. /*
  189. * Allocate a "bare" key for given ML-KEM variant. Initially without any public
  190. * or private key material.
  191. */
  192. ML_KEM_KEY *ossl_ml_kem_key_new(OSSL_LIB_CTX *libctx, const char *properties,
  193. int evp_type);
  194. /* Reset a key clearing all public and private key material */
  195. void ossl_ml_kem_key_reset(ML_KEM_KEY *key);
  196. /* Deallocate the key */
  197. void ossl_ml_kem_key_free(ML_KEM_KEY *key);
  198. /*
  199. * Duplicate a key, optionally including some key material, per the
  200. * |selection|, see <openssl/core_dispatch.h>.
  201. */
  202. ML_KEM_KEY *ossl_ml_kem_key_dup(const ML_KEM_KEY *key, int selection);
  203. /*
  204. * ----- Import or generate key material.
  205. */
  206. /*
  207. * Functions that augment "bare ML-KEM keys" with key material deserialised
  208. * from an input buffer. It is an error for any key material to already be
  209. * present.
  210. *
  211. * Return 1 on success, 0 otherwise.
  212. */
  213. __owur
  214. int ossl_ml_kem_parse_public_key(const uint8_t *in, size_t len,
  215. ML_KEM_KEY *key);
  216. __owur
  217. int ossl_ml_kem_parse_private_key(const uint8_t *in, size_t len,
  218. ML_KEM_KEY *key);
  219. ML_KEM_KEY *ossl_ml_kem_set_seed(const uint8_t *seed, size_t seedlen,
  220. ML_KEM_KEY *key);
  221. __owur
  222. int ossl_ml_kem_genkey(uint8_t *pubenc, size_t publen, ML_KEM_KEY *key);
  223. /*
  224. * Perform an ML-KEM operation with a given ML-KEM key. The key can generally
  225. * be either a private or public key, with the exception of encoding a private
  226. * key or performing KEM decapsulation.
  227. */
  228. __owur
  229. int ossl_ml_kem_encode_public_key(uint8_t *out, size_t len,
  230. const ML_KEM_KEY *key);
  231. __owur
  232. int ossl_ml_kem_encode_private_key(uint8_t *out, size_t len,
  233. const ML_KEM_KEY *key);
  234. __owur
  235. int ossl_ml_kem_encode_seed(uint8_t *out, size_t len,
  236. const ML_KEM_KEY *key);
  237. __owur
  238. int ossl_ml_kem_encap_seed(uint8_t *ctext, size_t clen,
  239. uint8_t *shared_secret, size_t slen,
  240. const uint8_t *entropy, size_t elen,
  241. const ML_KEM_KEY *key);
  242. __owur
  243. int ossl_ml_kem_encap_rand(uint8_t *ctext, size_t clen,
  244. uint8_t *shared_secret, size_t slen,
  245. const ML_KEM_KEY *key);
  246. __owur
  247. int ossl_ml_kem_decap(uint8_t *shared_secret, size_t slen,
  248. const uint8_t *ctext, size_t clen,
  249. const ML_KEM_KEY *key);
  250. /* Compare the public key hashes of two keys */
  251. __owur
  252. int ossl_ml_kem_pubkey_cmp(const ML_KEM_KEY *key1, const ML_KEM_KEY *key2);
  253. #endif /* OPENSSL_HEADER_ML_KEM_H */