blob: 5c1cd39e2a69db91a5b78cea90dfd810ef8813f3 [file] [log] [blame]
/* SPDX-License-Identifier: BSD-2-Clause */
/*
* Copyright (c) 2014, STMicroelectronics International N.V.
*/
#ifndef GUARD_MPALIB_H
#define GUARD_MPALIB_H
/*************************************************************
*
* How functions are exported.
*
*************************************************************/
#define MPALIB_EXPORT
/*************************************************************
*
* Include common configuration definitions
*
*************************************************************/
#include "mpalib_config.h"
#include <mempool.h>
/*************************************************************
*
* TYPE DEFINITIONS
*
*************************************************************/
#if defined(MPA_SUPPORT_DWORD_T)
typedef unsigned long long mpa_dword_t;
#endif
/*! \struct mpa_numbase_struct
* The internal representation of a multi precision integer.
*
* \param alloc The size of the allocated array d in number of mpa_word_t.
*
* \param size The number of used words in *d to represent the number, or
* minus the number if the mpa_numbase is representing a
* negative number. The mpa_numbase
* is representing zero if and only if size == 0.
*
* \param d The digits of the integer. The digits are in radix
* 2^WORD_SIZE.
* The digits are stored in a little endian format, i.e.
* the least significant word_t is stored in d[0].
*
* \internal ** NOTE **
* If you change this struct, you must update the const variables
* in mpa_misc.c and mpa_primetest.c
* And the
* MPA_NUMBASE_METADATA_SIZE_IN_U32
* below.
*/
typedef struct mpa_numbase_struct {
mpa_asize_t alloc;
mpa_usize_t size;
mpa_word_t d[];
} mpa_num_base;
/*/ mpanum is the type we use as parameters to function calls in this library */
typedef mpa_num_base *mpanum;
/*!
* The Context struct for a Montgomery multiplication
*
* \internal ** NOTE **
* If you change this struct, you must update the
* MPA_FMM_CONTEXT_METADATA_SIZE_IN_U32
* below.
*
*/
typedef struct mpa_fmm_context_struct {
mpanum r_ptr;
mpanum r2_ptr;
mpa_word_t n_inv;
uint32_t m[];
} mpa_fmm_context_base;
typedef mpa_fmm_context_base *mpa_fmm_context;
typedef struct mpa_scratch_mem_struct {
struct mempool *pool;
uint32_t bn_bits; /* default size of a temporary variables */
} mpa_scratch_mem_base;
typedef mpa_scratch_mem_base *mpa_scratch_mem;
/*************************************************************
*
* EXPORTED VARIABLES
*
*************************************************************/
/*************************************************************
*
* MACROS
*
*************************************************************/
#define MPA_STRING_MODE_HEX_UC 16
#define MPA_STRING_MODE_HEX_LC 17
#define MPA_EVEN_PARITY 0
#define MPA_ODD_PARITY 1
/*! Returns true if the mpanum 'a' is even (zero included) */
#define mpa_is_even(a) (mpa_parity((a)) == MPA_EVEN_PARITY)
/*! Returns true if the mpanum 'a' is odd */
#define mpa_is_odd(a) (mpa_parity((a)) == MPA_ODD_PARITY)
/* Short hand for setting the value of 'a' to the value of 'b' */
#define mpa_set(a, b) mpa_copy((a), (b))
/* */
/* Define how to convert between sizes given in uint32_t and mpa_word_t */
/* */
#define ASIZE_TO_U32(x) (((sizeof(mpa_word_t) * (x)) + 3) / 4)
#define U32_TO_ASIZE(x) \
((mpa_asize_t)(((4 * (x)) + (sizeof(mpa_word_t) - 1)) / \
sizeof(mpa_word_t)))
/*************************************************************
*
* STATIC MEMORY MODE DEFINES
*
*************************************************************/
/*
* The number of extra uint32_t in the internal representation.
* This is used in the static memory mode.
* It is chosen to be complient with the requirments of GlobalPlatform.
*/
#define MPA_NUMBASE_METADATA_SIZE_IN_U32 2
#define MPA_SCRATCHMEM_METADATA_SIZE_IN_U32 (sizeof(mpa_scratch_mem_base)/ 4)
/*
* The size (in uint32_t) of the constituent variables
* of mpa_fmm_context apart from m[]
*/
#define MPA_FMM_CONTEXT_METADATA_SIZE_IN_U32 (sizeof(mpa_fmm_context_base)/4)
/*
* This macro returns the size of the complete mpa_num_base struct that
* can hold n-bits integers. This is used in the static memory mode.
*/
#define mpa_StaticVarSizeInU32(n) \
((((n)+31)/32) + MPA_NUMBASE_METADATA_SIZE_IN_U32)
/*
*
*/
#define mpa_StaticTempVarSizeInU32(max_bits) \
(2 * mpa_StaticVarSizeInU32((max_bits)) - \
MPA_NUMBASE_METADATA_SIZE_IN_U32)
/*
*
*/
#define mpa_scratch_mem_size_in_U32(nr_temp_vars, max_bits) \
((nr_temp_vars) * (mpa_StaticTempVarSizeInU32((max_bits)) + \
sizeof(struct mempool_item) / sizeof(uint32_t)))
/*
*
*/
#define mpa_fmm_context_size_in_U32(n) \
(2 * (mpa_StaticVarSizeInU32((n)) + 2) + \
MPA_FMM_CONTEXT_METADATA_SIZE_IN_U32)
/*************************************************************
*
* FUNCTION PROTOTYPES
*
* All externally available functions from this lib.
*
*************************************************************/
/*
* From mpa_init.c
*/
/*
* mpa_init_static
* Initiate a mpanum to hold an integer of a certain size.
* The parameter 'len' is the return value of the macro
* mpa_StaticVarSizeInU32 called with the max bit size as parameter.
*
* \param src The mpanum to be initialized
* \param len The allocated size in uint32_t of src
*/
MPALIB_EXPORT void mpa_init_static(mpanum src, uint32_t len);
MPALIB_EXPORT void mpa_init_static_fmm_context(mpa_fmm_context_base *context,
uint32_t len);
/*
* From mpa_addsub.c
*/
MPALIB_EXPORT void mpa_add(mpanum dest, const mpanum op1, const mpanum op2,
mpa_scratch_mem pool);
MPALIB_EXPORT void mpa_sub(mpanum dest, const mpanum op1, const mpanum op2,
mpa_scratch_mem pool);
MPALIB_EXPORT void mpa_add_word(mpanum dest, const mpanum op1, mpa_word_t op2,
mpa_scratch_mem pool);
MPALIB_EXPORT void mpa_sub_word(mpanum dest, const mpanum op1, mpa_word_t op2,
mpa_scratch_mem pool);
MPALIB_EXPORT void mpa_neg(mpanum dest, const mpanum src);
/*
* From mpa_mul.c
*/
MPALIB_EXPORT void mpa_mul(mpanum dest, const mpanum op1, const mpanum op2,
mpa_scratch_mem pool);
MPALIB_EXPORT void mpa_mul_word(mpanum dest, const mpanum op1, mpa_word_t op2,
mpa_scratch_mem pool);
/*
* From mpa_div.c
*/
MPALIB_EXPORT void mpa_div(mpanum q, mpanum r,
const mpanum op1, const mpanum op2,
mpa_scratch_mem pool);
/*
* From mpa_modulus.c
*/
MPALIB_EXPORT void mpa_mod(mpanum dest, const mpanum op, const mpanum n,
mpa_scratch_mem pool);
MPALIB_EXPORT void mpa_add_mod(mpanum dest, const mpanum op1, const mpanum op2,
const mpanum n, mpa_scratch_mem pool);
MPALIB_EXPORT void mpa_sub_mod(mpanum dest, const mpanum op1, const mpanum op2,
const mpanum n, mpa_scratch_mem pool);
MPALIB_EXPORT void mpa_mul_mod(mpanum dest, const mpanum op1, const mpanum op2,
const mpanum n, mpa_scratch_mem pool);
MPALIB_EXPORT int mpa_inv_mod(mpanum dest, const mpanum op, const mpanum n,
mpa_scratch_mem pool);
/*
* From mpa_cmp.c
*/
MPALIB_EXPORT int32_t mpa_cmp(const mpanum op1, const mpanum op2);
MPALIB_EXPORT int32_t mpa_cmp_short(const mpanum op1, int32_t op2);
/*
* From mpa_conv.c
*/
MPALIB_EXPORT void mpa_set_S32(mpanum dest, int32_t short_val);
MPALIB_EXPORT int32_t mpa_get_S32(int32_t *dest, mpanum src);
MPALIB_EXPORT void mpa_set_word(mpanum dest, mpa_word_t src);
MPALIB_EXPORT mpa_word_t mpa_get_word(mpanum src);
/*
* From mpa_shift.c
*/
MPALIB_EXPORT void mpa_shift_left(mpanum dest, const mpanum src,
mpa_word_t steps);
MPALIB_EXPORT void mpa_shift_right(mpanum dest, const mpanum src,
mpa_word_t steps);
/*
* From mpa_gcd.c
*/
MPALIB_EXPORT void mpa_gcd(mpanum dest, const mpanum src1, const mpanum src2,
mpa_scratch_mem pool);
MPALIB_EXPORT void mpa_extended_gcd(mpanum gcd, mpanum dest1, mpanum dest2,
const mpanum src1, const mpanum src2,
mpa_scratch_mem pool);
/*
* From mpa_io.c
*/
MPALIB_EXPORT int mpa_get_str_size(void);
MPALIB_EXPORT int mpa_set_str(mpanum dest, const char *digitstr);
MPALIB_EXPORT char *mpa_get_str(char *str, int mode, const mpanum n);
MPALIB_EXPORT int mpa_set_oct_str(mpanum dest, const uint8_t *buffer,
size_t buffer_len, bool negative);
MPALIB_EXPORT int mpa_get_oct_str(uint8_t *buffer, size_t *buffer_len,
const mpanum n);
/*
* From mpa_expmod.c
*/
MPALIB_EXPORT void mpa_exp_mod(mpanum dest, const mpanum op1, const mpanum op2,
const mpanum n, const mpanum r_modn,
const mpanum r2_modn, const mpa_word_t n_inv,
mpa_scratch_mem pool);
/*
* From mpa_misc.c
*/
MPALIB_EXPORT void mpa_wipe(mpanum src);
MPALIB_EXPORT void mpa_copy(mpanum dest, const mpanum src);
MPALIB_EXPORT void mpa_abs(mpanum dest, const mpanum src);
MPALIB_EXPORT int mpa_highest_bit_index(const mpanum src);
MPALIB_EXPORT uint32_t mpa_get_bit(const mpanum src, uint32_t idx);
MPALIB_EXPORT int mpa_can_hold(mpanum dest, const mpanum src);
MPALIB_EXPORT int mpa_parity(const mpanum src);
MPALIB_EXPORT mpanum mpa_constant_one(void);
/*
* From mpa_Random.c
*/
MPALIB_EXPORT void mpa_get_random(mpanum dest, mpanum limit);
/*
* Clear and stores "size" random digits in dest. If the requested size is
* greater than what mpanum dest can hold, then this will return with size zero.
* If the caller needs more random data, then he needs to reallocate the mpanum
* used.
*
* @dest mpanum to store the random data
* @size the number of random digits to get
*
* @return the number of successfully generated random digits
*/
MPALIB_EXPORT int mpa_get_random_digits(mpanum dest, mpa_usize_t size);
/*
* From mpa_montgomery.c
*/
MPALIB_EXPORT int mpa_compute_fmm_context(const mpanum modulus, mpanum r_modn,
mpanum r2_modn, mpa_word_t *n_inv,
mpa_scratch_mem pool);
MPALIB_EXPORT void mpa_montgomery_mul(mpanum dest, mpanum op1, mpanum op2,
mpanum n, mpa_word_t n_inv,
mpa_scratch_mem pool);
/*
* From mpa_mem_static.c
*/
MPALIB_EXPORT mpanum mpa_alloc_static_temp_var(mpanum *var,
mpa_scratch_mem pool);
MPALIB_EXPORT mpanum mpa_alloc_static_temp_var_size(int size_bits,
mpanum *var,
mpa_scratch_mem pool);
MPALIB_EXPORT void mpa_free_static_temp_var(mpanum *var, mpa_scratch_mem pool);
/*
* From mpa_primetest.c
*/
MPALIB_EXPORT int mpa_is_prob_prime(mpanum n, int conf_level,
mpa_scratch_mem pool);
#endif /* include guard */