blob: c00697eb6f8014477cf5193ce349b74c351c1f60 [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 Bakker5121ce52009-01-03 21:22:43 +00001380 mpi RR, T, W[64];
1381
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
1397 j = N->n + 1;
1398 MPI_CHK( mpi_grow( X, j ) );
1399 MPI_CHK( mpi_grow( &W[1], j ) );
1400 MPI_CHK( mpi_grow( &T, j * 2 ) );
1401
1402 /*
1403 * If 1st call, pre-compute R^2 mod N
1404 */
1405 if( _RR == NULL || _RR->p == NULL )
1406 {
1407 MPI_CHK( mpi_lset( &RR, 1 ) );
1408 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1409 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1410
1411 if( _RR != NULL )
1412 memcpy( _RR, &RR, sizeof( mpi ) );
1413 }
1414 else
1415 memcpy( &RR, _RR, sizeof( mpi ) );
1416
1417 /*
1418 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1419 */
1420 if( mpi_cmp_mpi( A, N ) >= 0 )
1421 mpi_mod_mpi( &W[1], A, N );
1422 else mpi_copy( &W[1], A );
1423
1424 mpi_montmul( &W[1], &RR, N, mm, &T );
1425
1426 /*
1427 * X = R^2 * R^-1 mod N = R mod N
1428 */
1429 MPI_CHK( mpi_copy( X, &RR ) );
1430 mpi_montred( X, N, mm, &T );
1431
1432 if( wsize > 1 )
1433 {
1434 /*
1435 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1436 */
Paul Bakker23986e52011-04-24 08:57:21 +00001437 j = one << (wsize - 1);
Paul Bakker5121ce52009-01-03 21:22:43 +00001438
1439 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1440 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1441
1442 for( i = 0; i < wsize - 1; i++ )
1443 mpi_montmul( &W[j], &W[j], N, mm, &T );
1444
1445 /*
1446 * W[i] = W[i - 1] * W[1]
1447 */
Paul Bakker23986e52011-04-24 08:57:21 +00001448 for( i = j + 1; i < (one << wsize); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001449 {
1450 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1451 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1452
1453 mpi_montmul( &W[i], &W[1], N, mm, &T );
1454 }
1455 }
1456
1457 nblimbs = E->n;
1458 bufsize = 0;
1459 nbits = 0;
1460 wbits = 0;
1461 state = 0;
1462
1463 while( 1 )
1464 {
1465 if( bufsize == 0 )
1466 {
1467 if( nblimbs-- == 0 )
1468 break;
1469
Paul Bakkera755ca12011-04-24 09:11:17 +00001470 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001471 }
1472
1473 bufsize--;
1474
1475 ei = (E->p[nblimbs] >> bufsize) & 1;
1476
1477 /*
1478 * skip leading 0s
1479 */
1480 if( ei == 0 && state == 0 )
1481 continue;
1482
1483 if( ei == 0 && state == 1 )
1484 {
1485 /*
1486 * out of window, square X
1487 */
1488 mpi_montmul( X, X, N, mm, &T );
1489 continue;
1490 }
1491
1492 /*
1493 * add ei to current window
1494 */
1495 state = 2;
1496
1497 nbits++;
1498 wbits |= (ei << (wsize - nbits));
1499
1500 if( nbits == wsize )
1501 {
1502 /*
1503 * X = X^wsize R^-1 mod N
1504 */
1505 for( i = 0; i < wsize; i++ )
1506 mpi_montmul( X, X, N, mm, &T );
1507
1508 /*
1509 * X = X * W[wbits] R^-1 mod N
1510 */
1511 mpi_montmul( X, &W[wbits], N, mm, &T );
1512
1513 state--;
1514 nbits = 0;
1515 wbits = 0;
1516 }
1517 }
1518
1519 /*
1520 * process the remaining bits
1521 */
1522 for( i = 0; i < nbits; i++ )
1523 {
1524 mpi_montmul( X, X, N, mm, &T );
1525
1526 wbits <<= 1;
1527
Paul Bakker23986e52011-04-24 08:57:21 +00001528 if( (wbits & (one << wsize)) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001529 mpi_montmul( X, &W[1], N, mm, &T );
1530 }
1531
1532 /*
1533 * X = A^E * R * R^-1 mod N = A^E mod N
1534 */
1535 mpi_montred( X, N, mm, &T );
1536
1537cleanup:
1538
Paul Bakker23986e52011-04-24 08:57:21 +00001539 for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001540 mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001541
Paul Bakker6c591fa2011-05-05 11:49:20 +00001542 mpi_free( &W[1] ); mpi_free( &T );
1543
1544 if( _RR == NULL )
1545 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001546
1547 return( ret );
1548}
1549
Paul Bakker5121ce52009-01-03 21:22:43 +00001550/*
1551 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1552 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001553int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001554{
Paul Bakker23986e52011-04-24 08:57:21 +00001555 int ret;
1556 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001557 mpi TG, TA, TB;
1558
Paul Bakker6c591fa2011-05-05 11:49:20 +00001559 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001560
Paul Bakker5121ce52009-01-03 21:22:43 +00001561 MPI_CHK( mpi_copy( &TA, A ) );
1562 MPI_CHK( mpi_copy( &TB, B ) );
1563
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001564 lz = mpi_lsb( &TA );
1565 lzt = mpi_lsb( &TB );
1566
1567 if ( lzt < lz )
1568 lz = lzt;
1569
1570 MPI_CHK( mpi_shift_r( &TA, lz ) );
1571 MPI_CHK( mpi_shift_r( &TB, lz ) );
1572
Paul Bakker5121ce52009-01-03 21:22:43 +00001573 TA.s = TB.s = 1;
1574
1575 while( mpi_cmp_int( &TA, 0 ) != 0 )
1576 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001577 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1578 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001579
1580 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1581 {
1582 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1583 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1584 }
1585 else
1586 {
1587 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1588 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1589 }
1590 }
1591
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001592 MPI_CHK( mpi_shift_l( &TB, lz ) );
1593 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001594
1595cleanup:
1596
Paul Bakker6c591fa2011-05-05 11:49:20 +00001597 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001598
1599 return( ret );
1600}
1601
Paul Bakker23986e52011-04-24 08:57:21 +00001602int mpi_fill_random( mpi *X, size_t size, int (*f_rng)(void *), void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001603{
Paul Bakker23986e52011-04-24 08:57:21 +00001604 int ret;
1605 size_t k;
Paul Bakker287781a2011-03-26 13:18:49 +00001606 unsigned char *p;
1607
1608 MPI_CHK( mpi_grow( X, size ) );
1609 MPI_CHK( mpi_lset( X, 0 ) );
1610
1611 p = (unsigned char *) X->p;
1612 for( k = 0; k < X->n * ciL; k++ )
1613 *p++ = (unsigned char) f_rng( p_rng );
1614
1615cleanup:
1616 return( ret );
1617}
1618
Paul Bakker70b3eed2009-03-14 18:01:25 +00001619#if defined(POLARSSL_GENPRIME)
1620
Paul Bakker5121ce52009-01-03 21:22:43 +00001621/*
1622 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1623 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001624int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001625{
1626 int ret;
1627 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1628
1629 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001630 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001631
Paul Bakker6c591fa2011-05-05 11:49:20 +00001632 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1633 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1634 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001635
1636 MPI_CHK( mpi_gcd( &G, A, N ) );
1637
1638 if( mpi_cmp_int( &G, 1 ) != 0 )
1639 {
Paul Bakker40e46942009-01-03 21:51:57 +00001640 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001641 goto cleanup;
1642 }
1643
1644 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1645 MPI_CHK( mpi_copy( &TU, &TA ) );
1646 MPI_CHK( mpi_copy( &TB, N ) );
1647 MPI_CHK( mpi_copy( &TV, N ) );
1648
1649 MPI_CHK( mpi_lset( &U1, 1 ) );
1650 MPI_CHK( mpi_lset( &U2, 0 ) );
1651 MPI_CHK( mpi_lset( &V1, 0 ) );
1652 MPI_CHK( mpi_lset( &V2, 1 ) );
1653
1654 do
1655 {
1656 while( ( TU.p[0] & 1 ) == 0 )
1657 {
1658 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1659
1660 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1661 {
1662 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1663 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1664 }
1665
1666 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1667 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1668 }
1669
1670 while( ( TV.p[0] & 1 ) == 0 )
1671 {
1672 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1673
1674 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1675 {
1676 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1677 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1678 }
1679
1680 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1681 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1682 }
1683
1684 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1685 {
1686 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1687 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1688 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1689 }
1690 else
1691 {
1692 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1693 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1694 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1695 }
1696 }
1697 while( mpi_cmp_int( &TU, 0 ) != 0 );
1698
1699 while( mpi_cmp_int( &V1, 0 ) < 0 )
1700 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1701
1702 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1703 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1704
1705 MPI_CHK( mpi_copy( X, &V1 ) );
1706
1707cleanup:
1708
Paul Bakker6c591fa2011-05-05 11:49:20 +00001709 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1710 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1711 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001712
1713 return( ret );
1714}
1715
1716static const int small_prime[] =
1717{
1718 3, 5, 7, 11, 13, 17, 19, 23,
1719 29, 31, 37, 41, 43, 47, 53, 59,
1720 61, 67, 71, 73, 79, 83, 89, 97,
1721 101, 103, 107, 109, 113, 127, 131, 137,
1722 139, 149, 151, 157, 163, 167, 173, 179,
1723 181, 191, 193, 197, 199, 211, 223, 227,
1724 229, 233, 239, 241, 251, 257, 263, 269,
1725 271, 277, 281, 283, 293, 307, 311, 313,
1726 317, 331, 337, 347, 349, 353, 359, 367,
1727 373, 379, 383, 389, 397, 401, 409, 419,
1728 421, 431, 433, 439, 443, 449, 457, 461,
1729 463, 467, 479, 487, 491, 499, 503, 509,
1730 521, 523, 541, 547, 557, 563, 569, 571,
1731 577, 587, 593, 599, 601, 607, 613, 617,
1732 619, 631, 641, 643, 647, 653, 659, 661,
1733 673, 677, 683, 691, 701, 709, 719, 727,
1734 733, 739, 743, 751, 757, 761, 769, 773,
1735 787, 797, 809, 811, 821, 823, 827, 829,
1736 839, 853, 857, 859, 863, 877, 881, 883,
1737 887, 907, 911, 919, 929, 937, 941, 947,
1738 953, 967, 971, 977, 983, 991, 997, -103
1739};
1740
1741/*
1742 * Miller-Rabin primality test (HAC 4.24)
1743 */
1744int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng )
1745{
Paul Bakker23986e52011-04-24 08:57:21 +00001746 int ret, xs;
1747 size_t i, j, n, s;
Paul Bakker5121ce52009-01-03 21:22:43 +00001748 mpi W, R, T, A, RR;
Paul Bakker5121ce52009-01-03 21:22:43 +00001749
Paul Bakker48eab262009-06-25 21:25:49 +00001750 if( mpi_cmp_int( X, 0 ) == 0 ||
1751 mpi_cmp_int( X, 1 ) == 0 )
1752 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
1753
1754 if( mpi_cmp_int( X, 2 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001755 return( 0 );
1756
Paul Bakker6c591fa2011-05-05 11:49:20 +00001757 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1758 mpi_init( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001759
1760 xs = X->s; X->s = 1;
1761
1762 /*
1763 * test trivial factors first
1764 */
1765 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001766 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001767
1768 for( i = 0; small_prime[i] > 0; i++ )
1769 {
Paul Bakkera755ca12011-04-24 09:11:17 +00001770 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001771
1772 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
1773 return( 0 );
1774
1775 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1776
1777 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001778 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001779 }
1780
1781 /*
1782 * W = |X| - 1
1783 * R = W >> lsb( W )
1784 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001785 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001786 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001787 MPI_CHK( mpi_copy( &R, &W ) );
1788 MPI_CHK( mpi_shift_r( &R, s ) );
1789
1790 i = mpi_msb( X );
1791 /*
1792 * HAC, table 4.4
1793 */
1794 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1795 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1796 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1797
1798 for( i = 0; i < n; i++ )
1799 {
1800 /*
1801 * pick a random A, 1 < A < |X| - 1
1802 */
Paul Bakker287781a2011-03-26 13:18:49 +00001803 mpi_fill_random( &A, X->n, f_rng, p_rng );
Paul Bakker5121ce52009-01-03 21:22:43 +00001804
Paul Bakkerb94081b2011-01-05 15:53:06 +00001805 if( mpi_cmp_mpi( &A, &W ) >= 0 )
1806 {
1807 j = mpi_msb( &A ) - mpi_msb( &W );
1808 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
1809 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001810 A.p[0] |= 3;
1811
1812 /*
1813 * A = A^R mod |X|
1814 */
1815 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
1816
1817 if( mpi_cmp_mpi( &A, &W ) == 0 ||
1818 mpi_cmp_int( &A, 1 ) == 0 )
1819 continue;
1820
1821 j = 1;
1822 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
1823 {
1824 /*
1825 * A = A * A mod |X|
1826 */
1827 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
1828 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
1829
1830 if( mpi_cmp_int( &A, 1 ) == 0 )
1831 break;
1832
1833 j++;
1834 }
1835
1836 /*
1837 * not prime if A != |X| - 1 or A == 1
1838 */
1839 if( mpi_cmp_mpi( &A, &W ) != 0 ||
1840 mpi_cmp_int( &A, 1 ) == 0 )
1841 {
Paul Bakker40e46942009-01-03 21:51:57 +00001842 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001843 break;
1844 }
1845 }
1846
1847cleanup:
1848
1849 X->s = xs;
1850
Paul Bakker6c591fa2011-05-05 11:49:20 +00001851 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
1852 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001853
1854 return( ret );
1855}
1856
1857/*
1858 * Prime number generation
1859 */
Paul Bakker23986e52011-04-24 08:57:21 +00001860int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakker5121ce52009-01-03 21:22:43 +00001861 int (*f_rng)(void *), void *p_rng )
1862{
Paul Bakker23986e52011-04-24 08:57:21 +00001863 int ret;
1864 size_t k, n;
Paul Bakker5121ce52009-01-03 21:22:43 +00001865 mpi Y;
1866
Paul Bakkerf9688572011-05-05 10:00:45 +00001867 if( nbits < 3 || nbits > 4096 )
Paul Bakker40e46942009-01-03 21:51:57 +00001868 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001869
Paul Bakker6c591fa2011-05-05 11:49:20 +00001870 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00001871
1872 n = BITS_TO_LIMBS( nbits );
1873
Paul Bakker287781a2011-03-26 13:18:49 +00001874 mpi_fill_random( X, n, f_rng, p_rng );
Paul Bakker5121ce52009-01-03 21:22:43 +00001875
1876 k = mpi_msb( X );
1877 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
1878 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
1879
1880 X->p[0] |= 3;
1881
1882 if( dh_flag == 0 )
1883 {
1884 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
1885 {
Paul Bakker40e46942009-01-03 21:51:57 +00001886 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001887 goto cleanup;
1888
1889 MPI_CHK( mpi_add_int( X, X, 2 ) );
1890 }
1891 }
1892 else
1893 {
1894 MPI_CHK( mpi_sub_int( &Y, X, 1 ) );
1895 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1896
1897 while( 1 )
1898 {
1899 if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 )
1900 {
1901 if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 )
1902 break;
1903
Paul Bakker40e46942009-01-03 21:51:57 +00001904 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001905 goto cleanup;
1906 }
1907
Paul Bakker40e46942009-01-03 21:51:57 +00001908 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001909 goto cleanup;
1910
1911 MPI_CHK( mpi_add_int( &Y, X, 1 ) );
1912 MPI_CHK( mpi_add_int( X, X, 2 ) );
1913 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1914 }
1915 }
1916
1917cleanup:
1918
Paul Bakker6c591fa2011-05-05 11:49:20 +00001919 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00001920
1921 return( ret );
1922}
1923
1924#endif
1925
Paul Bakker40e46942009-01-03 21:51:57 +00001926#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001927
Paul Bakker23986e52011-04-24 08:57:21 +00001928#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001929
1930static const int gcd_pairs[GCD_PAIR_COUNT][3] =
1931{
1932 { 693, 609, 21 },
1933 { 1764, 868, 28 },
1934 { 768454923, 542167814, 1 }
1935};
1936
Paul Bakker5121ce52009-01-03 21:22:43 +00001937/*
1938 * Checkup routine
1939 */
1940int mpi_self_test( int verbose )
1941{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001942 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001943 mpi A, E, N, X, Y, U, V;
1944
Paul Bakker6c591fa2011-05-05 11:49:20 +00001945 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
1946 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00001947
1948 MPI_CHK( mpi_read_string( &A, 16,
1949 "EFE021C2645FD1DC586E69184AF4A31E" \
1950 "D5F53E93B5F123FA41680867BA110131" \
1951 "944FE7952E2517337780CB0DB80E61AA" \
1952 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
1953
1954 MPI_CHK( mpi_read_string( &E, 16,
1955 "B2E7EFD37075B9F03FF989C7C5051C20" \
1956 "34D2A323810251127E7BF8625A4F49A5" \
1957 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
1958 "5B5C25763222FEFCCFC38B832366C29E" ) );
1959
1960 MPI_CHK( mpi_read_string( &N, 16,
1961 "0066A198186C18C10B2F5ED9B522752A" \
1962 "9830B69916E535C8F047518A889A43A5" \
1963 "94B6BED27A168D31D4A52F88925AA8F5" ) );
1964
1965 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
1966
1967 MPI_CHK( mpi_read_string( &U, 16,
1968 "602AB7ECA597A3D6B56FF9829A5E8B85" \
1969 "9E857EA95A03512E2BAE7391688D264A" \
1970 "A5663B0341DB9CCFD2C4C5F421FEC814" \
1971 "8001B72E848A38CAE1C65F78E56ABDEF" \
1972 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
1973 "ECF677152EF804370C1A305CAF3B5BF1" \
1974 "30879B56C61DE584A0F53A2447A51E" ) );
1975
1976 if( verbose != 0 )
1977 printf( " MPI test #1 (mul_mpi): " );
1978
1979 if( mpi_cmp_mpi( &X, &U ) != 0 )
1980 {
1981 if( verbose != 0 )
1982 printf( "failed\n" );
1983
1984 return( 1 );
1985 }
1986
1987 if( verbose != 0 )
1988 printf( "passed\n" );
1989
1990 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
1991
1992 MPI_CHK( mpi_read_string( &U, 16,
1993 "256567336059E52CAE22925474705F39A94" ) );
1994
1995 MPI_CHK( mpi_read_string( &V, 16,
1996 "6613F26162223DF488E9CD48CC132C7A" \
1997 "0AC93C701B001B092E4E5B9F73BCD27B" \
1998 "9EE50D0657C77F374E903CDFA4C642" ) );
1999
2000 if( verbose != 0 )
2001 printf( " MPI test #2 (div_mpi): " );
2002
2003 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2004 mpi_cmp_mpi( &Y, &V ) != 0 )
2005 {
2006 if( verbose != 0 )
2007 printf( "failed\n" );
2008
2009 return( 1 );
2010 }
2011
2012 if( verbose != 0 )
2013 printf( "passed\n" );
2014
2015 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2016
2017 MPI_CHK( mpi_read_string( &U, 16,
2018 "36E139AEA55215609D2816998ED020BB" \
2019 "BD96C37890F65171D948E9BC7CBAA4D9" \
2020 "325D24D6A3C12710F10A09FA08AB87" ) );
2021
2022 if( verbose != 0 )
2023 printf( " MPI test #3 (exp_mod): " );
2024
2025 if( mpi_cmp_mpi( &X, &U ) != 0 )
2026 {
2027 if( verbose != 0 )
2028 printf( "failed\n" );
2029
2030 return( 1 );
2031 }
2032
2033 if( verbose != 0 )
2034 printf( "passed\n" );
2035
Paul Bakker5690efc2011-05-26 13:16:06 +00002036#if defined(POLARSSL_GENPRIME)
Paul Bakker5121ce52009-01-03 21:22:43 +00002037 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2038
2039 MPI_CHK( mpi_read_string( &U, 16,
2040 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2041 "C3DBA76456363A10869622EAC2DD84EC" \
2042 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2043
2044 if( verbose != 0 )
2045 printf( " MPI test #4 (inv_mod): " );
2046
2047 if( mpi_cmp_mpi( &X, &U ) != 0 )
2048 {
2049 if( verbose != 0 )
2050 printf( "failed\n" );
2051
2052 return( 1 );
2053 }
2054
2055 if( verbose != 0 )
2056 printf( "passed\n" );
Paul Bakker5690efc2011-05-26 13:16:06 +00002057#endif
Paul Bakker5121ce52009-01-03 21:22:43 +00002058
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002059 if( verbose != 0 )
2060 printf( " MPI test #5 (simple gcd): " );
2061
2062 for ( i = 0; i < GCD_PAIR_COUNT; i++)
2063 {
2064 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002065 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002066
Paul Bakker23986e52011-04-24 08:57:21 +00002067 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002068
Paul Bakker23986e52011-04-24 08:57:21 +00002069 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2070 {
2071 if( verbose != 0 )
2072 printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002073
Paul Bakker23986e52011-04-24 08:57:21 +00002074 return( 1 );
2075 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002076 }
2077
2078 if( verbose != 0 )
2079 printf( "passed\n" );
2080
Paul Bakker5121ce52009-01-03 21:22:43 +00002081cleanup:
2082
2083 if( ret != 0 && verbose != 0 )
2084 printf( "Unexpected error, return code = %08X\n", ret );
2085
Paul Bakker6c591fa2011-05-05 11:49:20 +00002086 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2087 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002088
2089 if( verbose != 0 )
2090 printf( "\n" );
2091
2092 return( ret );
2093}
2094
2095#endif
2096
2097#endif