#ifndef OPENSSL_HEADER_ML_KEM_H
#define OPENSSL_HEADER_ML_KEM_H
#pragma once
#include <openssl/e_os2.h>
#include <openssl/bio.h>
#include <openssl/core_dispatch.h>
#include <crypto/evp.h>
#define ML_KEM_DEGREE 256
#define ML_KEM_PRIME (ML_KEM_DEGREE * 13 + 1)
#define ML_KEM_RANDOM_BYTES 32
#define ML_KEM_SEED_BYTES (ML_KEM_RANDOM_BYTES * 2)
#define ML_KEM_PKHASH_BYTES 32
#define ML_KEM_SHARED_SECRET_BYTES 32
#if ML_KEM_PKHASH_BYTES != ML_KEM_RANDOM_BYTES
#error "unexpected ML-KEM public key hash size"
#endif
#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
#define ML_KEM_512_ETA2 2
#define ML_KEM_512_DU 10
#define ML_KEM_512_DV 4
#define ML_KEM_512_SECBITS 128
#define ML_KEM_512_SECURITY_CATEGORY 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_ETA2 2
#define ML_KEM_768_DU 10
#define ML_KEM_768_DV 4
#define ML_KEM_768_SECBITS 192
#define ML_KEM_768_SECURITY_CATEGORY 3
#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
#define ML_KEM_1024_ETA2 2
#define ML_KEM_1024_DU 11
#define ML_KEM_1024_DV 5
#define ML_KEM_1024_SECBITS 256
#define ML_KEM_1024_SECURITY_CATEGORY 5
#define ML_KEM_KEY_RANDOM_PCT (1 << 0)
#define ML_KEM_KEY_FIXED_PCT (1 << 1)
#define ML_KEM_KEY_PREFER_SEED (1 << 2)
#define ML_KEM_KEY_RETAIN_SEED (1 << 3)
#define ML_KEM_KEY_PCT_TYPE \
(ML_KEM_KEY_RANDOM_PCT | ML_KEM_KEY_FIXED_PCT)
#define ML_KEM_KEY_PROV_FLAGS_DEFAULT \
(ML_KEM_KEY_RANDOM_PCT | ML_KEM_KEY_PREFER_SEED | ML_KEM_KEY_RETAIN_SEED)
typedef struct {
const char *algorithm_name;
size_t prvkey_bytes;
size_t prvalloc;
size_t pubkey_bytes;
size_t puballoc;
size_t ctext_bytes;
size_t vector_bytes;
size_t u_vector_bytes;
int evp_type;
int bits;
int rank;
int du;
int dv;
int secbits;
int security_category;
} ML_KEM_VINFO;
const ML_KEM_VINFO *ossl_ml_kem_get_vinfo(int evp_type);
typedef struct ossl_ml_kem_key_st {
const ML_KEM_VINFO *vinfo;
OSSL_LIB_CTX *libctx;
EVP_MD *shake128_md;
EVP_MD *shake256_md;
EVP_MD *sha3_256_md;
EVP_MD *sha3_512_md;
uint8_t *rho;
uint8_t *pkhash;
struct ossl_ml_kem_scalar_st *t;
struct ossl_ml_kem_scalar_st *m;
struct ossl_ml_kem_scalar_st *s;
uint8_t *z;
uint8_t *d;
int prov_flags;
uint8_t rho_pkhash[64];
uint8_t *seedbuf;
uint8_t *encoded_dk;
} ML_KEM_KEY;
#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)
#define ossl_ml_kem_have_dkenc(key) ((key)->encoded_dk != NULL)
#define ossl_ml_kem_decoded_key(key) ((key)->encoded_dk != NULL \
|| ((key)->s == NULL && (key)->d != NULL))
ML_KEM_KEY *ossl_ml_kem_key_new(OSSL_LIB_CTX *libctx, const char *properties,
int evp_type);
void ossl_ml_kem_key_reset(ML_KEM_KEY *key);
void ossl_ml_kem_key_free(ML_KEM_KEY *key);
ML_KEM_KEY *ossl_ml_kem_key_dup(const ML_KEM_KEY *key, int selection);
__owur int ossl_ml_kem_parse_public_key(const uint8_t *in, size_t len,
ML_KEM_KEY *key);
__owur int ossl_ml_kem_parse_private_key(const uint8_t *in, size_t len,
ML_KEM_KEY *key);
ML_KEM_KEY *ossl_ml_kem_set_seed(const uint8_t *seed, size_t seedlen,
ML_KEM_KEY *key);
__owur int ossl_ml_kem_genkey(uint8_t *pubenc, size_t publen, ML_KEM_KEY *key);
__owur int ossl_ml_kem_encode_public_key(uint8_t *out, size_t len,
const ML_KEM_KEY *key);
__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_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,
uint8_t *shared_secret, size_t slen,
const uint8_t *entropy, size_t elen,
const ML_KEM_KEY *key);
__owur int ossl_ml_kem_encap_rand(uint8_t *ctext, size_t clen,
uint8_t *shared_secret, size_t slen,
const ML_KEM_KEY *key);
__owur int ossl_ml_kem_decap(uint8_t *shared_secret, size_t slen,
const uint8_t *ctext, size_t clen,
const ML_KEM_KEY *key);
__owur int ossl_ml_kem_pubkey_cmp(const ML_KEM_KEY *key1, const ML_KEM_KEY *key2);
#endif