2 * Multi-precision integer library
4 * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
6 * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
7 * Copyright (C) 2010 StackFoundry LLC <yann@stackfoundry.com>
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
14 * * Redistributions of source code must retain the above copyright
15 * notice, this list of conditions and the following disclaimer.
16 * * Redistributions in binary form must reproduce the above copyright
17 * notice, this list of conditions and the following disclaimer in the
18 * documentation and/or other materials provided with the distribution.
19 * * Neither the names of Tropic SSL,
20 * PolarSSL or XySSL nor the names of its contributors
21 * may be used to endorse or promote products derived from this software
22 * without specific prior written permission.
24 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
25 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
26 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
27 * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
28 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
29 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED
30 * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
31 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
32 * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
33 * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
34 * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
37 * This MPI implementation is based on:
39 * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
40 * http://www.stillhq.com/extracted/gnupg-api/mpi/
41 * http://math.libtomcrypt.com/files/tommath.pdf
44 #include "tropicssl/config.h"
46 #if defined(TROPICSSL_BIGNUM_C)
48 #include "tropicssl/bignum.h"
49 #include "tropicssl/bn_mul.h"
55 #define ciL ((int) sizeof(t_int)) /* chars in limb */
56 #define biL (ciL << 3) /* bits in limb */
57 #define biH (ciL << 2) /* half limb size */
60 * Convert between bits/chars and number of limbs
62 #define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
63 #define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
68 void mpi_init(mpi
* X
)
81 void mpi_free(mpi
* X
)
88 memset(X
->p
, 0, X
->n
* ciL
);
98 * Enlarge to the specified number of limbs
100 int mpi_grow(mpi
* X
, int nblimbs
)
104 if (X
->n
< nblimbs
) {
105 if ((p
= (t_int
*) malloc(nblimbs
* ciL
)) == NULL
)
108 memset(p
, 0, nblimbs
* ciL
);
111 memcpy(p
, X
->p
, X
->n
* ciL
);
112 memset(X
->p
, 0, X
->n
* ciL
);
124 * Copy the contents of Y into X
126 int mpi_copy(mpi
* X
, const mpi
* Y
)
133 for (i
= Y
->n
- 1; i
> 0; i
--)
140 MPI_CHK(mpi_grow(X
, i
));
142 memset(X
->p
, 0, X
->n
* ciL
);
143 memcpy(X
->p
, Y
->p
, i
* ciL
);
151 * Swap the contents of X and Y
153 void mpi_swap(mpi
* X
, mpi
* Y
)
157 memcpy(&T
, X
, sizeof(mpi
));
158 memcpy(X
, Y
, sizeof(mpi
));
159 memcpy(Y
, &T
, sizeof(mpi
));
163 * Set value from integer
165 int mpi_lset(mpi
* X
, int z
)
169 MPI_CHK(mpi_grow(X
, 1));
170 memset(X
->p
, 0, X
->n
* ciL
);
172 X
->p
[0] = (z
< 0) ? -z
: z
;
173 X
->s
= (z
< 0) ? -1 : 1;
181 * Return the number of least significant bits
183 int mpi_lsb(const mpi
* X
)
187 for (i
= 0; i
< X
->n
; i
++)
188 for (j
= 0; j
< (int)biL
; j
++, count
++)
189 if (((X
->p
[i
] >> j
) & 1) != 0)
196 * Return the number of most significant bits
198 int mpi_msb(const mpi
* X
)
202 for (i
= X
->n
- 1; i
> 0; i
--)
206 for (j
= biL
- 1; j
>= 0; j
--)
207 if (((X
->p
[i
] >> j
) & 1) != 0)
210 return ((i
* biL
) + j
+ 1);
214 * Return the total size in bytes
216 int mpi_size(const mpi
* X
)
218 return ((mpi_msb(X
) + 7) >> 3);
222 * Convert an ASCII character to digit value
224 static int mpi_get_digit(t_int
* d
, int radix
, char c
)
228 if (c
>= 0x30 && c
<= 0x39)
230 if (c
>= 0x41 && c
<= 0x46)
232 if (c
>= 0x61 && c
<= 0x66)
235 if (*d
>= (t_int
) radix
)
236 return (TROPICSSL_ERR_MPI_INVALID_CHARACTER
);
242 * Import from an ASCII string
244 int mpi_read_string(mpi
* X
, int radix
, const char *s
)
250 if (radix
< 2 || radix
> 16)
251 return (TROPICSSL_ERR_MPI_BAD_INPUT_DATA
);
256 n
= BITS_TO_LIMBS(strlen(s
) << 2);
258 MPI_CHK(mpi_grow(X
, n
));
259 MPI_CHK(mpi_lset(X
, 0));
261 for (i
= strlen(s
) - 1, j
= 0; i
>= 0; i
--, j
++) {
262 if (i
== 0 && s
[i
] == '-') {
267 MPI_CHK(mpi_get_digit(&d
, radix
, s
[i
]));
268 X
->p
[j
/ (2 * ciL
)] |= d
<< ((j
% (2 * ciL
)) << 2);
271 MPI_CHK(mpi_lset(X
, 0));
273 for (i
= 0; i
< (int)strlen(s
); i
++) {
274 if (i
== 0 && s
[i
] == '-') {
279 MPI_CHK(mpi_get_digit(&d
, radix
, s
[i
]));
280 MPI_CHK(mpi_mul_int(&T
, X
, radix
));
281 MPI_CHK(mpi_add_int(X
, &T
, d
));
293 * Helper to write the digits high-order first
295 static int mpi_write_hlp(mpi
* X
, int radix
, char **p
)
300 if (radix
< 2 || radix
> 16)
301 return (TROPICSSL_ERR_MPI_BAD_INPUT_DATA
);
303 MPI_CHK(mpi_mod_int(&r
, X
, radix
));
304 MPI_CHK(mpi_div_int(X
, NULL
, X
, radix
));
306 if (mpi_cmp_int(X
, 0) != 0)
307 MPI_CHK(mpi_write_hlp(X
, radix
, p
));
310 *(*p
)++ = (char)(r
+ 0x30);
312 *(*p
)++ = (char)(r
+ 0x37);
320 * Export into an ASCII string
322 int mpi_write_string(const mpi
* X
, int radix
, char *s
, int *slen
)
328 if (radix
< 2 || radix
> 16)
329 return (TROPICSSL_ERR_MPI_BAD_INPUT_DATA
);
340 return (TROPICSSL_ERR_MPI_BUFFER_TOO_SMALL
);
352 for (i
= X
->n
- 1, k
= 0; i
>= 0; i
--) {
353 for (j
= ciL
- 1; j
>= 0; j
--) {
354 c
= (X
->p
[i
] >> (j
<< 3)) & 0xFF;
356 if (c
== 0 && k
== 0 && (i
+ j
) != 0)
359 p
+= sprintf(p
, "%02X", c
);
364 MPI_CHK(mpi_copy(&T
, X
));
365 MPI_CHK(mpi_write_hlp(&T
, radix
, &p
));
379 * Read X from an opened file
381 int mpi_read_file(mpi
* X
, int radix
, FILE * fin
)
388 memset(s
, 0, sizeof(s
));
389 if (fgets(s
, sizeof(s
) - 1, fin
) == NULL
)
390 return (TROPICSSL_ERR_MPI_FILE_IO_ERROR
);
393 if (s
[slen
- 1] == '\n') {
397 if (s
[slen
- 1] == '\r') {
404 if (mpi_get_digit(&d
, radix
, *p
) != 0)
407 return (mpi_read_string(X
, radix
, p
+ 1));
411 * Write X into an opened file (or stdout if fout == NULL)
413 int mpi_write_file(const char *p
, const mpi
* X
, int radix
, FILE * fout
)
424 MPI_CHK(mpi_write_string(X
, radix
, s
, (int *)&n
));
435 if (fwrite(p
, 1, plen
, fout
) != plen
||
436 fwrite(s
, 1, slen
, fout
) != slen
)
437 return (TROPICSSL_ERR_MPI_FILE_IO_ERROR
);
439 printf("%s%s", p
, s
);
447 * Import X from unsigned binary data, big endian
449 int mpi_read_binary(mpi
* X
, const unsigned char *buf
, int buflen
)
453 for (n
= 0; n
< buflen
; n
++)
457 MPI_CHK(mpi_grow(X
, CHARS_TO_LIMBS(buflen
- n
)));
458 MPI_CHK(mpi_lset(X
, 0));
460 for (i
= buflen
- 1, j
= 0; i
>= n
; i
--, j
++)
461 X
->p
[j
/ ciL
] |= ((t_int
) buf
[i
]) << ((j
% ciL
) << 3);
469 * Export X into unsigned binary data, big endian
471 int mpi_write_binary(const mpi
* X
, unsigned char *buf
, int buflen
)
478 return (TROPICSSL_ERR_MPI_BUFFER_TOO_SMALL
);
480 memset(buf
, 0, buflen
);
482 for (i
= buflen
- 1, j
= 0; n
> 0; i
--, j
++, n
--)
483 buf
[i
] = (unsigned char)(X
->p
[j
/ ciL
] >> ((j
% ciL
) << 3));
489 * Left-shift: X <<= count
491 int mpi_shift_l(mpi
* X
, int count
)
497 t1
= count
& (biL
- 1);
499 i
= mpi_msb(X
) + count
;
501 if (X
->n
* (int)biL
< i
)
502 MPI_CHK(mpi_grow(X
, BITS_TO_LIMBS(i
)));
507 * shift by count / limb_size
510 for (i
= X
->n
- 1; i
>= v0
; i
--)
511 X
->p
[i
] = X
->p
[i
- v0
];
518 * shift by count % limb_size
521 for (i
= v0
; i
< X
->n
; i
++) {
522 r1
= X
->p
[i
] >> (biL
- t1
);
535 * Right-shift: X >>= count
537 int mpi_shift_r(mpi
* X
, int count
)
543 v1
= count
& (biL
- 1);
546 * shift by count / limb_size
549 for (i
= 0; i
< X
->n
- v0
; i
++)
550 X
->p
[i
] = X
->p
[i
+ v0
];
552 for (; i
< X
->n
; i
++)
557 * shift by count % limb_size
560 for (i
= X
->n
- 1; i
>= 0; i
--) {
561 r1
= X
->p
[i
] << (biL
- v1
);
572 * Compare unsigned values
574 int mpi_cmp_abs(const mpi
* X
, const mpi
* Y
)
578 for (i
= X
->n
- 1; i
>= 0; i
--)
582 for (j
= Y
->n
- 1; j
>= 0; j
--)
594 for (; i
>= 0; i
--) {
595 if (X
->p
[i
] > Y
->p
[i
])
597 if (X
->p
[i
] < Y
->p
[i
])
605 * Compare signed values
607 int mpi_cmp_mpi(const mpi
* X
, const mpi
* Y
)
611 for (i
= X
->n
- 1; i
>= 0; i
--)
615 for (j
= Y
->n
- 1; j
>= 0; j
--)
627 if (X
->s
> 0 && Y
->s
< 0)
629 if (Y
->s
> 0 && X
->s
< 0)
632 for (; i
>= 0; i
--) {
633 if (X
->p
[i
] > Y
->p
[i
])
635 if (X
->p
[i
] < Y
->p
[i
])
643 * Compare signed values
645 int mpi_cmp_int(const mpi
* X
, int z
)
650 *p
= (z
< 0) ? -z
: z
;
651 Y
.s
= (z
< 0) ? -1 : 1;
655 return (mpi_cmp_mpi(X
, &Y
));
659 * Unsigned addition: X = |A| + |B| (HAC 14.7)
661 int mpi_add_abs(mpi
* X
, const mpi
* A
, const mpi
* B
)
673 MPI_CHK(mpi_copy(X
, A
));
675 for (j
= B
->n
- 1; j
>= 0; j
--)
679 MPI_CHK(mpi_grow(X
, j
+ 1));
685 for (i
= 0; i
<= j
; i
++, o
++, p
++) {
694 MPI_CHK(mpi_grow(X
, i
+ 1));
709 * Helper for mpi substraction
711 static void mpi_sub_hlp(int n
, t_int
* s
, t_int
* d
)
716 for (i
= c
= 0; i
< n
; i
++, s
++, d
++) {
733 * Unsigned substraction: X = |A| - |B| (HAC 14.9)
735 int mpi_sub_abs(mpi
* X
, const mpi
* A
, const mpi
* B
)
740 if (mpi_cmp_abs(A
, B
) < 0)
741 return (TROPICSSL_ERR_MPI_NEGATIVE_VALUE
);
746 MPI_CHK(mpi_copy(&TB
, B
));
751 MPI_CHK(mpi_copy(X
, A
));
755 for (n
= B
->n
- 1; n
>= 0; n
--)
759 mpi_sub_hlp(n
+ 1, B
->p
, X
->p
);
769 * Signed addition: X = A + B
771 int mpi_add_mpi(mpi
* X
, const mpi
* A
, const mpi
* B
)
775 if (A
->s
* B
->s
< 0) {
776 if (mpi_cmp_abs(A
, B
) >= 0) {
777 MPI_CHK(mpi_sub_abs(X
, A
, B
));
780 MPI_CHK(mpi_sub_abs(X
, B
, A
));
784 MPI_CHK(mpi_add_abs(X
, A
, B
));
794 * Signed substraction: X = A - B
796 int mpi_sub_mpi(mpi
* X
, const mpi
* A
, const mpi
* B
)
800 if (A
->s
* B
->s
> 0) {
801 if (mpi_cmp_abs(A
, B
) >= 0) {
802 MPI_CHK(mpi_sub_abs(X
, A
, B
));
805 MPI_CHK(mpi_sub_abs(X
, B
, A
));
809 MPI_CHK(mpi_add_abs(X
, A
, B
));
819 * Signed addition: X = A + b
821 int mpi_add_int(mpi
* X
, const mpi
* A
, int b
)
826 p
[0] = (b
< 0) ? -b
: b
;
827 _B
.s
= (b
< 0) ? -1 : 1;
831 return (mpi_add_mpi(X
, A
, &_B
));
835 * Signed substraction: X = A - b
837 int mpi_sub_int(mpi
* X
, const mpi
* A
, int b
)
842 p
[0] = (b
< 0) ? -b
: b
;
843 _B
.s
= (b
< 0) ? -1 : 1;
847 return (mpi_sub_mpi(X
, A
, &_B
));
851 * Helper for mpi multiplication
853 static void mpi_mul_hlp(int i
, t_int
* s
, t_int
* d
, t_int b
)
857 #if defined(MULADDC_HUIT)
858 for (; i
>= 8; i
-= 8) {
859 MULADDC_INIT MULADDC_HUIT MULADDC_STOP
} for (; i
> 0; i
--) {
860 MULADDC_INIT MULADDC_CORE MULADDC_STOP
}
862 for (; i
>= 16; i
-= 16) {
864 MULADDC_CORE MULADDC_CORE
865 MULADDC_CORE MULADDC_CORE
866 MULADDC_CORE MULADDC_CORE
867 MULADDC_CORE MULADDC_CORE
868 MULADDC_CORE MULADDC_CORE
869 MULADDC_CORE MULADDC_CORE
870 MULADDC_CORE MULADDC_CORE
871 MULADDC_CORE MULADDC_CORE MULADDC_STOP
}
873 for (; i
>= 8; i
-= 8) {
875 MULADDC_CORE MULADDC_CORE
876 MULADDC_CORE MULADDC_CORE
877 MULADDC_CORE MULADDC_CORE
878 MULADDC_CORE MULADDC_CORE MULADDC_STOP
}
881 MULADDC_INIT MULADDC_CORE MULADDC_STOP
}
893 * Baseline multiplication: X = A * B (HAC 14.12)
895 int mpi_mul_mpi(mpi
* X
, const mpi
* A
, const mpi
* B
)
900 mpi_init(&TA
); mpi_init(&TB
);
903 MPI_CHK(mpi_copy(&TA
, A
));
907 MPI_CHK(mpi_copy(&TB
, B
));
911 for (i
= A
->n
- 1; i
>= 0; i
--)
915 for (j
= B
->n
- 1; j
>= 0; j
--)
919 MPI_CHK(mpi_grow(X
, i
+ j
+ 2));
920 MPI_CHK(mpi_lset(X
, 0));
922 for (i
++; j
>= 0; j
--)
923 mpi_mul_hlp(i
, A
->p
, X
->p
+ j
, B
->p
[j
]);
929 mpi_free(&TB
); mpi_free(&TA
);
935 * Baseline multiplication: X = A * b
937 int mpi_mul_int(mpi
* X
, const mpi
* A
, t_int b
)
947 return (mpi_mul_mpi(X
, A
, &_B
));
951 * Division by mpi: A = Q * B + R (HAC 14.20)
953 int mpi_div_mpi(mpi
* Q
, mpi
* R
, const mpi
* A
, const mpi
* B
)
958 if (mpi_cmp_int(B
, 0) == 0)
959 return (TROPICSSL_ERR_MPI_DIVISION_BY_ZERO
);
961 mpi_init(&X
); mpi_init(&Y
); mpi_init(&Z
);
962 mpi_init(&T1
); mpi_init(&T2
);
964 if (mpi_cmp_abs(A
, B
) < 0) {
966 MPI_CHK(mpi_lset(Q
, 0));
968 MPI_CHK(mpi_copy(R
, A
));
972 MPI_CHK(mpi_copy(&X
, A
));
973 MPI_CHK(mpi_copy(&Y
, B
));
976 MPI_CHK(mpi_grow(&Z
, A
->n
+ 2));
977 MPI_CHK(mpi_lset(&Z
, 0));
978 MPI_CHK(mpi_grow(&T1
, 2));
979 MPI_CHK(mpi_grow(&T2
, 3));
981 k
= mpi_msb(&Y
) % biL
;
982 if (k
< (int)biL
- 1) {
984 MPI_CHK(mpi_shift_l(&X
, k
));
985 MPI_CHK(mpi_shift_l(&Y
, k
));
991 mpi_shift_l(&Y
, biL
* (n
- t
));
993 while (mpi_cmp_mpi(&X
, &Y
) >= 0) {
995 mpi_sub_mpi(&X
, &X
, &Y
);
997 mpi_shift_r(&Y
, biL
* (n
- t
));
999 for (i
= n
; i
> t
; i
--) {
1000 if (X
.p
[i
] >= Y
.p
[t
])
1001 Z
.p
[i
- t
- 1] = ~0;
1003 #if defined(TROPICSSL_HAVE_LONGLONG)
1006 r
= (t_dbl
) X
.p
[i
] << biL
;
1007 r
|= (t_dbl
) X
.p
[i
- 1];
1009 if (r
> ((t_dbl
) 1 << biL
) - 1)
1010 r
= ((t_dbl
) 1 << biL
) - 1;
1012 Z
.p
[i
- t
- 1] = (t_int
) r
;
1015 * __udiv_qrnnd_c, from gmp/longlong.h
1017 t_int q0
, q1
, r0
, r1
;
1021 d0
= (d
<< biH
) >> biH
;
1025 r1
= X
.p
[i
] - d1
* q1
;
1027 r1
|= (X
.p
[i
- 1] >> biH
);
1032 while (r1
>= d
&& r1
< m
)
1040 r0
|= (X
.p
[i
- 1] << biH
) >> biH
;
1045 while (r0
>= d
&& r0
< m
)
1050 Z
.p
[i
- t
- 1] = (q1
<< biH
) | q0
;
1058 MPI_CHK(mpi_lset(&T1
, 0));
1059 T1
.p
[0] = (t
< 1) ? 0 : Y
.p
[t
- 1];
1061 MPI_CHK(mpi_mul_int(&T1
, &T1
, Z
.p
[i
- t
- 1]));
1063 MPI_CHK(mpi_lset(&T2
, 0));
1064 T2
.p
[0] = (i
< 2) ? 0 : X
.p
[i
- 2];
1065 T2
.p
[1] = (i
< 1) ? 0 : X
.p
[i
- 1];
1067 } while (mpi_cmp_mpi(&T1
, &T2
) > 0);
1069 MPI_CHK(mpi_mul_int(&T1
, &Y
, Z
.p
[i
- t
- 1]));
1070 MPI_CHK(mpi_shift_l(&T1
, biL
* (i
- t
- 1)));
1071 MPI_CHK(mpi_sub_mpi(&X
, &X
, &T1
));
1073 if (mpi_cmp_int(&X
, 0) < 0) {
1074 MPI_CHK(mpi_copy(&T1
, &Y
));
1075 MPI_CHK(mpi_shift_l(&T1
, biL
* (i
- t
- 1)));
1076 MPI_CHK(mpi_add_mpi(&X
, &X
, &T1
));
1091 if (mpi_cmp_int(R
, 0) == 0)
1097 mpi_free(&X
); mpi_free(&Y
); mpi_free(&Z
);
1098 mpi_free(&T1
); mpi_free(&T2
);
1104 * Division by int: A = Q * b + R
1106 * Returns 0 if successful
1107 * 1 if memory allocation failed
1108 * TROPICSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
1110 int mpi_div_int(mpi
* Q
, mpi
* R
, const mpi
* A
, int b
)
1115 p
[0] = (b
< 0) ? -b
: b
;
1116 _B
.s
= (b
< 0) ? -1 : 1;
1120 return (mpi_div_mpi(Q
, R
, A
, &_B
));
1124 * Modulo: R = A mod B
1126 int mpi_mod_mpi(mpi
* R
, const mpi
* A
, const mpi
* B
)
1130 MPI_CHK(mpi_div_mpi(NULL
, R
, A
, B
));
1132 while (mpi_cmp_int(R
, 0) < 0)
1133 MPI_CHK(mpi_add_mpi(R
, R
, B
));
1135 while (mpi_cmp_mpi(R
, B
) >= 0)
1136 MPI_CHK(mpi_sub_mpi(R
, R
, B
));
1144 * Modulo: r = A mod b
1146 int mpi_mod_int(t_int
* r
, const mpi
* A
, int b
)
1152 return (TROPICSSL_ERR_MPI_DIVISION_BY_ZERO
);
1158 * handle trivial cases
1173 for (i
= A
->n
- 1, y
= 0; i
>= 0; i
--) {
1175 y
= (y
<< biH
) | (x
>> biH
);
1180 y
= (y
<< biH
) | (x
>> biH
);
1191 * Fast Montgomery initialization (thanks to Tom St Denis)
1193 static void mpi_montg_init(t_int
* mm
, const mpi
* N
)
1195 t_int x
, m0
= N
->p
[0];
1198 x
+= ((m0
+ 2) & 4) << 1;
1199 x
*= (2 - (m0
* x
));
1202 x
*= (2 - (m0
* x
));
1204 x
*= (2 - (m0
* x
));
1206 x
*= (2 - (m0
* x
));
1212 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1214 static void mpi_montmul(mpi
* A
, const mpi
* B
, const mpi
* N
, t_int mm
, mpi
* T
)
1219 memset(T
->p
, 0, T
->n
* ciL
);
1223 m
= (B
->n
< n
) ? B
->n
: n
;
1225 for (i
= 0; i
< n
; i
++) {
1227 * T = (T + u0*B + u1*N) / 2^biL
1230 u1
= (d
[0] + u0
* B
->p
[0]) * mm
;
1232 mpi_mul_hlp(m
, B
->p
, d
, u0
);
1233 mpi_mul_hlp(n
, N
->p
, d
, u1
);
1239 memcpy(A
->p
, d
, (n
+ 1) * ciL
);
1241 if (mpi_cmp_abs(A
, N
) >= 0)
1242 mpi_sub_hlp(n
, N
->p
, A
->p
);
1244 /* prevent timing attacks */
1245 mpi_sub_hlp(n
, A
->p
, T
->p
);
1249 * Montgomery reduction: A = A * R^-1 mod N
1251 static void mpi_montred(mpi
* A
, const mpi
* N
, t_int mm
, mpi
* T
)
1259 mpi_montmul(A
, &U
, N
, mm
, T
);
1263 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1265 int mpi_exp_mod(mpi
* X
, const mpi
* A
, const mpi
* E
, const mpi
* N
, mpi
* _RR
)
1267 int ret
, i
, j
, wsize
, wbits
;
1268 int bufsize
, nblimbs
, nbits
;
1269 t_int ei
, mm
, state
;
1272 if (mpi_cmp_int(N
, 0) < 0 || (N
->p
[0] & 1) == 0)
1273 return (TROPICSSL_ERR_MPI_BAD_INPUT_DATA
);
1276 * Init temps and window size
1278 mpi_montg_init(&mm
, N
);
1279 mpi_init(&RR
); mpi_init(&T
);
1280 memset(W
, 0, sizeof(W
));
1284 wsize
= (i
> 671) ? 6 : (i
> 239) ? 5 : (i
> 79) ? 4 : (i
> 23) ? 3 : 1;
1287 MPI_CHK(mpi_grow(X
, j
));
1288 MPI_CHK(mpi_grow(&W
[1], j
));
1289 MPI_CHK(mpi_grow(&T
, j
* 2));
1292 * If 1st call, pre-compute R^2 mod N
1294 if (_RR
== NULL
|| _RR
->p
== NULL
) {
1295 MPI_CHK(mpi_lset(&RR
, 1));
1296 MPI_CHK(mpi_shift_l(&RR
, N
->n
* 2 * biL
));
1297 MPI_CHK(mpi_mod_mpi(&RR
, &RR
, N
));
1300 memcpy(_RR
, &RR
, sizeof(mpi
));
1302 memcpy(&RR
, _RR
, sizeof(mpi
));
1305 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1307 if (mpi_cmp_mpi(A
, N
) >= 0)
1308 mpi_mod_mpi(&W
[1], A
, N
);
1312 mpi_montmul(&W
[1], &RR
, N
, mm
, &T
);
1315 * X = R^2 * R^-1 mod N = R mod N
1317 MPI_CHK(mpi_copy(X
, &RR
));
1318 mpi_montred(X
, N
, mm
, &T
);
1322 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1324 j
= 1 << (wsize
- 1);
1326 MPI_CHK(mpi_grow(&W
[j
], N
->n
+ 1));
1327 MPI_CHK(mpi_copy(&W
[j
], &W
[1]));
1329 for (i
= 0; i
< wsize
- 1; i
++)
1330 mpi_montmul(&W
[j
], &W
[j
], N
, mm
, &T
);
1333 * W[i] = W[i - 1] * W[1]
1335 for (i
= j
+ 1; i
< (1 << wsize
); i
++) {
1336 MPI_CHK(mpi_grow(&W
[i
], N
->n
+ 1));
1337 MPI_CHK(mpi_copy(&W
[i
], &W
[i
- 1]));
1339 mpi_montmul(&W
[i
], &W
[1], N
, mm
, &T
);
1354 bufsize
= sizeof(t_int
) << 3;
1359 ei
= (E
->p
[nblimbs
] >> bufsize
) & 1;
1364 if (ei
== 0 && state
== 0)
1367 if (ei
== 0 && state
== 1) {
1369 * out of window, square X
1371 mpi_montmul(X
, X
, N
, mm
, &T
);
1376 * add ei to current window
1381 wbits
|= (ei
<< (wsize
- nbits
));
1383 if (nbits
== wsize
) {
1385 * X = X^wsize R^-1 mod N
1387 for (i
= 0; i
< wsize
; i
++)
1388 mpi_montmul(X
, X
, N
, mm
, &T
);
1391 * X = X * W[wbits] R^-1 mod N
1393 mpi_montmul(X
, &W
[wbits
], N
, mm
, &T
);
1402 * process the remaining bits
1404 for (i
= 0; i
< nbits
; i
++) {
1405 mpi_montmul(X
, X
, N
, mm
, &T
);
1409 if ((wbits
& (1 << wsize
)) != 0)
1410 mpi_montmul(X
, &W
[1], N
, mm
, &T
);
1414 * X = A^E * R * R^-1 mod N = A^E mod N
1416 mpi_montred(X
, N
, mm
, &T
);
1420 for (i
= (1 << (wsize
- 1)); i
< (1 << wsize
); i
++)
1423 mpi_free(&W
[1]); mpi_free(&T
);
1432 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1434 int mpi_gcd(mpi
* G
, const mpi
* A
, const mpi
* B
)
1439 mpi_init(&TG
); mpi_init(&TA
); mpi_init(&TB
);
1441 MPI_CHK(mpi_copy(&TA
, A
));
1442 MPI_CHK(mpi_copy(&TB
, B
));
1450 MPI_CHK(mpi_shift_r(&TA
, lz
));
1451 MPI_CHK(mpi_shift_r(&TB
, lz
));
1455 while (mpi_cmp_int(&TA
, 0) != 0) {
1456 MPI_CHK(mpi_shift_r(&TA
, mpi_lsb(&TA
)));
1457 MPI_CHK(mpi_shift_r(&TB
, mpi_lsb(&TB
)));
1459 if (mpi_cmp_mpi(&TA
, &TB
) >= 0) {
1460 MPI_CHK(mpi_sub_abs(&TA
, &TA
, &TB
));
1461 MPI_CHK(mpi_shift_r(&TA
, 1));
1463 MPI_CHK(mpi_sub_abs(&TB
, &TB
, &TA
));
1464 MPI_CHK(mpi_shift_r(&TB
, 1));
1468 MPI_CHK(mpi_shift_l(&TB
, lz
));
1469 MPI_CHK(mpi_copy(G
, &TB
));
1473 mpi_free(&TB
); mpi_free(&TA
); mpi_free(&TG
);
1478 #if defined(TROPICSSL_GENPRIME)
1481 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1483 int mpi_inv_mod(mpi
* X
, const mpi
* A
, const mpi
* N
)
1486 mpi G
, TA
, TU
, U1
, U2
, TB
, TV
, V1
, V2
;
1488 if (mpi_cmp_int(N
, 0) <= 0)
1489 return (TROPICSSL_ERR_MPI_BAD_INPUT_DATA
);
1491 mpi_init(&TA
); mpi_init(&TU
); mpi_init(&U1
); mpi_init(&U2
);
1492 mpi_init(&G
); mpi_init(&TB
); mpi_init(&TV
);
1493 mpi_init(&V1
); mpi_init(&V2
);
1495 MPI_CHK(mpi_gcd(&G
, A
, N
));
1497 if (mpi_cmp_int(&G
, 1) != 0) {
1498 ret
= TROPICSSL_ERR_MPI_NOT_ACCEPTABLE
;
1502 MPI_CHK(mpi_mod_mpi(&TA
, A
, N
));
1503 MPI_CHK(mpi_copy(&TU
, &TA
));
1504 MPI_CHK(mpi_copy(&TB
, N
));
1505 MPI_CHK(mpi_copy(&TV
, N
));
1507 MPI_CHK(mpi_lset(&U1
, 1));
1508 MPI_CHK(mpi_lset(&U2
, 0));
1509 MPI_CHK(mpi_lset(&V1
, 0));
1510 MPI_CHK(mpi_lset(&V2
, 1));
1513 while ((TU
.p
[0] & 1) == 0) {
1514 MPI_CHK(mpi_shift_r(&TU
, 1));
1516 if ((U1
.p
[0] & 1) != 0 || (U2
.p
[0] & 1) != 0) {
1517 MPI_CHK(mpi_add_mpi(&U1
, &U1
, &TB
));
1518 MPI_CHK(mpi_sub_mpi(&U2
, &U2
, &TA
));
1521 MPI_CHK(mpi_shift_r(&U1
, 1));
1522 MPI_CHK(mpi_shift_r(&U2
, 1));
1525 while ((TV
.p
[0] & 1) == 0) {
1526 MPI_CHK(mpi_shift_r(&TV
, 1));
1528 if ((V1
.p
[0] & 1) != 0 || (V2
.p
[0] & 1) != 0) {
1529 MPI_CHK(mpi_add_mpi(&V1
, &V1
, &TB
));
1530 MPI_CHK(mpi_sub_mpi(&V2
, &V2
, &TA
));
1533 MPI_CHK(mpi_shift_r(&V1
, 1));
1534 MPI_CHK(mpi_shift_r(&V2
, 1));
1537 if (mpi_cmp_mpi(&TU
, &TV
) >= 0) {
1538 MPI_CHK(mpi_sub_mpi(&TU
, &TU
, &TV
));
1539 MPI_CHK(mpi_sub_mpi(&U1
, &U1
, &V1
));
1540 MPI_CHK(mpi_sub_mpi(&U2
, &U2
, &V2
));
1542 MPI_CHK(mpi_sub_mpi(&TV
, &TV
, &TU
));
1543 MPI_CHK(mpi_sub_mpi(&V1
, &V1
, &U1
));
1544 MPI_CHK(mpi_sub_mpi(&V2
, &V2
, &U2
));
1546 } while (mpi_cmp_int(&TU
, 0) != 0);
1548 while (mpi_cmp_int(&V1
, 0) < 0)
1549 MPI_CHK(mpi_add_mpi(&V1
, &V1
, N
));
1551 while (mpi_cmp_mpi(&V1
, N
) >= 0)
1552 MPI_CHK(mpi_sub_mpi(&V1
, &V1
, N
));
1554 MPI_CHK(mpi_copy(X
, &V1
));
1558 mpi_free(&V2
); mpi_free(&V1
); mpi_free(&TV
); mpi_free(&TB
);
1559 mpi_free(&G
); mpi_free(&U2
); mpi_free(&U1
);
1560 mpi_free(&TU
); mpi_free(&TA
);
1565 static const int small_prime
[] = {
1566 3, 5, 7, 11, 13, 17, 19, 23,
1567 29, 31, 37, 41, 43, 47, 53, 59,
1568 61, 67, 71, 73, 79, 83, 89, 97,
1569 101, 103, 107, 109, 113, 127, 131, 137,
1570 139, 149, 151, 157, 163, 167, 173, 179,
1571 181, 191, 193, 197, 199, 211, 223, 227,
1572 229, 233, 239, 241, 251, 257, 263, 269,
1573 271, 277, 281, 283, 293, 307, 311, 313,
1574 317, 331, 337, 347, 349, 353, 359, 367,
1575 373, 379, 383, 389, 397, 401, 409, 419,
1576 421, 431, 433, 439, 443, 449, 457, 461,
1577 463, 467, 479, 487, 491, 499, 503, 509,
1578 521, 523, 541, 547, 557, 563, 569, 571,
1579 577, 587, 593, 599, 601, 607, 613, 617,
1580 619, 631, 641, 643, 647, 653, 659, 661,
1581 673, 677, 683, 691, 701, 709, 719, 727,
1582 733, 739, 743, 751, 757, 761, 769, 773,
1583 787, 797, 809, 811, 821, 823, 827, 829,
1584 839, 853, 857, 859, 863, 877, 881, 883,
1585 887, 907, 911, 919, 929, 937, 941, 947,
1586 953, 967, 971, 977, 983, 991, 997, -103
1590 * Miller-Rabin primality test (HAC 4.24)
1592 int mpi_is_prime(mpi
* X
, int (*f_rng
) (void *), void *p_rng
)
1594 int ret
, i
, j
, n
, s
, xs
;
1598 if (mpi_cmp_int(X
, 0) == 0)
1601 mpi_init(&W
); mpi_init(&R
); mpi_init(&T
);
1602 mpi_init(&A
); mpi_init(&RR
);
1608 * test trivial factors first
1610 if ((X
->p
[0] & 1) == 0)
1611 return (TROPICSSL_ERR_MPI_NOT_ACCEPTABLE
);
1613 for (i
= 0; small_prime
[i
] > 0; i
++) {
1616 if (mpi_cmp_int(X
, small_prime
[i
]) <= 0)
1619 MPI_CHK(mpi_mod_int(&r
, X
, small_prime
[i
]));
1622 return (TROPICSSL_ERR_MPI_NOT_ACCEPTABLE
);
1630 MPI_CHK(mpi_sub_int(&W
, X
, 1));
1631 MPI_CHK(mpi_copy(&R
, &W
));
1632 MPI_CHK(mpi_shift_r(&R
, s
));
1638 n
= ((i
>= 1300) ? 2 : (i
>= 850) ? 3 :
1639 (i
>= 650) ? 4 : (i
>= 350) ? 8 :
1640 (i
>= 250) ? 12 : (i
>= 150) ? 18 : 27);
1642 for (i
= 0; i
< n
; i
++) {
1644 * pick a random A, 1 < A < |X| - 1
1646 MPI_CHK(mpi_grow(&A
, X
->n
));
1648 p
= (unsigned char *)A
.p
;
1649 for (j
= 0; j
< A
.n
* ciL
; j
++)
1650 *p
++ = (unsigned char)f_rng(p_rng
);
1652 j
= mpi_msb(&A
) - mpi_msb(&W
);
1653 MPI_CHK(mpi_shift_r(&A
, j
+ 1));
1659 MPI_CHK(mpi_exp_mod(&A
, &A
, &R
, X
, &RR
));
1661 if (mpi_cmp_mpi(&A
, &W
) == 0 || mpi_cmp_int(&A
, 1) == 0)
1665 while (j
< s
&& mpi_cmp_mpi(&A
, &W
) != 0) {
1669 MPI_CHK(mpi_mul_mpi(&T
, &A
, &A
));
1670 MPI_CHK(mpi_mod_mpi(&A
, &T
, X
));
1672 if (mpi_cmp_int(&A
, 1) == 0)
1679 * not prime if A != |X| - 1 or A == 1
1681 if (mpi_cmp_mpi(&A
, &W
) != 0 || mpi_cmp_int(&A
, 1) == 0) {
1682 ret
= TROPICSSL_ERR_MPI_NOT_ACCEPTABLE
;
1691 mpi_free(&RR
); mpi_free(&A
); mpi_free(&T
);
1692 mpi_free(&R
); mpi_free(&W
);
1698 * Prime number generation
1700 int mpi_gen_prime(mpi
* X
, int nbits
, int dh_flag
,
1701 int (*f_rng
) (void *), void *p_rng
)
1708 return (TROPICSSL_ERR_MPI_BAD_INPUT_DATA
);
1712 n
= BITS_TO_LIMBS(nbits
);
1714 MPI_CHK(mpi_grow(X
, n
));
1715 MPI_CHK(mpi_lset(X
, 0));
1717 p
= (unsigned char *)X
->p
;
1718 for (k
= 0; k
< X
->n
* ciL
; k
++)
1719 *p
++ = (unsigned char)f_rng(p_rng
);
1723 MPI_CHK(mpi_shift_l(X
, nbits
- k
));
1725 MPI_CHK(mpi_shift_r(X
, k
- nbits
));
1730 while ((ret
= mpi_is_prime(X
, f_rng
, p_rng
)) != 0) {
1731 if (ret
!= TROPICSSL_ERR_MPI_NOT_ACCEPTABLE
)
1734 MPI_CHK(mpi_add_int(X
, X
, 2));
1737 MPI_CHK(mpi_sub_int(&Y
, X
, 1));
1738 MPI_CHK(mpi_shift_r(&Y
, 1));
1741 if ((ret
= mpi_is_prime(X
, f_rng
, p_rng
)) == 0) {
1742 if ((ret
= mpi_is_prime(&Y
, f_rng
, p_rng
)) == 0)
1745 if (ret
!= TROPICSSL_ERR_MPI_NOT_ACCEPTABLE
)
1749 if (ret
!= TROPICSSL_ERR_MPI_NOT_ACCEPTABLE
)
1752 MPI_CHK(mpi_add_int(&Y
, X
, 1));
1753 MPI_CHK(mpi_add_int(X
, X
, 2));
1754 MPI_CHK(mpi_shift_r(&Y
, 1));
1767 #if defined(TROPICSSL_SELF_TEST)
1769 #define GCD_PAIR_COUNT 3
1771 static const int gcd_pairs
[GCD_PAIR_COUNT
][3] = {
1774 {768454923, 542167814, 1}
1780 int mpi_self_test(int verbose
)
1783 mpi A
, E
, N
, X
, Y
, U
, V
;
1785 mpi_init(&A
); mpi_init(&E
); mpi_init(&N
); mpi_init(&X
);
1786 mpi_init(&Y
); mpi_init(&U
); mpi_init(&V
);
1788 MPI_CHK(mpi_read_string(&A
, 16,
1789 "EFE021C2645FD1DC586E69184AF4A31E"
1790 "D5F53E93B5F123FA41680867BA110131"
1791 "944FE7952E2517337780CB0DB80E61AA"
1792 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6"));
1794 MPI_CHK(mpi_read_string(&E
, 16,
1795 "B2E7EFD37075B9F03FF989C7C5051C20"
1796 "34D2A323810251127E7BF8625A4F49A5"
1797 "F3E27F4DA8BD59C47D6DAABA4C8127BD"
1798 "5B5C25763222FEFCCFC38B832366C29E"));
1800 MPI_CHK(mpi_read_string(&N
, 16,
1801 "0066A198186C18C10B2F5ED9B522752A"
1802 "9830B69916E535C8F047518A889A43A5"
1803 "94B6BED27A168D31D4A52F88925AA8F5"));
1805 MPI_CHK(mpi_mul_mpi(&X
, &A
, &N
));
1807 MPI_CHK(mpi_read_string(&U
, 16,
1808 "602AB7ECA597A3D6B56FF9829A5E8B85"
1809 "9E857EA95A03512E2BAE7391688D264A"
1810 "A5663B0341DB9CCFD2C4C5F421FEC814"
1811 "8001B72E848A38CAE1C65F78E56ABDEF"
1812 "E12D3C039B8A02D6BE593F0BBBDA56F1"
1813 "ECF677152EF804370C1A305CAF3B5BF1"
1814 "30879B56C61DE584A0F53A2447A51E"));
1817 printf(" MPI test #1 (mul_mpi): ");
1819 if (mpi_cmp_mpi(&X
, &U
) != 0) {
1829 MPI_CHK(mpi_div_mpi(&X
, &Y
, &A
, &N
));
1831 MPI_CHK(mpi_read_string(&U
, 16, "256567336059E52CAE22925474705F39A94"));
1833 MPI_CHK(mpi_read_string(&V
, 16,
1834 "6613F26162223DF488E9CD48CC132C7A"
1835 "0AC93C701B001B092E4E5B9F73BCD27B"
1836 "9EE50D0657C77F374E903CDFA4C642"));
1839 printf(" MPI test #2 (div_mpi): ");
1841 if (mpi_cmp_mpi(&X
, &U
) != 0 || mpi_cmp_mpi(&Y
, &V
) != 0) {
1851 MPI_CHK(mpi_exp_mod(&X
, &A
, &E
, &N
, NULL
));
1853 MPI_CHK(mpi_read_string(&U
, 16,
1854 "36E139AEA55215609D2816998ED020BB"
1855 "BD96C37890F65171D948E9BC7CBAA4D9"
1856 "325D24D6A3C12710F10A09FA08AB87"));
1859 printf(" MPI test #3 (exp_mod): ");
1861 if (mpi_cmp_mpi(&X
, &U
) != 0) {
1871 MPI_CHK(mpi_inv_mod(&X
, &A
, &N
));
1873 MPI_CHK(mpi_read_string(&U
, 16,
1874 "003A0AAEDD7E784FC07D8F9EC6E3BFD5"
1875 "C3DBA76456363A10869622EAC2DD84EC"
1876 "C5B8A74DAC4D09E03B5E0BE779F2DF61"));
1879 printf(" MPI test #4 (inv_mod): ");
1881 if (mpi_cmp_mpi(&X
, &U
) != 0) {
1892 printf(" MPI test #5 (simple gcd): ");
1894 for (i
= 0; i
< GCD_PAIR_COUNT
; i
++) {
1895 MPI_CHK(mpi_lset(&X
, gcd_pairs
[i
][0]));
1896 MPI_CHK(mpi_lset(&Y
, gcd_pairs
[i
][1]));
1898 MPI_CHK(mpi_gcd(&A
, &X
, &Y
));
1900 if (mpi_cmp_int(&A
, gcd_pairs
[i
][2]) != 0) {
1902 printf("failed at %d\n", i
);
1913 if (ret
!= 0 && verbose
!= 0)
1914 printf("Unexpected error, return code = %08X\n", ret
);
1916 mpi_free(&V
); mpi_free(&U
); mpi_free(&Y
); mpi_free(&X
);
1917 mpi_free(&N
); mpi_free(&E
); mpi_free(&A
);