blob: a73bf766568518d50407442ae179f79b821fd289 [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
Paul Bakker40e46942009-01-03 21:51:57 +000033#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000034
Paul Bakker40e46942009-01-03 21:51:57 +000035#if defined(POLARSSL_BIGNUM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000036
Paul Bakker40e46942009-01-03 21:51:57 +000037#include "polarssl/bignum.h"
38#include "polarssl/bn_mul.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000039
Paul Bakker7dc4c442014-02-01 22:50:26 +010040#if defined(POLARSSL_PLATFORM_C)
41#include "polarssl/platform.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020042#else
Paul Bakker7dc4c442014-02-01 22:50:26 +010043#define polarssl_printf printf
Paul Bakker6e339b52013-07-03 13:37:05 +020044#define polarssl_malloc malloc
45#define polarssl_free free
46#endif
47
Paul Bakker5121ce52009-01-03 21:22:43 +000048#include <stdlib.h>
Paul Bakker5121ce52009-01-03 21:22:43 +000049
Paul Bakkerf9688572011-05-05 10:00:45 +000050#define ciL (sizeof(t_uint)) /* chars in limb */
Paul Bakker5121ce52009-01-03 21:22:43 +000051#define biL (ciL << 3) /* bits in limb */
52#define biH (ciL << 2) /* half limb size */
53
54/*
55 * Convert between bits/chars and number of limbs
56 */
57#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
58#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
59
60/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000061 * Initialize one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000062 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000063void mpi_init( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000064{
Paul Bakker6c591fa2011-05-05 11:49:20 +000065 if( X == NULL )
66 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000067
Paul Bakker6c591fa2011-05-05 11:49:20 +000068 X->s = 1;
69 X->n = 0;
70 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000071}
72
73/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000074 * Unallocate one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000075 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000076void mpi_free( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000077{
Paul Bakker6c591fa2011-05-05 11:49:20 +000078 if( X == NULL )
79 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000080
Paul Bakker6c591fa2011-05-05 11:49:20 +000081 if( X->p != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +000082 {
Paul Bakker6c591fa2011-05-05 11:49:20 +000083 memset( X->p, 0, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +020084 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +000085 }
86
Paul Bakker6c591fa2011-05-05 11:49:20 +000087 X->s = 1;
88 X->n = 0;
89 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000090}
91
92/*
93 * Enlarge to the specified number of limbs
94 */
Paul Bakker23986e52011-04-24 08:57:21 +000095int mpi_grow( mpi *X, size_t nblimbs )
Paul Bakker5121ce52009-01-03 21:22:43 +000096{
Paul Bakkera755ca12011-04-24 09:11:17 +000097 t_uint *p;
Paul Bakker5121ce52009-01-03 21:22:43 +000098
Paul Bakkerf9688572011-05-05 10:00:45 +000099 if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
Paul Bakker69e095c2011-12-10 21:55:01 +0000100 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakkerf9688572011-05-05 10:00:45 +0000101
Paul Bakker5121ce52009-01-03 21:22:43 +0000102 if( X->n < nblimbs )
103 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200104 if( ( p = (t_uint *) polarssl_malloc( nblimbs * ciL ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000105 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000106
107 memset( p, 0, nblimbs * ciL );
108
109 if( X->p != NULL )
110 {
111 memcpy( p, X->p, X->n * ciL );
112 memset( X->p, 0, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +0200113 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000114 }
115
116 X->n = nblimbs;
117 X->p = p;
118 }
119
120 return( 0 );
121}
122
123/*
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100124 * Resize down as much as possible,
125 * while keeping at least the specified number of limbs
126 */
127int mpi_shrink( mpi *X, size_t nblimbs )
128{
129 t_uint *p;
130 size_t i;
131
132 /* Actually resize up in this case */
133 if( X->n <= nblimbs )
134 return( mpi_grow( X, nblimbs ) );
135
136 for( i = X->n - 1; i > 0; i-- )
137 if( X->p[i] != 0 )
138 break;
139 i++;
140
141 if( i < nblimbs )
142 i = nblimbs;
143
144 if( ( p = (t_uint *) polarssl_malloc( i * ciL ) ) == NULL )
145 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
146
147 memset( p, 0, i * ciL );
148
149 if( X->p != NULL )
150 {
151 memcpy( p, X->p, i * ciL );
152 memset( X->p, 0, X->n * ciL );
153 polarssl_free( X->p );
154 }
155
156 X->n = i;
157 X->p = p;
158
159 return( 0 );
160}
161
162/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000163 * Copy the contents of Y into X
164 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000165int mpi_copy( mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000166{
Paul Bakker23986e52011-04-24 08:57:21 +0000167 int ret;
168 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000169
170 if( X == Y )
171 return( 0 );
172
Manuel Pégourié-Gonnardf4999932013-08-12 17:02:59 +0200173 if( Y->p == NULL )
174 {
175 mpi_free( X );
176 return( 0 );
177 }
178
Paul Bakker5121ce52009-01-03 21:22:43 +0000179 for( i = Y->n - 1; i > 0; i-- )
180 if( Y->p[i] != 0 )
181 break;
182 i++;
183
184 X->s = Y->s;
185
186 MPI_CHK( mpi_grow( X, i ) );
187
188 memset( X->p, 0, X->n * ciL );
189 memcpy( X->p, Y->p, i * ciL );
190
191cleanup:
192
193 return( ret );
194}
195
196/*
197 * Swap the contents of X and Y
198 */
199void mpi_swap( mpi *X, mpi *Y )
200{
201 mpi T;
202
203 memcpy( &T, X, sizeof( mpi ) );
204 memcpy( X, Y, sizeof( mpi ) );
205 memcpy( Y, &T, sizeof( mpi ) );
206}
207
208/*
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100209 * Conditionally assign X = Y, without leaking information
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100210 * about whether the assignment was made or not.
211 * (Leaking information about the respective sizes of X and Y is ok however.)
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100212 */
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100213int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign )
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100214{
215 int ret = 0;
216 size_t i;
217
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100218 /* make sure assign is 0 or 1 */
219 assign = ( assign != 0 );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100220
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100221 MPI_CHK( mpi_grow( X, Y->n ) );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100222
Manuel Pégourié-Gonnard3e3d2b82013-11-21 21:12:26 +0100223 X->s = X->s * (1 - assign) + Y->s * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100224
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100225 for( i = 0; i < Y->n; i++ )
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100226 X->p[i] = X->p[i] * (1 - assign) + Y->p[i] * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100227
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100228 for( ; i < X->n; i++ )
229 X->p[i] *= (1 - assign);
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100230
231cleanup:
232 return( ret );
233}
234
235/*
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100236 * Conditionally swap X and Y, without leaking information
237 * about whether the swap was made or not.
238 * Here it is not ok to simply swap the pointers, which whould lead to
239 * different memory access patterns when X and Y are used afterwards.
240 */
241int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char swap )
242{
243 int ret, s;
244 size_t i;
245 t_uint tmp;
246
247 if( X == Y )
248 return( 0 );
249
250 /* make sure swap is 0 or 1 */
251 swap = ( swap != 0 );
252
253 MPI_CHK( mpi_grow( X, Y->n ) );
254 MPI_CHK( mpi_grow( Y, X->n ) );
255
256 s = X->s;
257 X->s = X->s * (1 - swap) + Y->s * swap;
258 Y->s = Y->s * (1 - swap) + s * swap;
259
260
261 for( i = 0; i < X->n; i++ )
262 {
263 tmp = X->p[i];
264 X->p[i] = X->p[i] * (1 - swap) + Y->p[i] * swap;
265 Y->p[i] = Y->p[i] * (1 - swap) + tmp * swap;
266 }
267
268cleanup:
269 return( ret );
270}
271
272/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000273 * Set value from integer
274 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000275int mpi_lset( mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000276{
277 int ret;
278
279 MPI_CHK( mpi_grow( X, 1 ) );
280 memset( X->p, 0, X->n * ciL );
281
282 X->p[0] = ( z < 0 ) ? -z : z;
283 X->s = ( z < 0 ) ? -1 : 1;
284
285cleanup:
286
287 return( ret );
288}
289
290/*
Paul Bakker2f5947e2011-05-18 15:47:11 +0000291 * Get a specific bit
292 */
Paul Bakker6b906e52012-05-08 12:01:43 +0000293int mpi_get_bit( const mpi *X, size_t pos )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000294{
295 if( X->n * biL <= pos )
296 return( 0 );
297
298 return ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01;
299}
300
301/*
302 * Set a bit to a specific value of 0 or 1
303 */
304int mpi_set_bit( mpi *X, size_t pos, unsigned char val )
305{
306 int ret = 0;
307 size_t off = pos / biL;
308 size_t idx = pos % biL;
309
310 if( val != 0 && val != 1 )
311 return POLARSSL_ERR_MPI_BAD_INPUT_DATA;
312
313 if( X->n * biL <= pos )
314 {
315 if( val == 0 )
316 return ( 0 );
317
318 MPI_CHK( mpi_grow( X, off + 1 ) );
319 }
320
Manuel Pégourié-Gonnard9a4a5ac2013-12-04 18:05:29 +0100321 X->p[off] &= ~( (t_uint) 0x01 << idx );
322 X->p[off] |= (t_uint) val << idx;
Paul Bakker2f5947e2011-05-18 15:47:11 +0000323
324cleanup:
325
326 return( ret );
327}
328
329/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000330 * Return the number of least significant bits
331 */
Paul Bakker23986e52011-04-24 08:57:21 +0000332size_t mpi_lsb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000333{
Paul Bakker23986e52011-04-24 08:57:21 +0000334 size_t i, j, count = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000335
336 for( i = 0; i < X->n; i++ )
Paul Bakkerf9688572011-05-05 10:00:45 +0000337 for( j = 0; j < biL; j++, count++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000338 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
339 return( count );
340
341 return( 0 );
342}
343
344/*
345 * Return the number of most significant bits
346 */
Paul Bakker23986e52011-04-24 08:57:21 +0000347size_t mpi_msb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000348{
Paul Bakker23986e52011-04-24 08:57:21 +0000349 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000350
351 for( i = X->n - 1; i > 0; i-- )
352 if( X->p[i] != 0 )
353 break;
354
Paul Bakker23986e52011-04-24 08:57:21 +0000355 for( j = biL; j > 0; j-- )
356 if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000357 break;
358
Paul Bakker23986e52011-04-24 08:57:21 +0000359 return( ( i * biL ) + j );
Paul Bakker5121ce52009-01-03 21:22:43 +0000360}
361
362/*
363 * Return the total size in bytes
364 */
Paul Bakker23986e52011-04-24 08:57:21 +0000365size_t mpi_size( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000366{
367 return( ( mpi_msb( X ) + 7 ) >> 3 );
368}
369
370/*
371 * Convert an ASCII character to digit value
372 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000373static int mpi_get_digit( t_uint *d, int radix, char c )
Paul Bakker5121ce52009-01-03 21:22:43 +0000374{
375 *d = 255;
376
377 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
378 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
379 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
380
Paul Bakkera755ca12011-04-24 09:11:17 +0000381 if( *d >= (t_uint) radix )
Paul Bakker40e46942009-01-03 21:51:57 +0000382 return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000383
384 return( 0 );
385}
386
387/*
388 * Import from an ASCII string
389 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000390int mpi_read_string( mpi *X, int radix, const char *s )
Paul Bakker5121ce52009-01-03 21:22:43 +0000391{
Paul Bakker23986e52011-04-24 08:57:21 +0000392 int ret;
393 size_t i, j, slen, n;
Paul Bakkera755ca12011-04-24 09:11:17 +0000394 t_uint d;
Paul Bakker5121ce52009-01-03 21:22:43 +0000395 mpi T;
396
397 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000398 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000399
Paul Bakker6c591fa2011-05-05 11:49:20 +0000400 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000401
Paul Bakkerff60ee62010-03-16 21:09:09 +0000402 slen = strlen( s );
403
Paul Bakker5121ce52009-01-03 21:22:43 +0000404 if( radix == 16 )
405 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000406 n = BITS_TO_LIMBS( slen << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000407
408 MPI_CHK( mpi_grow( X, n ) );
409 MPI_CHK( mpi_lset( X, 0 ) );
410
Paul Bakker23986e52011-04-24 08:57:21 +0000411 for( i = slen, j = 0; i > 0; i--, j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000412 {
Paul Bakker23986e52011-04-24 08:57:21 +0000413 if( i == 1 && s[i - 1] == '-' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000414 {
415 X->s = -1;
416 break;
417 }
418
Paul Bakker23986e52011-04-24 08:57:21 +0000419 MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000420 X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 );
421 }
422 }
423 else
424 {
425 MPI_CHK( mpi_lset( X, 0 ) );
426
Paul Bakkerff60ee62010-03-16 21:09:09 +0000427 for( i = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000428 {
429 if( i == 0 && s[i] == '-' )
430 {
431 X->s = -1;
432 continue;
433 }
434
435 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
436 MPI_CHK( mpi_mul_int( &T, X, radix ) );
Paul Bakker05feca62009-06-20 08:22:43 +0000437
438 if( X->s == 1 )
439 {
440 MPI_CHK( mpi_add_int( X, &T, d ) );
441 }
442 else
443 {
444 MPI_CHK( mpi_sub_int( X, &T, d ) );
445 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000446 }
447 }
448
449cleanup:
450
Paul Bakker6c591fa2011-05-05 11:49:20 +0000451 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000452
453 return( ret );
454}
455
456/*
457 * Helper to write the digits high-order first
458 */
459static int mpi_write_hlp( mpi *X, int radix, char **p )
460{
461 int ret;
Paul Bakkera755ca12011-04-24 09:11:17 +0000462 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +0000463
464 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000465 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000466
467 MPI_CHK( mpi_mod_int( &r, X, radix ) );
468 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
469
470 if( mpi_cmp_int( X, 0 ) != 0 )
471 MPI_CHK( mpi_write_hlp( X, radix, p ) );
472
473 if( r < 10 )
474 *(*p)++ = (char)( r + 0x30 );
475 else
476 *(*p)++ = (char)( r + 0x37 );
477
478cleanup:
479
480 return( ret );
481}
482
483/*
484 * Export into an ASCII string
485 */
Paul Bakker23986e52011-04-24 08:57:21 +0000486int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000487{
Paul Bakker23986e52011-04-24 08:57:21 +0000488 int ret = 0;
489 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000490 char *p;
491 mpi T;
492
493 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000494 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000495
496 n = mpi_msb( X );
497 if( radix >= 4 ) n >>= 1;
498 if( radix >= 16 ) n >>= 1;
499 n += 3;
500
501 if( *slen < n )
502 {
503 *slen = n;
Paul Bakker40e46942009-01-03 21:51:57 +0000504 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000505 }
506
507 p = s;
Paul Bakker6c591fa2011-05-05 11:49:20 +0000508 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000509
510 if( X->s == -1 )
511 *p++ = '-';
512
513 if( radix == 16 )
514 {
Paul Bakker23986e52011-04-24 08:57:21 +0000515 int c;
516 size_t i, j, k;
Paul Bakker5121ce52009-01-03 21:22:43 +0000517
Paul Bakker23986e52011-04-24 08:57:21 +0000518 for( i = X->n, k = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000519 {
Paul Bakker23986e52011-04-24 08:57:21 +0000520 for( j = ciL; j > 0; j-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000521 {
Paul Bakker23986e52011-04-24 08:57:21 +0000522 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000523
Paul Bakker23986e52011-04-24 08:57:21 +0000524 if( c == 0 && k == 0 && ( i + j + 3 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000525 continue;
526
Paul Bakker98fe5ea2012-10-24 11:17:48 +0000527 *(p++) = "0123456789ABCDEF" [c / 16];
Paul Bakkerd2c167e2012-10-30 07:49:19 +0000528 *(p++) = "0123456789ABCDEF" [c % 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000529 k = 1;
530 }
531 }
532 }
533 else
534 {
535 MPI_CHK( mpi_copy( &T, X ) );
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000536
537 if( T.s == -1 )
538 T.s = 1;
539
Paul Bakker5121ce52009-01-03 21:22:43 +0000540 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
541 }
542
543 *p++ = '\0';
544 *slen = p - s;
545
546cleanup:
547
Paul Bakker6c591fa2011-05-05 11:49:20 +0000548 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000549
550 return( ret );
551}
552
Paul Bakker335db3f2011-04-25 15:28:35 +0000553#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000554/*
555 * Read X from an opened file
556 */
557int mpi_read_file( mpi *X, int radix, FILE *fin )
558{
Paul Bakkera755ca12011-04-24 09:11:17 +0000559 t_uint d;
Paul Bakker23986e52011-04-24 08:57:21 +0000560 size_t slen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000561 char *p;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000562 /*
Paul Bakkercb37aa52011-11-30 16:00:20 +0000563 * Buffer should have space for (short) label and decimal formatted MPI,
564 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000565 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000566 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000567
568 memset( s, 0, sizeof( s ) );
569 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000570 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000571
572 slen = strlen( s );
Paul Bakkercb37aa52011-11-30 16:00:20 +0000573 if( slen == sizeof( s ) - 2 )
574 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
575
Paul Bakker5121ce52009-01-03 21:22:43 +0000576 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
577 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
578
579 p = s + slen;
580 while( --p >= s )
581 if( mpi_get_digit( &d, radix, *p ) != 0 )
582 break;
583
584 return( mpi_read_string( X, radix, p + 1 ) );
585}
586
587/*
588 * Write X into an opened file (or stdout if fout == NULL)
589 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000590int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
Paul Bakker5121ce52009-01-03 21:22:43 +0000591{
Paul Bakker23986e52011-04-24 08:57:21 +0000592 int ret;
593 size_t n, slen, plen;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000594 /*
Paul Bakker5531c6d2012-09-26 19:20:46 +0000595 * Buffer should have space for (short) label and decimal formatted MPI,
596 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000597 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000598 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
600 n = sizeof( s );
601 memset( s, 0, n );
602 n -= 2;
603
Paul Bakker23986e52011-04-24 08:57:21 +0000604 MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000605
606 if( p == NULL ) p = "";
607
608 plen = strlen( p );
609 slen = strlen( s );
610 s[slen++] = '\r';
611 s[slen++] = '\n';
612
613 if( fout != NULL )
614 {
615 if( fwrite( p, 1, plen, fout ) != plen ||
616 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000617 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000618 }
619 else
Paul Bakker7dc4c442014-02-01 22:50:26 +0100620 polarssl_printf( "%s%s", p, s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
622cleanup:
623
624 return( ret );
625}
Paul Bakker335db3f2011-04-25 15:28:35 +0000626#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000627
628/*
629 * Import X from unsigned binary data, big endian
630 */
Paul Bakker23986e52011-04-24 08:57:21 +0000631int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000632{
Paul Bakker23986e52011-04-24 08:57:21 +0000633 int ret;
634 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000635
636 for( n = 0; n < buflen; n++ )
637 if( buf[n] != 0 )
638 break;
639
640 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
641 MPI_CHK( mpi_lset( X, 0 ) );
642
Paul Bakker23986e52011-04-24 08:57:21 +0000643 for( i = buflen, j = 0; i > n; i--, j++ )
Paul Bakkera755ca12011-04-24 09:11:17 +0000644 X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000645
646cleanup:
647
648 return( ret );
649}
650
651/*
652 * Export X into unsigned binary data, big endian
653 */
Paul Bakker23986e52011-04-24 08:57:21 +0000654int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000655{
Paul Bakker23986e52011-04-24 08:57:21 +0000656 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000657
658 n = mpi_size( X );
659
660 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000661 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000662
663 memset( buf, 0, buflen );
664
665 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
666 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
667
668 return( 0 );
669}
670
671/*
672 * Left-shift: X <<= count
673 */
Paul Bakker23986e52011-04-24 08:57:21 +0000674int mpi_shift_l( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000675{
Paul Bakker23986e52011-04-24 08:57:21 +0000676 int ret;
677 size_t i, v0, t1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000678 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000679
680 v0 = count / (biL );
681 t1 = count & (biL - 1);
682
683 i = mpi_msb( X ) + count;
684
Paul Bakkerf9688572011-05-05 10:00:45 +0000685 if( X->n * biL < i )
Paul Bakker5121ce52009-01-03 21:22:43 +0000686 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
687
688 ret = 0;
689
690 /*
691 * shift by count / limb_size
692 */
693 if( v0 > 0 )
694 {
Paul Bakker23986e52011-04-24 08:57:21 +0000695 for( i = X->n; i > v0; i-- )
696 X->p[i - 1] = X->p[i - v0 - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000697
Paul Bakker23986e52011-04-24 08:57:21 +0000698 for( ; i > 0; i-- )
699 X->p[i - 1] = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000700 }
701
702 /*
703 * shift by count % limb_size
704 */
705 if( t1 > 0 )
706 {
707 for( i = v0; i < X->n; i++ )
708 {
709 r1 = X->p[i] >> (biL - t1);
710 X->p[i] <<= t1;
711 X->p[i] |= r0;
712 r0 = r1;
713 }
714 }
715
716cleanup:
717
718 return( ret );
719}
720
721/*
722 * Right-shift: X >>= count
723 */
Paul Bakker23986e52011-04-24 08:57:21 +0000724int mpi_shift_r( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000725{
Paul Bakker23986e52011-04-24 08:57:21 +0000726 size_t i, v0, v1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000727 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000728
729 v0 = count / biL;
730 v1 = count & (biL - 1);
731
Manuel Pégourié-Gonnarde44ec102012-11-17 12:42:51 +0100732 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
733 return mpi_lset( X, 0 );
734
Paul Bakker5121ce52009-01-03 21:22:43 +0000735 /*
736 * shift by count / limb_size
737 */
738 if( v0 > 0 )
739 {
740 for( i = 0; i < X->n - v0; i++ )
741 X->p[i] = X->p[i + v0];
742
743 for( ; i < X->n; i++ )
744 X->p[i] = 0;
745 }
746
747 /*
748 * shift by count % limb_size
749 */
750 if( v1 > 0 )
751 {
Paul Bakker23986e52011-04-24 08:57:21 +0000752 for( i = X->n; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000753 {
Paul Bakker23986e52011-04-24 08:57:21 +0000754 r1 = X->p[i - 1] << (biL - v1);
755 X->p[i - 1] >>= v1;
756 X->p[i - 1] |= r0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000757 r0 = r1;
758 }
759 }
760
761 return( 0 );
762}
763
764/*
765 * Compare unsigned values
766 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000767int mpi_cmp_abs( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000768{
Paul Bakker23986e52011-04-24 08:57:21 +0000769 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000770
Paul Bakker23986e52011-04-24 08:57:21 +0000771 for( i = X->n; i > 0; i-- )
772 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000773 break;
774
Paul Bakker23986e52011-04-24 08:57:21 +0000775 for( j = Y->n; j > 0; j-- )
776 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000777 break;
778
Paul Bakker23986e52011-04-24 08:57:21 +0000779 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000780 return( 0 );
781
782 if( i > j ) return( 1 );
783 if( j > i ) return( -1 );
784
Paul Bakker23986e52011-04-24 08:57:21 +0000785 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000786 {
Paul Bakker23986e52011-04-24 08:57:21 +0000787 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
788 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000789 }
790
791 return( 0 );
792}
793
794/*
795 * Compare signed values
796 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000797int mpi_cmp_mpi( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000798{
Paul Bakker23986e52011-04-24 08:57:21 +0000799 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000800
Paul Bakker23986e52011-04-24 08:57:21 +0000801 for( i = X->n; i > 0; i-- )
802 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000803 break;
804
Paul Bakker23986e52011-04-24 08:57:21 +0000805 for( j = Y->n; j > 0; j-- )
806 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000807 break;
808
Paul Bakker23986e52011-04-24 08:57:21 +0000809 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000810 return( 0 );
811
812 if( i > j ) return( X->s );
Paul Bakker0c8f73b2012-03-22 14:08:57 +0000813 if( j > i ) return( -Y->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000814
815 if( X->s > 0 && Y->s < 0 ) return( 1 );
816 if( Y->s > 0 && X->s < 0 ) return( -1 );
817
Paul Bakker23986e52011-04-24 08:57:21 +0000818 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000819 {
Paul Bakker23986e52011-04-24 08:57:21 +0000820 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
821 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000822 }
823
824 return( 0 );
825}
826
827/*
828 * Compare signed values
829 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000830int mpi_cmp_int( const mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000831{
832 mpi Y;
Paul Bakkera755ca12011-04-24 09:11:17 +0000833 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000834
835 *p = ( z < 0 ) ? -z : z;
836 Y.s = ( z < 0 ) ? -1 : 1;
837 Y.n = 1;
838 Y.p = p;
839
840 return( mpi_cmp_mpi( X, &Y ) );
841}
842
843/*
844 * Unsigned addition: X = |A| + |B| (HAC 14.7)
845 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000846int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000847{
Paul Bakker23986e52011-04-24 08:57:21 +0000848 int ret;
849 size_t i, j;
Paul Bakkera755ca12011-04-24 09:11:17 +0000850 t_uint *o, *p, c;
Paul Bakker5121ce52009-01-03 21:22:43 +0000851
852 if( X == B )
853 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000854 const mpi *T = A; A = X; B = T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000855 }
856
857 if( X != A )
858 MPI_CHK( mpi_copy( X, A ) );
Paul Bakkerf7ca7b92009-06-20 10:31:06 +0000859
860 /*
861 * X should always be positive as a result of unsigned additions.
862 */
863 X->s = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000864
Paul Bakker23986e52011-04-24 08:57:21 +0000865 for( j = B->n; j > 0; j-- )
866 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000867 break;
868
Paul Bakker23986e52011-04-24 08:57:21 +0000869 MPI_CHK( mpi_grow( X, j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000870
871 o = B->p; p = X->p; c = 0;
872
Paul Bakker23986e52011-04-24 08:57:21 +0000873 for( i = 0; i < j; i++, o++, p++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000874 {
875 *p += c; c = ( *p < c );
876 *p += *o; c += ( *p < *o );
877 }
878
879 while( c != 0 )
880 {
881 if( i >= X->n )
882 {
883 MPI_CHK( mpi_grow( X, i + 1 ) );
884 p = X->p + i;
885 }
886
Paul Bakker2d319fd2012-09-16 21:34:26 +0000887 *p += c; c = ( *p < c ); i++; p++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000888 }
889
890cleanup:
891
892 return( ret );
893}
894
895/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100896 * Helper for mpi subtraction
Paul Bakker5121ce52009-01-03 21:22:43 +0000897 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000898static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
Paul Bakker5121ce52009-01-03 21:22:43 +0000899{
Paul Bakker23986e52011-04-24 08:57:21 +0000900 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +0000901 t_uint c, z;
Paul Bakker5121ce52009-01-03 21:22:43 +0000902
903 for( i = c = 0; i < n; i++, s++, d++ )
904 {
905 z = ( *d < c ); *d -= c;
906 c = ( *d < *s ) + z; *d -= *s;
907 }
908
909 while( c != 0 )
910 {
911 z = ( *d < c ); *d -= c;
912 c = z; i++; d++;
913 }
914}
915
916/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100917 * Unsigned subtraction: X = |A| - |B| (HAC 14.9)
Paul Bakker5121ce52009-01-03 21:22:43 +0000918 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000919int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000920{
921 mpi TB;
Paul Bakker23986e52011-04-24 08:57:21 +0000922 int ret;
923 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000924
925 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000926 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000927
Paul Bakker6c591fa2011-05-05 11:49:20 +0000928 mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000929
930 if( X == B )
931 {
932 MPI_CHK( mpi_copy( &TB, B ) );
933 B = &TB;
934 }
935
936 if( X != A )
937 MPI_CHK( mpi_copy( X, A ) );
938
Paul Bakker1ef7a532009-06-20 10:50:55 +0000939 /*
Paul Bakker60b1d102013-10-29 10:02:51 +0100940 * X should always be positive as a result of unsigned subtractions.
Paul Bakker1ef7a532009-06-20 10:50:55 +0000941 */
942 X->s = 1;
943
Paul Bakker5121ce52009-01-03 21:22:43 +0000944 ret = 0;
945
Paul Bakker23986e52011-04-24 08:57:21 +0000946 for( n = B->n; n > 0; n-- )
947 if( B->p[n - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000948 break;
949
Paul Bakker23986e52011-04-24 08:57:21 +0000950 mpi_sub_hlp( n, B->p, X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000951
952cleanup:
953
Paul Bakker6c591fa2011-05-05 11:49:20 +0000954 mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000955
956 return( ret );
957}
958
959/*
960 * Signed addition: X = A + B
961 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000962int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000963{
964 int ret, s = A->s;
965
966 if( A->s * B->s < 0 )
967 {
968 if( mpi_cmp_abs( A, B ) >= 0 )
969 {
970 MPI_CHK( mpi_sub_abs( X, A, B ) );
971 X->s = s;
972 }
973 else
974 {
975 MPI_CHK( mpi_sub_abs( X, B, A ) );
976 X->s = -s;
977 }
978 }
979 else
980 {
981 MPI_CHK( mpi_add_abs( X, A, B ) );
982 X->s = s;
983 }
984
985cleanup:
986
987 return( ret );
988}
989
990/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100991 * Signed subtraction: X = A - B
Paul Bakker5121ce52009-01-03 21:22:43 +0000992 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000993int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000994{
995 int ret, s = A->s;
996
997 if( A->s * B->s > 0 )
998 {
999 if( mpi_cmp_abs( A, B ) >= 0 )
1000 {
1001 MPI_CHK( mpi_sub_abs( X, A, B ) );
1002 X->s = s;
1003 }
1004 else
1005 {
1006 MPI_CHK( mpi_sub_abs( X, B, A ) );
1007 X->s = -s;
1008 }
1009 }
1010 else
1011 {
1012 MPI_CHK( mpi_add_abs( X, A, B ) );
1013 X->s = s;
1014 }
1015
1016cleanup:
1017
1018 return( ret );
1019}
1020
1021/*
1022 * Signed addition: X = A + b
1023 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001024int mpi_add_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001025{
1026 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001027 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001028
1029 p[0] = ( b < 0 ) ? -b : b;
1030 _B.s = ( b < 0 ) ? -1 : 1;
1031 _B.n = 1;
1032 _B.p = p;
1033
1034 return( mpi_add_mpi( X, A, &_B ) );
1035}
1036
1037/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001038 * Signed subtraction: X = A - b
Paul Bakker5121ce52009-01-03 21:22:43 +00001039 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001040int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001041{
1042 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001043 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001044
1045 p[0] = ( b < 0 ) ? -b : b;
1046 _B.s = ( b < 0 ) ? -1 : 1;
1047 _B.n = 1;
1048 _B.p = p;
1049
1050 return( mpi_sub_mpi( X, A, &_B ) );
1051}
1052
1053/*
1054 * Helper for mpi multiplication
Paul Bakkerfc4f46f2013-06-24 19:23:56 +02001055 */
1056static
1057#if defined(__APPLE__) && defined(__arm__)
1058/*
1059 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1060 * appears to need this to prevent bad ARM code generation at -O3.
1061 */
1062__attribute__ ((noinline))
1063#endif
1064void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001065{
Paul Bakkera755ca12011-04-24 09:11:17 +00001066 t_uint c = 0, t = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001067
1068#if defined(MULADDC_HUIT)
1069 for( ; i >= 8; i -= 8 )
1070 {
1071 MULADDC_INIT
1072 MULADDC_HUIT
1073 MULADDC_STOP
1074 }
1075
1076 for( ; i > 0; i-- )
1077 {
1078 MULADDC_INIT
1079 MULADDC_CORE
1080 MULADDC_STOP
1081 }
1082#else
1083 for( ; i >= 16; i -= 16 )
1084 {
1085 MULADDC_INIT
1086 MULADDC_CORE MULADDC_CORE
1087 MULADDC_CORE MULADDC_CORE
1088 MULADDC_CORE MULADDC_CORE
1089 MULADDC_CORE MULADDC_CORE
1090
1091 MULADDC_CORE MULADDC_CORE
1092 MULADDC_CORE MULADDC_CORE
1093 MULADDC_CORE MULADDC_CORE
1094 MULADDC_CORE MULADDC_CORE
1095 MULADDC_STOP
1096 }
1097
1098 for( ; i >= 8; i -= 8 )
1099 {
1100 MULADDC_INIT
1101 MULADDC_CORE MULADDC_CORE
1102 MULADDC_CORE MULADDC_CORE
1103
1104 MULADDC_CORE MULADDC_CORE
1105 MULADDC_CORE MULADDC_CORE
1106 MULADDC_STOP
1107 }
1108
1109 for( ; i > 0; i-- )
1110 {
1111 MULADDC_INIT
1112 MULADDC_CORE
1113 MULADDC_STOP
1114 }
1115#endif
1116
1117 t++;
1118
1119 do {
1120 *d += c; c = ( *d < c ); d++;
1121 }
1122 while( c != 0 );
1123}
1124
1125/*
1126 * Baseline multiplication: X = A * B (HAC 14.12)
1127 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001128int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001129{
Paul Bakker23986e52011-04-24 08:57:21 +00001130 int ret;
1131 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00001132 mpi TA, TB;
1133
Paul Bakker6c591fa2011-05-05 11:49:20 +00001134 mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001135
1136 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
1137 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
1138
Paul Bakker23986e52011-04-24 08:57:21 +00001139 for( i = A->n; i > 0; i-- )
1140 if( A->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001141 break;
1142
Paul Bakker23986e52011-04-24 08:57:21 +00001143 for( j = B->n; j > 0; j-- )
1144 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001145 break;
1146
Paul Bakker23986e52011-04-24 08:57:21 +00001147 MPI_CHK( mpi_grow( X, i + j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001148 MPI_CHK( mpi_lset( X, 0 ) );
1149
Paul Bakker23986e52011-04-24 08:57:21 +00001150 for( i++; j > 0; j-- )
1151 mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001152
1153 X->s = A->s * B->s;
1154
1155cleanup:
1156
Paul Bakker6c591fa2011-05-05 11:49:20 +00001157 mpi_free( &TB ); mpi_free( &TA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001158
1159 return( ret );
1160}
1161
1162/*
1163 * Baseline multiplication: X = A * b
1164 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001165int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001166{
1167 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001168 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001169
1170 _B.s = 1;
1171 _B.n = 1;
1172 _B.p = p;
1173 p[0] = b;
1174
1175 return( mpi_mul_mpi( X, A, &_B ) );
1176}
1177
1178/*
1179 * Division by mpi: A = Q * B + R (HAC 14.20)
1180 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001181int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001182{
Paul Bakker23986e52011-04-24 08:57:21 +00001183 int ret;
1184 size_t i, n, t, k;
Paul Bakker5121ce52009-01-03 21:22:43 +00001185 mpi X, Y, Z, T1, T2;
1186
1187 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001188 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001189
Paul Bakker6c591fa2011-05-05 11:49:20 +00001190 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
1191 mpi_init( &T1 ); mpi_init( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001192
1193 if( mpi_cmp_abs( A, B ) < 0 )
1194 {
1195 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1196 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1197 return( 0 );
1198 }
1199
1200 MPI_CHK( mpi_copy( &X, A ) );
1201 MPI_CHK( mpi_copy( &Y, B ) );
1202 X.s = Y.s = 1;
1203
1204 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1205 MPI_CHK( mpi_lset( &Z, 0 ) );
1206 MPI_CHK( mpi_grow( &T1, 2 ) );
1207 MPI_CHK( mpi_grow( &T2, 3 ) );
1208
1209 k = mpi_msb( &Y ) % biL;
Paul Bakkerf9688572011-05-05 10:00:45 +00001210 if( k < biL - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001211 {
1212 k = biL - 1 - k;
1213 MPI_CHK( mpi_shift_l( &X, k ) );
1214 MPI_CHK( mpi_shift_l( &Y, k ) );
1215 }
1216 else k = 0;
1217
1218 n = X.n - 1;
1219 t = Y.n - 1;
Paul Bakkerc110d022012-10-19 12:15:08 +00001220 MPI_CHK( mpi_shift_l( &Y, biL * (n - t) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001221
1222 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1223 {
1224 Z.p[n - t]++;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001225 MPI_CHK( mpi_sub_mpi( &X, &X, &Y ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001226 }
Paul Bakker6ea1a952013-12-31 11:16:03 +01001227 MPI_CHK( mpi_shift_r( &Y, biL * (n - t) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001228
1229 for( i = n; i > t ; i-- )
1230 {
1231 if( X.p[i] >= Y.p[t] )
1232 Z.p[i - t - 1] = ~0;
1233 else
1234 {
Paul Bakker62261d62012-10-02 12:19:31 +00001235#if defined(POLARSSL_HAVE_UDBL)
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001236 t_udbl r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001237
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001238 r = (t_udbl) X.p[i] << biL;
1239 r |= (t_udbl) X.p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001240 r /= Y.p[t];
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001241 if( r > ((t_udbl) 1 << biL) - 1)
1242 r = ((t_udbl) 1 << biL) - 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001243
Paul Bakkera755ca12011-04-24 09:11:17 +00001244 Z.p[i - t - 1] = (t_uint) r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001245#else
1246 /*
1247 * __udiv_qrnnd_c, from gmp/longlong.h
1248 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001249 t_uint q0, q1, r0, r1;
1250 t_uint d0, d1, d, m;
Paul Bakker5121ce52009-01-03 21:22:43 +00001251
1252 d = Y.p[t];
1253 d0 = ( d << biH ) >> biH;
1254 d1 = ( d >> biH );
1255
1256 q1 = X.p[i] / d1;
1257 r1 = X.p[i] - d1 * q1;
1258 r1 <<= biH;
1259 r1 |= ( X.p[i - 1] >> biH );
1260
1261 m = q1 * d0;
1262 if( r1 < m )
1263 {
1264 q1--, r1 += d;
1265 while( r1 >= d && r1 < m )
1266 q1--, r1 += d;
1267 }
1268 r1 -= m;
1269
1270 q0 = r1 / d1;
1271 r0 = r1 - d1 * q0;
1272 r0 <<= biH;
1273 r0 |= ( X.p[i - 1] << biH ) >> biH;
1274
1275 m = q0 * d0;
1276 if( r0 < m )
1277 {
1278 q0--, r0 += d;
1279 while( r0 >= d && r0 < m )
1280 q0--, r0 += d;
1281 }
1282 r0 -= m;
1283
1284 Z.p[i - t - 1] = ( q1 << biH ) | q0;
1285#endif
1286 }
1287
1288 Z.p[i - t - 1]++;
1289 do
1290 {
1291 Z.p[i - t - 1]--;
1292
1293 MPI_CHK( mpi_lset( &T1, 0 ) );
1294 T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
1295 T1.p[1] = Y.p[t];
1296 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1297
1298 MPI_CHK( mpi_lset( &T2, 0 ) );
1299 T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
1300 T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
1301 T2.p[2] = X.p[i];
1302 }
1303 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1304
1305 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1306 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1307 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1308
1309 if( mpi_cmp_int( &X, 0 ) < 0 )
1310 {
1311 MPI_CHK( mpi_copy( &T1, &Y ) );
1312 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1313 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1314 Z.p[i - t - 1]--;
1315 }
1316 }
1317
1318 if( Q != NULL )
1319 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001320 MPI_CHK( mpi_copy( Q, &Z ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001321 Q->s = A->s * B->s;
1322 }
1323
1324 if( R != NULL )
1325 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001326 MPI_CHK( mpi_shift_r( &X, k ) );
Paul Bakkerf02c5642012-11-13 10:25:21 +00001327 X.s = A->s;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001328 MPI_CHK( mpi_copy( R, &X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001329
Paul Bakker5121ce52009-01-03 21:22:43 +00001330 if( mpi_cmp_int( R, 0 ) == 0 )
1331 R->s = 1;
1332 }
1333
1334cleanup:
1335
Paul Bakker6c591fa2011-05-05 11:49:20 +00001336 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
1337 mpi_free( &T1 ); mpi_free( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001338
1339 return( ret );
1340}
1341
1342/*
1343 * Division by int: A = Q * b + R
Paul Bakker5121ce52009-01-03 21:22:43 +00001344 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001345int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001346{
1347 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001348 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001349
1350 p[0] = ( b < 0 ) ? -b : b;
1351 _B.s = ( b < 0 ) ? -1 : 1;
1352 _B.n = 1;
1353 _B.p = p;
1354
1355 return( mpi_div_mpi( Q, R, A, &_B ) );
1356}
1357
1358/*
1359 * Modulo: R = A mod B
1360 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001361int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001362{
1363 int ret;
1364
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001365 if( mpi_cmp_int( B, 0 ) < 0 )
1366 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
1367
Paul Bakker5121ce52009-01-03 21:22:43 +00001368 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1369
1370 while( mpi_cmp_int( R, 0 ) < 0 )
1371 MPI_CHK( mpi_add_mpi( R, R, B ) );
1372
1373 while( mpi_cmp_mpi( R, B ) >= 0 )
1374 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1375
1376cleanup:
1377
1378 return( ret );
1379}
1380
1381/*
1382 * Modulo: r = A mod b
1383 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001384int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001385{
Paul Bakker23986e52011-04-24 08:57:21 +00001386 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +00001387 t_uint x, y, z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001388
1389 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001390 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001391
1392 if( b < 0 )
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001393 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001394
1395 /*
1396 * handle trivial cases
1397 */
1398 if( b == 1 )
1399 {
1400 *r = 0;
1401 return( 0 );
1402 }
1403
1404 if( b == 2 )
1405 {
1406 *r = A->p[0] & 1;
1407 return( 0 );
1408 }
1409
1410 /*
1411 * general case
1412 */
Paul Bakker23986e52011-04-24 08:57:21 +00001413 for( i = A->n, y = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001414 {
Paul Bakker23986e52011-04-24 08:57:21 +00001415 x = A->p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001416 y = ( y << biH ) | ( x >> biH );
1417 z = y / b;
1418 y -= z * b;
1419
1420 x <<= biH;
1421 y = ( y << biH ) | ( x >> biH );
1422 z = y / b;
1423 y -= z * b;
1424 }
1425
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001426 /*
1427 * If A is negative, then the current y represents a negative value.
1428 * Flipping it to the positive side.
1429 */
1430 if( A->s < 0 && y != 0 )
1431 y = b - y;
1432
Paul Bakker5121ce52009-01-03 21:22:43 +00001433 *r = y;
1434
1435 return( 0 );
1436}
1437
1438/*
1439 * Fast Montgomery initialization (thanks to Tom St Denis)
1440 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001441static void mpi_montg_init( t_uint *mm, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001442{
Paul Bakkera755ca12011-04-24 09:11:17 +00001443 t_uint x, m0 = N->p[0];
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001444 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001445
1446 x = m0;
1447 x += ( ( m0 + 2 ) & 4 ) << 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001448
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001449 for( i = biL; i >= 8; i /= 2 )
1450 x *= ( 2 - ( m0 * x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001451
1452 *mm = ~x + 1;
1453}
1454
1455/*
1456 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1457 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001458static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001459{
Paul Bakker23986e52011-04-24 08:57:21 +00001460 size_t i, n, m;
Paul Bakkera755ca12011-04-24 09:11:17 +00001461 t_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00001462
1463 memset( T->p, 0, T->n * ciL );
1464
1465 d = T->p;
1466 n = N->n;
1467 m = ( B->n < n ) ? B->n : n;
1468
1469 for( i = 0; i < n; i++ )
1470 {
1471 /*
1472 * T = (T + u0*B + u1*N) / 2^biL
1473 */
1474 u0 = A->p[i];
1475 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1476
1477 mpi_mul_hlp( m, B->p, d, u0 );
1478 mpi_mul_hlp( n, N->p, d, u1 );
1479
1480 *d++ = u0; d[n + 1] = 0;
1481 }
1482
1483 memcpy( A->p, d, (n + 1) * ciL );
1484
1485 if( mpi_cmp_abs( A, N ) >= 0 )
1486 mpi_sub_hlp( n, N->p, A->p );
1487 else
1488 /* prevent timing attacks */
1489 mpi_sub_hlp( n, A->p, T->p );
1490}
1491
1492/*
1493 * Montgomery reduction: A = A * R^-1 mod N
1494 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001495static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001496{
Paul Bakkera755ca12011-04-24 09:11:17 +00001497 t_uint z = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001498 mpi U;
1499
Paul Bakker8ddb6452013-02-27 14:56:33 +01001500 U.n = U.s = (int) z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001501 U.p = &z;
1502
1503 mpi_montmul( A, &U, N, mm, T );
1504}
1505
1506/*
1507 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1508 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001509int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00001510{
Paul Bakker23986e52011-04-24 08:57:21 +00001511 int ret;
1512 size_t wbits, wsize, one = 1;
1513 size_t i, j, nblimbs;
1514 size_t bufsize, nbits;
Paul Bakkera755ca12011-04-24 09:11:17 +00001515 t_uint ei, mm, state;
Paul Bakkerf6198c12012-05-16 08:02:29 +00001516 mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos;
1517 int neg;
Paul Bakker5121ce52009-01-03 21:22:43 +00001518
1519 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001520 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001521
Paul Bakkerf6198c12012-05-16 08:02:29 +00001522 if( mpi_cmp_int( E, 0 ) < 0 )
1523 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
1524
1525 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001526 * Init temps and window size
1527 */
1528 mpi_montg_init( &mm, N );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001529 mpi_init( &RR ); mpi_init( &T );
Manuel Pégourié-Gonnardfd6a1912014-01-18 19:05:23 +01001530 mpi_init( &Apos );
Paul Bakker5121ce52009-01-03 21:22:43 +00001531 memset( W, 0, sizeof( W ) );
1532
1533 i = mpi_msb( E );
1534
1535 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1536 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1537
Paul Bakkerb6d5f082011-11-25 11:52:11 +00001538 if( wsize > POLARSSL_MPI_WINDOW_SIZE )
1539 wsize = POLARSSL_MPI_WINDOW_SIZE;
1540
Paul Bakker5121ce52009-01-03 21:22:43 +00001541 j = N->n + 1;
1542 MPI_CHK( mpi_grow( X, j ) );
1543 MPI_CHK( mpi_grow( &W[1], j ) );
1544 MPI_CHK( mpi_grow( &T, j * 2 ) );
1545
1546 /*
Paul Bakker50546922012-05-19 08:40:49 +00001547 * Compensate for negative A (and correct at the end)
1548 */
1549 neg = ( A->s == -1 );
Paul Bakker50546922012-05-19 08:40:49 +00001550 if( neg )
1551 {
1552 MPI_CHK( mpi_copy( &Apos, A ) );
1553 Apos.s = 1;
1554 A = &Apos;
1555 }
1556
1557 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001558 * If 1st call, pre-compute R^2 mod N
1559 */
1560 if( _RR == NULL || _RR->p == NULL )
1561 {
1562 MPI_CHK( mpi_lset( &RR, 1 ) );
1563 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1564 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1565
1566 if( _RR != NULL )
1567 memcpy( _RR, &RR, sizeof( mpi ) );
1568 }
1569 else
1570 memcpy( &RR, _RR, sizeof( mpi ) );
1571
1572 /*
1573 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1574 */
1575 if( mpi_cmp_mpi( A, N ) >= 0 )
Paul Bakkerc2024f42014-01-23 20:38:35 +01001576 MPI_CHK( mpi_mod_mpi( &W[1], A, N ) );
1577 else
1578 MPI_CHK( mpi_copy( &W[1], A ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001579
1580 mpi_montmul( &W[1], &RR, N, mm, &T );
1581
1582 /*
1583 * X = R^2 * R^-1 mod N = R mod N
1584 */
1585 MPI_CHK( mpi_copy( X, &RR ) );
1586 mpi_montred( X, N, mm, &T );
1587
1588 if( wsize > 1 )
1589 {
1590 /*
1591 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1592 */
Paul Bakker23986e52011-04-24 08:57:21 +00001593 j = one << (wsize - 1);
Paul Bakker5121ce52009-01-03 21:22:43 +00001594
1595 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1596 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1597
1598 for( i = 0; i < wsize - 1; i++ )
1599 mpi_montmul( &W[j], &W[j], N, mm, &T );
Paul Bakker0d7702c2013-10-29 16:18:35 +01001600
Paul Bakker5121ce52009-01-03 21:22:43 +00001601 /*
1602 * W[i] = W[i - 1] * W[1]
1603 */
Paul Bakker23986e52011-04-24 08:57:21 +00001604 for( i = j + 1; i < (one << wsize); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001605 {
1606 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1607 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1608
1609 mpi_montmul( &W[i], &W[1], N, mm, &T );
1610 }
1611 }
1612
1613 nblimbs = E->n;
1614 bufsize = 0;
1615 nbits = 0;
1616 wbits = 0;
1617 state = 0;
1618
1619 while( 1 )
1620 {
1621 if( bufsize == 0 )
1622 {
Paul Bakker0d7702c2013-10-29 16:18:35 +01001623 if( nblimbs == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001624 break;
1625
Paul Bakker0d7702c2013-10-29 16:18:35 +01001626 nblimbs--;
1627
Paul Bakkera755ca12011-04-24 09:11:17 +00001628 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001629 }
1630
1631 bufsize--;
1632
1633 ei = (E->p[nblimbs] >> bufsize) & 1;
1634
1635 /*
1636 * skip leading 0s
1637 */
1638 if( ei == 0 && state == 0 )
1639 continue;
1640
1641 if( ei == 0 && state == 1 )
1642 {
1643 /*
1644 * out of window, square X
1645 */
1646 mpi_montmul( X, X, N, mm, &T );
1647 continue;
1648 }
1649
1650 /*
1651 * add ei to current window
1652 */
1653 state = 2;
1654
1655 nbits++;
1656 wbits |= (ei << (wsize - nbits));
1657
1658 if( nbits == wsize )
1659 {
1660 /*
1661 * X = X^wsize R^-1 mod N
1662 */
1663 for( i = 0; i < wsize; i++ )
1664 mpi_montmul( X, X, N, mm, &T );
1665
1666 /*
1667 * X = X * W[wbits] R^-1 mod N
1668 */
1669 mpi_montmul( X, &W[wbits], N, mm, &T );
1670
1671 state--;
1672 nbits = 0;
1673 wbits = 0;
1674 }
1675 }
1676
1677 /*
1678 * process the remaining bits
1679 */
1680 for( i = 0; i < nbits; i++ )
1681 {
1682 mpi_montmul( X, X, N, mm, &T );
1683
1684 wbits <<= 1;
1685
Paul Bakker23986e52011-04-24 08:57:21 +00001686 if( (wbits & (one << wsize)) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001687 mpi_montmul( X, &W[1], N, mm, &T );
1688 }
1689
1690 /*
1691 * X = A^E * R * R^-1 mod N = A^E mod N
1692 */
1693 mpi_montred( X, N, mm, &T );
1694
Paul Bakkerf6198c12012-05-16 08:02:29 +00001695 if( neg )
1696 {
1697 X->s = -1;
Paul Bakkerc2024f42014-01-23 20:38:35 +01001698 MPI_CHK( mpi_add_mpi( X, N, X ) );
Paul Bakkerf6198c12012-05-16 08:02:29 +00001699 }
1700
Paul Bakker5121ce52009-01-03 21:22:43 +00001701cleanup:
1702
Paul Bakker23986e52011-04-24 08:57:21 +00001703 for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001704 mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001705
Paul Bakkerf6198c12012-05-16 08:02:29 +00001706 mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001707
1708 if( _RR == NULL )
1709 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001710
1711 return( ret );
1712}
1713
Paul Bakker5121ce52009-01-03 21:22:43 +00001714/*
1715 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1716 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001717int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001718{
Paul Bakker23986e52011-04-24 08:57:21 +00001719 int ret;
1720 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001721 mpi TG, TA, TB;
1722
Paul Bakker6c591fa2011-05-05 11:49:20 +00001723 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001724
Paul Bakker5121ce52009-01-03 21:22:43 +00001725 MPI_CHK( mpi_copy( &TA, A ) );
1726 MPI_CHK( mpi_copy( &TB, B ) );
1727
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001728 lz = mpi_lsb( &TA );
1729 lzt = mpi_lsb( &TB );
1730
1731 if ( lzt < lz )
1732 lz = lzt;
1733
1734 MPI_CHK( mpi_shift_r( &TA, lz ) );
1735 MPI_CHK( mpi_shift_r( &TB, lz ) );
1736
Paul Bakker5121ce52009-01-03 21:22:43 +00001737 TA.s = TB.s = 1;
1738
1739 while( mpi_cmp_int( &TA, 0 ) != 0 )
1740 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001741 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1742 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001743
1744 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1745 {
1746 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1747 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1748 }
1749 else
1750 {
1751 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1752 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1753 }
1754 }
1755
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001756 MPI_CHK( mpi_shift_l( &TB, lz ) );
1757 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001758
1759cleanup:
1760
Paul Bakker6c591fa2011-05-05 11:49:20 +00001761 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001762
1763 return( ret );
1764}
1765
Paul Bakkera3d195c2011-11-27 21:07:34 +00001766int mpi_fill_random( mpi *X, size_t size,
1767 int (*f_rng)(void *, unsigned char *, size_t),
1768 void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001769{
Paul Bakker23986e52011-04-24 08:57:21 +00001770 int ret;
Paul Bakker287781a2011-03-26 13:18:49 +00001771
Paul Bakker39dfdac2012-02-12 17:17:27 +00001772 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( size ) ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001773 MPI_CHK( mpi_lset( X, 0 ) );
1774
Paul Bakker39dfdac2012-02-12 17:17:27 +00001775 MPI_CHK( f_rng( p_rng, (unsigned char *) X->p, size ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001776
1777cleanup:
1778 return( ret );
1779}
1780
Paul Bakker5121ce52009-01-03 21:22:43 +00001781/*
1782 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1783 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001784int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001785{
1786 int ret;
1787 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1788
1789 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001790 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001791
Paul Bakker6c591fa2011-05-05 11:49:20 +00001792 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1793 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1794 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001795
1796 MPI_CHK( mpi_gcd( &G, A, N ) );
1797
1798 if( mpi_cmp_int( &G, 1 ) != 0 )
1799 {
Paul Bakker40e46942009-01-03 21:51:57 +00001800 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001801 goto cleanup;
1802 }
1803
1804 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1805 MPI_CHK( mpi_copy( &TU, &TA ) );
1806 MPI_CHK( mpi_copy( &TB, N ) );
1807 MPI_CHK( mpi_copy( &TV, N ) );
1808
1809 MPI_CHK( mpi_lset( &U1, 1 ) );
1810 MPI_CHK( mpi_lset( &U2, 0 ) );
1811 MPI_CHK( mpi_lset( &V1, 0 ) );
1812 MPI_CHK( mpi_lset( &V2, 1 ) );
1813
1814 do
1815 {
1816 while( ( TU.p[0] & 1 ) == 0 )
1817 {
1818 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1819
1820 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1821 {
1822 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1823 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1824 }
1825
1826 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1827 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1828 }
1829
1830 while( ( TV.p[0] & 1 ) == 0 )
1831 {
1832 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1833
1834 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1835 {
1836 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1837 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1838 }
1839
1840 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1841 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1842 }
1843
1844 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1845 {
1846 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1847 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1848 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1849 }
1850 else
1851 {
1852 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1853 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1854 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1855 }
1856 }
1857 while( mpi_cmp_int( &TU, 0 ) != 0 );
1858
1859 while( mpi_cmp_int( &V1, 0 ) < 0 )
1860 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1861
1862 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1863 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1864
1865 MPI_CHK( mpi_copy( X, &V1 ) );
1866
1867cleanup:
1868
Paul Bakker6c591fa2011-05-05 11:49:20 +00001869 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1870 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1871 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001872
1873 return( ret );
1874}
1875
Paul Bakkerd9374b02012-11-02 11:02:58 +00001876#if defined(POLARSSL_GENPRIME)
1877
Paul Bakker5121ce52009-01-03 21:22:43 +00001878static const int small_prime[] =
1879{
1880 3, 5, 7, 11, 13, 17, 19, 23,
1881 29, 31, 37, 41, 43, 47, 53, 59,
1882 61, 67, 71, 73, 79, 83, 89, 97,
1883 101, 103, 107, 109, 113, 127, 131, 137,
1884 139, 149, 151, 157, 163, 167, 173, 179,
1885 181, 191, 193, 197, 199, 211, 223, 227,
1886 229, 233, 239, 241, 251, 257, 263, 269,
1887 271, 277, 281, 283, 293, 307, 311, 313,
1888 317, 331, 337, 347, 349, 353, 359, 367,
1889 373, 379, 383, 389, 397, 401, 409, 419,
1890 421, 431, 433, 439, 443, 449, 457, 461,
1891 463, 467, 479, 487, 491, 499, 503, 509,
1892 521, 523, 541, 547, 557, 563, 569, 571,
1893 577, 587, 593, 599, 601, 607, 613, 617,
1894 619, 631, 641, 643, 647, 653, 659, 661,
1895 673, 677, 683, 691, 701, 709, 719, 727,
1896 733, 739, 743, 751, 757, 761, 769, 773,
1897 787, 797, 809, 811, 821, 823, 827, 829,
1898 839, 853, 857, 859, 863, 877, 881, 883,
1899 887, 907, 911, 919, 929, 937, 941, 947,
1900 953, 967, 971, 977, 983, 991, 997, -103
1901};
1902
1903/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001904 * Small divisors test (X must be positive)
1905 *
1906 * Return values:
1907 * 0: no small factor (possible prime, more tests needed)
1908 * 1: certain prime
1909 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
1910 * other negative: error
Paul Bakker5121ce52009-01-03 21:22:43 +00001911 */
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001912static int mpi_check_small_factors( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +00001913{
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001914 int ret = 0;
1915 size_t i;
1916 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001917
Paul Bakker5121ce52009-01-03 21:22:43 +00001918 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001919 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001920
1921 for( i = 0; small_prime[i] > 0; i++ )
1922 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001923 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001924 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001925
1926 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1927
1928 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001929 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001930 }
1931
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001932cleanup:
1933 return( ret );
1934}
1935
1936/*
1937 * Miller-Rabin pseudo-primality test (HAC 4.24)
1938 */
1939static int mpi_miller_rabin( const mpi *X,
1940 int (*f_rng)(void *, unsigned char *, size_t),
1941 void *p_rng )
1942{
1943 int ret;
1944 size_t i, j, n, s;
1945 mpi W, R, T, A, RR;
1946
1947 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1948 mpi_init( &RR );
1949
Paul Bakker5121ce52009-01-03 21:22:43 +00001950 /*
1951 * W = |X| - 1
1952 * R = W >> lsb( W )
1953 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001954 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001955 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001956 MPI_CHK( mpi_copy( &R, &W ) );
1957 MPI_CHK( mpi_shift_r( &R, s ) );
1958
1959 i = mpi_msb( X );
1960 /*
1961 * HAC, table 4.4
1962 */
1963 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1964 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1965 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1966
1967 for( i = 0; i < n; i++ )
1968 {
1969 /*
1970 * pick a random A, 1 < A < |X| - 1
1971 */
Paul Bakker901c6562012-04-20 13:25:38 +00001972 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001973
Paul Bakkerb94081b2011-01-05 15:53:06 +00001974 if( mpi_cmp_mpi( &A, &W ) >= 0 )
1975 {
1976 j = mpi_msb( &A ) - mpi_msb( &W );
1977 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
1978 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001979 A.p[0] |= 3;
1980
1981 /*
1982 * A = A^R mod |X|
1983 */
1984 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
1985
1986 if( mpi_cmp_mpi( &A, &W ) == 0 ||
1987 mpi_cmp_int( &A, 1 ) == 0 )
1988 continue;
1989
1990 j = 1;
1991 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
1992 {
1993 /*
1994 * A = A * A mod |X|
1995 */
1996 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
1997 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
1998
1999 if( mpi_cmp_int( &A, 1 ) == 0 )
2000 break;
2001
2002 j++;
2003 }
2004
2005 /*
2006 * not prime if A != |X| - 1 or A == 1
2007 */
2008 if( mpi_cmp_mpi( &A, &W ) != 0 ||
2009 mpi_cmp_int( &A, 1 ) == 0 )
2010 {
Paul Bakker40e46942009-01-03 21:51:57 +00002011 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002012 break;
2013 }
2014 }
2015
2016cleanup:
Paul Bakker6c591fa2011-05-05 11:49:20 +00002017 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
2018 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002019
2020 return( ret );
2021}
2022
2023/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002024 * Pseudo-primality test: small factors, then Miller-Rabin
2025 */
Paul Bakker45f457d2013-11-25 14:26:52 +01002026int mpi_is_prime( mpi *X,
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002027 int (*f_rng)(void *, unsigned char *, size_t),
2028 void *p_rng )
2029{
2030 int ret;
2031 const mpi XX = { 1, X->n, X->p }; /* Abs(X) */
2032
2033 if( mpi_cmp_int( &XX, 0 ) == 0 ||
2034 mpi_cmp_int( &XX, 1 ) == 0 )
2035 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
2036
2037 if( mpi_cmp_int( &XX, 2 ) == 0 )
2038 return( 0 );
2039
2040 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2041 {
2042 if( ret == 1 )
2043 return( 0 );
2044
2045 return( ret );
2046 }
2047
2048 return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
2049}
2050
2051/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002052 * Prime number generation
2053 */
Paul Bakker23986e52011-04-24 08:57:21 +00002054int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002055 int (*f_rng)(void *, unsigned char *, size_t),
2056 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +00002057{
Paul Bakker23986e52011-04-24 08:57:21 +00002058 int ret;
2059 size_t k, n;
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002060 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002061 mpi Y;
2062
Paul Bakkerfe3256e2011-11-25 12:11:43 +00002063 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
Paul Bakker40e46942009-01-03 21:51:57 +00002064 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002065
Paul Bakker6c591fa2011-05-05 11:49:20 +00002066 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002067
2068 n = BITS_TO_LIMBS( nbits );
2069
Paul Bakker901c6562012-04-20 13:25:38 +00002070 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002071
2072 k = mpi_msb( X );
2073 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
2074 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
2075
2076 X->p[0] |= 3;
2077
2078 if( dh_flag == 0 )
2079 {
2080 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
2081 {
Paul Bakker40e46942009-01-03 21:51:57 +00002082 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002083 goto cleanup;
2084
2085 MPI_CHK( mpi_add_int( X, X, 2 ) );
2086 }
2087 }
2088 else
2089 {
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002090 /*
2091 * An necessary condition for Y and X = 2Y + 1 to be prime
2092 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2093 * Make sure it is satisfied, while keeping X = 3 mod 4
2094 */
2095 MPI_CHK( mpi_mod_int( &r, X, 3 ) );
2096 if( r == 0 )
2097 MPI_CHK( mpi_add_int( X, X, 8 ) );
2098 else if( r == 1 )
2099 MPI_CHK( mpi_add_int( X, X, 4 ) );
2100
2101 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2102 MPI_CHK( mpi_copy( &Y, X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002103 MPI_CHK( mpi_shift_r( &Y, 1 ) );
2104
2105 while( 1 )
2106 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002107 /*
2108 * First, check small factors for X and Y
2109 * before doing Miller-Rabin on any of them
2110 */
2111 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2112 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2113 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
2114 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002115 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002116 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002117 }
2118
Paul Bakker40e46942009-01-03 21:51:57 +00002119 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002120 goto cleanup;
2121
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002122 /*
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002123 * Next candidates. We want to preserve Y = (X-1) / 2 and
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002124 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2125 * so up Y by 6 and X by 12.
2126 */
2127 MPI_CHK( mpi_add_int( X, X, 12 ) );
2128 MPI_CHK( mpi_add_int( &Y, &Y, 6 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002129 }
2130 }
2131
2132cleanup:
2133
Paul Bakker6c591fa2011-05-05 11:49:20 +00002134 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002135
2136 return( ret );
2137}
2138
Manuel Pégourié-Gonnarddf0142b2013-08-22 18:29:07 +02002139#endif /* POLARSSL_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00002140
Paul Bakker40e46942009-01-03 21:51:57 +00002141#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002142
Paul Bakker23986e52011-04-24 08:57:21 +00002143#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002144
2145static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2146{
2147 { 693, 609, 21 },
2148 { 1764, 868, 28 },
2149 { 768454923, 542167814, 1 }
2150};
2151
Paul Bakker5121ce52009-01-03 21:22:43 +00002152/*
2153 * Checkup routine
2154 */
2155int mpi_self_test( int verbose )
2156{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002157 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00002158 mpi A, E, N, X, Y, U, V;
2159
Paul Bakker6c591fa2011-05-05 11:49:20 +00002160 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
2161 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002162
2163 MPI_CHK( mpi_read_string( &A, 16,
2164 "EFE021C2645FD1DC586E69184AF4A31E" \
2165 "D5F53E93B5F123FA41680867BA110131" \
2166 "944FE7952E2517337780CB0DB80E61AA" \
2167 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2168
2169 MPI_CHK( mpi_read_string( &E, 16,
2170 "B2E7EFD37075B9F03FF989C7C5051C20" \
2171 "34D2A323810251127E7BF8625A4F49A5" \
2172 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2173 "5B5C25763222FEFCCFC38B832366C29E" ) );
2174
2175 MPI_CHK( mpi_read_string( &N, 16,
2176 "0066A198186C18C10B2F5ED9B522752A" \
2177 "9830B69916E535C8F047518A889A43A5" \
2178 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2179
2180 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
2181
2182 MPI_CHK( mpi_read_string( &U, 16,
2183 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2184 "9E857EA95A03512E2BAE7391688D264A" \
2185 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2186 "8001B72E848A38CAE1C65F78E56ABDEF" \
2187 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2188 "ECF677152EF804370C1A305CAF3B5BF1" \
2189 "30879B56C61DE584A0F53A2447A51E" ) );
2190
2191 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002192 polarssl_printf( " MPI test #1 (mul_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002193
2194 if( mpi_cmp_mpi( &X, &U ) != 0 )
2195 {
2196 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002197 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002198
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002199 ret = 1;
2200 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002201 }
2202
2203 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002204 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002205
2206 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
2207
2208 MPI_CHK( mpi_read_string( &U, 16,
2209 "256567336059E52CAE22925474705F39A94" ) );
2210
2211 MPI_CHK( mpi_read_string( &V, 16,
2212 "6613F26162223DF488E9CD48CC132C7A" \
2213 "0AC93C701B001B092E4E5B9F73BCD27B" \
2214 "9EE50D0657C77F374E903CDFA4C642" ) );
2215
2216 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002217 polarssl_printf( " MPI test #2 (div_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002218
2219 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2220 mpi_cmp_mpi( &Y, &V ) != 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_exp_mod( &X, &A, &E, &N, NULL ) );
2233
2234 MPI_CHK( mpi_read_string( &U, 16,
2235 "36E139AEA55215609D2816998ED020BB" \
2236 "BD96C37890F65171D948E9BC7CBAA4D9" \
2237 "325D24D6A3C12710F10A09FA08AB87" ) );
2238
2239 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002240 polarssl_printf( " MPI test #3 (exp_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002241
2242 if( mpi_cmp_mpi( &X, &U ) != 0 )
2243 {
2244 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002245 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002246
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002247 ret = 1;
2248 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002249 }
2250
2251 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002252 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002253
2254 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2255
2256 MPI_CHK( mpi_read_string( &U, 16,
2257 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2258 "C3DBA76456363A10869622EAC2DD84EC" \
2259 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2260
2261 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002262 polarssl_printf( " MPI test #4 (inv_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002263
2264 if( mpi_cmp_mpi( &X, &U ) != 0 )
2265 {
2266 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002267 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002268
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002269 ret = 1;
2270 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002271 }
2272
2273 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002274 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002275
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002276 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002277 polarssl_printf( " MPI test #5 (simple gcd): " );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002278
2279 for ( i = 0; i < GCD_PAIR_COUNT; i++)
2280 {
2281 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002282 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002283
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002284 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002285
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002286 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2287 {
2288 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002289 polarssl_printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002290
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002291 ret = 1;
2292 goto cleanup;
2293 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002294 }
2295
2296 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002297 polarssl_printf( "passed\n" );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002298
Paul Bakker5121ce52009-01-03 21:22:43 +00002299cleanup:
2300
2301 if( ret != 0 && verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002302 polarssl_printf( "Unexpected error, return code = %08X\n", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002303
Paul Bakker6c591fa2011-05-05 11:49:20 +00002304 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2305 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002306
2307 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002308 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002309
2310 return( ret );
2311}
2312
2313#endif
2314
2315#endif