blob: cb55586ffb56143819f85db5ec314ba9e47633b2 [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];
Paul Bakker5121ce52009-01-03 21:22:43 +00001444
1445 x = m0;
1446 x += ( ( m0 + 2 ) & 4 ) << 1;
1447 x *= ( 2 - ( m0 * x ) );
1448
1449 if( biL >= 16 ) x *= ( 2 - ( m0 * x ) );
1450 if( biL >= 32 ) x *= ( 2 - ( m0 * x ) );
1451 if( biL >= 64 ) x *= ( 2 - ( m0 * x ) );
1452
1453 *mm = ~x + 1;
1454}
1455
1456/*
1457 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1458 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001459static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001460{
Paul Bakker23986e52011-04-24 08:57:21 +00001461 size_t i, n, m;
Paul Bakkera755ca12011-04-24 09:11:17 +00001462 t_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00001463
1464 memset( T->p, 0, T->n * ciL );
1465
1466 d = T->p;
1467 n = N->n;
1468 m = ( B->n < n ) ? B->n : n;
1469
1470 for( i = 0; i < n; i++ )
1471 {
1472 /*
1473 * T = (T + u0*B + u1*N) / 2^biL
1474 */
1475 u0 = A->p[i];
1476 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1477
1478 mpi_mul_hlp( m, B->p, d, u0 );
1479 mpi_mul_hlp( n, N->p, d, u1 );
1480
1481 *d++ = u0; d[n + 1] = 0;
1482 }
1483
1484 memcpy( A->p, d, (n + 1) * ciL );
1485
1486 if( mpi_cmp_abs( A, N ) >= 0 )
1487 mpi_sub_hlp( n, N->p, A->p );
1488 else
1489 /* prevent timing attacks */
1490 mpi_sub_hlp( n, A->p, T->p );
1491}
1492
1493/*
1494 * Montgomery reduction: A = A * R^-1 mod N
1495 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001496static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001497{
Paul Bakkera755ca12011-04-24 09:11:17 +00001498 t_uint z = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001499 mpi U;
1500
Paul Bakker8ddb6452013-02-27 14:56:33 +01001501 U.n = U.s = (int) z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001502 U.p = &z;
1503
1504 mpi_montmul( A, &U, N, mm, T );
1505}
1506
1507/*
1508 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1509 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001510int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00001511{
Paul Bakker23986e52011-04-24 08:57:21 +00001512 int ret;
1513 size_t wbits, wsize, one = 1;
1514 size_t i, j, nblimbs;
1515 size_t bufsize, nbits;
Paul Bakkera755ca12011-04-24 09:11:17 +00001516 t_uint ei, mm, state;
Paul Bakkerf6198c12012-05-16 08:02:29 +00001517 mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos;
1518 int neg;
Paul Bakker5121ce52009-01-03 21:22:43 +00001519
1520 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001521 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001522
Paul Bakkerf6198c12012-05-16 08:02:29 +00001523 if( mpi_cmp_int( E, 0 ) < 0 )
1524 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
1525
1526 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001527 * Init temps and window size
1528 */
1529 mpi_montg_init( &mm, N );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001530 mpi_init( &RR ); mpi_init( &T );
Manuel Pégourié-Gonnardfd6a1912014-01-18 19:05:23 +01001531 mpi_init( &Apos );
Paul Bakker5121ce52009-01-03 21:22:43 +00001532 memset( W, 0, sizeof( W ) );
1533
1534 i = mpi_msb( E );
1535
1536 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1537 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1538
Paul Bakkerb6d5f082011-11-25 11:52:11 +00001539 if( wsize > POLARSSL_MPI_WINDOW_SIZE )
1540 wsize = POLARSSL_MPI_WINDOW_SIZE;
1541
Paul Bakker5121ce52009-01-03 21:22:43 +00001542 j = N->n + 1;
1543 MPI_CHK( mpi_grow( X, j ) );
1544 MPI_CHK( mpi_grow( &W[1], j ) );
1545 MPI_CHK( mpi_grow( &T, j * 2 ) );
1546
1547 /*
Paul Bakker50546922012-05-19 08:40:49 +00001548 * Compensate for negative A (and correct at the end)
1549 */
1550 neg = ( A->s == -1 );
Paul Bakker50546922012-05-19 08:40:49 +00001551 if( neg )
1552 {
1553 MPI_CHK( mpi_copy( &Apos, A ) );
1554 Apos.s = 1;
1555 A = &Apos;
1556 }
1557
1558 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001559 * If 1st call, pre-compute R^2 mod N
1560 */
1561 if( _RR == NULL || _RR->p == NULL )
1562 {
1563 MPI_CHK( mpi_lset( &RR, 1 ) );
1564 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1565 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1566
1567 if( _RR != NULL )
1568 memcpy( _RR, &RR, sizeof( mpi ) );
1569 }
1570 else
1571 memcpy( &RR, _RR, sizeof( mpi ) );
1572
1573 /*
1574 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1575 */
1576 if( mpi_cmp_mpi( A, N ) >= 0 )
Paul Bakkerc2024f42014-01-23 20:38:35 +01001577 MPI_CHK( mpi_mod_mpi( &W[1], A, N ) );
1578 else
1579 MPI_CHK( mpi_copy( &W[1], A ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001580
1581 mpi_montmul( &W[1], &RR, N, mm, &T );
1582
1583 /*
1584 * X = R^2 * R^-1 mod N = R mod N
1585 */
1586 MPI_CHK( mpi_copy( X, &RR ) );
1587 mpi_montred( X, N, mm, &T );
1588
1589 if( wsize > 1 )
1590 {
1591 /*
1592 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1593 */
Paul Bakker23986e52011-04-24 08:57:21 +00001594 j = one << (wsize - 1);
Paul Bakker5121ce52009-01-03 21:22:43 +00001595
1596 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1597 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1598
1599 for( i = 0; i < wsize - 1; i++ )
1600 mpi_montmul( &W[j], &W[j], N, mm, &T );
Paul Bakker0d7702c2013-10-29 16:18:35 +01001601
Paul Bakker5121ce52009-01-03 21:22:43 +00001602 /*
1603 * W[i] = W[i - 1] * W[1]
1604 */
Paul Bakker23986e52011-04-24 08:57:21 +00001605 for( i = j + 1; i < (one << wsize); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001606 {
1607 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1608 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1609
1610 mpi_montmul( &W[i], &W[1], N, mm, &T );
1611 }
1612 }
1613
1614 nblimbs = E->n;
1615 bufsize = 0;
1616 nbits = 0;
1617 wbits = 0;
1618 state = 0;
1619
1620 while( 1 )
1621 {
1622 if( bufsize == 0 )
1623 {
Paul Bakker0d7702c2013-10-29 16:18:35 +01001624 if( nblimbs == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001625 break;
1626
Paul Bakker0d7702c2013-10-29 16:18:35 +01001627 nblimbs--;
1628
Paul Bakkera755ca12011-04-24 09:11:17 +00001629 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001630 }
1631
1632 bufsize--;
1633
1634 ei = (E->p[nblimbs] >> bufsize) & 1;
1635
1636 /*
1637 * skip leading 0s
1638 */
1639 if( ei == 0 && state == 0 )
1640 continue;
1641
1642 if( ei == 0 && state == 1 )
1643 {
1644 /*
1645 * out of window, square X
1646 */
1647 mpi_montmul( X, X, N, mm, &T );
1648 continue;
1649 }
1650
1651 /*
1652 * add ei to current window
1653 */
1654 state = 2;
1655
1656 nbits++;
1657 wbits |= (ei << (wsize - nbits));
1658
1659 if( nbits == wsize )
1660 {
1661 /*
1662 * X = X^wsize R^-1 mod N
1663 */
1664 for( i = 0; i < wsize; i++ )
1665 mpi_montmul( X, X, N, mm, &T );
1666
1667 /*
1668 * X = X * W[wbits] R^-1 mod N
1669 */
1670 mpi_montmul( X, &W[wbits], N, mm, &T );
1671
1672 state--;
1673 nbits = 0;
1674 wbits = 0;
1675 }
1676 }
1677
1678 /*
1679 * process the remaining bits
1680 */
1681 for( i = 0; i < nbits; i++ )
1682 {
1683 mpi_montmul( X, X, N, mm, &T );
1684
1685 wbits <<= 1;
1686
Paul Bakker23986e52011-04-24 08:57:21 +00001687 if( (wbits & (one << wsize)) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001688 mpi_montmul( X, &W[1], N, mm, &T );
1689 }
1690
1691 /*
1692 * X = A^E * R * R^-1 mod N = A^E mod N
1693 */
1694 mpi_montred( X, N, mm, &T );
1695
Paul Bakkerf6198c12012-05-16 08:02:29 +00001696 if( neg )
1697 {
1698 X->s = -1;
Paul Bakkerc2024f42014-01-23 20:38:35 +01001699 MPI_CHK( mpi_add_mpi( X, N, X ) );
Paul Bakkerf6198c12012-05-16 08:02:29 +00001700 }
1701
Paul Bakker5121ce52009-01-03 21:22:43 +00001702cleanup:
1703
Paul Bakker23986e52011-04-24 08:57:21 +00001704 for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001705 mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001706
Paul Bakkerf6198c12012-05-16 08:02:29 +00001707 mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001708
1709 if( _RR == NULL )
1710 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001711
1712 return( ret );
1713}
1714
Paul Bakker5121ce52009-01-03 21:22:43 +00001715/*
1716 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1717 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001718int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001719{
Paul Bakker23986e52011-04-24 08:57:21 +00001720 int ret;
1721 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001722 mpi TG, TA, TB;
1723
Paul Bakker6c591fa2011-05-05 11:49:20 +00001724 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001725
Paul Bakker5121ce52009-01-03 21:22:43 +00001726 MPI_CHK( mpi_copy( &TA, A ) );
1727 MPI_CHK( mpi_copy( &TB, B ) );
1728
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001729 lz = mpi_lsb( &TA );
1730 lzt = mpi_lsb( &TB );
1731
1732 if ( lzt < lz )
1733 lz = lzt;
1734
1735 MPI_CHK( mpi_shift_r( &TA, lz ) );
1736 MPI_CHK( mpi_shift_r( &TB, lz ) );
1737
Paul Bakker5121ce52009-01-03 21:22:43 +00001738 TA.s = TB.s = 1;
1739
1740 while( mpi_cmp_int( &TA, 0 ) != 0 )
1741 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001742 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1743 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001744
1745 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1746 {
1747 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1748 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1749 }
1750 else
1751 {
1752 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1753 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1754 }
1755 }
1756
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001757 MPI_CHK( mpi_shift_l( &TB, lz ) );
1758 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001759
1760cleanup:
1761
Paul Bakker6c591fa2011-05-05 11:49:20 +00001762 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001763
1764 return( ret );
1765}
1766
Paul Bakkera3d195c2011-11-27 21:07:34 +00001767int mpi_fill_random( mpi *X, size_t size,
1768 int (*f_rng)(void *, unsigned char *, size_t),
1769 void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001770{
Paul Bakker23986e52011-04-24 08:57:21 +00001771 int ret;
Paul Bakker287781a2011-03-26 13:18:49 +00001772
Paul Bakker39dfdac2012-02-12 17:17:27 +00001773 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( size ) ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001774 MPI_CHK( mpi_lset( X, 0 ) );
1775
Paul Bakker39dfdac2012-02-12 17:17:27 +00001776 MPI_CHK( f_rng( p_rng, (unsigned char *) X->p, size ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001777
1778cleanup:
1779 return( ret );
1780}
1781
Paul Bakker5121ce52009-01-03 21:22:43 +00001782/*
1783 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1784 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001785int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001786{
1787 int ret;
1788 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1789
1790 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001791 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001792
Paul Bakker6c591fa2011-05-05 11:49:20 +00001793 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1794 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1795 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001796
1797 MPI_CHK( mpi_gcd( &G, A, N ) );
1798
1799 if( mpi_cmp_int( &G, 1 ) != 0 )
1800 {
Paul Bakker40e46942009-01-03 21:51:57 +00001801 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001802 goto cleanup;
1803 }
1804
1805 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1806 MPI_CHK( mpi_copy( &TU, &TA ) );
1807 MPI_CHK( mpi_copy( &TB, N ) );
1808 MPI_CHK( mpi_copy( &TV, N ) );
1809
1810 MPI_CHK( mpi_lset( &U1, 1 ) );
1811 MPI_CHK( mpi_lset( &U2, 0 ) );
1812 MPI_CHK( mpi_lset( &V1, 0 ) );
1813 MPI_CHK( mpi_lset( &V2, 1 ) );
1814
1815 do
1816 {
1817 while( ( TU.p[0] & 1 ) == 0 )
1818 {
1819 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1820
1821 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1822 {
1823 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1824 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1825 }
1826
1827 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1828 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1829 }
1830
1831 while( ( TV.p[0] & 1 ) == 0 )
1832 {
1833 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1834
1835 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1836 {
1837 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1838 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1839 }
1840
1841 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1842 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1843 }
1844
1845 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1846 {
1847 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1848 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1849 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1850 }
1851 else
1852 {
1853 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1854 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1855 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1856 }
1857 }
1858 while( mpi_cmp_int( &TU, 0 ) != 0 );
1859
1860 while( mpi_cmp_int( &V1, 0 ) < 0 )
1861 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1862
1863 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1864 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1865
1866 MPI_CHK( mpi_copy( X, &V1 ) );
1867
1868cleanup:
1869
Paul Bakker6c591fa2011-05-05 11:49:20 +00001870 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1871 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1872 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001873
1874 return( ret );
1875}
1876
Paul Bakkerd9374b02012-11-02 11:02:58 +00001877#if defined(POLARSSL_GENPRIME)
1878
Paul Bakker5121ce52009-01-03 21:22:43 +00001879static const int small_prime[] =
1880{
1881 3, 5, 7, 11, 13, 17, 19, 23,
1882 29, 31, 37, 41, 43, 47, 53, 59,
1883 61, 67, 71, 73, 79, 83, 89, 97,
1884 101, 103, 107, 109, 113, 127, 131, 137,
1885 139, 149, 151, 157, 163, 167, 173, 179,
1886 181, 191, 193, 197, 199, 211, 223, 227,
1887 229, 233, 239, 241, 251, 257, 263, 269,
1888 271, 277, 281, 283, 293, 307, 311, 313,
1889 317, 331, 337, 347, 349, 353, 359, 367,
1890 373, 379, 383, 389, 397, 401, 409, 419,
1891 421, 431, 433, 439, 443, 449, 457, 461,
1892 463, 467, 479, 487, 491, 499, 503, 509,
1893 521, 523, 541, 547, 557, 563, 569, 571,
1894 577, 587, 593, 599, 601, 607, 613, 617,
1895 619, 631, 641, 643, 647, 653, 659, 661,
1896 673, 677, 683, 691, 701, 709, 719, 727,
1897 733, 739, 743, 751, 757, 761, 769, 773,
1898 787, 797, 809, 811, 821, 823, 827, 829,
1899 839, 853, 857, 859, 863, 877, 881, 883,
1900 887, 907, 911, 919, 929, 937, 941, 947,
1901 953, 967, 971, 977, 983, 991, 997, -103
1902};
1903
1904/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001905 * Small divisors test (X must be positive)
1906 *
1907 * Return values:
1908 * 0: no small factor (possible prime, more tests needed)
1909 * 1: certain prime
1910 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
1911 * other negative: error
Paul Bakker5121ce52009-01-03 21:22:43 +00001912 */
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001913static int mpi_check_small_factors( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +00001914{
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001915 int ret = 0;
1916 size_t i;
1917 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001918
Paul Bakker5121ce52009-01-03 21:22:43 +00001919 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001920 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001921
1922 for( i = 0; small_prime[i] > 0; i++ )
1923 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001924 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001925 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001926
1927 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1928
1929 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001930 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001931 }
1932
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001933cleanup:
1934 return( ret );
1935}
1936
1937/*
1938 * Miller-Rabin pseudo-primality test (HAC 4.24)
1939 */
1940static int mpi_miller_rabin( const mpi *X,
1941 int (*f_rng)(void *, unsigned char *, size_t),
1942 void *p_rng )
1943{
1944 int ret;
1945 size_t i, j, n, s;
1946 mpi W, R, T, A, RR;
1947
1948 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1949 mpi_init( &RR );
1950
Paul Bakker5121ce52009-01-03 21:22:43 +00001951 /*
1952 * W = |X| - 1
1953 * R = W >> lsb( W )
1954 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001955 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001956 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001957 MPI_CHK( mpi_copy( &R, &W ) );
1958 MPI_CHK( mpi_shift_r( &R, s ) );
1959
1960 i = mpi_msb( X );
1961 /*
1962 * HAC, table 4.4
1963 */
1964 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1965 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1966 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1967
1968 for( i = 0; i < n; i++ )
1969 {
1970 /*
1971 * pick a random A, 1 < A < |X| - 1
1972 */
Paul Bakker901c6562012-04-20 13:25:38 +00001973 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001974
Paul Bakkerb94081b2011-01-05 15:53:06 +00001975 if( mpi_cmp_mpi( &A, &W ) >= 0 )
1976 {
1977 j = mpi_msb( &A ) - mpi_msb( &W );
1978 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
1979 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001980 A.p[0] |= 3;
1981
1982 /*
1983 * A = A^R mod |X|
1984 */
1985 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
1986
1987 if( mpi_cmp_mpi( &A, &W ) == 0 ||
1988 mpi_cmp_int( &A, 1 ) == 0 )
1989 continue;
1990
1991 j = 1;
1992 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
1993 {
1994 /*
1995 * A = A * A mod |X|
1996 */
1997 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
1998 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
1999
2000 if( mpi_cmp_int( &A, 1 ) == 0 )
2001 break;
2002
2003 j++;
2004 }
2005
2006 /*
2007 * not prime if A != |X| - 1 or A == 1
2008 */
2009 if( mpi_cmp_mpi( &A, &W ) != 0 ||
2010 mpi_cmp_int( &A, 1 ) == 0 )
2011 {
Paul Bakker40e46942009-01-03 21:51:57 +00002012 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002013 break;
2014 }
2015 }
2016
2017cleanup:
Paul Bakker6c591fa2011-05-05 11:49:20 +00002018 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
2019 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002020
2021 return( ret );
2022}
2023
2024/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002025 * Pseudo-primality test: small factors, then Miller-Rabin
2026 */
Paul Bakker45f457d2013-11-25 14:26:52 +01002027int mpi_is_prime( mpi *X,
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002028 int (*f_rng)(void *, unsigned char *, size_t),
2029 void *p_rng )
2030{
2031 int ret;
2032 const mpi XX = { 1, X->n, X->p }; /* Abs(X) */
2033
2034 if( mpi_cmp_int( &XX, 0 ) == 0 ||
2035 mpi_cmp_int( &XX, 1 ) == 0 )
2036 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
2037
2038 if( mpi_cmp_int( &XX, 2 ) == 0 )
2039 return( 0 );
2040
2041 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2042 {
2043 if( ret == 1 )
2044 return( 0 );
2045
2046 return( ret );
2047 }
2048
2049 return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
2050}
2051
2052/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002053 * Prime number generation
2054 */
Paul Bakker23986e52011-04-24 08:57:21 +00002055int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002056 int (*f_rng)(void *, unsigned char *, size_t),
2057 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +00002058{
Paul Bakker23986e52011-04-24 08:57:21 +00002059 int ret;
2060 size_t k, n;
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002061 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002062 mpi Y;
2063
Paul Bakkerfe3256e2011-11-25 12:11:43 +00002064 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
Paul Bakker40e46942009-01-03 21:51:57 +00002065 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002066
Paul Bakker6c591fa2011-05-05 11:49:20 +00002067 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002068
2069 n = BITS_TO_LIMBS( nbits );
2070
Paul Bakker901c6562012-04-20 13:25:38 +00002071 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002072
2073 k = mpi_msb( X );
2074 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
2075 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
2076
2077 X->p[0] |= 3;
2078
2079 if( dh_flag == 0 )
2080 {
2081 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
2082 {
Paul Bakker40e46942009-01-03 21:51:57 +00002083 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002084 goto cleanup;
2085
2086 MPI_CHK( mpi_add_int( X, X, 2 ) );
2087 }
2088 }
2089 else
2090 {
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002091 /*
2092 * An necessary condition for Y and X = 2Y + 1 to be prime
2093 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2094 * Make sure it is satisfied, while keeping X = 3 mod 4
2095 */
2096 MPI_CHK( mpi_mod_int( &r, X, 3 ) );
2097 if( r == 0 )
2098 MPI_CHK( mpi_add_int( X, X, 8 ) );
2099 else if( r == 1 )
2100 MPI_CHK( mpi_add_int( X, X, 4 ) );
2101
2102 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2103 MPI_CHK( mpi_copy( &Y, X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002104 MPI_CHK( mpi_shift_r( &Y, 1 ) );
2105
2106 while( 1 )
2107 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002108 /*
2109 * First, check small factors for X and Y
2110 * before doing Miller-Rabin on any of them
2111 */
2112 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2113 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2114 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
2115 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002116 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002117 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002118 }
2119
Paul Bakker40e46942009-01-03 21:51:57 +00002120 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002121 goto cleanup;
2122
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002123 /*
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002124 * Next candidates. We want to preserve Y = (X-1) / 2 and
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002125 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2126 * so up Y by 6 and X by 12.
2127 */
2128 MPI_CHK( mpi_add_int( X, X, 12 ) );
2129 MPI_CHK( mpi_add_int( &Y, &Y, 6 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002130 }
2131 }
2132
2133cleanup:
2134
Paul Bakker6c591fa2011-05-05 11:49:20 +00002135 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002136
2137 return( ret );
2138}
2139
Manuel Pégourié-Gonnarddf0142b2013-08-22 18:29:07 +02002140#endif /* POLARSSL_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00002141
Paul Bakker40e46942009-01-03 21:51:57 +00002142#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002143
Paul Bakker23986e52011-04-24 08:57:21 +00002144#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002145
2146static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2147{
2148 { 693, 609, 21 },
2149 { 1764, 868, 28 },
2150 { 768454923, 542167814, 1 }
2151};
2152
Paul Bakker5121ce52009-01-03 21:22:43 +00002153/*
2154 * Checkup routine
2155 */
2156int mpi_self_test( int verbose )
2157{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002158 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00002159 mpi A, E, N, X, Y, U, V;
2160
Paul Bakker6c591fa2011-05-05 11:49:20 +00002161 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
2162 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002163
2164 MPI_CHK( mpi_read_string( &A, 16,
2165 "EFE021C2645FD1DC586E69184AF4A31E" \
2166 "D5F53E93B5F123FA41680867BA110131" \
2167 "944FE7952E2517337780CB0DB80E61AA" \
2168 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2169
2170 MPI_CHK( mpi_read_string( &E, 16,
2171 "B2E7EFD37075B9F03FF989C7C5051C20" \
2172 "34D2A323810251127E7BF8625A4F49A5" \
2173 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2174 "5B5C25763222FEFCCFC38B832366C29E" ) );
2175
2176 MPI_CHK( mpi_read_string( &N, 16,
2177 "0066A198186C18C10B2F5ED9B522752A" \
2178 "9830B69916E535C8F047518A889A43A5" \
2179 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2180
2181 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
2182
2183 MPI_CHK( mpi_read_string( &U, 16,
2184 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2185 "9E857EA95A03512E2BAE7391688D264A" \
2186 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2187 "8001B72E848A38CAE1C65F78E56ABDEF" \
2188 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2189 "ECF677152EF804370C1A305CAF3B5BF1" \
2190 "30879B56C61DE584A0F53A2447A51E" ) );
2191
2192 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002193 polarssl_printf( " MPI test #1 (mul_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002194
2195 if( mpi_cmp_mpi( &X, &U ) != 0 )
2196 {
2197 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002198 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002199
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002200 ret = 1;
2201 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002202 }
2203
2204 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002205 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002206
2207 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
2208
2209 MPI_CHK( mpi_read_string( &U, 16,
2210 "256567336059E52CAE22925474705F39A94" ) );
2211
2212 MPI_CHK( mpi_read_string( &V, 16,
2213 "6613F26162223DF488E9CD48CC132C7A" \
2214 "0AC93C701B001B092E4E5B9F73BCD27B" \
2215 "9EE50D0657C77F374E903CDFA4C642" ) );
2216
2217 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002218 polarssl_printf( " MPI test #2 (div_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002219
2220 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2221 mpi_cmp_mpi( &Y, &V ) != 0 )
2222 {
2223 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002224 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002225
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002226 ret = 1;
2227 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002228 }
2229
2230 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002231 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002232
2233 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2234
2235 MPI_CHK( mpi_read_string( &U, 16,
2236 "36E139AEA55215609D2816998ED020BB" \
2237 "BD96C37890F65171D948E9BC7CBAA4D9" \
2238 "325D24D6A3C12710F10A09FA08AB87" ) );
2239
2240 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002241 polarssl_printf( " MPI test #3 (exp_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002242
2243 if( mpi_cmp_mpi( &X, &U ) != 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_inv_mod( &X, &A, &N ) );
2256
2257 MPI_CHK( mpi_read_string( &U, 16,
2258 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2259 "C3DBA76456363A10869622EAC2DD84EC" \
2260 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2261
2262 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002263 polarssl_printf( " MPI test #4 (inv_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
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002277 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002278 polarssl_printf( " MPI test #5 (simple gcd): " );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002279
2280 for ( i = 0; i < GCD_PAIR_COUNT; i++)
2281 {
2282 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002283 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002284
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002285 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002286
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002287 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2288 {
2289 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002290 polarssl_printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002291
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002292 ret = 1;
2293 goto cleanup;
2294 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002295 }
2296
2297 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002298 polarssl_printf( "passed\n" );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002299
Paul Bakker5121ce52009-01-03 21:22:43 +00002300cleanup:
2301
2302 if( ret != 0 && verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002303 polarssl_printf( "Unexpected error, return code = %08X\n", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002304
Paul Bakker6c591fa2011-05-05 11:49:20 +00002305 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2306 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002307
2308 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002309 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002310
2311 return( ret );
2312}
2313
2314#endif
2315
2316#endif