blob: 6d49caab52532427e4df95c7d63c65a3f9761c7f [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 /*
Manuel Pégourié-Gonnard2eea2922014-03-14 18:23:26 +01001236 * The version of Clang shipped by Apple with Mavericks around
1237 * 2014-03 can't handle 128-bit division properly. Disable
1238 * 128-bits division for this version. Let's be optimistic and
1239 * assume it'll be fixed in the next minor version (next
1240 * patchlevel is probably a bit too optimistic).
Manuel Pégourié-Gonnardbb8661e2014-03-14 09:21:20 +01001241 */
Manuel Pégourié-Gonnard2eea2922014-03-14 18:23:26 +01001242#if defined(POLARSSL_HAVE_UDBL) && \
1243 ! ( defined(__x86_64__) && defined(__APPLE__) && \
1244 defined(__clang_major__) && __clang_major__ == 5 && \
1245 defined(__clang_minor__) && __clang_minor__ == 0 )
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001246 t_udbl r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001247
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001248 r = (t_udbl) X.p[i] << biL;
1249 r |= (t_udbl) X.p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001250 r /= Y.p[t];
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001251 if( r > ((t_udbl) 1 << biL) - 1)
1252 r = ((t_udbl) 1 << biL) - 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001253
Paul Bakkera755ca12011-04-24 09:11:17 +00001254 Z.p[i - t - 1] = (t_uint) r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001255#else
1256 /*
1257 * __udiv_qrnnd_c, from gmp/longlong.h
1258 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001259 t_uint q0, q1, r0, r1;
1260 t_uint d0, d1, d, m;
Paul Bakker5121ce52009-01-03 21:22:43 +00001261
1262 d = Y.p[t];
1263 d0 = ( d << biH ) >> biH;
1264 d1 = ( d >> biH );
1265
1266 q1 = X.p[i] / d1;
1267 r1 = X.p[i] - d1 * q1;
1268 r1 <<= biH;
1269 r1 |= ( X.p[i - 1] >> biH );
1270
1271 m = q1 * d0;
1272 if( r1 < m )
1273 {
1274 q1--, r1 += d;
1275 while( r1 >= d && r1 < m )
1276 q1--, r1 += d;
1277 }
1278 r1 -= m;
1279
1280 q0 = r1 / d1;
1281 r0 = r1 - d1 * q0;
1282 r0 <<= biH;
1283 r0 |= ( X.p[i - 1] << biH ) >> biH;
1284
1285 m = q0 * d0;
1286 if( r0 < m )
1287 {
1288 q0--, r0 += d;
1289 while( r0 >= d && r0 < m )
1290 q0--, r0 += d;
1291 }
1292 r0 -= m;
1293
1294 Z.p[i - t - 1] = ( q1 << biH ) | q0;
1295#endif
1296 }
1297
1298 Z.p[i - t - 1]++;
1299 do
1300 {
1301 Z.p[i - t - 1]--;
1302
1303 MPI_CHK( mpi_lset( &T1, 0 ) );
1304 T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
1305 T1.p[1] = Y.p[t];
1306 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1307
1308 MPI_CHK( mpi_lset( &T2, 0 ) );
1309 T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
1310 T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
1311 T2.p[2] = X.p[i];
1312 }
1313 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1314
1315 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1316 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1317 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1318
1319 if( mpi_cmp_int( &X, 0 ) < 0 )
1320 {
1321 MPI_CHK( mpi_copy( &T1, &Y ) );
1322 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1323 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1324 Z.p[i - t - 1]--;
1325 }
1326 }
1327
1328 if( Q != NULL )
1329 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001330 MPI_CHK( mpi_copy( Q, &Z ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001331 Q->s = A->s * B->s;
1332 }
1333
1334 if( R != NULL )
1335 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001336 MPI_CHK( mpi_shift_r( &X, k ) );
Paul Bakkerf02c5642012-11-13 10:25:21 +00001337 X.s = A->s;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001338 MPI_CHK( mpi_copy( R, &X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001339
Paul Bakker5121ce52009-01-03 21:22:43 +00001340 if( mpi_cmp_int( R, 0 ) == 0 )
1341 R->s = 1;
1342 }
1343
1344cleanup:
1345
Paul Bakker6c591fa2011-05-05 11:49:20 +00001346 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
1347 mpi_free( &T1 ); mpi_free( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001348
1349 return( ret );
1350}
1351
1352/*
1353 * Division by int: A = Q * b + R
Paul Bakker5121ce52009-01-03 21:22:43 +00001354 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001355int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001356{
1357 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001358 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001359
1360 p[0] = ( b < 0 ) ? -b : b;
1361 _B.s = ( b < 0 ) ? -1 : 1;
1362 _B.n = 1;
1363 _B.p = p;
1364
1365 return( mpi_div_mpi( Q, R, A, &_B ) );
1366}
1367
1368/*
1369 * Modulo: R = A mod B
1370 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001371int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001372{
1373 int ret;
1374
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001375 if( mpi_cmp_int( B, 0 ) < 0 )
1376 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
1377
Paul Bakker5121ce52009-01-03 21:22:43 +00001378 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1379
1380 while( mpi_cmp_int( R, 0 ) < 0 )
1381 MPI_CHK( mpi_add_mpi( R, R, B ) );
1382
1383 while( mpi_cmp_mpi( R, B ) >= 0 )
1384 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1385
1386cleanup:
1387
1388 return( ret );
1389}
1390
1391/*
1392 * Modulo: r = A mod b
1393 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001394int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001395{
Paul Bakker23986e52011-04-24 08:57:21 +00001396 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +00001397 t_uint x, y, z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001398
1399 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001400 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001401
1402 if( b < 0 )
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001403 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001404
1405 /*
1406 * handle trivial cases
1407 */
1408 if( b == 1 )
1409 {
1410 *r = 0;
1411 return( 0 );
1412 }
1413
1414 if( b == 2 )
1415 {
1416 *r = A->p[0] & 1;
1417 return( 0 );
1418 }
1419
1420 /*
1421 * general case
1422 */
Paul Bakker23986e52011-04-24 08:57:21 +00001423 for( i = A->n, y = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001424 {
Paul Bakker23986e52011-04-24 08:57:21 +00001425 x = A->p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001426 y = ( y << biH ) | ( x >> biH );
1427 z = y / b;
1428 y -= z * b;
1429
1430 x <<= biH;
1431 y = ( y << biH ) | ( x >> biH );
1432 z = y / b;
1433 y -= z * b;
1434 }
1435
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001436 /*
1437 * If A is negative, then the current y represents a negative value.
1438 * Flipping it to the positive side.
1439 */
1440 if( A->s < 0 && y != 0 )
1441 y = b - y;
1442
Paul Bakker5121ce52009-01-03 21:22:43 +00001443 *r = y;
1444
1445 return( 0 );
1446}
1447
1448/*
1449 * Fast Montgomery initialization (thanks to Tom St Denis)
1450 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001451static void mpi_montg_init( t_uint *mm, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001452{
Paul Bakkera755ca12011-04-24 09:11:17 +00001453 t_uint x, m0 = N->p[0];
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001454 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001455
1456 x = m0;
1457 x += ( ( m0 + 2 ) & 4 ) << 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001458
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001459 for( i = biL; i >= 8; i /= 2 )
1460 x *= ( 2 - ( m0 * x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001461
1462 *mm = ~x + 1;
1463}
1464
1465/*
1466 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1467 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001468static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001469{
Paul Bakker23986e52011-04-24 08:57:21 +00001470 size_t i, n, m;
Paul Bakkera755ca12011-04-24 09:11:17 +00001471 t_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00001472
1473 memset( T->p, 0, T->n * ciL );
1474
1475 d = T->p;
1476 n = N->n;
1477 m = ( B->n < n ) ? B->n : n;
1478
1479 for( i = 0; i < n; i++ )
1480 {
1481 /*
1482 * T = (T + u0*B + u1*N) / 2^biL
1483 */
1484 u0 = A->p[i];
1485 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1486
1487 mpi_mul_hlp( m, B->p, d, u0 );
1488 mpi_mul_hlp( n, N->p, d, u1 );
1489
1490 *d++ = u0; d[n + 1] = 0;
1491 }
1492
1493 memcpy( A->p, d, (n + 1) * ciL );
1494
1495 if( mpi_cmp_abs( A, N ) >= 0 )
1496 mpi_sub_hlp( n, N->p, A->p );
1497 else
1498 /* prevent timing attacks */
1499 mpi_sub_hlp( n, A->p, T->p );
1500}
1501
1502/*
1503 * Montgomery reduction: A = A * R^-1 mod N
1504 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001505static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001506{
Paul Bakkera755ca12011-04-24 09:11:17 +00001507 t_uint z = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001508 mpi U;
1509
Paul Bakker8ddb6452013-02-27 14:56:33 +01001510 U.n = U.s = (int) z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001511 U.p = &z;
1512
1513 mpi_montmul( A, &U, N, mm, T );
1514}
1515
1516/*
1517 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1518 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001519int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00001520{
Paul Bakker23986e52011-04-24 08:57:21 +00001521 int ret;
1522 size_t wbits, wsize, one = 1;
1523 size_t i, j, nblimbs;
1524 size_t bufsize, nbits;
Paul Bakkera755ca12011-04-24 09:11:17 +00001525 t_uint ei, mm, state;
Paul Bakkerf6198c12012-05-16 08:02:29 +00001526 mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos;
1527 int neg;
Paul Bakker5121ce52009-01-03 21:22:43 +00001528
1529 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001530 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001531
Paul Bakkerf6198c12012-05-16 08:02:29 +00001532 if( mpi_cmp_int( E, 0 ) < 0 )
1533 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
1534
1535 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001536 * Init temps and window size
1537 */
1538 mpi_montg_init( &mm, N );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001539 mpi_init( &RR ); mpi_init( &T );
Manuel Pégourié-Gonnardfd6a1912014-01-18 19:05:23 +01001540 mpi_init( &Apos );
Paul Bakker5121ce52009-01-03 21:22:43 +00001541 memset( W, 0, sizeof( W ) );
1542
1543 i = mpi_msb( E );
1544
1545 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1546 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1547
Paul Bakkerb6d5f082011-11-25 11:52:11 +00001548 if( wsize > POLARSSL_MPI_WINDOW_SIZE )
1549 wsize = POLARSSL_MPI_WINDOW_SIZE;
1550
Paul Bakker5121ce52009-01-03 21:22:43 +00001551 j = N->n + 1;
1552 MPI_CHK( mpi_grow( X, j ) );
1553 MPI_CHK( mpi_grow( &W[1], j ) );
1554 MPI_CHK( mpi_grow( &T, j * 2 ) );
1555
1556 /*
Paul Bakker50546922012-05-19 08:40:49 +00001557 * Compensate for negative A (and correct at the end)
1558 */
1559 neg = ( A->s == -1 );
Paul Bakker50546922012-05-19 08:40:49 +00001560 if( neg )
1561 {
1562 MPI_CHK( mpi_copy( &Apos, A ) );
1563 Apos.s = 1;
1564 A = &Apos;
1565 }
1566
1567 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001568 * If 1st call, pre-compute R^2 mod N
1569 */
1570 if( _RR == NULL || _RR->p == NULL )
1571 {
1572 MPI_CHK( mpi_lset( &RR, 1 ) );
1573 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1574 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1575
1576 if( _RR != NULL )
1577 memcpy( _RR, &RR, sizeof( mpi ) );
1578 }
1579 else
1580 memcpy( &RR, _RR, sizeof( mpi ) );
1581
1582 /*
1583 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1584 */
1585 if( mpi_cmp_mpi( A, N ) >= 0 )
Paul Bakkerc2024f42014-01-23 20:38:35 +01001586 MPI_CHK( mpi_mod_mpi( &W[1], A, N ) );
1587 else
1588 MPI_CHK( mpi_copy( &W[1], A ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001589
1590 mpi_montmul( &W[1], &RR, N, mm, &T );
1591
1592 /*
1593 * X = R^2 * R^-1 mod N = R mod N
1594 */
1595 MPI_CHK( mpi_copy( X, &RR ) );
1596 mpi_montred( X, N, mm, &T );
1597
1598 if( wsize > 1 )
1599 {
1600 /*
1601 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1602 */
Paul Bakker23986e52011-04-24 08:57:21 +00001603 j = one << (wsize - 1);
Paul Bakker5121ce52009-01-03 21:22:43 +00001604
1605 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1606 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1607
1608 for( i = 0; i < wsize - 1; i++ )
1609 mpi_montmul( &W[j], &W[j], N, mm, &T );
Paul Bakker0d7702c2013-10-29 16:18:35 +01001610
Paul Bakker5121ce52009-01-03 21:22:43 +00001611 /*
1612 * W[i] = W[i - 1] * W[1]
1613 */
Paul Bakker23986e52011-04-24 08:57:21 +00001614 for( i = j + 1; i < (one << wsize); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001615 {
1616 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1617 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1618
1619 mpi_montmul( &W[i], &W[1], N, mm, &T );
1620 }
1621 }
1622
1623 nblimbs = E->n;
1624 bufsize = 0;
1625 nbits = 0;
1626 wbits = 0;
1627 state = 0;
1628
1629 while( 1 )
1630 {
1631 if( bufsize == 0 )
1632 {
Paul Bakker0d7702c2013-10-29 16:18:35 +01001633 if( nblimbs == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001634 break;
1635
Paul Bakker0d7702c2013-10-29 16:18:35 +01001636 nblimbs--;
1637
Paul Bakkera755ca12011-04-24 09:11:17 +00001638 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001639 }
1640
1641 bufsize--;
1642
1643 ei = (E->p[nblimbs] >> bufsize) & 1;
1644
1645 /*
1646 * skip leading 0s
1647 */
1648 if( ei == 0 && state == 0 )
1649 continue;
1650
1651 if( ei == 0 && state == 1 )
1652 {
1653 /*
1654 * out of window, square X
1655 */
1656 mpi_montmul( X, X, N, mm, &T );
1657 continue;
1658 }
1659
1660 /*
1661 * add ei to current window
1662 */
1663 state = 2;
1664
1665 nbits++;
1666 wbits |= (ei << (wsize - nbits));
1667
1668 if( nbits == wsize )
1669 {
1670 /*
1671 * X = X^wsize R^-1 mod N
1672 */
1673 for( i = 0; i < wsize; i++ )
1674 mpi_montmul( X, X, N, mm, &T );
1675
1676 /*
1677 * X = X * W[wbits] R^-1 mod N
1678 */
1679 mpi_montmul( X, &W[wbits], N, mm, &T );
1680
1681 state--;
1682 nbits = 0;
1683 wbits = 0;
1684 }
1685 }
1686
1687 /*
1688 * process the remaining bits
1689 */
1690 for( i = 0; i < nbits; i++ )
1691 {
1692 mpi_montmul( X, X, N, mm, &T );
1693
1694 wbits <<= 1;
1695
Paul Bakker23986e52011-04-24 08:57:21 +00001696 if( (wbits & (one << wsize)) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001697 mpi_montmul( X, &W[1], N, mm, &T );
1698 }
1699
1700 /*
1701 * X = A^E * R * R^-1 mod N = A^E mod N
1702 */
1703 mpi_montred( X, N, mm, &T );
1704
Paul Bakkerf6198c12012-05-16 08:02:29 +00001705 if( neg )
1706 {
1707 X->s = -1;
Paul Bakkerc2024f42014-01-23 20:38:35 +01001708 MPI_CHK( mpi_add_mpi( X, N, X ) );
Paul Bakkerf6198c12012-05-16 08:02:29 +00001709 }
1710
Paul Bakker5121ce52009-01-03 21:22:43 +00001711cleanup:
1712
Paul Bakker23986e52011-04-24 08:57:21 +00001713 for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001714 mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001715
Paul Bakkerf6198c12012-05-16 08:02:29 +00001716 mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001717
1718 if( _RR == NULL )
1719 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001720
1721 return( ret );
1722}
1723
Paul Bakker5121ce52009-01-03 21:22:43 +00001724/*
1725 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1726 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001727int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001728{
Paul Bakker23986e52011-04-24 08:57:21 +00001729 int ret;
1730 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001731 mpi TG, TA, TB;
1732
Paul Bakker6c591fa2011-05-05 11:49:20 +00001733 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001734
Paul Bakker5121ce52009-01-03 21:22:43 +00001735 MPI_CHK( mpi_copy( &TA, A ) );
1736 MPI_CHK( mpi_copy( &TB, B ) );
1737
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001738 lz = mpi_lsb( &TA );
1739 lzt = mpi_lsb( &TB );
1740
1741 if ( lzt < lz )
1742 lz = lzt;
1743
1744 MPI_CHK( mpi_shift_r( &TA, lz ) );
1745 MPI_CHK( mpi_shift_r( &TB, lz ) );
1746
Paul Bakker5121ce52009-01-03 21:22:43 +00001747 TA.s = TB.s = 1;
1748
1749 while( mpi_cmp_int( &TA, 0 ) != 0 )
1750 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001751 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1752 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001753
1754 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1755 {
1756 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1757 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1758 }
1759 else
1760 {
1761 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1762 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1763 }
1764 }
1765
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001766 MPI_CHK( mpi_shift_l( &TB, lz ) );
1767 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001768
1769cleanup:
1770
Paul Bakker6c591fa2011-05-05 11:49:20 +00001771 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001772
1773 return( ret );
1774}
1775
Paul Bakkera3d195c2011-11-27 21:07:34 +00001776int mpi_fill_random( mpi *X, size_t size,
1777 int (*f_rng)(void *, unsigned char *, size_t),
1778 void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001779{
Paul Bakker23986e52011-04-24 08:57:21 +00001780 int ret;
Paul Bakker287781a2011-03-26 13:18:49 +00001781
Paul Bakker39dfdac2012-02-12 17:17:27 +00001782 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( size ) ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001783 MPI_CHK( mpi_lset( X, 0 ) );
1784
Paul Bakker39dfdac2012-02-12 17:17:27 +00001785 MPI_CHK( f_rng( p_rng, (unsigned char *) X->p, size ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001786
1787cleanup:
1788 return( ret );
1789}
1790
Paul Bakker5121ce52009-01-03 21:22:43 +00001791/*
1792 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1793 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001794int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001795{
1796 int ret;
1797 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1798
1799 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001800 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001801
Paul Bakker6c591fa2011-05-05 11:49:20 +00001802 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1803 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1804 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001805
1806 MPI_CHK( mpi_gcd( &G, A, N ) );
1807
1808 if( mpi_cmp_int( &G, 1 ) != 0 )
1809 {
Paul Bakker40e46942009-01-03 21:51:57 +00001810 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001811 goto cleanup;
1812 }
1813
1814 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1815 MPI_CHK( mpi_copy( &TU, &TA ) );
1816 MPI_CHK( mpi_copy( &TB, N ) );
1817 MPI_CHK( mpi_copy( &TV, N ) );
1818
1819 MPI_CHK( mpi_lset( &U1, 1 ) );
1820 MPI_CHK( mpi_lset( &U2, 0 ) );
1821 MPI_CHK( mpi_lset( &V1, 0 ) );
1822 MPI_CHK( mpi_lset( &V2, 1 ) );
1823
1824 do
1825 {
1826 while( ( TU.p[0] & 1 ) == 0 )
1827 {
1828 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1829
1830 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1831 {
1832 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1833 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1834 }
1835
1836 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1837 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1838 }
1839
1840 while( ( TV.p[0] & 1 ) == 0 )
1841 {
1842 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1843
1844 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1845 {
1846 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1847 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1848 }
1849
1850 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1851 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1852 }
1853
1854 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1855 {
1856 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1857 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1858 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1859 }
1860 else
1861 {
1862 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1863 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1864 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1865 }
1866 }
1867 while( mpi_cmp_int( &TU, 0 ) != 0 );
1868
1869 while( mpi_cmp_int( &V1, 0 ) < 0 )
1870 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1871
1872 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1873 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1874
1875 MPI_CHK( mpi_copy( X, &V1 ) );
1876
1877cleanup:
1878
Paul Bakker6c591fa2011-05-05 11:49:20 +00001879 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1880 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1881 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001882
1883 return( ret );
1884}
1885
Paul Bakkerd9374b02012-11-02 11:02:58 +00001886#if defined(POLARSSL_GENPRIME)
1887
Paul Bakker5121ce52009-01-03 21:22:43 +00001888static const int small_prime[] =
1889{
1890 3, 5, 7, 11, 13, 17, 19, 23,
1891 29, 31, 37, 41, 43, 47, 53, 59,
1892 61, 67, 71, 73, 79, 83, 89, 97,
1893 101, 103, 107, 109, 113, 127, 131, 137,
1894 139, 149, 151, 157, 163, 167, 173, 179,
1895 181, 191, 193, 197, 199, 211, 223, 227,
1896 229, 233, 239, 241, 251, 257, 263, 269,
1897 271, 277, 281, 283, 293, 307, 311, 313,
1898 317, 331, 337, 347, 349, 353, 359, 367,
1899 373, 379, 383, 389, 397, 401, 409, 419,
1900 421, 431, 433, 439, 443, 449, 457, 461,
1901 463, 467, 479, 487, 491, 499, 503, 509,
1902 521, 523, 541, 547, 557, 563, 569, 571,
1903 577, 587, 593, 599, 601, 607, 613, 617,
1904 619, 631, 641, 643, 647, 653, 659, 661,
1905 673, 677, 683, 691, 701, 709, 719, 727,
1906 733, 739, 743, 751, 757, 761, 769, 773,
1907 787, 797, 809, 811, 821, 823, 827, 829,
1908 839, 853, 857, 859, 863, 877, 881, 883,
1909 887, 907, 911, 919, 929, 937, 941, 947,
1910 953, 967, 971, 977, 983, 991, 997, -103
1911};
1912
1913/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001914 * Small divisors test (X must be positive)
1915 *
1916 * Return values:
1917 * 0: no small factor (possible prime, more tests needed)
1918 * 1: certain prime
1919 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
1920 * other negative: error
Paul Bakker5121ce52009-01-03 21:22:43 +00001921 */
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001922static int mpi_check_small_factors( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +00001923{
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001924 int ret = 0;
1925 size_t i;
1926 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001927
Paul Bakker5121ce52009-01-03 21:22:43 +00001928 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001929 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001930
1931 for( i = 0; small_prime[i] > 0; i++ )
1932 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001933 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001934 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001935
1936 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1937
1938 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001939 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001940 }
1941
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001942cleanup:
1943 return( ret );
1944}
1945
1946/*
1947 * Miller-Rabin pseudo-primality test (HAC 4.24)
1948 */
1949static int mpi_miller_rabin( const mpi *X,
1950 int (*f_rng)(void *, unsigned char *, size_t),
1951 void *p_rng )
1952{
1953 int ret;
1954 size_t i, j, n, s;
1955 mpi W, R, T, A, RR;
1956
1957 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1958 mpi_init( &RR );
1959
Paul Bakker5121ce52009-01-03 21:22:43 +00001960 /*
1961 * W = |X| - 1
1962 * R = W >> lsb( W )
1963 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001964 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001965 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001966 MPI_CHK( mpi_copy( &R, &W ) );
1967 MPI_CHK( mpi_shift_r( &R, s ) );
1968
1969 i = mpi_msb( X );
1970 /*
1971 * HAC, table 4.4
1972 */
1973 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1974 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1975 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1976
1977 for( i = 0; i < n; i++ )
1978 {
1979 /*
1980 * pick a random A, 1 < A < |X| - 1
1981 */
Paul Bakker901c6562012-04-20 13:25:38 +00001982 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001983
Paul Bakkerb94081b2011-01-05 15:53:06 +00001984 if( mpi_cmp_mpi( &A, &W ) >= 0 )
1985 {
1986 j = mpi_msb( &A ) - mpi_msb( &W );
1987 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
1988 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001989 A.p[0] |= 3;
1990
1991 /*
1992 * A = A^R mod |X|
1993 */
1994 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
1995
1996 if( mpi_cmp_mpi( &A, &W ) == 0 ||
1997 mpi_cmp_int( &A, 1 ) == 0 )
1998 continue;
1999
2000 j = 1;
2001 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
2002 {
2003 /*
2004 * A = A * A mod |X|
2005 */
2006 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
2007 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
2008
2009 if( mpi_cmp_int( &A, 1 ) == 0 )
2010 break;
2011
2012 j++;
2013 }
2014
2015 /*
2016 * not prime if A != |X| - 1 or A == 1
2017 */
2018 if( mpi_cmp_mpi( &A, &W ) != 0 ||
2019 mpi_cmp_int( &A, 1 ) == 0 )
2020 {
Paul Bakker40e46942009-01-03 21:51:57 +00002021 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002022 break;
2023 }
2024 }
2025
2026cleanup:
Paul Bakker6c591fa2011-05-05 11:49:20 +00002027 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
2028 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002029
2030 return( ret );
2031}
2032
2033/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002034 * Pseudo-primality test: small factors, then Miller-Rabin
2035 */
Paul Bakker45f457d2013-11-25 14:26:52 +01002036int mpi_is_prime( mpi *X,
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002037 int (*f_rng)(void *, unsigned char *, size_t),
2038 void *p_rng )
2039{
2040 int ret;
2041 const mpi XX = { 1, X->n, X->p }; /* Abs(X) */
2042
2043 if( mpi_cmp_int( &XX, 0 ) == 0 ||
2044 mpi_cmp_int( &XX, 1 ) == 0 )
2045 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
2046
2047 if( mpi_cmp_int( &XX, 2 ) == 0 )
2048 return( 0 );
2049
2050 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2051 {
2052 if( ret == 1 )
2053 return( 0 );
2054
2055 return( ret );
2056 }
2057
2058 return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
2059}
2060
2061/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002062 * Prime number generation
2063 */
Paul Bakker23986e52011-04-24 08:57:21 +00002064int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002065 int (*f_rng)(void *, unsigned char *, size_t),
2066 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +00002067{
Paul Bakker23986e52011-04-24 08:57:21 +00002068 int ret;
2069 size_t k, n;
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002070 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002071 mpi Y;
2072
Paul Bakkerfe3256e2011-11-25 12:11:43 +00002073 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
Paul Bakker40e46942009-01-03 21:51:57 +00002074 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002075
Paul Bakker6c591fa2011-05-05 11:49:20 +00002076 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002077
2078 n = BITS_TO_LIMBS( nbits );
2079
Paul Bakker901c6562012-04-20 13:25:38 +00002080 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002081
2082 k = mpi_msb( X );
2083 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
2084 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
2085
2086 X->p[0] |= 3;
2087
2088 if( dh_flag == 0 )
2089 {
2090 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
2091 {
Paul Bakker40e46942009-01-03 21:51:57 +00002092 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002093 goto cleanup;
2094
2095 MPI_CHK( mpi_add_int( X, X, 2 ) );
2096 }
2097 }
2098 else
2099 {
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002100 /*
2101 * An necessary condition for Y and X = 2Y + 1 to be prime
2102 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2103 * Make sure it is satisfied, while keeping X = 3 mod 4
2104 */
2105 MPI_CHK( mpi_mod_int( &r, X, 3 ) );
2106 if( r == 0 )
2107 MPI_CHK( mpi_add_int( X, X, 8 ) );
2108 else if( r == 1 )
2109 MPI_CHK( mpi_add_int( X, X, 4 ) );
2110
2111 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2112 MPI_CHK( mpi_copy( &Y, X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002113 MPI_CHK( mpi_shift_r( &Y, 1 ) );
2114
2115 while( 1 )
2116 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002117 /*
2118 * First, check small factors for X and Y
2119 * before doing Miller-Rabin on any of them
2120 */
2121 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2122 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2123 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
2124 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002125 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002126 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002127 }
2128
Paul Bakker40e46942009-01-03 21:51:57 +00002129 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002130 goto cleanup;
2131
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002132 /*
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002133 * Next candidates. We want to preserve Y = (X-1) / 2 and
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002134 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2135 * so up Y by 6 and X by 12.
2136 */
2137 MPI_CHK( mpi_add_int( X, X, 12 ) );
2138 MPI_CHK( mpi_add_int( &Y, &Y, 6 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002139 }
2140 }
2141
2142cleanup:
2143
Paul Bakker6c591fa2011-05-05 11:49:20 +00002144 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002145
2146 return( ret );
2147}
2148
Manuel Pégourié-Gonnarddf0142b2013-08-22 18:29:07 +02002149#endif /* POLARSSL_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00002150
Paul Bakker40e46942009-01-03 21:51:57 +00002151#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002152
Paul Bakker23986e52011-04-24 08:57:21 +00002153#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002154
2155static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2156{
2157 { 693, 609, 21 },
2158 { 1764, 868, 28 },
2159 { 768454923, 542167814, 1 }
2160};
2161
Paul Bakker5121ce52009-01-03 21:22:43 +00002162/*
2163 * Checkup routine
2164 */
2165int mpi_self_test( int verbose )
2166{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002167 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00002168 mpi A, E, N, X, Y, U, V;
2169
Paul Bakker6c591fa2011-05-05 11:49:20 +00002170 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
2171 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002172
2173 MPI_CHK( mpi_read_string( &A, 16,
2174 "EFE021C2645FD1DC586E69184AF4A31E" \
2175 "D5F53E93B5F123FA41680867BA110131" \
2176 "944FE7952E2517337780CB0DB80E61AA" \
2177 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2178
2179 MPI_CHK( mpi_read_string( &E, 16,
2180 "B2E7EFD37075B9F03FF989C7C5051C20" \
2181 "34D2A323810251127E7BF8625A4F49A5" \
2182 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2183 "5B5C25763222FEFCCFC38B832366C29E" ) );
2184
2185 MPI_CHK( mpi_read_string( &N, 16,
2186 "0066A198186C18C10B2F5ED9B522752A" \
2187 "9830B69916E535C8F047518A889A43A5" \
2188 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2189
2190 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
2191
2192 MPI_CHK( mpi_read_string( &U, 16,
2193 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2194 "9E857EA95A03512E2BAE7391688D264A" \
2195 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2196 "8001B72E848A38CAE1C65F78E56ABDEF" \
2197 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2198 "ECF677152EF804370C1A305CAF3B5BF1" \
2199 "30879B56C61DE584A0F53A2447A51E" ) );
2200
2201 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002202 polarssl_printf( " MPI test #1 (mul_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002203
2204 if( mpi_cmp_mpi( &X, &U ) != 0 )
2205 {
2206 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002207 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002208
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002209 ret = 1;
2210 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002211 }
2212
2213 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002214 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002215
2216 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
2217
2218 MPI_CHK( mpi_read_string( &U, 16,
2219 "256567336059E52CAE22925474705F39A94" ) );
2220
2221 MPI_CHK( mpi_read_string( &V, 16,
2222 "6613F26162223DF488E9CD48CC132C7A" \
2223 "0AC93C701B001B092E4E5B9F73BCD27B" \
2224 "9EE50D0657C77F374E903CDFA4C642" ) );
2225
2226 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002227 polarssl_printf( " MPI test #2 (div_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002228
2229 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2230 mpi_cmp_mpi( &Y, &V ) != 0 )
2231 {
2232 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002233 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002234
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002235 ret = 1;
2236 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002237 }
2238
2239 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002240 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002241
2242 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2243
2244 MPI_CHK( mpi_read_string( &U, 16,
2245 "36E139AEA55215609D2816998ED020BB" \
2246 "BD96C37890F65171D948E9BC7CBAA4D9" \
2247 "325D24D6A3C12710F10A09FA08AB87" ) );
2248
2249 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002250 polarssl_printf( " MPI test #3 (exp_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002251
2252 if( mpi_cmp_mpi( &X, &U ) != 0 )
2253 {
2254 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002255 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002256
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002257 ret = 1;
2258 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002259 }
2260
2261 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002262 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002263
2264 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2265
2266 MPI_CHK( mpi_read_string( &U, 16,
2267 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2268 "C3DBA76456363A10869622EAC2DD84EC" \
2269 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2270
2271 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002272 polarssl_printf( " MPI test #4 (inv_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002273
2274 if( mpi_cmp_mpi( &X, &U ) != 0 )
2275 {
2276 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002277 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002278
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002279 ret = 1;
2280 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002281 }
2282
2283 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002284 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002285
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002286 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002287 polarssl_printf( " MPI test #5 (simple gcd): " );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002288
2289 for ( i = 0; i < GCD_PAIR_COUNT; i++)
2290 {
2291 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002292 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002293
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002294 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002295
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002296 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2297 {
2298 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002299 polarssl_printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002300
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002301 ret = 1;
2302 goto cleanup;
2303 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002304 }
2305
2306 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002307 polarssl_printf( "passed\n" );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002308
Paul Bakker5121ce52009-01-03 21:22:43 +00002309cleanup:
2310
2311 if( ret != 0 && verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002312 polarssl_printf( "Unexpected error, return code = %08X\n", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002313
Paul Bakker6c591fa2011-05-05 11:49:20 +00002314 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2315 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002316
2317 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002318 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002319
2320 return( ret );
2321}
2322
2323#endif
2324
2325#endif