23 #ifndef CRYPTO_BIGNUMBERUTIL_h
24 #define CRYPTO_BIGNUMBERUTIL_h
30 #if defined(__AVR__) || defined(ESP8266)
33 #define BIGNUMBER_LIMB_8BIT 0
34 #define BIGNUMBER_LIMB_16BIT 1
35 #define BIGNUMBER_LIMB_32BIT 0
36 #define BIGNUMBER_LIMB_64BIT 0
37 #elif defined(__GNUC__) && __WORDSIZE == 64
39 #define BIGNUMBER_LIMB_8BIT 0
40 #define BIGNUMBER_LIMB_16BIT 0
41 #define BIGNUMBER_LIMB_32BIT 0
42 #define BIGNUMBER_LIMB_64BIT 1
45 #define BIGNUMBER_LIMB_8BIT 0
46 #define BIGNUMBER_LIMB_16BIT 0
47 #define BIGNUMBER_LIMB_32BIT 1
48 #define BIGNUMBER_LIMB_64BIT 0
52 #if BIGNUMBER_LIMB_8BIT
53 typedef uint8_t limb_t;
54 typedef int8_t slimb_t;
55 typedef uint16_t dlimb_t;
56 #elif BIGNUMBER_LIMB_16BIT
57 typedef uint16_t limb_t;
58 typedef int16_t slimb_t;
59 typedef uint32_t dlimb_t;
60 #elif BIGNUMBER_LIMB_32BIT
61 typedef uint32_t limb_t;
62 typedef int32_t slimb_t;
63 typedef uint64_t dlimb_t;
64 #elif BIGNUMBER_LIMB_64BIT
65 typedef uint64_t limb_t;
66 typedef int64_t slimb_t;
67 typedef unsigned __int128 dlimb_t;
69 #error "limb_t must be 8, 16, 32, or 64 bits in size"
75 static void unpackLE(limb_t *limbs,
size_t count,
76 const uint8_t *bytes,
size_t len);
77 static void unpackBE(limb_t *limbs,
size_t count,
78 const uint8_t *bytes,
size_t len);
79 static void packLE(uint8_t *bytes,
size_t len,
80 const limb_t *limbs,
size_t count);
81 static void packBE(uint8_t *bytes,
size_t len,
82 const limb_t *limbs,
size_t count);
84 static limb_t
add(limb_t *result,
const limb_t *x,
85 const limb_t *y,
size_t size);
86 static limb_t
sub(limb_t *result,
const limb_t *x,
87 const limb_t *y,
size_t size);
88 static void mul(limb_t *result,
const limb_t *x,
size_t xcount,
89 const limb_t *y,
size_t ycount);
90 static void reduceQuick(limb_t *result,
const limb_t *x,
91 const limb_t *y,
size_t size);
93 static limb_t
add_P(limb_t *result,
const limb_t *x,
94 const limb_t *y,
size_t size);
95 static limb_t
sub_P(limb_t *result,
const limb_t *x,
96 const limb_t *y,
size_t size);
97 static void mul_P(limb_t *result,
const limb_t *x,
size_t xcount,
98 const limb_t *y,
size_t ycount);
100 const limb_t *y,
size_t size);
102 static limb_t
isZero(
const limb_t *x,
size_t size);
Utilities to assist with implementing big number arithmetic.
static void reduceQuick_P(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Reduces x modulo y using subtraction where y is in program memory.
static void mul(limb_t *result, const limb_t *x, size_t xcount, const limb_t *y, size_t ycount)
Multiplies two big numbers.
static void unpackLE(limb_t *limbs, size_t count, const uint8_t *bytes, size_t len)
Unpacks the little-endian byte representation of a big number into a limb array.
static void reduceQuick(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Reduces x modulo y using subtraction.
static void unpackBE(limb_t *limbs, size_t count, const uint8_t *bytes, size_t len)
Unpacks the big-endian byte representation of a big number into a limb array.
static limb_t sub(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Subtracts one big number from another.
static void packLE(uint8_t *bytes, size_t len, const limb_t *limbs, size_t count)
Packs the little-endian byte representation of a big number into a byte array.
static limb_t add(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Adds two big numbers.
static void mul_P(limb_t *result, const limb_t *x, size_t xcount, const limb_t *y, size_t ycount)
Multiplies two big numbers where one is in program memory.
static limb_t add_P(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Adds two big numbers where one of them is in program memory.
static limb_t isZero(const limb_t *x, size_t size)
Determine if a big number is zero.
static limb_t sub_P(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Subtracts one big number from another where one is in program memory.
static void packBE(uint8_t *bytes, size_t len, const limb_t *limbs, size_t count)
Packs the big-endian byte representation of a big number into a byte array.