blob: d9a22c1dd3325fede02f59c7c510450f4f32d8cf [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 {
Manuel Pégourié-Gonnardbb8661e2014-03-14 09:21:20 +01001235 /*
1236 * The version of Clang shipped by Apple with Mavericks can't
1237 * handle 128-bit division properly. Disable 128-bits division
1238 * for Clang on Apple for now, while waiting for more input on the
1239 * exact version(s) affected and their identification macros.
1240 */
1241#if defined(POLARSSL_HAVE_UDBL) && \
1242 ! ( defined(__x86_64__) && defined(__clang__) && defined(__APPLE__) )
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001243 t_udbl r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001244
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001245 r = (t_udbl) X.p[i] << biL;
1246 r |= (t_udbl) X.p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001247 r /= Y.p[t];
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001248 if( r > ((t_udbl) 1 << biL) - 1)
1249 r = ((t_udbl) 1 << biL) - 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001250
Paul Bakkera755ca12011-04-24 09:11:17 +00001251 Z.p[i - t - 1] = (t_uint) r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001252#else
1253 /*
1254 * __udiv_qrnnd_c, from gmp/longlong.h
1255 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001256 t_uint q0, q1, r0, r1;
1257 t_uint d0, d1, d, m;
Paul Bakker5121ce52009-01-03 21:22:43 +00001258
1259 d = Y.p[t];
1260 d0 = ( d << biH ) >> biH;
1261 d1 = ( d >> biH );
1262
1263 q1 = X.p[i] / d1;
1264 r1 = X.p[i] - d1 * q1;
1265 r1 <<= biH;
1266 r1 |= ( X.p[i - 1] >> biH );
1267
1268 m = q1 * d0;
1269 if( r1 < m )
1270 {
1271 q1--, r1 += d;
1272 while( r1 >= d && r1 < m )
1273 q1--, r1 += d;
1274 }
1275 r1 -= m;
1276
1277 q0 = r1 / d1;
1278 r0 = r1 - d1 * q0;
1279 r0 <<= biH;
1280 r0 |= ( X.p[i - 1] << biH ) >> biH;
1281
1282 m = q0 * d0;
1283 if( r0 < m )
1284 {
1285 q0--, r0 += d;
1286 while( r0 >= d && r0 < m )
1287 q0--, r0 += d;
1288 }
1289 r0 -= m;
1290
1291 Z.p[i - t - 1] = ( q1 << biH ) | q0;
1292#endif
1293 }
1294
1295 Z.p[i - t - 1]++;
1296 do
1297 {
1298 Z.p[i - t - 1]--;
1299
1300 MPI_CHK( mpi_lset( &T1, 0 ) );
1301 T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
1302 T1.p[1] = Y.p[t];
1303 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1304
1305 MPI_CHK( mpi_lset( &T2, 0 ) );
1306 T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
1307 T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
1308 T2.p[2] = X.p[i];
1309 }
1310 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1311
1312 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1313 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1314 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1315
1316 if( mpi_cmp_int( &X, 0 ) < 0 )
1317 {
1318 MPI_CHK( mpi_copy( &T1, &Y ) );
1319 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1320 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1321 Z.p[i - t - 1]--;
1322 }
1323 }
1324
1325 if( Q != NULL )
1326 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001327 MPI_CHK( mpi_copy( Q, &Z ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001328 Q->s = A->s * B->s;
1329 }
1330
1331 if( R != NULL )
1332 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001333 MPI_CHK( mpi_shift_r( &X, k ) );
Paul Bakkerf02c5642012-11-13 10:25:21 +00001334 X.s = A->s;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001335 MPI_CHK( mpi_copy( R, &X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001336
Paul Bakker5121ce52009-01-03 21:22:43 +00001337 if( mpi_cmp_int( R, 0 ) == 0 )
1338 R->s = 1;
1339 }
1340
1341cleanup:
1342
Paul Bakker6c591fa2011-05-05 11:49:20 +00001343 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
1344 mpi_free( &T1 ); mpi_free( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001345
1346 return( ret );
1347}
1348
1349/*
1350 * Division by int: A = Q * b + R
Paul Bakker5121ce52009-01-03 21:22:43 +00001351 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001352int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001353{
1354 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001355 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001356
1357 p[0] = ( b < 0 ) ? -b : b;
1358 _B.s = ( b < 0 ) ? -1 : 1;
1359 _B.n = 1;
1360 _B.p = p;
1361
1362 return( mpi_div_mpi( Q, R, A, &_B ) );
1363}
1364
1365/*
1366 * Modulo: R = A mod B
1367 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001368int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001369{
1370 int ret;
1371
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001372 if( mpi_cmp_int( B, 0 ) < 0 )
1373 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
1374
Paul Bakker5121ce52009-01-03 21:22:43 +00001375 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1376
1377 while( mpi_cmp_int( R, 0 ) < 0 )
1378 MPI_CHK( mpi_add_mpi( R, R, B ) );
1379
1380 while( mpi_cmp_mpi( R, B ) >= 0 )
1381 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1382
1383cleanup:
1384
1385 return( ret );
1386}
1387
1388/*
1389 * Modulo: r = A mod b
1390 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001391int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001392{
Paul Bakker23986e52011-04-24 08:57:21 +00001393 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +00001394 t_uint x, y, z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001395
1396 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001397 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001398
1399 if( b < 0 )
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001400 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001401
1402 /*
1403 * handle trivial cases
1404 */
1405 if( b == 1 )
1406 {
1407 *r = 0;
1408 return( 0 );
1409 }
1410
1411 if( b == 2 )
1412 {
1413 *r = A->p[0] & 1;
1414 return( 0 );
1415 }
1416
1417 /*
1418 * general case
1419 */
Paul Bakker23986e52011-04-24 08:57:21 +00001420 for( i = A->n, y = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001421 {
Paul Bakker23986e52011-04-24 08:57:21 +00001422 x = A->p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001423 y = ( y << biH ) | ( x >> biH );
1424 z = y / b;
1425 y -= z * b;
1426
1427 x <<= biH;
1428 y = ( y << biH ) | ( x >> biH );
1429 z = y / b;
1430 y -= z * b;
1431 }
1432
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001433 /*
1434 * If A is negative, then the current y represents a negative value.
1435 * Flipping it to the positive side.
1436 */
1437 if( A->s < 0 && y != 0 )
1438 y = b - y;
1439
Paul Bakker5121ce52009-01-03 21:22:43 +00001440 *r = y;
1441
1442 return( 0 );
1443}
1444
1445/*
1446 * Fast Montgomery initialization (thanks to Tom St Denis)
1447 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001448static void mpi_montg_init( t_uint *mm, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001449{
Paul Bakkera755ca12011-04-24 09:11:17 +00001450 t_uint x, m0 = N->p[0];
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001451 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001452
1453 x = m0;
1454 x += ( ( m0 + 2 ) & 4 ) << 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001455
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001456 for( i = biL; i >= 8; i /= 2 )
1457 x *= ( 2 - ( m0 * x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001458
1459 *mm = ~x + 1;
1460}
1461
1462/*
1463 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1464 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001465static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001466{
Paul Bakker23986e52011-04-24 08:57:21 +00001467 size_t i, n, m;
Paul Bakkera755ca12011-04-24 09:11:17 +00001468 t_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00001469
1470 memset( T->p, 0, T->n * ciL );
1471
1472 d = T->p;
1473 n = N->n;
1474 m = ( B->n < n ) ? B->n : n;
1475
1476 for( i = 0; i < n; i++ )
1477 {
1478 /*
1479 * T = (T + u0*B + u1*N) / 2^biL
1480 */
1481 u0 = A->p[i];
1482 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1483
1484 mpi_mul_hlp( m, B->p, d, u0 );
1485 mpi_mul_hlp( n, N->p, d, u1 );
1486
1487 *d++ = u0; d[n + 1] = 0;
1488 }
1489
1490 memcpy( A->p, d, (n + 1) * ciL );
1491
1492 if( mpi_cmp_abs( A, N ) >= 0 )
1493 mpi_sub_hlp( n, N->p, A->p );
1494 else
1495 /* prevent timing attacks */
1496 mpi_sub_hlp( n, A->p, T->p );
1497}
1498
1499/*
1500 * Montgomery reduction: A = A * R^-1 mod N
1501 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001502static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001503{
Paul Bakkera755ca12011-04-24 09:11:17 +00001504 t_uint z = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001505 mpi U;
1506
Paul Bakker8ddb6452013-02-27 14:56:33 +01001507 U.n = U.s = (int) z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001508 U.p = &z;
1509
1510 mpi_montmul( A, &U, N, mm, T );
1511}
1512
1513/*
1514 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1515 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001516int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00001517{
Paul Bakker23986e52011-04-24 08:57:21 +00001518 int ret;
1519 size_t wbits, wsize, one = 1;
1520 size_t i, j, nblimbs;
1521 size_t bufsize, nbits;
Paul Bakkera755ca12011-04-24 09:11:17 +00001522 t_uint ei, mm, state;
Paul Bakkerf6198c12012-05-16 08:02:29 +00001523 mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos;
1524 int neg;
Paul Bakker5121ce52009-01-03 21:22:43 +00001525
1526 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001527 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001528
Paul Bakkerf6198c12012-05-16 08:02:29 +00001529 if( mpi_cmp_int( E, 0 ) < 0 )
1530 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
1531
1532 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001533 * Init temps and window size
1534 */
1535 mpi_montg_init( &mm, N );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001536 mpi_init( &RR ); mpi_init( &T );
Manuel Pégourié-Gonnardfd6a1912014-01-18 19:05:23 +01001537 mpi_init( &Apos );
Paul Bakker5121ce52009-01-03 21:22:43 +00001538 memset( W, 0, sizeof( W ) );
1539
1540 i = mpi_msb( E );
1541
1542 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1543 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1544
Paul Bakkerb6d5f082011-11-25 11:52:11 +00001545 if( wsize > POLARSSL_MPI_WINDOW_SIZE )
1546 wsize = POLARSSL_MPI_WINDOW_SIZE;
1547
Paul Bakker5121ce52009-01-03 21:22:43 +00001548 j = N->n + 1;
1549 MPI_CHK( mpi_grow( X, j ) );
1550 MPI_CHK( mpi_grow( &W[1], j ) );
1551 MPI_CHK( mpi_grow( &T, j * 2 ) );
1552
1553 /*
Paul Bakker50546922012-05-19 08:40:49 +00001554 * Compensate for negative A (and correct at the end)
1555 */
1556 neg = ( A->s == -1 );
Paul Bakker50546922012-05-19 08:40:49 +00001557 if( neg )
1558 {
1559 MPI_CHK( mpi_copy( &Apos, A ) );
1560 Apos.s = 1;
1561 A = &Apos;
1562 }
1563
1564 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001565 * If 1st call, pre-compute R^2 mod N
1566 */
1567 if( _RR == NULL || _RR->p == NULL )
1568 {
1569 MPI_CHK( mpi_lset( &RR, 1 ) );
1570 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1571 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1572
1573 if( _RR != NULL )
1574 memcpy( _RR, &RR, sizeof( mpi ) );
1575 }
1576 else
1577 memcpy( &RR, _RR, sizeof( mpi ) );
1578
1579 /*
1580 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1581 */
1582 if( mpi_cmp_mpi( A, N ) >= 0 )
Paul Bakkerc2024f42014-01-23 20:38:35 +01001583 MPI_CHK( mpi_mod_mpi( &W[1], A, N ) );
1584 else
1585 MPI_CHK( mpi_copy( &W[1], A ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001586
1587 mpi_montmul( &W[1], &RR, N, mm, &T );
1588
1589 /*
1590 * X = R^2 * R^-1 mod N = R mod N
1591 */
1592 MPI_CHK( mpi_copy( X, &RR ) );
1593 mpi_montred( X, N, mm, &T );
1594
1595 if( wsize > 1 )
1596 {
1597 /*
1598 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1599 */
Paul Bakker23986e52011-04-24 08:57:21 +00001600 j = one << (wsize - 1);
Paul Bakker5121ce52009-01-03 21:22:43 +00001601
1602 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1603 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1604
1605 for( i = 0; i < wsize - 1; i++ )
1606 mpi_montmul( &W[j], &W[j], N, mm, &T );
Paul Bakker0d7702c2013-10-29 16:18:35 +01001607
Paul Bakker5121ce52009-01-03 21:22:43 +00001608 /*
1609 * W[i] = W[i - 1] * W[1]
1610 */
Paul Bakker23986e52011-04-24 08:57:21 +00001611 for( i = j + 1; i < (one << wsize); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001612 {
1613 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1614 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1615
1616 mpi_montmul( &W[i], &W[1], N, mm, &T );
1617 }
1618 }
1619
1620 nblimbs = E->n;
1621 bufsize = 0;
1622 nbits = 0;
1623 wbits = 0;
1624 state = 0;
1625
1626 while( 1 )
1627 {
1628 if( bufsize == 0 )
1629 {
Paul Bakker0d7702c2013-10-29 16:18:35 +01001630 if( nblimbs == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001631 break;
1632
Paul Bakker0d7702c2013-10-29 16:18:35 +01001633 nblimbs--;
1634
Paul Bakkera755ca12011-04-24 09:11:17 +00001635 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001636 }
1637
1638 bufsize--;
1639
1640 ei = (E->p[nblimbs] >> bufsize) & 1;
1641
1642 /*
1643 * skip leading 0s
1644 */
1645 if( ei == 0 && state == 0 )
1646 continue;
1647
1648 if( ei == 0 && state == 1 )
1649 {
1650 /*
1651 * out of window, square X
1652 */
1653 mpi_montmul( X, X, N, mm, &T );
1654 continue;
1655 }
1656
1657 /*
1658 * add ei to current window
1659 */
1660 state = 2;
1661
1662 nbits++;
1663 wbits |= (ei << (wsize - nbits));
1664
1665 if( nbits == wsize )
1666 {
1667 /*
1668 * X = X^wsize R^-1 mod N
1669 */
1670 for( i = 0; i < wsize; i++ )
1671 mpi_montmul( X, X, N, mm, &T );
1672
1673 /*
1674 * X = X * W[wbits] R^-1 mod N
1675 */
1676 mpi_montmul( X, &W[wbits], N, mm, &T );
1677
1678 state--;
1679 nbits = 0;
1680 wbits = 0;
1681 }
1682 }
1683
1684 /*
1685 * process the remaining bits
1686 */
1687 for( i = 0; i < nbits; i++ )
1688 {
1689 mpi_montmul( X, X, N, mm, &T );
1690
1691 wbits <<= 1;
1692
Paul Bakker23986e52011-04-24 08:57:21 +00001693 if( (wbits & (one << wsize)) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001694 mpi_montmul( X, &W[1], N, mm, &T );
1695 }
1696
1697 /*
1698 * X = A^E * R * R^-1 mod N = A^E mod N
1699 */
1700 mpi_montred( X, N, mm, &T );
1701
Paul Bakkerf6198c12012-05-16 08:02:29 +00001702 if( neg )
1703 {
1704 X->s = -1;
Paul Bakkerc2024f42014-01-23 20:38:35 +01001705 MPI_CHK( mpi_add_mpi( X, N, X ) );
Paul Bakkerf6198c12012-05-16 08:02:29 +00001706 }
1707
Paul Bakker5121ce52009-01-03 21:22:43 +00001708cleanup:
1709
Paul Bakker23986e52011-04-24 08:57:21 +00001710 for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001711 mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001712
Paul Bakkerf6198c12012-05-16 08:02:29 +00001713 mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001714
1715 if( _RR == NULL )
1716 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001717
1718 return( ret );
1719}
1720
Paul Bakker5121ce52009-01-03 21:22:43 +00001721/*
1722 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1723 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001724int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001725{
Paul Bakker23986e52011-04-24 08:57:21 +00001726 int ret;
1727 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001728 mpi TG, TA, TB;
1729
Paul Bakker6c591fa2011-05-05 11:49:20 +00001730 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001731
Paul Bakker5121ce52009-01-03 21:22:43 +00001732 MPI_CHK( mpi_copy( &TA, A ) );
1733 MPI_CHK( mpi_copy( &TB, B ) );
1734
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001735 lz = mpi_lsb( &TA );
1736 lzt = mpi_lsb( &TB );
1737
1738 if ( lzt < lz )
1739 lz = lzt;
1740
1741 MPI_CHK( mpi_shift_r( &TA, lz ) );
1742 MPI_CHK( mpi_shift_r( &TB, lz ) );
1743
Paul Bakker5121ce52009-01-03 21:22:43 +00001744 TA.s = TB.s = 1;
1745
1746 while( mpi_cmp_int( &TA, 0 ) != 0 )
1747 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001748 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1749 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001750
1751 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1752 {
1753 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1754 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1755 }
1756 else
1757 {
1758 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1759 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1760 }
1761 }
1762
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001763 MPI_CHK( mpi_shift_l( &TB, lz ) );
1764 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001765
1766cleanup:
1767
Paul Bakker6c591fa2011-05-05 11:49:20 +00001768 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001769
1770 return( ret );
1771}
1772
Paul Bakkera3d195c2011-11-27 21:07:34 +00001773int mpi_fill_random( mpi *X, size_t size,
1774 int (*f_rng)(void *, unsigned char *, size_t),
1775 void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001776{
Paul Bakker23986e52011-04-24 08:57:21 +00001777 int ret;
Paul Bakker287781a2011-03-26 13:18:49 +00001778
Paul Bakker39dfdac2012-02-12 17:17:27 +00001779 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( size ) ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001780 MPI_CHK( mpi_lset( X, 0 ) );
1781
Paul Bakker39dfdac2012-02-12 17:17:27 +00001782 MPI_CHK( f_rng( p_rng, (unsigned char *) X->p, size ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001783
1784cleanup:
1785 return( ret );
1786}
1787
Paul Bakker5121ce52009-01-03 21:22:43 +00001788/*
1789 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1790 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001791int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001792{
1793 int ret;
1794 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1795
1796 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001797 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001798
Paul Bakker6c591fa2011-05-05 11:49:20 +00001799 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1800 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1801 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001802
1803 MPI_CHK( mpi_gcd( &G, A, N ) );
1804
1805 if( mpi_cmp_int( &G, 1 ) != 0 )
1806 {
Paul Bakker40e46942009-01-03 21:51:57 +00001807 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001808 goto cleanup;
1809 }
1810
1811 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1812 MPI_CHK( mpi_copy( &TU, &TA ) );
1813 MPI_CHK( mpi_copy( &TB, N ) );
1814 MPI_CHK( mpi_copy( &TV, N ) );
1815
1816 MPI_CHK( mpi_lset( &U1, 1 ) );
1817 MPI_CHK( mpi_lset( &U2, 0 ) );
1818 MPI_CHK( mpi_lset( &V1, 0 ) );
1819 MPI_CHK( mpi_lset( &V2, 1 ) );
1820
1821 do
1822 {
1823 while( ( TU.p[0] & 1 ) == 0 )
1824 {
1825 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1826
1827 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1828 {
1829 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1830 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1831 }
1832
1833 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1834 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1835 }
1836
1837 while( ( TV.p[0] & 1 ) == 0 )
1838 {
1839 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1840
1841 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1842 {
1843 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1844 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1845 }
1846
1847 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1848 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1849 }
1850
1851 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1852 {
1853 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1854 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1855 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1856 }
1857 else
1858 {
1859 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1860 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1861 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1862 }
1863 }
1864 while( mpi_cmp_int( &TU, 0 ) != 0 );
1865
1866 while( mpi_cmp_int( &V1, 0 ) < 0 )
1867 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1868
1869 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1870 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1871
1872 MPI_CHK( mpi_copy( X, &V1 ) );
1873
1874cleanup:
1875
Paul Bakker6c591fa2011-05-05 11:49:20 +00001876 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1877 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1878 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001879
1880 return( ret );
1881}
1882
Paul Bakkerd9374b02012-11-02 11:02:58 +00001883#if defined(POLARSSL_GENPRIME)
1884
Paul Bakker5121ce52009-01-03 21:22:43 +00001885static const int small_prime[] =
1886{
1887 3, 5, 7, 11, 13, 17, 19, 23,
1888 29, 31, 37, 41, 43, 47, 53, 59,
1889 61, 67, 71, 73, 79, 83, 89, 97,
1890 101, 103, 107, 109, 113, 127, 131, 137,
1891 139, 149, 151, 157, 163, 167, 173, 179,
1892 181, 191, 193, 197, 199, 211, 223, 227,
1893 229, 233, 239, 241, 251, 257, 263, 269,
1894 271, 277, 281, 283, 293, 307, 311, 313,
1895 317, 331, 337, 347, 349, 353, 359, 367,
1896 373, 379, 383, 389, 397, 401, 409, 419,
1897 421, 431, 433, 439, 443, 449, 457, 461,
1898 463, 467, 479, 487, 491, 499, 503, 509,
1899 521, 523, 541, 547, 557, 563, 569, 571,
1900 577, 587, 593, 599, 601, 607, 613, 617,
1901 619, 631, 641, 643, 647, 653, 659, 661,
1902 673, 677, 683, 691, 701, 709, 719, 727,
1903 733, 739, 743, 751, 757, 761, 769, 773,
1904 787, 797, 809, 811, 821, 823, 827, 829,
1905 839, 853, 857, 859, 863, 877, 881, 883,
1906 887, 907, 911, 919, 929, 937, 941, 947,
1907 953, 967, 971, 977, 983, 991, 997, -103
1908};
1909
1910/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001911 * Small divisors test (X must be positive)
1912 *
1913 * Return values:
1914 * 0: no small factor (possible prime, more tests needed)
1915 * 1: certain prime
1916 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
1917 * other negative: error
Paul Bakker5121ce52009-01-03 21:22:43 +00001918 */
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001919static int mpi_check_small_factors( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +00001920{
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001921 int ret = 0;
1922 size_t i;
1923 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001924
Paul Bakker5121ce52009-01-03 21:22:43 +00001925 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001926 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001927
1928 for( i = 0; small_prime[i] > 0; i++ )
1929 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001930 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001931 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001932
1933 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1934
1935 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001936 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001937 }
1938
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001939cleanup:
1940 return( ret );
1941}
1942
1943/*
1944 * Miller-Rabin pseudo-primality test (HAC 4.24)
1945 */
1946static int mpi_miller_rabin( const mpi *X,
1947 int (*f_rng)(void *, unsigned char *, size_t),
1948 void *p_rng )
1949{
1950 int ret;
1951 size_t i, j, n, s;
1952 mpi W, R, T, A, RR;
1953
1954 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1955 mpi_init( &RR );
1956
Paul Bakker5121ce52009-01-03 21:22:43 +00001957 /*
1958 * W = |X| - 1
1959 * R = W >> lsb( W )
1960 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001961 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001962 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001963 MPI_CHK( mpi_copy( &R, &W ) );
1964 MPI_CHK( mpi_shift_r( &R, s ) );
1965
1966 i = mpi_msb( X );
1967 /*
1968 * HAC, table 4.4
1969 */
1970 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1971 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1972 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1973
1974 for( i = 0; i < n; i++ )
1975 {
1976 /*
1977 * pick a random A, 1 < A < |X| - 1
1978 */
Paul Bakker901c6562012-04-20 13:25:38 +00001979 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001980
Paul Bakkerb94081b2011-01-05 15:53:06 +00001981 if( mpi_cmp_mpi( &A, &W ) >= 0 )
1982 {
1983 j = mpi_msb( &A ) - mpi_msb( &W );
1984 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
1985 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001986 A.p[0] |= 3;
1987
1988 /*
1989 * A = A^R mod |X|
1990 */
1991 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
1992
1993 if( mpi_cmp_mpi( &A, &W ) == 0 ||
1994 mpi_cmp_int( &A, 1 ) == 0 )
1995 continue;
1996
1997 j = 1;
1998 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
1999 {
2000 /*
2001 * A = A * A mod |X|
2002 */
2003 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
2004 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
2005
2006 if( mpi_cmp_int( &A, 1 ) == 0 )
2007 break;
2008
2009 j++;
2010 }
2011
2012 /*
2013 * not prime if A != |X| - 1 or A == 1
2014 */
2015 if( mpi_cmp_mpi( &A, &W ) != 0 ||
2016 mpi_cmp_int( &A, 1 ) == 0 )
2017 {
Paul Bakker40e46942009-01-03 21:51:57 +00002018 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002019 break;
2020 }
2021 }
2022
2023cleanup:
Paul Bakker6c591fa2011-05-05 11:49:20 +00002024 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
2025 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002026
2027 return( ret );
2028}
2029
2030/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002031 * Pseudo-primality test: small factors, then Miller-Rabin
2032 */
Paul Bakker45f457d2013-11-25 14:26:52 +01002033int mpi_is_prime( mpi *X,
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002034 int (*f_rng)(void *, unsigned char *, size_t),
2035 void *p_rng )
2036{
2037 int ret;
2038 const mpi XX = { 1, X->n, X->p }; /* Abs(X) */
2039
2040 if( mpi_cmp_int( &XX, 0 ) == 0 ||
2041 mpi_cmp_int( &XX, 1 ) == 0 )
2042 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
2043
2044 if( mpi_cmp_int( &XX, 2 ) == 0 )
2045 return( 0 );
2046
2047 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2048 {
2049 if( ret == 1 )
2050 return( 0 );
2051
2052 return( ret );
2053 }
2054
2055 return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
2056}
2057
2058/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002059 * Prime number generation
2060 */
Paul Bakker23986e52011-04-24 08:57:21 +00002061int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002062 int (*f_rng)(void *, unsigned char *, size_t),
2063 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +00002064{
Paul Bakker23986e52011-04-24 08:57:21 +00002065 int ret;
2066 size_t k, n;
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002067 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002068 mpi Y;
2069
Paul Bakkerfe3256e2011-11-25 12:11:43 +00002070 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
Paul Bakker40e46942009-01-03 21:51:57 +00002071 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002072
Paul Bakker6c591fa2011-05-05 11:49:20 +00002073 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002074
2075 n = BITS_TO_LIMBS( nbits );
2076
Paul Bakker901c6562012-04-20 13:25:38 +00002077 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002078
2079 k = mpi_msb( X );
2080 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
2081 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
2082
2083 X->p[0] |= 3;
2084
2085 if( dh_flag == 0 )
2086 {
2087 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
2088 {
Paul Bakker40e46942009-01-03 21:51:57 +00002089 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002090 goto cleanup;
2091
2092 MPI_CHK( mpi_add_int( X, X, 2 ) );
2093 }
2094 }
2095 else
2096 {
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002097 /*
2098 * An necessary condition for Y and X = 2Y + 1 to be prime
2099 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2100 * Make sure it is satisfied, while keeping X = 3 mod 4
2101 */
2102 MPI_CHK( mpi_mod_int( &r, X, 3 ) );
2103 if( r == 0 )
2104 MPI_CHK( mpi_add_int( X, X, 8 ) );
2105 else if( r == 1 )
2106 MPI_CHK( mpi_add_int( X, X, 4 ) );
2107
2108 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2109 MPI_CHK( mpi_copy( &Y, X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002110 MPI_CHK( mpi_shift_r( &Y, 1 ) );
2111
2112 while( 1 )
2113 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002114 /*
2115 * First, check small factors for X and Y
2116 * before doing Miller-Rabin on any of them
2117 */
2118 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2119 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2120 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
2121 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002122 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002123 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002124 }
2125
Paul Bakker40e46942009-01-03 21:51:57 +00002126 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002127 goto cleanup;
2128
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002129 /*
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002130 * Next candidates. We want to preserve Y = (X-1) / 2 and
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002131 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2132 * so up Y by 6 and X by 12.
2133 */
2134 MPI_CHK( mpi_add_int( X, X, 12 ) );
2135 MPI_CHK( mpi_add_int( &Y, &Y, 6 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002136 }
2137 }
2138
2139cleanup:
2140
Paul Bakker6c591fa2011-05-05 11:49:20 +00002141 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002142
2143 return( ret );
2144}
2145
Manuel Pégourié-Gonnarddf0142b2013-08-22 18:29:07 +02002146#endif /* POLARSSL_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00002147
Paul Bakker40e46942009-01-03 21:51:57 +00002148#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002149
Paul Bakker23986e52011-04-24 08:57:21 +00002150#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002151
2152static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2153{
2154 { 693, 609, 21 },
2155 { 1764, 868, 28 },
2156 { 768454923, 542167814, 1 }
2157};
2158
Paul Bakker5121ce52009-01-03 21:22:43 +00002159/*
2160 * Checkup routine
2161 */
2162int mpi_self_test( int verbose )
2163{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002164 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00002165 mpi A, E, N, X, Y, U, V;
2166
Paul Bakker6c591fa2011-05-05 11:49:20 +00002167 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
2168 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002169
2170 MPI_CHK( mpi_read_string( &A, 16,
2171 "EFE021C2645FD1DC586E69184AF4A31E" \
2172 "D5F53E93B5F123FA41680867BA110131" \
2173 "944FE7952E2517337780CB0DB80E61AA" \
2174 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2175
2176 MPI_CHK( mpi_read_string( &E, 16,
2177 "B2E7EFD37075B9F03FF989C7C5051C20" \
2178 "34D2A323810251127E7BF8625A4F49A5" \
2179 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2180 "5B5C25763222FEFCCFC38B832366C29E" ) );
2181
2182 MPI_CHK( mpi_read_string( &N, 16,
2183 "0066A198186C18C10B2F5ED9B522752A" \
2184 "9830B69916E535C8F047518A889A43A5" \
2185 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2186
2187 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
2188
2189 MPI_CHK( mpi_read_string( &U, 16,
2190 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2191 "9E857EA95A03512E2BAE7391688D264A" \
2192 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2193 "8001B72E848A38CAE1C65F78E56ABDEF" \
2194 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2195 "ECF677152EF804370C1A305CAF3B5BF1" \
2196 "30879B56C61DE584A0F53A2447A51E" ) );
2197
2198 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002199 polarssl_printf( " MPI test #1 (mul_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002200
2201 if( mpi_cmp_mpi( &X, &U ) != 0 )
2202 {
2203 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002204 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002205
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002206 ret = 1;
2207 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002208 }
2209
2210 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002211 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002212
2213 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
2214
2215 MPI_CHK( mpi_read_string( &U, 16,
2216 "256567336059E52CAE22925474705F39A94" ) );
2217
2218 MPI_CHK( mpi_read_string( &V, 16,
2219 "6613F26162223DF488E9CD48CC132C7A" \
2220 "0AC93C701B001B092E4E5B9F73BCD27B" \
2221 "9EE50D0657C77F374E903CDFA4C642" ) );
2222
2223 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002224 polarssl_printf( " MPI test #2 (div_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002225
2226 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2227 mpi_cmp_mpi( &Y, &V ) != 0 )
2228 {
2229 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002230 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002231
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002232 ret = 1;
2233 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002234 }
2235
2236 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002237 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002238
2239 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2240
2241 MPI_CHK( mpi_read_string( &U, 16,
2242 "36E139AEA55215609D2816998ED020BB" \
2243 "BD96C37890F65171D948E9BC7CBAA4D9" \
2244 "325D24D6A3C12710F10A09FA08AB87" ) );
2245
2246 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002247 polarssl_printf( " MPI test #3 (exp_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002248
2249 if( mpi_cmp_mpi( &X, &U ) != 0 )
2250 {
2251 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002252 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002253
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002254 ret = 1;
2255 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002256 }
2257
2258 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002259 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002260
2261 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2262
2263 MPI_CHK( mpi_read_string( &U, 16,
2264 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2265 "C3DBA76456363A10869622EAC2DD84EC" \
2266 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2267
2268 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002269 polarssl_printf( " MPI test #4 (inv_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002270
2271 if( mpi_cmp_mpi( &X, &U ) != 0 )
2272 {
2273 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002274 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002275
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002276 ret = 1;
2277 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002278 }
2279
2280 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002281 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002282
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002283 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002284 polarssl_printf( " MPI test #5 (simple gcd): " );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002285
2286 for ( i = 0; i < GCD_PAIR_COUNT; i++)
2287 {
2288 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002289 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002290
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002291 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002292
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002293 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2294 {
2295 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002296 polarssl_printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002297
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002298 ret = 1;
2299 goto cleanup;
2300 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002301 }
2302
2303 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002304 polarssl_printf( "passed\n" );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002305
Paul Bakker5121ce52009-01-03 21:22:43 +00002306cleanup:
2307
2308 if( ret != 0 && verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002309 polarssl_printf( "Unexpected error, return code = %08X\n", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002310
Paul Bakker6c591fa2011-05-05 11:49:20 +00002311 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2312 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002313
2314 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002315 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002316
2317 return( ret );
2318}
2319
2320#endif
2321
2322#endif