#ifndef WOLF_CRYPT_SP_INT_H
#define WOLF_CRYPT_SP_INT_H
#ifndef NO_LIMITS_H
#include <limits.h>
#endif
#include <wolfssl/wolfcrypt/settings.h>
#include <wolfssl/wolfcrypt/types.h>
#include <wolfssl/wolfcrypt/hash.h>
#ifdef __cplusplus
extern "C" {
#endif
#if defined(WOLFSSL_SP_ARM_ARCH) && !defined(WOLFSSL_ARM_ARCH)
#define WOLFSSL_ARM_ARCH WOLFSSL_SP_ARM_ARCH
#endif
#if defined(OPENSSL_EXTRA) && !defined(NO_ASN) && \
!defined(WOLFSSL_SP_INT_NEGATIVE)
#define WOLFSSL_SP_INT_NEGATIVE
#endif
#if UCHAR_MAX == 255
#define SP_UCHAR_BITS 8
typedef unsigned char sp_uint8;
typedef char sp_int8;
#elif UCHAR_MAX == 127
#define SP_UCHAR_BITS 7
typedef unsigned char sp_uint7;
typedef char sp_int7;
#else
#error "Size of unsigned short not detected"
#endif
#if USHRT_MAX == 65535
#define SP_USHORT_BITS 16
typedef unsigned short sp_uint16;
typedef short sp_int16;
#elif USHRT_MAX == 255
#define SP_USHORT_BITS 8
#if USHRT_MAX > UCHAR_MAX
typedef unsigned short sp_uint8;
typedef short sp_int8;
#endif
#else
#error "Size of unsigned short not detected"
#endif
#if UINT_MAX == 4294967295UL
#define SP_UINT_BITS 32
typedef unsigned int sp_uint32;
typedef int sp_int32;
#elif UINT_MAX == 65535
#define SP_UINT_BITS 16
#if UINT_MAX > USHRT_MAX
typedef unsigned int sp_uint16;
typedef int sp_int16;
#endif
#elif UINT_MAX == 255
#define SP_UINT_BITS 8
#if UINT_MAX > USHRT_MAX
typedef unsigned int sp_uint8;
typedef int sp_int8;
#endif
#else
#error "Size of unsigned int not detected"
#endif
#if defined(__WATCOMC__) && defined(__WATCOM_INT64__)
#define SP_ULLONG_BITS 64
typedef unsigned __int64 sp_uint64;
typedef __int64 sp_int64;
#else
#if defined(WOLF_C89) && !defined(NO_64BIT) && \
ULONG_MAX == 18446744073709551615UL
#define SP_ULONG_BITS 64
typedef unsigned long sp_uint64;
typedef long sp_int64;
#elif !defined(WOLF_C89) && !defined(NO_64BIT) && \
ULONG_MAX == 18446744073709551615ULL && \
\
4294967295UL != 18446744073709551615ULL
#define SP_ULONG_BITS 64
typedef unsigned long sp_uint64;
typedef long sp_int64;
#elif ULONG_MAX == 4294967295UL
#define SP_ULONG_BITS 32
#if ULONG_MAX > UINT_MAX
typedef unsigned long sp_uint32;
typedef long sp_int32;
#endif
#elif ULONG_MAX == 65535
#define SP_ULONG_BITS 16
#if ULONG_MAX > UINT_MAX
typedef unsigned long sp_uint16;
typedef long sp_int16;
#endif
#else
#error "Size of unsigned long not detected"
#endif
#ifdef ULLONG_MAX
#if defined(WOLF_C89) && ULLONG_MAX == 18446744073709551615UL
#define SP_ULLONG_BITS 64
#if SP_ULLONG_BITS > SP_ULONG_BITS
typedef unsigned long long sp_uint64;
typedef long long sp_int64;
#endif
#elif !defined(WOLF_C89) && ULLONG_MAX == 18446744073709551615ULL
#define SP_ULLONG_BITS 64
#if SP_ULLONG_BITS > SP_ULONG_BITS
typedef unsigned long long sp_uint64;
typedef long long sp_int64;
#endif
#elif ULLONG_MAX == 4294967295UL
#define SP_ULLONG_BITS 32
#if SP_ULLONG_BITS > SP_ULONG_BITS
typedef unsigned long long sp_uint32;
typedef long long sp_int32;
#endif
#elif ULLONG_MAX == 65535
#define SP_ULLONG_BITS 16
#if SP_ULLONG_BITS > SP_ULONG_BITS
typedef unsigned long long sp_uint16;
typedef long long sp_int16;
#endif
#else
#error "Size of unsigned long long not detected"
#endif
#elif (SP_ULONG_BITS == 32) && !defined(NO_64BIT)
#define SP_ULLONG_BITS 64
typedef unsigned long long sp_uint64;
typedef long long sp_int64;
#else
#define SP_ULLONG_BITS 0
#endif
#endif
#ifdef WOLFSSL_SP_DIV_32
#define WOLFSSL_SP_DIV_WORD_HALF
#endif
#if !defined(WOLFSSL_SP_ASM) && ( \
defined(WOLFSSL_SP_X86_64_ASM) || defined(WOLFSSL_SP_ARM32_ASM) || \
defined(WOLFSSL_SP_ARM64_ASM) || defined(WOLFSSL_SP_ARM_THUMB_ASM) || \
defined(WOLFSSL_SP_ARM_CORTEX_M_ASM))
#define WOLFSSL_SP_ASM
#endif
#ifdef SP_WORD_SIZE
#elif defined(WOLFSSL_DSP_BUILD)
#define SP_WORD_SIZE 32
#elif defined(WOLFSSL_SP_X86_64) && !defined(WOLFSSL_SP_X86_64_ASM) && \
!defined(HAVE___UINT128_T)
#define SP_WORD_SIZE 32
#elif defined(WOLFSSL_SP_X86_64_ASM) || defined(WOLFSSL_SP_X86_64)
#if SP_ULONG_BITS == 64 || SP_ULLONG_BITS == 64
#define SP_WORD_SIZE 64
#ifndef HAVE_INTEL_AVX1
#define HAVE_INTEL_AVX1
#endif
#if !defined(NO_AVX2_SUPPORT) && !defined(HAVE_INTEL_AVX2)
#define HAVE_INTEL_AVX2
#endif
#elif SP_ULONG_BITS == 32
#define SP_WORD_SIZE 32
#undef WOLFSSL_SP_ASM
#elif SP_ULONG_BITS == 16
#define SP_WORD_SIZE 16
#undef WOLFSSL_SP_ASM
#endif
#elif defined(WOLFSSL_SP_X86)
#define SP_WORD_SIZE 32
#elif defined(WOLFSSL_SP_ARM64_ASM) || defined(WOLFSSL_SP_ARM64)
#define SP_WORD_SIZE 64
#elif defined(WOLFSSL_SP_ARM32_ASM) || defined(WOLFSSL_SP_ARM32)
#define SP_WORD_SIZE 32
#elif defined(WOLFSSL_SP_ARM_THUMB_ASM) || defined(WOLFSSL_SP_ARM_THUMB)
#define SP_WORD_SIZE 32
#elif defined(WOLFSSL_SP_PPC)
#define SP_WORD_SIZE 32
#elif defined(WOLFSSL_SP_PPC64)
#define SP_WORD_SIZE 64
#elif defined(WOLFSSL_SP_MIPS)
#define SP_WORD_SIZE 32
#elif defined(WOLFSSL_SP_MIPS64)
#define SP_WORD_SIZE 64
#elif defined(WOLFSSL_SP_RISCV32)
#define SP_WORD_SIZE 32
#elif defined(WOLFSSL_SP_RISCV64)
#define SP_WORD_SIZE 64
#elif defined(WOLFSSL_SP_S390X)
#define SP_WORD_SIZE 64
#endif
#ifndef SP_WORD_SIZE
#ifdef NO_64BIT
#define SP_WORD_SIZE 16
#elif !defined(HAVE___UINT128_T) || defined(_WIN32)
#define SP_WORD_SIZE 32
#else
#define SP_WORD_SIZE 64
#endif
#endif
#if defined(HAVE___UINT128_T) && !defined(NO_INT128)
#ifdef __SIZEOF_INT128__
typedef __uint128_t sp_uint128;
typedef __int128_t sp_int128;
#else
typedef unsigned long sp_uint128 __attribute__ ((mode(TI)));
typedef long sp_int128 __attribute__ ((mode(TI)));
#endif
#ifndef WOLFSSL_UINT128_T_DEFINED
#ifdef __SIZEOF_INT128__
typedef __uint128_t uint128_t;
typedef __int128_t int128_t;
#else
typedef unsigned long uint128_t __attribute__ ((mode(TI)));
typedef long int128_t __attribute__ ((mode(TI)));
#endif
#define WOLFSSL_UINT128_T_DEFINED
#endif
#endif
#if SP_WORD_SIZE == 8
#define SP_WORD_SIZEOF 1
typedef sp_uint8 sp_int_digit;
typedef sp_int8 sp_int_sdigit;
typedef sp_uint16 sp_int_word;
typedef sp_int16 sp_int_sword;
#define SP_MASK 0xffU
#elif SP_WORD_SIZE == 16
#define SP_WORD_SIZEOF 2
typedef sp_uint16 sp_int_digit;
typedef sp_int16 sp_int_sdigit;
typedef sp_uint32 sp_int_word;
typedef sp_int32 sp_int_sword;
#define SP_MASK 0xffffU
#elif SP_WORD_SIZE == 32
#define SP_WORD_SIZEOF 4
typedef sp_uint32 sp_int_digit;
typedef sp_int32 sp_int_sdigit;
typedef sp_uint64 sp_int_word;
typedef sp_int64 sp_int_sword;
#define SP_MASK 0xffffffffU
#elif SP_WORD_SIZE == 64
#define SP_WORD_SIZEOF 8
typedef sp_uint64 sp_int_digit;
typedef sp_int64 sp_int_sdigit;
#if (defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)) && \
!defined(_WIN64) && defined(WOLFSSL_UINT128_T_DEFINED)
typedef sp_uint128 sp_int_word;
typedef sp_int128 sp_int_sword;
#endif
#define SP_MASK 0xffffffffffffffffUL
#else
#error Word size not defined
#endif
#ifndef WOLFSSL_SP_ASM
#if SP_WORD_SIZE == 8
typedef sp_int8 sp_digit;
#elif SP_WORD_SIZE == 16
typedef sp_int16 sp_digit;
#elif SP_WORD_SIZE == 32
typedef sp_int32 sp_digit;
#elif SP_WORD_SIZE == 64
typedef sp_int64 sp_digit;
#endif
#else
#if SP_WORD_SIZE == 8
typedef sp_uint8 sp_digit;
#elif SP_WORD_SIZE == 16
typedef sp_uint16 sp_digit;
#elif SP_WORD_SIZE == 32
typedef sp_uint32 sp_digit;
#elif SP_WORD_SIZE == 64
typedef sp_uint64 sp_digit;
#endif
#endif
#define SP_HALF_SIZE (SP_WORD_SIZE / 2)
#define SP_HALF_MAX (((sp_digit)1 << SP_HALF_SIZE) - 1)
#define SP_DIGIT_MAX SP_MASK
#if SP_WORD_SIZE == 8
#define SP_WORD_SHIFT 3
#elif SP_WORD_SIZE == 16
#define SP_WORD_SHIFT 4
#elif SP_WORD_SIZE == 32
#define SP_WORD_SHIFT 5
#elif SP_WORD_SIZE == 64
#define SP_WORD_SHIFT 6
#endif
#define SP_WORD_MASK (SP_WORD_SIZE - 1)
#if SP_WORD_SIZE == 64
#if SP_ULONG_BITS == 64
#define SP_PRINT_FMT "%016lx"
#else
#define SP_PRINT_FMT "%016llx"
#endif
#elif SP_WORD_SIZE == 32
#if SP_UINT_BITS == 32
#define SP_PRINT_FMT "%08x"
#else
#define SP_PRINT_FMT "%08lx"
#endif
#elif SP_WORD_SIZE == 16
#define SP_PRINT_FMT "%04x"
#elif SP_WORD_SIZE == 8
#define SP_PRINT_FMT "%02x"
#endif
#if defined(WOLFSSL_HAVE_SP_ECC) && defined(WOLFSSL_SP_NONBLOCK)
typedef struct sp_ecc_ctx {
#ifdef WOLFSSL_SP_521
XALIGNED(4) byte data[66*80];
#elif defined(WOLFSSL_SP_384)
XALIGNED(4) byte data[48*80];
#else
XALIGNED(4) byte data[32*80];
#endif
} sp_ecc_ctx_t;
#endif
#if defined(WOLFSSL_SP_MATH) || defined(WOLFSSL_SP_MATH_ALL)
#include <wolfssl/wolfcrypt/random.h>
#ifndef SP_INT_BITS
#ifdef SP_INT_DIGITS
#define SP_INT_BITS (((SP_INT_DIGITS - 1) * SP_WORD_SIZE) / 2)
#else
#ifdef WOLFSSL_MYSQL_COMPATIBLE
#define SP_INT_BITS 8192
#elif !defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_HAVE_SP_DH) && \
!defined(WOLFSSL_HAVE_SP_ECC)
#if !defined(NO_RSA) || !defined(NO_DH) || !defined(NO_DSA)
#if !defined(NO_DH) && defined(HAVE_FFDHE_8192)
#define SP_INT_BITS 8192
#elif !defined(NO_DH) && defined(HAVE_FFDHE_6144)
#define SP_INT_BITS 6144
#elif !defined(NO_DH) && defined(HAVE_FFDHE_4096)
#define SP_INT_BITS 4096
#else
#define SP_INT_BITS 3072
#endif
#elif defined(WOLFCRYPT_HAVE_SAKKE)
#define SP_INT_BITS 1024
#elif defined(HAVE_ECC)
#define SP_INT_BITS 521
#elif !defined(NO_PWDBASED) && defined(HAVE_PKCS12)
#define SP_INT_BITS (64 * 8)
#else
#define SP_INT_BITS 128
#endif
#elif !defined(WOLFSSL_HAVE_SP_RSA) && !defined(WOLFSSL_HAVE_SP_DH)
#if defined(WOLFCRYPT_HAVE_SAKKE)
#define SP_INT_BITS 1024
#elif defined(WOLFSSL_SP_521) || defined(WOLFSSL_SP_MATH_ALL)
#define SP_INT_BITS 521
#elif defined(WOLFSSL_SP_384)
#define SP_INT_BITS 384
#else
#define SP_INT_BITS 256
#endif
#elif defined(WOLFSSL_SP_4096)
#define SP_INT_BITS 4096
#elif !defined(WOLFSSL_SP_NO_3072) || defined(WOLFSSL_SP_MATH_ALL)
#define SP_INT_BITS 3072
#else
#define SP_INT_BITS 2048
#endif
#endif
#endif
#ifndef SP_INT_DIGITS
#define SP_INT_DIGITS \
(((SP_INT_BITS + SP_WORD_SIZE - 1) / SP_WORD_SIZE) * 2 + 1)
#endif
#ifndef SP_INT_MAX_BITS
#define SP_INT_MAX_BITS (SP_INT_DIGITS * SP_WORD_SIZE)
#endif
#if SP_WORD_SIZE < 32
#define SP_MUL_SQR_DIGITS (SP_INT_MAX_BITS / 2 / SP_WORD_SIZE)
#define SP_MUL_SQR_MAX_PARTIAL \
(SP_MUL_SQR_DIGITS * ((1 << SP_WORD_SIZE) - 1))
#define SP_INT_WORD_MAX ((1 << (SP_WORD_SIZE * 2)) - 1)
#if SP_MUL_SQR_MAX_PARTIAL > SP_INT_WORD_MAX
#define SP_WORD_OVERFLOW
#endif
#endif
#ifndef NO_FILESYSTEM
#ifndef WOLFSSL_SP_INT_NEGATIVE
#define sp_print(a, s) \
do { \
int ii; \
fprintf(stderr, "%s=0x0", s); \
for (ii = (a)->used-1; ii >= 0; ii--) { \
fprintf(stderr, SP_PRINT_FMT, (a)->dp[ii]); \
} \
fprintf(stderr, "\n"); \
} \
while (0)
#else
#define sp_print(a, s) \
do { \
int ii; \
fprintf(stderr, "%s=0x", s); \
if ((a)->sign == MP_NEG) { \
fprintf(stderr, "-"); \
} \
fprintf(stderr, "0"); \
for (ii = (a)->used-1; ii >= 0; ii--) { \
fprintf(stderr, SP_PRINT_FMT, (a)->dp[ii]); \
} \
fprintf(stderr, "\n"); \
} \
while (0)
#endif
#define sp_print_digit(a, s) \
do { \
fprintf(stderr, "%s=0x0", s); \
fprintf(stderr, SP_PRINT_FMT, a); \
fprintf(stderr, "\n"); \
} \
while (0)
#define sp_print_int(a, s) \
do { \
fprintf(stderr, "%s=0x0%x\n", s, a); \
} \
while (0)
#else
#define sp_print(a, s) WC_DO_NOTHING
#define sp_print_digit(a, s) WC_DO_NOTHING
#define sp_print_int(a, s) WC_DO_NOTHING
#endif
#define sp_isodd(a) (((a)->used != 0) && ((a)->dp[0] & 1))
#define sp_iseven(a) (((a)->used != 0) && (((a)->dp[0] & 1) == 0))
#define sp_iszero(a) ((a)->used == 0)
#ifndef WOLFSSL_SP_INT_NEGATIVE
#define sp_isone(a) (((a)->used == 1) && ((a)->dp[0] == 1))
#else
#define sp_isone(a) \
(((a)->used == 1) && ((a)->dp[0] == 1) && ((a)->sign == MP_ZPOS))
#endif
#ifndef WOLFSSL_SP_INT_NEGATIVE
#define sp_isword(a, d) \
((((d) == 0) && sp_iszero(a)) || (((a)->used == 1) && ((a)->dp[0] == (d))))
#else
#define sp_isword(a, d) \
((((d) == 0) && sp_iszero(a)) || \
(((a)->used == 1) && ((a)->dp[0] == (d)) && ((a)->sign == MP_ZPOS)))
#endif
#ifndef WOLFSSL_SP_INT_NEGATIVE
#define sp_abs(a, b) sp_copy(a, b)
#define sp_isneg(a) (0)
#define sp_setneg(a) WC_DO_NOTHING
#else
#define sp_isneg(a) ((a)->sign == MP_NEG)
#define sp_setneg(a) ((a)->sign = MP_NEG)
#endif
#define sp_bitsused(a) ((a)->used * SP_WORD_SIZE)
#define sp_clamp(a) \
do { \
int ii; \
if ((a)->used > 0) { \
for (ii = (int)(a)->used - 1; ii >= 0; ii--) { \
if ((a)->dp[ii] != 0) { \
break; \
} \
} \
(a)->used = (wc_mp_size_t)(ii + 1); \
} \
} while (0)
#define CheckFastMathSettings() (SP_WORD_SIZE == CheckRunTimeFastMath())
#define MP_NO 0
#define MP_YES 1
#ifdef WOLFSSL_SP_INT_NEGATIVE
#define MP_ZPOS 0
#define MP_NEG 1
#endif
#define MP_RADIX_DEC 10
#define MP_RADIX_HEX 16
#define MP_GT 1
#define MP_EQ 0
#define MP_LT (-1)
#define MP_OKAY 0
#define FP_WOULDBLOCK MP_WOULDBLOCK
#define MP_RANGE MP_NOT_INF
#ifdef USE_FAST_MATH
#define FP_MEM MP_MEM
#endif
#define DIGIT_BIT SP_WORD_SIZE
#define MP_MASK SP_MASK
#ifdef MP_LOW_MEM
#define WOLFSSL_SP_LOW_MEM
#endif
#define MP_INT_SIZEOF(cnt) \
(sizeof(sp_int_minimal) + (((cnt) <= 1) ? 0 : ((size_t)((cnt) - 1))) * \
sizeof(sp_int_digit))
#define MP_INT_NEXT(t, cnt) \
(sp_int*)(((byte*)(t)) + MP_INT_SIZEOF(cnt))
#define MP_INT_SIZEOF_DIGITS(cnt) (MP_INT_SIZEOF(cnt) / sizeof(sp_int_digit))
#define MP_BITS_CNT(bits) \
((unsigned int)(((((bits) + SP_WORD_SIZE - 1) / SP_WORD_SIZE) * 2 + 1)))
#if !defined(WOLFSSL_SP_NO_DYN_STACK) && defined(__STDC_VERSION__) && \
(__STDC_VERSION__ >= 199901L) && \
(defined(WOLFSSL_SP_NO_MALLOC) || \
!(defined(WOLFSSL_SMALL_STACK) || defined(SP_ALLOC)))
#define WOLFSSL_SP_DYN_STACK
#endif
#ifdef WOLFSSL_SMALL_STACK
#define DECL_MP_INT_SIZE_DYN(name, bits, max) \
sp_int* name = NULL
#define DECL_MP_INT_SIZE(name, bits) \
sp_int* name = NULL
#define NEW_MP_INT_SIZE(name, bits, heap, type) \
do { \
(name) = (mp_int*)XMALLOC(MP_INT_SIZEOF(MP_BITS_CNT(bits)), heap, type); \
if ((name) != NULL) { \
XMEMSET(name, 0, MP_INT_SIZEOF(MP_BITS_CNT(bits))); \
} \
} \
while (0)
#define FREE_MP_INT_SIZE(name, heap, type) \
XFREE(name, heap, type)
#define MP_INT_SIZE sp_int
#define MP_INT_SIZE_CHECK_NULL
#else
#ifdef WOLFSSL_SP_DYN_STACK
#define DECL_MP_INT_SIZE_DYN(name, bits, max) \
sp_int_digit name##d[MP_INT_SIZEOF_DIGITS(MP_BITS_CNT(bits))]; \
sp_int* (name) = (sp_int*)name##d
#elif defined(__cplusplus)
#define DECL_MP_INT_SIZE_DYN(name, bits, max) \
sp_int_digit name##d[MP_INT_SIZEOF_DIGITS(MP_BITS_CNT(max))]; \
sp_int* name = (sp_int*)name##d
#else
#define DECL_MP_INT_SIZE_DYN(name, bits, max) \
sp_int_digit name##d[MP_INT_SIZEOF_DIGITS(MP_BITS_CNT(max))]; \
sp_int* (name) = (sp_int*)name##d
#endif
#define DECL_MP_INT_SIZE(name, bits) \
sp_int_digit name##d[MP_INT_SIZEOF_DIGITS(MP_BITS_CNT(bits))]; \
sp_int* (name) = (sp_int*)name##d
#define NEW_MP_INT_SIZE(name, bits, heap, type) \
XMEMSET(name, 0, MP_INT_SIZEOF(MP_BITS_CNT(bits)))
#define FREE_MP_INT_SIZE(name, heap, type) WC_DO_NOTHING
#define MP_INT_SIZE sp_int_minimal
#endif
#define INIT_MP_INT_SIZE(name, bits) \
mp_init_size(name, MP_BITS_CNT(bits))
#ifdef HAVE_WOLF_BIGINT
typedef struct WC_BIGINT {
byte* buf;
word32 len;
void* heap;
} WC_BIGINT;
#define WOLF_BIGINT_DEFINED
#endif
#if SP_INT_DIGITS < (65536 / SP_WORD_SIZEOF)
typedef word16 sp_size_t;
#else
typedef unsigned int sp_size_t;
#endif
#define wc_mp_size_t sp_size_t
#ifdef WOLFSSL_SP_INT_NEGATIVE
typedef sp_uint8 sp_sign_t;
#define wc_mp_sign_t sp_sign_t
#endif
typedef struct sp_int {
sp_size_t used;
sp_size_t size;
#ifdef WOLFSSL_SP_INT_NEGATIVE
sp_sign_t sign;
#endif
#ifdef HAVE_WOLF_BIGINT
struct WC_BIGINT raw;
#endif
XALIGNED(SP_WORD_SIZEOF) sp_int_digit dp[SP_INT_DIGITS];
} sp_int;
typedef struct sp_int_minimal {
sp_size_t used;
sp_size_t size;
#ifdef WOLFSSL_SP_INT_NEGATIVE
sp_sign_t sign;
#endif
#ifdef HAVE_WOLF_BIGINT
struct WC_BIGINT raw;
#endif
XALIGNED(SP_WORD_SIZEOF) sp_int_digit dp[1];
} sp_int_minimal;
wc_static_assert(sizeof(struct sp_int) % sizeof(sp_int_digit) == 0);
wc_static_assert(sizeof(struct sp_int_minimal) % sizeof(sp_int_digit) == 0);
typedef sp_int mp_int;
typedef sp_int_digit mp_digit;
#include <wolfssl/wolfcrypt/wolfmath.h>
#ifdef WOLFSSL_API_PREFIX_MAP
#define sp_init wc_sp_init
#define sp_init_size wc_sp_init_size
#define sp_init_multi wc_sp_init_multi
#define sp_free wc_sp_free
#define sp_grow wc_sp_grow
#define sp_zero wc_sp_zero
#define sp_clear wc_sp_clear
#define sp_forcezero wc_sp_forcezero
#define sp_init_copy wc_sp_init_copy
#define sp_copy wc_sp_copy
#define sp_exch wc_sp_exch
#define sp_cond_swap_ct wc_sp_cond_swap_ct
#define sp_cond_swap_ct_ex wc_sp_cond_swap_ct_ex
#ifdef WOLFSSL_SP_INT_NEGATIVE
#define sp_abs wc_sp_abs
#endif
#ifdef WOLFSSL_SP_MATH_ALL
#define sp_cmp_mag wc_sp_cmp_mag
#endif
#define sp_cmp wc_sp_cmp
#define sp_cmp_ct wc_sp_cmp_ct
#define sp_is_bit_set wc_sp_is_bit_set
#define sp_count_bits wc_sp_count_bits
#if defined(HAVE_ECC) && defined(HAVE_COMP_KEY)
#define sp_cnt_lsb wc_sp_cnt_lsb
#endif
#define sp_leading_bit wc_sp_leading_bit
#define sp_set_bit wc_sp_set_bit
#define sp_2expt wc_sp_2expt
#define sp_set wc_sp_set
#define sp_set_int wc_sp_set_int
#define sp_cmp_d wc_sp_cmp_d
#define sp_add_d wc_sp_add_d
#define sp_sub_d wc_sp_sub_d
#define sp_mul_d wc_sp_mul_d
#if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \
defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \
defined(WC_MP_TO_RADIX)
#define sp_div_d wc_sp_div_d
#endif
#if defined(WOLFSSL_SP_MATH_ALL) || (defined(HAVE_ECC) && \
defined(HAVE_COMP_KEY)) || defined(OPENSSL_EXTRA)
#define sp_mod_d wc_sp_mod_d
#endif
#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC)
#define sp_div_2_mod_ct wc_sp_div_2_mod_ct
#define sp_div_2 wc_sp_div_2
#endif
#define sp_add wc_sp_add
#define sp_sub wc_sp_sub
#if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \
(!defined(WOLFSSL_SP_MATH) && defined(WOLFSSL_CUSTOM_CURVES)) || \
defined(WOLFCRYPT_HAVE_ECCSI) || defined(WOLFCRYPT_HAVE_SAKKE)
#define sp_addmod wc_sp_addmod
#endif
#if defined(WOLFSSL_SP_MATH_ALL) && (!defined(WOLFSSL_RSA_VERIFY_ONLY) || \
defined(HAVE_ECC))
#define sp_submod wc_sp_submod
#endif
#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC)
#define sp_submod_ct wc_sp_submod_ct
#define sp_addmod_ct wc_sp_addmod_ct
#endif
#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC)
#define sp_xor_ct wc_sp_xor_ct
#endif
#define sp_lshd wc_sp_lshd
#ifdef WOLFSSL_SP_MATH_ALL
#define sp_rshd wc_sp_rshd
#endif
#define sp_rshb wc_sp_rshb
#if defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_DH) || defined(HAVE_ECC) || \
(!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY) && \
!defined(WOLFSSL_RSA_PUBLIC_ONLY))
#define sp_div wc_sp_div
#endif
#define sp_mod wc_sp_mod
#define sp_mul wc_sp_mul
#define sp_mulmod wc_sp_mulmod
#define sp_invmod wc_sp_invmod
#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC)
#define sp_invmod_mont_ct wc_sp_invmod_mont_ct
#endif
#define sp_exptmod_ex wc_sp_exptmod_ex
#define sp_exptmod wc_sp_exptmod
#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH)
#define sp_exptmod_nct wc_sp_exptmod_nct
#endif
#if defined(WOLFSSL_SP_MATH_ALL) || defined(OPENSSL_ALL)
#define sp_div_2d wc_sp_div_2d
#define sp_mul_2d wc_sp_mul_2d
#endif
#if defined(WOLFSSL_SP_MATH_ALL) || defined(HAVE_ECC) || defined(OPENSSL_ALL)
#define sp_mod_2d wc_sp_mod_2d
#endif
#define sp_sqr wc_sp_sqr
#define sp_sqrmod wc_sp_sqrmod
#define sp_mont_red_ex wc_sp_mont_red_ex
#define sp_mont_setup wc_sp_mont_setup
#define sp_mont_norm wc_sp_mont_norm
#define sp_unsigned_bin_size wc_sp_unsigned_bin_size
#define sp_read_unsigned_bin wc_sp_read_unsigned_bin
#define sp_to_unsigned_bin wc_sp_to_unsigned_bin
#define sp_to_unsigned_bin_len wc_sp_to_unsigned_bin_len
#define sp_to_unsigned_bin_len_ct wc_sp_to_unsigned_bin_len_ct
#ifdef WOLFSSL_SP_MATH_ALL
#define sp_to_unsigned_bin_at_pos wc_sp_to_unsigned_bin_at_pos
#endif
#define sp_read_radix wc_sp_read_radix
#define sp_tohex wc_sp_tohex
#define sp_todecimal wc_sp_todecimal
#if defined(WOLFSSL_SP_MATH_ALL) || defined(WC_MP_TO_RADIX)
#define sp_toradix wc_sp_toradix
#define sp_radix_size wc_sp_radix_size
#endif
#define sp_rand_prime wc_sp_rand_prime
#define sp_prime_is_prime wc_sp_prime_is_prime
#define sp_prime_is_prime_ex wc_sp_prime_is_prime_ex
#if !defined(NO_RSA) || defined(WOLFSSL_KEY_GEN)
#define sp_gcd wc_sp_gcd
#endif
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
(!defined(WC_RSA_BLINDING) || defined(HAVE_FIPS) || defined(HAVE_SELFTEST))
#define sp_lcm wc_sp_lcm
#endif
#define CheckRunTimeFastMath wc_CheckRunTimeFastMath
#endif
MP_API int sp_init(sp_int* a);
MP_API int sp_init_size(sp_int* a, unsigned int size);
MP_API int sp_init_multi(sp_int* n1, sp_int* n2, sp_int* n3, sp_int* n4,
sp_int* n5, sp_int* n6);
MP_API void sp_free(sp_int* a);
MP_API int sp_grow(sp_int* a, int l);
MP_API void sp_zero(sp_int* a);
MP_API void sp_clear(sp_int* a);
MP_API void sp_forcezero(sp_int* a);
MP_API int sp_init_copy (sp_int* r, const sp_int* a);
MP_API int sp_copy(const sp_int* a, sp_int* r);
MP_API int sp_exch(sp_int* a, sp_int* b);
MP_API int sp_cond_swap_ct(sp_int* a, sp_int* b, int cnt, int swap);
MP_API int sp_cond_swap_ct_ex(sp_int* a, sp_int* b, int cnt, int swap,
sp_int* t);
#ifdef WOLFSSL_SP_INT_NEGATIVE
MP_API int sp_abs(const sp_int* a, sp_int* r);
#endif
#ifdef WOLFSSL_SP_MATH_ALL
MP_API int sp_cmp_mag(const sp_int* a, const sp_int* b);
#endif
MP_API int sp_cmp(const sp_int* a, const sp_int* b);
MP_API int sp_cmp_ct(const sp_int* a, const sp_int* b, unsigned int n);
MP_API int sp_is_bit_set(const sp_int* a, unsigned int b);
MP_API int sp_count_bits(const sp_int* a);
#if defined(HAVE_ECC) && defined(HAVE_COMP_KEY)
MP_API int sp_cnt_lsb(const sp_int* a);
#endif
MP_API int sp_leading_bit(const sp_int* a);
MP_API int sp_set_bit(sp_int* a, int i);
MP_API int sp_2expt(sp_int* a, int e);
MP_API int sp_set(sp_int* a, sp_int_digit d);
MP_API int sp_set_int(sp_int* a, unsigned long n);
MP_API int sp_cmp_d(const sp_int* a, sp_int_digit d);
MP_API int sp_add_d(const sp_int* a, sp_int_digit d, sp_int* r);
MP_API int sp_sub_d(const sp_int* a, sp_int_digit d, sp_int* r);
MP_API int sp_mul_d(const sp_int* a, sp_int_digit d, sp_int* r);
#if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \
defined(WOLFSSL_KEY_GEN) || defined(HAVE_COMP_KEY) || \
defined(WC_MP_TO_RADIX)
MP_API int sp_div_d(const sp_int* a, sp_int_digit d, sp_int* r,
sp_int_digit* rem);
#endif
#if defined(WOLFSSL_SP_MATH_ALL) || (defined(HAVE_ECC) && \
defined(HAVE_COMP_KEY)) || defined(OPENSSL_EXTRA)
MP_API int sp_mod_d(const sp_int* a, sp_int_digit d, sp_int_digit* r);
#endif
#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC)
MP_API int sp_div_2_mod_ct(const sp_int* a, const sp_int* m, sp_int* r);
MP_API int sp_div_2(const sp_int* a, sp_int* r);
#endif
MP_API int sp_add(const sp_int* a, const sp_int* b, sp_int* r);
MP_API int sp_sub(const sp_int* a, const sp_int* b, sp_int* r);
#if (defined(WOLFSSL_SP_MATH_ALL) && !defined(WOLFSSL_RSA_VERIFY_ONLY)) || \
(!defined(WOLFSSL_SP_MATH) && defined(WOLFSSL_CUSTOM_CURVES)) || \
defined(WOLFCRYPT_HAVE_ECCSI) || defined(WOLFCRYPT_HAVE_SAKKE)
MP_API int sp_addmod(const sp_int* a, const sp_int* b, const sp_int* m,
sp_int* r);
#endif
#if defined(WOLFSSL_SP_MATH_ALL) && (!defined(WOLFSSL_RSA_VERIFY_ONLY) || \
defined(HAVE_ECC))
MP_API int sp_submod(const sp_int* a, const sp_int* b, const sp_int* m,
sp_int* r);
#endif
#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC)
MP_API int sp_submod_ct(const sp_int* a, const sp_int* b, const sp_int* m,
sp_int* r);
MP_API int sp_addmod_ct(const sp_int* a, const sp_int* b, const sp_int* m,
sp_int* r);
#endif
#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC)
MP_API void sp_xor_ct(const sp_int* a, const sp_int* b, int len, sp_int* r);
#endif
MP_API int sp_lshd(sp_int* a, int s);
#ifdef WOLFSSL_SP_MATH_ALL
MP_API void sp_rshd(sp_int* a, int c);
#endif
MP_API int sp_rshb(const sp_int* a, int n, sp_int* r);
#if defined(WOLFSSL_SP_MATH_ALL) || !defined(NO_DH) || defined(HAVE_ECC) || \
(!defined(NO_RSA) && !defined(WOLFSSL_RSA_VERIFY_ONLY) && \
!defined(WOLFSSL_RSA_PUBLIC_ONLY))
MP_API int sp_div(const sp_int* a, const sp_int* d, sp_int* r, sp_int* rem);
#endif
MP_API int sp_mod(const sp_int* a, const sp_int* m, sp_int* r);
MP_API int sp_mul(const sp_int* a, const sp_int* b, sp_int* r);
MP_API int sp_mulmod(const sp_int* a, const sp_int* b, const sp_int* m,
sp_int* r);
MP_API int sp_invmod(const sp_int* a, const sp_int* m, sp_int* r);
#if defined(WOLFSSL_SP_MATH_ALL) && defined(HAVE_ECC)
MP_API int sp_invmod_mont_ct(const sp_int* a, const sp_int* m, sp_int* r,
sp_int_digit mp);
#endif
MP_API int sp_exptmod_ex(const sp_int* b, const sp_int* e, int digits,
const sp_int* m, sp_int* r);
MP_API int sp_exptmod(const sp_int* b, const sp_int* e, const sp_int* m,
sp_int* r);
#if defined(WOLFSSL_SP_MATH_ALL) || defined(WOLFSSL_HAVE_SP_DH)
MP_API int sp_exptmod_nct(const sp_int* b, const sp_int* e, const sp_int* m,
sp_int* r);
#endif
#if defined(WOLFSSL_SP_MATH_ALL) || defined(OPENSSL_ALL)
MP_API int sp_div_2d(const sp_int* a, int e, sp_int* r, sp_int* rem);
MP_API int sp_mul_2d(const sp_int* a, int e, sp_int* r);
#endif
#if defined(WOLFSSL_SP_MATH_ALL) || defined(HAVE_ECC) || defined(OPENSSL_ALL)
MP_API int sp_mod_2d(const sp_int* a, int e, sp_int* r);
#endif
MP_API int sp_sqr(const sp_int* a, sp_int* r);
MP_API int sp_sqrmod(const sp_int* a, const sp_int* m, sp_int* r);
MP_API int sp_mont_red_ex(sp_int* a, const sp_int* m, sp_int_digit mp, int ct);
#define sp_mont_red(a, m, mp) sp_mont_red_ex(a, m, mp, 0)
MP_API int sp_mont_setup(const sp_int* m, sp_int_digit* rho);
MP_API int sp_mont_norm(sp_int* norm, const sp_int* m);
MP_API int sp_unsigned_bin_size(const sp_int* a);
MP_API int sp_read_unsigned_bin(sp_int* a, const byte* in, word32 inSz);
MP_API int sp_to_unsigned_bin(const sp_int* a, byte* out);
MP_API int sp_to_unsigned_bin_len(const sp_int* a, byte* out, int outSz);
MP_API int sp_to_unsigned_bin_len_ct(const sp_int* a, byte* out, int outSz);
#ifdef WOLFSSL_SP_MATH_ALL
MP_API int sp_to_unsigned_bin_at_pos(int o, const sp_int* a,
unsigned char* out);
#endif
MP_API int sp_read_radix(sp_int* a, const char* in, int radix);
MP_API int sp_tohex(const sp_int* a, char* str);
MP_API int sp_todecimal(const sp_int* a, char* str);
#if defined(WOLFSSL_SP_MATH_ALL) || defined(WC_MP_TO_RADIX)
MP_API int sp_toradix(const sp_int* a, char* str, int radix);
MP_API int sp_radix_size(const sp_int* a, int radix, int* size);
#endif
MP_API int sp_rand_prime(sp_int* r, int len, WC_RNG* rng, void* heap);
MP_API int sp_prime_is_prime(const sp_int* a, int t, int* result);
MP_API int sp_prime_is_prime_ex(const sp_int* a, int t, int* result,
WC_RNG* rng);
#if !defined(NO_RSA) || defined(WOLFSSL_KEY_GEN)
MP_API int sp_gcd(const sp_int* a, const sp_int* b, sp_int* r);
#endif
#if !defined(NO_RSA) && defined(WOLFSSL_KEY_GEN) && \
(!defined(WC_RSA_BLINDING) || defined(HAVE_FIPS) || defined(HAVE_SELFTEST))
MP_API int sp_lcm(const sp_int* a, const sp_int* b, sp_int* r);
#endif
WOLFSSL_API word32 CheckRunTimeFastMath(void);
#ifdef WOLFSSL_CHECK_MEM_ZERO
WOLFSSL_LOCAL void sp_memzero_add(const char* name, sp_int* sp);
WOLFSSL_LOCAL void sp_memzero_check(sp_int* sp);
#endif
#define mp_mul_2(a, r) sp_mul_2d(a, 1, r)
#define mp_div_3(a, r, rem) sp_div_d(a, 3, r, rem)
#define mp_rshb(A,x) sp_rshb(A,x,A)
#define mp_is_bit_set(a,b) sp_is_bit_set(a,(unsigned int)(b))
#define mp_montgomery_reduce(a, m, mp) sp_mont_red_ex(a, m, mp, 0)
#define mp_montgomery_reduce_ct(a, m, mp) sp_mont_red_ex(a, m, mp, 1)
#define mp_montgomery_setup sp_mont_setup
#define mp_montgomery_calc_normalization sp_mont_norm
#define mp_isodd sp_isodd
#define mp_iseven sp_iseven
#define mp_iszero sp_iszero
#define mp_isone sp_isone
#define mp_isword sp_isword
#define mp_abs sp_abs
#define mp_isneg sp_isneg
#define mp_setneg sp_setneg
#define mp_bitsused sp_bitsused
#define mp_clamp sp_clamp
#define mp_init sp_init
#define mp_init_size sp_init_size
#define mp_init_multi sp_init_multi
#define mp_free sp_free
#define mp_grow sp_grow
#define mp_zero sp_zero
#define mp_clear sp_clear
#define mp_forcezero sp_forcezero
#define mp_copy sp_copy
#define mp_init_copy sp_init_copy
#define mp_exch sp_exch
#define mp_cond_swap_ct sp_cond_swap_ct
#define mp_cond_swap_ct_ex sp_cond_swap_ct_ex
#define mp_cmp_mag sp_cmp_mag
#define mp_cmp sp_cmp
#define mp_cmp_ct sp_cmp_ct
#define mp_count_bits sp_count_bits
#define mp_cnt_lsb sp_cnt_lsb
#define mp_leading_bit sp_leading_bit
#define mp_set_bit sp_set_bit
#define mp_2expt sp_2expt
#define mp_set sp_set
#define mp_set_int sp_set_int
#define mp_cmp_d sp_cmp_d
#define mp_add_d sp_add_d
#define mp_sub_d sp_sub_d
#define mp_mul_d sp_mul_d
#define mp_div_d sp_div_d
#define mp_mod_d sp_mod_d
#define mp_div_2_mod_ct sp_div_2_mod_ct
#define mp_div_2 sp_div_2
#define mp_add sp_add
#define mp_sub sp_sub
#define mp_addmod_ct sp_addmod_ct
#define mp_submod_ct sp_submod_ct
#define mp_xor_ct sp_xor_ct
#define mp_lshd sp_lshd
#define mp_rshd sp_rshd
#define mp_div sp_div
#define mp_mul sp_mul
#define mp_invmod sp_invmod
#define mp_invmod_mont_ct sp_invmod_mont_ct
#define mp_exptmod_ex sp_exptmod_ex
#define mp_exptmod_nct sp_exptmod_nct
#define mp_div_2d sp_div_2d
#define mp_mod_2d sp_mod_2d
#define mp_mul_2d sp_mul_2d
#define mp_sqr sp_sqr
#define mp_unsigned_bin_size sp_unsigned_bin_size
#define mp_read_unsigned_bin sp_read_unsigned_bin
#define mp_to_unsigned_bin sp_to_unsigned_bin
#define mp_to_unsigned_bin_len sp_to_unsigned_bin_len
#define mp_to_unsigned_bin_len_ct sp_to_unsigned_bin_len_ct
#define mp_to_unsigned_bin_at_pos sp_to_unsigned_bin_at_pos
#define mp_read_radix sp_read_radix
#define mp_tohex sp_tohex
#define mp_todecimal sp_todecimal
#define mp_toradix sp_toradix
#define mp_radix_size sp_radix_size
#define mp_rand_prime sp_rand_prime
#define mp_prime_is_prime sp_prime_is_prime
#define mp_prime_is_prime_ex sp_prime_is_prime_ex
#define mp_gcd sp_gcd
#define mp_lcm sp_lcm
#define mp_memzero_add sp_memzero_add
#define mp_memzero_check sp_memzero_check
#ifndef WOLFSSL_USE_HW_MP
#define mp_mod sp_mod
#define mp_addmod sp_addmod
#define mp_submod sp_submod
#define mp_mulmod sp_mulmod
#define mp_exptmod sp_exptmod
#define mp_sqrmod sp_sqrmod
#endif
#ifdef WOLFSSL_DEBUG_MATH
#define mp_dump(d, a, v) sp_print(a, d)
#endif
#endif
#ifdef __cplusplus
}
#endif
#endif