blob: d4035b62b2e16a30852c17fcf7da9e3c8af77600 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Multi-precision integer library
3 *
Paul Bakker84f12b72010-07-18 10:13:04 +00004 * Copyright (C) 2006-2010, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 * This MPI implementation is based on:
27 *
28 * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
29 * http://www.stillhq.com/extracted/gnupg-api/mpi/
30 * http://math.libtomcrypt.com/files/tommath.pdf
31 */
32
Paul Bakker40e46942009-01-03 21:51:57 +000033#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Paul Bakker40e46942009-01-03 21:51:57 +000035#if defined(POLARSSL_BIGNUM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Paul Bakker40e46942009-01-03 21:51:57 +000037#include "polarssl/bignum.h"
38#include "polarssl/bn_mul.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000039
Paul Bakker5121ce52009-01-03 21:22:43 +000040#include <stdlib.h>
Paul Bakker5121ce52009-01-03 21:22:43 +000041
Paul Bakkerf9688572011-05-05 10:00:45 +000042#define ciL (sizeof(t_uint)) /* chars in limb */
Paul Bakker5121ce52009-01-03 21:22:43 +000043#define biL (ciL << 3) /* bits in limb */
44#define biH (ciL << 2) /* half limb size */
45
46/*
47 * Convert between bits/chars and number of limbs
48 */
49#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
50#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
51
52/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000053 * Initialize one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000054 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000055void mpi_init( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000056{
Paul Bakker6c591fa2011-05-05 11:49:20 +000057 if( X == NULL )
58 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000059
Paul Bakker6c591fa2011-05-05 11:49:20 +000060 X->s = 1;
61 X->n = 0;
62 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000063}
64
65/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000066 * Unallocate one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000067 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000068void mpi_free( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000069{
Paul Bakker6c591fa2011-05-05 11:49:20 +000070 if( X == NULL )
71 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000072
Paul Bakker6c591fa2011-05-05 11:49:20 +000073 if( X->p != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +000074 {
Paul Bakker6c591fa2011-05-05 11:49:20 +000075 memset( X->p, 0, X->n * ciL );
76 free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +000077 }
78
Paul Bakker6c591fa2011-05-05 11:49:20 +000079 X->s = 1;
80 X->n = 0;
81 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000082}
83
84/*
85 * Enlarge to the specified number of limbs
86 */
Paul Bakker23986e52011-04-24 08:57:21 +000087int mpi_grow( mpi *X, size_t nblimbs )
Paul Bakker5121ce52009-01-03 21:22:43 +000088{
Paul Bakkera755ca12011-04-24 09:11:17 +000089 t_uint *p;
Paul Bakker5121ce52009-01-03 21:22:43 +000090
Paul Bakkerf9688572011-05-05 10:00:45 +000091 if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
92 return( 1 );
93
Paul Bakker5121ce52009-01-03 21:22:43 +000094 if( X->n < nblimbs )
95 {
Paul Bakkera755ca12011-04-24 09:11:17 +000096 if( ( p = (t_uint *) malloc( nblimbs * ciL ) ) == NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +000097 return( 1 );
98
99 memset( p, 0, nblimbs * ciL );
100
101 if( X->p != NULL )
102 {
103 memcpy( p, X->p, X->n * ciL );
104 memset( X->p, 0, X->n * ciL );
105 free( X->p );
106 }
107
108 X->n = nblimbs;
109 X->p = p;
110 }
111
112 return( 0 );
113}
114
115/*
116 * Copy the contents of Y into X
117 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000118int mpi_copy( mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000119{
Paul Bakker23986e52011-04-24 08:57:21 +0000120 int ret;
121 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000122
123 if( X == Y )
124 return( 0 );
125
126 for( i = Y->n - 1; i > 0; i-- )
127 if( Y->p[i] != 0 )
128 break;
129 i++;
130
131 X->s = Y->s;
132
133 MPI_CHK( mpi_grow( X, i ) );
134
135 memset( X->p, 0, X->n * ciL );
136 memcpy( X->p, Y->p, i * ciL );
137
138cleanup:
139
140 return( ret );
141}
142
143/*
144 * Swap the contents of X and Y
145 */
146void mpi_swap( mpi *X, mpi *Y )
147{
148 mpi T;
149
150 memcpy( &T, X, sizeof( mpi ) );
151 memcpy( X, Y, sizeof( mpi ) );
152 memcpy( Y, &T, sizeof( mpi ) );
153}
154
155/*
156 * Set value from integer
157 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000158int mpi_lset( mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000159{
160 int ret;
161
162 MPI_CHK( mpi_grow( X, 1 ) );
163 memset( X->p, 0, X->n * ciL );
164
165 X->p[0] = ( z < 0 ) ? -z : z;
166 X->s = ( z < 0 ) ? -1 : 1;
167
168cleanup:
169
170 return( ret );
171}
172
173/*
Paul Bakker2f5947e2011-05-18 15:47:11 +0000174 * Get a specific bit
175 */
176int mpi_get_bit( mpi *X, size_t pos )
177{
178 if( X->n * biL <= pos )
179 return( 0 );
180
181 return ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01;
182}
183
184/*
185 * Set a bit to a specific value of 0 or 1
186 */
187int mpi_set_bit( mpi *X, size_t pos, unsigned char val )
188{
189 int ret = 0;
190 size_t off = pos / biL;
191 size_t idx = pos % biL;
192
193 if( val != 0 && val != 1 )
194 return POLARSSL_ERR_MPI_BAD_INPUT_DATA;
195
196 if( X->n * biL <= pos )
197 {
198 if( val == 0 )
199 return ( 0 );
200
201 MPI_CHK( mpi_grow( X, off + 1 ) );
202 }
203
204 X->p[off] = ( X->p[off] & ~( 0x01 << idx ) ) | ( val << idx );
205
206cleanup:
207
208 return( ret );
209}
210
211/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000212 * Return the number of least significant bits
213 */
Paul Bakker23986e52011-04-24 08:57:21 +0000214size_t mpi_lsb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000215{
Paul Bakker23986e52011-04-24 08:57:21 +0000216 size_t i, j, count = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000217
218 for( i = 0; i < X->n; i++ )
Paul Bakkerf9688572011-05-05 10:00:45 +0000219 for( j = 0; j < biL; j++, count++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000220 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
221 return( count );
222
223 return( 0 );
224}
225
226/*
227 * Return the number of most significant bits
228 */
Paul Bakker23986e52011-04-24 08:57:21 +0000229size_t mpi_msb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000230{
Paul Bakker23986e52011-04-24 08:57:21 +0000231 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000232
233 for( i = X->n - 1; i > 0; i-- )
234 if( X->p[i] != 0 )
235 break;
236
Paul Bakker23986e52011-04-24 08:57:21 +0000237 for( j = biL; j > 0; j-- )
238 if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000239 break;
240
Paul Bakker23986e52011-04-24 08:57:21 +0000241 return( ( i * biL ) + j );
Paul Bakker5121ce52009-01-03 21:22:43 +0000242}
243
244/*
245 * Return the total size in bytes
246 */
Paul Bakker23986e52011-04-24 08:57:21 +0000247size_t mpi_size( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000248{
249 return( ( mpi_msb( X ) + 7 ) >> 3 );
250}
251
252/*
253 * Convert an ASCII character to digit value
254 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000255static int mpi_get_digit( t_uint *d, int radix, char c )
Paul Bakker5121ce52009-01-03 21:22:43 +0000256{
257 *d = 255;
258
259 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
260 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
261 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
262
Paul Bakkera755ca12011-04-24 09:11:17 +0000263 if( *d >= (t_uint) radix )
Paul Bakker40e46942009-01-03 21:51:57 +0000264 return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000265
266 return( 0 );
267}
268
269/*
270 * Import from an ASCII string
271 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000272int mpi_read_string( mpi *X, int radix, const char *s )
Paul Bakker5121ce52009-01-03 21:22:43 +0000273{
Paul Bakker23986e52011-04-24 08:57:21 +0000274 int ret;
275 size_t i, j, slen, n;
Paul Bakkera755ca12011-04-24 09:11:17 +0000276 t_uint d;
Paul Bakker5121ce52009-01-03 21:22:43 +0000277 mpi T;
278
279 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000280 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000281
Paul Bakker6c591fa2011-05-05 11:49:20 +0000282 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000283
Paul Bakkerff60ee62010-03-16 21:09:09 +0000284 slen = strlen( s );
285
Paul Bakker5121ce52009-01-03 21:22:43 +0000286 if( radix == 16 )
287 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000288 n = BITS_TO_LIMBS( slen << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000289
290 MPI_CHK( mpi_grow( X, n ) );
291 MPI_CHK( mpi_lset( X, 0 ) );
292
Paul Bakker23986e52011-04-24 08:57:21 +0000293 for( i = slen, j = 0; i > 0; i--, j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000294 {
Paul Bakker23986e52011-04-24 08:57:21 +0000295 if( i == 1 && s[i - 1] == '-' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000296 {
297 X->s = -1;
298 break;
299 }
300
Paul Bakker23986e52011-04-24 08:57:21 +0000301 MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000302 X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 );
303 }
304 }
305 else
306 {
307 MPI_CHK( mpi_lset( X, 0 ) );
308
Paul Bakkerff60ee62010-03-16 21:09:09 +0000309 for( i = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000310 {
311 if( i == 0 && s[i] == '-' )
312 {
313 X->s = -1;
314 continue;
315 }
316
317 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
318 MPI_CHK( mpi_mul_int( &T, X, radix ) );
Paul Bakker05feca62009-06-20 08:22:43 +0000319
320 if( X->s == 1 )
321 {
322 MPI_CHK( mpi_add_int( X, &T, d ) );
323 }
324 else
325 {
326 MPI_CHK( mpi_sub_int( X, &T, d ) );
327 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000328 }
329 }
330
331cleanup:
332
Paul Bakker6c591fa2011-05-05 11:49:20 +0000333 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000334
335 return( ret );
336}
337
338/*
339 * Helper to write the digits high-order first
340 */
341static int mpi_write_hlp( mpi *X, int radix, char **p )
342{
343 int ret;
Paul Bakkera755ca12011-04-24 09:11:17 +0000344 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
346 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000347 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000348
349 MPI_CHK( mpi_mod_int( &r, X, radix ) );
350 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
351
352 if( mpi_cmp_int( X, 0 ) != 0 )
353 MPI_CHK( mpi_write_hlp( X, radix, p ) );
354
355 if( r < 10 )
356 *(*p)++ = (char)( r + 0x30 );
357 else
358 *(*p)++ = (char)( r + 0x37 );
359
360cleanup:
361
362 return( ret );
363}
364
365/*
366 * Export into an ASCII string
367 */
Paul Bakker23986e52011-04-24 08:57:21 +0000368int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000369{
Paul Bakker23986e52011-04-24 08:57:21 +0000370 int ret = 0;
371 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000372 char *p;
373 mpi T;
374
375 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000376 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000377
378 n = mpi_msb( X );
379 if( radix >= 4 ) n >>= 1;
380 if( radix >= 16 ) n >>= 1;
381 n += 3;
382
383 if( *slen < n )
384 {
385 *slen = n;
Paul Bakker40e46942009-01-03 21:51:57 +0000386 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000387 }
388
389 p = s;
Paul Bakker6c591fa2011-05-05 11:49:20 +0000390 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000391
392 if( X->s == -1 )
393 *p++ = '-';
394
395 if( radix == 16 )
396 {
Paul Bakker23986e52011-04-24 08:57:21 +0000397 int c;
398 size_t i, j, k;
Paul Bakker5121ce52009-01-03 21:22:43 +0000399
Paul Bakker23986e52011-04-24 08:57:21 +0000400 for( i = X->n, k = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000401 {
Paul Bakker23986e52011-04-24 08:57:21 +0000402 for( j = ciL; j > 0; j-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000403 {
Paul Bakker23986e52011-04-24 08:57:21 +0000404 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000405
Paul Bakker23986e52011-04-24 08:57:21 +0000406 if( c == 0 && k == 0 && ( i + j + 3 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000407 continue;
408
409 p += sprintf( p, "%02X", c );
410 k = 1;
411 }
412 }
413 }
414 else
415 {
416 MPI_CHK( mpi_copy( &T, X ) );
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000417
418 if( T.s == -1 )
419 T.s = 1;
420
Paul Bakker5121ce52009-01-03 21:22:43 +0000421 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
422 }
423
424 *p++ = '\0';
425 *slen = p - s;
426
427cleanup:
428
Paul Bakker6c591fa2011-05-05 11:49:20 +0000429 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000430
431 return( ret );
432}
433
Paul Bakker335db3f2011-04-25 15:28:35 +0000434#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000435/*
436 * Read X from an opened file
437 */
438int mpi_read_file( mpi *X, int radix, FILE *fin )
439{
Paul Bakkera755ca12011-04-24 09:11:17 +0000440 t_uint d;
Paul Bakker23986e52011-04-24 08:57:21 +0000441 size_t slen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 char *p;
443 char s[1024];
444
445 memset( s, 0, sizeof( s ) );
446 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000447 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000448
449 slen = strlen( s );
450 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
451 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
452
453 p = s + slen;
454 while( --p >= s )
455 if( mpi_get_digit( &d, radix, *p ) != 0 )
456 break;
457
458 return( mpi_read_string( X, radix, p + 1 ) );
459}
460
461/*
462 * Write X into an opened file (or stdout if fout == NULL)
463 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000464int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
Paul Bakker5121ce52009-01-03 21:22:43 +0000465{
Paul Bakker23986e52011-04-24 08:57:21 +0000466 int ret;
467 size_t n, slen, plen;
Paul Bakker08f3c302010-07-08 06:54:25 +0000468 char s[2048];
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
470 n = sizeof( s );
471 memset( s, 0, n );
472 n -= 2;
473
Paul Bakker23986e52011-04-24 08:57:21 +0000474 MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000475
476 if( p == NULL ) p = "";
477
478 plen = strlen( p );
479 slen = strlen( s );
480 s[slen++] = '\r';
481 s[slen++] = '\n';
482
483 if( fout != NULL )
484 {
485 if( fwrite( p, 1, plen, fout ) != plen ||
486 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000487 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000488 }
489 else
490 printf( "%s%s", p, s );
491
492cleanup:
493
494 return( ret );
495}
Paul Bakker335db3f2011-04-25 15:28:35 +0000496#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000497
498/*
499 * Import X from unsigned binary data, big endian
500 */
Paul Bakker23986e52011-04-24 08:57:21 +0000501int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000502{
Paul Bakker23986e52011-04-24 08:57:21 +0000503 int ret;
504 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000505
506 for( n = 0; n < buflen; n++ )
507 if( buf[n] != 0 )
508 break;
509
510 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
511 MPI_CHK( mpi_lset( X, 0 ) );
512
Paul Bakker23986e52011-04-24 08:57:21 +0000513 for( i = buflen, j = 0; i > n; i--, j++ )
Paul Bakkera755ca12011-04-24 09:11:17 +0000514 X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000515
516cleanup:
517
518 return( ret );
519}
520
521/*
522 * Export X into unsigned binary data, big endian
523 */
Paul Bakker23986e52011-04-24 08:57:21 +0000524int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000525{
Paul Bakker23986e52011-04-24 08:57:21 +0000526 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000527
528 n = mpi_size( X );
529
530 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000531 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000532
533 memset( buf, 0, buflen );
534
535 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
536 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
537
538 return( 0 );
539}
540
541/*
542 * Left-shift: X <<= count
543 */
Paul Bakker23986e52011-04-24 08:57:21 +0000544int mpi_shift_l( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000545{
Paul Bakker23986e52011-04-24 08:57:21 +0000546 int ret;
547 size_t i, v0, t1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000548 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000549
550 v0 = count / (biL );
551 t1 = count & (biL - 1);
552
553 i = mpi_msb( X ) + count;
554
Paul Bakkerf9688572011-05-05 10:00:45 +0000555 if( X->n * biL < i )
Paul Bakker5121ce52009-01-03 21:22:43 +0000556 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
557
558 ret = 0;
559
560 /*
561 * shift by count / limb_size
562 */
563 if( v0 > 0 )
564 {
Paul Bakker23986e52011-04-24 08:57:21 +0000565 for( i = X->n; i > v0; i-- )
566 X->p[i - 1] = X->p[i - v0 - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000567
Paul Bakker23986e52011-04-24 08:57:21 +0000568 for( ; i > 0; i-- )
569 X->p[i - 1] = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000570 }
571
572 /*
573 * shift by count % limb_size
574 */
575 if( t1 > 0 )
576 {
577 for( i = v0; i < X->n; i++ )
578 {
579 r1 = X->p[i] >> (biL - t1);
580 X->p[i] <<= t1;
581 X->p[i] |= r0;
582 r0 = r1;
583 }
584 }
585
586cleanup:
587
588 return( ret );
589}
590
591/*
592 * Right-shift: X >>= count
593 */
Paul Bakker23986e52011-04-24 08:57:21 +0000594int mpi_shift_r( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000595{
Paul Bakker23986e52011-04-24 08:57:21 +0000596 size_t i, v0, v1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000597 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000598
599 v0 = count / biL;
600 v1 = count & (biL - 1);
601
602 /*
603 * shift by count / limb_size
604 */
605 if( v0 > 0 )
606 {
607 for( i = 0; i < X->n - v0; i++ )
608 X->p[i] = X->p[i + v0];
609
610 for( ; i < X->n; i++ )
611 X->p[i] = 0;
612 }
613
614 /*
615 * shift by count % limb_size
616 */
617 if( v1 > 0 )
618 {
Paul Bakker23986e52011-04-24 08:57:21 +0000619 for( i = X->n; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000620 {
Paul Bakker23986e52011-04-24 08:57:21 +0000621 r1 = X->p[i - 1] << (biL - v1);
622 X->p[i - 1] >>= v1;
623 X->p[i - 1] |= r0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000624 r0 = r1;
625 }
626 }
627
628 return( 0 );
629}
630
631/*
632 * Compare unsigned values
633 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000634int mpi_cmp_abs( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000635{
Paul Bakker23986e52011-04-24 08:57:21 +0000636 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
Paul Bakker23986e52011-04-24 08:57:21 +0000638 for( i = X->n; i > 0; i-- )
639 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000640 break;
641
Paul Bakker23986e52011-04-24 08:57:21 +0000642 for( j = Y->n; j > 0; j-- )
643 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000644 break;
645
Paul Bakker23986e52011-04-24 08:57:21 +0000646 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000647 return( 0 );
648
649 if( i > j ) return( 1 );
650 if( j > i ) return( -1 );
651
Paul Bakker23986e52011-04-24 08:57:21 +0000652 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000653 {
Paul Bakker23986e52011-04-24 08:57:21 +0000654 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
655 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000656 }
657
658 return( 0 );
659}
660
661/*
662 * Compare signed values
663 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000664int mpi_cmp_mpi( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000665{
Paul Bakker23986e52011-04-24 08:57:21 +0000666 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000667
Paul Bakker23986e52011-04-24 08:57:21 +0000668 for( i = X->n; i > 0; i-- )
669 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000670 break;
671
Paul Bakker23986e52011-04-24 08:57:21 +0000672 for( j = Y->n; j > 0; j-- )
673 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000674 break;
675
Paul Bakker23986e52011-04-24 08:57:21 +0000676 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000677 return( 0 );
678
679 if( i > j ) return( X->s );
680 if( j > i ) return( -X->s );
681
682 if( X->s > 0 && Y->s < 0 ) return( 1 );
683 if( Y->s > 0 && X->s < 0 ) return( -1 );
684
Paul Bakker23986e52011-04-24 08:57:21 +0000685 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000686 {
Paul Bakker23986e52011-04-24 08:57:21 +0000687 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
688 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000689 }
690
691 return( 0 );
692}
693
694/*
695 * Compare signed values
696 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000697int mpi_cmp_int( const mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000698{
699 mpi Y;
Paul Bakkera755ca12011-04-24 09:11:17 +0000700 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000701
702 *p = ( z < 0 ) ? -z : z;
703 Y.s = ( z < 0 ) ? -1 : 1;
704 Y.n = 1;
705 Y.p = p;
706
707 return( mpi_cmp_mpi( X, &Y ) );
708}
709
710/*
711 * Unsigned addition: X = |A| + |B| (HAC 14.7)
712 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000713int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000714{
Paul Bakker23986e52011-04-24 08:57:21 +0000715 int ret;
716 size_t i, j;
Paul Bakkera755ca12011-04-24 09:11:17 +0000717 t_uint *o, *p, c;
Paul Bakker5121ce52009-01-03 21:22:43 +0000718
719 if( X == B )
720 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000721 const mpi *T = A; A = X; B = T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000722 }
723
724 if( X != A )
725 MPI_CHK( mpi_copy( X, A ) );
Paul Bakkerf7ca7b92009-06-20 10:31:06 +0000726
727 /*
728 * X should always be positive as a result of unsigned additions.
729 */
730 X->s = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000731
Paul Bakker23986e52011-04-24 08:57:21 +0000732 for( j = B->n; j > 0; j-- )
733 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000734 break;
735
Paul Bakker23986e52011-04-24 08:57:21 +0000736 MPI_CHK( mpi_grow( X, j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000737
738 o = B->p; p = X->p; c = 0;
739
Paul Bakker23986e52011-04-24 08:57:21 +0000740 for( i = 0; i < j; i++, o++, p++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000741 {
742 *p += c; c = ( *p < c );
743 *p += *o; c += ( *p < *o );
744 }
745
746 while( c != 0 )
747 {
748 if( i >= X->n )
749 {
750 MPI_CHK( mpi_grow( X, i + 1 ) );
751 p = X->p + i;
752 }
753
754 *p += c; c = ( *p < c ); i++;
755 }
756
757cleanup:
758
759 return( ret );
760}
761
762/*
763 * Helper for mpi substraction
764 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000765static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
Paul Bakker5121ce52009-01-03 21:22:43 +0000766{
Paul Bakker23986e52011-04-24 08:57:21 +0000767 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +0000768 t_uint c, z;
Paul Bakker5121ce52009-01-03 21:22:43 +0000769
770 for( i = c = 0; i < n; i++, s++, d++ )
771 {
772 z = ( *d < c ); *d -= c;
773 c = ( *d < *s ) + z; *d -= *s;
774 }
775
776 while( c != 0 )
777 {
778 z = ( *d < c ); *d -= c;
779 c = z; i++; d++;
780 }
781}
782
783/*
784 * Unsigned substraction: X = |A| - |B| (HAC 14.9)
785 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000786int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000787{
788 mpi TB;
Paul Bakker23986e52011-04-24 08:57:21 +0000789 int ret;
790 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000791
792 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000793 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000794
Paul Bakker6c591fa2011-05-05 11:49:20 +0000795 mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000796
797 if( X == B )
798 {
799 MPI_CHK( mpi_copy( &TB, B ) );
800 B = &TB;
801 }
802
803 if( X != A )
804 MPI_CHK( mpi_copy( X, A ) );
805
Paul Bakker1ef7a532009-06-20 10:50:55 +0000806 /*
807 * X should always be positive as a result of unsigned substractions.
808 */
809 X->s = 1;
810
Paul Bakker5121ce52009-01-03 21:22:43 +0000811 ret = 0;
812
Paul Bakker23986e52011-04-24 08:57:21 +0000813 for( n = B->n; n > 0; n-- )
814 if( B->p[n - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000815 break;
816
Paul Bakker23986e52011-04-24 08:57:21 +0000817 mpi_sub_hlp( n, B->p, X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000818
819cleanup:
820
Paul Bakker6c591fa2011-05-05 11:49:20 +0000821 mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000822
823 return( ret );
824}
825
826/*
827 * Signed addition: X = A + B
828 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000829int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000830{
831 int ret, s = A->s;
832
833 if( A->s * B->s < 0 )
834 {
835 if( mpi_cmp_abs( A, B ) >= 0 )
836 {
837 MPI_CHK( mpi_sub_abs( X, A, B ) );
838 X->s = s;
839 }
840 else
841 {
842 MPI_CHK( mpi_sub_abs( X, B, A ) );
843 X->s = -s;
844 }
845 }
846 else
847 {
848 MPI_CHK( mpi_add_abs( X, A, B ) );
849 X->s = s;
850 }
851
852cleanup:
853
854 return( ret );
855}
856
857/*
858 * Signed substraction: X = A - B
859 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000860int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000861{
862 int ret, s = A->s;
863
864 if( A->s * B->s > 0 )
865 {
866 if( mpi_cmp_abs( A, B ) >= 0 )
867 {
868 MPI_CHK( mpi_sub_abs( X, A, B ) );
869 X->s = s;
870 }
871 else
872 {
873 MPI_CHK( mpi_sub_abs( X, B, A ) );
874 X->s = -s;
875 }
876 }
877 else
878 {
879 MPI_CHK( mpi_add_abs( X, A, B ) );
880 X->s = s;
881 }
882
883cleanup:
884
885 return( ret );
886}
887
888/*
889 * Signed addition: X = A + b
890 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000891int mpi_add_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +0000892{
893 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +0000894 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000895
896 p[0] = ( b < 0 ) ? -b : b;
897 _B.s = ( b < 0 ) ? -1 : 1;
898 _B.n = 1;
899 _B.p = p;
900
901 return( mpi_add_mpi( X, A, &_B ) );
902}
903
904/*
905 * Signed substraction: X = A - b
906 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000907int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +0000908{
909 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +0000910 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000911
912 p[0] = ( b < 0 ) ? -b : b;
913 _B.s = ( b < 0 ) ? -1 : 1;
914 _B.n = 1;
915 _B.p = p;
916
917 return( mpi_sub_mpi( X, A, &_B ) );
918}
919
920/*
921 * Helper for mpi multiplication
922 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000923static void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
Paul Bakker5121ce52009-01-03 21:22:43 +0000924{
Paul Bakkera755ca12011-04-24 09:11:17 +0000925 t_uint c = 0, t = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000926
927#if defined(MULADDC_HUIT)
928 for( ; i >= 8; i -= 8 )
929 {
930 MULADDC_INIT
931 MULADDC_HUIT
932 MULADDC_STOP
933 }
934
935 for( ; i > 0; i-- )
936 {
937 MULADDC_INIT
938 MULADDC_CORE
939 MULADDC_STOP
940 }
941#else
942 for( ; i >= 16; i -= 16 )
943 {
944 MULADDC_INIT
945 MULADDC_CORE MULADDC_CORE
946 MULADDC_CORE MULADDC_CORE
947 MULADDC_CORE MULADDC_CORE
948 MULADDC_CORE MULADDC_CORE
949
950 MULADDC_CORE MULADDC_CORE
951 MULADDC_CORE MULADDC_CORE
952 MULADDC_CORE MULADDC_CORE
953 MULADDC_CORE MULADDC_CORE
954 MULADDC_STOP
955 }
956
957 for( ; i >= 8; i -= 8 )
958 {
959 MULADDC_INIT
960 MULADDC_CORE MULADDC_CORE
961 MULADDC_CORE MULADDC_CORE
962
963 MULADDC_CORE MULADDC_CORE
964 MULADDC_CORE MULADDC_CORE
965 MULADDC_STOP
966 }
967
968 for( ; i > 0; i-- )
969 {
970 MULADDC_INIT
971 MULADDC_CORE
972 MULADDC_STOP
973 }
974#endif
975
976 t++;
977
978 do {
979 *d += c; c = ( *d < c ); d++;
980 }
981 while( c != 0 );
982}
983
984/*
985 * Baseline multiplication: X = A * B (HAC 14.12)
986 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000987int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000988{
Paul Bakker23986e52011-04-24 08:57:21 +0000989 int ret;
990 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000991 mpi TA, TB;
992
Paul Bakker6c591fa2011-05-05 11:49:20 +0000993 mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000994
995 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
996 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
997
Paul Bakker23986e52011-04-24 08:57:21 +0000998 for( i = A->n; i > 0; i-- )
999 if( A->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001000 break;
1001
Paul Bakker23986e52011-04-24 08:57:21 +00001002 for( j = B->n; j > 0; j-- )
1003 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001004 break;
1005
Paul Bakker23986e52011-04-24 08:57:21 +00001006 MPI_CHK( mpi_grow( X, i + j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001007 MPI_CHK( mpi_lset( X, 0 ) );
1008
Paul Bakker23986e52011-04-24 08:57:21 +00001009 for( i++; j > 0; j-- )
1010 mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001011
1012 X->s = A->s * B->s;
1013
1014cleanup:
1015
Paul Bakker6c591fa2011-05-05 11:49:20 +00001016 mpi_free( &TB ); mpi_free( &TA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001017
1018 return( ret );
1019}
1020
1021/*
1022 * Baseline multiplication: X = A * b
1023 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001024int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001025{
1026 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001027 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001028
1029 _B.s = 1;
1030 _B.n = 1;
1031 _B.p = p;
1032 p[0] = b;
1033
1034 return( mpi_mul_mpi( X, A, &_B ) );
1035}
1036
1037/*
1038 * Division by mpi: A = Q * B + R (HAC 14.20)
1039 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001040int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001041{
Paul Bakker23986e52011-04-24 08:57:21 +00001042 int ret;
1043 size_t i, n, t, k;
Paul Bakker5121ce52009-01-03 21:22:43 +00001044 mpi X, Y, Z, T1, T2;
1045
1046 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001047 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001048
Paul Bakker6c591fa2011-05-05 11:49:20 +00001049 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
1050 mpi_init( &T1 ); mpi_init( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001051
1052 if( mpi_cmp_abs( A, B ) < 0 )
1053 {
1054 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1055 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1056 return( 0 );
1057 }
1058
1059 MPI_CHK( mpi_copy( &X, A ) );
1060 MPI_CHK( mpi_copy( &Y, B ) );
1061 X.s = Y.s = 1;
1062
1063 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1064 MPI_CHK( mpi_lset( &Z, 0 ) );
1065 MPI_CHK( mpi_grow( &T1, 2 ) );
1066 MPI_CHK( mpi_grow( &T2, 3 ) );
1067
1068 k = mpi_msb( &Y ) % biL;
Paul Bakkerf9688572011-05-05 10:00:45 +00001069 if( k < biL - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001070 {
1071 k = biL - 1 - k;
1072 MPI_CHK( mpi_shift_l( &X, k ) );
1073 MPI_CHK( mpi_shift_l( &Y, k ) );
1074 }
1075 else k = 0;
1076
1077 n = X.n - 1;
1078 t = Y.n - 1;
1079 mpi_shift_l( &Y, biL * (n - t) );
1080
1081 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1082 {
1083 Z.p[n - t]++;
1084 mpi_sub_mpi( &X, &X, &Y );
1085 }
1086 mpi_shift_r( &Y, biL * (n - t) );
1087
1088 for( i = n; i > t ; i-- )
1089 {
1090 if( X.p[i] >= Y.p[t] )
1091 Z.p[i - t - 1] = ~0;
1092 else
1093 {
Paul Bakker40e46942009-01-03 21:51:57 +00001094#if defined(POLARSSL_HAVE_LONGLONG)
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001095 t_udbl r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001096
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001097 r = (t_udbl) X.p[i] << biL;
1098 r |= (t_udbl) X.p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001099 r /= Y.p[t];
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001100 if( r > ((t_udbl) 1 << biL) - 1)
1101 r = ((t_udbl) 1 << biL) - 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001102
Paul Bakkera755ca12011-04-24 09:11:17 +00001103 Z.p[i - t - 1] = (t_uint) r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001104#else
1105 /*
1106 * __udiv_qrnnd_c, from gmp/longlong.h
1107 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001108 t_uint q0, q1, r0, r1;
1109 t_uint d0, d1, d, m;
Paul Bakker5121ce52009-01-03 21:22:43 +00001110
1111 d = Y.p[t];
1112 d0 = ( d << biH ) >> biH;
1113 d1 = ( d >> biH );
1114
1115 q1 = X.p[i] / d1;
1116 r1 = X.p[i] - d1 * q1;
1117 r1 <<= biH;
1118 r1 |= ( X.p[i - 1] >> biH );
1119
1120 m = q1 * d0;
1121 if( r1 < m )
1122 {
1123 q1--, r1 += d;
1124 while( r1 >= d && r1 < m )
1125 q1--, r1 += d;
1126 }
1127 r1 -= m;
1128
1129 q0 = r1 / d1;
1130 r0 = r1 - d1 * q0;
1131 r0 <<= biH;
1132 r0 |= ( X.p[i - 1] << biH ) >> biH;
1133
1134 m = q0 * d0;
1135 if( r0 < m )
1136 {
1137 q0--, r0 += d;
1138 while( r0 >= d && r0 < m )
1139 q0--, r0 += d;
1140 }
1141 r0 -= m;
1142
1143 Z.p[i - t - 1] = ( q1 << biH ) | q0;
1144#endif
1145 }
1146
1147 Z.p[i - t - 1]++;
1148 do
1149 {
1150 Z.p[i - t - 1]--;
1151
1152 MPI_CHK( mpi_lset( &T1, 0 ) );
1153 T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
1154 T1.p[1] = Y.p[t];
1155 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1156
1157 MPI_CHK( mpi_lset( &T2, 0 ) );
1158 T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
1159 T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
1160 T2.p[2] = X.p[i];
1161 }
1162 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1163
1164 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1165 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1166 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1167
1168 if( mpi_cmp_int( &X, 0 ) < 0 )
1169 {
1170 MPI_CHK( mpi_copy( &T1, &Y ) );
1171 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1172 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1173 Z.p[i - t - 1]--;
1174 }
1175 }
1176
1177 if( Q != NULL )
1178 {
1179 mpi_copy( Q, &Z );
1180 Q->s = A->s * B->s;
1181 }
1182
1183 if( R != NULL )
1184 {
1185 mpi_shift_r( &X, k );
1186 mpi_copy( R, &X );
1187
1188 R->s = A->s;
1189 if( mpi_cmp_int( R, 0 ) == 0 )
1190 R->s = 1;
1191 }
1192
1193cleanup:
1194
Paul Bakker6c591fa2011-05-05 11:49:20 +00001195 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
1196 mpi_free( &T1 ); mpi_free( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001197
1198 return( ret );
1199}
1200
1201/*
1202 * Division by int: A = Q * b + R
1203 *
1204 * Returns 0 if successful
1205 * 1 if memory allocation failed
Paul Bakker40e46942009-01-03 21:51:57 +00001206 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
Paul Bakker5121ce52009-01-03 21:22:43 +00001207 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001208int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001209{
1210 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001211 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001212
1213 p[0] = ( b < 0 ) ? -b : b;
1214 _B.s = ( b < 0 ) ? -1 : 1;
1215 _B.n = 1;
1216 _B.p = p;
1217
1218 return( mpi_div_mpi( Q, R, A, &_B ) );
1219}
1220
1221/*
1222 * Modulo: R = A mod B
1223 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001224int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001225{
1226 int ret;
1227
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001228 if( mpi_cmp_int( B, 0 ) < 0 )
1229 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
1230
Paul Bakker5121ce52009-01-03 21:22:43 +00001231 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1232
1233 while( mpi_cmp_int( R, 0 ) < 0 )
1234 MPI_CHK( mpi_add_mpi( R, R, B ) );
1235
1236 while( mpi_cmp_mpi( R, B ) >= 0 )
1237 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1238
1239cleanup:
1240
1241 return( ret );
1242}
1243
1244/*
1245 * Modulo: r = A mod b
1246 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001247int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001248{
Paul Bakker23986e52011-04-24 08:57:21 +00001249 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +00001250 t_uint x, y, z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001251
1252 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001253 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001254
1255 if( b < 0 )
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001256 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001257
1258 /*
1259 * handle trivial cases
1260 */
1261 if( b == 1 )
1262 {
1263 *r = 0;
1264 return( 0 );
1265 }
1266
1267 if( b == 2 )
1268 {
1269 *r = A->p[0] & 1;
1270 return( 0 );
1271 }
1272
1273 /*
1274 * general case
1275 */
Paul Bakker23986e52011-04-24 08:57:21 +00001276 for( i = A->n, y = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001277 {
Paul Bakker23986e52011-04-24 08:57:21 +00001278 x = A->p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001279 y = ( y << biH ) | ( x >> biH );
1280 z = y / b;
1281 y -= z * b;
1282
1283 x <<= biH;
1284 y = ( y << biH ) | ( x >> biH );
1285 z = y / b;
1286 y -= z * b;
1287 }
1288
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001289 /*
1290 * If A is negative, then the current y represents a negative value.
1291 * Flipping it to the positive side.
1292 */
1293 if( A->s < 0 && y != 0 )
1294 y = b - y;
1295
Paul Bakker5121ce52009-01-03 21:22:43 +00001296 *r = y;
1297
1298 return( 0 );
1299}
1300
1301/*
1302 * Fast Montgomery initialization (thanks to Tom St Denis)
1303 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001304static void mpi_montg_init( t_uint *mm, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001305{
Paul Bakkera755ca12011-04-24 09:11:17 +00001306 t_uint x, m0 = N->p[0];
Paul Bakker5121ce52009-01-03 21:22:43 +00001307
1308 x = m0;
1309 x += ( ( m0 + 2 ) & 4 ) << 1;
1310 x *= ( 2 - ( m0 * x ) );
1311
1312 if( biL >= 16 ) x *= ( 2 - ( m0 * x ) );
1313 if( biL >= 32 ) x *= ( 2 - ( m0 * x ) );
1314 if( biL >= 64 ) x *= ( 2 - ( m0 * x ) );
1315
1316 *mm = ~x + 1;
1317}
1318
1319/*
1320 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1321 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001322static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001323{
Paul Bakker23986e52011-04-24 08:57:21 +00001324 size_t i, n, m;
Paul Bakkera755ca12011-04-24 09:11:17 +00001325 t_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00001326
1327 memset( T->p, 0, T->n * ciL );
1328
1329 d = T->p;
1330 n = N->n;
1331 m = ( B->n < n ) ? B->n : n;
1332
1333 for( i = 0; i < n; i++ )
1334 {
1335 /*
1336 * T = (T + u0*B + u1*N) / 2^biL
1337 */
1338 u0 = A->p[i];
1339 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1340
1341 mpi_mul_hlp( m, B->p, d, u0 );
1342 mpi_mul_hlp( n, N->p, d, u1 );
1343
1344 *d++ = u0; d[n + 1] = 0;
1345 }
1346
1347 memcpy( A->p, d, (n + 1) * ciL );
1348
1349 if( mpi_cmp_abs( A, N ) >= 0 )
1350 mpi_sub_hlp( n, N->p, A->p );
1351 else
1352 /* prevent timing attacks */
1353 mpi_sub_hlp( n, A->p, T->p );
1354}
1355
1356/*
1357 * Montgomery reduction: A = A * R^-1 mod N
1358 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001359static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001360{
Paul Bakkera755ca12011-04-24 09:11:17 +00001361 t_uint z = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001362 mpi U;
1363
1364 U.n = U.s = z;
1365 U.p = &z;
1366
1367 mpi_montmul( A, &U, N, mm, T );
1368}
1369
1370/*
1371 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1372 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001373int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00001374{
Paul Bakker23986e52011-04-24 08:57:21 +00001375 int ret;
1376 size_t wbits, wsize, one = 1;
1377 size_t i, j, nblimbs;
1378 size_t bufsize, nbits;
Paul Bakkera755ca12011-04-24 09:11:17 +00001379 t_uint ei, mm, state;
Paul Bakkerb6d5f082011-11-25 11:52:11 +00001380 mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +00001381
1382 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001383 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001384
1385 /*
1386 * Init temps and window size
1387 */
1388 mpi_montg_init( &mm, N );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001389 mpi_init( &RR ); mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00001390 memset( W, 0, sizeof( W ) );
1391
1392 i = mpi_msb( E );
1393
1394 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1395 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1396
Paul Bakkerb6d5f082011-11-25 11:52:11 +00001397 if( wsize > POLARSSL_MPI_WINDOW_SIZE )
1398 wsize = POLARSSL_MPI_WINDOW_SIZE;
1399
Paul Bakker5121ce52009-01-03 21:22:43 +00001400 j = N->n + 1;
1401 MPI_CHK( mpi_grow( X, j ) );
1402 MPI_CHK( mpi_grow( &W[1], j ) );
1403 MPI_CHK( mpi_grow( &T, j * 2 ) );
1404
1405 /*
1406 * If 1st call, pre-compute R^2 mod N
1407 */
1408 if( _RR == NULL || _RR->p == NULL )
1409 {
1410 MPI_CHK( mpi_lset( &RR, 1 ) );
1411 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1412 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1413
1414 if( _RR != NULL )
1415 memcpy( _RR, &RR, sizeof( mpi ) );
1416 }
1417 else
1418 memcpy( &RR, _RR, sizeof( mpi ) );
1419
1420 /*
1421 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1422 */
1423 if( mpi_cmp_mpi( A, N ) >= 0 )
1424 mpi_mod_mpi( &W[1], A, N );
1425 else mpi_copy( &W[1], A );
1426
1427 mpi_montmul( &W[1], &RR, N, mm, &T );
1428
1429 /*
1430 * X = R^2 * R^-1 mod N = R mod N
1431 */
1432 MPI_CHK( mpi_copy( X, &RR ) );
1433 mpi_montred( X, N, mm, &T );
1434
1435 if( wsize > 1 )
1436 {
1437 /*
1438 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1439 */
Paul Bakker23986e52011-04-24 08:57:21 +00001440 j = one << (wsize - 1);
Paul Bakker5121ce52009-01-03 21:22:43 +00001441
1442 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1443 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1444
1445 for( i = 0; i < wsize - 1; i++ )
1446 mpi_montmul( &W[j], &W[j], N, mm, &T );
1447
1448 /*
1449 * W[i] = W[i - 1] * W[1]
1450 */
Paul Bakker23986e52011-04-24 08:57:21 +00001451 for( i = j + 1; i < (one << wsize); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001452 {
1453 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1454 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1455
1456 mpi_montmul( &W[i], &W[1], N, mm, &T );
1457 }
1458 }
1459
1460 nblimbs = E->n;
1461 bufsize = 0;
1462 nbits = 0;
1463 wbits = 0;
1464 state = 0;
1465
1466 while( 1 )
1467 {
1468 if( bufsize == 0 )
1469 {
1470 if( nblimbs-- == 0 )
1471 break;
1472
Paul Bakkera755ca12011-04-24 09:11:17 +00001473 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001474 }
1475
1476 bufsize--;
1477
1478 ei = (E->p[nblimbs] >> bufsize) & 1;
1479
1480 /*
1481 * skip leading 0s
1482 */
1483 if( ei == 0 && state == 0 )
1484 continue;
1485
1486 if( ei == 0 && state == 1 )
1487 {
1488 /*
1489 * out of window, square X
1490 */
1491 mpi_montmul( X, X, N, mm, &T );
1492 continue;
1493 }
1494
1495 /*
1496 * add ei to current window
1497 */
1498 state = 2;
1499
1500 nbits++;
1501 wbits |= (ei << (wsize - nbits));
1502
1503 if( nbits == wsize )
1504 {
1505 /*
1506 * X = X^wsize R^-1 mod N
1507 */
1508 for( i = 0; i < wsize; i++ )
1509 mpi_montmul( X, X, N, mm, &T );
1510
1511 /*
1512 * X = X * W[wbits] R^-1 mod N
1513 */
1514 mpi_montmul( X, &W[wbits], N, mm, &T );
1515
1516 state--;
1517 nbits = 0;
1518 wbits = 0;
1519 }
1520 }
1521
1522 /*
1523 * process the remaining bits
1524 */
1525 for( i = 0; i < nbits; i++ )
1526 {
1527 mpi_montmul( X, X, N, mm, &T );
1528
1529 wbits <<= 1;
1530
Paul Bakker23986e52011-04-24 08:57:21 +00001531 if( (wbits & (one << wsize)) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001532 mpi_montmul( X, &W[1], N, mm, &T );
1533 }
1534
1535 /*
1536 * X = A^E * R * R^-1 mod N = A^E mod N
1537 */
1538 mpi_montred( X, N, mm, &T );
1539
1540cleanup:
1541
Paul Bakker23986e52011-04-24 08:57:21 +00001542 for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001543 mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001544
Paul Bakker6c591fa2011-05-05 11:49:20 +00001545 mpi_free( &W[1] ); mpi_free( &T );
1546
1547 if( _RR == NULL )
1548 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001549
1550 return( ret );
1551}
1552
Paul Bakker5121ce52009-01-03 21:22:43 +00001553/*
1554 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1555 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001556int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001557{
Paul Bakker23986e52011-04-24 08:57:21 +00001558 int ret;
1559 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001560 mpi TG, TA, TB;
1561
Paul Bakker6c591fa2011-05-05 11:49:20 +00001562 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001563
Paul Bakker5121ce52009-01-03 21:22:43 +00001564 MPI_CHK( mpi_copy( &TA, A ) );
1565 MPI_CHK( mpi_copy( &TB, B ) );
1566
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001567 lz = mpi_lsb( &TA );
1568 lzt = mpi_lsb( &TB );
1569
1570 if ( lzt < lz )
1571 lz = lzt;
1572
1573 MPI_CHK( mpi_shift_r( &TA, lz ) );
1574 MPI_CHK( mpi_shift_r( &TB, lz ) );
1575
Paul Bakker5121ce52009-01-03 21:22:43 +00001576 TA.s = TB.s = 1;
1577
1578 while( mpi_cmp_int( &TA, 0 ) != 0 )
1579 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001580 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1581 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001582
1583 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1584 {
1585 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1586 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1587 }
1588 else
1589 {
1590 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1591 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1592 }
1593 }
1594
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001595 MPI_CHK( mpi_shift_l( &TB, lz ) );
1596 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001597
1598cleanup:
1599
Paul Bakker6c591fa2011-05-05 11:49:20 +00001600 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001601
1602 return( ret );
1603}
1604
Paul Bakker23986e52011-04-24 08:57:21 +00001605int mpi_fill_random( mpi *X, size_t size, int (*f_rng)(void *), void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001606{
Paul Bakker23986e52011-04-24 08:57:21 +00001607 int ret;
1608 size_t k;
Paul Bakker287781a2011-03-26 13:18:49 +00001609 unsigned char *p;
1610
1611 MPI_CHK( mpi_grow( X, size ) );
1612 MPI_CHK( mpi_lset( X, 0 ) );
1613
1614 p = (unsigned char *) X->p;
1615 for( k = 0; k < X->n * ciL; k++ )
1616 *p++ = (unsigned char) f_rng( p_rng );
1617
1618cleanup:
1619 return( ret );
1620}
1621
Paul Bakker70b3eed2009-03-14 18:01:25 +00001622#if defined(POLARSSL_GENPRIME)
1623
Paul Bakker5121ce52009-01-03 21:22:43 +00001624/*
1625 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1626 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001627int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001628{
1629 int ret;
1630 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1631
1632 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001633 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001634
Paul Bakker6c591fa2011-05-05 11:49:20 +00001635 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1636 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1637 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001638
1639 MPI_CHK( mpi_gcd( &G, A, N ) );
1640
1641 if( mpi_cmp_int( &G, 1 ) != 0 )
1642 {
Paul Bakker40e46942009-01-03 21:51:57 +00001643 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001644 goto cleanup;
1645 }
1646
1647 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1648 MPI_CHK( mpi_copy( &TU, &TA ) );
1649 MPI_CHK( mpi_copy( &TB, N ) );
1650 MPI_CHK( mpi_copy( &TV, N ) );
1651
1652 MPI_CHK( mpi_lset( &U1, 1 ) );
1653 MPI_CHK( mpi_lset( &U2, 0 ) );
1654 MPI_CHK( mpi_lset( &V1, 0 ) );
1655 MPI_CHK( mpi_lset( &V2, 1 ) );
1656
1657 do
1658 {
1659 while( ( TU.p[0] & 1 ) == 0 )
1660 {
1661 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1662
1663 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1664 {
1665 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1666 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1667 }
1668
1669 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1670 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1671 }
1672
1673 while( ( TV.p[0] & 1 ) == 0 )
1674 {
1675 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1676
1677 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1678 {
1679 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1680 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1681 }
1682
1683 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1684 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1685 }
1686
1687 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1688 {
1689 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1690 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1691 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1692 }
1693 else
1694 {
1695 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1696 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1697 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1698 }
1699 }
1700 while( mpi_cmp_int( &TU, 0 ) != 0 );
1701
1702 while( mpi_cmp_int( &V1, 0 ) < 0 )
1703 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1704
1705 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1706 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1707
1708 MPI_CHK( mpi_copy( X, &V1 ) );
1709
1710cleanup:
1711
Paul Bakker6c591fa2011-05-05 11:49:20 +00001712 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1713 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1714 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001715
1716 return( ret );
1717}
1718
1719static const int small_prime[] =
1720{
1721 3, 5, 7, 11, 13, 17, 19, 23,
1722 29, 31, 37, 41, 43, 47, 53, 59,
1723 61, 67, 71, 73, 79, 83, 89, 97,
1724 101, 103, 107, 109, 113, 127, 131, 137,
1725 139, 149, 151, 157, 163, 167, 173, 179,
1726 181, 191, 193, 197, 199, 211, 223, 227,
1727 229, 233, 239, 241, 251, 257, 263, 269,
1728 271, 277, 281, 283, 293, 307, 311, 313,
1729 317, 331, 337, 347, 349, 353, 359, 367,
1730 373, 379, 383, 389, 397, 401, 409, 419,
1731 421, 431, 433, 439, 443, 449, 457, 461,
1732 463, 467, 479, 487, 491, 499, 503, 509,
1733 521, 523, 541, 547, 557, 563, 569, 571,
1734 577, 587, 593, 599, 601, 607, 613, 617,
1735 619, 631, 641, 643, 647, 653, 659, 661,
1736 673, 677, 683, 691, 701, 709, 719, 727,
1737 733, 739, 743, 751, 757, 761, 769, 773,
1738 787, 797, 809, 811, 821, 823, 827, 829,
1739 839, 853, 857, 859, 863, 877, 881, 883,
1740 887, 907, 911, 919, 929, 937, 941, 947,
1741 953, 967, 971, 977, 983, 991, 997, -103
1742};
1743
1744/*
1745 * Miller-Rabin primality test (HAC 4.24)
1746 */
1747int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng )
1748{
Paul Bakker23986e52011-04-24 08:57:21 +00001749 int ret, xs;
1750 size_t i, j, n, s;
Paul Bakker5121ce52009-01-03 21:22:43 +00001751 mpi W, R, T, A, RR;
Paul Bakker5121ce52009-01-03 21:22:43 +00001752
Paul Bakker48eab262009-06-25 21:25:49 +00001753 if( mpi_cmp_int( X, 0 ) == 0 ||
1754 mpi_cmp_int( X, 1 ) == 0 )
1755 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
1756
1757 if( mpi_cmp_int( X, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001758 return( 0 );
1759
Paul Bakker6c591fa2011-05-05 11:49:20 +00001760 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1761 mpi_init( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001762
1763 xs = X->s; X->s = 1;
1764
1765 /*
1766 * test trivial factors first
1767 */
1768 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001769 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001770
1771 for( i = 0; small_prime[i] > 0; i++ )
1772 {
Paul Bakkera755ca12011-04-24 09:11:17 +00001773 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001774
1775 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
1776 return( 0 );
1777
1778 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1779
1780 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001781 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001782 }
1783
1784 /*
1785 * W = |X| - 1
1786 * R = W >> lsb( W )
1787 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001788 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001789 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001790 MPI_CHK( mpi_copy( &R, &W ) );
1791 MPI_CHK( mpi_shift_r( &R, s ) );
1792
1793 i = mpi_msb( X );
1794 /*
1795 * HAC, table 4.4
1796 */
1797 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1798 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1799 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1800
1801 for( i = 0; i < n; i++ )
1802 {
1803 /*
1804 * pick a random A, 1 < A < |X| - 1
1805 */
Paul Bakker287781a2011-03-26 13:18:49 +00001806 mpi_fill_random( &A, X->n, f_rng, p_rng );
Paul Bakker5121ce52009-01-03 21:22:43 +00001807
Paul Bakkerb94081b2011-01-05 15:53:06 +00001808 if( mpi_cmp_mpi( &A, &W ) >= 0 )
1809 {
1810 j = mpi_msb( &A ) - mpi_msb( &W );
1811 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
1812 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001813 A.p[0] |= 3;
1814
1815 /*
1816 * A = A^R mod |X|
1817 */
1818 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
1819
1820 if( mpi_cmp_mpi( &A, &W ) == 0 ||
1821 mpi_cmp_int( &A, 1 ) == 0 )
1822 continue;
1823
1824 j = 1;
1825 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
1826 {
1827 /*
1828 * A = A * A mod |X|
1829 */
1830 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
1831 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
1832
1833 if( mpi_cmp_int( &A, 1 ) == 0 )
1834 break;
1835
1836 j++;
1837 }
1838
1839 /*
1840 * not prime if A != |X| - 1 or A == 1
1841 */
1842 if( mpi_cmp_mpi( &A, &W ) != 0 ||
1843 mpi_cmp_int( &A, 1 ) == 0 )
1844 {
Paul Bakker40e46942009-01-03 21:51:57 +00001845 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001846 break;
1847 }
1848 }
1849
1850cleanup:
1851
1852 X->s = xs;
1853
Paul Bakker6c591fa2011-05-05 11:49:20 +00001854 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
1855 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001856
1857 return( ret );
1858}
1859
1860/*
1861 * Prime number generation
1862 */
Paul Bakker23986e52011-04-24 08:57:21 +00001863int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakker5121ce52009-01-03 21:22:43 +00001864 int (*f_rng)(void *), void *p_rng )
1865{
Paul Bakker23986e52011-04-24 08:57:21 +00001866 int ret;
1867 size_t k, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00001868 mpi Y;
1869
Paul Bakkerf9688572011-05-05 10:00:45 +00001870 if( nbits < 3 || nbits > 4096 )
Paul Bakker40e46942009-01-03 21:51:57 +00001871 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001872
Paul Bakker6c591fa2011-05-05 11:49:20 +00001873 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00001874
1875 n = BITS_TO_LIMBS( nbits );
1876
Paul Bakker287781a2011-03-26 13:18:49 +00001877 mpi_fill_random( X, n, f_rng, p_rng );
Paul Bakker5121ce52009-01-03 21:22:43 +00001878
1879 k = mpi_msb( X );
1880 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
1881 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
1882
1883 X->p[0] |= 3;
1884
1885 if( dh_flag == 0 )
1886 {
1887 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
1888 {
Paul Bakker40e46942009-01-03 21:51:57 +00001889 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001890 goto cleanup;
1891
1892 MPI_CHK( mpi_add_int( X, X, 2 ) );
1893 }
1894 }
1895 else
1896 {
1897 MPI_CHK( mpi_sub_int( &Y, X, 1 ) );
1898 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1899
1900 while( 1 )
1901 {
1902 if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 )
1903 {
1904 if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 )
1905 break;
1906
Paul Bakker40e46942009-01-03 21:51:57 +00001907 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001908 goto cleanup;
1909 }
1910
Paul Bakker40e46942009-01-03 21:51:57 +00001911 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001912 goto cleanup;
1913
1914 MPI_CHK( mpi_add_int( &Y, X, 1 ) );
1915 MPI_CHK( mpi_add_int( X, X, 2 ) );
1916 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1917 }
1918 }
1919
1920cleanup:
1921
Paul Bakker6c591fa2011-05-05 11:49:20 +00001922 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00001923
1924 return( ret );
1925}
1926
1927#endif
1928
Paul Bakker40e46942009-01-03 21:51:57 +00001929#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001930
Paul Bakker23986e52011-04-24 08:57:21 +00001931#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001932
1933static const int gcd_pairs[GCD_PAIR_COUNT][3] =
1934{
1935 { 693, 609, 21 },
1936 { 1764, 868, 28 },
1937 { 768454923, 542167814, 1 }
1938};
1939
Paul Bakker5121ce52009-01-03 21:22:43 +00001940/*
1941 * Checkup routine
1942 */
1943int mpi_self_test( int verbose )
1944{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001945 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001946 mpi A, E, N, X, Y, U, V;
1947
Paul Bakker6c591fa2011-05-05 11:49:20 +00001948 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
1949 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00001950
1951 MPI_CHK( mpi_read_string( &A, 16,
1952 "EFE021C2645FD1DC586E69184AF4A31E" \
1953 "D5F53E93B5F123FA41680867BA110131" \
1954 "944FE7952E2517337780CB0DB80E61AA" \
1955 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
1956
1957 MPI_CHK( mpi_read_string( &E, 16,
1958 "B2E7EFD37075B9F03FF989C7C5051C20" \
1959 "34D2A323810251127E7BF8625A4F49A5" \
1960 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
1961 "5B5C25763222FEFCCFC38B832366C29E" ) );
1962
1963 MPI_CHK( mpi_read_string( &N, 16,
1964 "0066A198186C18C10B2F5ED9B522752A" \
1965 "9830B69916E535C8F047518A889A43A5" \
1966 "94B6BED27A168D31D4A52F88925AA8F5" ) );
1967
1968 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
1969
1970 MPI_CHK( mpi_read_string( &U, 16,
1971 "602AB7ECA597A3D6B56FF9829A5E8B85" \
1972 "9E857EA95A03512E2BAE7391688D264A" \
1973 "A5663B0341DB9CCFD2C4C5F421FEC814" \
1974 "8001B72E848A38CAE1C65F78E56ABDEF" \
1975 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
1976 "ECF677152EF804370C1A305CAF3B5BF1" \
1977 "30879B56C61DE584A0F53A2447A51E" ) );
1978
1979 if( verbose != 0 )
1980 printf( " MPI test #1 (mul_mpi): " );
1981
1982 if( mpi_cmp_mpi( &X, &U ) != 0 )
1983 {
1984 if( verbose != 0 )
1985 printf( "failed\n" );
1986
1987 return( 1 );
1988 }
1989
1990 if( verbose != 0 )
1991 printf( "passed\n" );
1992
1993 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
1994
1995 MPI_CHK( mpi_read_string( &U, 16,
1996 "256567336059E52CAE22925474705F39A94" ) );
1997
1998 MPI_CHK( mpi_read_string( &V, 16,
1999 "6613F26162223DF488E9CD48CC132C7A" \
2000 "0AC93C701B001B092E4E5B9F73BCD27B" \
2001 "9EE50D0657C77F374E903CDFA4C642" ) );
2002
2003 if( verbose != 0 )
2004 printf( " MPI test #2 (div_mpi): " );
2005
2006 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2007 mpi_cmp_mpi( &Y, &V ) != 0 )
2008 {
2009 if( verbose != 0 )
2010 printf( "failed\n" );
2011
2012 return( 1 );
2013 }
2014
2015 if( verbose != 0 )
2016 printf( "passed\n" );
2017
2018 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2019
2020 MPI_CHK( mpi_read_string( &U, 16,
2021 "36E139AEA55215609D2816998ED020BB" \
2022 "BD96C37890F65171D948E9BC7CBAA4D9" \
2023 "325D24D6A3C12710F10A09FA08AB87" ) );
2024
2025 if( verbose != 0 )
2026 printf( " MPI test #3 (exp_mod): " );
2027
2028 if( mpi_cmp_mpi( &X, &U ) != 0 )
2029 {
2030 if( verbose != 0 )
2031 printf( "failed\n" );
2032
2033 return( 1 );
2034 }
2035
2036 if( verbose != 0 )
2037 printf( "passed\n" );
2038
Paul Bakker5690efc2011-05-26 13:16:06 +00002039#if defined(POLARSSL_GENPRIME)
Paul Bakker5121ce52009-01-03 21:22:43 +00002040 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2041
2042 MPI_CHK( mpi_read_string( &U, 16,
2043 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2044 "C3DBA76456363A10869622EAC2DD84EC" \
2045 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2046
2047 if( verbose != 0 )
2048 printf( " MPI test #4 (inv_mod): " );
2049
2050 if( mpi_cmp_mpi( &X, &U ) != 0 )
2051 {
2052 if( verbose != 0 )
2053 printf( "failed\n" );
2054
2055 return( 1 );
2056 }
2057
2058 if( verbose != 0 )
2059 printf( "passed\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00002060#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002061
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002062 if( verbose != 0 )
2063 printf( " MPI test #5 (simple gcd): " );
2064
2065 for ( i = 0; i < GCD_PAIR_COUNT; i++)
2066 {
2067 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002068 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002069
Paul Bakker23986e52011-04-24 08:57:21 +00002070 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002071
Paul Bakker23986e52011-04-24 08:57:21 +00002072 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2073 {
2074 if( verbose != 0 )
2075 printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002076
Paul Bakker23986e52011-04-24 08:57:21 +00002077 return( 1 );
2078 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002079 }
2080
2081 if( verbose != 0 )
2082 printf( "passed\n" );
2083
Paul Bakker5121ce52009-01-03 21:22:43 +00002084cleanup:
2085
2086 if( ret != 0 && verbose != 0 )
2087 printf( "Unexpected error, return code = %08X\n", ret );
2088
Paul Bakker6c591fa2011-05-05 11:49:20 +00002089 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2090 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002091
2092 if( verbose != 0 )
2093 printf( "\n" );
2094
2095 return( ret );
2096}
2097
2098#endif
2099
2100#endif