blob: 8f29324e479bf6aa25781eded0c40346d2977dde [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>
41#include <stdarg.h>
42
Paul Bakkera755ca12011-04-24 09:11:17 +000043#define ciL ((int) sizeof(t_uint)) /* chars in limb */
Paul Bakker5121ce52009-01-03 21:22:43 +000044#define biL (ciL << 3) /* bits in limb */
45#define biH (ciL << 2) /* half limb size */
46
47/*
48 * Convert between bits/chars and number of limbs
49 */
50#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
51#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
52
53/*
54 * Initialize one or more mpi
55 */
56void mpi_init( mpi *X, ... )
57{
58 va_list args;
59
60 va_start( args, X );
61
62 while( X != NULL )
63 {
64 X->s = 1;
65 X->n = 0;
66 X->p = NULL;
67
68 X = va_arg( args, mpi* );
69 }
70
71 va_end( args );
72}
73
74/*
75 * Unallocate one or more mpi
76 */
77void mpi_free( mpi *X, ... )
78{
79 va_list args;
80
81 va_start( args, X );
82
83 while( X != NULL )
84 {
85 if( X->p != NULL )
86 {
87 memset( X->p, 0, X->n * ciL );
88 free( X->p );
89 }
90
91 X->s = 1;
92 X->n = 0;
93 X->p = NULL;
94
95 X = va_arg( args, mpi* );
96 }
97
98 va_end( args );
99}
100
101/*
102 * Enlarge to the specified number of limbs
103 */
Paul Bakker23986e52011-04-24 08:57:21 +0000104int mpi_grow( mpi *X, size_t nblimbs )
Paul Bakker5121ce52009-01-03 21:22:43 +0000105{
Paul Bakkera755ca12011-04-24 09:11:17 +0000106 t_uint *p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
108 if( X->n < nblimbs )
109 {
Paul Bakkera755ca12011-04-24 09:11:17 +0000110 if( ( p = (t_uint *) malloc( nblimbs * ciL ) ) == NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +0000111 return( 1 );
112
113 memset( p, 0, nblimbs * ciL );
114
115 if( X->p != NULL )
116 {
117 memcpy( p, X->p, X->n * ciL );
118 memset( X->p, 0, X->n * ciL );
119 free( X->p );
120 }
121
122 X->n = nblimbs;
123 X->p = p;
124 }
125
126 return( 0 );
127}
128
129/*
130 * Copy the contents of Y into X
131 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000132int mpi_copy( mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000133{
Paul Bakker23986e52011-04-24 08:57:21 +0000134 int ret;
135 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000136
137 if( X == Y )
138 return( 0 );
139
140 for( i = Y->n - 1; i > 0; i-- )
141 if( Y->p[i] != 0 )
142 break;
143 i++;
144
145 X->s = Y->s;
146
147 MPI_CHK( mpi_grow( X, i ) );
148
149 memset( X->p, 0, X->n * ciL );
150 memcpy( X->p, Y->p, i * ciL );
151
152cleanup:
153
154 return( ret );
155}
156
157/*
158 * Swap the contents of X and Y
159 */
160void mpi_swap( mpi *X, mpi *Y )
161{
162 mpi T;
163
164 memcpy( &T, X, sizeof( mpi ) );
165 memcpy( X, Y, sizeof( mpi ) );
166 memcpy( Y, &T, sizeof( mpi ) );
167}
168
169/*
170 * Set value from integer
171 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000172int mpi_lset( mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000173{
174 int ret;
175
176 MPI_CHK( mpi_grow( X, 1 ) );
177 memset( X->p, 0, X->n * ciL );
178
179 X->p[0] = ( z < 0 ) ? -z : z;
180 X->s = ( z < 0 ) ? -1 : 1;
181
182cleanup:
183
184 return( ret );
185}
186
187/*
188 * Return the number of least significant bits
189 */
Paul Bakker23986e52011-04-24 08:57:21 +0000190size_t mpi_lsb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000191{
Paul Bakker23986e52011-04-24 08:57:21 +0000192 size_t i, j, count = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000193
194 for( i = 0; i < X->n; i++ )
195 for( j = 0; j < (int) biL; j++, count++ )
196 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
197 return( count );
198
199 return( 0 );
200}
201
202/*
203 * Return the number of most significant bits
204 */
Paul Bakker23986e52011-04-24 08:57:21 +0000205size_t mpi_msb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000206{
Paul Bakker23986e52011-04-24 08:57:21 +0000207 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000208
209 for( i = X->n - 1; i > 0; i-- )
210 if( X->p[i] != 0 )
211 break;
212
Paul Bakker23986e52011-04-24 08:57:21 +0000213 for( j = biL; j > 0; j-- )
214 if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000215 break;
216
Paul Bakker23986e52011-04-24 08:57:21 +0000217 return( ( i * biL ) + j );
Paul Bakker5121ce52009-01-03 21:22:43 +0000218}
219
220/*
221 * Return the total size in bytes
222 */
Paul Bakker23986e52011-04-24 08:57:21 +0000223size_t mpi_size( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000224{
225 return( ( mpi_msb( X ) + 7 ) >> 3 );
226}
227
228/*
229 * Convert an ASCII character to digit value
230 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000231static int mpi_get_digit( t_uint *d, int radix, char c )
Paul Bakker5121ce52009-01-03 21:22:43 +0000232{
233 *d = 255;
234
235 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
236 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
237 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
238
Paul Bakkera755ca12011-04-24 09:11:17 +0000239 if( *d >= (t_uint) radix )
Paul Bakker40e46942009-01-03 21:51:57 +0000240 return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000241
242 return( 0 );
243}
244
245/*
246 * Import from an ASCII string
247 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000248int mpi_read_string( mpi *X, int radix, const char *s )
Paul Bakker5121ce52009-01-03 21:22:43 +0000249{
Paul Bakker23986e52011-04-24 08:57:21 +0000250 int ret;
251 size_t i, j, slen, n;
Paul Bakkera755ca12011-04-24 09:11:17 +0000252 t_uint d;
Paul Bakker5121ce52009-01-03 21:22:43 +0000253 mpi T;
254
255 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000256 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000257
258 mpi_init( &T, NULL );
259
Paul Bakkerff60ee62010-03-16 21:09:09 +0000260 slen = strlen( s );
261
Paul Bakker5121ce52009-01-03 21:22:43 +0000262 if( radix == 16 )
263 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000264 n = BITS_TO_LIMBS( slen << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000265
266 MPI_CHK( mpi_grow( X, n ) );
267 MPI_CHK( mpi_lset( X, 0 ) );
268
Paul Bakker23986e52011-04-24 08:57:21 +0000269 for( i = slen, j = 0; i > 0; i--, j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000270 {
Paul Bakker23986e52011-04-24 08:57:21 +0000271 if( i == 1 && s[i - 1] == '-' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000272 {
273 X->s = -1;
274 break;
275 }
276
Paul Bakker23986e52011-04-24 08:57:21 +0000277 MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000278 X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 );
279 }
280 }
281 else
282 {
283 MPI_CHK( mpi_lset( X, 0 ) );
284
Paul Bakkerff60ee62010-03-16 21:09:09 +0000285 for( i = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000286 {
287 if( i == 0 && s[i] == '-' )
288 {
289 X->s = -1;
290 continue;
291 }
292
293 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
294 MPI_CHK( mpi_mul_int( &T, X, radix ) );
Paul Bakker05feca62009-06-20 08:22:43 +0000295
296 if( X->s == 1 )
297 {
298 MPI_CHK( mpi_add_int( X, &T, d ) );
299 }
300 else
301 {
302 MPI_CHK( mpi_sub_int( X, &T, d ) );
303 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000304 }
305 }
306
307cleanup:
308
309 mpi_free( &T, NULL );
310
311 return( ret );
312}
313
314/*
315 * Helper to write the digits high-order first
316 */
317static int mpi_write_hlp( mpi *X, int radix, char **p )
318{
319 int ret;
Paul Bakkera755ca12011-04-24 09:11:17 +0000320 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +0000321
322 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000323 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000324
325 MPI_CHK( mpi_mod_int( &r, X, radix ) );
326 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
327
328 if( mpi_cmp_int( X, 0 ) != 0 )
329 MPI_CHK( mpi_write_hlp( X, radix, p ) );
330
331 if( r < 10 )
332 *(*p)++ = (char)( r + 0x30 );
333 else
334 *(*p)++ = (char)( r + 0x37 );
335
336cleanup:
337
338 return( ret );
339}
340
341/*
342 * Export into an ASCII string
343 */
Paul Bakker23986e52011-04-24 08:57:21 +0000344int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000345{
Paul Bakker23986e52011-04-24 08:57:21 +0000346 int ret = 0;
347 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000348 char *p;
349 mpi T;
350
351 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000352 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000353
354 n = mpi_msb( X );
355 if( radix >= 4 ) n >>= 1;
356 if( radix >= 16 ) n >>= 1;
357 n += 3;
358
359 if( *slen < n )
360 {
361 *slen = n;
Paul Bakker40e46942009-01-03 21:51:57 +0000362 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000363 }
364
365 p = s;
366 mpi_init( &T, NULL );
367
368 if( X->s == -1 )
369 *p++ = '-';
370
371 if( radix == 16 )
372 {
Paul Bakker23986e52011-04-24 08:57:21 +0000373 int c;
374 size_t i, j, k;
Paul Bakker5121ce52009-01-03 21:22:43 +0000375
Paul Bakker23986e52011-04-24 08:57:21 +0000376 for( i = X->n, k = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000377 {
Paul Bakker23986e52011-04-24 08:57:21 +0000378 for( j = ciL; j > 0; j-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000379 {
Paul Bakker23986e52011-04-24 08:57:21 +0000380 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000381
Paul Bakker23986e52011-04-24 08:57:21 +0000382 if( c == 0 && k == 0 && ( i + j + 3 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000383 continue;
384
385 p += sprintf( p, "%02X", c );
386 k = 1;
387 }
388 }
389 }
390 else
391 {
392 MPI_CHK( mpi_copy( &T, X ) );
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000393
394 if( T.s == -1 )
395 T.s = 1;
396
Paul Bakker5121ce52009-01-03 21:22:43 +0000397 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
398 }
399
400 *p++ = '\0';
401 *slen = p - s;
402
403cleanup:
404
405 mpi_free( &T, NULL );
406
407 return( ret );
408}
409
Paul Bakker335db3f2011-04-25 15:28:35 +0000410#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000411/*
412 * Read X from an opened file
413 */
414int mpi_read_file( mpi *X, int radix, FILE *fin )
415{
Paul Bakkera755ca12011-04-24 09:11:17 +0000416 t_uint d;
Paul Bakker23986e52011-04-24 08:57:21 +0000417 size_t slen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000418 char *p;
419 char s[1024];
420
421 memset( s, 0, sizeof( s ) );
422 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000423 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000424
425 slen = strlen( s );
426 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
427 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
428
429 p = s + slen;
430 while( --p >= s )
431 if( mpi_get_digit( &d, radix, *p ) != 0 )
432 break;
433
434 return( mpi_read_string( X, radix, p + 1 ) );
435}
436
437/*
438 * Write X into an opened file (or stdout if fout == NULL)
439 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000440int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
Paul Bakker5121ce52009-01-03 21:22:43 +0000441{
Paul Bakker23986e52011-04-24 08:57:21 +0000442 int ret;
443 size_t n, slen, plen;
Paul Bakker08f3c302010-07-08 06:54:25 +0000444 char s[2048];
Paul Bakker5121ce52009-01-03 21:22:43 +0000445
446 n = sizeof( s );
447 memset( s, 0, n );
448 n -= 2;
449
Paul Bakker23986e52011-04-24 08:57:21 +0000450 MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
452 if( p == NULL ) p = "";
453
454 plen = strlen( p );
455 slen = strlen( s );
456 s[slen++] = '\r';
457 s[slen++] = '\n';
458
459 if( fout != NULL )
460 {
461 if( fwrite( p, 1, plen, fout ) != plen ||
462 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000463 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000464 }
465 else
466 printf( "%s%s", p, s );
467
468cleanup:
469
470 return( ret );
471}
Paul Bakker335db3f2011-04-25 15:28:35 +0000472#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000473
474/*
475 * Import X from unsigned binary data, big endian
476 */
Paul Bakker23986e52011-04-24 08:57:21 +0000477int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000478{
Paul Bakker23986e52011-04-24 08:57:21 +0000479 int ret;
480 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000481
482 for( n = 0; n < buflen; n++ )
483 if( buf[n] != 0 )
484 break;
485
486 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
487 MPI_CHK( mpi_lset( X, 0 ) );
488
Paul Bakker23986e52011-04-24 08:57:21 +0000489 for( i = buflen, j = 0; i > n; i--, j++ )
Paul Bakkera755ca12011-04-24 09:11:17 +0000490 X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000491
492cleanup:
493
494 return( ret );
495}
496
497/*
498 * Export X into unsigned binary data, big endian
499 */
Paul Bakker23986e52011-04-24 08:57:21 +0000500int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000501{
Paul Bakker23986e52011-04-24 08:57:21 +0000502 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000503
504 n = mpi_size( X );
505
506 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000507 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000508
509 memset( buf, 0, buflen );
510
511 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
512 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
513
514 return( 0 );
515}
516
517/*
518 * Left-shift: X <<= count
519 */
Paul Bakker23986e52011-04-24 08:57:21 +0000520int mpi_shift_l( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000521{
Paul Bakker23986e52011-04-24 08:57:21 +0000522 int ret;
523 size_t i, v0, t1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000524 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000525
526 v0 = count / (biL );
527 t1 = count & (biL - 1);
528
529 i = mpi_msb( X ) + count;
530
531 if( X->n * (int) biL < i )
532 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
533
534 ret = 0;
535
536 /*
537 * shift by count / limb_size
538 */
539 if( v0 > 0 )
540 {
Paul Bakker23986e52011-04-24 08:57:21 +0000541 for( i = X->n; i > v0; i-- )
542 X->p[i - 1] = X->p[i - v0 - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000543
Paul Bakker23986e52011-04-24 08:57:21 +0000544 for( ; i > 0; i-- )
545 X->p[i - 1] = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000546 }
547
548 /*
549 * shift by count % limb_size
550 */
551 if( t1 > 0 )
552 {
553 for( i = v0; i < X->n; i++ )
554 {
555 r1 = X->p[i] >> (biL - t1);
556 X->p[i] <<= t1;
557 X->p[i] |= r0;
558 r0 = r1;
559 }
560 }
561
562cleanup:
563
564 return( ret );
565}
566
567/*
568 * Right-shift: X >>= count
569 */
Paul Bakker23986e52011-04-24 08:57:21 +0000570int mpi_shift_r( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000571{
Paul Bakker23986e52011-04-24 08:57:21 +0000572 size_t i, v0, v1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000573 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000574
575 v0 = count / biL;
576 v1 = count & (biL - 1);
577
578 /*
579 * shift by count / limb_size
580 */
581 if( v0 > 0 )
582 {
583 for( i = 0; i < X->n - v0; i++ )
584 X->p[i] = X->p[i + v0];
585
586 for( ; i < X->n; i++ )
587 X->p[i] = 0;
588 }
589
590 /*
591 * shift by count % limb_size
592 */
593 if( v1 > 0 )
594 {
Paul Bakker23986e52011-04-24 08:57:21 +0000595 for( i = X->n; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000596 {
Paul Bakker23986e52011-04-24 08:57:21 +0000597 r1 = X->p[i - 1] << (biL - v1);
598 X->p[i - 1] >>= v1;
599 X->p[i - 1] |= r0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000600 r0 = r1;
601 }
602 }
603
604 return( 0 );
605}
606
607/*
608 * Compare unsigned values
609 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000610int mpi_cmp_abs( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000611{
Paul Bakker23986e52011-04-24 08:57:21 +0000612 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000613
Paul Bakker23986e52011-04-24 08:57:21 +0000614 for( i = X->n; i > 0; i-- )
615 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000616 break;
617
Paul Bakker23986e52011-04-24 08:57:21 +0000618 for( j = Y->n; j > 0; j-- )
619 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000620 break;
621
Paul Bakker23986e52011-04-24 08:57:21 +0000622 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000623 return( 0 );
624
625 if( i > j ) return( 1 );
626 if( j > i ) return( -1 );
627
Paul Bakker23986e52011-04-24 08:57:21 +0000628 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000629 {
Paul Bakker23986e52011-04-24 08:57:21 +0000630 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
631 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000632 }
633
634 return( 0 );
635}
636
637/*
638 * Compare signed values
639 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000640int mpi_cmp_mpi( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000641{
Paul Bakker23986e52011-04-24 08:57:21 +0000642 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000643
Paul Bakker23986e52011-04-24 08:57:21 +0000644 for( i = X->n; i > 0; i-- )
645 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000646 break;
647
Paul Bakker23986e52011-04-24 08:57:21 +0000648 for( j = Y->n; j > 0; j-- )
649 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000650 break;
651
Paul Bakker23986e52011-04-24 08:57:21 +0000652 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000653 return( 0 );
654
655 if( i > j ) return( X->s );
656 if( j > i ) return( -X->s );
657
658 if( X->s > 0 && Y->s < 0 ) return( 1 );
659 if( Y->s > 0 && X->s < 0 ) return( -1 );
660
Paul Bakker23986e52011-04-24 08:57:21 +0000661 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000662 {
Paul Bakker23986e52011-04-24 08:57:21 +0000663 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
664 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000665 }
666
667 return( 0 );
668}
669
670/*
671 * Compare signed values
672 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000673int mpi_cmp_int( const mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000674{
675 mpi Y;
Paul Bakkera755ca12011-04-24 09:11:17 +0000676 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000677
678 *p = ( z < 0 ) ? -z : z;
679 Y.s = ( z < 0 ) ? -1 : 1;
680 Y.n = 1;
681 Y.p = p;
682
683 return( mpi_cmp_mpi( X, &Y ) );
684}
685
686/*
687 * Unsigned addition: X = |A| + |B| (HAC 14.7)
688 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000689int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000690{
Paul Bakker23986e52011-04-24 08:57:21 +0000691 int ret;
692 size_t i, j;
Paul Bakkera755ca12011-04-24 09:11:17 +0000693 t_uint *o, *p, c;
Paul Bakker5121ce52009-01-03 21:22:43 +0000694
695 if( X == B )
696 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000697 const mpi *T = A; A = X; B = T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000698 }
699
700 if( X != A )
701 MPI_CHK( mpi_copy( X, A ) );
Paul Bakkerf7ca7b92009-06-20 10:31:06 +0000702
703 /*
704 * X should always be positive as a result of unsigned additions.
705 */
706 X->s = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000707
Paul Bakker23986e52011-04-24 08:57:21 +0000708 for( j = B->n; j > 0; j-- )
709 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000710 break;
711
Paul Bakker23986e52011-04-24 08:57:21 +0000712 MPI_CHK( mpi_grow( X, j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000713
714 o = B->p; p = X->p; c = 0;
715
Paul Bakker23986e52011-04-24 08:57:21 +0000716 for( i = 0; i < j; i++, o++, p++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000717 {
718 *p += c; c = ( *p < c );
719 *p += *o; c += ( *p < *o );
720 }
721
722 while( c != 0 )
723 {
724 if( i >= X->n )
725 {
726 MPI_CHK( mpi_grow( X, i + 1 ) );
727 p = X->p + i;
728 }
729
730 *p += c; c = ( *p < c ); i++;
731 }
732
733cleanup:
734
735 return( ret );
736}
737
738/*
739 * Helper for mpi substraction
740 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000741static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
Paul Bakker5121ce52009-01-03 21:22:43 +0000742{
Paul Bakker23986e52011-04-24 08:57:21 +0000743 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +0000744 t_uint c, z;
Paul Bakker5121ce52009-01-03 21:22:43 +0000745
746 for( i = c = 0; i < n; i++, s++, d++ )
747 {
748 z = ( *d < c ); *d -= c;
749 c = ( *d < *s ) + z; *d -= *s;
750 }
751
752 while( c != 0 )
753 {
754 z = ( *d < c ); *d -= c;
755 c = z; i++; d++;
756 }
757}
758
759/*
760 * Unsigned substraction: X = |A| - |B| (HAC 14.9)
761 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000762int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000763{
764 mpi TB;
Paul Bakker23986e52011-04-24 08:57:21 +0000765 int ret;
766 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000767
768 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000769 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000770
771 mpi_init( &TB, NULL );
772
773 if( X == B )
774 {
775 MPI_CHK( mpi_copy( &TB, B ) );
776 B = &TB;
777 }
778
779 if( X != A )
780 MPI_CHK( mpi_copy( X, A ) );
781
Paul Bakker1ef7a532009-06-20 10:50:55 +0000782 /*
783 * X should always be positive as a result of unsigned substractions.
784 */
785 X->s = 1;
786
Paul Bakker5121ce52009-01-03 21:22:43 +0000787 ret = 0;
788
Paul Bakker23986e52011-04-24 08:57:21 +0000789 for( n = B->n; n > 0; n-- )
790 if( B->p[n - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000791 break;
792
Paul Bakker23986e52011-04-24 08:57:21 +0000793 mpi_sub_hlp( n, B->p, X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000794
795cleanup:
796
797 mpi_free( &TB, NULL );
798
799 return( ret );
800}
801
802/*
803 * Signed addition: X = A + B
804 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000805int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000806{
807 int ret, s = A->s;
808
809 if( A->s * B->s < 0 )
810 {
811 if( mpi_cmp_abs( A, B ) >= 0 )
812 {
813 MPI_CHK( mpi_sub_abs( X, A, B ) );
814 X->s = s;
815 }
816 else
817 {
818 MPI_CHK( mpi_sub_abs( X, B, A ) );
819 X->s = -s;
820 }
821 }
822 else
823 {
824 MPI_CHK( mpi_add_abs( X, A, B ) );
825 X->s = s;
826 }
827
828cleanup:
829
830 return( ret );
831}
832
833/*
834 * Signed substraction: X = A - B
835 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000836int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000837{
838 int ret, s = A->s;
839
840 if( A->s * B->s > 0 )
841 {
842 if( mpi_cmp_abs( A, B ) >= 0 )
843 {
844 MPI_CHK( mpi_sub_abs( X, A, B ) );
845 X->s = s;
846 }
847 else
848 {
849 MPI_CHK( mpi_sub_abs( X, B, A ) );
850 X->s = -s;
851 }
852 }
853 else
854 {
855 MPI_CHK( mpi_add_abs( X, A, B ) );
856 X->s = s;
857 }
858
859cleanup:
860
861 return( ret );
862}
863
864/*
865 * Signed addition: X = A + b
866 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000867int mpi_add_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +0000868{
869 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +0000870 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000871
872 p[0] = ( b < 0 ) ? -b : b;
873 _B.s = ( b < 0 ) ? -1 : 1;
874 _B.n = 1;
875 _B.p = p;
876
877 return( mpi_add_mpi( X, A, &_B ) );
878}
879
880/*
881 * Signed substraction: X = A - b
882 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000883int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +0000884{
885 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +0000886 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000887
888 p[0] = ( b < 0 ) ? -b : b;
889 _B.s = ( b < 0 ) ? -1 : 1;
890 _B.n = 1;
891 _B.p = p;
892
893 return( mpi_sub_mpi( X, A, &_B ) );
894}
895
896/*
897 * Helper for mpi multiplication
898 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000899static void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
Paul Bakker5121ce52009-01-03 21:22:43 +0000900{
Paul Bakkera755ca12011-04-24 09:11:17 +0000901 t_uint c = 0, t = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000902
903#if defined(MULADDC_HUIT)
904 for( ; i >= 8; i -= 8 )
905 {
906 MULADDC_INIT
907 MULADDC_HUIT
908 MULADDC_STOP
909 }
910
911 for( ; i > 0; i-- )
912 {
913 MULADDC_INIT
914 MULADDC_CORE
915 MULADDC_STOP
916 }
917#else
918 for( ; i >= 16; i -= 16 )
919 {
920 MULADDC_INIT
921 MULADDC_CORE MULADDC_CORE
922 MULADDC_CORE MULADDC_CORE
923 MULADDC_CORE MULADDC_CORE
924 MULADDC_CORE MULADDC_CORE
925
926 MULADDC_CORE MULADDC_CORE
927 MULADDC_CORE MULADDC_CORE
928 MULADDC_CORE MULADDC_CORE
929 MULADDC_CORE MULADDC_CORE
930 MULADDC_STOP
931 }
932
933 for( ; i >= 8; i -= 8 )
934 {
935 MULADDC_INIT
936 MULADDC_CORE MULADDC_CORE
937 MULADDC_CORE MULADDC_CORE
938
939 MULADDC_CORE MULADDC_CORE
940 MULADDC_CORE MULADDC_CORE
941 MULADDC_STOP
942 }
943
944 for( ; i > 0; i-- )
945 {
946 MULADDC_INIT
947 MULADDC_CORE
948 MULADDC_STOP
949 }
950#endif
951
952 t++;
953
954 do {
955 *d += c; c = ( *d < c ); d++;
956 }
957 while( c != 0 );
958}
959
960/*
961 * Baseline multiplication: X = A * B (HAC 14.12)
962 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000963int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000964{
Paul Bakker23986e52011-04-24 08:57:21 +0000965 int ret;
966 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000967 mpi TA, TB;
968
969 mpi_init( &TA, &TB, NULL );
970
971 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
972 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
973
Paul Bakker23986e52011-04-24 08:57:21 +0000974 for( i = A->n; i > 0; i-- )
975 if( A->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000976 break;
977
Paul Bakker23986e52011-04-24 08:57:21 +0000978 for( j = B->n; j > 0; j-- )
979 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000980 break;
981
Paul Bakker23986e52011-04-24 08:57:21 +0000982 MPI_CHK( mpi_grow( X, i + j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000983 MPI_CHK( mpi_lset( X, 0 ) );
984
Paul Bakker23986e52011-04-24 08:57:21 +0000985 for( i++; j > 0; j-- )
986 mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000987
988 X->s = A->s * B->s;
989
990cleanup:
991
992 mpi_free( &TB, &TA, NULL );
993
994 return( ret );
995}
996
997/*
998 * Baseline multiplication: X = A * b
999 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001000int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001001{
1002 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001003 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001004
1005 _B.s = 1;
1006 _B.n = 1;
1007 _B.p = p;
1008 p[0] = b;
1009
1010 return( mpi_mul_mpi( X, A, &_B ) );
1011}
1012
1013/*
1014 * Division by mpi: A = Q * B + R (HAC 14.20)
1015 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001016int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001017{
Paul Bakker23986e52011-04-24 08:57:21 +00001018 int ret;
1019 size_t i, n, t, k;
Paul Bakker5121ce52009-01-03 21:22:43 +00001020 mpi X, Y, Z, T1, T2;
1021
1022 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001023 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001024
1025 mpi_init( &X, &Y, &Z, &T1, &T2, NULL );
1026
1027 if( mpi_cmp_abs( A, B ) < 0 )
1028 {
1029 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1030 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1031 return( 0 );
1032 }
1033
1034 MPI_CHK( mpi_copy( &X, A ) );
1035 MPI_CHK( mpi_copy( &Y, B ) );
1036 X.s = Y.s = 1;
1037
1038 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1039 MPI_CHK( mpi_lset( &Z, 0 ) );
1040 MPI_CHK( mpi_grow( &T1, 2 ) );
1041 MPI_CHK( mpi_grow( &T2, 3 ) );
1042
1043 k = mpi_msb( &Y ) % biL;
1044 if( k < (int) biL - 1 )
1045 {
1046 k = biL - 1 - k;
1047 MPI_CHK( mpi_shift_l( &X, k ) );
1048 MPI_CHK( mpi_shift_l( &Y, k ) );
1049 }
1050 else k = 0;
1051
1052 n = X.n - 1;
1053 t = Y.n - 1;
1054 mpi_shift_l( &Y, biL * (n - t) );
1055
1056 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1057 {
1058 Z.p[n - t]++;
1059 mpi_sub_mpi( &X, &X, &Y );
1060 }
1061 mpi_shift_r( &Y, biL * (n - t) );
1062
1063 for( i = n; i > t ; i-- )
1064 {
1065 if( X.p[i] >= Y.p[t] )
1066 Z.p[i - t - 1] = ~0;
1067 else
1068 {
Paul Bakker40e46942009-01-03 21:51:57 +00001069#if defined(POLARSSL_HAVE_LONGLONG)
Paul Bakker5121ce52009-01-03 21:22:43 +00001070 t_dbl r;
1071
1072 r = (t_dbl) X.p[i] << biL;
1073 r |= (t_dbl) X.p[i - 1];
1074 r /= Y.p[t];
1075 if( r > ((t_dbl) 1 << biL) - 1)
1076 r = ((t_dbl) 1 << biL) - 1;
1077
Paul Bakkera755ca12011-04-24 09:11:17 +00001078 Z.p[i - t - 1] = (t_uint) r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001079#else
1080 /*
1081 * __udiv_qrnnd_c, from gmp/longlong.h
1082 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001083 t_uint q0, q1, r0, r1;
1084 t_uint d0, d1, d, m;
Paul Bakker5121ce52009-01-03 21:22:43 +00001085
1086 d = Y.p[t];
1087 d0 = ( d << biH ) >> biH;
1088 d1 = ( d >> biH );
1089
1090 q1 = X.p[i] / d1;
1091 r1 = X.p[i] - d1 * q1;
1092 r1 <<= biH;
1093 r1 |= ( X.p[i - 1] >> biH );
1094
1095 m = q1 * d0;
1096 if( r1 < m )
1097 {
1098 q1--, r1 += d;
1099 while( r1 >= d && r1 < m )
1100 q1--, r1 += d;
1101 }
1102 r1 -= m;
1103
1104 q0 = r1 / d1;
1105 r0 = r1 - d1 * q0;
1106 r0 <<= biH;
1107 r0 |= ( X.p[i - 1] << biH ) >> biH;
1108
1109 m = q0 * d0;
1110 if( r0 < m )
1111 {
1112 q0--, r0 += d;
1113 while( r0 >= d && r0 < m )
1114 q0--, r0 += d;
1115 }
1116 r0 -= m;
1117
1118 Z.p[i - t - 1] = ( q1 << biH ) | q0;
1119#endif
1120 }
1121
1122 Z.p[i - t - 1]++;
1123 do
1124 {
1125 Z.p[i - t - 1]--;
1126
1127 MPI_CHK( mpi_lset( &T1, 0 ) );
1128 T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
1129 T1.p[1] = Y.p[t];
1130 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1131
1132 MPI_CHK( mpi_lset( &T2, 0 ) );
1133 T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
1134 T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
1135 T2.p[2] = X.p[i];
1136 }
1137 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1138
1139 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1140 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1141 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1142
1143 if( mpi_cmp_int( &X, 0 ) < 0 )
1144 {
1145 MPI_CHK( mpi_copy( &T1, &Y ) );
1146 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1147 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1148 Z.p[i - t - 1]--;
1149 }
1150 }
1151
1152 if( Q != NULL )
1153 {
1154 mpi_copy( Q, &Z );
1155 Q->s = A->s * B->s;
1156 }
1157
1158 if( R != NULL )
1159 {
1160 mpi_shift_r( &X, k );
1161 mpi_copy( R, &X );
1162
1163 R->s = A->s;
1164 if( mpi_cmp_int( R, 0 ) == 0 )
1165 R->s = 1;
1166 }
1167
1168cleanup:
1169
1170 mpi_free( &X, &Y, &Z, &T1, &T2, NULL );
1171
1172 return( ret );
1173}
1174
1175/*
1176 * Division by int: A = Q * b + R
1177 *
1178 * Returns 0 if successful
1179 * 1 if memory allocation failed
Paul Bakker40e46942009-01-03 21:51:57 +00001180 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
Paul Bakker5121ce52009-01-03 21:22:43 +00001181 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001182int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001183{
1184 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001185 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001186
1187 p[0] = ( b < 0 ) ? -b : b;
1188 _B.s = ( b < 0 ) ? -1 : 1;
1189 _B.n = 1;
1190 _B.p = p;
1191
1192 return( mpi_div_mpi( Q, R, A, &_B ) );
1193}
1194
1195/*
1196 * Modulo: R = A mod B
1197 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001198int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001199{
1200 int ret;
1201
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001202 if( mpi_cmp_int( B, 0 ) < 0 )
1203 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
1204
Paul Bakker5121ce52009-01-03 21:22:43 +00001205 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1206
1207 while( mpi_cmp_int( R, 0 ) < 0 )
1208 MPI_CHK( mpi_add_mpi( R, R, B ) );
1209
1210 while( mpi_cmp_mpi( R, B ) >= 0 )
1211 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1212
1213cleanup:
1214
1215 return( ret );
1216}
1217
1218/*
1219 * Modulo: r = A mod b
1220 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001221int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001222{
Paul Bakker23986e52011-04-24 08:57:21 +00001223 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +00001224 t_uint x, y, z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001225
1226 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001227 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001228
1229 if( b < 0 )
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001230 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001231
1232 /*
1233 * handle trivial cases
1234 */
1235 if( b == 1 )
1236 {
1237 *r = 0;
1238 return( 0 );
1239 }
1240
1241 if( b == 2 )
1242 {
1243 *r = A->p[0] & 1;
1244 return( 0 );
1245 }
1246
1247 /*
1248 * general case
1249 */
Paul Bakker23986e52011-04-24 08:57:21 +00001250 for( i = A->n, y = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001251 {
Paul Bakker23986e52011-04-24 08:57:21 +00001252 x = A->p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001253 y = ( y << biH ) | ( x >> biH );
1254 z = y / b;
1255 y -= z * b;
1256
1257 x <<= biH;
1258 y = ( y << biH ) | ( x >> biH );
1259 z = y / b;
1260 y -= z * b;
1261 }
1262
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001263 /*
1264 * If A is negative, then the current y represents a negative value.
1265 * Flipping it to the positive side.
1266 */
1267 if( A->s < 0 && y != 0 )
1268 y = b - y;
1269
Paul Bakker5121ce52009-01-03 21:22:43 +00001270 *r = y;
1271
1272 return( 0 );
1273}
1274
1275/*
1276 * Fast Montgomery initialization (thanks to Tom St Denis)
1277 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001278static void mpi_montg_init( t_uint *mm, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001279{
Paul Bakkera755ca12011-04-24 09:11:17 +00001280 t_uint x, m0 = N->p[0];
Paul Bakker5121ce52009-01-03 21:22:43 +00001281
1282 x = m0;
1283 x += ( ( m0 + 2 ) & 4 ) << 1;
1284 x *= ( 2 - ( m0 * x ) );
1285
1286 if( biL >= 16 ) x *= ( 2 - ( m0 * x ) );
1287 if( biL >= 32 ) x *= ( 2 - ( m0 * x ) );
1288 if( biL >= 64 ) x *= ( 2 - ( m0 * x ) );
1289
1290 *mm = ~x + 1;
1291}
1292
1293/*
1294 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1295 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001296static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001297{
Paul Bakker23986e52011-04-24 08:57:21 +00001298 size_t i, n, m;
Paul Bakkera755ca12011-04-24 09:11:17 +00001299 t_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00001300
1301 memset( T->p, 0, T->n * ciL );
1302
1303 d = T->p;
1304 n = N->n;
1305 m = ( B->n < n ) ? B->n : n;
1306
1307 for( i = 0; i < n; i++ )
1308 {
1309 /*
1310 * T = (T + u0*B + u1*N) / 2^biL
1311 */
1312 u0 = A->p[i];
1313 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1314
1315 mpi_mul_hlp( m, B->p, d, u0 );
1316 mpi_mul_hlp( n, N->p, d, u1 );
1317
1318 *d++ = u0; d[n + 1] = 0;
1319 }
1320
1321 memcpy( A->p, d, (n + 1) * ciL );
1322
1323 if( mpi_cmp_abs( A, N ) >= 0 )
1324 mpi_sub_hlp( n, N->p, A->p );
1325 else
1326 /* prevent timing attacks */
1327 mpi_sub_hlp( n, A->p, T->p );
1328}
1329
1330/*
1331 * Montgomery reduction: A = A * R^-1 mod N
1332 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001333static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001334{
Paul Bakkera755ca12011-04-24 09:11:17 +00001335 t_uint z = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001336 mpi U;
1337
1338 U.n = U.s = z;
1339 U.p = &z;
1340
1341 mpi_montmul( A, &U, N, mm, T );
1342}
1343
1344/*
1345 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1346 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001347int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00001348{
Paul Bakker23986e52011-04-24 08:57:21 +00001349 int ret;
1350 size_t wbits, wsize, one = 1;
1351 size_t i, j, nblimbs;
1352 size_t bufsize, nbits;
Paul Bakkera755ca12011-04-24 09:11:17 +00001353 t_uint ei, mm, state;
Paul Bakker5121ce52009-01-03 21:22:43 +00001354 mpi RR, T, W[64];
1355
1356 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001357 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001358
1359 /*
1360 * Init temps and window size
1361 */
1362 mpi_montg_init( &mm, N );
1363 mpi_init( &RR, &T, NULL );
1364 memset( W, 0, sizeof( W ) );
1365
1366 i = mpi_msb( E );
1367
1368 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1369 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1370
1371 j = N->n + 1;
1372 MPI_CHK( mpi_grow( X, j ) );
1373 MPI_CHK( mpi_grow( &W[1], j ) );
1374 MPI_CHK( mpi_grow( &T, j * 2 ) );
1375
1376 /*
1377 * If 1st call, pre-compute R^2 mod N
1378 */
1379 if( _RR == NULL || _RR->p == NULL )
1380 {
1381 MPI_CHK( mpi_lset( &RR, 1 ) );
1382 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1383 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1384
1385 if( _RR != NULL )
1386 memcpy( _RR, &RR, sizeof( mpi ) );
1387 }
1388 else
1389 memcpy( &RR, _RR, sizeof( mpi ) );
1390
1391 /*
1392 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1393 */
1394 if( mpi_cmp_mpi( A, N ) >= 0 )
1395 mpi_mod_mpi( &W[1], A, N );
1396 else mpi_copy( &W[1], A );
1397
1398 mpi_montmul( &W[1], &RR, N, mm, &T );
1399
1400 /*
1401 * X = R^2 * R^-1 mod N = R mod N
1402 */
1403 MPI_CHK( mpi_copy( X, &RR ) );
1404 mpi_montred( X, N, mm, &T );
1405
1406 if( wsize > 1 )
1407 {
1408 /*
1409 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1410 */
Paul Bakker23986e52011-04-24 08:57:21 +00001411 j = one << (wsize - 1);
Paul Bakker5121ce52009-01-03 21:22:43 +00001412
1413 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1414 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1415
1416 for( i = 0; i < wsize - 1; i++ )
1417 mpi_montmul( &W[j], &W[j], N, mm, &T );
1418
1419 /*
1420 * W[i] = W[i - 1] * W[1]
1421 */
Paul Bakker23986e52011-04-24 08:57:21 +00001422 for( i = j + 1; i < (one << wsize); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001423 {
1424 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1425 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1426
1427 mpi_montmul( &W[i], &W[1], N, mm, &T );
1428 }
1429 }
1430
1431 nblimbs = E->n;
1432 bufsize = 0;
1433 nbits = 0;
1434 wbits = 0;
1435 state = 0;
1436
1437 while( 1 )
1438 {
1439 if( bufsize == 0 )
1440 {
1441 if( nblimbs-- == 0 )
1442 break;
1443
Paul Bakkera755ca12011-04-24 09:11:17 +00001444 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001445 }
1446
1447 bufsize--;
1448
1449 ei = (E->p[nblimbs] >> bufsize) & 1;
1450
1451 /*
1452 * skip leading 0s
1453 */
1454 if( ei == 0 && state == 0 )
1455 continue;
1456
1457 if( ei == 0 && state == 1 )
1458 {
1459 /*
1460 * out of window, square X
1461 */
1462 mpi_montmul( X, X, N, mm, &T );
1463 continue;
1464 }
1465
1466 /*
1467 * add ei to current window
1468 */
1469 state = 2;
1470
1471 nbits++;
1472 wbits |= (ei << (wsize - nbits));
1473
1474 if( nbits == wsize )
1475 {
1476 /*
1477 * X = X^wsize R^-1 mod N
1478 */
1479 for( i = 0; i < wsize; i++ )
1480 mpi_montmul( X, X, N, mm, &T );
1481
1482 /*
1483 * X = X * W[wbits] R^-1 mod N
1484 */
1485 mpi_montmul( X, &W[wbits], N, mm, &T );
1486
1487 state--;
1488 nbits = 0;
1489 wbits = 0;
1490 }
1491 }
1492
1493 /*
1494 * process the remaining bits
1495 */
1496 for( i = 0; i < nbits; i++ )
1497 {
1498 mpi_montmul( X, X, N, mm, &T );
1499
1500 wbits <<= 1;
1501
Paul Bakker23986e52011-04-24 08:57:21 +00001502 if( (wbits & (one << wsize)) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001503 mpi_montmul( X, &W[1], N, mm, &T );
1504 }
1505
1506 /*
1507 * X = A^E * R * R^-1 mod N = A^E mod N
1508 */
1509 mpi_montred( X, N, mm, &T );
1510
1511cleanup:
1512
Paul Bakker23986e52011-04-24 08:57:21 +00001513 for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001514 mpi_free( &W[i], NULL );
1515
1516 if( _RR != NULL )
1517 mpi_free( &W[1], &T, NULL );
1518 else mpi_free( &W[1], &T, &RR, NULL );
1519
1520 return( ret );
1521}
1522
Paul Bakker5121ce52009-01-03 21:22:43 +00001523/*
1524 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1525 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001526int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001527{
Paul Bakker23986e52011-04-24 08:57:21 +00001528 int ret;
1529 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001530 mpi TG, TA, TB;
1531
1532 mpi_init( &TG, &TA, &TB, NULL );
1533
Paul Bakker5121ce52009-01-03 21:22:43 +00001534 MPI_CHK( mpi_copy( &TA, A ) );
1535 MPI_CHK( mpi_copy( &TB, B ) );
1536
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001537 lz = mpi_lsb( &TA );
1538 lzt = mpi_lsb( &TB );
1539
1540 if ( lzt < lz )
1541 lz = lzt;
1542
1543 MPI_CHK( mpi_shift_r( &TA, lz ) );
1544 MPI_CHK( mpi_shift_r( &TB, lz ) );
1545
Paul Bakker5121ce52009-01-03 21:22:43 +00001546 TA.s = TB.s = 1;
1547
1548 while( mpi_cmp_int( &TA, 0 ) != 0 )
1549 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001550 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1551 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001552
1553 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1554 {
1555 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1556 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1557 }
1558 else
1559 {
1560 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1561 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1562 }
1563 }
1564
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001565 MPI_CHK( mpi_shift_l( &TB, lz ) );
1566 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001567
1568cleanup:
1569
1570 mpi_free( &TB, &TA, &TG, NULL );
1571
1572 return( ret );
1573}
1574
Paul Bakker23986e52011-04-24 08:57:21 +00001575int mpi_fill_random( mpi *X, size_t size, int (*f_rng)(void *), void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001576{
Paul Bakker23986e52011-04-24 08:57:21 +00001577 int ret;
1578 size_t k;
Paul Bakker287781a2011-03-26 13:18:49 +00001579 unsigned char *p;
1580
1581 MPI_CHK( mpi_grow( X, size ) );
1582 MPI_CHK( mpi_lset( X, 0 ) );
1583
1584 p = (unsigned char *) X->p;
1585 for( k = 0; k < X->n * ciL; k++ )
1586 *p++ = (unsigned char) f_rng( p_rng );
1587
1588cleanup:
1589 return( ret );
1590}
1591
Paul Bakker70b3eed2009-03-14 18:01:25 +00001592#if defined(POLARSSL_GENPRIME)
1593
Paul Bakker5121ce52009-01-03 21:22:43 +00001594/*
1595 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1596 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001597int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001598{
1599 int ret;
1600 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1601
1602 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001603 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001604
1605 mpi_init( &TA, &TU, &U1, &U2, &G,
1606 &TB, &TV, &V1, &V2, NULL );
1607
1608 MPI_CHK( mpi_gcd( &G, A, N ) );
1609
1610 if( mpi_cmp_int( &G, 1 ) != 0 )
1611 {
Paul Bakker40e46942009-01-03 21:51:57 +00001612 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001613 goto cleanup;
1614 }
1615
1616 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1617 MPI_CHK( mpi_copy( &TU, &TA ) );
1618 MPI_CHK( mpi_copy( &TB, N ) );
1619 MPI_CHK( mpi_copy( &TV, N ) );
1620
1621 MPI_CHK( mpi_lset( &U1, 1 ) );
1622 MPI_CHK( mpi_lset( &U2, 0 ) );
1623 MPI_CHK( mpi_lset( &V1, 0 ) );
1624 MPI_CHK( mpi_lset( &V2, 1 ) );
1625
1626 do
1627 {
1628 while( ( TU.p[0] & 1 ) == 0 )
1629 {
1630 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1631
1632 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1633 {
1634 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1635 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1636 }
1637
1638 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1639 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1640 }
1641
1642 while( ( TV.p[0] & 1 ) == 0 )
1643 {
1644 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1645
1646 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1647 {
1648 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1649 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1650 }
1651
1652 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1653 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1654 }
1655
1656 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1657 {
1658 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1659 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1660 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1661 }
1662 else
1663 {
1664 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1665 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1666 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1667 }
1668 }
1669 while( mpi_cmp_int( &TU, 0 ) != 0 );
1670
1671 while( mpi_cmp_int( &V1, 0 ) < 0 )
1672 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1673
1674 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1675 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1676
1677 MPI_CHK( mpi_copy( X, &V1 ) );
1678
1679cleanup:
1680
1681 mpi_free( &V2, &V1, &TV, &TB, &G,
1682 &U2, &U1, &TU, &TA, NULL );
1683
1684 return( ret );
1685}
1686
1687static const int small_prime[] =
1688{
1689 3, 5, 7, 11, 13, 17, 19, 23,
1690 29, 31, 37, 41, 43, 47, 53, 59,
1691 61, 67, 71, 73, 79, 83, 89, 97,
1692 101, 103, 107, 109, 113, 127, 131, 137,
1693 139, 149, 151, 157, 163, 167, 173, 179,
1694 181, 191, 193, 197, 199, 211, 223, 227,
1695 229, 233, 239, 241, 251, 257, 263, 269,
1696 271, 277, 281, 283, 293, 307, 311, 313,
1697 317, 331, 337, 347, 349, 353, 359, 367,
1698 373, 379, 383, 389, 397, 401, 409, 419,
1699 421, 431, 433, 439, 443, 449, 457, 461,
1700 463, 467, 479, 487, 491, 499, 503, 509,
1701 521, 523, 541, 547, 557, 563, 569, 571,
1702 577, 587, 593, 599, 601, 607, 613, 617,
1703 619, 631, 641, 643, 647, 653, 659, 661,
1704 673, 677, 683, 691, 701, 709, 719, 727,
1705 733, 739, 743, 751, 757, 761, 769, 773,
1706 787, 797, 809, 811, 821, 823, 827, 829,
1707 839, 853, 857, 859, 863, 877, 881, 883,
1708 887, 907, 911, 919, 929, 937, 941, 947,
1709 953, 967, 971, 977, 983, 991, 997, -103
1710};
1711
1712/*
1713 * Miller-Rabin primality test (HAC 4.24)
1714 */
1715int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng )
1716{
Paul Bakker23986e52011-04-24 08:57:21 +00001717 int ret, xs;
1718 size_t i, j, n, s;
Paul Bakker5121ce52009-01-03 21:22:43 +00001719 mpi W, R, T, A, RR;
Paul Bakker5121ce52009-01-03 21:22:43 +00001720
Paul Bakker48eab262009-06-25 21:25:49 +00001721 if( mpi_cmp_int( X, 0 ) == 0 ||
1722 mpi_cmp_int( X, 1 ) == 0 )
1723 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
1724
1725 if( mpi_cmp_int( X, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001726 return( 0 );
1727
1728 mpi_init( &W, &R, &T, &A, &RR, NULL );
1729
1730 xs = X->s; X->s = 1;
1731
1732 /*
1733 * test trivial factors first
1734 */
1735 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001736 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001737
1738 for( i = 0; small_prime[i] > 0; i++ )
1739 {
Paul Bakkera755ca12011-04-24 09:11:17 +00001740 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001741
1742 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
1743 return( 0 );
1744
1745 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1746
1747 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001748 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001749 }
1750
1751 /*
1752 * W = |X| - 1
1753 * R = W >> lsb( W )
1754 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001755 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001756 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001757 MPI_CHK( mpi_copy( &R, &W ) );
1758 MPI_CHK( mpi_shift_r( &R, s ) );
1759
1760 i = mpi_msb( X );
1761 /*
1762 * HAC, table 4.4
1763 */
1764 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1765 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1766 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1767
1768 for( i = 0; i < n; i++ )
1769 {
1770 /*
1771 * pick a random A, 1 < A < |X| - 1
1772 */
Paul Bakker287781a2011-03-26 13:18:49 +00001773 mpi_fill_random( &A, X->n, f_rng, p_rng );
Paul Bakker5121ce52009-01-03 21:22:43 +00001774
Paul Bakkerb94081b2011-01-05 15:53:06 +00001775 if( mpi_cmp_mpi( &A, &W ) >= 0 )
1776 {
1777 j = mpi_msb( &A ) - mpi_msb( &W );
1778 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
1779 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001780 A.p[0] |= 3;
1781
1782 /*
1783 * A = A^R mod |X|
1784 */
1785 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
1786
1787 if( mpi_cmp_mpi( &A, &W ) == 0 ||
1788 mpi_cmp_int( &A, 1 ) == 0 )
1789 continue;
1790
1791 j = 1;
1792 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
1793 {
1794 /*
1795 * A = A * A mod |X|
1796 */
1797 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
1798 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
1799
1800 if( mpi_cmp_int( &A, 1 ) == 0 )
1801 break;
1802
1803 j++;
1804 }
1805
1806 /*
1807 * not prime if A != |X| - 1 or A == 1
1808 */
1809 if( mpi_cmp_mpi( &A, &W ) != 0 ||
1810 mpi_cmp_int( &A, 1 ) == 0 )
1811 {
Paul Bakker40e46942009-01-03 21:51:57 +00001812 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001813 break;
1814 }
1815 }
1816
1817cleanup:
1818
1819 X->s = xs;
1820
1821 mpi_free( &RR, &A, &T, &R, &W, NULL );
1822
1823 return( ret );
1824}
1825
1826/*
1827 * Prime number generation
1828 */
Paul Bakker23986e52011-04-24 08:57:21 +00001829int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakker5121ce52009-01-03 21:22:43 +00001830 int (*f_rng)(void *), void *p_rng )
1831{
Paul Bakker23986e52011-04-24 08:57:21 +00001832 int ret;
1833 size_t k, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00001834 mpi Y;
1835
1836 if( nbits < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +00001837 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001838
1839 mpi_init( &Y, NULL );
1840
1841 n = BITS_TO_LIMBS( nbits );
1842
Paul Bakker287781a2011-03-26 13:18:49 +00001843 mpi_fill_random( X, n, f_rng, p_rng );
Paul Bakker5121ce52009-01-03 21:22:43 +00001844
1845 k = mpi_msb( X );
1846 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
1847 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
1848
1849 X->p[0] |= 3;
1850
1851 if( dh_flag == 0 )
1852 {
1853 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
1854 {
Paul Bakker40e46942009-01-03 21:51:57 +00001855 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001856 goto cleanup;
1857
1858 MPI_CHK( mpi_add_int( X, X, 2 ) );
1859 }
1860 }
1861 else
1862 {
1863 MPI_CHK( mpi_sub_int( &Y, X, 1 ) );
1864 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1865
1866 while( 1 )
1867 {
1868 if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 )
1869 {
1870 if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 )
1871 break;
1872
Paul Bakker40e46942009-01-03 21:51:57 +00001873 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001874 goto cleanup;
1875 }
1876
Paul Bakker40e46942009-01-03 21:51:57 +00001877 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001878 goto cleanup;
1879
1880 MPI_CHK( mpi_add_int( &Y, X, 1 ) );
1881 MPI_CHK( mpi_add_int( X, X, 2 ) );
1882 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1883 }
1884 }
1885
1886cleanup:
1887
1888 mpi_free( &Y, NULL );
1889
1890 return( ret );
1891}
1892
1893#endif
1894
Paul Bakker40e46942009-01-03 21:51:57 +00001895#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001896
Paul Bakker23986e52011-04-24 08:57:21 +00001897#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001898
1899static const int gcd_pairs[GCD_PAIR_COUNT][3] =
1900{
1901 { 693, 609, 21 },
1902 { 1764, 868, 28 },
1903 { 768454923, 542167814, 1 }
1904};
1905
Paul Bakker5121ce52009-01-03 21:22:43 +00001906/*
1907 * Checkup routine
1908 */
1909int mpi_self_test( int verbose )
1910{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001911 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001912 mpi A, E, N, X, Y, U, V;
1913
1914 mpi_init( &A, &E, &N, &X, &Y, &U, &V, NULL );
1915
1916 MPI_CHK( mpi_read_string( &A, 16,
1917 "EFE021C2645FD1DC586E69184AF4A31E" \
1918 "D5F53E93B5F123FA41680867BA110131" \
1919 "944FE7952E2517337780CB0DB80E61AA" \
1920 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
1921
1922 MPI_CHK( mpi_read_string( &E, 16,
1923 "B2E7EFD37075B9F03FF989C7C5051C20" \
1924 "34D2A323810251127E7BF8625A4F49A5" \
1925 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
1926 "5B5C25763222FEFCCFC38B832366C29E" ) );
1927
1928 MPI_CHK( mpi_read_string( &N, 16,
1929 "0066A198186C18C10B2F5ED9B522752A" \
1930 "9830B69916E535C8F047518A889A43A5" \
1931 "94B6BED27A168D31D4A52F88925AA8F5" ) );
1932
1933 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
1934
1935 MPI_CHK( mpi_read_string( &U, 16,
1936 "602AB7ECA597A3D6B56FF9829A5E8B85" \
1937 "9E857EA95A03512E2BAE7391688D264A" \
1938 "A5663B0341DB9CCFD2C4C5F421FEC814" \
1939 "8001B72E848A38CAE1C65F78E56ABDEF" \
1940 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
1941 "ECF677152EF804370C1A305CAF3B5BF1" \
1942 "30879B56C61DE584A0F53A2447A51E" ) );
1943
1944 if( verbose != 0 )
1945 printf( " MPI test #1 (mul_mpi): " );
1946
1947 if( mpi_cmp_mpi( &X, &U ) != 0 )
1948 {
1949 if( verbose != 0 )
1950 printf( "failed\n" );
1951
1952 return( 1 );
1953 }
1954
1955 if( verbose != 0 )
1956 printf( "passed\n" );
1957
1958 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
1959
1960 MPI_CHK( mpi_read_string( &U, 16,
1961 "256567336059E52CAE22925474705F39A94" ) );
1962
1963 MPI_CHK( mpi_read_string( &V, 16,
1964 "6613F26162223DF488E9CD48CC132C7A" \
1965 "0AC93C701B001B092E4E5B9F73BCD27B" \
1966 "9EE50D0657C77F374E903CDFA4C642" ) );
1967
1968 if( verbose != 0 )
1969 printf( " MPI test #2 (div_mpi): " );
1970
1971 if( mpi_cmp_mpi( &X, &U ) != 0 ||
1972 mpi_cmp_mpi( &Y, &V ) != 0 )
1973 {
1974 if( verbose != 0 )
1975 printf( "failed\n" );
1976
1977 return( 1 );
1978 }
1979
1980 if( verbose != 0 )
1981 printf( "passed\n" );
1982
1983 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
1984
1985 MPI_CHK( mpi_read_string( &U, 16,
1986 "36E139AEA55215609D2816998ED020BB" \
1987 "BD96C37890F65171D948E9BC7CBAA4D9" \
1988 "325D24D6A3C12710F10A09FA08AB87" ) );
1989
1990 if( verbose != 0 )
1991 printf( " MPI test #3 (exp_mod): " );
1992
1993 if( mpi_cmp_mpi( &X, &U ) != 0 )
1994 {
1995 if( verbose != 0 )
1996 printf( "failed\n" );
1997
1998 return( 1 );
1999 }
2000
2001 if( verbose != 0 )
2002 printf( "passed\n" );
2003
2004 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2005
2006 MPI_CHK( mpi_read_string( &U, 16,
2007 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2008 "C3DBA76456363A10869622EAC2DD84EC" \
2009 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2010
2011 if( verbose != 0 )
2012 printf( " MPI test #4 (inv_mod): " );
2013
2014 if( mpi_cmp_mpi( &X, &U ) != 0 )
2015 {
2016 if( verbose != 0 )
2017 printf( "failed\n" );
2018
2019 return( 1 );
2020 }
2021
2022 if( verbose != 0 )
2023 printf( "passed\n" );
2024
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002025 if( verbose != 0 )
2026 printf( " MPI test #5 (simple gcd): " );
2027
2028 for ( i = 0; i < GCD_PAIR_COUNT; i++)
2029 {
2030 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002031 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002032
Paul Bakker23986e52011-04-24 08:57:21 +00002033 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002034
Paul Bakker23986e52011-04-24 08:57:21 +00002035 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2036 {
2037 if( verbose != 0 )
2038 printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002039
Paul Bakker23986e52011-04-24 08:57:21 +00002040 return( 1 );
2041 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002042 }
2043
2044 if( verbose != 0 )
2045 printf( "passed\n" );
2046
Paul Bakker5121ce52009-01-03 21:22:43 +00002047cleanup:
2048
2049 if( ret != 0 && verbose != 0 )
2050 printf( "Unexpected error, return code = %08X\n", ret );
2051
2052 mpi_free( &V, &U, &Y, &X, &N, &E, &A, NULL );
2053
2054 if( verbose != 0 )
2055 printf( "\n" );
2056
2057 return( ret );
2058}
2059
2060#endif
2061
2062#endif