#ifndef MLD_SIGN_H
#define MLD_SIGN_H
#include <stddef.h>
#include "cbmc.h"
#include "common.h"
#include "poly.h"
#include "polyvec.h"
#include "sys.h"
#if defined(MLD_CHECK_APIS)
#include "mldsa_native.h"
#if MLDSA_CRYPTO_SECRETKEYBYTES != \
MLDSA_SECRETKEYBYTES(MLD_CONFIG_PARAMETER_SET)
#error Mismatch for SECRETKEYBYTES between sign.h and mldsa_native.h
#endif
#if MLDSA_CRYPTO_PUBLICKEYBYTES != \
MLDSA_PUBLICKEYBYTES(MLD_CONFIG_PARAMETER_SET)
#error Mismatch for PUBLICKEYBYTES between sign.h and mldsa_native.h
#endif
#if MLDSA_CRYPTO_BYTES != MLDSA_BYTES(MLD_CONFIG_PARAMETER_SET)
#error Mismatch for BYTES between sign.h and mldsa_native.h
#endif
#endif
#define mld_sign_keypair_internal \
MLD_NAMESPACE_KL(keypair_internal) MLD_CONTEXT_PARAMETERS_3
#define mld_sign_keypair MLD_NAMESPACE_KL(keypair) MLD_CONTEXT_PARAMETERS_2
#define mld_sign_signature_internal \
MLD_NAMESPACE_KL(signature_internal) MLD_CONTEXT_PARAMETERS_9
#define mld_sign_signature MLD_NAMESPACE_KL(signature) MLD_CONTEXT_PARAMETERS_7
#define mld_sign_signature_extmu \
MLD_NAMESPACE_KL(signature_extmu) MLD_CONTEXT_PARAMETERS_4
#define mld_sign_verify_internal \
MLD_NAMESPACE_KL(verify_internal) MLD_CONTEXT_PARAMETERS_8
#define mld_sign_verify MLD_NAMESPACE_KL(verify) MLD_CONTEXT_PARAMETERS_7
#define mld_sign_verify_extmu \
MLD_NAMESPACE_KL(verify_extmu) MLD_CONTEXT_PARAMETERS_4
#define mld_sign_signature_pre_hash_internal \
MLD_NAMESPACE_KL(signature_pre_hash_internal) MLD_CONTEXT_PARAMETERS_9
#define mld_sign_verify_pre_hash_internal \
MLD_NAMESPACE_KL(verify_pre_hash_internal) MLD_CONTEXT_PARAMETERS_8
#define mld_sign_signature_pre_hash_shake256 \
MLD_NAMESPACE_KL(signature_pre_hash_shake256) MLD_CONTEXT_PARAMETERS_8
#define mld_sign_verify_pre_hash_shake256 \
MLD_NAMESPACE_KL(verify_pre_hash_shake256) MLD_CONTEXT_PARAMETERS_7
#define mld_prepare_domain_separation_prefix \
MLD_NAMESPACE_KL(prepare_domain_separation_prefix)
#define mld_sign_pk_from_sk \
MLD_NAMESPACE_KL(pk_from_sk) MLD_CONTEXT_PARAMETERS_2
#define MLD_PREHASH_NONE 0
#define MLD_PREHASH_SHA2_224 1
#define MLD_PREHASH_SHA2_256 2
#define MLD_PREHASH_SHA2_384 3
#define MLD_PREHASH_SHA2_512 4
#define MLD_PREHASH_SHA2_512_224 5
#define MLD_PREHASH_SHA2_512_256 6
#define MLD_PREHASH_SHA3_224 7
#define MLD_PREHASH_SHA3_256 8
#define MLD_PREHASH_SHA3_384 9
#define MLD_PREHASH_SHA3_512 10
#define MLD_PREHASH_SHAKE_128 11
#define MLD_PREHASH_SHAKE_256 12
#if !defined(MLD_CONFIG_NO_KEYPAIR_API)
MLD_MUST_CHECK_RETURN_VALUE
MLD_EXTERNAL_API
int mld_sign_keypair_internal(uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES],
const uint8_t seed[MLDSA_SEEDBYTES],
MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
requires(memory_no_alias(seed, MLDSA_SEEDBYTES))
assigns(object_whole(pk))
assigns(object_whole(sk))
ensures(return_value == 0 || MLD_ANY_ERROR(return_value))
);
#if !defined(MLD_CONFIG_CORE_API_ONLY)
MLD_MUST_CHECK_RETURN_VALUE
MLD_EXTERNAL_API
int mld_sign_keypair(uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES],
MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
assigns(object_whole(pk))
assigns(object_whole(sk))
ensures(return_value == 0 || MLD_ANY_ERROR(return_value))
);
#endif
#endif
#if !defined(MLD_CONFIG_NO_SIGN_API)
MLD_MUST_CHECK_RETURN_VALUE
MLD_EXTERNAL_API
int mld_sign_signature_internal(uint8_t sig[MLDSA_CRYPTO_BYTES], size_t *siglen,
const uint8_t *m, size_t mlen,
const uint8_t *pre, size_t prelen,
const uint8_t rnd[MLDSA_RNDBYTES],
const uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES],
int externalmu,
MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(mlen <= MLD_MAX_BUFFER_SIZE)
requires(prelen <= MLD_MAX_BUFFER_SIZE)
requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
requires(memory_no_alias(siglen, sizeof(size_t)))
requires(memory_no_alias(m, mlen))
requires(memory_no_alias(rnd, MLDSA_RNDBYTES))
requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
requires((externalmu == 0) ==> ((prelen == 0) || memory_no_alias(pre, prelen)))
requires((externalmu != 0) ==> (mlen == MLDSA_CRHBYTES))
assigns(memory_slice(sig, MLDSA_CRYPTO_BYTES))
assigns(object_whole(siglen))
ensures(return_value == 0 || return_value == MLD_ERR_FAIL ||
return_value == MLD_ERR_OUT_OF_MEMORY ||
return_value == MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED)
ensures(return_value == 0 ==> *siglen == MLDSA_CRYPTO_BYTES)
ensures(return_value != 0 ==> *siglen == 0)
);
#if !defined(MLD_CONFIG_CORE_API_ONLY)
MLD_MUST_CHECK_RETURN_VALUE
MLD_EXTERNAL_API
int mld_sign_signature(uint8_t sig[MLDSA_CRYPTO_BYTES], size_t *siglen,
const uint8_t *m, size_t mlen, const uint8_t *ctx,
size_t ctxlen,
const uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES],
MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(mlen <= MLD_MAX_BUFFER_SIZE)
requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
requires(memory_no_alias(siglen, sizeof(size_t)))
requires(memory_no_alias(m, mlen))
requires(ctxlen <= MLD_MAX_BUFFER_SIZE)
requires(ctxlen == 0 || memory_no_alias(ctx, ctxlen))
requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
assigns(memory_slice(sig, MLDSA_CRYPTO_BYTES))
assigns(object_whole(siglen))
ensures((return_value == 0 && *siglen == MLDSA_CRYPTO_BYTES) ||
(MLD_ANY_ERROR(return_value) && *siglen == 0))
);
MLD_MUST_CHECK_RETURN_VALUE
MLD_EXTERNAL_API
int mld_sign_signature_extmu(uint8_t sig[MLDSA_CRYPTO_BYTES], size_t *siglen,
const uint8_t mu[MLDSA_CRHBYTES],
const uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES],
MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
requires(memory_no_alias(siglen, sizeof(size_t)))
requires(memory_no_alias(mu, MLDSA_CRHBYTES))
requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
assigns(memory_slice(sig, MLDSA_CRYPTO_BYTES))
assigns(object_whole(siglen))
ensures((return_value == 0 && *siglen == MLDSA_CRYPTO_BYTES) ||
(MLD_ANY_ERROR(return_value) && *siglen == 0))
);
#endif
#endif
#if !defined(MLD_CONFIG_NO_VERIFY_API)
MLD_MUST_CHECK_RETURN_VALUE
MLD_EXTERNAL_API
int mld_sign_verify_internal(const uint8_t *sig, size_t siglen,
const uint8_t *m, size_t mlen, const uint8_t *pre,
size_t prelen,
const uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
int externalmu,
MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(prelen <= MLD_MAX_BUFFER_SIZE)
requires(mlen <= MLD_MAX_BUFFER_SIZE)
requires(siglen <= MLD_MAX_BUFFER_SIZE)
requires(memory_no_alias(sig, siglen))
requires(memory_no_alias(m, mlen))
requires((externalmu == 0) ==> ((prelen == 0) || memory_no_alias(pre, prelen)))
requires((externalmu != 0) ==> (mlen == MLDSA_CRHBYTES))
requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
ensures(return_value == 0 || return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY)
);
#if !defined(MLD_CONFIG_CORE_API_ONLY)
MLD_MUST_CHECK_RETURN_VALUE
MLD_EXTERNAL_API
int mld_sign_verify(const uint8_t *sig, size_t siglen, const uint8_t *m,
size_t mlen, const uint8_t *ctx, size_t ctxlen,
const uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(mlen <= MLD_MAX_BUFFER_SIZE)
requires(siglen <= MLD_MAX_BUFFER_SIZE)
requires(ctxlen <= MLD_MAX_BUFFER_SIZE)
requires(memory_no_alias(sig, siglen))
requires(memory_no_alias(m, mlen))
requires(ctxlen == 0 || memory_no_alias(ctx, ctxlen))
requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
ensures(return_value == 0 || return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY)
);
MLD_MUST_CHECK_RETURN_VALUE
MLD_EXTERNAL_API
int mld_sign_verify_extmu(const uint8_t *sig, size_t siglen,
const uint8_t mu[MLDSA_CRHBYTES],
const uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(siglen <= MLD_MAX_BUFFER_SIZE)
requires(memory_no_alias(sig, siglen))
requires(memory_no_alias(mu, MLDSA_CRHBYTES))
requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
ensures(return_value == 0 || return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY)
);
#endif
#endif
#if !defined(MLD_CONFIG_CORE_API_ONLY)
#if !defined(MLD_CONFIG_NO_SIGN_API)
MLD_MUST_CHECK_RETURN_VALUE
MLD_EXTERNAL_API
int mld_sign_signature_pre_hash_internal(
uint8_t sig[MLDSA_CRYPTO_BYTES], size_t *siglen, const uint8_t *ph,
size_t phlen, const uint8_t *ctx, size_t ctxlen,
const uint8_t rnd[MLDSA_RNDBYTES],
const uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES], int hashalg,
MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(ctxlen <= MLD_MAX_BUFFER_SIZE)
requires(phlen <= MLD_MAX_BUFFER_SIZE)
requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
requires(memory_no_alias(siglen, sizeof(size_t)))
requires(memory_no_alias(ph, phlen))
requires(ctxlen == 0 || memory_no_alias(ctx, ctxlen))
requires(memory_no_alias(rnd, MLDSA_RNDBYTES))
requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
assigns(memory_slice(sig, MLDSA_CRYPTO_BYTES))
assigns(object_whole(siglen))
ensures((return_value == 0 && *siglen == MLDSA_CRYPTO_BYTES) ||
((return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY || return_value == MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED) && *siglen == 0))
);
#endif
#if !defined(MLD_CONFIG_NO_VERIFY_API)
MLD_MUST_CHECK_RETURN_VALUE
MLD_EXTERNAL_API
int mld_sign_verify_pre_hash_internal(
const uint8_t *sig, size_t siglen, const uint8_t *ph, size_t phlen,
const uint8_t *ctx, size_t ctxlen,
const uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES], int hashalg,
MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(phlen <= MLD_MAX_BUFFER_SIZE)
requires(ctxlen <= MLD_MAX_BUFFER_SIZE - 77)
requires(siglen <= MLD_MAX_BUFFER_SIZE)
requires(memory_no_alias(sig, siglen))
requires(memory_no_alias(ph, phlen))
requires(ctxlen == 0 || memory_no_alias(ctx, ctxlen))
requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
ensures(return_value == 0 || return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY)
);
#endif
#if !defined(MLD_CONFIG_NO_SIGN_API)
MLD_MUST_CHECK_RETURN_VALUE
MLD_EXTERNAL_API
int mld_sign_signature_pre_hash_shake256(
uint8_t sig[MLDSA_CRYPTO_BYTES], size_t *siglen, const uint8_t *m,
size_t mlen, const uint8_t *ctx, size_t ctxlen,
const uint8_t rnd[MLDSA_RNDBYTES],
const uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES],
MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(mlen <= MLD_MAX_BUFFER_SIZE)
requires(ctxlen <= MLD_MAX_BUFFER_SIZE)
requires(memory_no_alias(sig, MLDSA_CRYPTO_BYTES))
requires(memory_no_alias(siglen, sizeof(size_t)))
requires(memory_no_alias(m, mlen))
requires(ctxlen == 0 || memory_no_alias(ctx, ctxlen))
requires(memory_no_alias(rnd, MLDSA_RNDBYTES))
requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
assigns(memory_slice(sig, MLDSA_CRYPTO_BYTES))
assigns(object_whole(siglen))
ensures((return_value == 0 && *siglen == MLDSA_CRYPTO_BYTES) ||
((return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY || return_value == MLD_ERR_SIGN_ATTEMPTS_EXHAUSTED) && *siglen == 0))
);
#endif
#if !defined(MLD_CONFIG_NO_VERIFY_API)
MLD_MUST_CHECK_RETURN_VALUE
MLD_EXTERNAL_API
int mld_sign_verify_pre_hash_shake256(
const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
const uint8_t *ctx, size_t ctxlen,
const uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(mlen <= MLD_MAX_BUFFER_SIZE)
requires(ctxlen <= MLD_MAX_BUFFER_SIZE - 77)
requires(siglen <= MLD_MAX_BUFFER_SIZE)
requires(memory_no_alias(sig, siglen))
requires(memory_no_alias(m, mlen))
requires(ctxlen == 0 || memory_no_alias(ctx, ctxlen))
requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
ensures(return_value == 0 || return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY)
);
#endif
#if !defined(MLD_CONFIG_NO_SIGN_API) || !defined(MLD_CONFIG_NO_VERIFY_API)
#define MLD_DOMAIN_SEPARATION_MAX_BYTES (2 + 255 + 11 + 64)
MLD_MUST_CHECK_RETURN_VALUE
MLD_EXTERNAL_API
size_t mld_prepare_domain_separation_prefix(
uint8_t prefix[MLD_DOMAIN_SEPARATION_MAX_BYTES], const uint8_t *ph,
size_t phlen, const uint8_t *ctx, size_t ctxlen, int hashalg)
__contract__(
requires(ctxlen <= 255)
requires(phlen <= MLD_MAX_BUFFER_SIZE)
requires(ctxlen == 0 || memory_no_alias(ctx, ctxlen))
requires(hashalg == MLD_PREHASH_NONE || memory_no_alias(ph, phlen))
requires(memory_no_alias(prefix, MLD_DOMAIN_SEPARATION_MAX_BYTES))
assigns(memory_slice(prefix, MLD_DOMAIN_SEPARATION_MAX_BYTES))
ensures(return_value <= MLD_DOMAIN_SEPARATION_MAX_BYTES)
);
#endif
#if !defined(MLD_CONFIG_NO_KEYPAIR_API)
MLD_MUST_CHECK_RETURN_VALUE
MLD_EXTERNAL_API
int mld_sign_pk_from_sk(uint8_t pk[MLDSA_CRYPTO_PUBLICKEYBYTES],
const uint8_t sk[MLDSA_CRYPTO_SECRETKEYBYTES],
MLD_CONFIG_CONTEXT_PARAMETER_TYPE context)
__contract__(
requires(memory_no_alias(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
requires(memory_no_alias(sk, MLDSA_CRYPTO_SECRETKEYBYTES))
assigns(memory_slice(pk, MLDSA_CRYPTO_PUBLICKEYBYTES))
ensures(return_value == 0 || return_value == MLD_ERR_FAIL || return_value == MLD_ERR_OUT_OF_MEMORY)
);
#endif
#endif
#endif