blob: ac7f25c01e258f61f507b36739c4407f64ce3624 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Multi-precision integer library
3 *
Paul Bakker7dc4c442014-02-01 22:50:26 +01004 * Copyright (C) 2006-2014, 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
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020033#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker40e46942009-01-03 21:51:57 +000034#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020035#else
36#include POLARSSL_CONFIG_FILE
37#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Paul Bakker40e46942009-01-03 21:51:57 +000039#if defined(POLARSSL_BIGNUM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Paul Bakker40e46942009-01-03 21:51:57 +000041#include "polarssl/bignum.h"
42#include "polarssl/bn_mul.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000043
Paul Bakker7dc4c442014-02-01 22:50:26 +010044#if defined(POLARSSL_PLATFORM_C)
45#include "polarssl/platform.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020046#else
Paul Bakker7dc4c442014-02-01 22:50:26 +010047#define polarssl_printf printf
Paul Bakker6e339b52013-07-03 13:37:05 +020048#define polarssl_malloc malloc
49#define polarssl_free free
50#endif
51
Paul Bakker5121ce52009-01-03 21:22:43 +000052#include <stdlib.h>
Paul Bakker5121ce52009-01-03 21:22:43 +000053
Paul Bakkerf9688572011-05-05 10:00:45 +000054#define ciL (sizeof(t_uint)) /* chars in limb */
Paul Bakker5121ce52009-01-03 21:22:43 +000055#define biL (ciL << 3) /* bits in limb */
56#define biH (ciL << 2) /* half limb size */
57
58/*
59 * Convert between bits/chars and number of limbs
60 */
61#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
62#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
63
64/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000065 * Initialize one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000066 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000067void mpi_init( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000068{
Paul Bakker6c591fa2011-05-05 11:49:20 +000069 if( X == NULL )
70 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000071
Paul Bakker6c591fa2011-05-05 11:49:20 +000072 X->s = 1;
73 X->n = 0;
74 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000075}
76
77/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000078 * Unallocate one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000079 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000080void mpi_free( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000081{
Paul Bakker6c591fa2011-05-05 11:49:20 +000082 if( X == NULL )
83 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000084
Paul Bakker6c591fa2011-05-05 11:49:20 +000085 if( X->p != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +000086 {
Paul Bakker6c591fa2011-05-05 11:49:20 +000087 memset( X->p, 0, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +020088 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +000089 }
90
Paul Bakker6c591fa2011-05-05 11:49:20 +000091 X->s = 1;
92 X->n = 0;
93 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000094}
95
96/*
97 * Enlarge to the specified number of limbs
98 */
Paul Bakker23986e52011-04-24 08:57:21 +000099int mpi_grow( mpi *X, size_t nblimbs )
Paul Bakker5121ce52009-01-03 21:22:43 +0000100{
Paul Bakkera755ca12011-04-24 09:11:17 +0000101 t_uint *p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000102
Paul Bakkerf9688572011-05-05 10:00:45 +0000103 if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
Paul Bakker69e095c2011-12-10 21:55:01 +0000104 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakkerf9688572011-05-05 10:00:45 +0000105
Paul Bakker5121ce52009-01-03 21:22:43 +0000106 if( X->n < nblimbs )
107 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200108 if( ( p = (t_uint *) polarssl_malloc( nblimbs * ciL ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000109 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000110
111 memset( p, 0, nblimbs * ciL );
112
113 if( X->p != NULL )
114 {
115 memcpy( p, X->p, X->n * ciL );
116 memset( X->p, 0, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +0200117 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000118 }
119
120 X->n = nblimbs;
121 X->p = p;
122 }
123
124 return( 0 );
125}
126
127/*
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100128 * Resize down as much as possible,
129 * while keeping at least the specified number of limbs
130 */
131int mpi_shrink( mpi *X, size_t nblimbs )
132{
133 t_uint *p;
134 size_t i;
135
136 /* Actually resize up in this case */
137 if( X->n <= nblimbs )
138 return( mpi_grow( X, nblimbs ) );
139
140 for( i = X->n - 1; i > 0; i-- )
141 if( X->p[i] != 0 )
142 break;
143 i++;
144
145 if( i < nblimbs )
146 i = nblimbs;
147
148 if( ( p = (t_uint *) polarssl_malloc( i * ciL ) ) == NULL )
149 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
150
151 memset( p, 0, i * ciL );
152
153 if( X->p != NULL )
154 {
155 memcpy( p, X->p, i * ciL );
156 memset( X->p, 0, X->n * ciL );
157 polarssl_free( X->p );
158 }
159
160 X->n = i;
161 X->p = p;
162
163 return( 0 );
164}
165
166/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000167 * Copy the contents of Y into X
168 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000169int mpi_copy( mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000170{
Paul Bakker23986e52011-04-24 08:57:21 +0000171 int ret;
172 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000173
174 if( X == Y )
175 return( 0 );
176
Manuel Pégourié-Gonnardf4999932013-08-12 17:02:59 +0200177 if( Y->p == NULL )
178 {
179 mpi_free( X );
180 return( 0 );
181 }
182
Paul Bakker5121ce52009-01-03 21:22:43 +0000183 for( i = Y->n - 1; i > 0; i-- )
184 if( Y->p[i] != 0 )
185 break;
186 i++;
187
188 X->s = Y->s;
189
190 MPI_CHK( mpi_grow( X, i ) );
191
192 memset( X->p, 0, X->n * ciL );
193 memcpy( X->p, Y->p, i * ciL );
194
195cleanup:
196
197 return( ret );
198}
199
200/*
201 * Swap the contents of X and Y
202 */
203void mpi_swap( mpi *X, mpi *Y )
204{
205 mpi T;
206
207 memcpy( &T, X, sizeof( mpi ) );
208 memcpy( X, Y, sizeof( mpi ) );
209 memcpy( Y, &T, sizeof( mpi ) );
210}
211
212/*
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100213 * Conditionally assign X = Y, without leaking information
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100214 * about whether the assignment was made or not.
215 * (Leaking information about the respective sizes of X and Y is ok however.)
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100216 */
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100217int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign )
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100218{
219 int ret = 0;
220 size_t i;
221
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100222 /* make sure assign is 0 or 1 */
223 assign = ( assign != 0 );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100224
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100225 MPI_CHK( mpi_grow( X, Y->n ) );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100226
Manuel Pégourié-Gonnard3e3d2b82013-11-21 21:12:26 +0100227 X->s = X->s * (1 - assign) + Y->s * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100228
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100229 for( i = 0; i < Y->n; i++ )
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100230 X->p[i] = X->p[i] * (1 - assign) + Y->p[i] * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100231
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100232 for( ; i < X->n; i++ )
233 X->p[i] *= (1 - assign);
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100234
235cleanup:
236 return( ret );
237}
238
239/*
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100240 * Conditionally swap X and Y, without leaking information
241 * about whether the swap was made or not.
242 * Here it is not ok to simply swap the pointers, which whould lead to
243 * different memory access patterns when X and Y are used afterwards.
244 */
245int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char swap )
246{
247 int ret, s;
248 size_t i;
249 t_uint tmp;
250
251 if( X == Y )
252 return( 0 );
253
254 /* make sure swap is 0 or 1 */
255 swap = ( swap != 0 );
256
257 MPI_CHK( mpi_grow( X, Y->n ) );
258 MPI_CHK( mpi_grow( Y, X->n ) );
259
260 s = X->s;
261 X->s = X->s * (1 - swap) + Y->s * swap;
262 Y->s = Y->s * (1 - swap) + s * swap;
263
264
265 for( i = 0; i < X->n; i++ )
266 {
267 tmp = X->p[i];
268 X->p[i] = X->p[i] * (1 - swap) + Y->p[i] * swap;
269 Y->p[i] = Y->p[i] * (1 - swap) + tmp * swap;
270 }
271
272cleanup:
273 return( ret );
274}
275
276/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000277 * Set value from integer
278 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000279int mpi_lset( mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000280{
281 int ret;
282
283 MPI_CHK( mpi_grow( X, 1 ) );
284 memset( X->p, 0, X->n * ciL );
285
286 X->p[0] = ( z < 0 ) ? -z : z;
287 X->s = ( z < 0 ) ? -1 : 1;
288
289cleanup:
290
291 return( ret );
292}
293
294/*
Paul Bakker2f5947e2011-05-18 15:47:11 +0000295 * Get a specific bit
296 */
Paul Bakker6b906e52012-05-08 12:01:43 +0000297int mpi_get_bit( const mpi *X, size_t pos )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000298{
299 if( X->n * biL <= pos )
300 return( 0 );
301
302 return ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01;
303}
304
305/*
306 * Set a bit to a specific value of 0 or 1
307 */
308int mpi_set_bit( mpi *X, size_t pos, unsigned char val )
309{
310 int ret = 0;
311 size_t off = pos / biL;
312 size_t idx = pos % biL;
313
314 if( val != 0 && val != 1 )
315 return POLARSSL_ERR_MPI_BAD_INPUT_DATA;
316
317 if( X->n * biL <= pos )
318 {
319 if( val == 0 )
320 return ( 0 );
321
322 MPI_CHK( mpi_grow( X, off + 1 ) );
323 }
324
Manuel Pégourié-Gonnard9a4a5ac2013-12-04 18:05:29 +0100325 X->p[off] &= ~( (t_uint) 0x01 << idx );
326 X->p[off] |= (t_uint) val << idx;
Paul Bakker2f5947e2011-05-18 15:47:11 +0000327
328cleanup:
329
330 return( ret );
331}
332
333/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000334 * Return the number of least significant bits
335 */
Paul Bakker23986e52011-04-24 08:57:21 +0000336size_t mpi_lsb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000337{
Paul Bakker23986e52011-04-24 08:57:21 +0000338 size_t i, j, count = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000339
340 for( i = 0; i < X->n; i++ )
Paul Bakkerf9688572011-05-05 10:00:45 +0000341 for( j = 0; j < biL; j++, count++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000342 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
343 return( count );
344
345 return( 0 );
346}
347
348/*
349 * Return the number of most significant bits
350 */
Paul Bakker23986e52011-04-24 08:57:21 +0000351size_t mpi_msb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000352{
Paul Bakker23986e52011-04-24 08:57:21 +0000353 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000354
355 for( i = X->n - 1; i > 0; i-- )
356 if( X->p[i] != 0 )
357 break;
358
Paul Bakker23986e52011-04-24 08:57:21 +0000359 for( j = biL; j > 0; j-- )
360 if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000361 break;
362
Paul Bakker23986e52011-04-24 08:57:21 +0000363 return( ( i * biL ) + j );
Paul Bakker5121ce52009-01-03 21:22:43 +0000364}
365
366/*
367 * Return the total size in bytes
368 */
Paul Bakker23986e52011-04-24 08:57:21 +0000369size_t mpi_size( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000370{
371 return( ( mpi_msb( X ) + 7 ) >> 3 );
372}
373
374/*
375 * Convert an ASCII character to digit value
376 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000377static int mpi_get_digit( t_uint *d, int radix, char c )
Paul Bakker5121ce52009-01-03 21:22:43 +0000378{
379 *d = 255;
380
381 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
382 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
383 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
384
Paul Bakkera755ca12011-04-24 09:11:17 +0000385 if( *d >= (t_uint) radix )
Paul Bakker40e46942009-01-03 21:51:57 +0000386 return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000387
388 return( 0 );
389}
390
391/*
392 * Import from an ASCII string
393 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000394int mpi_read_string( mpi *X, int radix, const char *s )
Paul Bakker5121ce52009-01-03 21:22:43 +0000395{
Paul Bakker23986e52011-04-24 08:57:21 +0000396 int ret;
397 size_t i, j, slen, n;
Paul Bakkera755ca12011-04-24 09:11:17 +0000398 t_uint d;
Paul Bakker5121ce52009-01-03 21:22:43 +0000399 mpi T;
400
401 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000402 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
Paul Bakker6c591fa2011-05-05 11:49:20 +0000404 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000405
Paul Bakkerff60ee62010-03-16 21:09:09 +0000406 slen = strlen( s );
407
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 if( radix == 16 )
409 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000410 n = BITS_TO_LIMBS( slen << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
412 MPI_CHK( mpi_grow( X, n ) );
413 MPI_CHK( mpi_lset( X, 0 ) );
414
Paul Bakker23986e52011-04-24 08:57:21 +0000415 for( i = slen, j = 0; i > 0; i--, j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000416 {
Paul Bakker23986e52011-04-24 08:57:21 +0000417 if( i == 1 && s[i - 1] == '-' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000418 {
419 X->s = -1;
420 break;
421 }
422
Paul Bakker23986e52011-04-24 08:57:21 +0000423 MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000424 X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 );
425 }
426 }
427 else
428 {
429 MPI_CHK( mpi_lset( X, 0 ) );
430
Paul Bakkerff60ee62010-03-16 21:09:09 +0000431 for( i = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000432 {
433 if( i == 0 && s[i] == '-' )
434 {
435 X->s = -1;
436 continue;
437 }
438
439 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
440 MPI_CHK( mpi_mul_int( &T, X, radix ) );
Paul Bakker05feca62009-06-20 08:22:43 +0000441
442 if( X->s == 1 )
443 {
444 MPI_CHK( mpi_add_int( X, &T, d ) );
445 }
446 else
447 {
448 MPI_CHK( mpi_sub_int( X, &T, d ) );
449 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000450 }
451 }
452
453cleanup:
454
Paul Bakker6c591fa2011-05-05 11:49:20 +0000455 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000456
457 return( ret );
458}
459
460/*
461 * Helper to write the digits high-order first
462 */
463static int mpi_write_hlp( mpi *X, int radix, char **p )
464{
465 int ret;
Paul Bakkera755ca12011-04-24 09:11:17 +0000466 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +0000467
468 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000469 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000470
471 MPI_CHK( mpi_mod_int( &r, X, radix ) );
472 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
473
474 if( mpi_cmp_int( X, 0 ) != 0 )
475 MPI_CHK( mpi_write_hlp( X, radix, p ) );
476
477 if( r < 10 )
478 *(*p)++ = (char)( r + 0x30 );
479 else
480 *(*p)++ = (char)( r + 0x37 );
481
482cleanup:
483
484 return( ret );
485}
486
487/*
488 * Export into an ASCII string
489 */
Paul Bakker23986e52011-04-24 08:57:21 +0000490int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000491{
Paul Bakker23986e52011-04-24 08:57:21 +0000492 int ret = 0;
493 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000494 char *p;
495 mpi T;
496
497 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000498 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000499
500 n = mpi_msb( X );
501 if( radix >= 4 ) n >>= 1;
502 if( radix >= 16 ) n >>= 1;
503 n += 3;
504
505 if( *slen < n )
506 {
507 *slen = n;
Paul Bakker40e46942009-01-03 21:51:57 +0000508 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000509 }
510
511 p = s;
Paul Bakker6c591fa2011-05-05 11:49:20 +0000512 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000513
514 if( X->s == -1 )
515 *p++ = '-';
516
517 if( radix == 16 )
518 {
Paul Bakker23986e52011-04-24 08:57:21 +0000519 int c;
520 size_t i, j, k;
Paul Bakker5121ce52009-01-03 21:22:43 +0000521
Paul Bakker23986e52011-04-24 08:57:21 +0000522 for( i = X->n, k = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000523 {
Paul Bakker23986e52011-04-24 08:57:21 +0000524 for( j = ciL; j > 0; j-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000525 {
Paul Bakker23986e52011-04-24 08:57:21 +0000526 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000527
Paul Bakker23986e52011-04-24 08:57:21 +0000528 if( c == 0 && k == 0 && ( i + j + 3 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000529 continue;
530
Paul Bakker98fe5ea2012-10-24 11:17:48 +0000531 *(p++) = "0123456789ABCDEF" [c / 16];
Paul Bakkerd2c167e2012-10-30 07:49:19 +0000532 *(p++) = "0123456789ABCDEF" [c % 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000533 k = 1;
534 }
535 }
536 }
537 else
538 {
539 MPI_CHK( mpi_copy( &T, X ) );
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000540
541 if( T.s == -1 )
542 T.s = 1;
543
Paul Bakker5121ce52009-01-03 21:22:43 +0000544 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
545 }
546
547 *p++ = '\0';
548 *slen = p - s;
549
550cleanup:
551
Paul Bakker6c591fa2011-05-05 11:49:20 +0000552 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000553
554 return( ret );
555}
556
Paul Bakker335db3f2011-04-25 15:28:35 +0000557#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000558/*
559 * Read X from an opened file
560 */
561int mpi_read_file( mpi *X, int radix, FILE *fin )
562{
Paul Bakkera755ca12011-04-24 09:11:17 +0000563 t_uint d;
Paul Bakker23986e52011-04-24 08:57:21 +0000564 size_t slen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000565 char *p;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000566 /*
Paul Bakkercb37aa52011-11-30 16:00:20 +0000567 * Buffer should have space for (short) label and decimal formatted MPI,
568 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000569 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000570 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000571
572 memset( s, 0, sizeof( s ) );
573 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000574 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000575
576 slen = strlen( s );
Paul Bakkercb37aa52011-11-30 16:00:20 +0000577 if( slen == sizeof( s ) - 2 )
578 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
579
Paul Bakker5121ce52009-01-03 21:22:43 +0000580 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
581 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
582
583 p = s + slen;
584 while( --p >= s )
585 if( mpi_get_digit( &d, radix, *p ) != 0 )
586 break;
587
588 return( mpi_read_string( X, radix, p + 1 ) );
589}
590
591/*
592 * Write X into an opened file (or stdout if fout == NULL)
593 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000594int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
Paul Bakker5121ce52009-01-03 21:22:43 +0000595{
Paul Bakker23986e52011-04-24 08:57:21 +0000596 int ret;
597 size_t n, slen, plen;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000598 /*
Paul Bakker5531c6d2012-09-26 19:20:46 +0000599 * Buffer should have space for (short) label and decimal formatted MPI,
600 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000601 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000602 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000603
604 n = sizeof( s );
605 memset( s, 0, n );
606 n -= 2;
607
Paul Bakker23986e52011-04-24 08:57:21 +0000608 MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
610 if( p == NULL ) p = "";
611
612 plen = strlen( p );
613 slen = strlen( s );
614 s[slen++] = '\r';
615 s[slen++] = '\n';
616
617 if( fout != NULL )
618 {
619 if( fwrite( p, 1, plen, fout ) != plen ||
620 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000621 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000622 }
623 else
Paul Bakker7dc4c442014-02-01 22:50:26 +0100624 polarssl_printf( "%s%s", p, s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000625
626cleanup:
627
628 return( ret );
629}
Paul Bakker335db3f2011-04-25 15:28:35 +0000630#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000631
632/*
633 * Import X from unsigned binary data, big endian
634 */
Paul Bakker23986e52011-04-24 08:57:21 +0000635int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000636{
Paul Bakker23986e52011-04-24 08:57:21 +0000637 int ret;
638 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000639
640 for( n = 0; n < buflen; n++ )
641 if( buf[n] != 0 )
642 break;
643
644 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
645 MPI_CHK( mpi_lset( X, 0 ) );
646
Paul Bakker23986e52011-04-24 08:57:21 +0000647 for( i = buflen, j = 0; i > n; i--, j++ )
Paul Bakkera755ca12011-04-24 09:11:17 +0000648 X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000649
650cleanup:
651
652 return( ret );
653}
654
655/*
656 * Export X into unsigned binary data, big endian
657 */
Paul Bakker23986e52011-04-24 08:57:21 +0000658int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000659{
Paul Bakker23986e52011-04-24 08:57:21 +0000660 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
662 n = mpi_size( X );
663
664 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000665 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000666
667 memset( buf, 0, buflen );
668
669 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
670 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
671
672 return( 0 );
673}
674
675/*
676 * Left-shift: X <<= count
677 */
Paul Bakker23986e52011-04-24 08:57:21 +0000678int mpi_shift_l( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000679{
Paul Bakker23986e52011-04-24 08:57:21 +0000680 int ret;
681 size_t i, v0, t1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000682 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000683
684 v0 = count / (biL );
685 t1 = count & (biL - 1);
686
687 i = mpi_msb( X ) + count;
688
Paul Bakkerf9688572011-05-05 10:00:45 +0000689 if( X->n * biL < i )
Paul Bakker5121ce52009-01-03 21:22:43 +0000690 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
691
692 ret = 0;
693
694 /*
695 * shift by count / limb_size
696 */
697 if( v0 > 0 )
698 {
Paul Bakker23986e52011-04-24 08:57:21 +0000699 for( i = X->n; i > v0; i-- )
700 X->p[i - 1] = X->p[i - v0 - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000701
Paul Bakker23986e52011-04-24 08:57:21 +0000702 for( ; i > 0; i-- )
703 X->p[i - 1] = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000704 }
705
706 /*
707 * shift by count % limb_size
708 */
709 if( t1 > 0 )
710 {
711 for( i = v0; i < X->n; i++ )
712 {
713 r1 = X->p[i] >> (biL - t1);
714 X->p[i] <<= t1;
715 X->p[i] |= r0;
716 r0 = r1;
717 }
718 }
719
720cleanup:
721
722 return( ret );
723}
724
725/*
726 * Right-shift: X >>= count
727 */
Paul Bakker23986e52011-04-24 08:57:21 +0000728int mpi_shift_r( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000729{
Paul Bakker23986e52011-04-24 08:57:21 +0000730 size_t i, v0, v1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000731 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000732
733 v0 = count / biL;
734 v1 = count & (biL - 1);
735
Manuel Pégourié-Gonnarde44ec102012-11-17 12:42:51 +0100736 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
737 return mpi_lset( X, 0 );
738
Paul Bakker5121ce52009-01-03 21:22:43 +0000739 /*
740 * shift by count / limb_size
741 */
742 if( v0 > 0 )
743 {
744 for( i = 0; i < X->n - v0; i++ )
745 X->p[i] = X->p[i + v0];
746
747 for( ; i < X->n; i++ )
748 X->p[i] = 0;
749 }
750
751 /*
752 * shift by count % limb_size
753 */
754 if( v1 > 0 )
755 {
Paul Bakker23986e52011-04-24 08:57:21 +0000756 for( i = X->n; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000757 {
Paul Bakker23986e52011-04-24 08:57:21 +0000758 r1 = X->p[i - 1] << (biL - v1);
759 X->p[i - 1] >>= v1;
760 X->p[i - 1] |= r0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000761 r0 = r1;
762 }
763 }
764
765 return( 0 );
766}
767
768/*
769 * Compare unsigned values
770 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000771int mpi_cmp_abs( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000772{
Paul Bakker23986e52011-04-24 08:57:21 +0000773 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000774
Paul Bakker23986e52011-04-24 08:57:21 +0000775 for( i = X->n; i > 0; i-- )
776 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000777 break;
778
Paul Bakker23986e52011-04-24 08:57:21 +0000779 for( j = Y->n; j > 0; j-- )
780 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000781 break;
782
Paul Bakker23986e52011-04-24 08:57:21 +0000783 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000784 return( 0 );
785
786 if( i > j ) return( 1 );
787 if( j > i ) return( -1 );
788
Paul Bakker23986e52011-04-24 08:57:21 +0000789 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000790 {
Paul Bakker23986e52011-04-24 08:57:21 +0000791 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
792 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000793 }
794
795 return( 0 );
796}
797
798/*
799 * Compare signed values
800 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000801int mpi_cmp_mpi( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000802{
Paul Bakker23986e52011-04-24 08:57:21 +0000803 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000804
Paul Bakker23986e52011-04-24 08:57:21 +0000805 for( i = X->n; i > 0; i-- )
806 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000807 break;
808
Paul Bakker23986e52011-04-24 08:57:21 +0000809 for( j = Y->n; j > 0; j-- )
810 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000811 break;
812
Paul Bakker23986e52011-04-24 08:57:21 +0000813 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000814 return( 0 );
815
816 if( i > j ) return( X->s );
Paul Bakker0c8f73b2012-03-22 14:08:57 +0000817 if( j > i ) return( -Y->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000818
819 if( X->s > 0 && Y->s < 0 ) return( 1 );
820 if( Y->s > 0 && X->s < 0 ) return( -1 );
821
Paul Bakker23986e52011-04-24 08:57:21 +0000822 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000823 {
Paul Bakker23986e52011-04-24 08:57:21 +0000824 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
825 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000826 }
827
828 return( 0 );
829}
830
831/*
832 * Compare signed values
833 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000834int mpi_cmp_int( const mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000835{
836 mpi Y;
Paul Bakkera755ca12011-04-24 09:11:17 +0000837 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000838
839 *p = ( z < 0 ) ? -z : z;
840 Y.s = ( z < 0 ) ? -1 : 1;
841 Y.n = 1;
842 Y.p = p;
843
844 return( mpi_cmp_mpi( X, &Y ) );
845}
846
847/*
848 * Unsigned addition: X = |A| + |B| (HAC 14.7)
849 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000850int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000851{
Paul Bakker23986e52011-04-24 08:57:21 +0000852 int ret;
853 size_t i, j;
Paul Bakkera755ca12011-04-24 09:11:17 +0000854 t_uint *o, *p, c;
Paul Bakker5121ce52009-01-03 21:22:43 +0000855
856 if( X == B )
857 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000858 const mpi *T = A; A = X; B = T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000859 }
860
861 if( X != A )
862 MPI_CHK( mpi_copy( X, A ) );
Paul Bakkerf7ca7b92009-06-20 10:31:06 +0000863
864 /*
865 * X should always be positive as a result of unsigned additions.
866 */
867 X->s = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000868
Paul Bakker23986e52011-04-24 08:57:21 +0000869 for( j = B->n; j > 0; j-- )
870 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000871 break;
872
Paul Bakker23986e52011-04-24 08:57:21 +0000873 MPI_CHK( mpi_grow( X, j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000874
875 o = B->p; p = X->p; c = 0;
876
Paul Bakker23986e52011-04-24 08:57:21 +0000877 for( i = 0; i < j; i++, o++, p++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000878 {
879 *p += c; c = ( *p < c );
880 *p += *o; c += ( *p < *o );
881 }
882
883 while( c != 0 )
884 {
885 if( i >= X->n )
886 {
887 MPI_CHK( mpi_grow( X, i + 1 ) );
888 p = X->p + i;
889 }
890
Paul Bakker2d319fd2012-09-16 21:34:26 +0000891 *p += c; c = ( *p < c ); i++; p++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000892 }
893
894cleanup:
895
896 return( ret );
897}
898
899/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100900 * Helper for mpi subtraction
Paul Bakker5121ce52009-01-03 21:22:43 +0000901 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000902static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
Paul Bakker5121ce52009-01-03 21:22:43 +0000903{
Paul Bakker23986e52011-04-24 08:57:21 +0000904 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +0000905 t_uint c, z;
Paul Bakker5121ce52009-01-03 21:22:43 +0000906
907 for( i = c = 0; i < n; i++, s++, d++ )
908 {
909 z = ( *d < c ); *d -= c;
910 c = ( *d < *s ) + z; *d -= *s;
911 }
912
913 while( c != 0 )
914 {
915 z = ( *d < c ); *d -= c;
916 c = z; i++; d++;
917 }
918}
919
920/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100921 * Unsigned subtraction: X = |A| - |B| (HAC 14.9)
Paul Bakker5121ce52009-01-03 21:22:43 +0000922 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000923int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000924{
925 mpi TB;
Paul Bakker23986e52011-04-24 08:57:21 +0000926 int ret;
927 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000928
929 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000930 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000931
Paul Bakker6c591fa2011-05-05 11:49:20 +0000932 mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000933
934 if( X == B )
935 {
936 MPI_CHK( mpi_copy( &TB, B ) );
937 B = &TB;
938 }
939
940 if( X != A )
941 MPI_CHK( mpi_copy( X, A ) );
942
Paul Bakker1ef7a532009-06-20 10:50:55 +0000943 /*
Paul Bakker60b1d102013-10-29 10:02:51 +0100944 * X should always be positive as a result of unsigned subtractions.
Paul Bakker1ef7a532009-06-20 10:50:55 +0000945 */
946 X->s = 1;
947
Paul Bakker5121ce52009-01-03 21:22:43 +0000948 ret = 0;
949
Paul Bakker23986e52011-04-24 08:57:21 +0000950 for( n = B->n; n > 0; n-- )
951 if( B->p[n - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000952 break;
953
Paul Bakker23986e52011-04-24 08:57:21 +0000954 mpi_sub_hlp( n, B->p, X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000955
956cleanup:
957
Paul Bakker6c591fa2011-05-05 11:49:20 +0000958 mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000959
960 return( ret );
961}
962
963/*
964 * Signed addition: X = A + B
965 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000966int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000967{
968 int ret, s = A->s;
969
970 if( A->s * B->s < 0 )
971 {
972 if( mpi_cmp_abs( A, B ) >= 0 )
973 {
974 MPI_CHK( mpi_sub_abs( X, A, B ) );
975 X->s = s;
976 }
977 else
978 {
979 MPI_CHK( mpi_sub_abs( X, B, A ) );
980 X->s = -s;
981 }
982 }
983 else
984 {
985 MPI_CHK( mpi_add_abs( X, A, B ) );
986 X->s = s;
987 }
988
989cleanup:
990
991 return( ret );
992}
993
994/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100995 * Signed subtraction: X = A - B
Paul Bakker5121ce52009-01-03 21:22:43 +0000996 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000997int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000998{
999 int ret, s = A->s;
1000
1001 if( A->s * B->s > 0 )
1002 {
1003 if( mpi_cmp_abs( A, B ) >= 0 )
1004 {
1005 MPI_CHK( mpi_sub_abs( X, A, B ) );
1006 X->s = s;
1007 }
1008 else
1009 {
1010 MPI_CHK( mpi_sub_abs( X, B, A ) );
1011 X->s = -s;
1012 }
1013 }
1014 else
1015 {
1016 MPI_CHK( mpi_add_abs( X, A, B ) );
1017 X->s = s;
1018 }
1019
1020cleanup:
1021
1022 return( ret );
1023}
1024
1025/*
1026 * Signed addition: X = A + b
1027 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001028int mpi_add_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001029{
1030 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001031 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001032
1033 p[0] = ( b < 0 ) ? -b : b;
1034 _B.s = ( b < 0 ) ? -1 : 1;
1035 _B.n = 1;
1036 _B.p = p;
1037
1038 return( mpi_add_mpi( X, A, &_B ) );
1039}
1040
1041/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001042 * Signed subtraction: X = A - b
Paul Bakker5121ce52009-01-03 21:22:43 +00001043 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001044int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001045{
1046 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001047 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001048
1049 p[0] = ( b < 0 ) ? -b : b;
1050 _B.s = ( b < 0 ) ? -1 : 1;
1051 _B.n = 1;
1052 _B.p = p;
1053
1054 return( mpi_sub_mpi( X, A, &_B ) );
1055}
1056
1057/*
1058 * Helper for mpi multiplication
Paul Bakkerfc4f46f2013-06-24 19:23:56 +02001059 */
1060static
1061#if defined(__APPLE__) && defined(__arm__)
1062/*
1063 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1064 * appears to need this to prevent bad ARM code generation at -O3.
1065 */
1066__attribute__ ((noinline))
1067#endif
1068void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001069{
Paul Bakkera755ca12011-04-24 09:11:17 +00001070 t_uint c = 0, t = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001071
1072#if defined(MULADDC_HUIT)
1073 for( ; i >= 8; i -= 8 )
1074 {
1075 MULADDC_INIT
1076 MULADDC_HUIT
1077 MULADDC_STOP
1078 }
1079
1080 for( ; i > 0; i-- )
1081 {
1082 MULADDC_INIT
1083 MULADDC_CORE
1084 MULADDC_STOP
1085 }
1086#else
1087 for( ; i >= 16; i -= 16 )
1088 {
1089 MULADDC_INIT
1090 MULADDC_CORE MULADDC_CORE
1091 MULADDC_CORE MULADDC_CORE
1092 MULADDC_CORE MULADDC_CORE
1093 MULADDC_CORE MULADDC_CORE
1094
1095 MULADDC_CORE MULADDC_CORE
1096 MULADDC_CORE MULADDC_CORE
1097 MULADDC_CORE MULADDC_CORE
1098 MULADDC_CORE MULADDC_CORE
1099 MULADDC_STOP
1100 }
1101
1102 for( ; i >= 8; i -= 8 )
1103 {
1104 MULADDC_INIT
1105 MULADDC_CORE MULADDC_CORE
1106 MULADDC_CORE MULADDC_CORE
1107
1108 MULADDC_CORE MULADDC_CORE
1109 MULADDC_CORE MULADDC_CORE
1110 MULADDC_STOP
1111 }
1112
1113 for( ; i > 0; i-- )
1114 {
1115 MULADDC_INIT
1116 MULADDC_CORE
1117 MULADDC_STOP
1118 }
1119#endif
1120
1121 t++;
1122
1123 do {
1124 *d += c; c = ( *d < c ); d++;
1125 }
1126 while( c != 0 );
1127}
1128
1129/*
1130 * Baseline multiplication: X = A * B (HAC 14.12)
1131 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001132int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001133{
Paul Bakker23986e52011-04-24 08:57:21 +00001134 int ret;
1135 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00001136 mpi TA, TB;
1137
Paul Bakker6c591fa2011-05-05 11:49:20 +00001138 mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001139
1140 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
1141 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
1142
Paul Bakker23986e52011-04-24 08:57:21 +00001143 for( i = A->n; i > 0; i-- )
1144 if( A->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001145 break;
1146
Paul Bakker23986e52011-04-24 08:57:21 +00001147 for( j = B->n; j > 0; j-- )
1148 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001149 break;
1150
Paul Bakker23986e52011-04-24 08:57:21 +00001151 MPI_CHK( mpi_grow( X, i + j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001152 MPI_CHK( mpi_lset( X, 0 ) );
1153
Paul Bakker23986e52011-04-24 08:57:21 +00001154 for( i++; j > 0; j-- )
1155 mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001156
1157 X->s = A->s * B->s;
1158
1159cleanup:
1160
Paul Bakker6c591fa2011-05-05 11:49:20 +00001161 mpi_free( &TB ); mpi_free( &TA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001162
1163 return( ret );
1164}
1165
1166/*
1167 * Baseline multiplication: X = A * b
1168 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001169int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001170{
1171 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001172 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001173
1174 _B.s = 1;
1175 _B.n = 1;
1176 _B.p = p;
1177 p[0] = b;
1178
1179 return( mpi_mul_mpi( X, A, &_B ) );
1180}
1181
1182/*
1183 * Division by mpi: A = Q * B + R (HAC 14.20)
1184 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001185int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001186{
Paul Bakker23986e52011-04-24 08:57:21 +00001187 int ret;
1188 size_t i, n, t, k;
Paul Bakker5121ce52009-01-03 21:22:43 +00001189 mpi X, Y, Z, T1, T2;
1190
1191 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001192 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001193
Paul Bakker6c591fa2011-05-05 11:49:20 +00001194 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
1195 mpi_init( &T1 ); mpi_init( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001196
1197 if( mpi_cmp_abs( A, B ) < 0 )
1198 {
1199 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1200 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1201 return( 0 );
1202 }
1203
1204 MPI_CHK( mpi_copy( &X, A ) );
1205 MPI_CHK( mpi_copy( &Y, B ) );
1206 X.s = Y.s = 1;
1207
1208 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1209 MPI_CHK( mpi_lset( &Z, 0 ) );
1210 MPI_CHK( mpi_grow( &T1, 2 ) );
1211 MPI_CHK( mpi_grow( &T2, 3 ) );
1212
1213 k = mpi_msb( &Y ) % biL;
Paul Bakkerf9688572011-05-05 10:00:45 +00001214 if( k < biL - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001215 {
1216 k = biL - 1 - k;
1217 MPI_CHK( mpi_shift_l( &X, k ) );
1218 MPI_CHK( mpi_shift_l( &Y, k ) );
1219 }
1220 else k = 0;
1221
1222 n = X.n - 1;
1223 t = Y.n - 1;
Paul Bakkerc110d022012-10-19 12:15:08 +00001224 MPI_CHK( mpi_shift_l( &Y, biL * (n - t) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001225
1226 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1227 {
1228 Z.p[n - t]++;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001229 MPI_CHK( mpi_sub_mpi( &X, &X, &Y ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001230 }
Paul Bakker6ea1a952013-12-31 11:16:03 +01001231 MPI_CHK( mpi_shift_r( &Y, biL * (n - t) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001232
1233 for( i = n; i > t ; i-- )
1234 {
1235 if( X.p[i] >= Y.p[t] )
1236 Z.p[i - t - 1] = ~0;
1237 else
1238 {
Manuel Pégourié-Gonnardbb8661e2014-03-14 09:21:20 +01001239 /*
Manuel Pégourié-Gonnard2eea2922014-03-14 18:23:26 +01001240 * The version of Clang shipped by Apple with Mavericks around
1241 * 2014-03 can't handle 128-bit division properly. Disable
1242 * 128-bits division for this version. Let's be optimistic and
1243 * assume it'll be fixed in the next minor version (next
1244 * patchlevel is probably a bit too optimistic).
Manuel Pégourié-Gonnardbb8661e2014-03-14 09:21:20 +01001245 */
Manuel Pégourié-Gonnard2eea2922014-03-14 18:23:26 +01001246#if defined(POLARSSL_HAVE_UDBL) && \
1247 ! ( defined(__x86_64__) && defined(__APPLE__) && \
1248 defined(__clang_major__) && __clang_major__ == 5 && \
1249 defined(__clang_minor__) && __clang_minor__ == 0 )
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001250 t_udbl r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001251
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001252 r = (t_udbl) X.p[i] << biL;
1253 r |= (t_udbl) X.p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001254 r /= Y.p[t];
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001255 if( r > ((t_udbl) 1 << biL) - 1)
1256 r = ((t_udbl) 1 << biL) - 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001257
Paul Bakkera755ca12011-04-24 09:11:17 +00001258 Z.p[i - t - 1] = (t_uint) r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001259#else
1260 /*
1261 * __udiv_qrnnd_c, from gmp/longlong.h
1262 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001263 t_uint q0, q1, r0, r1;
1264 t_uint d0, d1, d, m;
Paul Bakker5121ce52009-01-03 21:22:43 +00001265
1266 d = Y.p[t];
1267 d0 = ( d << biH ) >> biH;
1268 d1 = ( d >> biH );
1269
1270 q1 = X.p[i] / d1;
1271 r1 = X.p[i] - d1 * q1;
1272 r1 <<= biH;
1273 r1 |= ( X.p[i - 1] >> biH );
1274
1275 m = q1 * d0;
1276 if( r1 < m )
1277 {
1278 q1--, r1 += d;
1279 while( r1 >= d && r1 < m )
1280 q1--, r1 += d;
1281 }
1282 r1 -= m;
1283
1284 q0 = r1 / d1;
1285 r0 = r1 - d1 * q0;
1286 r0 <<= biH;
1287 r0 |= ( X.p[i - 1] << biH ) >> biH;
1288
1289 m = q0 * d0;
1290 if( r0 < m )
1291 {
1292 q0--, r0 += d;
1293 while( r0 >= d && r0 < m )
1294 q0--, r0 += d;
1295 }
1296 r0 -= m;
1297
1298 Z.p[i - t - 1] = ( q1 << biH ) | q0;
1299#endif
1300 }
1301
1302 Z.p[i - t - 1]++;
1303 do
1304 {
1305 Z.p[i - t - 1]--;
1306
1307 MPI_CHK( mpi_lset( &T1, 0 ) );
1308 T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
1309 T1.p[1] = Y.p[t];
1310 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1311
1312 MPI_CHK( mpi_lset( &T2, 0 ) );
1313 T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
1314 T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
1315 T2.p[2] = X.p[i];
1316 }
1317 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1318
1319 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1320 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1321 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1322
1323 if( mpi_cmp_int( &X, 0 ) < 0 )
1324 {
1325 MPI_CHK( mpi_copy( &T1, &Y ) );
1326 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1327 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1328 Z.p[i - t - 1]--;
1329 }
1330 }
1331
1332 if( Q != NULL )
1333 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001334 MPI_CHK( mpi_copy( Q, &Z ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001335 Q->s = A->s * B->s;
1336 }
1337
1338 if( R != NULL )
1339 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001340 MPI_CHK( mpi_shift_r( &X, k ) );
Paul Bakkerf02c5642012-11-13 10:25:21 +00001341 X.s = A->s;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001342 MPI_CHK( mpi_copy( R, &X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001343
Paul Bakker5121ce52009-01-03 21:22:43 +00001344 if( mpi_cmp_int( R, 0 ) == 0 )
1345 R->s = 1;
1346 }
1347
1348cleanup:
1349
Paul Bakker6c591fa2011-05-05 11:49:20 +00001350 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
1351 mpi_free( &T1 ); mpi_free( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001352
1353 return( ret );
1354}
1355
1356/*
1357 * Division by int: A = Q * b + R
Paul Bakker5121ce52009-01-03 21:22:43 +00001358 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001359int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001360{
1361 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001362 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001363
1364 p[0] = ( b < 0 ) ? -b : b;
1365 _B.s = ( b < 0 ) ? -1 : 1;
1366 _B.n = 1;
1367 _B.p = p;
1368
1369 return( mpi_div_mpi( Q, R, A, &_B ) );
1370}
1371
1372/*
1373 * Modulo: R = A mod B
1374 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001375int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001376{
1377 int ret;
1378
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001379 if( mpi_cmp_int( B, 0 ) < 0 )
1380 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
1381
Paul Bakker5121ce52009-01-03 21:22:43 +00001382 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1383
1384 while( mpi_cmp_int( R, 0 ) < 0 )
1385 MPI_CHK( mpi_add_mpi( R, R, B ) );
1386
1387 while( mpi_cmp_mpi( R, B ) >= 0 )
1388 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1389
1390cleanup:
1391
1392 return( ret );
1393}
1394
1395/*
1396 * Modulo: r = A mod b
1397 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001398int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001399{
Paul Bakker23986e52011-04-24 08:57:21 +00001400 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +00001401 t_uint x, y, z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001402
1403 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001404 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001405
1406 if( b < 0 )
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001407 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001408
1409 /*
1410 * handle trivial cases
1411 */
1412 if( b == 1 )
1413 {
1414 *r = 0;
1415 return( 0 );
1416 }
1417
1418 if( b == 2 )
1419 {
1420 *r = A->p[0] & 1;
1421 return( 0 );
1422 }
1423
1424 /*
1425 * general case
1426 */
Paul Bakker23986e52011-04-24 08:57:21 +00001427 for( i = A->n, y = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001428 {
Paul Bakker23986e52011-04-24 08:57:21 +00001429 x = A->p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001430 y = ( y << biH ) | ( x >> biH );
1431 z = y / b;
1432 y -= z * b;
1433
1434 x <<= biH;
1435 y = ( y << biH ) | ( x >> biH );
1436 z = y / b;
1437 y -= z * b;
1438 }
1439
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001440 /*
1441 * If A is negative, then the current y represents a negative value.
1442 * Flipping it to the positive side.
1443 */
1444 if( A->s < 0 && y != 0 )
1445 y = b - y;
1446
Paul Bakker5121ce52009-01-03 21:22:43 +00001447 *r = y;
1448
1449 return( 0 );
1450}
1451
1452/*
1453 * Fast Montgomery initialization (thanks to Tom St Denis)
1454 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001455static void mpi_montg_init( t_uint *mm, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001456{
Paul Bakkera755ca12011-04-24 09:11:17 +00001457 t_uint x, m0 = N->p[0];
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001458 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001459
1460 x = m0;
1461 x += ( ( m0 + 2 ) & 4 ) << 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001462
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001463 for( i = biL; i >= 8; i /= 2 )
1464 x *= ( 2 - ( m0 * x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001465
1466 *mm = ~x + 1;
1467}
1468
1469/*
1470 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1471 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001472static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001473{
Paul Bakker23986e52011-04-24 08:57:21 +00001474 size_t i, n, m;
Paul Bakkera755ca12011-04-24 09:11:17 +00001475 t_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00001476
1477 memset( T->p, 0, T->n * ciL );
1478
1479 d = T->p;
1480 n = N->n;
1481 m = ( B->n < n ) ? B->n : n;
1482
1483 for( i = 0; i < n; i++ )
1484 {
1485 /*
1486 * T = (T + u0*B + u1*N) / 2^biL
1487 */
1488 u0 = A->p[i];
1489 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1490
1491 mpi_mul_hlp( m, B->p, d, u0 );
1492 mpi_mul_hlp( n, N->p, d, u1 );
1493
1494 *d++ = u0; d[n + 1] = 0;
1495 }
1496
1497 memcpy( A->p, d, (n + 1) * ciL );
1498
1499 if( mpi_cmp_abs( A, N ) >= 0 )
1500 mpi_sub_hlp( n, N->p, A->p );
1501 else
1502 /* prevent timing attacks */
1503 mpi_sub_hlp( n, A->p, T->p );
1504}
1505
1506/*
1507 * Montgomery reduction: A = A * R^-1 mod N
1508 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001509static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001510{
Paul Bakkera755ca12011-04-24 09:11:17 +00001511 t_uint z = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001512 mpi U;
1513
Paul Bakker8ddb6452013-02-27 14:56:33 +01001514 U.n = U.s = (int) z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001515 U.p = &z;
1516
1517 mpi_montmul( A, &U, N, mm, T );
1518}
1519
1520/*
1521 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1522 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001523int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00001524{
Paul Bakker23986e52011-04-24 08:57:21 +00001525 int ret;
1526 size_t wbits, wsize, one = 1;
1527 size_t i, j, nblimbs;
1528 size_t bufsize, nbits;
Paul Bakkera755ca12011-04-24 09:11:17 +00001529 t_uint ei, mm, state;
Paul Bakkerf6198c12012-05-16 08:02:29 +00001530 mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos;
1531 int neg;
Paul Bakker5121ce52009-01-03 21:22:43 +00001532
1533 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001534 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001535
Paul Bakkerf6198c12012-05-16 08:02:29 +00001536 if( mpi_cmp_int( E, 0 ) < 0 )
1537 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
1538
1539 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001540 * Init temps and window size
1541 */
1542 mpi_montg_init( &mm, N );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001543 mpi_init( &RR ); mpi_init( &T );
Manuel Pégourié-Gonnardfd6a1912014-01-18 19:05:23 +01001544 mpi_init( &Apos );
Paul Bakker5121ce52009-01-03 21:22:43 +00001545 memset( W, 0, sizeof( W ) );
1546
1547 i = mpi_msb( E );
1548
1549 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1550 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1551
Paul Bakkerb6d5f082011-11-25 11:52:11 +00001552 if( wsize > POLARSSL_MPI_WINDOW_SIZE )
1553 wsize = POLARSSL_MPI_WINDOW_SIZE;
1554
Paul Bakker5121ce52009-01-03 21:22:43 +00001555 j = N->n + 1;
1556 MPI_CHK( mpi_grow( X, j ) );
1557 MPI_CHK( mpi_grow( &W[1], j ) );
1558 MPI_CHK( mpi_grow( &T, j * 2 ) );
1559
1560 /*
Paul Bakker50546922012-05-19 08:40:49 +00001561 * Compensate for negative A (and correct at the end)
1562 */
1563 neg = ( A->s == -1 );
Paul Bakker50546922012-05-19 08:40:49 +00001564 if( neg )
1565 {
1566 MPI_CHK( mpi_copy( &Apos, A ) );
1567 Apos.s = 1;
1568 A = &Apos;
1569 }
1570
1571 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001572 * If 1st call, pre-compute R^2 mod N
1573 */
1574 if( _RR == NULL || _RR->p == NULL )
1575 {
1576 MPI_CHK( mpi_lset( &RR, 1 ) );
1577 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1578 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1579
1580 if( _RR != NULL )
1581 memcpy( _RR, &RR, sizeof( mpi ) );
1582 }
1583 else
1584 memcpy( &RR, _RR, sizeof( mpi ) );
1585
1586 /*
1587 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1588 */
1589 if( mpi_cmp_mpi( A, N ) >= 0 )
Paul Bakkerc2024f42014-01-23 20:38:35 +01001590 MPI_CHK( mpi_mod_mpi( &W[1], A, N ) );
1591 else
1592 MPI_CHK( mpi_copy( &W[1], A ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001593
1594 mpi_montmul( &W[1], &RR, N, mm, &T );
1595
1596 /*
1597 * X = R^2 * R^-1 mod N = R mod N
1598 */
1599 MPI_CHK( mpi_copy( X, &RR ) );
1600 mpi_montred( X, N, mm, &T );
1601
1602 if( wsize > 1 )
1603 {
1604 /*
1605 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1606 */
Paul Bakker23986e52011-04-24 08:57:21 +00001607 j = one << (wsize - 1);
Paul Bakker5121ce52009-01-03 21:22:43 +00001608
1609 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1610 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1611
1612 for( i = 0; i < wsize - 1; i++ )
1613 mpi_montmul( &W[j], &W[j], N, mm, &T );
Paul Bakker0d7702c2013-10-29 16:18:35 +01001614
Paul Bakker5121ce52009-01-03 21:22:43 +00001615 /*
1616 * W[i] = W[i - 1] * W[1]
1617 */
Paul Bakker23986e52011-04-24 08:57:21 +00001618 for( i = j + 1; i < (one << wsize); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001619 {
1620 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1621 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1622
1623 mpi_montmul( &W[i], &W[1], N, mm, &T );
1624 }
1625 }
1626
1627 nblimbs = E->n;
1628 bufsize = 0;
1629 nbits = 0;
1630 wbits = 0;
1631 state = 0;
1632
1633 while( 1 )
1634 {
1635 if( bufsize == 0 )
1636 {
Paul Bakker0d7702c2013-10-29 16:18:35 +01001637 if( nblimbs == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001638 break;
1639
Paul Bakker0d7702c2013-10-29 16:18:35 +01001640 nblimbs--;
1641
Paul Bakkera755ca12011-04-24 09:11:17 +00001642 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001643 }
1644
1645 bufsize--;
1646
1647 ei = (E->p[nblimbs] >> bufsize) & 1;
1648
1649 /*
1650 * skip leading 0s
1651 */
1652 if( ei == 0 && state == 0 )
1653 continue;
1654
1655 if( ei == 0 && state == 1 )
1656 {
1657 /*
1658 * out of window, square X
1659 */
1660 mpi_montmul( X, X, N, mm, &T );
1661 continue;
1662 }
1663
1664 /*
1665 * add ei to current window
1666 */
1667 state = 2;
1668
1669 nbits++;
1670 wbits |= (ei << (wsize - nbits));
1671
1672 if( nbits == wsize )
1673 {
1674 /*
1675 * X = X^wsize R^-1 mod N
1676 */
1677 for( i = 0; i < wsize; i++ )
1678 mpi_montmul( X, X, N, mm, &T );
1679
1680 /*
1681 * X = X * W[wbits] R^-1 mod N
1682 */
1683 mpi_montmul( X, &W[wbits], N, mm, &T );
1684
1685 state--;
1686 nbits = 0;
1687 wbits = 0;
1688 }
1689 }
1690
1691 /*
1692 * process the remaining bits
1693 */
1694 for( i = 0; i < nbits; i++ )
1695 {
1696 mpi_montmul( X, X, N, mm, &T );
1697
1698 wbits <<= 1;
1699
Paul Bakker23986e52011-04-24 08:57:21 +00001700 if( (wbits & (one << wsize)) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001701 mpi_montmul( X, &W[1], N, mm, &T );
1702 }
1703
1704 /*
1705 * X = A^E * R * R^-1 mod N = A^E mod N
1706 */
1707 mpi_montred( X, N, mm, &T );
1708
Paul Bakkerf6198c12012-05-16 08:02:29 +00001709 if( neg )
1710 {
1711 X->s = -1;
Paul Bakkerc2024f42014-01-23 20:38:35 +01001712 MPI_CHK( mpi_add_mpi( X, N, X ) );
Paul Bakkerf6198c12012-05-16 08:02:29 +00001713 }
1714
Paul Bakker5121ce52009-01-03 21:22:43 +00001715cleanup:
1716
Paul Bakker23986e52011-04-24 08:57:21 +00001717 for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001718 mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001719
Paul Bakkerf6198c12012-05-16 08:02:29 +00001720 mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001721
Paul Bakker75a28602014-03-31 12:08:17 +02001722 if( _RR == NULL || _RR->p == NULL )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001723 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001724
1725 return( ret );
1726}
1727
Paul Bakker5121ce52009-01-03 21:22:43 +00001728/*
1729 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1730 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001731int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001732{
Paul Bakker23986e52011-04-24 08:57:21 +00001733 int ret;
1734 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001735 mpi TG, TA, TB;
1736
Paul Bakker6c591fa2011-05-05 11:49:20 +00001737 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001738
Paul Bakker5121ce52009-01-03 21:22:43 +00001739 MPI_CHK( mpi_copy( &TA, A ) );
1740 MPI_CHK( mpi_copy( &TB, B ) );
1741
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001742 lz = mpi_lsb( &TA );
1743 lzt = mpi_lsb( &TB );
1744
1745 if ( lzt < lz )
1746 lz = lzt;
1747
1748 MPI_CHK( mpi_shift_r( &TA, lz ) );
1749 MPI_CHK( mpi_shift_r( &TB, lz ) );
1750
Paul Bakker5121ce52009-01-03 21:22:43 +00001751 TA.s = TB.s = 1;
1752
1753 while( mpi_cmp_int( &TA, 0 ) != 0 )
1754 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001755 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1756 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001757
1758 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1759 {
1760 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1761 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1762 }
1763 else
1764 {
1765 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1766 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1767 }
1768 }
1769
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001770 MPI_CHK( mpi_shift_l( &TB, lz ) );
1771 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001772
1773cleanup:
1774
Paul Bakker6c591fa2011-05-05 11:49:20 +00001775 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001776
1777 return( ret );
1778}
1779
Paul Bakker33dc46b2014-04-30 16:11:39 +02001780/*
1781 * Fill X with size bytes of random.
1782 *
1783 * Use a temporary bytes representation to make sure the result is the same
1784 * regardless of the platform endianness (usefull when f_rng is actually
1785 * deterministic, eg for tests).
1786 */
Paul Bakkera3d195c2011-11-27 21:07:34 +00001787int mpi_fill_random( mpi *X, size_t size,
1788 int (*f_rng)(void *, unsigned char *, size_t),
1789 void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001790{
Paul Bakker23986e52011-04-24 08:57:21 +00001791 int ret;
Paul Bakker33dc46b2014-04-30 16:11:39 +02001792 unsigned char buf[POLARSSL_MPI_MAX_SIZE];
1793
1794 if( size > POLARSSL_MPI_MAX_SIZE )
1795 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker287781a2011-03-26 13:18:49 +00001796
Paul Bakker39dfdac2012-02-12 17:17:27 +00001797 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( size ) ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001798 MPI_CHK( mpi_lset( X, 0 ) );
1799
Paul Bakker33dc46b2014-04-30 16:11:39 +02001800 MPI_CHK( f_rng( p_rng, buf, size ) );
1801 MPI_CHK( mpi_read_binary( X, buf, size ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001802
1803cleanup:
1804 return( ret );
1805}
1806
Paul Bakker5121ce52009-01-03 21:22:43 +00001807/*
1808 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1809 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001810int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001811{
1812 int ret;
1813 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1814
1815 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001816 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001817
Paul Bakker6c591fa2011-05-05 11:49:20 +00001818 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1819 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1820 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001821
1822 MPI_CHK( mpi_gcd( &G, A, N ) );
1823
1824 if( mpi_cmp_int( &G, 1 ) != 0 )
1825 {
Paul Bakker40e46942009-01-03 21:51:57 +00001826 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001827 goto cleanup;
1828 }
1829
1830 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1831 MPI_CHK( mpi_copy( &TU, &TA ) );
1832 MPI_CHK( mpi_copy( &TB, N ) );
1833 MPI_CHK( mpi_copy( &TV, N ) );
1834
1835 MPI_CHK( mpi_lset( &U1, 1 ) );
1836 MPI_CHK( mpi_lset( &U2, 0 ) );
1837 MPI_CHK( mpi_lset( &V1, 0 ) );
1838 MPI_CHK( mpi_lset( &V2, 1 ) );
1839
1840 do
1841 {
1842 while( ( TU.p[0] & 1 ) == 0 )
1843 {
1844 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1845
1846 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1847 {
1848 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1849 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1850 }
1851
1852 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1853 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1854 }
1855
1856 while( ( TV.p[0] & 1 ) == 0 )
1857 {
1858 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1859
1860 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1861 {
1862 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1863 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1864 }
1865
1866 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1867 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1868 }
1869
1870 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1871 {
1872 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1873 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1874 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1875 }
1876 else
1877 {
1878 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1879 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1880 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1881 }
1882 }
1883 while( mpi_cmp_int( &TU, 0 ) != 0 );
1884
1885 while( mpi_cmp_int( &V1, 0 ) < 0 )
1886 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1887
1888 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1889 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1890
1891 MPI_CHK( mpi_copy( X, &V1 ) );
1892
1893cleanup:
1894
Paul Bakker6c591fa2011-05-05 11:49:20 +00001895 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1896 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1897 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001898
1899 return( ret );
1900}
1901
Paul Bakkerd9374b02012-11-02 11:02:58 +00001902#if defined(POLARSSL_GENPRIME)
1903
Paul Bakker5121ce52009-01-03 21:22:43 +00001904static const int small_prime[] =
1905{
1906 3, 5, 7, 11, 13, 17, 19, 23,
1907 29, 31, 37, 41, 43, 47, 53, 59,
1908 61, 67, 71, 73, 79, 83, 89, 97,
1909 101, 103, 107, 109, 113, 127, 131, 137,
1910 139, 149, 151, 157, 163, 167, 173, 179,
1911 181, 191, 193, 197, 199, 211, 223, 227,
1912 229, 233, 239, 241, 251, 257, 263, 269,
1913 271, 277, 281, 283, 293, 307, 311, 313,
1914 317, 331, 337, 347, 349, 353, 359, 367,
1915 373, 379, 383, 389, 397, 401, 409, 419,
1916 421, 431, 433, 439, 443, 449, 457, 461,
1917 463, 467, 479, 487, 491, 499, 503, 509,
1918 521, 523, 541, 547, 557, 563, 569, 571,
1919 577, 587, 593, 599, 601, 607, 613, 617,
1920 619, 631, 641, 643, 647, 653, 659, 661,
1921 673, 677, 683, 691, 701, 709, 719, 727,
1922 733, 739, 743, 751, 757, 761, 769, 773,
1923 787, 797, 809, 811, 821, 823, 827, 829,
1924 839, 853, 857, 859, 863, 877, 881, 883,
1925 887, 907, 911, 919, 929, 937, 941, 947,
1926 953, 967, 971, 977, 983, 991, 997, -103
1927};
1928
1929/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001930 * Small divisors test (X must be positive)
1931 *
1932 * Return values:
1933 * 0: no small factor (possible prime, more tests needed)
1934 * 1: certain prime
1935 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
1936 * other negative: error
Paul Bakker5121ce52009-01-03 21:22:43 +00001937 */
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001938static int mpi_check_small_factors( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +00001939{
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001940 int ret = 0;
1941 size_t i;
1942 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001943
Paul Bakker5121ce52009-01-03 21:22:43 +00001944 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001945 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001946
1947 for( i = 0; small_prime[i] > 0; i++ )
1948 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001949 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001950 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001951
1952 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1953
1954 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001955 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001956 }
1957
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001958cleanup:
1959 return( ret );
1960}
1961
1962/*
1963 * Miller-Rabin pseudo-primality test (HAC 4.24)
1964 */
1965static int mpi_miller_rabin( const mpi *X,
1966 int (*f_rng)(void *, unsigned char *, size_t),
1967 void *p_rng )
1968{
1969 int ret;
1970 size_t i, j, n, s;
1971 mpi W, R, T, A, RR;
1972
1973 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1974 mpi_init( &RR );
1975
Paul Bakker5121ce52009-01-03 21:22:43 +00001976 /*
1977 * W = |X| - 1
1978 * R = W >> lsb( W )
1979 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001980 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001981 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001982 MPI_CHK( mpi_copy( &R, &W ) );
1983 MPI_CHK( mpi_shift_r( &R, s ) );
1984
1985 i = mpi_msb( X );
1986 /*
1987 * HAC, table 4.4
1988 */
1989 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1990 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1991 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1992
1993 for( i = 0; i < n; i++ )
1994 {
1995 /*
1996 * pick a random A, 1 < A < |X| - 1
1997 */
Paul Bakker901c6562012-04-20 13:25:38 +00001998 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001999
Paul Bakkerb94081b2011-01-05 15:53:06 +00002000 if( mpi_cmp_mpi( &A, &W ) >= 0 )
2001 {
2002 j = mpi_msb( &A ) - mpi_msb( &W );
2003 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
2004 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002005 A.p[0] |= 3;
2006
2007 /*
2008 * A = A^R mod |X|
2009 */
2010 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
2011
2012 if( mpi_cmp_mpi( &A, &W ) == 0 ||
2013 mpi_cmp_int( &A, 1 ) == 0 )
2014 continue;
2015
2016 j = 1;
2017 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
2018 {
2019 /*
2020 * A = A * A mod |X|
2021 */
2022 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
2023 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
2024
2025 if( mpi_cmp_int( &A, 1 ) == 0 )
2026 break;
2027
2028 j++;
2029 }
2030
2031 /*
2032 * not prime if A != |X| - 1 or A == 1
2033 */
2034 if( mpi_cmp_mpi( &A, &W ) != 0 ||
2035 mpi_cmp_int( &A, 1 ) == 0 )
2036 {
Paul Bakker40e46942009-01-03 21:51:57 +00002037 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002038 break;
2039 }
2040 }
2041
2042cleanup:
Paul Bakker6c591fa2011-05-05 11:49:20 +00002043 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
2044 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002045
2046 return( ret );
2047}
2048
2049/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002050 * Pseudo-primality test: small factors, then Miller-Rabin
2051 */
Paul Bakker45f457d2013-11-25 14:26:52 +01002052int mpi_is_prime( mpi *X,
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002053 int (*f_rng)(void *, unsigned char *, size_t),
2054 void *p_rng )
2055{
2056 int ret;
2057 const mpi XX = { 1, X->n, X->p }; /* Abs(X) */
2058
2059 if( mpi_cmp_int( &XX, 0 ) == 0 ||
2060 mpi_cmp_int( &XX, 1 ) == 0 )
2061 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
2062
2063 if( mpi_cmp_int( &XX, 2 ) == 0 )
2064 return( 0 );
2065
2066 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2067 {
2068 if( ret == 1 )
2069 return( 0 );
2070
2071 return( ret );
2072 }
2073
2074 return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
2075}
2076
2077/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002078 * Prime number generation
2079 */
Paul Bakker23986e52011-04-24 08:57:21 +00002080int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002081 int (*f_rng)(void *, unsigned char *, size_t),
2082 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +00002083{
Paul Bakker23986e52011-04-24 08:57:21 +00002084 int ret;
2085 size_t k, n;
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002086 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002087 mpi Y;
2088
Paul Bakkerfe3256e2011-11-25 12:11:43 +00002089 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
Paul Bakker40e46942009-01-03 21:51:57 +00002090 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002091
Paul Bakker6c591fa2011-05-05 11:49:20 +00002092 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002093
2094 n = BITS_TO_LIMBS( nbits );
2095
Paul Bakker901c6562012-04-20 13:25:38 +00002096 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002097
2098 k = mpi_msb( X );
2099 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
2100 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
2101
2102 X->p[0] |= 3;
2103
2104 if( dh_flag == 0 )
2105 {
2106 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
2107 {
Paul Bakker40e46942009-01-03 21:51:57 +00002108 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002109 goto cleanup;
2110
2111 MPI_CHK( mpi_add_int( X, X, 2 ) );
2112 }
2113 }
2114 else
2115 {
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002116 /*
2117 * An necessary condition for Y and X = 2Y + 1 to be prime
2118 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2119 * Make sure it is satisfied, while keeping X = 3 mod 4
2120 */
2121 MPI_CHK( mpi_mod_int( &r, X, 3 ) );
2122 if( r == 0 )
2123 MPI_CHK( mpi_add_int( X, X, 8 ) );
2124 else if( r == 1 )
2125 MPI_CHK( mpi_add_int( X, X, 4 ) );
2126
2127 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2128 MPI_CHK( mpi_copy( &Y, X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002129 MPI_CHK( mpi_shift_r( &Y, 1 ) );
2130
2131 while( 1 )
2132 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002133 /*
2134 * First, check small factors for X and Y
2135 * before doing Miller-Rabin on any of them
2136 */
2137 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2138 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2139 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
2140 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002141 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002142 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002143 }
2144
Paul Bakker40e46942009-01-03 21:51:57 +00002145 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002146 goto cleanup;
2147
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002148 /*
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002149 * Next candidates. We want to preserve Y = (X-1) / 2 and
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002150 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2151 * so up Y by 6 and X by 12.
2152 */
2153 MPI_CHK( mpi_add_int( X, X, 12 ) );
2154 MPI_CHK( mpi_add_int( &Y, &Y, 6 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002155 }
2156 }
2157
2158cleanup:
2159
Paul Bakker6c591fa2011-05-05 11:49:20 +00002160 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002161
2162 return( ret );
2163}
2164
Manuel Pégourié-Gonnarddf0142b2013-08-22 18:29:07 +02002165#endif /* POLARSSL_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00002166
Paul Bakker40e46942009-01-03 21:51:57 +00002167#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002168
Paul Bakker23986e52011-04-24 08:57:21 +00002169#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002170
2171static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2172{
2173 { 693, 609, 21 },
2174 { 1764, 868, 28 },
2175 { 768454923, 542167814, 1 }
2176};
2177
Paul Bakker5121ce52009-01-03 21:22:43 +00002178/*
2179 * Checkup routine
2180 */
2181int mpi_self_test( int verbose )
2182{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002183 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00002184 mpi A, E, N, X, Y, U, V;
2185
Paul Bakker6c591fa2011-05-05 11:49:20 +00002186 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
2187 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002188
2189 MPI_CHK( mpi_read_string( &A, 16,
2190 "EFE021C2645FD1DC586E69184AF4A31E" \
2191 "D5F53E93B5F123FA41680867BA110131" \
2192 "944FE7952E2517337780CB0DB80E61AA" \
2193 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2194
2195 MPI_CHK( mpi_read_string( &E, 16,
2196 "B2E7EFD37075B9F03FF989C7C5051C20" \
2197 "34D2A323810251127E7BF8625A4F49A5" \
2198 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2199 "5B5C25763222FEFCCFC38B832366C29E" ) );
2200
2201 MPI_CHK( mpi_read_string( &N, 16,
2202 "0066A198186C18C10B2F5ED9B522752A" \
2203 "9830B69916E535C8F047518A889A43A5" \
2204 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2205
2206 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
2207
2208 MPI_CHK( mpi_read_string( &U, 16,
2209 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2210 "9E857EA95A03512E2BAE7391688D264A" \
2211 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2212 "8001B72E848A38CAE1C65F78E56ABDEF" \
2213 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2214 "ECF677152EF804370C1A305CAF3B5BF1" \
2215 "30879B56C61DE584A0F53A2447A51E" ) );
2216
2217 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002218 polarssl_printf( " MPI test #1 (mul_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002219
2220 if( mpi_cmp_mpi( &X, &U ) != 0 )
2221 {
2222 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002223 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002224
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002225 ret = 1;
2226 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002227 }
2228
2229 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002230 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002231
2232 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
2233
2234 MPI_CHK( mpi_read_string( &U, 16,
2235 "256567336059E52CAE22925474705F39A94" ) );
2236
2237 MPI_CHK( mpi_read_string( &V, 16,
2238 "6613F26162223DF488E9CD48CC132C7A" \
2239 "0AC93C701B001B092E4E5B9F73BCD27B" \
2240 "9EE50D0657C77F374E903CDFA4C642" ) );
2241
2242 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002243 polarssl_printf( " MPI test #2 (div_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002244
2245 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2246 mpi_cmp_mpi( &Y, &V ) != 0 )
2247 {
2248 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002249 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002250
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002251 ret = 1;
2252 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002253 }
2254
2255 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002256 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002257
2258 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2259
2260 MPI_CHK( mpi_read_string( &U, 16,
2261 "36E139AEA55215609D2816998ED020BB" \
2262 "BD96C37890F65171D948E9BC7CBAA4D9" \
2263 "325D24D6A3C12710F10A09FA08AB87" ) );
2264
2265 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002266 polarssl_printf( " MPI test #3 (exp_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002267
2268 if( mpi_cmp_mpi( &X, &U ) != 0 )
2269 {
2270 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002271 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002272
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002273 ret = 1;
2274 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002275 }
2276
2277 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002278 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002279
2280 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2281
2282 MPI_CHK( mpi_read_string( &U, 16,
2283 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2284 "C3DBA76456363A10869622EAC2DD84EC" \
2285 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2286
2287 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002288 polarssl_printf( " MPI test #4 (inv_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002289
2290 if( mpi_cmp_mpi( &X, &U ) != 0 )
2291 {
2292 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002293 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002294
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002295 ret = 1;
2296 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002297 }
2298
2299 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002300 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002301
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002302 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002303 polarssl_printf( " MPI test #5 (simple gcd): " );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002304
2305 for ( i = 0; i < GCD_PAIR_COUNT; i++)
2306 {
2307 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002308 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002309
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002310 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002311
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002312 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2313 {
2314 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002315 polarssl_printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002316
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002317 ret = 1;
2318 goto cleanup;
2319 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002320 }
2321
2322 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002323 polarssl_printf( "passed\n" );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002324
Paul Bakker5121ce52009-01-03 21:22:43 +00002325cleanup:
2326
2327 if( ret != 0 && verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002328 polarssl_printf( "Unexpected error, return code = %08X\n", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002329
Paul Bakker6c591fa2011-05-05 11:49:20 +00002330 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2331 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002332
2333 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002334 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002335
2336 return( ret );
2337}
2338
2339#endif
2340
2341#endif