#include <stdlib.h>
#include <string.h>
#include <openssl/mlkem.h>
#include "mlkem_internal.h"
MLKEM_private_key *
MLKEM_private_key_new(int rank)
{
MLKEM_private_key *key = NULL;
MLKEM_private_key *ret = NULL;
if ((key = calloc(1, sizeof(*key))) == NULL)
goto err;
switch (rank) {
case MLKEM768_RANK:
if ((key->key_768 = calloc(1, sizeof(*key->key_768))) == NULL)
goto err;
break;
case MLKEM1024_RANK:
if ((key->key_1024 = calloc(1, sizeof(*key->key_1024))) == NULL)
goto err;
break;
default:
goto err;
}
key->rank = rank;
key->state = MLKEM_PRIVATE_KEY_UNINITIALIZED;
ret = key;
key = NULL;
err:
MLKEM_private_key_free(key);
return ret;
}
LCRYPTO_ALIAS(MLKEM_private_key_new);
void
MLKEM_private_key_free(MLKEM_private_key *key)
{
if (key == NULL)
return;
freezero(key->key_768, sizeof(*key->key_768));
freezero(key->key_1024, sizeof(*key->key_1024));
freezero(key, sizeof(*key));
}
LCRYPTO_ALIAS(MLKEM_private_key_free);
size_t
MLKEM_private_key_encoded_length(const MLKEM_private_key *key)
{
if (key == NULL)
return 0;
switch (key->rank) {
case MLKEM768_RANK:
return MLKEM768_PRIVATE_KEY_BYTES;
case MLKEM1024_RANK:
return MLKEM1024_PRIVATE_KEY_BYTES;
default:
return 0;
}
return 0;
}
LCRYPTO_ALIAS(MLKEM_private_key_encoded_length);
size_t
MLKEM_private_key_ciphertext_length(const MLKEM_private_key *key)
{
if (key == NULL)
return 0;
switch (key->rank) {
case MLKEM768_RANK:
return MLKEM768_CIPHERTEXT_BYTES;
case MLKEM1024_RANK:
return MLKEM1024_CIPHERTEXT_BYTES;
default:
return 0;
}
return 0;
}
LCRYPTO_ALIAS(MLKEM_private_key_ciphertext_length);
MLKEM_public_key *
MLKEM_public_key_new(int rank)
{
MLKEM_public_key *key = NULL;
MLKEM_public_key *ret = NULL;
if ((key = calloc(1, sizeof(*key))) == NULL)
goto err;
switch (rank) {
case MLKEM768_RANK:
if ((key->key_768 = calloc(1, sizeof(*key->key_768))) == NULL)
goto err;
break;
case MLKEM1024_RANK:
if ((key->key_1024 = calloc(1, sizeof(*key->key_1024))) == NULL)
goto err;
break;
default:
goto err;
}
key->rank = rank;
key->state = MLKEM_PUBLIC_KEY_UNINITIALIZED;
ret = key;
key = NULL;
err:
MLKEM_public_key_free(key);
return ret;
}
LCRYPTO_ALIAS(MLKEM_public_key_new);
void
MLKEM_public_key_free(MLKEM_public_key *key)
{
if (key == NULL)
return;
freezero(key->key_768, sizeof(*key->key_768));
freezero(key->key_1024, sizeof(*key->key_1024));
freezero(key, sizeof(*key));
}
LCRYPTO_ALIAS(MLKEM_public_key_free);
size_t
MLKEM_public_key_encoded_length(const MLKEM_public_key *key)
{
if (key == NULL)
return 0;
switch (key->rank) {
case MLKEM768_RANK:
return MLKEM768_PUBLIC_KEY_BYTES;
case MLKEM1024_RANK:
return MLKEM1024_PUBLIC_KEY_BYTES;
default:
return 0;
}
return 0;
}
LCRYPTO_ALIAS(MLKEM_public_key_encoded_length);
size_t
MLKEM_public_key_ciphertext_length(const MLKEM_public_key *key)
{
if (key == NULL)
return 0;
switch (key->rank) {
case MLKEM768_RANK:
return MLKEM768_CIPHERTEXT_BYTES;
case MLKEM1024_RANK:
return MLKEM1024_CIPHERTEXT_BYTES;
default:
return 0;
}
return 0;
}
LCRYPTO_ALIAS(MLKEM_public_key_ciphertext_length);