blob: 2e3595c5eb124f095750eefd339c4c726e2e1715 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Multi-precision integer library
3 *
Paul Bakker84f12b72010-07-18 10:13:04 +00004 * Copyright (C) 2006-2010, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 * This MPI implementation is based on:
27 *
28 * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
29 * http://www.stillhq.com/extracted/gnupg-api/mpi/
30 * http://math.libtomcrypt.com/files/tommath.pdf
31 */
32
Paul Bakker40e46942009-01-03 21:51:57 +000033#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Paul Bakker40e46942009-01-03 21:51:57 +000035#if defined(POLARSSL_BIGNUM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Paul Bakker40e46942009-01-03 21:51:57 +000037#include "polarssl/bignum.h"
38#include "polarssl/bn_mul.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000039
Paul Bakker5121ce52009-01-03 21:22:43 +000040#include <stdlib.h>
Paul Bakker5121ce52009-01-03 21:22:43 +000041
Paul Bakkerf9688572011-05-05 10:00:45 +000042#define ciL (sizeof(t_uint)) /* chars in limb */
Paul Bakker5121ce52009-01-03 21:22:43 +000043#define biL (ciL << 3) /* bits in limb */
44#define biH (ciL << 2) /* half limb size */
45
46/*
47 * Convert between bits/chars and number of limbs
48 */
49#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
50#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
51
52/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000053 * Initialize one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000054 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000055void mpi_init( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000056{
Paul Bakker6c591fa2011-05-05 11:49:20 +000057 if( X == NULL )
58 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000059
Paul Bakker6c591fa2011-05-05 11:49:20 +000060 X->s = 1;
61 X->n = 0;
62 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000063}
64
65/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000066 * Unallocate one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000067 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000068void mpi_free( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000069{
Paul Bakker6c591fa2011-05-05 11:49:20 +000070 if( X == NULL )
71 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000072
Paul Bakker6c591fa2011-05-05 11:49:20 +000073 if( X->p != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +000074 {
Paul Bakker6c591fa2011-05-05 11:49:20 +000075 memset( X->p, 0, X->n * ciL );
76 free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +000077 }
78
Paul Bakker6c591fa2011-05-05 11:49:20 +000079 X->s = 1;
80 X->n = 0;
81 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000082}
83
84/*
85 * Enlarge to the specified number of limbs
86 */
Paul Bakker23986e52011-04-24 08:57:21 +000087int mpi_grow( mpi *X, size_t nblimbs )
Paul Bakker5121ce52009-01-03 21:22:43 +000088{
Paul Bakkera755ca12011-04-24 09:11:17 +000089 t_uint *p;
Paul Bakker5121ce52009-01-03 21:22:43 +000090
Paul Bakkerf9688572011-05-05 10:00:45 +000091 if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
92 return( 1 );
93
Paul Bakker5121ce52009-01-03 21:22:43 +000094 if( X->n < nblimbs )
95 {
Paul Bakkera755ca12011-04-24 09:11:17 +000096 if( ( p = (t_uint *) malloc( nblimbs * ciL ) ) == NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +000097 return( 1 );
98
99 memset( p, 0, nblimbs * ciL );
100
101 if( X->p != NULL )
102 {
103 memcpy( p, X->p, X->n * ciL );
104 memset( X->p, 0, X->n * ciL );
105 free( X->p );
106 }
107
108 X->n = nblimbs;
109 X->p = p;
110 }
111
112 return( 0 );
113}
114
115/*
116 * Copy the contents of Y into X
117 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000118int mpi_copy( mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000119{
Paul Bakker23986e52011-04-24 08:57:21 +0000120 int ret;
121 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000122
123 if( X == Y )
124 return( 0 );
125
126 for( i = Y->n - 1; i > 0; i-- )
127 if( Y->p[i] != 0 )
128 break;
129 i++;
130
131 X->s = Y->s;
132
133 MPI_CHK( mpi_grow( X, i ) );
134
135 memset( X->p, 0, X->n * ciL );
136 memcpy( X->p, Y->p, i * ciL );
137
138cleanup:
139
140 return( ret );
141}
142
143/*
144 * Swap the contents of X and Y
145 */
146void mpi_swap( mpi *X, mpi *Y )
147{
148 mpi T;
149
150 memcpy( &T, X, sizeof( mpi ) );
151 memcpy( X, Y, sizeof( mpi ) );
152 memcpy( Y, &T, sizeof( mpi ) );
153}
154
155/*
156 * Set value from integer
157 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000158int mpi_lset( mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000159{
160 int ret;
161
162 MPI_CHK( mpi_grow( X, 1 ) );
163 memset( X->p, 0, X->n * ciL );
164
165 X->p[0] = ( z < 0 ) ? -z : z;
166 X->s = ( z < 0 ) ? -1 : 1;
167
168cleanup:
169
170 return( ret );
171}
172
173/*
174 * Return the number of least significant bits
175 */
Paul Bakker23986e52011-04-24 08:57:21 +0000176size_t mpi_lsb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000177{
Paul Bakker23986e52011-04-24 08:57:21 +0000178 size_t i, j, count = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000179
180 for( i = 0; i < X->n; i++ )
Paul Bakkerf9688572011-05-05 10:00:45 +0000181 for( j = 0; j < biL; j++, count++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000182 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
183 return( count );
184
185 return( 0 );
186}
187
188/*
189 * Return the number of most significant bits
190 */
Paul Bakker23986e52011-04-24 08:57:21 +0000191size_t mpi_msb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000192{
Paul Bakker23986e52011-04-24 08:57:21 +0000193 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000194
195 for( i = X->n - 1; i > 0; i-- )
196 if( X->p[i] != 0 )
197 break;
198
Paul Bakker23986e52011-04-24 08:57:21 +0000199 for( j = biL; j > 0; j-- )
200 if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000201 break;
202
Paul Bakker23986e52011-04-24 08:57:21 +0000203 return( ( i * biL ) + j );
Paul Bakker5121ce52009-01-03 21:22:43 +0000204}
205
206/*
207 * Return the total size in bytes
208 */
Paul Bakker23986e52011-04-24 08:57:21 +0000209size_t mpi_size( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000210{
211 return( ( mpi_msb( X ) + 7 ) >> 3 );
212}
213
214/*
215 * Convert an ASCII character to digit value
216 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000217static int mpi_get_digit( t_uint *d, int radix, char c )
Paul Bakker5121ce52009-01-03 21:22:43 +0000218{
219 *d = 255;
220
221 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
222 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
223 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
224
Paul Bakkera755ca12011-04-24 09:11:17 +0000225 if( *d >= (t_uint) radix )
Paul Bakker40e46942009-01-03 21:51:57 +0000226 return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000227
228 return( 0 );
229}
230
231/*
232 * Import from an ASCII string
233 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000234int mpi_read_string( mpi *X, int radix, const char *s )
Paul Bakker5121ce52009-01-03 21:22:43 +0000235{
Paul Bakker23986e52011-04-24 08:57:21 +0000236 int ret;
237 size_t i, j, slen, n;
Paul Bakkera755ca12011-04-24 09:11:17 +0000238 t_uint d;
Paul Bakker5121ce52009-01-03 21:22:43 +0000239 mpi T;
240
241 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000242 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000243
Paul Bakker6c591fa2011-05-05 11:49:20 +0000244 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000245
Paul Bakkerff60ee62010-03-16 21:09:09 +0000246 slen = strlen( s );
247
Paul Bakker5121ce52009-01-03 21:22:43 +0000248 if( radix == 16 )
249 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000250 n = BITS_TO_LIMBS( slen << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000251
252 MPI_CHK( mpi_grow( X, n ) );
253 MPI_CHK( mpi_lset( X, 0 ) );
254
Paul Bakker23986e52011-04-24 08:57:21 +0000255 for( i = slen, j = 0; i > 0; i--, j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000256 {
Paul Bakker23986e52011-04-24 08:57:21 +0000257 if( i == 1 && s[i - 1] == '-' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000258 {
259 X->s = -1;
260 break;
261 }
262
Paul Bakker23986e52011-04-24 08:57:21 +0000263 MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000264 X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 );
265 }
266 }
267 else
268 {
269 MPI_CHK( mpi_lset( X, 0 ) );
270
Paul Bakkerff60ee62010-03-16 21:09:09 +0000271 for( i = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000272 {
273 if( i == 0 && s[i] == '-' )
274 {
275 X->s = -1;
276 continue;
277 }
278
279 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
280 MPI_CHK( mpi_mul_int( &T, X, radix ) );
Paul Bakker05feca62009-06-20 08:22:43 +0000281
282 if( X->s == 1 )
283 {
284 MPI_CHK( mpi_add_int( X, &T, d ) );
285 }
286 else
287 {
288 MPI_CHK( mpi_sub_int( X, &T, d ) );
289 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000290 }
291 }
292
293cleanup:
294
Paul Bakker6c591fa2011-05-05 11:49:20 +0000295 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000296
297 return( ret );
298}
299
300/*
301 * Helper to write the digits high-order first
302 */
303static int mpi_write_hlp( mpi *X, int radix, char **p )
304{
305 int ret;
Paul Bakkera755ca12011-04-24 09:11:17 +0000306 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +0000307
308 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000309 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000310
311 MPI_CHK( mpi_mod_int( &r, X, radix ) );
312 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
313
314 if( mpi_cmp_int( X, 0 ) != 0 )
315 MPI_CHK( mpi_write_hlp( X, radix, p ) );
316
317 if( r < 10 )
318 *(*p)++ = (char)( r + 0x30 );
319 else
320 *(*p)++ = (char)( r + 0x37 );
321
322cleanup:
323
324 return( ret );
325}
326
327/*
328 * Export into an ASCII string
329 */
Paul Bakker23986e52011-04-24 08:57:21 +0000330int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000331{
Paul Bakker23986e52011-04-24 08:57:21 +0000332 int ret = 0;
333 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000334 char *p;
335 mpi T;
336
337 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000338 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000339
340 n = mpi_msb( X );
341 if( radix >= 4 ) n >>= 1;
342 if( radix >= 16 ) n >>= 1;
343 n += 3;
344
345 if( *slen < n )
346 {
347 *slen = n;
Paul Bakker40e46942009-01-03 21:51:57 +0000348 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000349 }
350
351 p = s;
Paul Bakker6c591fa2011-05-05 11:49:20 +0000352 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000353
354 if( X->s == -1 )
355 *p++ = '-';
356
357 if( radix == 16 )
358 {
Paul Bakker23986e52011-04-24 08:57:21 +0000359 int c;
360 size_t i, j, k;
Paul Bakker5121ce52009-01-03 21:22:43 +0000361
Paul Bakker23986e52011-04-24 08:57:21 +0000362 for( i = X->n, k = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000363 {
Paul Bakker23986e52011-04-24 08:57:21 +0000364 for( j = ciL; j > 0; j-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000365 {
Paul Bakker23986e52011-04-24 08:57:21 +0000366 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000367
Paul Bakker23986e52011-04-24 08:57:21 +0000368 if( c == 0 && k == 0 && ( i + j + 3 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000369 continue;
370
371 p += sprintf( p, "%02X", c );
372 k = 1;
373 }
374 }
375 }
376 else
377 {
378 MPI_CHK( mpi_copy( &T, X ) );
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000379
380 if( T.s == -1 )
381 T.s = 1;
382
Paul Bakker5121ce52009-01-03 21:22:43 +0000383 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
384 }
385
386 *p++ = '\0';
387 *slen = p - s;
388
389cleanup:
390
Paul Bakker6c591fa2011-05-05 11:49:20 +0000391 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000392
393 return( ret );
394}
395
Paul Bakker335db3f2011-04-25 15:28:35 +0000396#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000397/*
398 * Read X from an opened file
399 */
400int mpi_read_file( mpi *X, int radix, FILE *fin )
401{
Paul Bakkera755ca12011-04-24 09:11:17 +0000402 t_uint d;
Paul Bakker23986e52011-04-24 08:57:21 +0000403 size_t slen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000404 char *p;
405 char s[1024];
406
407 memset( s, 0, sizeof( s ) );
408 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000409 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
411 slen = strlen( s );
412 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
413 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
414
415 p = s + slen;
416 while( --p >= s )
417 if( mpi_get_digit( &d, radix, *p ) != 0 )
418 break;
419
420 return( mpi_read_string( X, radix, p + 1 ) );
421}
422
423/*
424 * Write X into an opened file (or stdout if fout == NULL)
425 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000426int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
Paul Bakker5121ce52009-01-03 21:22:43 +0000427{
Paul Bakker23986e52011-04-24 08:57:21 +0000428 int ret;
429 size_t n, slen, plen;
Paul Bakker08f3c302010-07-08 06:54:25 +0000430 char s[2048];
Paul Bakker5121ce52009-01-03 21:22:43 +0000431
432 n = sizeof( s );
433 memset( s, 0, n );
434 n -= 2;
435
Paul Bakker23986e52011-04-24 08:57:21 +0000436 MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000437
438 if( p == NULL ) p = "";
439
440 plen = strlen( p );
441 slen = strlen( s );
442 s[slen++] = '\r';
443 s[slen++] = '\n';
444
445 if( fout != NULL )
446 {
447 if( fwrite( p, 1, plen, fout ) != plen ||
448 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000449 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000450 }
451 else
452 printf( "%s%s", p, s );
453
454cleanup:
455
456 return( ret );
457}
Paul Bakker335db3f2011-04-25 15:28:35 +0000458#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000459
460/*
461 * Import X from unsigned binary data, big endian
462 */
Paul Bakker23986e52011-04-24 08:57:21 +0000463int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000464{
Paul Bakker23986e52011-04-24 08:57:21 +0000465 int ret;
466 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000467
468 for( n = 0; n < buflen; n++ )
469 if( buf[n] != 0 )
470 break;
471
472 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
473 MPI_CHK( mpi_lset( X, 0 ) );
474
Paul Bakker23986e52011-04-24 08:57:21 +0000475 for( i = buflen, j = 0; i > n; i--, j++ )
Paul Bakkera755ca12011-04-24 09:11:17 +0000476 X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
478cleanup:
479
480 return( ret );
481}
482
483/*
484 * Export X into unsigned binary data, big endian
485 */
Paul Bakker23986e52011-04-24 08:57:21 +0000486int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000487{
Paul Bakker23986e52011-04-24 08:57:21 +0000488 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000489
490 n = mpi_size( X );
491
492 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000493 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
495 memset( buf, 0, buflen );
496
497 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
498 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
499
500 return( 0 );
501}
502
503/*
504 * Left-shift: X <<= count
505 */
Paul Bakker23986e52011-04-24 08:57:21 +0000506int mpi_shift_l( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000507{
Paul Bakker23986e52011-04-24 08:57:21 +0000508 int ret;
509 size_t i, v0, t1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000510 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000511
512 v0 = count / (biL );
513 t1 = count & (biL - 1);
514
515 i = mpi_msb( X ) + count;
516
Paul Bakkerf9688572011-05-05 10:00:45 +0000517 if( X->n * biL < i )
Paul Bakker5121ce52009-01-03 21:22:43 +0000518 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
519
520 ret = 0;
521
522 /*
523 * shift by count / limb_size
524 */
525 if( v0 > 0 )
526 {
Paul Bakker23986e52011-04-24 08:57:21 +0000527 for( i = X->n; i > v0; i-- )
528 X->p[i - 1] = X->p[i - v0 - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000529
Paul Bakker23986e52011-04-24 08:57:21 +0000530 for( ; i > 0; i-- )
531 X->p[i - 1] = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000532 }
533
534 /*
535 * shift by count % limb_size
536 */
537 if( t1 > 0 )
538 {
539 for( i = v0; i < X->n; i++ )
540 {
541 r1 = X->p[i] >> (biL - t1);
542 X->p[i] <<= t1;
543 X->p[i] |= r0;
544 r0 = r1;
545 }
546 }
547
548cleanup:
549
550 return( ret );
551}
552
553/*
554 * Right-shift: X >>= count
555 */
Paul Bakker23986e52011-04-24 08:57:21 +0000556int mpi_shift_r( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000557{
Paul Bakker23986e52011-04-24 08:57:21 +0000558 size_t i, v0, v1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000559 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
561 v0 = count / biL;
562 v1 = count & (biL - 1);
563
564 /*
565 * shift by count / limb_size
566 */
567 if( v0 > 0 )
568 {
569 for( i = 0; i < X->n - v0; i++ )
570 X->p[i] = X->p[i + v0];
571
572 for( ; i < X->n; i++ )
573 X->p[i] = 0;
574 }
575
576 /*
577 * shift by count % limb_size
578 */
579 if( v1 > 0 )
580 {
Paul Bakker23986e52011-04-24 08:57:21 +0000581 for( i = X->n; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000582 {
Paul Bakker23986e52011-04-24 08:57:21 +0000583 r1 = X->p[i - 1] << (biL - v1);
584 X->p[i - 1] >>= v1;
585 X->p[i - 1] |= r0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000586 r0 = r1;
587 }
588 }
589
590 return( 0 );
591}
592
593/*
594 * Compare unsigned values
595 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000596int mpi_cmp_abs( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000597{
Paul Bakker23986e52011-04-24 08:57:21 +0000598 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
Paul Bakker23986e52011-04-24 08:57:21 +0000600 for( i = X->n; i > 0; i-- )
601 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000602 break;
603
Paul Bakker23986e52011-04-24 08:57:21 +0000604 for( j = Y->n; j > 0; j-- )
605 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000606 break;
607
Paul Bakker23986e52011-04-24 08:57:21 +0000608 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000609 return( 0 );
610
611 if( i > j ) return( 1 );
612 if( j > i ) return( -1 );
613
Paul Bakker23986e52011-04-24 08:57:21 +0000614 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000615 {
Paul Bakker23986e52011-04-24 08:57:21 +0000616 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
617 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000618 }
619
620 return( 0 );
621}
622
623/*
624 * Compare signed values
625 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000626int mpi_cmp_mpi( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000627{
Paul Bakker23986e52011-04-24 08:57:21 +0000628 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000629
Paul Bakker23986e52011-04-24 08:57:21 +0000630 for( i = X->n; i > 0; i-- )
631 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000632 break;
633
Paul Bakker23986e52011-04-24 08:57:21 +0000634 for( j = Y->n; j > 0; j-- )
635 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000636 break;
637
Paul Bakker23986e52011-04-24 08:57:21 +0000638 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000639 return( 0 );
640
641 if( i > j ) return( X->s );
642 if( j > i ) return( -X->s );
643
644 if( X->s > 0 && Y->s < 0 ) return( 1 );
645 if( Y->s > 0 && X->s < 0 ) return( -1 );
646
Paul Bakker23986e52011-04-24 08:57:21 +0000647 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000648 {
Paul Bakker23986e52011-04-24 08:57:21 +0000649 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
650 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000651 }
652
653 return( 0 );
654}
655
656/*
657 * Compare signed values
658 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000659int mpi_cmp_int( const mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000660{
661 mpi Y;
Paul Bakkera755ca12011-04-24 09:11:17 +0000662 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000663
664 *p = ( z < 0 ) ? -z : z;
665 Y.s = ( z < 0 ) ? -1 : 1;
666 Y.n = 1;
667 Y.p = p;
668
669 return( mpi_cmp_mpi( X, &Y ) );
670}
671
672/*
673 * Unsigned addition: X = |A| + |B| (HAC 14.7)
674 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000675int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000676{
Paul Bakker23986e52011-04-24 08:57:21 +0000677 int ret;
678 size_t i, j;
Paul Bakkera755ca12011-04-24 09:11:17 +0000679 t_uint *o, *p, c;
Paul Bakker5121ce52009-01-03 21:22:43 +0000680
681 if( X == B )
682 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000683 const mpi *T = A; A = X; B = T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000684 }
685
686 if( X != A )
687 MPI_CHK( mpi_copy( X, A ) );
Paul Bakkerf7ca7b92009-06-20 10:31:06 +0000688
689 /*
690 * X should always be positive as a result of unsigned additions.
691 */
692 X->s = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000693
Paul Bakker23986e52011-04-24 08:57:21 +0000694 for( j = B->n; j > 0; j-- )
695 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000696 break;
697
Paul Bakker23986e52011-04-24 08:57:21 +0000698 MPI_CHK( mpi_grow( X, j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000699
700 o = B->p; p = X->p; c = 0;
701
Paul Bakker23986e52011-04-24 08:57:21 +0000702 for( i = 0; i < j; i++, o++, p++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000703 {
704 *p += c; c = ( *p < c );
705 *p += *o; c += ( *p < *o );
706 }
707
708 while( c != 0 )
709 {
710 if( i >= X->n )
711 {
712 MPI_CHK( mpi_grow( X, i + 1 ) );
713 p = X->p + i;
714 }
715
716 *p += c; c = ( *p < c ); i++;
717 }
718
719cleanup:
720
721 return( ret );
722}
723
724/*
725 * Helper for mpi substraction
726 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000727static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
Paul Bakker5121ce52009-01-03 21:22:43 +0000728{
Paul Bakker23986e52011-04-24 08:57:21 +0000729 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +0000730 t_uint c, z;
Paul Bakker5121ce52009-01-03 21:22:43 +0000731
732 for( i = c = 0; i < n; i++, s++, d++ )
733 {
734 z = ( *d < c ); *d -= c;
735 c = ( *d < *s ) + z; *d -= *s;
736 }
737
738 while( c != 0 )
739 {
740 z = ( *d < c ); *d -= c;
741 c = z; i++; d++;
742 }
743}
744
745/*
746 * Unsigned substraction: X = |A| - |B| (HAC 14.9)
747 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000748int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000749{
750 mpi TB;
Paul Bakker23986e52011-04-24 08:57:21 +0000751 int ret;
752 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000753
754 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000755 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000756
Paul Bakker6c591fa2011-05-05 11:49:20 +0000757 mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000758
759 if( X == B )
760 {
761 MPI_CHK( mpi_copy( &TB, B ) );
762 B = &TB;
763 }
764
765 if( X != A )
766 MPI_CHK( mpi_copy( X, A ) );
767
Paul Bakker1ef7a532009-06-20 10:50:55 +0000768 /*
769 * X should always be positive as a result of unsigned substractions.
770 */
771 X->s = 1;
772
Paul Bakker5121ce52009-01-03 21:22:43 +0000773 ret = 0;
774
Paul Bakker23986e52011-04-24 08:57:21 +0000775 for( n = B->n; n > 0; n-- )
776 if( B->p[n - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000777 break;
778
Paul Bakker23986e52011-04-24 08:57:21 +0000779 mpi_sub_hlp( n, B->p, X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000780
781cleanup:
782
Paul Bakker6c591fa2011-05-05 11:49:20 +0000783 mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000784
785 return( ret );
786}
787
788/*
789 * Signed addition: X = A + B
790 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000791int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000792{
793 int ret, s = A->s;
794
795 if( A->s * B->s < 0 )
796 {
797 if( mpi_cmp_abs( A, B ) >= 0 )
798 {
799 MPI_CHK( mpi_sub_abs( X, A, B ) );
800 X->s = s;
801 }
802 else
803 {
804 MPI_CHK( mpi_sub_abs( X, B, A ) );
805 X->s = -s;
806 }
807 }
808 else
809 {
810 MPI_CHK( mpi_add_abs( X, A, B ) );
811 X->s = s;
812 }
813
814cleanup:
815
816 return( ret );
817}
818
819/*
820 * Signed substraction: X = A - B
821 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000822int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000823{
824 int ret, s = A->s;
825
826 if( A->s * B->s > 0 )
827 {
828 if( mpi_cmp_abs( A, B ) >= 0 )
829 {
830 MPI_CHK( mpi_sub_abs( X, A, B ) );
831 X->s = s;
832 }
833 else
834 {
835 MPI_CHK( mpi_sub_abs( X, B, A ) );
836 X->s = -s;
837 }
838 }
839 else
840 {
841 MPI_CHK( mpi_add_abs( X, A, B ) );
842 X->s = s;
843 }
844
845cleanup:
846
847 return( ret );
848}
849
850/*
851 * Signed addition: X = A + b
852 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000853int mpi_add_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +0000854{
855 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +0000856 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000857
858 p[0] = ( b < 0 ) ? -b : b;
859 _B.s = ( b < 0 ) ? -1 : 1;
860 _B.n = 1;
861 _B.p = p;
862
863 return( mpi_add_mpi( X, A, &_B ) );
864}
865
866/*
867 * Signed substraction: X = A - b
868 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000869int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +0000870{
871 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +0000872 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000873
874 p[0] = ( b < 0 ) ? -b : b;
875 _B.s = ( b < 0 ) ? -1 : 1;
876 _B.n = 1;
877 _B.p = p;
878
879 return( mpi_sub_mpi( X, A, &_B ) );
880}
881
882/*
883 * Helper for mpi multiplication
884 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000885static void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
Paul Bakker5121ce52009-01-03 21:22:43 +0000886{
Paul Bakkera755ca12011-04-24 09:11:17 +0000887 t_uint c = 0, t = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000888
889#if defined(MULADDC_HUIT)
890 for( ; i >= 8; i -= 8 )
891 {
892 MULADDC_INIT
893 MULADDC_HUIT
894 MULADDC_STOP
895 }
896
897 for( ; i > 0; i-- )
898 {
899 MULADDC_INIT
900 MULADDC_CORE
901 MULADDC_STOP
902 }
903#else
904 for( ; i >= 16; i -= 16 )
905 {
906 MULADDC_INIT
907 MULADDC_CORE MULADDC_CORE
908 MULADDC_CORE MULADDC_CORE
909 MULADDC_CORE MULADDC_CORE
910 MULADDC_CORE MULADDC_CORE
911
912 MULADDC_CORE MULADDC_CORE
913 MULADDC_CORE MULADDC_CORE
914 MULADDC_CORE MULADDC_CORE
915 MULADDC_CORE MULADDC_CORE
916 MULADDC_STOP
917 }
918
919 for( ; i >= 8; i -= 8 )
920 {
921 MULADDC_INIT
922 MULADDC_CORE MULADDC_CORE
923 MULADDC_CORE MULADDC_CORE
924
925 MULADDC_CORE MULADDC_CORE
926 MULADDC_CORE MULADDC_CORE
927 MULADDC_STOP
928 }
929
930 for( ; i > 0; i-- )
931 {
932 MULADDC_INIT
933 MULADDC_CORE
934 MULADDC_STOP
935 }
936#endif
937
938 t++;
939
940 do {
941 *d += c; c = ( *d < c ); d++;
942 }
943 while( c != 0 );
944}
945
946/*
947 * Baseline multiplication: X = A * B (HAC 14.12)
948 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000949int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000950{
Paul Bakker23986e52011-04-24 08:57:21 +0000951 int ret;
952 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 mpi TA, TB;
954
Paul Bakker6c591fa2011-05-05 11:49:20 +0000955 mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000956
957 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
958 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
959
Paul Bakker23986e52011-04-24 08:57:21 +0000960 for( i = A->n; i > 0; i-- )
961 if( A->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000962 break;
963
Paul Bakker23986e52011-04-24 08:57:21 +0000964 for( j = B->n; j > 0; j-- )
965 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000966 break;
967
Paul Bakker23986e52011-04-24 08:57:21 +0000968 MPI_CHK( mpi_grow( X, i + j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000969 MPI_CHK( mpi_lset( X, 0 ) );
970
Paul Bakker23986e52011-04-24 08:57:21 +0000971 for( i++; j > 0; j-- )
972 mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000973
974 X->s = A->s * B->s;
975
976cleanup:
977
Paul Bakker6c591fa2011-05-05 11:49:20 +0000978 mpi_free( &TB ); mpi_free( &TA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000979
980 return( ret );
981}
982
983/*
984 * Baseline multiplication: X = A * b
985 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000986int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +0000987{
988 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +0000989 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000990
991 _B.s = 1;
992 _B.n = 1;
993 _B.p = p;
994 p[0] = b;
995
996 return( mpi_mul_mpi( X, A, &_B ) );
997}
998
999/*
1000 * Division by mpi: A = Q * B + R (HAC 14.20)
1001 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001002int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001003{
Paul Bakker23986e52011-04-24 08:57:21 +00001004 int ret;
1005 size_t i, n, t, k;
Paul Bakker5121ce52009-01-03 21:22:43 +00001006 mpi X, Y, Z, T1, T2;
1007
1008 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001009 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001010
Paul Bakker6c591fa2011-05-05 11:49:20 +00001011 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
1012 mpi_init( &T1 ); mpi_init( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001013
1014 if( mpi_cmp_abs( A, B ) < 0 )
1015 {
1016 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1017 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1018 return( 0 );
1019 }
1020
1021 MPI_CHK( mpi_copy( &X, A ) );
1022 MPI_CHK( mpi_copy( &Y, B ) );
1023 X.s = Y.s = 1;
1024
1025 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1026 MPI_CHK( mpi_lset( &Z, 0 ) );
1027 MPI_CHK( mpi_grow( &T1, 2 ) );
1028 MPI_CHK( mpi_grow( &T2, 3 ) );
1029
1030 k = mpi_msb( &Y ) % biL;
Paul Bakkerf9688572011-05-05 10:00:45 +00001031 if( k < biL - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001032 {
1033 k = biL - 1 - k;
1034 MPI_CHK( mpi_shift_l( &X, k ) );
1035 MPI_CHK( mpi_shift_l( &Y, k ) );
1036 }
1037 else k = 0;
1038
1039 n = X.n - 1;
1040 t = Y.n - 1;
1041 mpi_shift_l( &Y, biL * (n - t) );
1042
1043 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1044 {
1045 Z.p[n - t]++;
1046 mpi_sub_mpi( &X, &X, &Y );
1047 }
1048 mpi_shift_r( &Y, biL * (n - t) );
1049
1050 for( i = n; i > t ; i-- )
1051 {
1052 if( X.p[i] >= Y.p[t] )
1053 Z.p[i - t - 1] = ~0;
1054 else
1055 {
Paul Bakker40e46942009-01-03 21:51:57 +00001056#if defined(POLARSSL_HAVE_LONGLONG)
Paul Bakker5121ce52009-01-03 21:22:43 +00001057 t_dbl r;
1058
1059 r = (t_dbl) X.p[i] << biL;
1060 r |= (t_dbl) X.p[i - 1];
1061 r /= Y.p[t];
1062 if( r > ((t_dbl) 1 << biL) - 1)
1063 r = ((t_dbl) 1 << biL) - 1;
1064
Paul Bakkera755ca12011-04-24 09:11:17 +00001065 Z.p[i - t - 1] = (t_uint) r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001066#else
1067 /*
1068 * __udiv_qrnnd_c, from gmp/longlong.h
1069 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001070 t_uint q0, q1, r0, r1;
1071 t_uint d0, d1, d, m;
Paul Bakker5121ce52009-01-03 21:22:43 +00001072
1073 d = Y.p[t];
1074 d0 = ( d << biH ) >> biH;
1075 d1 = ( d >> biH );
1076
1077 q1 = X.p[i] / d1;
1078 r1 = X.p[i] - d1 * q1;
1079 r1 <<= biH;
1080 r1 |= ( X.p[i - 1] >> biH );
1081
1082 m = q1 * d0;
1083 if( r1 < m )
1084 {
1085 q1--, r1 += d;
1086 while( r1 >= d && r1 < m )
1087 q1--, r1 += d;
1088 }
1089 r1 -= m;
1090
1091 q0 = r1 / d1;
1092 r0 = r1 - d1 * q0;
1093 r0 <<= biH;
1094 r0 |= ( X.p[i - 1] << biH ) >> biH;
1095
1096 m = q0 * d0;
1097 if( r0 < m )
1098 {
1099 q0--, r0 += d;
1100 while( r0 >= d && r0 < m )
1101 q0--, r0 += d;
1102 }
1103 r0 -= m;
1104
1105 Z.p[i - t - 1] = ( q1 << biH ) | q0;
1106#endif
1107 }
1108
1109 Z.p[i - t - 1]++;
1110 do
1111 {
1112 Z.p[i - t - 1]--;
1113
1114 MPI_CHK( mpi_lset( &T1, 0 ) );
1115 T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
1116 T1.p[1] = Y.p[t];
1117 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1118
1119 MPI_CHK( mpi_lset( &T2, 0 ) );
1120 T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
1121 T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
1122 T2.p[2] = X.p[i];
1123 }
1124 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1125
1126 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1127 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1128 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1129
1130 if( mpi_cmp_int( &X, 0 ) < 0 )
1131 {
1132 MPI_CHK( mpi_copy( &T1, &Y ) );
1133 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1134 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1135 Z.p[i - t - 1]--;
1136 }
1137 }
1138
1139 if( Q != NULL )
1140 {
1141 mpi_copy( Q, &Z );
1142 Q->s = A->s * B->s;
1143 }
1144
1145 if( R != NULL )
1146 {
1147 mpi_shift_r( &X, k );
1148 mpi_copy( R, &X );
1149
1150 R->s = A->s;
1151 if( mpi_cmp_int( R, 0 ) == 0 )
1152 R->s = 1;
1153 }
1154
1155cleanup:
1156
Paul Bakker6c591fa2011-05-05 11:49:20 +00001157 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
1158 mpi_free( &T1 ); mpi_free( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001159
1160 return( ret );
1161}
1162
1163/*
1164 * Division by int: A = Q * b + R
1165 *
1166 * Returns 0 if successful
1167 * 1 if memory allocation failed
Paul Bakker40e46942009-01-03 21:51:57 +00001168 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
Paul Bakker5121ce52009-01-03 21:22:43 +00001169 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001170int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001171{
1172 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001173 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001174
1175 p[0] = ( b < 0 ) ? -b : b;
1176 _B.s = ( b < 0 ) ? -1 : 1;
1177 _B.n = 1;
1178 _B.p = p;
1179
1180 return( mpi_div_mpi( Q, R, A, &_B ) );
1181}
1182
1183/*
1184 * Modulo: R = A mod B
1185 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001186int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001187{
1188 int ret;
1189
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001190 if( mpi_cmp_int( B, 0 ) < 0 )
1191 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
1192
Paul Bakker5121ce52009-01-03 21:22:43 +00001193 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1194
1195 while( mpi_cmp_int( R, 0 ) < 0 )
1196 MPI_CHK( mpi_add_mpi( R, R, B ) );
1197
1198 while( mpi_cmp_mpi( R, B ) >= 0 )
1199 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1200
1201cleanup:
1202
1203 return( ret );
1204}
1205
1206/*
1207 * Modulo: r = A mod b
1208 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001209int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001210{
Paul Bakker23986e52011-04-24 08:57:21 +00001211 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +00001212 t_uint x, y, z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001213
1214 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001215 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001216
1217 if( b < 0 )
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001218 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001219
1220 /*
1221 * handle trivial cases
1222 */
1223 if( b == 1 )
1224 {
1225 *r = 0;
1226 return( 0 );
1227 }
1228
1229 if( b == 2 )
1230 {
1231 *r = A->p[0] & 1;
1232 return( 0 );
1233 }
1234
1235 /*
1236 * general case
1237 */
Paul Bakker23986e52011-04-24 08:57:21 +00001238 for( i = A->n, y = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001239 {
Paul Bakker23986e52011-04-24 08:57:21 +00001240 x = A->p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001241 y = ( y << biH ) | ( x >> biH );
1242 z = y / b;
1243 y -= z * b;
1244
1245 x <<= biH;
1246 y = ( y << biH ) | ( x >> biH );
1247 z = y / b;
1248 y -= z * b;
1249 }
1250
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001251 /*
1252 * If A is negative, then the current y represents a negative value.
1253 * Flipping it to the positive side.
1254 */
1255 if( A->s < 0 && y != 0 )
1256 y = b - y;
1257
Paul Bakker5121ce52009-01-03 21:22:43 +00001258 *r = y;
1259
1260 return( 0 );
1261}
1262
1263/*
1264 * Fast Montgomery initialization (thanks to Tom St Denis)
1265 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001266static void mpi_montg_init( t_uint *mm, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001267{
Paul Bakkera755ca12011-04-24 09:11:17 +00001268 t_uint x, m0 = N->p[0];
Paul Bakker5121ce52009-01-03 21:22:43 +00001269
1270 x = m0;
1271 x += ( ( m0 + 2 ) & 4 ) << 1;
1272 x *= ( 2 - ( m0 * x ) );
1273
1274 if( biL >= 16 ) x *= ( 2 - ( m0 * x ) );
1275 if( biL >= 32 ) x *= ( 2 - ( m0 * x ) );
1276 if( biL >= 64 ) x *= ( 2 - ( m0 * x ) );
1277
1278 *mm = ~x + 1;
1279}
1280
1281/*
1282 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1283 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001284static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001285{
Paul Bakker23986e52011-04-24 08:57:21 +00001286 size_t i, n, m;
Paul Bakkera755ca12011-04-24 09:11:17 +00001287 t_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00001288
1289 memset( T->p, 0, T->n * ciL );
1290
1291 d = T->p;
1292 n = N->n;
1293 m = ( B->n < n ) ? B->n : n;
1294
1295 for( i = 0; i < n; i++ )
1296 {
1297 /*
1298 * T = (T + u0*B + u1*N) / 2^biL
1299 */
1300 u0 = A->p[i];
1301 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1302
1303 mpi_mul_hlp( m, B->p, d, u0 );
1304 mpi_mul_hlp( n, N->p, d, u1 );
1305
1306 *d++ = u0; d[n + 1] = 0;
1307 }
1308
1309 memcpy( A->p, d, (n + 1) * ciL );
1310
1311 if( mpi_cmp_abs( A, N ) >= 0 )
1312 mpi_sub_hlp( n, N->p, A->p );
1313 else
1314 /* prevent timing attacks */
1315 mpi_sub_hlp( n, A->p, T->p );
1316}
1317
1318/*
1319 * Montgomery reduction: A = A * R^-1 mod N
1320 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001321static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001322{
Paul Bakkera755ca12011-04-24 09:11:17 +00001323 t_uint z = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001324 mpi U;
1325
1326 U.n = U.s = z;
1327 U.p = &z;
1328
1329 mpi_montmul( A, &U, N, mm, T );
1330}
1331
1332/*
1333 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1334 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001335int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00001336{
Paul Bakker23986e52011-04-24 08:57:21 +00001337 int ret;
1338 size_t wbits, wsize, one = 1;
1339 size_t i, j, nblimbs;
1340 size_t bufsize, nbits;
Paul Bakkera755ca12011-04-24 09:11:17 +00001341 t_uint ei, mm, state;
Paul Bakker5121ce52009-01-03 21:22:43 +00001342 mpi RR, T, W[64];
1343
1344 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001345 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001346
1347 /*
1348 * Init temps and window size
1349 */
1350 mpi_montg_init( &mm, N );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001351 mpi_init( &RR ); mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00001352 memset( W, 0, sizeof( W ) );
1353
1354 i = mpi_msb( E );
1355
1356 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1357 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1358
1359 j = N->n + 1;
1360 MPI_CHK( mpi_grow( X, j ) );
1361 MPI_CHK( mpi_grow( &W[1], j ) );
1362 MPI_CHK( mpi_grow( &T, j * 2 ) );
1363
1364 /*
1365 * If 1st call, pre-compute R^2 mod N
1366 */
1367 if( _RR == NULL || _RR->p == NULL )
1368 {
1369 MPI_CHK( mpi_lset( &RR, 1 ) );
1370 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1371 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1372
1373 if( _RR != NULL )
1374 memcpy( _RR, &RR, sizeof( mpi ) );
1375 }
1376 else
1377 memcpy( &RR, _RR, sizeof( mpi ) );
1378
1379 /*
1380 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1381 */
1382 if( mpi_cmp_mpi( A, N ) >= 0 )
1383 mpi_mod_mpi( &W[1], A, N );
1384 else mpi_copy( &W[1], A );
1385
1386 mpi_montmul( &W[1], &RR, N, mm, &T );
1387
1388 /*
1389 * X = R^2 * R^-1 mod N = R mod N
1390 */
1391 MPI_CHK( mpi_copy( X, &RR ) );
1392 mpi_montred( X, N, mm, &T );
1393
1394 if( wsize > 1 )
1395 {
1396 /*
1397 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1398 */
Paul Bakker23986e52011-04-24 08:57:21 +00001399 j = one << (wsize - 1);
Paul Bakker5121ce52009-01-03 21:22:43 +00001400
1401 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1402 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1403
1404 for( i = 0; i < wsize - 1; i++ )
1405 mpi_montmul( &W[j], &W[j], N, mm, &T );
1406
1407 /*
1408 * W[i] = W[i - 1] * W[1]
1409 */
Paul Bakker23986e52011-04-24 08:57:21 +00001410 for( i = j + 1; i < (one << wsize); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001411 {
1412 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1413 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1414
1415 mpi_montmul( &W[i], &W[1], N, mm, &T );
1416 }
1417 }
1418
1419 nblimbs = E->n;
1420 bufsize = 0;
1421 nbits = 0;
1422 wbits = 0;
1423 state = 0;
1424
1425 while( 1 )
1426 {
1427 if( bufsize == 0 )
1428 {
1429 if( nblimbs-- == 0 )
1430 break;
1431
Paul Bakkera755ca12011-04-24 09:11:17 +00001432 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001433 }
1434
1435 bufsize--;
1436
1437 ei = (E->p[nblimbs] >> bufsize) & 1;
1438
1439 /*
1440 * skip leading 0s
1441 */
1442 if( ei == 0 && state == 0 )
1443 continue;
1444
1445 if( ei == 0 && state == 1 )
1446 {
1447 /*
1448 * out of window, square X
1449 */
1450 mpi_montmul( X, X, N, mm, &T );
1451 continue;
1452 }
1453
1454 /*
1455 * add ei to current window
1456 */
1457 state = 2;
1458
1459 nbits++;
1460 wbits |= (ei << (wsize - nbits));
1461
1462 if( nbits == wsize )
1463 {
1464 /*
1465 * X = X^wsize R^-1 mod N
1466 */
1467 for( i = 0; i < wsize; i++ )
1468 mpi_montmul( X, X, N, mm, &T );
1469
1470 /*
1471 * X = X * W[wbits] R^-1 mod N
1472 */
1473 mpi_montmul( X, &W[wbits], N, mm, &T );
1474
1475 state--;
1476 nbits = 0;
1477 wbits = 0;
1478 }
1479 }
1480
1481 /*
1482 * process the remaining bits
1483 */
1484 for( i = 0; i < nbits; i++ )
1485 {
1486 mpi_montmul( X, X, N, mm, &T );
1487
1488 wbits <<= 1;
1489
Paul Bakker23986e52011-04-24 08:57:21 +00001490 if( (wbits & (one << wsize)) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001491 mpi_montmul( X, &W[1], N, mm, &T );
1492 }
1493
1494 /*
1495 * X = A^E * R * R^-1 mod N = A^E mod N
1496 */
1497 mpi_montred( X, N, mm, &T );
1498
1499cleanup:
1500
Paul Bakker23986e52011-04-24 08:57:21 +00001501 for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001502 mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001503
Paul Bakker6c591fa2011-05-05 11:49:20 +00001504 mpi_free( &W[1] ); mpi_free( &T );
1505
1506 if( _RR == NULL )
1507 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001508
1509 return( ret );
1510}
1511
Paul Bakker5121ce52009-01-03 21:22:43 +00001512/*
1513 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1514 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001515int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001516{
Paul Bakker23986e52011-04-24 08:57:21 +00001517 int ret;
1518 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001519 mpi TG, TA, TB;
1520
Paul Bakker6c591fa2011-05-05 11:49:20 +00001521 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001522
Paul Bakker5121ce52009-01-03 21:22:43 +00001523 MPI_CHK( mpi_copy( &TA, A ) );
1524 MPI_CHK( mpi_copy( &TB, B ) );
1525
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001526 lz = mpi_lsb( &TA );
1527 lzt = mpi_lsb( &TB );
1528
1529 if ( lzt < lz )
1530 lz = lzt;
1531
1532 MPI_CHK( mpi_shift_r( &TA, lz ) );
1533 MPI_CHK( mpi_shift_r( &TB, lz ) );
1534
Paul Bakker5121ce52009-01-03 21:22:43 +00001535 TA.s = TB.s = 1;
1536
1537 while( mpi_cmp_int( &TA, 0 ) != 0 )
1538 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001539 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1540 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001541
1542 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1543 {
1544 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1545 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1546 }
1547 else
1548 {
1549 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1550 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1551 }
1552 }
1553
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001554 MPI_CHK( mpi_shift_l( &TB, lz ) );
1555 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001556
1557cleanup:
1558
Paul Bakker6c591fa2011-05-05 11:49:20 +00001559 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001560
1561 return( ret );
1562}
1563
Paul Bakker23986e52011-04-24 08:57:21 +00001564int mpi_fill_random( mpi *X, size_t size, int (*f_rng)(void *), void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001565{
Paul Bakker23986e52011-04-24 08:57:21 +00001566 int ret;
1567 size_t k;
Paul Bakker287781a2011-03-26 13:18:49 +00001568 unsigned char *p;
1569
1570 MPI_CHK( mpi_grow( X, size ) );
1571 MPI_CHK( mpi_lset( X, 0 ) );
1572
1573 p = (unsigned char *) X->p;
1574 for( k = 0; k < X->n * ciL; k++ )
1575 *p++ = (unsigned char) f_rng( p_rng );
1576
1577cleanup:
1578 return( ret );
1579}
1580
Paul Bakker70b3eed2009-03-14 18:01:25 +00001581#if defined(POLARSSL_GENPRIME)
1582
Paul Bakker5121ce52009-01-03 21:22:43 +00001583/*
1584 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1585 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001586int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001587{
1588 int ret;
1589 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1590
1591 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001592 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001593
Paul Bakker6c591fa2011-05-05 11:49:20 +00001594 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1595 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1596 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001597
1598 MPI_CHK( mpi_gcd( &G, A, N ) );
1599
1600 if( mpi_cmp_int( &G, 1 ) != 0 )
1601 {
Paul Bakker40e46942009-01-03 21:51:57 +00001602 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001603 goto cleanup;
1604 }
1605
1606 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1607 MPI_CHK( mpi_copy( &TU, &TA ) );
1608 MPI_CHK( mpi_copy( &TB, N ) );
1609 MPI_CHK( mpi_copy( &TV, N ) );
1610
1611 MPI_CHK( mpi_lset( &U1, 1 ) );
1612 MPI_CHK( mpi_lset( &U2, 0 ) );
1613 MPI_CHK( mpi_lset( &V1, 0 ) );
1614 MPI_CHK( mpi_lset( &V2, 1 ) );
1615
1616 do
1617 {
1618 while( ( TU.p[0] & 1 ) == 0 )
1619 {
1620 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1621
1622 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1623 {
1624 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1625 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1626 }
1627
1628 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1629 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1630 }
1631
1632 while( ( TV.p[0] & 1 ) == 0 )
1633 {
1634 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1635
1636 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1637 {
1638 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1639 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1640 }
1641
1642 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1643 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1644 }
1645
1646 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1647 {
1648 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1649 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1650 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1651 }
1652 else
1653 {
1654 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1655 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1656 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1657 }
1658 }
1659 while( mpi_cmp_int( &TU, 0 ) != 0 );
1660
1661 while( mpi_cmp_int( &V1, 0 ) < 0 )
1662 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1663
1664 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1665 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1666
1667 MPI_CHK( mpi_copy( X, &V1 ) );
1668
1669cleanup:
1670
Paul Bakker6c591fa2011-05-05 11:49:20 +00001671 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1672 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1673 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001674
1675 return( ret );
1676}
1677
1678static const int small_prime[] =
1679{
1680 3, 5, 7, 11, 13, 17, 19, 23,
1681 29, 31, 37, 41, 43, 47, 53, 59,
1682 61, 67, 71, 73, 79, 83, 89, 97,
1683 101, 103, 107, 109, 113, 127, 131, 137,
1684 139, 149, 151, 157, 163, 167, 173, 179,
1685 181, 191, 193, 197, 199, 211, 223, 227,
1686 229, 233, 239, 241, 251, 257, 263, 269,
1687 271, 277, 281, 283, 293, 307, 311, 313,
1688 317, 331, 337, 347, 349, 353, 359, 367,
1689 373, 379, 383, 389, 397, 401, 409, 419,
1690 421, 431, 433, 439, 443, 449, 457, 461,
1691 463, 467, 479, 487, 491, 499, 503, 509,
1692 521, 523, 541, 547, 557, 563, 569, 571,
1693 577, 587, 593, 599, 601, 607, 613, 617,
1694 619, 631, 641, 643, 647, 653, 659, 661,
1695 673, 677, 683, 691, 701, 709, 719, 727,
1696 733, 739, 743, 751, 757, 761, 769, 773,
1697 787, 797, 809, 811, 821, 823, 827, 829,
1698 839, 853, 857, 859, 863, 877, 881, 883,
1699 887, 907, 911, 919, 929, 937, 941, 947,
1700 953, 967, 971, 977, 983, 991, 997, -103
1701};
1702
1703/*
1704 * Miller-Rabin primality test (HAC 4.24)
1705 */
1706int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng )
1707{
Paul Bakker23986e52011-04-24 08:57:21 +00001708 int ret, xs;
1709 size_t i, j, n, s;
Paul Bakker5121ce52009-01-03 21:22:43 +00001710 mpi W, R, T, A, RR;
Paul Bakker5121ce52009-01-03 21:22:43 +00001711
Paul Bakker48eab262009-06-25 21:25:49 +00001712 if( mpi_cmp_int( X, 0 ) == 0 ||
1713 mpi_cmp_int( X, 1 ) == 0 )
1714 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
1715
1716 if( mpi_cmp_int( X, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001717 return( 0 );
1718
Paul Bakker6c591fa2011-05-05 11:49:20 +00001719 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1720 mpi_init( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001721
1722 xs = X->s; X->s = 1;
1723
1724 /*
1725 * test trivial factors first
1726 */
1727 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001728 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001729
1730 for( i = 0; small_prime[i] > 0; i++ )
1731 {
Paul Bakkera755ca12011-04-24 09:11:17 +00001732 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001733
1734 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
1735 return( 0 );
1736
1737 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1738
1739 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001740 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001741 }
1742
1743 /*
1744 * W = |X| - 1
1745 * R = W >> lsb( W )
1746 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001747 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001748 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001749 MPI_CHK( mpi_copy( &R, &W ) );
1750 MPI_CHK( mpi_shift_r( &R, s ) );
1751
1752 i = mpi_msb( X );
1753 /*
1754 * HAC, table 4.4
1755 */
1756 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1757 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1758 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1759
1760 for( i = 0; i < n; i++ )
1761 {
1762 /*
1763 * pick a random A, 1 < A < |X| - 1
1764 */
Paul Bakker287781a2011-03-26 13:18:49 +00001765 mpi_fill_random( &A, X->n, f_rng, p_rng );
Paul Bakker5121ce52009-01-03 21:22:43 +00001766
Paul Bakkerb94081b2011-01-05 15:53:06 +00001767 if( mpi_cmp_mpi( &A, &W ) >= 0 )
1768 {
1769 j = mpi_msb( &A ) - mpi_msb( &W );
1770 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
1771 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001772 A.p[0] |= 3;
1773
1774 /*
1775 * A = A^R mod |X|
1776 */
1777 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
1778
1779 if( mpi_cmp_mpi( &A, &W ) == 0 ||
1780 mpi_cmp_int( &A, 1 ) == 0 )
1781 continue;
1782
1783 j = 1;
1784 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
1785 {
1786 /*
1787 * A = A * A mod |X|
1788 */
1789 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
1790 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
1791
1792 if( mpi_cmp_int( &A, 1 ) == 0 )
1793 break;
1794
1795 j++;
1796 }
1797
1798 /*
1799 * not prime if A != |X| - 1 or A == 1
1800 */
1801 if( mpi_cmp_mpi( &A, &W ) != 0 ||
1802 mpi_cmp_int( &A, 1 ) == 0 )
1803 {
Paul Bakker40e46942009-01-03 21:51:57 +00001804 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001805 break;
1806 }
1807 }
1808
1809cleanup:
1810
1811 X->s = xs;
1812
Paul Bakker6c591fa2011-05-05 11:49:20 +00001813 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
1814 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001815
1816 return( ret );
1817}
1818
1819/*
1820 * Prime number generation
1821 */
Paul Bakker23986e52011-04-24 08:57:21 +00001822int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakker5121ce52009-01-03 21:22:43 +00001823 int (*f_rng)(void *), void *p_rng )
1824{
Paul Bakker23986e52011-04-24 08:57:21 +00001825 int ret;
1826 size_t k, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00001827 mpi Y;
1828
Paul Bakkerf9688572011-05-05 10:00:45 +00001829 if( nbits < 3 || nbits > 4096 )
Paul Bakker40e46942009-01-03 21:51:57 +00001830 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001831
Paul Bakker6c591fa2011-05-05 11:49:20 +00001832 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00001833
1834 n = BITS_TO_LIMBS( nbits );
1835
Paul Bakker287781a2011-03-26 13:18:49 +00001836 mpi_fill_random( X, n, f_rng, p_rng );
Paul Bakker5121ce52009-01-03 21:22:43 +00001837
1838 k = mpi_msb( X );
1839 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
1840 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
1841
1842 X->p[0] |= 3;
1843
1844 if( dh_flag == 0 )
1845 {
1846 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
1847 {
Paul Bakker40e46942009-01-03 21:51:57 +00001848 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001849 goto cleanup;
1850
1851 MPI_CHK( mpi_add_int( X, X, 2 ) );
1852 }
1853 }
1854 else
1855 {
1856 MPI_CHK( mpi_sub_int( &Y, X, 1 ) );
1857 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1858
1859 while( 1 )
1860 {
1861 if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 )
1862 {
1863 if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 )
1864 break;
1865
Paul Bakker40e46942009-01-03 21:51:57 +00001866 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001867 goto cleanup;
1868 }
1869
Paul Bakker40e46942009-01-03 21:51:57 +00001870 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001871 goto cleanup;
1872
1873 MPI_CHK( mpi_add_int( &Y, X, 1 ) );
1874 MPI_CHK( mpi_add_int( X, X, 2 ) );
1875 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1876 }
1877 }
1878
1879cleanup:
1880
Paul Bakker6c591fa2011-05-05 11:49:20 +00001881 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00001882
1883 return( ret );
1884}
1885
1886#endif
1887
Paul Bakker40e46942009-01-03 21:51:57 +00001888#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001889
Paul Bakker23986e52011-04-24 08:57:21 +00001890#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001891
1892static const int gcd_pairs[GCD_PAIR_COUNT][3] =
1893{
1894 { 693, 609, 21 },
1895 { 1764, 868, 28 },
1896 { 768454923, 542167814, 1 }
1897};
1898
Paul Bakker5121ce52009-01-03 21:22:43 +00001899/*
1900 * Checkup routine
1901 */
1902int mpi_self_test( int verbose )
1903{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001904 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001905 mpi A, E, N, X, Y, U, V;
1906
Paul Bakker6c591fa2011-05-05 11:49:20 +00001907 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
1908 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00001909
1910 MPI_CHK( mpi_read_string( &A, 16,
1911 "EFE021C2645FD1DC586E69184AF4A31E" \
1912 "D5F53E93B5F123FA41680867BA110131" \
1913 "944FE7952E2517337780CB0DB80E61AA" \
1914 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
1915
1916 MPI_CHK( mpi_read_string( &E, 16,
1917 "B2E7EFD37075B9F03FF989C7C5051C20" \
1918 "34D2A323810251127E7BF8625A4F49A5" \
1919 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
1920 "5B5C25763222FEFCCFC38B832366C29E" ) );
1921
1922 MPI_CHK( mpi_read_string( &N, 16,
1923 "0066A198186C18C10B2F5ED9B522752A" \
1924 "9830B69916E535C8F047518A889A43A5" \
1925 "94B6BED27A168D31D4A52F88925AA8F5" ) );
1926
1927 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
1928
1929 MPI_CHK( mpi_read_string( &U, 16,
1930 "602AB7ECA597A3D6B56FF9829A5E8B85" \
1931 "9E857EA95A03512E2BAE7391688D264A" \
1932 "A5663B0341DB9CCFD2C4C5F421FEC814" \
1933 "8001B72E848A38CAE1C65F78E56ABDEF" \
1934 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
1935 "ECF677152EF804370C1A305CAF3B5BF1" \
1936 "30879B56C61DE584A0F53A2447A51E" ) );
1937
1938 if( verbose != 0 )
1939 printf( " MPI test #1 (mul_mpi): " );
1940
1941 if( mpi_cmp_mpi( &X, &U ) != 0 )
1942 {
1943 if( verbose != 0 )
1944 printf( "failed\n" );
1945
1946 return( 1 );
1947 }
1948
1949 if( verbose != 0 )
1950 printf( "passed\n" );
1951
1952 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
1953
1954 MPI_CHK( mpi_read_string( &U, 16,
1955 "256567336059E52CAE22925474705F39A94" ) );
1956
1957 MPI_CHK( mpi_read_string( &V, 16,
1958 "6613F26162223DF488E9CD48CC132C7A" \
1959 "0AC93C701B001B092E4E5B9F73BCD27B" \
1960 "9EE50D0657C77F374E903CDFA4C642" ) );
1961
1962 if( verbose != 0 )
1963 printf( " MPI test #2 (div_mpi): " );
1964
1965 if( mpi_cmp_mpi( &X, &U ) != 0 ||
1966 mpi_cmp_mpi( &Y, &V ) != 0 )
1967 {
1968 if( verbose != 0 )
1969 printf( "failed\n" );
1970
1971 return( 1 );
1972 }
1973
1974 if( verbose != 0 )
1975 printf( "passed\n" );
1976
1977 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
1978
1979 MPI_CHK( mpi_read_string( &U, 16,
1980 "36E139AEA55215609D2816998ED020BB" \
1981 "BD96C37890F65171D948E9BC7CBAA4D9" \
1982 "325D24D6A3C12710F10A09FA08AB87" ) );
1983
1984 if( verbose != 0 )
1985 printf( " MPI test #3 (exp_mod): " );
1986
1987 if( mpi_cmp_mpi( &X, &U ) != 0 )
1988 {
1989 if( verbose != 0 )
1990 printf( "failed\n" );
1991
1992 return( 1 );
1993 }
1994
1995 if( verbose != 0 )
1996 printf( "passed\n" );
1997
1998 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
1999
2000 MPI_CHK( mpi_read_string( &U, 16,
2001 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2002 "C3DBA76456363A10869622EAC2DD84EC" \
2003 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2004
2005 if( verbose != 0 )
2006 printf( " MPI test #4 (inv_mod): " );
2007
2008 if( mpi_cmp_mpi( &X, &U ) != 0 )
2009 {
2010 if( verbose != 0 )
2011 printf( "failed\n" );
2012
2013 return( 1 );
2014 }
2015
2016 if( verbose != 0 )
2017 printf( "passed\n" );
2018
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002019 if( verbose != 0 )
2020 printf( " MPI test #5 (simple gcd): " );
2021
2022 for ( i = 0; i < GCD_PAIR_COUNT; i++)
2023 {
2024 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002025 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002026
Paul Bakker23986e52011-04-24 08:57:21 +00002027 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002028
Paul Bakker23986e52011-04-24 08:57:21 +00002029 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2030 {
2031 if( verbose != 0 )
2032 printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002033
Paul Bakker23986e52011-04-24 08:57:21 +00002034 return( 1 );
2035 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002036 }
2037
2038 if( verbose != 0 )
2039 printf( "passed\n" );
2040
Paul Bakker5121ce52009-01-03 21:22:43 +00002041cleanup:
2042
2043 if( ret != 0 && verbose != 0 )
2044 printf( "Unexpected error, return code = %08X\n", ret );
2045
Paul Bakker6c591fa2011-05-05 11:49:20 +00002046 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2047 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002048
2049 if( verbose != 0 )
2050 printf( "\n" );
2051
2052 return( ret );
2053}
2054
2055#endif
2056
2057#endif