#ifndef __EC_KEY_H__
#define __EC_KEY_H__
#include <libecc/lib_ecc_config.h>
#include <libecc/lib_ecc_types.h>
#include <libecc/fp/fp.h>
#include <libecc/curves/ec_params.h>
#include <libecc/nn/nn_rand.h>
#include <libecc/nn/nn_add.h>
#include <libecc/nn/nn_logical.h>
#include <libecc/curves/prj_pt.h>
#include <libecc/hash/hash_algs.h>
typedef enum {
EC_PUBKEY = 0,
EC_PRIVKEY = 1,
} ec_key_type;
#define PRIV_KEY_MAGIC ((word_t)(0x2feb91e938a4855dULL))
typedef struct {
ec_alg_type key_type;
const ec_params *params;
nn x;
word_t magic;
} ec_priv_key;
#if defined(WITH_SIG_EDDSA25519) || defined(WITH_SIG_EDDSA448)
#define EC_PRIV_KEY_MAX_SIZE (LOCAL_MAX(MAX_DIGEST_SIZE, LOCAL_MAX(BYTECEIL(CURVES_MAX_Q_BIT_LEN), BYTECEIL(CURVES_MAX_P_BIT_LEN))))
#define EC_PRIV_KEY_EXPORT_SIZE(priv_key) \
((u8)(LOCAL_MAX(MAX_DIGEST_SIZE, LOCAL_MAX(BYTECEIL((priv_key)->params->ec_gen_order_bitlen), BYTECEIL((priv_key)->params->ec_fp.p_bitlen)))))
#else
#define EC_PRIV_KEY_MAX_SIZE (LOCAL_MAX(BYTECEIL(CURVES_MAX_Q_BIT_LEN), BYTECEIL(CURVES_MAX_P_BIT_LEN)))
#define EC_PRIV_KEY_EXPORT_SIZE(priv_key) \
((u8)(LOCAL_MAX(BYTECEIL((priv_key)->params->ec_gen_order_bitlen), BYTECEIL((priv_key)->params->ec_fp.p_bitlen))))
#endif
#define EC_STRUCTURED_PRIV_KEY_MAX_EXPORT_SIZE (EC_PRIV_KEY_MAX_SIZE + 3)
#if (EC_STRUCTURED_PRIV_KEY_MAX_EXPORT_SIZE > 255)
#error "All structured priv keys size are expected to fit on an u8."
#endif
#define EC_STRUCTURED_PRIV_KEY_EXPORT_SIZE(priv_key) \
((u8)(EC_PRIV_KEY_EXPORT_SIZE(priv_key) + (3 * sizeof(u8))))
ATTRIBUTE_WARN_UNUSED_RET int priv_key_check_initialized(const ec_priv_key *A);
ATTRIBUTE_WARN_UNUSED_RET int priv_key_check_initialized_and_type(const ec_priv_key *A,
ec_alg_type sig_type);
ATTRIBUTE_WARN_UNUSED_RET int ec_priv_key_import_from_buf(ec_priv_key *priv_key,
const ec_params *params,
const u8 *priv_key_buf, u8 priv_key_buf_len,
ec_alg_type ec_key_alg);
ATTRIBUTE_WARN_UNUSED_RET int ec_priv_key_export_to_buf(const ec_priv_key *priv_key, u8 *priv_key_buf,
u8 priv_key_buf_len);
ATTRIBUTE_WARN_UNUSED_RET int ec_structured_priv_key_import_from_buf(ec_priv_key *priv_key,
const ec_params *params,
const u8 *priv_key_buf,
u8 priv_key_buf_len,
ec_alg_type ec_key_alg);
ATTRIBUTE_WARN_UNUSED_RET int ec_structured_priv_key_export_to_buf(const ec_priv_key *priv_key,
u8 *priv_key_buf,
u8 priv_key_buf_len);
#define PUB_KEY_MAGIC ((word_t)(0x31327f37741ffb76ULL))
typedef struct {
ec_alg_type key_type;
const ec_params *params;
prj_pt y;
word_t magic;
} ec_pub_key;
#define EC_PUB_KEY_MAX_SIZE (3 * BYTECEIL(CURVES_MAX_P_BIT_LEN))
#define EC_PUB_KEY_EXPORT_SIZE(pub_key) \
(3 * BYTECEIL((pub_key)->params->ec_curve.a.ctx->p_bitlen))
#define EC_STRUCTURED_PUB_KEY_MAX_EXPORT_SIZE (EC_PUB_KEY_MAX_SIZE + 3)
#if (EC_STRUCTURED_PUB_KEY_MAX_EXPORT_SIZE > 255)
#error "All structured pub keys size are expected to fit on an u8."
#endif
#define EC_STRUCTURED_PUB_KEY_EXPORT_SIZE(pub_key) \
((u8)(EC_PUB_KEY_EXPORT_SIZE(pub_key) + (u8)(3 * sizeof(u8))))
ATTRIBUTE_WARN_UNUSED_RET int pub_key_check_initialized(const ec_pub_key *A);
ATTRIBUTE_WARN_UNUSED_RET int pub_key_check_initialized_and_type(const ec_pub_key *A,
ec_alg_type sig_type);
ATTRIBUTE_WARN_UNUSED_RET int ec_pub_key_import_from_buf(ec_pub_key *pub_key, const ec_params *params,
const u8 *pub_key_buf, u8 pub_key_buf_len,
ec_alg_type ec_key_alg);
ATTRIBUTE_WARN_UNUSED_RET int ec_pub_key_export_to_buf(const ec_pub_key *pub_key, u8 *pub_key_buf,
u8 pub_key_buf_len);
ATTRIBUTE_WARN_UNUSED_RET int ec_pub_key_import_from_aff_buf(ec_pub_key *pub_key, const ec_params *params,
const u8 *pub_key_buf, u8 pub_key_buf_len,
ec_alg_type ec_key_alg);
ATTRIBUTE_WARN_UNUSED_RET int ec_pub_key_export_to_aff_buf(const ec_pub_key *pub_key, u8 *pub_key_buf,
u8 pub_key_buf_len);
ATTRIBUTE_WARN_UNUSED_RET int ec_structured_pub_key_import_from_buf(ec_pub_key *pub_key,
const ec_params *params,
const u8 *pub_key_buf,
u8 pub_key_buf_len,
ec_alg_type ec_key_alg);
ATTRIBUTE_WARN_UNUSED_RET int ec_structured_pub_key_export_to_buf(const ec_pub_key *pub_key,
u8 *pub_key_buf, u8 pub_key_buf_len);
typedef struct {
ec_priv_key priv_key;
ec_pub_key pub_key;
} ec_key_pair;
ATTRIBUTE_WARN_UNUSED_RET int key_pair_check_initialized(const ec_key_pair *A);
ATTRIBUTE_WARN_UNUSED_RET int key_pair_check_initialized_and_type(const ec_key_pair *A,
ec_alg_type sig_type);
ATTRIBUTE_WARN_UNUSED_RET int ec_key_pair_import_from_priv_key_buf(ec_key_pair *kp,
const ec_params *params,
const u8 *priv_key, u8 priv_key_len,
ec_alg_type ec_key_alg);
ATTRIBUTE_WARN_UNUSED_RET int ec_key_pair_gen(ec_key_pair *kp, const ec_params *params,
ec_alg_type ec_key_alg);
ATTRIBUTE_WARN_UNUSED_RET int ec_structured_key_pair_import_from_priv_key_buf(ec_key_pair *kp,
const ec_params *params,
const u8 *priv_key_buf,
u8 priv_key_buf_len,
ec_alg_type ec_key_alg);
ATTRIBUTE_WARN_UNUSED_RET int ec_structured_key_pair_import_from_buf(ec_key_pair *kp,
const ec_params *params,
const u8 *priv_key_buf,
u8 priv_key_buf_len,
const u8 *pub_key_buf,
u8 pub_key_buf_len,
ec_alg_type ec_key_alg);
ATTRIBUTE_WARN_UNUSED_RET int generic_gen_priv_key(ec_priv_key *priv_key);
typedef struct {
nn number;
prj_pt point;
u32 index;
} verify_batch_scratch_pad;
#endif