23 #include "BigNumberUtil.h"
24 #include "utility/EndianUtil.h"
25 #include "utility/LimbUtil.h"
56 const uint8_t *bytes,
size_t len)
58 #if BIGNUMBER_LIMB_8BIT
60 memcpy(limbs, bytes, len);
61 memset(limbs + len, 0, count - len);
63 memcpy(limbs, bytes, count);
65 #elif CRYPTO_LITTLE_ENDIAN
66 count *=
sizeof(limb_t);
68 memcpy(limbs, bytes, len);
69 memset(((uint8_t *)limbs) + len, 0, count - len);
71 memcpy(limbs, bytes, count);
73 #elif BIGNUMBER_LIMB_16BIT
74 while (count > 0 && len >= 2) {
75 *limbs++ = ((limb_t)(bytes[0])) |
76 (((limb_t)(bytes[1])) << 8);
81 if (count > 0 && len == 1) {
82 *limbs++ = ((limb_t)(bytes[0]));
89 #elif BIGNUMBER_LIMB_32BIT
90 while (count > 0 && len >= 4) {
91 *limbs++ = ((limb_t)(bytes[0])) |
92 (((limb_t)(bytes[1])) << 8) |
93 (((limb_t)(bytes[2])) << 16) |
94 (((limb_t)(bytes[3])) << 24);
101 *limbs++ = ((limb_t)(bytes[0])) |
102 (((limb_t)(bytes[1])) << 8) |
103 (((limb_t)(bytes[2])) << 16);
104 }
else if (len == 2) {
105 *limbs++ = ((limb_t)(bytes[0])) |
106 (((limb_t)(bytes[1])) << 8);
107 }
else if (len == 1) {
108 *limbs++ = ((limb_t)(bytes[0]));
135 const uint8_t *bytes,
size_t len)
137 #if BIGNUMBER_LIMB_8BIT
138 while (count > 0 && len > 0) {
141 *limbs++ = bytes[len];
143 memset(limbs, 0, count);
144 #elif BIGNUMBER_LIMB_16BIT
146 while (count > 0 && len >= 2) {
150 *limbs++ = ((limb_t)(bytes[1])) |
151 (((limb_t)(bytes[0])) << 8);
153 if (count > 0 && len == 1) {
156 *limbs++ = (limb_t)(bytes[0]);
158 memset(limbs, 0, count *
sizeof(limb_t));
159 #elif BIGNUMBER_LIMB_32BIT
161 while (count > 0 && len >= 4) {
165 *limbs++ = ((limb_t)(bytes[3])) |
166 (((limb_t)(bytes[2])) << 8) |
167 (((limb_t)(bytes[1])) << 16) |
168 (((limb_t)(bytes[0])) << 24);
174 *limbs++ = ((limb_t)(bytes[2])) |
175 (((limb_t)(bytes[1])) << 8) |
176 (((limb_t)(bytes[0])) << 16);
177 }
else if (len == 2) {
180 *limbs++ = ((limb_t)(bytes[1])) |
181 (((limb_t)(bytes[0])) << 8);
182 }
else if (len == 1) {
185 *limbs++ = (limb_t)(bytes[0]);
188 memset(limbs, 0, count *
sizeof(limb_t));
209 const limb_t *limbs,
size_t count)
211 #if BIGNUMBER_LIMB_8BIT
213 memcpy(bytes, limbs, len);
215 memcpy(bytes, limbs, count);
216 memset(bytes + count, 0, len - count);
218 #elif CRYPTO_LITTLE_ENDIAN
219 count *=
sizeof(limb_t);
221 memcpy(bytes, limbs, len);
223 memcpy(bytes, limbs, count);
224 memset(bytes + count, 0, len - count);
226 #elif BIGNUMBER_LIMB_16BIT
228 while (count > 0 && len >= 2) {
230 bytes[0] = (uint8_t)word;
231 bytes[1] = (uint8_t)(word >> 8);
236 if (count > 0 && len == 1) {
237 bytes[0] = (uint8_t)(*limbs);
241 memset(bytes, 0, len);
242 #elif BIGNUMBER_LIMB_32BIT
244 while (count > 0 && len >= 4) {
246 bytes[0] = (uint8_t)word;
247 bytes[1] = (uint8_t)(word >> 8);
248 bytes[2] = (uint8_t)(word >> 16);
249 bytes[3] = (uint8_t)(word >> 24);
257 bytes[0] = (uint8_t)word;
258 bytes[1] = (uint8_t)(word >> 8);
259 bytes[2] = (uint8_t)(word >> 16);
262 }
else if (len == 2) {
264 bytes[0] = (uint8_t)word;
265 bytes[1] = (uint8_t)(word >> 8);
268 }
else if (len == 1) {
269 bytes[0] = (uint8_t)(*limbs);
274 memset(bytes, 0, len);
295 const limb_t *limbs,
size_t count)
297 #if BIGNUMBER_LIMB_8BIT
299 size_t size = len - count;
300 memset(bytes, 0, size);
303 }
else if (len < count) {
309 *bytes++ = *(--limbs);
311 #elif BIGNUMBER_LIMB_16BIT
312 size_t countBytes = count *
sizeof(limb_t);
314 if (len >= countBytes) {
315 size_t size = len - countBytes;
316 memset(bytes, 0, size);
321 count = len /
sizeof(limb_t);
324 *bytes++ = (uint8_t)(*limbs);
329 *bytes++ = (uint8_t)(word >> 8);
330 *bytes++ = (uint8_t)word;
332 #elif BIGNUMBER_LIMB_32BIT
333 size_t countBytes = count *
sizeof(limb_t);
335 if (len >= countBytes) {
336 size_t size = len - countBytes;
337 memset(bytes, 0, size);
342 count = len /
sizeof(limb_t);
344 if ((len & 3) == 3) {
346 *bytes++ = (uint8_t)(word >> 16);
347 *bytes++ = (uint8_t)(word >> 8);
348 *bytes++ = (uint8_t)word;
349 }
else if ((len & 3) == 2) {
351 *bytes++ = (uint8_t)(word >> 8);
352 *bytes++ = (uint8_t)word;
353 }
else if ((len & 3) == 1) {
354 *bytes++ = (uint8_t)(*limbs);
360 *bytes++ = (uint8_t)(word >> 24);
361 *bytes++ = (uint8_t)(word >> 16);
362 *bytes++ = (uint8_t)(word >> 8);
363 *bytes++ = (uint8_t)word;
382 const limb_t *y,
size_t size)
388 *result++ = (limb_t)carry;
392 return (limb_t)carry;
409 const limb_t *y,
size_t size)
413 borrow = ((dlimb_t)(*x++)) - (*y++) - ((borrow >> LIMB_BITS) & 0x01);
414 *result++ = (limb_t)borrow;
417 return ((limb_t)(borrow >> LIMB_BITS)) & 0x01;
433 const limb_t *y,
size_t ycount)
446 for (i = 0; i < xcount; ++i) {
447 carry += ((dlimb_t)(*xx++)) * word;
448 *rr++ = (limb_t)carry;
454 for (i = 1; i < ycount; ++i) {
459 for (j = 0; j < xcount; ++j) {
460 carry += ((dlimb_t)(*xx++)) * word;
462 *rr++ = (limb_t)carry;
485 const limb_t *y,
size_t size)
488 limb_t mask =
sub(result, x, y, size);
495 carry += (*y++ & mask);
496 *result++ = (limb_t)carry;
515 const limb_t *y,
size_t size)
520 carry += pgm_read_limb(y++);
521 *result++ = (limb_t)carry;
525 return (limb_t)carry;
542 const limb_t *y,
size_t size)
546 borrow = ((dlimb_t)(*x++)) - pgm_read_limb(y++) - ((borrow >> LIMB_BITS) & 0x01);
547 *result++ = (limb_t)borrow;
550 return ((limb_t)(borrow >> LIMB_BITS)) & 0x01;
567 const limb_t *y,
size_t ycount)
577 word = pgm_read_limb(&(y[0]));
580 for (i = 0; i < xcount; ++i) {
581 carry += ((dlimb_t)(*xx++)) * word;
582 *rr++ = (limb_t)carry;
588 for (i = 1; i < ycount; ++i) {
589 word = pgm_read_limb(&(y[i]));
593 for (j = 0; j < xcount; ++j) {
594 carry += ((dlimb_t)(*xx++)) * word;
596 *rr++ = (limb_t)carry;
621 const limb_t *y,
size_t size)
624 limb_t mask =
sub_P(result, x, y, size);
631 carry += (pgm_read_limb(y++) & mask);
632 *result++ = (limb_t)carry;
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 limb_t add(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Adds two big numbers.
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 reduceQuick(limb_t *result, const limb_t *x, const limb_t *y, size_t size)
Reduces x modulo y using subtraction.
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 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 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.
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 mul(limb_t *result, const limb_t *x, size_t xcount, const limb_t *y, size_t ycount)
Multiplies two big numbers.
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 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_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.