blob: a2b132d65d4afe7282023d9b93d66f8296e496e8 [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
410/*
411 * Read X from an opened file
412 */
413int mpi_read_file( mpi *X, int radix, FILE *fin )
414{
Paul Bakkera755ca12011-04-24 09:11:17 +0000415 t_uint d;
Paul Bakker23986e52011-04-24 08:57:21 +0000416 size_t slen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000417 char *p;
418 char s[1024];
419
420 memset( s, 0, sizeof( s ) );
421 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000422 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000423
424 slen = strlen( s );
425 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
426 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
427
428 p = s + slen;
429 while( --p >= s )
430 if( mpi_get_digit( &d, radix, *p ) != 0 )
431 break;
432
433 return( mpi_read_string( X, radix, p + 1 ) );
434}
435
436/*
437 * Write X into an opened file (or stdout if fout == NULL)
438 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000439int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
Paul Bakker5121ce52009-01-03 21:22:43 +0000440{
Paul Bakker23986e52011-04-24 08:57:21 +0000441 int ret;
442 size_t n, slen, plen;
Paul Bakker08f3c302010-07-08 06:54:25 +0000443 char s[2048];
Paul Bakker5121ce52009-01-03 21:22:43 +0000444
445 n = sizeof( s );
446 memset( s, 0, n );
447 n -= 2;
448
Paul Bakker23986e52011-04-24 08:57:21 +0000449 MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000450
451 if( p == NULL ) p = "";
452
453 plen = strlen( p );
454 slen = strlen( s );
455 s[slen++] = '\r';
456 s[slen++] = '\n';
457
458 if( fout != NULL )
459 {
460 if( fwrite( p, 1, plen, fout ) != plen ||
461 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000462 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000463 }
464 else
465 printf( "%s%s", p, s );
466
467cleanup:
468
469 return( ret );
470}
471
472/*
473 * Import X from unsigned binary data, big endian
474 */
Paul Bakker23986e52011-04-24 08:57:21 +0000475int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000476{
Paul Bakker23986e52011-04-24 08:57:21 +0000477 int ret;
478 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000479
480 for( n = 0; n < buflen; n++ )
481 if( buf[n] != 0 )
482 break;
483
484 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
485 MPI_CHK( mpi_lset( X, 0 ) );
486
Paul Bakker23986e52011-04-24 08:57:21 +0000487 for( i = buflen, j = 0; i > n; i--, j++ )
Paul Bakkera755ca12011-04-24 09:11:17 +0000488 X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000489
490cleanup:
491
492 return( ret );
493}
494
495/*
496 * Export X into unsigned binary data, big endian
497 */
Paul Bakker23986e52011-04-24 08:57:21 +0000498int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000499{
Paul Bakker23986e52011-04-24 08:57:21 +0000500 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000501
502 n = mpi_size( X );
503
504 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000505 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000506
507 memset( buf, 0, buflen );
508
509 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
510 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
511
512 return( 0 );
513}
514
515/*
516 * Left-shift: X <<= count
517 */
Paul Bakker23986e52011-04-24 08:57:21 +0000518int mpi_shift_l( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000519{
Paul Bakker23986e52011-04-24 08:57:21 +0000520 int ret;
521 size_t i, v0, t1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000522 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000523
524 v0 = count / (biL );
525 t1 = count & (biL - 1);
526
527 i = mpi_msb( X ) + count;
528
529 if( X->n * (int) biL < i )
530 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
531
532 ret = 0;
533
534 /*
535 * shift by count / limb_size
536 */
537 if( v0 > 0 )
538 {
Paul Bakker23986e52011-04-24 08:57:21 +0000539 for( i = X->n; i > v0; i-- )
540 X->p[i - 1] = X->p[i - v0 - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000541
Paul Bakker23986e52011-04-24 08:57:21 +0000542 for( ; i > 0; i-- )
543 X->p[i - 1] = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000544 }
545
546 /*
547 * shift by count % limb_size
548 */
549 if( t1 > 0 )
550 {
551 for( i = v0; i < X->n; i++ )
552 {
553 r1 = X->p[i] >> (biL - t1);
554 X->p[i] <<= t1;
555 X->p[i] |= r0;
556 r0 = r1;
557 }
558 }
559
560cleanup:
561
562 return( ret );
563}
564
565/*
566 * Right-shift: X >>= count
567 */
Paul Bakker23986e52011-04-24 08:57:21 +0000568int mpi_shift_r( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000569{
Paul Bakker23986e52011-04-24 08:57:21 +0000570 size_t i, v0, v1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000571 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000572
573 v0 = count / biL;
574 v1 = count & (biL - 1);
575
576 /*
577 * shift by count / limb_size
578 */
579 if( v0 > 0 )
580 {
581 for( i = 0; i < X->n - v0; i++ )
582 X->p[i] = X->p[i + v0];
583
584 for( ; i < X->n; i++ )
585 X->p[i] = 0;
586 }
587
588 /*
589 * shift by count % limb_size
590 */
591 if( v1 > 0 )
592 {
Paul Bakker23986e52011-04-24 08:57:21 +0000593 for( i = X->n; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000594 {
Paul Bakker23986e52011-04-24 08:57:21 +0000595 r1 = X->p[i - 1] << (biL - v1);
596 X->p[i - 1] >>= v1;
597 X->p[i - 1] |= r0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000598 r0 = r1;
599 }
600 }
601
602 return( 0 );
603}
604
605/*
606 * Compare unsigned values
607 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000608int mpi_cmp_abs( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000609{
Paul Bakker23986e52011-04-24 08:57:21 +0000610 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
Paul Bakker23986e52011-04-24 08:57:21 +0000612 for( i = X->n; i > 0; i-- )
613 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000614 break;
615
Paul Bakker23986e52011-04-24 08:57:21 +0000616 for( j = Y->n; j > 0; j-- )
617 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000618 break;
619
Paul Bakker23986e52011-04-24 08:57:21 +0000620 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000621 return( 0 );
622
623 if( i > j ) return( 1 );
624 if( j > i ) return( -1 );
625
Paul Bakker23986e52011-04-24 08:57:21 +0000626 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000627 {
Paul Bakker23986e52011-04-24 08:57:21 +0000628 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
629 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000630 }
631
632 return( 0 );
633}
634
635/*
636 * Compare signed values
637 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000638int mpi_cmp_mpi( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000639{
Paul Bakker23986e52011-04-24 08:57:21 +0000640 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000641
Paul Bakker23986e52011-04-24 08:57:21 +0000642 for( i = X->n; i > 0; i-- )
643 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000644 break;
645
Paul Bakker23986e52011-04-24 08:57:21 +0000646 for( j = Y->n; j > 0; j-- )
647 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000648 break;
649
Paul Bakker23986e52011-04-24 08:57:21 +0000650 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000651 return( 0 );
652
653 if( i > j ) return( X->s );
654 if( j > i ) return( -X->s );
655
656 if( X->s > 0 && Y->s < 0 ) return( 1 );
657 if( Y->s > 0 && X->s < 0 ) return( -1 );
658
Paul Bakker23986e52011-04-24 08:57:21 +0000659 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000660 {
Paul Bakker23986e52011-04-24 08:57:21 +0000661 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
662 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000663 }
664
665 return( 0 );
666}
667
668/*
669 * Compare signed values
670 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000671int mpi_cmp_int( const mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000672{
673 mpi Y;
Paul Bakkera755ca12011-04-24 09:11:17 +0000674 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000675
676 *p = ( z < 0 ) ? -z : z;
677 Y.s = ( z < 0 ) ? -1 : 1;
678 Y.n = 1;
679 Y.p = p;
680
681 return( mpi_cmp_mpi( X, &Y ) );
682}
683
684/*
685 * Unsigned addition: X = |A| + |B| (HAC 14.7)
686 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000687int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000688{
Paul Bakker23986e52011-04-24 08:57:21 +0000689 int ret;
690 size_t i, j;
Paul Bakkera755ca12011-04-24 09:11:17 +0000691 t_uint *o, *p, c;
Paul Bakker5121ce52009-01-03 21:22:43 +0000692
693 if( X == B )
694 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000695 const mpi *T = A; A = X; B = T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000696 }
697
698 if( X != A )
699 MPI_CHK( mpi_copy( X, A ) );
Paul Bakkerf7ca7b92009-06-20 10:31:06 +0000700
701 /*
702 * X should always be positive as a result of unsigned additions.
703 */
704 X->s = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000705
Paul Bakker23986e52011-04-24 08:57:21 +0000706 for( j = B->n; j > 0; j-- )
707 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000708 break;
709
Paul Bakker23986e52011-04-24 08:57:21 +0000710 MPI_CHK( mpi_grow( X, j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000711
712 o = B->p; p = X->p; c = 0;
713
Paul Bakker23986e52011-04-24 08:57:21 +0000714 for( i = 0; i < j; i++, o++, p++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000715 {
716 *p += c; c = ( *p < c );
717 *p += *o; c += ( *p < *o );
718 }
719
720 while( c != 0 )
721 {
722 if( i >= X->n )
723 {
724 MPI_CHK( mpi_grow( X, i + 1 ) );
725 p = X->p + i;
726 }
727
728 *p += c; c = ( *p < c ); i++;
729 }
730
731cleanup:
732
733 return( ret );
734}
735
736/*
737 * Helper for mpi substraction
738 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000739static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
Paul Bakker5121ce52009-01-03 21:22:43 +0000740{
Paul Bakker23986e52011-04-24 08:57:21 +0000741 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +0000742 t_uint c, z;
Paul Bakker5121ce52009-01-03 21:22:43 +0000743
744 for( i = c = 0; i < n; i++, s++, d++ )
745 {
746 z = ( *d < c ); *d -= c;
747 c = ( *d < *s ) + z; *d -= *s;
748 }
749
750 while( c != 0 )
751 {
752 z = ( *d < c ); *d -= c;
753 c = z; i++; d++;
754 }
755}
756
757/*
758 * Unsigned substraction: X = |A| - |B| (HAC 14.9)
759 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000760int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000761{
762 mpi TB;
Paul Bakker23986e52011-04-24 08:57:21 +0000763 int ret;
764 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000765
766 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000767 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000768
769 mpi_init( &TB, NULL );
770
771 if( X == B )
772 {
773 MPI_CHK( mpi_copy( &TB, B ) );
774 B = &TB;
775 }
776
777 if( X != A )
778 MPI_CHK( mpi_copy( X, A ) );
779
Paul Bakker1ef7a532009-06-20 10:50:55 +0000780 /*
781 * X should always be positive as a result of unsigned substractions.
782 */
783 X->s = 1;
784
Paul Bakker5121ce52009-01-03 21:22:43 +0000785 ret = 0;
786
Paul Bakker23986e52011-04-24 08:57:21 +0000787 for( n = B->n; n > 0; n-- )
788 if( B->p[n - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000789 break;
790
Paul Bakker23986e52011-04-24 08:57:21 +0000791 mpi_sub_hlp( n, B->p, X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000792
793cleanup:
794
795 mpi_free( &TB, NULL );
796
797 return( ret );
798}
799
800/*
801 * Signed addition: X = A + B
802 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000803int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000804{
805 int ret, s = A->s;
806
807 if( A->s * B->s < 0 )
808 {
809 if( mpi_cmp_abs( A, B ) >= 0 )
810 {
811 MPI_CHK( mpi_sub_abs( X, A, B ) );
812 X->s = s;
813 }
814 else
815 {
816 MPI_CHK( mpi_sub_abs( X, B, A ) );
817 X->s = -s;
818 }
819 }
820 else
821 {
822 MPI_CHK( mpi_add_abs( X, A, B ) );
823 X->s = s;
824 }
825
826cleanup:
827
828 return( ret );
829}
830
831/*
832 * Signed substraction: X = A - B
833 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000834int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000835{
836 int ret, s = A->s;
837
838 if( A->s * B->s > 0 )
839 {
840 if( mpi_cmp_abs( A, B ) >= 0 )
841 {
842 MPI_CHK( mpi_sub_abs( X, A, B ) );
843 X->s = s;
844 }
845 else
846 {
847 MPI_CHK( mpi_sub_abs( X, B, A ) );
848 X->s = -s;
849 }
850 }
851 else
852 {
853 MPI_CHK( mpi_add_abs( X, A, B ) );
854 X->s = s;
855 }
856
857cleanup:
858
859 return( ret );
860}
861
862/*
863 * Signed addition: X = A + b
864 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000865int mpi_add_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +0000866{
867 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +0000868 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000869
870 p[0] = ( b < 0 ) ? -b : b;
871 _B.s = ( b < 0 ) ? -1 : 1;
872 _B.n = 1;
873 _B.p = p;
874
875 return( mpi_add_mpi( X, A, &_B ) );
876}
877
878/*
879 * Signed substraction: X = A - b
880 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000881int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +0000882{
883 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +0000884 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000885
886 p[0] = ( b < 0 ) ? -b : b;
887 _B.s = ( b < 0 ) ? -1 : 1;
888 _B.n = 1;
889 _B.p = p;
890
891 return( mpi_sub_mpi( X, A, &_B ) );
892}
893
894/*
895 * Helper for mpi multiplication
896 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000897static void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
Paul Bakker5121ce52009-01-03 21:22:43 +0000898{
Paul Bakkera755ca12011-04-24 09:11:17 +0000899 t_uint c = 0, t = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000900
901#if defined(MULADDC_HUIT)
902 for( ; i >= 8; i -= 8 )
903 {
904 MULADDC_INIT
905 MULADDC_HUIT
906 MULADDC_STOP
907 }
908
909 for( ; i > 0; i-- )
910 {
911 MULADDC_INIT
912 MULADDC_CORE
913 MULADDC_STOP
914 }
915#else
916 for( ; i >= 16; i -= 16 )
917 {
918 MULADDC_INIT
919 MULADDC_CORE MULADDC_CORE
920 MULADDC_CORE MULADDC_CORE
921 MULADDC_CORE MULADDC_CORE
922 MULADDC_CORE MULADDC_CORE
923
924 MULADDC_CORE MULADDC_CORE
925 MULADDC_CORE MULADDC_CORE
926 MULADDC_CORE MULADDC_CORE
927 MULADDC_CORE MULADDC_CORE
928 MULADDC_STOP
929 }
930
931 for( ; i >= 8; i -= 8 )
932 {
933 MULADDC_INIT
934 MULADDC_CORE MULADDC_CORE
935 MULADDC_CORE MULADDC_CORE
936
937 MULADDC_CORE MULADDC_CORE
938 MULADDC_CORE MULADDC_CORE
939 MULADDC_STOP
940 }
941
942 for( ; i > 0; i-- )
943 {
944 MULADDC_INIT
945 MULADDC_CORE
946 MULADDC_STOP
947 }
948#endif
949
950 t++;
951
952 do {
953 *d += c; c = ( *d < c ); d++;
954 }
955 while( c != 0 );
956}
957
958/*
959 * Baseline multiplication: X = A * B (HAC 14.12)
960 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000961int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000962{
Paul Bakker23986e52011-04-24 08:57:21 +0000963 int ret;
964 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000965 mpi TA, TB;
966
967 mpi_init( &TA, &TB, NULL );
968
969 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
970 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
971
Paul Bakker23986e52011-04-24 08:57:21 +0000972 for( i = A->n; i > 0; i-- )
973 if( A->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000974 break;
975
Paul Bakker23986e52011-04-24 08:57:21 +0000976 for( j = B->n; j > 0; j-- )
977 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000978 break;
979
Paul Bakker23986e52011-04-24 08:57:21 +0000980 MPI_CHK( mpi_grow( X, i + j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000981 MPI_CHK( mpi_lset( X, 0 ) );
982
Paul Bakker23986e52011-04-24 08:57:21 +0000983 for( i++; j > 0; j-- )
984 mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000985
986 X->s = A->s * B->s;
987
988cleanup:
989
990 mpi_free( &TB, &TA, NULL );
991
992 return( ret );
993}
994
995/*
996 * Baseline multiplication: X = A * b
997 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000998int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +0000999{
1000 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001001 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001002
1003 _B.s = 1;
1004 _B.n = 1;
1005 _B.p = p;
1006 p[0] = b;
1007
1008 return( mpi_mul_mpi( X, A, &_B ) );
1009}
1010
1011/*
1012 * Division by mpi: A = Q * B + R (HAC 14.20)
1013 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001014int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001015{
Paul Bakker23986e52011-04-24 08:57:21 +00001016 int ret;
1017 size_t i, n, t, k;
Paul Bakker5121ce52009-01-03 21:22:43 +00001018 mpi X, Y, Z, T1, T2;
1019
1020 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001021 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001022
1023 mpi_init( &X, &Y, &Z, &T1, &T2, NULL );
1024
1025 if( mpi_cmp_abs( A, B ) < 0 )
1026 {
1027 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1028 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1029 return( 0 );
1030 }
1031
1032 MPI_CHK( mpi_copy( &X, A ) );
1033 MPI_CHK( mpi_copy( &Y, B ) );
1034 X.s = Y.s = 1;
1035
1036 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1037 MPI_CHK( mpi_lset( &Z, 0 ) );
1038 MPI_CHK( mpi_grow( &T1, 2 ) );
1039 MPI_CHK( mpi_grow( &T2, 3 ) );
1040
1041 k = mpi_msb( &Y ) % biL;
1042 if( k < (int) biL - 1 )
1043 {
1044 k = biL - 1 - k;
1045 MPI_CHK( mpi_shift_l( &X, k ) );
1046 MPI_CHK( mpi_shift_l( &Y, k ) );
1047 }
1048 else k = 0;
1049
1050 n = X.n - 1;
1051 t = Y.n - 1;
1052 mpi_shift_l( &Y, biL * (n - t) );
1053
1054 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1055 {
1056 Z.p[n - t]++;
1057 mpi_sub_mpi( &X, &X, &Y );
1058 }
1059 mpi_shift_r( &Y, biL * (n - t) );
1060
1061 for( i = n; i > t ; i-- )
1062 {
1063 if( X.p[i] >= Y.p[t] )
1064 Z.p[i - t - 1] = ~0;
1065 else
1066 {
Paul Bakker40e46942009-01-03 21:51:57 +00001067#if defined(POLARSSL_HAVE_LONGLONG)
Paul Bakker5121ce52009-01-03 21:22:43 +00001068 t_dbl r;
1069
1070 r = (t_dbl) X.p[i] << biL;
1071 r |= (t_dbl) X.p[i - 1];
1072 r /= Y.p[t];
1073 if( r > ((t_dbl) 1 << biL) - 1)
1074 r = ((t_dbl) 1 << biL) - 1;
1075
Paul Bakkera755ca12011-04-24 09:11:17 +00001076 Z.p[i - t - 1] = (t_uint) r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001077#else
1078 /*
1079 * __udiv_qrnnd_c, from gmp/longlong.h
1080 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001081 t_uint q0, q1, r0, r1;
1082 t_uint d0, d1, d, m;
Paul Bakker5121ce52009-01-03 21:22:43 +00001083
1084 d = Y.p[t];
1085 d0 = ( d << biH ) >> biH;
1086 d1 = ( d >> biH );
1087
1088 q1 = X.p[i] / d1;
1089 r1 = X.p[i] - d1 * q1;
1090 r1 <<= biH;
1091 r1 |= ( X.p[i - 1] >> biH );
1092
1093 m = q1 * d0;
1094 if( r1 < m )
1095 {
1096 q1--, r1 += d;
1097 while( r1 >= d && r1 < m )
1098 q1--, r1 += d;
1099 }
1100 r1 -= m;
1101
1102 q0 = r1 / d1;
1103 r0 = r1 - d1 * q0;
1104 r0 <<= biH;
1105 r0 |= ( X.p[i - 1] << biH ) >> biH;
1106
1107 m = q0 * d0;
1108 if( r0 < m )
1109 {
1110 q0--, r0 += d;
1111 while( r0 >= d && r0 < m )
1112 q0--, r0 += d;
1113 }
1114 r0 -= m;
1115
1116 Z.p[i - t - 1] = ( q1 << biH ) | q0;
1117#endif
1118 }
1119
1120 Z.p[i - t - 1]++;
1121 do
1122 {
1123 Z.p[i - t - 1]--;
1124
1125 MPI_CHK( mpi_lset( &T1, 0 ) );
1126 T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
1127 T1.p[1] = Y.p[t];
1128 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1129
1130 MPI_CHK( mpi_lset( &T2, 0 ) );
1131 T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
1132 T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
1133 T2.p[2] = X.p[i];
1134 }
1135 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1136
1137 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1138 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1139 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1140
1141 if( mpi_cmp_int( &X, 0 ) < 0 )
1142 {
1143 MPI_CHK( mpi_copy( &T1, &Y ) );
1144 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1145 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1146 Z.p[i - t - 1]--;
1147 }
1148 }
1149
1150 if( Q != NULL )
1151 {
1152 mpi_copy( Q, &Z );
1153 Q->s = A->s * B->s;
1154 }
1155
1156 if( R != NULL )
1157 {
1158 mpi_shift_r( &X, k );
1159 mpi_copy( R, &X );
1160
1161 R->s = A->s;
1162 if( mpi_cmp_int( R, 0 ) == 0 )
1163 R->s = 1;
1164 }
1165
1166cleanup:
1167
1168 mpi_free( &X, &Y, &Z, &T1, &T2, NULL );
1169
1170 return( ret );
1171}
1172
1173/*
1174 * Division by int: A = Q * b + R
1175 *
1176 * Returns 0 if successful
1177 * 1 if memory allocation failed
Paul Bakker40e46942009-01-03 21:51:57 +00001178 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
Paul Bakker5121ce52009-01-03 21:22:43 +00001179 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001180int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001181{
1182 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001183 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001184
1185 p[0] = ( b < 0 ) ? -b : b;
1186 _B.s = ( b < 0 ) ? -1 : 1;
1187 _B.n = 1;
1188 _B.p = p;
1189
1190 return( mpi_div_mpi( Q, R, A, &_B ) );
1191}
1192
1193/*
1194 * Modulo: R = A mod B
1195 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001196int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001197{
1198 int ret;
1199
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001200 if( mpi_cmp_int( B, 0 ) < 0 )
1201 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
1202
Paul Bakker5121ce52009-01-03 21:22:43 +00001203 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1204
1205 while( mpi_cmp_int( R, 0 ) < 0 )
1206 MPI_CHK( mpi_add_mpi( R, R, B ) );
1207
1208 while( mpi_cmp_mpi( R, B ) >= 0 )
1209 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1210
1211cleanup:
1212
1213 return( ret );
1214}
1215
1216/*
1217 * Modulo: r = A mod b
1218 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001219int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001220{
Paul Bakker23986e52011-04-24 08:57:21 +00001221 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +00001222 t_uint x, y, z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001223
1224 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001225 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001226
1227 if( b < 0 )
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001228 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001229
1230 /*
1231 * handle trivial cases
1232 */
1233 if( b == 1 )
1234 {
1235 *r = 0;
1236 return( 0 );
1237 }
1238
1239 if( b == 2 )
1240 {
1241 *r = A->p[0] & 1;
1242 return( 0 );
1243 }
1244
1245 /*
1246 * general case
1247 */
Paul Bakker23986e52011-04-24 08:57:21 +00001248 for( i = A->n, y = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001249 {
Paul Bakker23986e52011-04-24 08:57:21 +00001250 x = A->p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001251 y = ( y << biH ) | ( x >> biH );
1252 z = y / b;
1253 y -= z * b;
1254
1255 x <<= biH;
1256 y = ( y << biH ) | ( x >> biH );
1257 z = y / b;
1258 y -= z * b;
1259 }
1260
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001261 /*
1262 * If A is negative, then the current y represents a negative value.
1263 * Flipping it to the positive side.
1264 */
1265 if( A->s < 0 && y != 0 )
1266 y = b - y;
1267
Paul Bakker5121ce52009-01-03 21:22:43 +00001268 *r = y;
1269
1270 return( 0 );
1271}
1272
1273/*
1274 * Fast Montgomery initialization (thanks to Tom St Denis)
1275 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001276static void mpi_montg_init( t_uint *mm, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001277{
Paul Bakkera755ca12011-04-24 09:11:17 +00001278 t_uint x, m0 = N->p[0];
Paul Bakker5121ce52009-01-03 21:22:43 +00001279
1280 x = m0;
1281 x += ( ( m0 + 2 ) & 4 ) << 1;
1282 x *= ( 2 - ( m0 * x ) );
1283
1284 if( biL >= 16 ) x *= ( 2 - ( m0 * x ) );
1285 if( biL >= 32 ) x *= ( 2 - ( m0 * x ) );
1286 if( biL >= 64 ) x *= ( 2 - ( m0 * x ) );
1287
1288 *mm = ~x + 1;
1289}
1290
1291/*
1292 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1293 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001294static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001295{
Paul Bakker23986e52011-04-24 08:57:21 +00001296 size_t i, n, m;
Paul Bakkera755ca12011-04-24 09:11:17 +00001297 t_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00001298
1299 memset( T->p, 0, T->n * ciL );
1300
1301 d = T->p;
1302 n = N->n;
1303 m = ( B->n < n ) ? B->n : n;
1304
1305 for( i = 0; i < n; i++ )
1306 {
1307 /*
1308 * T = (T + u0*B + u1*N) / 2^biL
1309 */
1310 u0 = A->p[i];
1311 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1312
1313 mpi_mul_hlp( m, B->p, d, u0 );
1314 mpi_mul_hlp( n, N->p, d, u1 );
1315
1316 *d++ = u0; d[n + 1] = 0;
1317 }
1318
1319 memcpy( A->p, d, (n + 1) * ciL );
1320
1321 if( mpi_cmp_abs( A, N ) >= 0 )
1322 mpi_sub_hlp( n, N->p, A->p );
1323 else
1324 /* prevent timing attacks */
1325 mpi_sub_hlp( n, A->p, T->p );
1326}
1327
1328/*
1329 * Montgomery reduction: A = A * R^-1 mod N
1330 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001331static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001332{
Paul Bakkera755ca12011-04-24 09:11:17 +00001333 t_uint z = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001334 mpi U;
1335
1336 U.n = U.s = z;
1337 U.p = &z;
1338
1339 mpi_montmul( A, &U, N, mm, T );
1340}
1341
1342/*
1343 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1344 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001345int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00001346{
Paul Bakker23986e52011-04-24 08:57:21 +00001347 int ret;
1348 size_t wbits, wsize, one = 1;
1349 size_t i, j, nblimbs;
1350 size_t bufsize, nbits;
Paul Bakkera755ca12011-04-24 09:11:17 +00001351 t_uint ei, mm, state;
Paul Bakker5121ce52009-01-03 21:22:43 +00001352 mpi RR, T, W[64];
1353
1354 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001355 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001356
1357 /*
1358 * Init temps and window size
1359 */
1360 mpi_montg_init( &mm, N );
1361 mpi_init( &RR, &T, NULL );
1362 memset( W, 0, sizeof( W ) );
1363
1364 i = mpi_msb( E );
1365
1366 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1367 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1368
1369 j = N->n + 1;
1370 MPI_CHK( mpi_grow( X, j ) );
1371 MPI_CHK( mpi_grow( &W[1], j ) );
1372 MPI_CHK( mpi_grow( &T, j * 2 ) );
1373
1374 /*
1375 * If 1st call, pre-compute R^2 mod N
1376 */
1377 if( _RR == NULL || _RR->p == NULL )
1378 {
1379 MPI_CHK( mpi_lset( &RR, 1 ) );
1380 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1381 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1382
1383 if( _RR != NULL )
1384 memcpy( _RR, &RR, sizeof( mpi ) );
1385 }
1386 else
1387 memcpy( &RR, _RR, sizeof( mpi ) );
1388
1389 /*
1390 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1391 */
1392 if( mpi_cmp_mpi( A, N ) >= 0 )
1393 mpi_mod_mpi( &W[1], A, N );
1394 else mpi_copy( &W[1], A );
1395
1396 mpi_montmul( &W[1], &RR, N, mm, &T );
1397
1398 /*
1399 * X = R^2 * R^-1 mod N = R mod N
1400 */
1401 MPI_CHK( mpi_copy( X, &RR ) );
1402 mpi_montred( X, N, mm, &T );
1403
1404 if( wsize > 1 )
1405 {
1406 /*
1407 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1408 */
Paul Bakker23986e52011-04-24 08:57:21 +00001409 j = one << (wsize - 1);
Paul Bakker5121ce52009-01-03 21:22:43 +00001410
1411 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1412 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1413
1414 for( i = 0; i < wsize - 1; i++ )
1415 mpi_montmul( &W[j], &W[j], N, mm, &T );
1416
1417 /*
1418 * W[i] = W[i - 1] * W[1]
1419 */
Paul Bakker23986e52011-04-24 08:57:21 +00001420 for( i = j + 1; i < (one << wsize); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001421 {
1422 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1423 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1424
1425 mpi_montmul( &W[i], &W[1], N, mm, &T );
1426 }
1427 }
1428
1429 nblimbs = E->n;
1430 bufsize = 0;
1431 nbits = 0;
1432 wbits = 0;
1433 state = 0;
1434
1435 while( 1 )
1436 {
1437 if( bufsize == 0 )
1438 {
1439 if( nblimbs-- == 0 )
1440 break;
1441
Paul Bakkera755ca12011-04-24 09:11:17 +00001442 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001443 }
1444
1445 bufsize--;
1446
1447 ei = (E->p[nblimbs] >> bufsize) & 1;
1448
1449 /*
1450 * skip leading 0s
1451 */
1452 if( ei == 0 && state == 0 )
1453 continue;
1454
1455 if( ei == 0 && state == 1 )
1456 {
1457 /*
1458 * out of window, square X
1459 */
1460 mpi_montmul( X, X, N, mm, &T );
1461 continue;
1462 }
1463
1464 /*
1465 * add ei to current window
1466 */
1467 state = 2;
1468
1469 nbits++;
1470 wbits |= (ei << (wsize - nbits));
1471
1472 if( nbits == wsize )
1473 {
1474 /*
1475 * X = X^wsize R^-1 mod N
1476 */
1477 for( i = 0; i < wsize; i++ )
1478 mpi_montmul( X, X, N, mm, &T );
1479
1480 /*
1481 * X = X * W[wbits] R^-1 mod N
1482 */
1483 mpi_montmul( X, &W[wbits], N, mm, &T );
1484
1485 state--;
1486 nbits = 0;
1487 wbits = 0;
1488 }
1489 }
1490
1491 /*
1492 * process the remaining bits
1493 */
1494 for( i = 0; i < nbits; i++ )
1495 {
1496 mpi_montmul( X, X, N, mm, &T );
1497
1498 wbits <<= 1;
1499
Paul Bakker23986e52011-04-24 08:57:21 +00001500 if( (wbits & (one << wsize)) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001501 mpi_montmul( X, &W[1], N, mm, &T );
1502 }
1503
1504 /*
1505 * X = A^E * R * R^-1 mod N = A^E mod N
1506 */
1507 mpi_montred( X, N, mm, &T );
1508
1509cleanup:
1510
Paul Bakker23986e52011-04-24 08:57:21 +00001511 for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001512 mpi_free( &W[i], NULL );
1513
1514 if( _RR != NULL )
1515 mpi_free( &W[1], &T, NULL );
1516 else mpi_free( &W[1], &T, &RR, NULL );
1517
1518 return( ret );
1519}
1520
Paul Bakker5121ce52009-01-03 21:22:43 +00001521/*
1522 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1523 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001524int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001525{
Paul Bakker23986e52011-04-24 08:57:21 +00001526 int ret;
1527 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001528 mpi TG, TA, TB;
1529
1530 mpi_init( &TG, &TA, &TB, NULL );
1531
Paul Bakker5121ce52009-01-03 21:22:43 +00001532 MPI_CHK( mpi_copy( &TA, A ) );
1533 MPI_CHK( mpi_copy( &TB, B ) );
1534
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001535 lz = mpi_lsb( &TA );
1536 lzt = mpi_lsb( &TB );
1537
1538 if ( lzt < lz )
1539 lz = lzt;
1540
1541 MPI_CHK( mpi_shift_r( &TA, lz ) );
1542 MPI_CHK( mpi_shift_r( &TB, lz ) );
1543
Paul Bakker5121ce52009-01-03 21:22:43 +00001544 TA.s = TB.s = 1;
1545
1546 while( mpi_cmp_int( &TA, 0 ) != 0 )
1547 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001548 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1549 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001550
1551 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1552 {
1553 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1554 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1555 }
1556 else
1557 {
1558 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1559 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1560 }
1561 }
1562
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001563 MPI_CHK( mpi_shift_l( &TB, lz ) );
1564 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001565
1566cleanup:
1567
1568 mpi_free( &TB, &TA, &TG, NULL );
1569
1570 return( ret );
1571}
1572
Paul Bakker23986e52011-04-24 08:57:21 +00001573int mpi_fill_random( mpi *X, size_t size, int (*f_rng)(void *), void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001574{
Paul Bakker23986e52011-04-24 08:57:21 +00001575 int ret;
1576 size_t k;
Paul Bakker287781a2011-03-26 13:18:49 +00001577 unsigned char *p;
1578
1579 MPI_CHK( mpi_grow( X, size ) );
1580 MPI_CHK( mpi_lset( X, 0 ) );
1581
1582 p = (unsigned char *) X->p;
1583 for( k = 0; k < X->n * ciL; k++ )
1584 *p++ = (unsigned char) f_rng( p_rng );
1585
1586cleanup:
1587 return( ret );
1588}
1589
Paul Bakker70b3eed2009-03-14 18:01:25 +00001590#if defined(POLARSSL_GENPRIME)
1591
Paul Bakker5121ce52009-01-03 21:22:43 +00001592/*
1593 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1594 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001595int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001596{
1597 int ret;
1598 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1599
1600 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001601 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001602
1603 mpi_init( &TA, &TU, &U1, &U2, &G,
1604 &TB, &TV, &V1, &V2, NULL );
1605
1606 MPI_CHK( mpi_gcd( &G, A, N ) );
1607
1608 if( mpi_cmp_int( &G, 1 ) != 0 )
1609 {
Paul Bakker40e46942009-01-03 21:51:57 +00001610 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001611 goto cleanup;
1612 }
1613
1614 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1615 MPI_CHK( mpi_copy( &TU, &TA ) );
1616 MPI_CHK( mpi_copy( &TB, N ) );
1617 MPI_CHK( mpi_copy( &TV, N ) );
1618
1619 MPI_CHK( mpi_lset( &U1, 1 ) );
1620 MPI_CHK( mpi_lset( &U2, 0 ) );
1621 MPI_CHK( mpi_lset( &V1, 0 ) );
1622 MPI_CHK( mpi_lset( &V2, 1 ) );
1623
1624 do
1625 {
1626 while( ( TU.p[0] & 1 ) == 0 )
1627 {
1628 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1629
1630 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1631 {
1632 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1633 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1634 }
1635
1636 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1637 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1638 }
1639
1640 while( ( TV.p[0] & 1 ) == 0 )
1641 {
1642 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1643
1644 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1645 {
1646 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1647 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1648 }
1649
1650 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1651 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1652 }
1653
1654 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1655 {
1656 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1657 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1658 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1659 }
1660 else
1661 {
1662 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1663 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1664 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1665 }
1666 }
1667 while( mpi_cmp_int( &TU, 0 ) != 0 );
1668
1669 while( mpi_cmp_int( &V1, 0 ) < 0 )
1670 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1671
1672 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1673 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1674
1675 MPI_CHK( mpi_copy( X, &V1 ) );
1676
1677cleanup:
1678
1679 mpi_free( &V2, &V1, &TV, &TB, &G,
1680 &U2, &U1, &TU, &TA, NULL );
1681
1682 return( ret );
1683}
1684
1685static const int small_prime[] =
1686{
1687 3, 5, 7, 11, 13, 17, 19, 23,
1688 29, 31, 37, 41, 43, 47, 53, 59,
1689 61, 67, 71, 73, 79, 83, 89, 97,
1690 101, 103, 107, 109, 113, 127, 131, 137,
1691 139, 149, 151, 157, 163, 167, 173, 179,
1692 181, 191, 193, 197, 199, 211, 223, 227,
1693 229, 233, 239, 241, 251, 257, 263, 269,
1694 271, 277, 281, 283, 293, 307, 311, 313,
1695 317, 331, 337, 347, 349, 353, 359, 367,
1696 373, 379, 383, 389, 397, 401, 409, 419,
1697 421, 431, 433, 439, 443, 449, 457, 461,
1698 463, 467, 479, 487, 491, 499, 503, 509,
1699 521, 523, 541, 547, 557, 563, 569, 571,
1700 577, 587, 593, 599, 601, 607, 613, 617,
1701 619, 631, 641, 643, 647, 653, 659, 661,
1702 673, 677, 683, 691, 701, 709, 719, 727,
1703 733, 739, 743, 751, 757, 761, 769, 773,
1704 787, 797, 809, 811, 821, 823, 827, 829,
1705 839, 853, 857, 859, 863, 877, 881, 883,
1706 887, 907, 911, 919, 929, 937, 941, 947,
1707 953, 967, 971, 977, 983, 991, 997, -103
1708};
1709
1710/*
1711 * Miller-Rabin primality test (HAC 4.24)
1712 */
1713int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng )
1714{
Paul Bakker23986e52011-04-24 08:57:21 +00001715 int ret, xs;
1716 size_t i, j, n, s;
Paul Bakker5121ce52009-01-03 21:22:43 +00001717 mpi W, R, T, A, RR;
Paul Bakker5121ce52009-01-03 21:22:43 +00001718
Paul Bakker48eab262009-06-25 21:25:49 +00001719 if( mpi_cmp_int( X, 0 ) == 0 ||
1720 mpi_cmp_int( X, 1 ) == 0 )
1721 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
1722
1723 if( mpi_cmp_int( X, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001724 return( 0 );
1725
1726 mpi_init( &W, &R, &T, &A, &RR, NULL );
1727
1728 xs = X->s; X->s = 1;
1729
1730 /*
1731 * test trivial factors first
1732 */
1733 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001734 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001735
1736 for( i = 0; small_prime[i] > 0; i++ )
1737 {
Paul Bakkera755ca12011-04-24 09:11:17 +00001738 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001739
1740 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
1741 return( 0 );
1742
1743 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1744
1745 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001746 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001747 }
1748
1749 /*
1750 * W = |X| - 1
1751 * R = W >> lsb( W )
1752 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001753 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001754 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001755 MPI_CHK( mpi_copy( &R, &W ) );
1756 MPI_CHK( mpi_shift_r( &R, s ) );
1757
1758 i = mpi_msb( X );
1759 /*
1760 * HAC, table 4.4
1761 */
1762 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1763 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1764 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1765
1766 for( i = 0; i < n; i++ )
1767 {
1768 /*
1769 * pick a random A, 1 < A < |X| - 1
1770 */
Paul Bakker287781a2011-03-26 13:18:49 +00001771 mpi_fill_random( &A, X->n, f_rng, p_rng );
Paul Bakker5121ce52009-01-03 21:22:43 +00001772
Paul Bakkerb94081b2011-01-05 15:53:06 +00001773 if( mpi_cmp_mpi( &A, &W ) >= 0 )
1774 {
1775 j = mpi_msb( &A ) - mpi_msb( &W );
1776 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
1777 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001778 A.p[0] |= 3;
1779
1780 /*
1781 * A = A^R mod |X|
1782 */
1783 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
1784
1785 if( mpi_cmp_mpi( &A, &W ) == 0 ||
1786 mpi_cmp_int( &A, 1 ) == 0 )
1787 continue;
1788
1789 j = 1;
1790 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
1791 {
1792 /*
1793 * A = A * A mod |X|
1794 */
1795 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
1796 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
1797
1798 if( mpi_cmp_int( &A, 1 ) == 0 )
1799 break;
1800
1801 j++;
1802 }
1803
1804 /*
1805 * not prime if A != |X| - 1 or A == 1
1806 */
1807 if( mpi_cmp_mpi( &A, &W ) != 0 ||
1808 mpi_cmp_int( &A, 1 ) == 0 )
1809 {
Paul Bakker40e46942009-01-03 21:51:57 +00001810 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001811 break;
1812 }
1813 }
1814
1815cleanup:
1816
1817 X->s = xs;
1818
1819 mpi_free( &RR, &A, &T, &R, &W, NULL );
1820
1821 return( ret );
1822}
1823
1824/*
1825 * Prime number generation
1826 */
Paul Bakker23986e52011-04-24 08:57:21 +00001827int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakker5121ce52009-01-03 21:22:43 +00001828 int (*f_rng)(void *), void *p_rng )
1829{
Paul Bakker23986e52011-04-24 08:57:21 +00001830 int ret;
1831 size_t k, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00001832 mpi Y;
1833
1834 if( nbits < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +00001835 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001836
1837 mpi_init( &Y, NULL );
1838
1839 n = BITS_TO_LIMBS( nbits );
1840
Paul Bakker287781a2011-03-26 13:18:49 +00001841 mpi_fill_random( X, n, f_rng, p_rng );
Paul Bakker5121ce52009-01-03 21:22:43 +00001842
1843 k = mpi_msb( X );
1844 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
1845 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
1846
1847 X->p[0] |= 3;
1848
1849 if( dh_flag == 0 )
1850 {
1851 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
1852 {
Paul Bakker40e46942009-01-03 21:51:57 +00001853 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001854 goto cleanup;
1855
1856 MPI_CHK( mpi_add_int( X, X, 2 ) );
1857 }
1858 }
1859 else
1860 {
1861 MPI_CHK( mpi_sub_int( &Y, X, 1 ) );
1862 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1863
1864 while( 1 )
1865 {
1866 if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 )
1867 {
1868 if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 )
1869 break;
1870
Paul Bakker40e46942009-01-03 21:51:57 +00001871 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001872 goto cleanup;
1873 }
1874
Paul Bakker40e46942009-01-03 21:51:57 +00001875 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001876 goto cleanup;
1877
1878 MPI_CHK( mpi_add_int( &Y, X, 1 ) );
1879 MPI_CHK( mpi_add_int( X, X, 2 ) );
1880 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1881 }
1882 }
1883
1884cleanup:
1885
1886 mpi_free( &Y, NULL );
1887
1888 return( ret );
1889}
1890
1891#endif
1892
Paul Bakker40e46942009-01-03 21:51:57 +00001893#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001894
Paul Bakker23986e52011-04-24 08:57:21 +00001895#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001896
1897static const int gcd_pairs[GCD_PAIR_COUNT][3] =
1898{
1899 { 693, 609, 21 },
1900 { 1764, 868, 28 },
1901 { 768454923, 542167814, 1 }
1902};
1903
Paul Bakker5121ce52009-01-03 21:22:43 +00001904/*
1905 * Checkup routine
1906 */
1907int mpi_self_test( int verbose )
1908{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001909 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001910 mpi A, E, N, X, Y, U, V;
1911
1912 mpi_init( &A, &E, &N, &X, &Y, &U, &V, NULL );
1913
1914 MPI_CHK( mpi_read_string( &A, 16,
1915 "EFE021C2645FD1DC586E69184AF4A31E" \
1916 "D5F53E93B5F123FA41680867BA110131" \
1917 "944FE7952E2517337780CB0DB80E61AA" \
1918 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
1919
1920 MPI_CHK( mpi_read_string( &E, 16,
1921 "B2E7EFD37075B9F03FF989C7C5051C20" \
1922 "34D2A323810251127E7BF8625A4F49A5" \
1923 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
1924 "5B5C25763222FEFCCFC38B832366C29E" ) );
1925
1926 MPI_CHK( mpi_read_string( &N, 16,
1927 "0066A198186C18C10B2F5ED9B522752A" \
1928 "9830B69916E535C8F047518A889A43A5" \
1929 "94B6BED27A168D31D4A52F88925AA8F5" ) );
1930
1931 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
1932
1933 MPI_CHK( mpi_read_string( &U, 16,
1934 "602AB7ECA597A3D6B56FF9829A5E8B85" \
1935 "9E857EA95A03512E2BAE7391688D264A" \
1936 "A5663B0341DB9CCFD2C4C5F421FEC814" \
1937 "8001B72E848A38CAE1C65F78E56ABDEF" \
1938 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
1939 "ECF677152EF804370C1A305CAF3B5BF1" \
1940 "30879B56C61DE584A0F53A2447A51E" ) );
1941
1942 if( verbose != 0 )
1943 printf( " MPI test #1 (mul_mpi): " );
1944
1945 if( mpi_cmp_mpi( &X, &U ) != 0 )
1946 {
1947 if( verbose != 0 )
1948 printf( "failed\n" );
1949
1950 return( 1 );
1951 }
1952
1953 if( verbose != 0 )
1954 printf( "passed\n" );
1955
1956 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
1957
1958 MPI_CHK( mpi_read_string( &U, 16,
1959 "256567336059E52CAE22925474705F39A94" ) );
1960
1961 MPI_CHK( mpi_read_string( &V, 16,
1962 "6613F26162223DF488E9CD48CC132C7A" \
1963 "0AC93C701B001B092E4E5B9F73BCD27B" \
1964 "9EE50D0657C77F374E903CDFA4C642" ) );
1965
1966 if( verbose != 0 )
1967 printf( " MPI test #2 (div_mpi): " );
1968
1969 if( mpi_cmp_mpi( &X, &U ) != 0 ||
1970 mpi_cmp_mpi( &Y, &V ) != 0 )
1971 {
1972 if( verbose != 0 )
1973 printf( "failed\n" );
1974
1975 return( 1 );
1976 }
1977
1978 if( verbose != 0 )
1979 printf( "passed\n" );
1980
1981 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
1982
1983 MPI_CHK( mpi_read_string( &U, 16,
1984 "36E139AEA55215609D2816998ED020BB" \
1985 "BD96C37890F65171D948E9BC7CBAA4D9" \
1986 "325D24D6A3C12710F10A09FA08AB87" ) );
1987
1988 if( verbose != 0 )
1989 printf( " MPI test #3 (exp_mod): " );
1990
1991 if( mpi_cmp_mpi( &X, &U ) != 0 )
1992 {
1993 if( verbose != 0 )
1994 printf( "failed\n" );
1995
1996 return( 1 );
1997 }
1998
1999 if( verbose != 0 )
2000 printf( "passed\n" );
2001
2002 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2003
2004 MPI_CHK( mpi_read_string( &U, 16,
2005 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2006 "C3DBA76456363A10869622EAC2DD84EC" \
2007 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2008
2009 if( verbose != 0 )
2010 printf( " MPI test #4 (inv_mod): " );
2011
2012 if( mpi_cmp_mpi( &X, &U ) != 0 )
2013 {
2014 if( verbose != 0 )
2015 printf( "failed\n" );
2016
2017 return( 1 );
2018 }
2019
2020 if( verbose != 0 )
2021 printf( "passed\n" );
2022
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002023 if( verbose != 0 )
2024 printf( " MPI test #5 (simple gcd): " );
2025
2026 for ( i = 0; i < GCD_PAIR_COUNT; i++)
2027 {
2028 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002029 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002030
Paul Bakker23986e52011-04-24 08:57:21 +00002031 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002032
Paul Bakker23986e52011-04-24 08:57:21 +00002033 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2034 {
2035 if( verbose != 0 )
2036 printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002037
Paul Bakker23986e52011-04-24 08:57:21 +00002038 return( 1 );
2039 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002040 }
2041
2042 if( verbose != 0 )
2043 printf( "passed\n" );
2044
Paul Bakker5121ce52009-01-03 21:22:43 +00002045cleanup:
2046
2047 if( ret != 0 && verbose != 0 )
2048 printf( "Unexpected error, return code = %08X\n", ret );
2049
2050 mpi_free( &V, &U, &Y, &X, &N, &E, &A, NULL );
2051
2052 if( verbose != 0 )
2053 printf( "\n" );
2054
2055 return( ret );
2056}
2057
2058#endif
2059
2060#endif