text
[RRG-proxmark3.git] / common / mbedtls / bignum.c
blob200ad7ca008e2ede2cf9ed7b48cc8098257f640b
1 /*
2 * Multi-precision integer library
4 * Copyright The Mbed TLS Contributors
5 * SPDX-License-Identifier: Apache-2.0
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
11 * http://www.apache.org/licenses/LICENSE-2.0
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
21 * The following sources were referenced in the design of this Multi-precision
22 * Integer library:
24 * [1] Handbook of Applied Cryptography - 1997
25 * Menezes, van Oorschot and Vanstone
27 * [2] Multi-Precision Math
28 * Tom St Denis
29 * https://github.com/libtom/libtommath/blob/develop/tommath.pdf
31 * [3] GNU Multi-Precision Arithmetic Library
32 * https://gmplib.org/manual/index.html
36 #pragma GCC diagnostic ignored "-Wunused-variable"
38 #include "common.h"
40 #if defined(MBEDTLS_BIGNUM_C)
42 #include "mbedtls/bignum.h"
43 #include "mbedtls/bn_mul.h"
44 #include "mbedtls/platform_util.h"
45 #include "mbedtls/error.h"
47 #include <string.h>
49 #if defined(MBEDTLS_PLATFORM_C)
50 #include "mbedtls/platform.h"
51 #else
52 #include <stdio.h>
53 #include <stdlib.h>
54 #define mbedtls_printf printf
55 #define mbedtls_calloc calloc
56 #define mbedtls_free free
57 #endif
59 #define MPI_VALIDATE_RET( cond ) \
60 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
61 #define MPI_VALIDATE( cond ) \
62 MBEDTLS_INTERNAL_VALIDATE( cond )
64 #define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
65 #define biL (ciL << 3) /* bits in limb */
66 #define biH (ciL << 2) /* half limb size */
68 #define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
71 * Convert between bits/chars and number of limbs
72 * Divide first in order to avoid potential overflows
74 #define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
75 #define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
77 /* Implementation that should never be optimized out by the compiler */
78 static void mbedtls_mpi_zeroize(mbedtls_mpi_uint *v, size_t n) {
79 mbedtls_platform_zeroize(v, ciL * n);
83 * Initialize one MPI
85 void mbedtls_mpi_init(mbedtls_mpi *X) {
86 MPI_VALIDATE(X != NULL);
88 X->s = 1;
89 X->n = 0;
90 X->p = NULL;
94 * Unallocate one MPI
96 void mbedtls_mpi_free(mbedtls_mpi *X) {
97 if (X == NULL)
98 return;
100 if (X->p != NULL) {
101 mbedtls_mpi_zeroize(X->p, X->n);
102 mbedtls_free(X->p);
105 X->s = 1;
106 X->n = 0;
107 X->p = NULL;
111 * Enlarge to the specified number of limbs
113 int mbedtls_mpi_grow(mbedtls_mpi *X, size_t nblimbs) {
114 mbedtls_mpi_uint *p;
115 MPI_VALIDATE_RET(X != NULL);
117 if (nblimbs > MBEDTLS_MPI_MAX_LIMBS)
118 return (MBEDTLS_ERR_MPI_ALLOC_FAILED);
120 if (X->n < nblimbs) {
121 if ((p = (mbedtls_mpi_uint *)mbedtls_calloc(nblimbs, ciL)) == NULL)
122 return (MBEDTLS_ERR_MPI_ALLOC_FAILED);
124 if (X->p != NULL) {
125 memcpy(p, X->p, X->n * ciL);
126 mbedtls_mpi_zeroize(X->p, X->n);
127 mbedtls_free(X->p);
130 X->n = nblimbs;
131 X->p = p;
134 return (0);
138 * Resize down as much as possible,
139 * while keeping at least the specified number of limbs
141 int mbedtls_mpi_shrink(mbedtls_mpi *X, size_t nblimbs) {
142 mbedtls_mpi_uint *p;
143 size_t i;
144 MPI_VALIDATE_RET(X != NULL);
146 if (nblimbs > MBEDTLS_MPI_MAX_LIMBS)
147 return (MBEDTLS_ERR_MPI_ALLOC_FAILED);
149 /* Actually resize up if there are currently fewer than nblimbs limbs. */
150 if (X->n <= nblimbs)
151 return (mbedtls_mpi_grow(X, nblimbs));
152 /* After this point, then X->n > nblimbs and in particular X->n > 0. */
154 for (i = X->n - 1; i > 0; i--)
155 if (X->p[i] != 0)
156 break;
157 i++;
159 if (i < nblimbs)
160 i = nblimbs;
162 if ((p = (mbedtls_mpi_uint *)mbedtls_calloc(i, ciL)) == NULL)
163 return (MBEDTLS_ERR_MPI_ALLOC_FAILED);
165 if (X->p != NULL) {
166 memcpy(p, X->p, i * ciL);
167 mbedtls_mpi_zeroize(X->p, X->n);
168 mbedtls_free(X->p);
171 X->n = i;
172 X->p = p;
174 return (0);
178 * Copy the contents of Y into X
180 int mbedtls_mpi_copy(mbedtls_mpi *X, const mbedtls_mpi *Y) {
181 int ret = 0;
182 size_t i;
183 MPI_VALIDATE_RET(X != NULL);
184 MPI_VALIDATE_RET(Y != NULL);
186 if (X == Y)
187 return (0);
189 if (Y->n == 0) {
190 mbedtls_mpi_free(X);
191 return (0);
194 for (i = Y->n - 1; i > 0; i--)
195 if (Y->p[i] != 0)
196 break;
197 i++;
199 X->s = Y->s;
201 if (X->n < i) {
202 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i));
203 } else {
204 memset(X->p + i, 0, (X->n - i) * ciL);
207 memcpy(X->p, Y->p, i * ciL);
209 cleanup:
211 return (ret);
215 * Swap the contents of X and Y
217 void mbedtls_mpi_swap(mbedtls_mpi *X, mbedtls_mpi *Y) {
218 mbedtls_mpi T;
219 MPI_VALIDATE(X != NULL);
220 MPI_VALIDATE(Y != NULL);
222 memcpy(&T, X, sizeof(mbedtls_mpi));
223 memcpy(X, Y, sizeof(mbedtls_mpi));
224 memcpy(Y, &T, sizeof(mbedtls_mpi));
228 * Conditionally assign dest = src, without leaking information
229 * about whether the assignment was made or not.
230 * dest and src must be arrays of limbs of size n.
231 * assign must be 0 or 1.
233 static void mpi_safe_cond_assign(size_t n,
234 mbedtls_mpi_uint *dest,
235 const mbedtls_mpi_uint *src,
236 unsigned char assign) {
237 size_t i;
238 for (i = 0; i < n; i++)
239 dest[i] = dest[i] * (1 - assign) + src[i] * assign;
243 * Conditionally assign X = Y, without leaking information
244 * about whether the assignment was made or not.
245 * (Leaking information about the respective sizes of X and Y is ok however.)
247 int mbedtls_mpi_safe_cond_assign(mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign) {
248 int ret = 0;
249 size_t i;
250 MPI_VALIDATE_RET(X != NULL);
251 MPI_VALIDATE_RET(Y != NULL);
253 /* make sure assign is 0 or 1 in a time-constant manner */
254 assign = (assign | (unsigned char) - assign) >> 7;
256 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));
258 X->s = X->s * (1 - assign) + Y->s * assign;
260 mpi_safe_cond_assign(Y->n, X->p, Y->p, assign);
262 for (i = Y->n; i < X->n; i++)
263 X->p[i] *= (1 - assign);
265 cleanup:
266 return (ret);
270 * Conditionally swap X and Y, without leaking information
271 * about whether the swap was made or not.
272 * Here it is not ok to simply swap the pointers, which whould lead to
273 * different memory access patterns when X and Y are used afterwards.
275 int mbedtls_mpi_safe_cond_swap(mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap) {
276 int ret, s;
277 size_t i;
278 mbedtls_mpi_uint tmp;
279 MPI_VALIDATE_RET(X != NULL);
280 MPI_VALIDATE_RET(Y != NULL);
282 if (X == Y)
283 return (0);
285 /* make sure swap is 0 or 1 in a time-constant manner */
286 swap = (swap | (unsigned char) - swap) >> 7;
288 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, Y->n));
289 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(Y, X->n));
291 s = X->s;
292 X->s = X->s * (1 - swap) + Y->s * swap;
293 Y->s = Y->s * (1 - swap) + s * swap;
296 for (i = 0; i < X->n; i++) {
297 tmp = X->p[i];
298 X->p[i] = X->p[i] * (1 - swap) + Y->p[i] * swap;
299 Y->p[i] = Y->p[i] * (1 - swap) + tmp * swap;
302 cleanup:
303 return (ret);
307 * Set value from integer
309 int mbedtls_mpi_lset(mbedtls_mpi *X, mbedtls_mpi_sint z) {
310 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
311 MPI_VALIDATE_RET(X != NULL);
313 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, 1));
314 memset(X->p, 0, X->n * ciL);
316 X->p[0] = (z < 0) ? -z : z;
317 X->s = (z < 0) ? -1 : 1;
319 cleanup:
321 return (ret);
325 * Get a specific bit
327 int mbedtls_mpi_get_bit(const mbedtls_mpi *X, size_t pos) {
328 MPI_VALIDATE_RET(X != NULL);
330 if (X->n * biL <= pos)
331 return (0);
333 return ((X->p[pos / biL] >> (pos % biL)) & 0x01);
336 /* Get a specific byte, without range checks. */
337 #define GET_BYTE( X, i ) \
338 ( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff )
341 * Set a bit to a specific value of 0 or 1
343 int mbedtls_mpi_set_bit(mbedtls_mpi *X, size_t pos, unsigned char val) {
344 int ret = 0;
345 size_t off = pos / biL;
346 size_t idx = pos % biL;
347 MPI_VALIDATE_RET(X != NULL);
349 if (val != 0 && val != 1)
350 return (MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
352 if (X->n * biL <= pos) {
353 if (val == 0)
354 return (0);
356 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, off + 1));
359 X->p[off] &= ~((mbedtls_mpi_uint) 0x01 << idx);
360 X->p[off] |= (mbedtls_mpi_uint) val << idx;
362 cleanup:
364 return (ret);
368 * Return the number of less significant zero-bits
370 size_t mbedtls_mpi_lsb(const mbedtls_mpi *X) {
371 size_t i, j, count = 0;
372 MBEDTLS_INTERNAL_VALIDATE_RET(X != NULL, 0);
374 for (i = 0; i < X->n; i++)
375 for (j = 0; j < biL; j++, count++)
376 if (((X->p[i] >> j) & 1) != 0)
377 return (count);
379 return (0);
383 * Count leading zero bits in a given integer
385 static size_t mbedtls_clz(const mbedtls_mpi_uint x) {
386 size_t j;
387 mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);
389 for (j = 0; j < biL; j++) {
390 if (x & mask) break;
392 mask >>= 1;
395 return j;
399 * Return the number of bits
401 size_t mbedtls_mpi_bitlen(const mbedtls_mpi *X) {
402 size_t i, j;
404 if (X->n == 0)
405 return (0);
407 for (i = X->n - 1; i > 0; i--)
408 if (X->p[i] != 0)
409 break;
411 j = biL - mbedtls_clz(X->p[i]);
413 return ((i * biL) + j);
417 * Return the total size in bytes
419 size_t mbedtls_mpi_size(const mbedtls_mpi *X) {
420 return ((mbedtls_mpi_bitlen(X) + 7) >> 3);
424 * Convert an ASCII character to digit value
426 static int mpi_get_digit(mbedtls_mpi_uint *d, int radix, char c) {
427 *d = 255;
429 if (c >= 0x30 && c <= 0x39) *d = c - 0x30;
430 if (c >= 0x41 && c <= 0x46) *d = c - 0x37;
431 if (c >= 0x61 && c <= 0x66) *d = c - 0x57;
433 if (*d >= (mbedtls_mpi_uint) radix)
434 return (MBEDTLS_ERR_MPI_INVALID_CHARACTER);
436 return (0);
440 * Import from an ASCII string
442 int mbedtls_mpi_read_string(mbedtls_mpi *X, int radix, const char *s) {
443 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
444 size_t i, j, slen, n;
445 mbedtls_mpi_uint d;
446 mbedtls_mpi T;
447 MPI_VALIDATE_RET(X != NULL);
448 MPI_VALIDATE_RET(s != NULL);
450 if (radix < 2 || radix > 16)
451 return (MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
453 mbedtls_mpi_init(&T);
455 slen = strlen(s);
457 if (radix == 16) {
458 if (slen > MPI_SIZE_T_MAX >> 2)
459 return (MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
461 n = BITS_TO_LIMBS(slen << 2);
463 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, n));
464 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));
466 for (i = slen, j = 0; i > 0; i--, j++) {
467 if (i == 1 && s[i - 1] == '-') {
468 X->s = -1;
469 break;
472 MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i - 1]));
473 X->p[j / (2 * ciL)] |= d << ((j % (2 * ciL)) << 2);
475 } else {
476 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));
478 for (i = 0; i < slen; i++) {
479 if (i == 0 && s[i] == '-') {
480 X->s = -1;
481 continue;
484 MBEDTLS_MPI_CHK(mpi_get_digit(&d, radix, s[i]));
485 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T, X, radix));
487 if (X->s == 1) {
488 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, &T, d));
489 } else {
490 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(X, &T, d));
495 cleanup:
497 mbedtls_mpi_free(&T);
499 return (ret);
503 * Helper to write the digits high-order first.
505 static int mpi_write_hlp(mbedtls_mpi *X, int radix,
506 char **p, const size_t buflen) {
507 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
508 mbedtls_mpi_uint r;
509 size_t length = 0;
510 char *p_end = *p + buflen;
512 do {
513 if (length >= buflen) {
514 return (MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL);
517 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, radix));
518 MBEDTLS_MPI_CHK(mbedtls_mpi_div_int(X, NULL, X, radix));
520 * Write the residue in the current position, as an ASCII character.
522 if (r < 0xA)
523 *(--p_end) = (char)('0' + r);
524 else
525 *(--p_end) = (char)('A' + (r - 0xA));
527 length++;
528 } while (mbedtls_mpi_cmp_int(X, 0) != 0);
530 memmove(*p, p_end, length);
531 *p += length;
533 cleanup:
535 return (ret);
539 * Export into an ASCII string
541 int mbedtls_mpi_write_string(const mbedtls_mpi *X, int radix,
542 char *buf, size_t buflen, size_t *olen) {
543 int ret = 0;
544 size_t n;
545 char *p;
546 mbedtls_mpi T;
547 MPI_VALIDATE_RET(X != NULL);
548 MPI_VALIDATE_RET(olen != NULL);
549 MPI_VALIDATE_RET(buflen == 0 || buf != NULL);
551 if (radix < 2 || radix > 16)
552 return (MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
554 n = mbedtls_mpi_bitlen(X); /* Number of bits necessary to present `n`. */
555 if (radix >= 4) n >>= 1; /* Number of 4-adic digits necessary to present
556 * `n`. If radix > 4, this might be a strict
557 * overapproximation of the number of
558 * radix-adic digits needed to present `n`. */
559 if (radix >= 16) n >>= 1; /* Number of hexadecimal digits necessary to
560 * present `n`. */
562 n += 1; /* Terminating null byte */
563 n += 1; /* Compensate for the divisions above, which round down `n`
564 * in case it's not even. */
565 n += 1; /* Potential '-'-sign. */
566 n += (n & 1); /* Make n even to have enough space for hexadecimal writing,
567 * which always uses an even number of hex-digits. */
569 if (buflen < n) {
570 *olen = n;
571 return (MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL);
574 p = buf;
575 mbedtls_mpi_init(&T);
577 if (X->s == -1) {
578 *p++ = '-';
579 buflen--;
582 if (radix == 16) {
583 int c;
584 size_t i, j, k;
586 for (i = X->n, k = 0; i > 0; i--) {
587 for (j = ciL; j > 0; j--) {
588 c = (X->p[i - 1] >> ((j - 1) << 3)) & 0xFF;
590 if (c == 0 && k == 0 && (i + j) != 2)
591 continue;
593 *(p++) = "0123456789ABCDEF" [c / 16];
594 *(p++) = "0123456789ABCDEF" [c % 16];
595 k = 1;
598 } else {
599 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T, X));
601 if (T.s == -1)
602 T.s = 1;
604 MBEDTLS_MPI_CHK(mpi_write_hlp(&T, radix, &p, buflen));
607 *p++ = '\0';
608 *olen = p - buf;
610 cleanup:
612 mbedtls_mpi_free(&T);
614 return (ret);
617 #if defined(MBEDTLS_FS_IO)
619 * Read X from an opened file
621 int mbedtls_mpi_read_file(mbedtls_mpi *X, int radix, FILE *fin) {
622 mbedtls_mpi_uint d;
623 size_t slen;
624 char *p;
626 * Buffer should have space for (short) label and decimal formatted MPI,
627 * newline characters and '\0'
629 char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
631 MPI_VALIDATE_RET(X != NULL);
632 MPI_VALIDATE_RET(fin != NULL);
634 if (radix < 2 || radix > 16)
635 return (MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
637 memset(s, 0, sizeof(s));
638 if (fgets(s, sizeof(s) - 1, fin) == NULL)
639 return (MBEDTLS_ERR_MPI_FILE_IO_ERROR);
641 slen = strlen(s);
642 if (slen == sizeof(s) - 2)
643 return (MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL);
645 if (slen > 0 && s[slen - 1] == '\n') { slen--; s[slen] = '\0'; }
646 if (slen > 0 && s[slen - 1] == '\r') { slen--; s[slen] = '\0'; }
648 p = s + slen;
649 while (p-- > s)
650 if (mpi_get_digit(&d, radix, *p) != 0)
651 break;
653 return (mbedtls_mpi_read_string(X, radix, p + 1));
657 * Write X into an opened file (or stdout if fout == NULL)
659 int mbedtls_mpi_write_file(const char *p, const mbedtls_mpi *X, int radix, FILE *fout) {
660 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
661 size_t n, slen, plen;
663 * Buffer should have space for (short) label and decimal formatted MPI,
664 * newline characters and '\0'
666 char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
667 MPI_VALIDATE_RET(X != NULL);
669 if (radix < 2 || radix > 16)
670 return (MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
672 memset(s, 0, sizeof(s));
674 MBEDTLS_MPI_CHK(mbedtls_mpi_write_string(X, radix, s, sizeof(s) - 2, &n));
676 if (p == NULL) p = "";
678 plen = strlen(p);
679 slen = strlen(s);
680 s[slen++] = '\r';
681 s[slen++] = '\n';
683 if (fout != NULL) {
684 if (fwrite(p, 1, plen, fout) != plen ||
685 fwrite(s, 1, slen, fout) != slen)
686 return (MBEDTLS_ERR_MPI_FILE_IO_ERROR);
687 } else
688 mbedtls_printf("%s%s", p, s);
690 cleanup:
692 return (ret);
694 #endif /* MBEDTLS_FS_IO */
697 /* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint
698 * into the storage form used by mbedtls_mpi. */
700 static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c(mbedtls_mpi_uint x) {
701 uint8_t i;
702 unsigned char *x_ptr;
703 mbedtls_mpi_uint tmp = 0;
705 for (i = 0, x_ptr = (unsigned char *) &x; i < ciL; i++, x_ptr++) {
706 tmp <<= CHAR_BIT;
707 tmp |= (mbedtls_mpi_uint) * x_ptr;
710 return (tmp);
713 static mbedtls_mpi_uint mpi_uint_bigendian_to_host(mbedtls_mpi_uint x) {
714 #if defined(__BYTE_ORDER__)
716 /* Nothing to do on bigendian systems. */
717 #if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ )
718 return (x);
719 #endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */
721 #if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ )
723 /* For GCC and Clang, have builtins for byte swapping. */
724 #if defined(__GNUC__) && defined(__GNUC_PREREQ)
725 #if __GNUC_PREREQ(4,3)
726 #define have_bswap
727 #endif
728 #endif
730 #if defined(__clang__) && defined(__has_builtin)
731 #if __has_builtin(__builtin_bswap32) && \
732 __has_builtin(__builtin_bswap64)
733 #define have_bswap
734 #endif
735 #endif
737 #if defined(have_bswap)
738 /* The compiler is hopefully able to statically evaluate this! */
739 switch (sizeof(mbedtls_mpi_uint)) {
740 case 4:
741 return (__builtin_bswap32(x));
742 case 8:
743 return (__builtin_bswap64(x));
745 #endif
746 #endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
747 #endif /* __BYTE_ORDER__ */
749 /* Fall back to C-based reordering if we don't know the byte order
750 * or we couldn't use a compiler-specific builtin. */
751 return (mpi_uint_bigendian_to_host_c(x));
754 static void mpi_bigendian_to_host(mbedtls_mpi_uint *const p, size_t limbs) {
755 mbedtls_mpi_uint *cur_limb_left;
756 mbedtls_mpi_uint *cur_limb_right;
757 if (limbs == 0)
758 return;
761 * Traverse limbs and
762 * - adapt byte-order in each limb
763 * - swap the limbs themselves.
764 * For that, simultaneously traverse the limbs from left to right
765 * and from right to left, as long as the left index is not bigger
766 * than the right index (it's not a problem if limbs is odd and the
767 * indices coincide in the last iteration).
769 for (cur_limb_left = p, cur_limb_right = p + (limbs - 1);
770 cur_limb_left <= cur_limb_right;
771 cur_limb_left++, cur_limb_right--) {
772 mbedtls_mpi_uint tmp;
773 /* Note that if cur_limb_left == cur_limb_right,
774 * this code effectively swaps the bytes only once. */
775 tmp = mpi_uint_bigendian_to_host(*cur_limb_left);
776 *cur_limb_left = mpi_uint_bigendian_to_host(*cur_limb_right);
777 *cur_limb_right = tmp;
782 * Import X from unsigned binary data, little endian
784 int mbedtls_mpi_read_binary_le(mbedtls_mpi *X,
785 const unsigned char *buf, size_t buflen) {
786 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
787 size_t i;
788 size_t const limbs = CHARS_TO_LIMBS(buflen);
790 /* Ensure that target MPI has exactly the necessary number of limbs */
791 if (X->n != limbs) {
792 mbedtls_mpi_free(X);
793 mbedtls_mpi_init(X);
794 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, limbs));
797 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));
799 for (i = 0; i < buflen; i++)
800 X->p[i / ciL] |= ((mbedtls_mpi_uint) buf[i]) << ((i % ciL) << 3);
802 cleanup:
805 * This function is also used to import keys. However, wiping the buffers
806 * upon failure is not necessary because failure only can happen before any
807 * input is copied.
809 return (ret);
813 * Import X from unsigned binary data, big endian
815 int mbedtls_mpi_read_binary(mbedtls_mpi *X, const unsigned char *buf, size_t buflen) {
816 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
817 size_t const limbs = CHARS_TO_LIMBS(buflen);
818 size_t const overhead = (limbs * ciL) - buflen;
819 unsigned char *Xp;
821 MPI_VALIDATE_RET(X != NULL);
822 MPI_VALIDATE_RET(buflen == 0 || buf != NULL);
824 /* Ensure that target MPI has exactly the necessary number of limbs */
825 if (X->n != limbs) {
826 mbedtls_mpi_free(X);
827 mbedtls_mpi_init(X);
828 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, limbs));
830 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));
832 /* Avoid calling `memcpy` with NULL source argument,
833 * even if buflen is 0. */
834 if (buf != NULL) {
835 Xp = (unsigned char *) X->p;
836 memcpy(Xp + overhead, buf, buflen);
838 mpi_bigendian_to_host(X->p, limbs);
841 cleanup:
844 * This function is also used to import keys. However, wiping the buffers
845 * upon failure is not necessary because failure only can happen before any
846 * input is copied.
848 return (ret);
852 * Export X into unsigned binary data, little endian
854 int mbedtls_mpi_write_binary_le(const mbedtls_mpi *X,
855 unsigned char *buf, size_t buflen) {
856 size_t stored_bytes = X->n * ciL;
857 size_t bytes_to_copy;
858 size_t i;
860 if (stored_bytes < buflen) {
861 bytes_to_copy = stored_bytes;
862 } else {
863 bytes_to_copy = buflen;
865 /* The output buffer is smaller than the allocated size of X.
866 * However X may fit if its leading bytes are zero. */
867 for (i = bytes_to_copy; i < stored_bytes; i++) {
868 if (GET_BYTE(X, i) != 0)
869 return (MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL);
873 for (i = 0; i < bytes_to_copy; i++)
874 buf[i] = GET_BYTE(X, i);
876 if (stored_bytes < buflen) {
877 /* Write trailing 0 bytes */
878 memset(buf + stored_bytes, 0, buflen - stored_bytes);
881 return (0);
885 * Export X into unsigned binary data, big endian
887 int mbedtls_mpi_write_binary(const mbedtls_mpi *X,
888 unsigned char *buf, size_t buflen) {
889 size_t stored_bytes;
890 size_t bytes_to_copy;
891 unsigned char *p;
892 size_t i;
894 MPI_VALIDATE_RET(X != NULL);
895 MPI_VALIDATE_RET(buflen == 0 || buf != NULL);
897 stored_bytes = X->n * ciL;
899 if (stored_bytes < buflen) {
900 /* There is enough space in the output buffer. Write initial
901 * null bytes and record the position at which to start
902 * writing the significant bytes. In this case, the execution
903 * trace of this function does not depend on the value of the
904 * number. */
905 bytes_to_copy = stored_bytes;
906 p = buf + buflen - stored_bytes;
907 memset(buf, 0, buflen - stored_bytes);
908 } else {
909 /* The output buffer is smaller than the allocated size of X.
910 * However X may fit if its leading bytes are zero. */
911 bytes_to_copy = buflen;
912 p = buf;
913 for (i = bytes_to_copy; i < stored_bytes; i++) {
914 if (GET_BYTE(X, i) != 0)
915 return (MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL);
919 for (i = 0; i < bytes_to_copy; i++)
920 p[bytes_to_copy - i - 1] = GET_BYTE(X, i);
922 return (0);
926 * Left-shift: X <<= count
928 int mbedtls_mpi_shift_l(mbedtls_mpi *X, size_t count) {
929 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
930 size_t i, v0, t1;
931 mbedtls_mpi_uint r0 = 0, r1;
932 MPI_VALIDATE_RET(X != NULL);
934 v0 = count / (biL);
935 t1 = count & (biL - 1);
937 i = mbedtls_mpi_bitlen(X) + count;
939 if (X->n * biL < i)
940 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, BITS_TO_LIMBS(i)));
942 ret = 0;
945 * shift by count / limb_size
947 if (v0 > 0) {
948 for (i = X->n; i > v0; i--)
949 X->p[i - 1] = X->p[i - v0 - 1];
951 for (; i > 0; i--)
952 X->p[i - 1] = 0;
956 * shift by count % limb_size
958 if (t1 > 0) {
959 for (i = v0; i < X->n; i++) {
960 r1 = X->p[i] >> (biL - t1);
961 X->p[i] <<= t1;
962 X->p[i] |= r0;
963 r0 = r1;
967 cleanup:
969 return (ret);
973 * Right-shift: X >>= count
975 int mbedtls_mpi_shift_r(mbedtls_mpi *X, size_t count) {
976 size_t i, v0, v1;
977 mbedtls_mpi_uint r0 = 0, r1;
978 MPI_VALIDATE_RET(X != NULL);
980 v0 = count / biL;
981 v1 = count & (biL - 1);
983 if (v0 > X->n || (v0 == X->n && v1 > 0))
984 return mbedtls_mpi_lset(X, 0);
987 * shift by count / limb_size
989 if (v0 > 0) {
990 for (i = 0; i < X->n - v0; i++)
991 X->p[i] = X->p[i + v0];
993 for (; i < X->n; i++)
994 X->p[i] = 0;
998 * shift by count % limb_size
1000 if (v1 > 0) {
1001 for (i = X->n; i > 0; i--) {
1002 r1 = X->p[i - 1] << (biL - v1);
1003 X->p[i - 1] >>= v1;
1004 X->p[i - 1] |= r0;
1005 r0 = r1;
1009 return (0);
1013 * Compare unsigned values
1015 int mbedtls_mpi_cmp_abs(const mbedtls_mpi *X, const mbedtls_mpi *Y) {
1016 size_t i, j;
1017 MPI_VALIDATE_RET(X != NULL);
1018 MPI_VALIDATE_RET(Y != NULL);
1020 for (i = X->n; i > 0; i--)
1021 if (X->p[i - 1] != 0)
1022 break;
1024 for (j = Y->n; j > 0; j--)
1025 if (Y->p[j - 1] != 0)
1026 break;
1028 if (i == 0 && j == 0)
1029 return (0);
1031 if (i > j) return (1);
1032 if (j > i) return (-1);
1034 for (; i > 0; i--) {
1035 if (X->p[i - 1] > Y->p[i - 1]) return (1);
1036 if (X->p[i - 1] < Y->p[i - 1]) return (-1);
1039 return (0);
1043 * Compare signed values
1045 int mbedtls_mpi_cmp_mpi(const mbedtls_mpi *X, const mbedtls_mpi *Y) {
1046 size_t i, j;
1047 MPI_VALIDATE_RET(X != NULL);
1048 MPI_VALIDATE_RET(Y != NULL);
1050 for (i = X->n; i > 0; i--)
1051 if (X->p[i - 1] != 0)
1052 break;
1054 for (j = Y->n; j > 0; j--)
1055 if (Y->p[j - 1] != 0)
1056 break;
1058 if (i == 0 && j == 0)
1059 return (0);
1061 if (i > j) return (X->s);
1062 if (j > i) return (-Y->s);
1064 if (X->s > 0 && Y->s < 0) return (1);
1065 if (Y->s > 0 && X->s < 0) return (-1);
1067 for (; i > 0; i--) {
1068 if (X->p[i - 1] > Y->p[i - 1]) return (X->s);
1069 if (X->p[i - 1] < Y->p[i - 1]) return (-X->s);
1072 return (0);
1075 /** Decide if an integer is less than the other, without branches.
1077 * \param x First integer.
1078 * \param y Second integer.
1080 * \return 1 if \p x is less than \p y, 0 otherwise
1082 static unsigned ct_lt_mpi_uint(const mbedtls_mpi_uint x,
1083 const mbedtls_mpi_uint y) {
1084 mbedtls_mpi_uint ret;
1085 mbedtls_mpi_uint cond;
1088 * Check if the most significant bits (MSB) of the operands are different.
1090 cond = (x ^ y);
1092 * If the MSB are the same then the difference x-y will be negative (and
1093 * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
1095 ret = (x - y) & ~cond;
1097 * If the MSB are different, then the operand with the MSB of 1 is the
1098 * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
1099 * the MSB of y is 0.)
1101 ret |= y & cond;
1104 ret = ret >> (biL - 1);
1106 return (unsigned) ret;
1110 * Compare signed values in constant time
1112 int mbedtls_mpi_lt_mpi_ct(const mbedtls_mpi *X, const mbedtls_mpi *Y,
1113 unsigned *ret) {
1114 size_t i;
1115 /* The value of any of these variables is either 0 or 1 at all times. */
1116 unsigned cond, done, X_is_negative, Y_is_negative;
1118 MPI_VALIDATE_RET(X != NULL);
1119 MPI_VALIDATE_RET(Y != NULL);
1120 MPI_VALIDATE_RET(ret != NULL);
1122 if (X->n != Y->n)
1123 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1126 * Set sign_N to 1 if N >= 0, 0 if N < 0.
1127 * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
1129 X_is_negative = (X->s & 2) >> 1;
1130 Y_is_negative = (Y->s & 2) >> 1;
1133 * If the signs are different, then the positive operand is the bigger.
1134 * That is if X is negative (X_is_negative == 1), then X < Y is true and it
1135 * is false if X is positive (X_is_negative == 0).
1137 cond = (X_is_negative ^ Y_is_negative);
1138 *ret = cond & X_is_negative;
1141 * This is a constant-time function. We might have the result, but we still
1142 * need to go through the loop. Record if we have the result already.
1144 done = cond;
1146 for (i = X->n; i > 0; i--) {
1148 * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
1149 * X and Y are negative.
1151 * Again even if we can make a decision, we just mark the result and
1152 * the fact that we are done and continue looping.
1154 cond = ct_lt_mpi_uint(Y->p[i - 1], X->p[i - 1]);
1155 *ret |= cond & (1 - done) & X_is_negative;
1156 done |= cond;
1159 * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
1160 * X and Y are positive.
1162 * Again even if we can make a decision, we just mark the result and
1163 * the fact that we are done and continue looping.
1165 cond = ct_lt_mpi_uint(X->p[i - 1], Y->p[i - 1]);
1166 *ret |= cond & (1 - done) & (1 - X_is_negative);
1167 done |= cond;
1170 return (0);
1174 * Compare signed values
1176 int mbedtls_mpi_cmp_int(const mbedtls_mpi *X, mbedtls_mpi_sint z) {
1177 mbedtls_mpi Y;
1178 mbedtls_mpi_uint p[1];
1179 MPI_VALIDATE_RET(X != NULL);
1181 *p = (z < 0) ? -z : z;
1182 Y.s = (z < 0) ? -1 : 1;
1183 Y.n = 1;
1184 Y.p = p;
1186 return (mbedtls_mpi_cmp_mpi(X, &Y));
1190 * Unsigned addition: X = |A| + |B| (HAC 14.7)
1192 int mbedtls_mpi_add_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) {
1193 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1194 size_t i, j;
1195 mbedtls_mpi_uint *o, *p, c, tmp;
1196 MPI_VALIDATE_RET(X != NULL);
1197 MPI_VALIDATE_RET(A != NULL);
1198 MPI_VALIDATE_RET(B != NULL);
1200 if (X == B) {
1201 const mbedtls_mpi *T = A;
1202 A = X;
1203 B = T;
1206 if (X != A)
1207 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
1210 * X should always be positive as a result of unsigned additions.
1212 X->s = 1;
1214 for (j = B->n; j > 0; j--)
1215 if (B->p[j - 1] != 0)
1216 break;
1218 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j));
1220 o = B->p;
1221 p = X->p;
1222 c = 0;
1225 * tmp is used because it might happen that p == o
1227 for (i = 0; i < j; i++, o++, p++) {
1228 tmp = *o;
1229 *p += c;
1230 c = (*p < c);
1231 *p += tmp;
1232 c += (*p < tmp);
1235 while (c != 0) {
1236 if (i >= X->n) {
1237 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i + 1));
1238 p = X->p + i;
1241 *p += c;
1242 c = (*p < c);
1243 i++;
1244 p++;
1247 cleanup:
1249 return (ret);
1253 * Helper for mbedtls_mpi subtraction.
1255 * Calculate d - s where d and s have the same size.
1256 * This function operates modulo (2^ciL)^n and returns the carry
1257 * (1 if there was a wraparound, i.e. if `d < s`, and 0 otherwise).
1259 * \param n Number of limbs of \p d and \p s.
1260 * \param[in,out] d On input, the left operand.
1261 * On output, the result of the subtraction:
1262 * \param[in] s The right operand.
1264 * \return 1 if `d < s`.
1265 * 0 if `d >= s`.
1267 static mbedtls_mpi_uint mpi_sub_hlp(size_t n,
1268 mbedtls_mpi_uint *d,
1269 const mbedtls_mpi_uint *s) {
1270 size_t i;
1271 mbedtls_mpi_uint c, z;
1273 for (i = c = 0; i < n; i++, s++, d++) {
1274 z = (*d < c);
1275 *d -= c;
1276 c = (*d < *s) + z;
1277 *d -= *s;
1280 return (c);
1284 * Unsigned subtraction: X = |A| - |B| (HAC 14.9, 14.10)
1286 int mbedtls_mpi_sub_abs(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) {
1287 mbedtls_mpi TB;
1288 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1289 size_t n;
1290 mbedtls_mpi_uint carry;
1291 MPI_VALIDATE_RET(X != NULL);
1292 MPI_VALIDATE_RET(A != NULL);
1293 MPI_VALIDATE_RET(B != NULL);
1295 mbedtls_mpi_init(&TB);
1297 if (X == B) {
1298 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B));
1299 B = &TB;
1302 if (X != A)
1303 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, A));
1306 * X should always be positive as a result of unsigned subtractions.
1308 X->s = 1;
1310 ret = 0;
1312 for (n = B->n; n > 0; n--)
1313 if (B->p[n - 1] != 0)
1314 break;
1315 if (n > A->n) {
1316 /* B >= (2^ciL)^n > A */
1317 ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
1318 goto cleanup;
1321 carry = mpi_sub_hlp(n, X->p, B->p);
1322 if (carry != 0) {
1323 /* Propagate the carry to the first nonzero limb of X. */
1324 for (; n < X->n && X->p[n] == 0; n++)
1325 --X->p[n];
1326 /* If we ran out of space for the carry, it means that the result
1327 * is negative. */
1328 if (n == X->n) {
1329 ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
1330 goto cleanup;
1332 --X->p[n];
1335 cleanup:
1337 mbedtls_mpi_free(&TB);
1339 return (ret);
1343 * Signed addition: X = A + B
1345 int mbedtls_mpi_add_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) {
1346 int ret, s;
1347 MPI_VALIDATE_RET(X != NULL);
1348 MPI_VALIDATE_RET(A != NULL);
1349 MPI_VALIDATE_RET(B != NULL);
1351 s = A->s;
1352 if (A->s * B->s < 0) {
1353 if (mbedtls_mpi_cmp_abs(A, B) >= 0) {
1354 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, A, B));
1355 X->s = s;
1356 } else {
1357 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, B, A));
1358 X->s = -s;
1360 } else {
1361 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(X, A, B));
1362 X->s = s;
1365 cleanup:
1367 return (ret);
1371 * Signed subtraction: X = A - B
1373 int mbedtls_mpi_sub_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) {
1374 int ret, s;
1375 MPI_VALIDATE_RET(X != NULL);
1376 MPI_VALIDATE_RET(A != NULL);
1377 MPI_VALIDATE_RET(B != NULL);
1379 s = A->s;
1380 if (A->s * B->s > 0) {
1381 if (mbedtls_mpi_cmp_abs(A, B) >= 0) {
1382 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, A, B));
1383 X->s = s;
1384 } else {
1385 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(X, B, A));
1386 X->s = -s;
1388 } else {
1389 MBEDTLS_MPI_CHK(mbedtls_mpi_add_abs(X, A, B));
1390 X->s = s;
1393 cleanup:
1395 return (ret);
1399 * Signed addition: X = A + b
1401 int mbedtls_mpi_add_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b) {
1402 mbedtls_mpi _B;
1403 mbedtls_mpi_uint p[1];
1404 MPI_VALIDATE_RET(X != NULL);
1405 MPI_VALIDATE_RET(A != NULL);
1407 p[0] = (b < 0) ? -b : b;
1408 _B.s = (b < 0) ? -1 : 1;
1409 _B.n = 1;
1410 _B.p = p;
1412 return (mbedtls_mpi_add_mpi(X, A, &_B));
1416 * Signed subtraction: X = A - b
1418 int mbedtls_mpi_sub_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b) {
1419 mbedtls_mpi _B;
1420 mbedtls_mpi_uint p[1];
1421 MPI_VALIDATE_RET(X != NULL);
1422 MPI_VALIDATE_RET(A != NULL);
1424 p[0] = (b < 0) ? -b : b;
1425 _B.s = (b < 0) ? -1 : 1;
1426 _B.n = 1;
1427 _B.p = p;
1429 return (mbedtls_mpi_sub_mpi(X, A, &_B));
1433 * Helper for mbedtls_mpi multiplication
1435 static
1436 #if defined(__APPLE__) && defined(__arm__)
1438 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1439 * appears to need this to prevent bad ARM code generation at -O3.
1441 __attribute__((noinline))
1442 #endif
1443 void mpi_mul_hlp(size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mpi_uint b) {
1444 mbedtls_mpi_uint c = 0, t = 0;
1445 (void)t;
1447 #if defined(MULADDC_HUIT)
1448 for (; i >= 8; i -= 8) {
1449 MULADDC_INIT
1450 MULADDC_HUIT
1451 MULADDC_STOP
1454 for (; i > 0; i--) {
1455 MULADDC_INIT
1456 MULADDC_CORE
1457 MULADDC_STOP
1459 #else /* MULADDC_HUIT */
1460 for (; i >= 16; i -= 16) {
1461 MULADDC_INIT
1462 MULADDC_CORE MULADDC_CORE
1463 MULADDC_CORE MULADDC_CORE
1464 MULADDC_CORE MULADDC_CORE
1465 MULADDC_CORE MULADDC_CORE
1467 MULADDC_CORE MULADDC_CORE
1468 MULADDC_CORE MULADDC_CORE
1469 MULADDC_CORE MULADDC_CORE
1470 MULADDC_CORE MULADDC_CORE
1471 MULADDC_STOP
1474 for (; i >= 8; i -= 8) {
1475 MULADDC_INIT
1476 MULADDC_CORE MULADDC_CORE
1477 MULADDC_CORE MULADDC_CORE
1479 MULADDC_CORE MULADDC_CORE
1480 MULADDC_CORE MULADDC_CORE
1481 MULADDC_STOP
1484 for (; i > 0; i--) {
1485 MULADDC_INIT
1486 MULADDC_CORE
1487 MULADDC_STOP
1489 #endif /* MULADDC_HUIT */
1491 t++;
1493 do {
1494 *d += c;
1495 c = (*d < c);
1496 d++;
1497 } while (c != 0);
1501 * Baseline multiplication: X = A * B (HAC 14.12)
1503 int mbedtls_mpi_mul_mpi(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B) {
1504 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1505 size_t i, j;
1506 mbedtls_mpi TA, TB;
1507 MPI_VALIDATE_RET(X != NULL);
1508 MPI_VALIDATE_RET(A != NULL);
1509 MPI_VALIDATE_RET(B != NULL);
1511 mbedtls_mpi_init(&TA);
1512 mbedtls_mpi_init(&TB);
1514 if (X == A) { MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A)); A = &TA; }
1515 if (X == B) { MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B)); B = &TB; }
1517 for (i = A->n; i > 0; i--)
1518 if (A->p[i - 1] != 0)
1519 break;
1521 for (j = B->n; j > 0; j--)
1522 if (B->p[j - 1] != 0)
1523 break;
1525 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, i + j));
1526 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));
1528 for (; j > 0; j--)
1529 mpi_mul_hlp(i, A->p, X->p + j - 1, B->p[j - 1]);
1531 X->s = A->s * B->s;
1533 cleanup:
1535 mbedtls_mpi_free(&TB);
1536 mbedtls_mpi_free(&TA);
1538 return (ret);
1542 * Baseline multiplication: X = A * b
1544 int mbedtls_mpi_mul_int(mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b) {
1545 mbedtls_mpi _B;
1546 mbedtls_mpi_uint p[1];
1547 MPI_VALIDATE_RET(X != NULL);
1548 MPI_VALIDATE_RET(A != NULL);
1550 _B.s = 1;
1551 _B.n = 1;
1552 _B.p = p;
1553 p[0] = b;
1555 return (mbedtls_mpi_mul_mpi(X, A, &_B));
1559 * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and
1560 * mbedtls_mpi_uint divisor, d
1562 static mbedtls_mpi_uint mbedtls_int_div_int(mbedtls_mpi_uint u1,
1563 mbedtls_mpi_uint u0, mbedtls_mpi_uint d, mbedtls_mpi_uint *r) {
1564 #if defined(MBEDTLS_HAVE_UDBL)
1565 mbedtls_t_udbl dividend, quotient;
1566 #else
1567 const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH;
1568 const mbedtls_mpi_uint uint_halfword_mask = ((mbedtls_mpi_uint) 1 << biH) - 1;
1569 mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient;
1570 mbedtls_mpi_uint u0_msw, u0_lsw;
1571 size_t s;
1572 #endif
1575 * Check for overflow
1577 if (0 == d || u1 >= d) {
1578 if (r != NULL) *r = ~0;
1580 return (~0);
1583 #if defined(MBEDTLS_HAVE_UDBL)
1584 dividend = (mbedtls_t_udbl) u1 << biL;
1585 dividend |= (mbedtls_t_udbl) u0;
1586 quotient = dividend / d;
1587 if (quotient > ((mbedtls_t_udbl) 1 << biL) - 1)
1588 quotient = ((mbedtls_t_udbl) 1 << biL) - 1;
1590 if (r != NULL)
1591 *r = (mbedtls_mpi_uint)(dividend - (quotient * d));
1593 return (mbedtls_mpi_uint) quotient;
1594 #else
1597 * Algorithm D, Section 4.3.1 - The Art of Computer Programming
1598 * Vol. 2 - Seminumerical Algorithms, Knuth
1602 * Normalize the divisor, d, and dividend, u0, u1
1604 s = mbedtls_clz(d);
1605 d = d << s;
1607 u1 = u1 << s;
1608 u1 |= (u0 >> (biL - s)) & (-(mbedtls_mpi_sint)s >> (biL - 1));
1609 u0 = u0 << s;
1611 d1 = d >> biH;
1612 d0 = d & uint_halfword_mask;
1614 u0_msw = u0 >> biH;
1615 u0_lsw = u0 & uint_halfword_mask;
1618 * Find the first quotient and remainder
1620 q1 = u1 / d1;
1621 r0 = u1 - d1 * q1;
1623 while (q1 >= radix || (q1 * d0 > radix * r0 + u0_msw)) {
1624 q1 -= 1;
1625 r0 += d1;
1627 if (r0 >= radix) break;
1630 rAX = (u1 * radix) + (u0_msw - q1 * d);
1631 q0 = rAX / d1;
1632 r0 = rAX - q0 * d1;
1634 while (q0 >= radix || (q0 * d0 > radix * r0 + u0_lsw)) {
1635 q0 -= 1;
1636 r0 += d1;
1638 if (r0 >= radix) break;
1641 if (r != NULL)
1642 *r = (rAX * radix + u0_lsw - q0 * d) >> s;
1644 quotient = q1 * radix + q0;
1646 return quotient;
1647 #endif
1651 * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20)
1653 int mbedtls_mpi_div_mpi(mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
1654 const mbedtls_mpi *B) {
1655 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1656 size_t i, n, t, k;
1657 mbedtls_mpi X, Y, Z, T1, T2;
1658 mbedtls_mpi_uint TP2[3];
1659 MPI_VALIDATE_RET(A != NULL);
1660 MPI_VALIDATE_RET(B != NULL);
1662 if (mbedtls_mpi_cmp_int(B, 0) == 0)
1663 return (MBEDTLS_ERR_MPI_DIVISION_BY_ZERO);
1665 mbedtls_mpi_init(&X);
1666 mbedtls_mpi_init(&Y);
1667 mbedtls_mpi_init(&Z);
1668 mbedtls_mpi_init(&T1);
1670 * Avoid dynamic memory allocations for constant-size T2.
1672 * T2 is used for comparison only and the 3 limbs are assigned explicitly,
1673 * so nobody increase the size of the MPI and we're safe to use an on-stack
1674 * buffer.
1676 T2.s = 1;
1677 T2.n = sizeof(TP2) / sizeof(*TP2);
1678 T2.p = TP2;
1680 if (mbedtls_mpi_cmp_abs(A, B) < 0) {
1681 if (Q != NULL) MBEDTLS_MPI_CHK(mbedtls_mpi_lset(Q, 0));
1682 if (R != NULL) MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, A));
1683 return (0);
1686 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&X, A));
1687 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, B));
1688 X.s = Y.s = 1;
1690 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&Z, A->n + 2));
1691 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Z, 0));
1692 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&T1, 2));
1694 k = mbedtls_mpi_bitlen(&Y) % biL;
1695 if (k < biL - 1) {
1696 k = biL - 1 - k;
1697 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&X, k));
1698 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, k));
1699 } else k = 0;
1701 n = X.n - 1;
1702 t = Y.n - 1;
1703 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&Y, biL * (n - t)));
1705 while (mbedtls_mpi_cmp_mpi(&X, &Y) >= 0) {
1706 Z.p[n - t]++;
1707 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &Y));
1709 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, biL * (n - t)));
1711 for (i = n; i > t ; i--) {
1712 if (X.p[i] >= Y.p[t])
1713 Z.p[i - t - 1] = ~0;
1714 else {
1715 Z.p[i - t - 1] = mbedtls_int_div_int(X.p[i], X.p[i - 1],
1716 Y.p[t], NULL);
1719 T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
1720 T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
1721 T2.p[2] = X.p[i];
1723 Z.p[i - t - 1]++;
1724 do {
1725 Z.p[i - t - 1]--;
1727 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&T1, 0));
1728 T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
1729 T1.p[1] = Y.p[t];
1730 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &T1, Z.p[i - t - 1]));
1731 } while (mbedtls_mpi_cmp_mpi(&T1, &T2) > 0);
1733 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_int(&T1, &Y, Z.p[i - t - 1]));
1734 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1, biL * (i - t - 1)));
1735 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&X, &X, &T1));
1737 if (mbedtls_mpi_cmp_int(&X, 0) < 0) {
1738 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&T1, &Y));
1739 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&T1, biL * (i - t - 1)));
1740 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&X, &X, &T1));
1741 Z.p[i - t - 1]--;
1745 if (Q != NULL) {
1746 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(Q, &Z));
1747 Q->s = A->s * B->s;
1750 if (R != NULL) {
1751 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&X, k));
1752 X.s = A->s;
1753 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(R, &X));
1755 if (mbedtls_mpi_cmp_int(R, 0) == 0)
1756 R->s = 1;
1759 cleanup:
1761 mbedtls_mpi_free(&X);
1762 mbedtls_mpi_free(&Y);
1763 mbedtls_mpi_free(&Z);
1764 mbedtls_mpi_free(&T1);
1765 mbedtls_platform_zeroize(TP2, sizeof(TP2));
1767 return (ret);
1771 * Division by int: A = Q * b + R
1773 int mbedtls_mpi_div_int(mbedtls_mpi *Q, mbedtls_mpi *R,
1774 const mbedtls_mpi *A,
1775 mbedtls_mpi_sint b) {
1776 mbedtls_mpi _B;
1777 mbedtls_mpi_uint p[1];
1778 MPI_VALIDATE_RET(A != NULL);
1780 p[0] = (b < 0) ? -b : b;
1781 _B.s = (b < 0) ? -1 : 1;
1782 _B.n = 1;
1783 _B.p = p;
1785 return (mbedtls_mpi_div_mpi(Q, R, A, &_B));
1789 * Modulo: R = A mod B
1791 int mbedtls_mpi_mod_mpi(mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B) {
1792 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1793 MPI_VALIDATE_RET(R != NULL);
1794 MPI_VALIDATE_RET(A != NULL);
1795 MPI_VALIDATE_RET(B != NULL);
1797 if (mbedtls_mpi_cmp_int(B, 0) < 0)
1798 return (MBEDTLS_ERR_MPI_NEGATIVE_VALUE);
1800 MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(NULL, R, A, B));
1802 while (mbedtls_mpi_cmp_int(R, 0) < 0)
1803 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(R, R, B));
1805 while (mbedtls_mpi_cmp_mpi(R, B) >= 0)
1806 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(R, R, B));
1808 cleanup:
1810 return (ret);
1814 * Modulo: r = A mod b
1816 int mbedtls_mpi_mod_int(mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b) {
1817 size_t i;
1818 mbedtls_mpi_uint x, y, z;
1819 MPI_VALIDATE_RET(r != NULL);
1820 MPI_VALIDATE_RET(A != NULL);
1822 if (b == 0)
1823 return (MBEDTLS_ERR_MPI_DIVISION_BY_ZERO);
1825 if (b < 0)
1826 return (MBEDTLS_ERR_MPI_NEGATIVE_VALUE);
1829 * handle trivial cases
1831 if (b == 1) {
1832 *r = 0;
1833 return (0);
1836 if (b == 2) {
1837 *r = A->p[0] & 1;
1838 return (0);
1842 * general case
1844 for (i = A->n, y = 0; i > 0; i--) {
1845 x = A->p[i - 1];
1846 y = (y << biH) | (x >> biH);
1847 z = y / b;
1848 y -= z * b;
1850 x <<= biH;
1851 y = (y << biH) | (x >> biH);
1852 z = y / b;
1853 y -= z * b;
1857 * If A is negative, then the current y represents a negative value.
1858 * Flipping it to the positive side.
1860 if (A->s < 0 && y != 0)
1861 y = b - y;
1863 *r = y;
1865 return (0);
1869 * Fast Montgomery initialization (thanks to Tom St Denis)
1871 static void mpi_montg_init(mbedtls_mpi_uint *mm, const mbedtls_mpi *N) {
1872 mbedtls_mpi_uint x, m0 = N->p[0];
1873 unsigned int i;
1875 x = m0;
1876 x += ((m0 + 2) & 4) << 1;
1878 for (i = biL; i >= 8; i /= 2)
1879 x *= (2 - (m0 * x));
1881 *mm = ~x + 1;
1884 /** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1886 * \param[in,out] A One of the numbers to multiply.
1887 * It must have at least as many limbs as N
1888 * (A->n >= N->n), and any limbs beyond n are ignored.
1889 * On successful completion, A contains the result of
1890 * the multiplication A * B * R^-1 mod N where
1891 * R = (2^ciL)^n.
1892 * \param[in] B One of the numbers to multiply.
1893 * It must be nonzero and must not have more limbs than N
1894 * (B->n <= N->n).
1895 * \param[in] N The modulo. N must be odd.
1896 * \param mm The value calculated by `mpi_montg_init(&mm, N)`.
1897 * This is -N^-1 mod 2^ciL.
1898 * \param[in,out] T A bignum for temporary storage.
1899 * It must be at least twice the limb size of N plus 2
1900 * (T->n >= 2 * (N->n + 1)).
1901 * Its initial content is unused and
1902 * its final content is indeterminate.
1903 * Note that unlike the usual convention in the library
1904 * for `const mbedtls_mpi*`, the content of T can change.
1906 static void mpi_montmul(mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
1907 const mbedtls_mpi *T) {
1908 size_t i, n, m;
1909 mbedtls_mpi_uint u0, u1, *d;
1911 memset(T->p, 0, T->n * ciL);
1913 d = T->p;
1914 n = N->n;
1915 m = (B->n < n) ? B->n : n;
1917 for (i = 0; i < n; i++) {
1919 * T = (T + u0*B + u1*N) / 2^biL
1921 u0 = A->p[i];
1922 u1 = (d[0] + u0 * B->p[0]) * mm;
1924 mpi_mul_hlp(m, B->p, d, u0);
1925 mpi_mul_hlp(n, N->p, d, u1);
1927 *d++ = u0;
1928 d[n + 1] = 0;
1931 /* At this point, d is either the desired result or the desired result
1932 * plus N. We now potentially subtract N, avoiding leaking whether the
1933 * subtraction is performed through side channels. */
1935 /* Copy the n least significant limbs of d to A, so that
1936 * A = d if d < N (recall that N has n limbs). */
1937 memcpy(A->p, d, n * ciL);
1938 /* If d >= N then we want to set A to d - N. To prevent timing attacks,
1939 * do the calculation without using conditional tests. */
1940 /* Set d to d0 + (2^biL)^n - N where d0 is the current value of d. */
1941 d[n] += 1;
1942 d[n] -= mpi_sub_hlp(n, d, N->p);
1943 /* If d0 < N then d < (2^biL)^n
1944 * so d[n] == 0 and we want to keep A as it is.
1945 * If d0 >= N then d >= (2^biL)^n, and d <= (2^biL)^n + N < 2 * (2^biL)^n
1946 * so d[n] == 1 and we want to set A to the result of the subtraction
1947 * which is d - (2^biL)^n, i.e. the n least significant limbs of d.
1948 * This exactly corresponds to a conditional assignment. */
1949 mpi_safe_cond_assign(n, A->p, d, (unsigned char) d[n]);
1953 * Montgomery reduction: A = A * R^-1 mod N
1955 * See mpi_montmul() regarding constraints and guarantees on the parameters.
1957 static void mpi_montred(mbedtls_mpi *A, const mbedtls_mpi *N,
1958 mbedtls_mpi_uint mm, const mbedtls_mpi *T) {
1959 mbedtls_mpi_uint z = 1;
1960 mbedtls_mpi U;
1962 U.n = U.s = (int) z;
1963 U.p = &z;
1965 mpi_montmul(A, &U, N, mm, T);
1969 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1971 int mbedtls_mpi_exp_mod(mbedtls_mpi *X, const mbedtls_mpi *A,
1972 const mbedtls_mpi *E, const mbedtls_mpi *N,
1973 mbedtls_mpi *_RR) {
1974 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
1975 size_t wbits, wsize, one = 1;
1976 size_t i, j, nblimbs;
1977 size_t bufsize, nbits;
1978 mbedtls_mpi_uint ei, mm, state;
1979 mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
1980 int neg;
1982 MPI_VALIDATE_RET(X != NULL);
1983 MPI_VALIDATE_RET(A != NULL);
1984 MPI_VALIDATE_RET(E != NULL);
1985 MPI_VALIDATE_RET(N != NULL);
1987 if (mbedtls_mpi_cmp_int(N, 0) <= 0 || (N->p[0] & 1) == 0)
1988 return (MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
1990 if (mbedtls_mpi_cmp_int(E, 0) < 0)
1991 return (MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
1993 if (mbedtls_mpi_bitlen(E) > MBEDTLS_MPI_MAX_BITS ||
1994 mbedtls_mpi_bitlen(N) > MBEDTLS_MPI_MAX_BITS)
1995 return (MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
1998 * Init temps and window size
2000 mpi_montg_init(&mm, N);
2001 mbedtls_mpi_init(&RR);
2002 mbedtls_mpi_init(&T);
2003 mbedtls_mpi_init(&Apos);
2004 memset(W, 0, sizeof(W));
2006 i = mbedtls_mpi_bitlen(E);
2008 wsize = (i > 671) ? 6 : (i > 239) ? 5 :
2009 (i > 79) ? 4 : (i > 23) ? 3 : 1;
2011 #if( MBEDTLS_MPI_WINDOW_SIZE < 6 )
2012 if (wsize > MBEDTLS_MPI_WINDOW_SIZE)
2013 wsize = MBEDTLS_MPI_WINDOW_SIZE;
2014 #endif
2016 j = N->n + 1;
2017 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, j));
2018 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[1], j));
2019 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&T, j * 2));
2022 * Compensate for negative A (and correct at the end)
2024 neg = (A->s == -1);
2025 if (neg) {
2026 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Apos, A));
2027 Apos.s = 1;
2028 A = &Apos;
2032 * If 1st call, pre-compute R^2 mod N
2034 if (_RR == NULL || _RR->p == NULL) {
2035 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&RR, 1));
2036 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&RR, N->n * 2 * biL));
2037 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&RR, &RR, N));
2039 if (_RR != NULL)
2040 memcpy(_RR, &RR, sizeof(mbedtls_mpi));
2041 } else
2042 memcpy(&RR, _RR, sizeof(mbedtls_mpi));
2045 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
2047 if (mbedtls_mpi_cmp_mpi(A, N) >= 0)
2048 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&W[1], A, N));
2049 else
2050 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[1], A));
2052 mpi_montmul(&W[1], &RR, N, mm, &T);
2055 * X = R^2 * R^-1 mod N = R mod N
2057 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &RR));
2058 mpi_montred(X, N, mm, &T);
2060 if (wsize > 1) {
2062 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
2064 j = one << (wsize - 1);
2066 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[j], N->n + 1));
2067 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[j], &W[1]));
2069 for (i = 0; i < wsize - 1; i++)
2070 mpi_montmul(&W[j], &W[j], N, mm, &T);
2073 * W[i] = W[i - 1] * W[1]
2075 for (i = j + 1; i < (one << wsize); i++) {
2076 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(&W[i], N->n + 1));
2077 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&W[i], &W[i - 1]));
2079 mpi_montmul(&W[i], &W[1], N, mm, &T);
2083 nblimbs = E->n;
2084 bufsize = 0;
2085 nbits = 0;
2086 wbits = 0;
2087 state = 0;
2089 while (1) {
2090 if (bufsize == 0) {
2091 if (nblimbs == 0)
2092 break;
2094 nblimbs--;
2096 bufsize = sizeof(mbedtls_mpi_uint) << 3;
2099 bufsize--;
2101 ei = (E->p[nblimbs] >> bufsize) & 1;
2104 * skip leading 0s
2106 if (ei == 0 && state == 0)
2107 continue;
2109 if (ei == 0 && state == 1) {
2111 * out of window, square X
2113 mpi_montmul(X, X, N, mm, &T);
2114 continue;
2118 * add ei to current window
2120 state = 2;
2122 nbits++;
2123 wbits |= (ei << (wsize - nbits));
2125 if (nbits == wsize) {
2127 * X = X^wsize R^-1 mod N
2129 for (i = 0; i < wsize; i++)
2130 mpi_montmul(X, X, N, mm, &T);
2133 * X = X * W[wbits] R^-1 mod N
2135 mpi_montmul(X, &W[wbits], N, mm, &T);
2137 state--;
2138 nbits = 0;
2139 wbits = 0;
2144 * process the remaining bits
2146 for (i = 0; i < nbits; i++) {
2147 mpi_montmul(X, X, N, mm, &T);
2149 wbits <<= 1;
2151 if ((wbits & (one << wsize)) != 0)
2152 mpi_montmul(X, &W[1], N, mm, &T);
2156 * X = A^E * R * R^-1 mod N = A^E mod N
2158 mpi_montred(X, N, mm, &T);
2160 if (neg && E->n != 0 && (E->p[0] & 1) != 0) {
2161 X->s = -1;
2162 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(X, N, X));
2165 cleanup:
2167 for (i = (one << (wsize - 1)); i < (one << wsize); i++)
2168 mbedtls_mpi_free(&W[i]);
2170 mbedtls_mpi_free(&W[1]);
2171 mbedtls_mpi_free(&T);
2172 mbedtls_mpi_free(&Apos);
2174 if (_RR == NULL || _RR->p == NULL)
2175 mbedtls_mpi_free(&RR);
2177 return (ret);
2181 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
2183 int mbedtls_mpi_gcd(mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B) {
2184 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2185 size_t lz, lzt;
2186 mbedtls_mpi TA, TB;
2188 MPI_VALIDATE_RET(G != NULL);
2189 MPI_VALIDATE_RET(A != NULL);
2190 MPI_VALIDATE_RET(B != NULL);
2192 mbedtls_mpi_init(&TA);
2193 mbedtls_mpi_init(&TB);
2195 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TA, A));
2196 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, B));
2198 lz = mbedtls_mpi_lsb(&TA);
2199 lzt = mbedtls_mpi_lsb(&TB);
2201 if (lzt < lz)
2202 lz = lzt;
2204 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, lz));
2205 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, lz));
2207 TA.s = TB.s = 1;
2209 while (mbedtls_mpi_cmp_int(&TA, 0) != 0) {
2210 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, mbedtls_mpi_lsb(&TA)));
2211 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, mbedtls_mpi_lsb(&TB)));
2213 if (mbedtls_mpi_cmp_mpi(&TA, &TB) >= 0) {
2214 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(&TA, &TA, &TB));
2215 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TA, 1));
2216 } else {
2217 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_abs(&TB, &TB, &TA));
2218 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TB, 1));
2222 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_l(&TB, lz));
2223 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(G, &TB));
2225 cleanup:
2227 mbedtls_mpi_free(&TA);
2228 mbedtls_mpi_free(&TB);
2230 return (ret);
2234 * Fill X with size bytes of random.
2236 * Use a temporary bytes representation to make sure the result is the same
2237 * regardless of the platform endianness (useful when f_rng is actually
2238 * deterministic, eg for tests).
2240 int mbedtls_mpi_fill_random(mbedtls_mpi *X, size_t size,
2241 int (*f_rng)(void *, unsigned char *, size_t),
2242 void *p_rng) {
2243 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2244 size_t const limbs = CHARS_TO_LIMBS(size);
2245 size_t const overhead = (limbs * ciL) - size;
2246 unsigned char *Xp;
2248 MPI_VALIDATE_RET(X != NULL);
2249 MPI_VALIDATE_RET(f_rng != NULL);
2251 /* Ensure that target MPI has exactly the necessary number of limbs */
2252 if (X->n != limbs) {
2253 mbedtls_mpi_free(X);
2254 mbedtls_mpi_init(X);
2255 MBEDTLS_MPI_CHK(mbedtls_mpi_grow(X, limbs));
2257 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(X, 0));
2259 Xp = (unsigned char *) X->p;
2260 MBEDTLS_MPI_CHK(f_rng(p_rng, Xp + overhead, size));
2262 mpi_bigendian_to_host(X->p, limbs);
2264 cleanup:
2265 return (ret);
2269 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
2271 int mbedtls_mpi_inv_mod(mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N) {
2272 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2273 mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
2274 MPI_VALIDATE_RET(X != NULL);
2275 MPI_VALIDATE_RET(A != NULL);
2276 MPI_VALIDATE_RET(N != NULL);
2278 if (mbedtls_mpi_cmp_int(N, 1) <= 0)
2279 return (MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
2281 mbedtls_mpi_init(&TA);
2282 mbedtls_mpi_init(&TU);
2283 mbedtls_mpi_init(&U1);
2284 mbedtls_mpi_init(&U2);
2285 mbedtls_mpi_init(&G);
2286 mbedtls_mpi_init(&TB);
2287 mbedtls_mpi_init(&TV);
2288 mbedtls_mpi_init(&V1);
2289 mbedtls_mpi_init(&V2);
2291 MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&G, A, N));
2293 if (mbedtls_mpi_cmp_int(&G, 1) != 0) {
2294 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2295 goto cleanup;
2298 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&TA, A, N));
2299 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TU, &TA));
2300 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TB, N));
2301 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&TV, N));
2303 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&U1, 1));
2304 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&U2, 0));
2305 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&V1, 0));
2306 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&V2, 1));
2308 do {
2309 while ((TU.p[0] & 1) == 0) {
2310 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TU, 1));
2312 if ((U1.p[0] & 1) != 0 || (U2.p[0] & 1) != 0) {
2313 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&U1, &U1, &TB));
2314 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U2, &U2, &TA));
2317 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&U1, 1));
2318 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&U2, 1));
2321 while ((TV.p[0] & 1) == 0) {
2322 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&TV, 1));
2324 if ((V1.p[0] & 1) != 0 || (V2.p[0] & 1) != 0) {
2325 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&V1, &V1, &TB));
2326 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V2, &V2, &TA));
2329 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&V1, 1));
2330 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&V2, 1));
2333 if (mbedtls_mpi_cmp_mpi(&TU, &TV) >= 0) {
2334 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&TU, &TU, &TV));
2335 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U1, &U1, &V1));
2336 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&U2, &U2, &V2));
2337 } else {
2338 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&TV, &TV, &TU));
2339 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V1, &V1, &U1));
2340 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V2, &V2, &U2));
2342 } while (mbedtls_mpi_cmp_int(&TU, 0) != 0);
2344 while (mbedtls_mpi_cmp_int(&V1, 0) < 0)
2345 MBEDTLS_MPI_CHK(mbedtls_mpi_add_mpi(&V1, &V1, N));
2347 while (mbedtls_mpi_cmp_mpi(&V1, N) >= 0)
2348 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_mpi(&V1, &V1, N));
2350 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(X, &V1));
2352 cleanup:
2354 mbedtls_mpi_free(&TA);
2355 mbedtls_mpi_free(&TU);
2356 mbedtls_mpi_free(&U1);
2357 mbedtls_mpi_free(&U2);
2358 mbedtls_mpi_free(&G);
2359 mbedtls_mpi_free(&TB);
2360 mbedtls_mpi_free(&TV);
2361 mbedtls_mpi_free(&V1);
2362 mbedtls_mpi_free(&V2);
2364 return (ret);
2367 #if defined(MBEDTLS_GENPRIME)
2369 static const int small_prime[] = {
2370 3, 5, 7, 11, 13, 17, 19, 23,
2371 29, 31, 37, 41, 43, 47, 53, 59,
2372 61, 67, 71, 73, 79, 83, 89, 97,
2373 101, 103, 107, 109, 113, 127, 131, 137,
2374 139, 149, 151, 157, 163, 167, 173, 179,
2375 181, 191, 193, 197, 199, 211, 223, 227,
2376 229, 233, 239, 241, 251, 257, 263, 269,
2377 271, 277, 281, 283, 293, 307, 311, 313,
2378 317, 331, 337, 347, 349, 353, 359, 367,
2379 373, 379, 383, 389, 397, 401, 409, 419,
2380 421, 431, 433, 439, 443, 449, 457, 461,
2381 463, 467, 479, 487, 491, 499, 503, 509,
2382 521, 523, 541, 547, 557, 563, 569, 571,
2383 577, 587, 593, 599, 601, 607, 613, 617,
2384 619, 631, 641, 643, 647, 653, 659, 661,
2385 673, 677, 683, 691, 701, 709, 719, 727,
2386 733, 739, 743, 751, 757, 761, 769, 773,
2387 787, 797, 809, 811, 821, 823, 827, 829,
2388 839, 853, 857, 859, 863, 877, 881, 883,
2389 887, 907, 911, 919, 929, 937, 941, 947,
2390 953, 967, 971, 977, 983, 991, 997, -103
2394 * Small divisors test (X must be positive)
2396 * Return values:
2397 * 0: no small factor (possible prime, more tests needed)
2398 * 1: certain prime
2399 * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
2400 * other negative: error
2402 static int mpi_check_small_factors(const mbedtls_mpi *X) {
2403 int ret = 0;
2404 size_t i;
2405 mbedtls_mpi_uint r;
2407 if ((X->p[0] & 1) == 0)
2408 return (MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
2410 for (i = 0; small_prime[i] > 0; i++) {
2411 if (mbedtls_mpi_cmp_int(X, small_prime[i]) <= 0)
2412 return (1);
2414 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, small_prime[i]));
2416 if (r == 0)
2417 return (MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
2420 cleanup:
2421 return (ret);
2425 * Miller-Rabin pseudo-primality test (HAC 4.24)
2427 static int mpi_miller_rabin(const mbedtls_mpi *X, size_t rounds,
2428 int (*f_rng)(void *, unsigned char *, size_t),
2429 void *p_rng) {
2430 int ret, count;
2431 size_t i, j, k, s;
2432 mbedtls_mpi W, R, T, A, RR;
2434 MPI_VALIDATE_RET(X != NULL);
2435 MPI_VALIDATE_RET(f_rng != NULL);
2437 mbedtls_mpi_init(&W);
2438 mbedtls_mpi_init(&R);
2439 mbedtls_mpi_init(&T);
2440 mbedtls_mpi_init(&A);
2441 mbedtls_mpi_init(&RR);
2444 * W = |X| - 1
2445 * R = W >> lsb( W )
2447 MBEDTLS_MPI_CHK(mbedtls_mpi_sub_int(&W, X, 1));
2448 s = mbedtls_mpi_lsb(&W);
2449 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&R, &W));
2450 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&R, s));
2452 for (i = 0; i < rounds; i++) {
2454 * pick a random A, 1 < A < |X| - 1
2456 count = 0;
2457 do {
2458 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(&A, X->n * ciL, f_rng, p_rng));
2460 j = mbedtls_mpi_bitlen(&A);
2461 k = mbedtls_mpi_bitlen(&W);
2462 if (j > k) {
2463 A.p[A.n - 1] &= ((mbedtls_mpi_uint) 1 << (k - (A.n - 1) * biL - 1)) - 1;
2466 if (count++ > 30) {
2467 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2468 goto cleanup;
2471 } while (mbedtls_mpi_cmp_mpi(&A, &W) >= 0 ||
2472 mbedtls_mpi_cmp_int(&A, 1) <= 0);
2475 * A = A^R mod |X|
2477 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&A, &A, &R, X, &RR));
2479 if (mbedtls_mpi_cmp_mpi(&A, &W) == 0 ||
2480 mbedtls_mpi_cmp_int(&A, 1) == 0)
2481 continue;
2483 j = 1;
2484 while (j < s && mbedtls_mpi_cmp_mpi(&A, &W) != 0) {
2486 * A = A * A mod |X|
2488 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&T, &A, &A));
2489 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_mpi(&A, &T, X));
2491 if (mbedtls_mpi_cmp_int(&A, 1) == 0)
2492 break;
2494 j++;
2498 * not prime if A != |X| - 1 or A == 1
2500 if (mbedtls_mpi_cmp_mpi(&A, &W) != 0 ||
2501 mbedtls_mpi_cmp_int(&A, 1) == 0) {
2502 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2503 break;
2507 cleanup:
2508 mbedtls_mpi_free(&W);
2509 mbedtls_mpi_free(&R);
2510 mbedtls_mpi_free(&T);
2511 mbedtls_mpi_free(&A);
2512 mbedtls_mpi_free(&RR);
2514 return (ret);
2518 * Pseudo-primality test: small factors, then Miller-Rabin
2520 int mbedtls_mpi_is_prime_ext(const mbedtls_mpi *X, int rounds,
2521 int (*f_rng)(void *, unsigned char *, size_t),
2522 void *p_rng) {
2523 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2524 mbedtls_mpi XX;
2525 MPI_VALIDATE_RET(X != NULL);
2526 MPI_VALIDATE_RET(f_rng != NULL);
2528 XX.s = 1;
2529 XX.n = X->n;
2530 XX.p = X->p;
2532 if (mbedtls_mpi_cmp_int(&XX, 0) == 0 ||
2533 mbedtls_mpi_cmp_int(&XX, 1) == 0)
2534 return (MBEDTLS_ERR_MPI_NOT_ACCEPTABLE);
2536 if (mbedtls_mpi_cmp_int(&XX, 2) == 0)
2537 return (0);
2539 if ((ret = mpi_check_small_factors(&XX)) != 0) {
2540 if (ret == 1)
2541 return (0);
2543 return (ret);
2546 return (mpi_miller_rabin(&XX, rounds, f_rng, p_rng));
2549 #if !defined(MBEDTLS_DEPRECATED_REMOVED)
2551 * Pseudo-primality test, error probability 2^-80
2553 int mbedtls_mpi_is_prime(const mbedtls_mpi *X,
2554 int (*f_rng)(void *, unsigned char *, size_t),
2555 void *p_rng) {
2556 MPI_VALIDATE_RET(X != NULL);
2557 MPI_VALIDATE_RET(f_rng != NULL);
2560 * In the past our key generation aimed for an error rate of at most
2561 * 2^-80. Since this function is deprecated, aim for the same certainty
2562 * here as well.
2564 return (mbedtls_mpi_is_prime_ext(X, 40, f_rng, p_rng));
2566 #endif
2569 * Prime number generation
2571 * To generate an RSA key in a way recommended by FIPS 186-4, both primes must
2572 * be either 1024 bits or 1536 bits long, and flags must contain
2573 * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR.
2575 int mbedtls_mpi_gen_prime(mbedtls_mpi *X, size_t nbits, int flags,
2576 int (*f_rng)(void *, unsigned char *, size_t),
2577 void *p_rng) {
2578 #ifdef MBEDTLS_HAVE_INT64
2579 // ceil(2^63.5)
2580 #define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL
2581 #else
2582 // ceil(2^31.5)
2583 #define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U
2584 #endif
2585 int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2586 size_t k, n;
2587 int rounds;
2588 mbedtls_mpi_uint r;
2589 mbedtls_mpi Y;
2591 MPI_VALIDATE_RET(X != NULL);
2592 MPI_VALIDATE_RET(f_rng != NULL);
2594 if (nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS)
2595 return (MBEDTLS_ERR_MPI_BAD_INPUT_DATA);
2597 mbedtls_mpi_init(&Y);
2599 n = BITS_TO_LIMBS(nbits);
2601 if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR) == 0) {
2603 * 2^-80 error probability, number of rounds chosen per HAC, table 4.4
2605 rounds = ((nbits >= 1300) ? 2 : (nbits >= 850) ? 3 :
2606 (nbits >= 650) ? 4 : (nbits >= 350) ? 8 :
2607 (nbits >= 250) ? 12 : (nbits >= 150) ? 18 : 27);
2608 } else {
2610 * 2^-100 error probability, number of rounds computed based on HAC,
2611 * fact 4.48
2613 rounds = ((nbits >= 1450) ? 4 : (nbits >= 1150) ? 5 :
2614 (nbits >= 1000) ? 6 : (nbits >= 850) ? 7 :
2615 (nbits >= 750) ? 8 : (nbits >= 500) ? 13 :
2616 (nbits >= 250) ? 28 : (nbits >= 150) ? 40 : 51);
2619 while (1) {
2620 MBEDTLS_MPI_CHK(mbedtls_mpi_fill_random(X, n * ciL, f_rng, p_rng));
2621 /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */
2622 if (X->p[n - 1] < CEIL_MAXUINT_DIV_SQRT2) continue;
2624 k = n * biL;
2625 if (k > nbits) MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(X, k - nbits));
2626 X->p[0] |= 1;
2628 if ((flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH) == 0) {
2629 ret = mbedtls_mpi_is_prime_ext(X, rounds, f_rng, p_rng);
2631 if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE)
2632 goto cleanup;
2633 } else {
2635 * An necessary condition for Y and X = 2Y + 1 to be prime
2636 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2637 * Make sure it is satisfied, while keeping X = 3 mod 4
2640 X->p[0] |= 2;
2642 MBEDTLS_MPI_CHK(mbedtls_mpi_mod_int(&r, X, 3));
2643 if (r == 0)
2644 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 8));
2645 else if (r == 1)
2646 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 4));
2648 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2649 MBEDTLS_MPI_CHK(mbedtls_mpi_copy(&Y, X));
2650 MBEDTLS_MPI_CHK(mbedtls_mpi_shift_r(&Y, 1));
2652 while (1) {
2654 * First, check small factors for X and Y
2655 * before doing Miller-Rabin on any of them
2657 if ((ret = mpi_check_small_factors(X)) == 0 &&
2658 (ret = mpi_check_small_factors(&Y)) == 0 &&
2659 (ret = mpi_miller_rabin(X, rounds, f_rng, p_rng))
2660 == 0 &&
2661 (ret = mpi_miller_rabin(&Y, rounds, f_rng, p_rng))
2662 == 0)
2663 goto cleanup;
2665 if (ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE)
2666 goto cleanup;
2669 * Next candidates. We want to preserve Y = (X-1) / 2 and
2670 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2671 * so up Y by 6 and X by 12.
2673 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(X, X, 12));
2674 MBEDTLS_MPI_CHK(mbedtls_mpi_add_int(&Y, &Y, 6));
2679 cleanup:
2681 mbedtls_mpi_free(&Y);
2683 return (ret);
2686 #endif /* MBEDTLS_GENPRIME */
2688 #if defined(MBEDTLS_SELF_TEST)
2690 #define GCD_PAIR_COUNT 3
2692 static const int gcd_pairs[GCD_PAIR_COUNT][3] = {
2693 { 693, 609, 21 },
2694 { 1764, 868, 28 },
2695 { 768454923, 542167814, 1 }
2699 * Checkup routine
2701 int mbedtls_mpi_self_test(int verbose) {
2702 int ret, i;
2703 mbedtls_mpi A, E, N, X, Y, U, V;
2705 mbedtls_mpi_init(&A);
2706 mbedtls_mpi_init(&E);
2707 mbedtls_mpi_init(&N);
2708 mbedtls_mpi_init(&X);
2709 mbedtls_mpi_init(&Y);
2710 mbedtls_mpi_init(&U);
2711 mbedtls_mpi_init(&V);
2713 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&A, 16,
2714 "EFE021C2645FD1DC586E69184AF4A31E" \
2715 "D5F53E93B5F123FA41680867BA110131" \
2716 "944FE7952E2517337780CB0DB80E61AA" \
2717 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6"));
2719 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&E, 16,
2720 "B2E7EFD37075B9F03FF989C7C5051C20" \
2721 "34D2A323810251127E7BF8625A4F49A5" \
2722 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2723 "5B5C25763222FEFCCFC38B832366C29E"));
2725 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&N, 16,
2726 "0066A198186C18C10B2F5ED9B522752A" \
2727 "9830B69916E535C8F047518A889A43A5" \
2728 "94B6BED27A168D31D4A52F88925AA8F5"));
2730 MBEDTLS_MPI_CHK(mbedtls_mpi_mul_mpi(&X, &A, &N));
2732 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
2733 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2734 "9E857EA95A03512E2BAE7391688D264A" \
2735 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2736 "8001B72E848A38CAE1C65F78E56ABDEF" \
2737 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2738 "ECF677152EF804370C1A305CAF3B5BF1" \
2739 "30879B56C61DE584A0F53A2447A51E"));
2741 if (verbose != 0)
2742 mbedtls_printf(" MPI test #1 (mul_mpi): ");
2744 if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {
2745 if (verbose != 0)
2746 mbedtls_printf("failed\n");
2748 ret = 1;
2749 goto cleanup;
2752 if (verbose != 0)
2753 mbedtls_printf("passed\n");
2755 MBEDTLS_MPI_CHK(mbedtls_mpi_div_mpi(&X, &Y, &A, &N));
2757 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
2758 "256567336059E52CAE22925474705F39A94"));
2760 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&V, 16,
2761 "6613F26162223DF488E9CD48CC132C7A" \
2762 "0AC93C701B001B092E4E5B9F73BCD27B" \
2763 "9EE50D0657C77F374E903CDFA4C642"));
2765 if (verbose != 0)
2766 mbedtls_printf(" MPI test #2 (div_mpi): ");
2768 if (mbedtls_mpi_cmp_mpi(&X, &U) != 0 ||
2769 mbedtls_mpi_cmp_mpi(&Y, &V) != 0) {
2770 if (verbose != 0)
2771 mbedtls_printf("failed\n");
2773 ret = 1;
2774 goto cleanup;
2777 if (verbose != 0)
2778 mbedtls_printf("passed\n");
2780 MBEDTLS_MPI_CHK(mbedtls_mpi_exp_mod(&X, &A, &E, &N, NULL));
2782 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
2783 "36E139AEA55215609D2816998ED020BB" \
2784 "BD96C37890F65171D948E9BC7CBAA4D9" \
2785 "325D24D6A3C12710F10A09FA08AB87"));
2787 if (verbose != 0)
2788 mbedtls_printf(" MPI test #3 (exp_mod): ");
2790 if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {
2791 if (verbose != 0)
2792 mbedtls_printf("failed\n");
2794 ret = 1;
2795 goto cleanup;
2798 if (verbose != 0)
2799 mbedtls_printf("passed\n");
2801 MBEDTLS_MPI_CHK(mbedtls_mpi_inv_mod(&X, &A, &N));
2803 MBEDTLS_MPI_CHK(mbedtls_mpi_read_string(&U, 16,
2804 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2805 "C3DBA76456363A10869622EAC2DD84EC" \
2806 "C5B8A74DAC4D09E03B5E0BE779F2DF61"));
2808 if (verbose != 0)
2809 mbedtls_printf(" MPI test #4 (inv_mod): ");
2811 if (mbedtls_mpi_cmp_mpi(&X, &U) != 0) {
2812 if (verbose != 0)
2813 mbedtls_printf("failed\n");
2815 ret = 1;
2816 goto cleanup;
2819 if (verbose != 0)
2820 mbedtls_printf("passed\n");
2822 if (verbose != 0)
2823 mbedtls_printf(" MPI test #5 (simple gcd): ");
2825 for (i = 0; i < GCD_PAIR_COUNT; i++) {
2826 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&X, gcd_pairs[i][0]));
2827 MBEDTLS_MPI_CHK(mbedtls_mpi_lset(&Y, gcd_pairs[i][1]));
2829 MBEDTLS_MPI_CHK(mbedtls_mpi_gcd(&A, &X, &Y));
2831 if (mbedtls_mpi_cmp_int(&A, gcd_pairs[i][2]) != 0) {
2832 if (verbose != 0)
2833 mbedtls_printf("failed at %d\n", i);
2835 ret = 1;
2836 goto cleanup;
2840 if (verbose != 0)
2841 mbedtls_printf("passed\n");
2843 cleanup:
2845 if (ret != 0 && verbose != 0)
2846 mbedtls_printf("Unexpected error, return code = %08X\n", (unsigned int) ret);
2848 mbedtls_mpi_free(&A);
2849 mbedtls_mpi_free(&E);
2850 mbedtls_mpi_free(&N);
2851 mbedtls_mpi_free(&X);
2852 mbedtls_mpi_free(&Y);
2853 mbedtls_mpi_free(&U);
2854 mbedtls_mpi_free(&V);
2856 if (verbose != 0)
2857 mbedtls_printf("\n");
2859 return (ret);
2862 #endif /* MBEDTLS_SELF_TEST */
2864 #endif /* MBEDTLS_BIGNUM_C */