blob: b9175f6a33693fcbac4845ad8d10016b93cb1e29 [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 Bakker33dc46b2014-04-30 16:11:39 +02001797 MPI_CHK( f_rng( p_rng, buf, size ) );
1798 MPI_CHK( mpi_read_binary( X, buf, size ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001799
1800cleanup:
1801 return( ret );
1802}
1803
Paul Bakker5121ce52009-01-03 21:22:43 +00001804/*
1805 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1806 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001807int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001808{
1809 int ret;
1810 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1811
1812 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001813 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001814
Paul Bakker6c591fa2011-05-05 11:49:20 +00001815 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1816 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1817 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001818
1819 MPI_CHK( mpi_gcd( &G, A, N ) );
1820
1821 if( mpi_cmp_int( &G, 1 ) != 0 )
1822 {
Paul Bakker40e46942009-01-03 21:51:57 +00001823 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001824 goto cleanup;
1825 }
1826
1827 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1828 MPI_CHK( mpi_copy( &TU, &TA ) );
1829 MPI_CHK( mpi_copy( &TB, N ) );
1830 MPI_CHK( mpi_copy( &TV, N ) );
1831
1832 MPI_CHK( mpi_lset( &U1, 1 ) );
1833 MPI_CHK( mpi_lset( &U2, 0 ) );
1834 MPI_CHK( mpi_lset( &V1, 0 ) );
1835 MPI_CHK( mpi_lset( &V2, 1 ) );
1836
1837 do
1838 {
1839 while( ( TU.p[0] & 1 ) == 0 )
1840 {
1841 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1842
1843 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1844 {
1845 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1846 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1847 }
1848
1849 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1850 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1851 }
1852
1853 while( ( TV.p[0] & 1 ) == 0 )
1854 {
1855 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1856
1857 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1858 {
1859 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1860 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1861 }
1862
1863 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1864 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1865 }
1866
1867 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1868 {
1869 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1870 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1871 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1872 }
1873 else
1874 {
1875 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1876 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1877 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1878 }
1879 }
1880 while( mpi_cmp_int( &TU, 0 ) != 0 );
1881
1882 while( mpi_cmp_int( &V1, 0 ) < 0 )
1883 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1884
1885 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1886 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1887
1888 MPI_CHK( mpi_copy( X, &V1 ) );
1889
1890cleanup:
1891
Paul Bakker6c591fa2011-05-05 11:49:20 +00001892 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1893 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1894 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001895
1896 return( ret );
1897}
1898
Paul Bakkerd9374b02012-11-02 11:02:58 +00001899#if defined(POLARSSL_GENPRIME)
1900
Paul Bakker5121ce52009-01-03 21:22:43 +00001901static const int small_prime[] =
1902{
1903 3, 5, 7, 11, 13, 17, 19, 23,
1904 29, 31, 37, 41, 43, 47, 53, 59,
1905 61, 67, 71, 73, 79, 83, 89, 97,
1906 101, 103, 107, 109, 113, 127, 131, 137,
1907 139, 149, 151, 157, 163, 167, 173, 179,
1908 181, 191, 193, 197, 199, 211, 223, 227,
1909 229, 233, 239, 241, 251, 257, 263, 269,
1910 271, 277, 281, 283, 293, 307, 311, 313,
1911 317, 331, 337, 347, 349, 353, 359, 367,
1912 373, 379, 383, 389, 397, 401, 409, 419,
1913 421, 431, 433, 439, 443, 449, 457, 461,
1914 463, 467, 479, 487, 491, 499, 503, 509,
1915 521, 523, 541, 547, 557, 563, 569, 571,
1916 577, 587, 593, 599, 601, 607, 613, 617,
1917 619, 631, 641, 643, 647, 653, 659, 661,
1918 673, 677, 683, 691, 701, 709, 719, 727,
1919 733, 739, 743, 751, 757, 761, 769, 773,
1920 787, 797, 809, 811, 821, 823, 827, 829,
1921 839, 853, 857, 859, 863, 877, 881, 883,
1922 887, 907, 911, 919, 929, 937, 941, 947,
1923 953, 967, 971, 977, 983, 991, 997, -103
1924};
1925
1926/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001927 * Small divisors test (X must be positive)
1928 *
1929 * Return values:
1930 * 0: no small factor (possible prime, more tests needed)
1931 * 1: certain prime
1932 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
1933 * other negative: error
Paul Bakker5121ce52009-01-03 21:22:43 +00001934 */
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001935static int mpi_check_small_factors( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +00001936{
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001937 int ret = 0;
1938 size_t i;
1939 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001940
Paul Bakker5121ce52009-01-03 21:22:43 +00001941 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001942 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001943
1944 for( i = 0; small_prime[i] > 0; i++ )
1945 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001946 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001947 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001948
1949 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1950
1951 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001952 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001953 }
1954
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001955cleanup:
1956 return( ret );
1957}
1958
1959/*
1960 * Miller-Rabin pseudo-primality test (HAC 4.24)
1961 */
1962static int mpi_miller_rabin( const mpi *X,
1963 int (*f_rng)(void *, unsigned char *, size_t),
1964 void *p_rng )
1965{
1966 int ret;
1967 size_t i, j, n, s;
1968 mpi W, R, T, A, RR;
1969
1970 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1971 mpi_init( &RR );
1972
Paul Bakker5121ce52009-01-03 21:22:43 +00001973 /*
1974 * W = |X| - 1
1975 * R = W >> lsb( W )
1976 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001977 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001978 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001979 MPI_CHK( mpi_copy( &R, &W ) );
1980 MPI_CHK( mpi_shift_r( &R, s ) );
1981
1982 i = mpi_msb( X );
1983 /*
1984 * HAC, table 4.4
1985 */
1986 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1987 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1988 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1989
1990 for( i = 0; i < n; i++ )
1991 {
1992 /*
1993 * pick a random A, 1 < A < |X| - 1
1994 */
Paul Bakker901c6562012-04-20 13:25:38 +00001995 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001996
Paul Bakkerb94081b2011-01-05 15:53:06 +00001997 if( mpi_cmp_mpi( &A, &W ) >= 0 )
1998 {
1999 j = mpi_msb( &A ) - mpi_msb( &W );
2000 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
2001 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002002 A.p[0] |= 3;
2003
2004 /*
2005 * A = A^R mod |X|
2006 */
2007 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
2008
2009 if( mpi_cmp_mpi( &A, &W ) == 0 ||
2010 mpi_cmp_int( &A, 1 ) == 0 )
2011 continue;
2012
2013 j = 1;
2014 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
2015 {
2016 /*
2017 * A = A * A mod |X|
2018 */
2019 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
2020 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
2021
2022 if( mpi_cmp_int( &A, 1 ) == 0 )
2023 break;
2024
2025 j++;
2026 }
2027
2028 /*
2029 * not prime if A != |X| - 1 or A == 1
2030 */
2031 if( mpi_cmp_mpi( &A, &W ) != 0 ||
2032 mpi_cmp_int( &A, 1 ) == 0 )
2033 {
Paul Bakker40e46942009-01-03 21:51:57 +00002034 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002035 break;
2036 }
2037 }
2038
2039cleanup:
Paul Bakker6c591fa2011-05-05 11:49:20 +00002040 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
2041 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002042
2043 return( ret );
2044}
2045
2046/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002047 * Pseudo-primality test: small factors, then Miller-Rabin
2048 */
Paul Bakker45f457d2013-11-25 14:26:52 +01002049int mpi_is_prime( mpi *X,
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002050 int (*f_rng)(void *, unsigned char *, size_t),
2051 void *p_rng )
2052{
2053 int ret;
2054 const mpi XX = { 1, X->n, X->p }; /* Abs(X) */
2055
2056 if( mpi_cmp_int( &XX, 0 ) == 0 ||
2057 mpi_cmp_int( &XX, 1 ) == 0 )
2058 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
2059
2060 if( mpi_cmp_int( &XX, 2 ) == 0 )
2061 return( 0 );
2062
2063 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2064 {
2065 if( ret == 1 )
2066 return( 0 );
2067
2068 return( ret );
2069 }
2070
2071 return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
2072}
2073
2074/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002075 * Prime number generation
2076 */
Paul Bakker23986e52011-04-24 08:57:21 +00002077int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002078 int (*f_rng)(void *, unsigned char *, size_t),
2079 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +00002080{
Paul Bakker23986e52011-04-24 08:57:21 +00002081 int ret;
2082 size_t k, n;
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002083 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002084 mpi Y;
2085
Paul Bakkerfe3256e2011-11-25 12:11:43 +00002086 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
Paul Bakker40e46942009-01-03 21:51:57 +00002087 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002088
Paul Bakker6c591fa2011-05-05 11:49:20 +00002089 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002090
2091 n = BITS_TO_LIMBS( nbits );
2092
Paul Bakker901c6562012-04-20 13:25:38 +00002093 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002094
2095 k = mpi_msb( X );
2096 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
2097 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
2098
2099 X->p[0] |= 3;
2100
2101 if( dh_flag == 0 )
2102 {
2103 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
2104 {
Paul Bakker40e46942009-01-03 21:51:57 +00002105 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002106 goto cleanup;
2107
2108 MPI_CHK( mpi_add_int( X, X, 2 ) );
2109 }
2110 }
2111 else
2112 {
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002113 /*
2114 * An necessary condition for Y and X = 2Y + 1 to be prime
2115 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2116 * Make sure it is satisfied, while keeping X = 3 mod 4
2117 */
2118 MPI_CHK( mpi_mod_int( &r, X, 3 ) );
2119 if( r == 0 )
2120 MPI_CHK( mpi_add_int( X, X, 8 ) );
2121 else if( r == 1 )
2122 MPI_CHK( mpi_add_int( X, X, 4 ) );
2123
2124 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2125 MPI_CHK( mpi_copy( &Y, X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002126 MPI_CHK( mpi_shift_r( &Y, 1 ) );
2127
2128 while( 1 )
2129 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002130 /*
2131 * First, check small factors for X and Y
2132 * before doing Miller-Rabin on any of them
2133 */
2134 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2135 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2136 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
2137 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002138 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002139 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002140 }
2141
Paul Bakker40e46942009-01-03 21:51:57 +00002142 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002143 goto cleanup;
2144
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002145 /*
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002146 * Next candidates. We want to preserve Y = (X-1) / 2 and
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002147 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2148 * so up Y by 6 and X by 12.
2149 */
2150 MPI_CHK( mpi_add_int( X, X, 12 ) );
2151 MPI_CHK( mpi_add_int( &Y, &Y, 6 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002152 }
2153 }
2154
2155cleanup:
2156
Paul Bakker6c591fa2011-05-05 11:49:20 +00002157 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002158
2159 return( ret );
2160}
2161
Manuel Pégourié-Gonnarddf0142b2013-08-22 18:29:07 +02002162#endif /* POLARSSL_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00002163
Paul Bakker40e46942009-01-03 21:51:57 +00002164#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002165
Paul Bakker23986e52011-04-24 08:57:21 +00002166#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002167
2168static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2169{
2170 { 693, 609, 21 },
2171 { 1764, 868, 28 },
2172 { 768454923, 542167814, 1 }
2173};
2174
Paul Bakker5121ce52009-01-03 21:22:43 +00002175/*
2176 * Checkup routine
2177 */
2178int mpi_self_test( int verbose )
2179{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002180 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00002181 mpi A, E, N, X, Y, U, V;
2182
Paul Bakker6c591fa2011-05-05 11:49:20 +00002183 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
2184 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002185
2186 MPI_CHK( mpi_read_string( &A, 16,
2187 "EFE021C2645FD1DC586E69184AF4A31E" \
2188 "D5F53E93B5F123FA41680867BA110131" \
2189 "944FE7952E2517337780CB0DB80E61AA" \
2190 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2191
2192 MPI_CHK( mpi_read_string( &E, 16,
2193 "B2E7EFD37075B9F03FF989C7C5051C20" \
2194 "34D2A323810251127E7BF8625A4F49A5" \
2195 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2196 "5B5C25763222FEFCCFC38B832366C29E" ) );
2197
2198 MPI_CHK( mpi_read_string( &N, 16,
2199 "0066A198186C18C10B2F5ED9B522752A" \
2200 "9830B69916E535C8F047518A889A43A5" \
2201 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2202
2203 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
2204
2205 MPI_CHK( mpi_read_string( &U, 16,
2206 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2207 "9E857EA95A03512E2BAE7391688D264A" \
2208 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2209 "8001B72E848A38CAE1C65F78E56ABDEF" \
2210 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2211 "ECF677152EF804370C1A305CAF3B5BF1" \
2212 "30879B56C61DE584A0F53A2447A51E" ) );
2213
2214 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002215 polarssl_printf( " MPI test #1 (mul_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002216
2217 if( mpi_cmp_mpi( &X, &U ) != 0 )
2218 {
2219 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002220 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002221
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002222 ret = 1;
2223 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002224 }
2225
2226 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002227 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002228
2229 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
2230
2231 MPI_CHK( mpi_read_string( &U, 16,
2232 "256567336059E52CAE22925474705F39A94" ) );
2233
2234 MPI_CHK( mpi_read_string( &V, 16,
2235 "6613F26162223DF488E9CD48CC132C7A" \
2236 "0AC93C701B001B092E4E5B9F73BCD27B" \
2237 "9EE50D0657C77F374E903CDFA4C642" ) );
2238
2239 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002240 polarssl_printf( " MPI test #2 (div_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002241
2242 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2243 mpi_cmp_mpi( &Y, &V ) != 0 )
2244 {
2245 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002246 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002247
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002248 ret = 1;
2249 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002250 }
2251
2252 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002253 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002254
2255 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2256
2257 MPI_CHK( mpi_read_string( &U, 16,
2258 "36E139AEA55215609D2816998ED020BB" \
2259 "BD96C37890F65171D948E9BC7CBAA4D9" \
2260 "325D24D6A3C12710F10A09FA08AB87" ) );
2261
2262 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002263 polarssl_printf( " MPI test #3 (exp_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002264
2265 if( mpi_cmp_mpi( &X, &U ) != 0 )
2266 {
2267 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002268 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002269
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002270 ret = 1;
2271 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002272 }
2273
2274 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002275 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002276
2277 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2278
2279 MPI_CHK( mpi_read_string( &U, 16,
2280 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2281 "C3DBA76456363A10869622EAC2DD84EC" \
2282 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2283
2284 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002285 polarssl_printf( " MPI test #4 (inv_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002286
2287 if( mpi_cmp_mpi( &X, &U ) != 0 )
2288 {
2289 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002290 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002291
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002292 ret = 1;
2293 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002294 }
2295
2296 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002297 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002298
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002299 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002300 polarssl_printf( " MPI test #5 (simple gcd): " );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002301
2302 for ( i = 0; i < GCD_PAIR_COUNT; i++)
2303 {
2304 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002305 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002306
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002307 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002308
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002309 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2310 {
2311 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002312 polarssl_printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002313
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002314 ret = 1;
2315 goto cleanup;
2316 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002317 }
2318
2319 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002320 polarssl_printf( "passed\n" );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002321
Paul Bakker5121ce52009-01-03 21:22:43 +00002322cleanup:
2323
2324 if( ret != 0 && verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002325 polarssl_printf( "Unexpected error, return code = %08X\n", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002326
Paul Bakker6c591fa2011-05-05 11:49:20 +00002327 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2328 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002329
2330 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002331 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002332
2333 return( ret );
2334}
2335
2336#endif
2337
2338#endif