blob: 61b21fb688705be7bfa6d93d44af74ec15bd5e65 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Multi-precision integer library
3 *
Paul Bakker84f12b72010-07-18 10:13:04 +00004 * Copyright (C) 2006-2010, 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 Bakker6e339b52013-07-03 13:37:05 +020040#if defined(POLARSSL_MEMORY_C)
41#include "polarssl/memory.h"
42#else
43#define polarssl_malloc malloc
44#define polarssl_free free
45#endif
46
Paul Bakker5121ce52009-01-03 21:22:43 +000047#include <stdlib.h>
Paul Bakker5121ce52009-01-03 21:22:43 +000048
Paul Bakkerf9688572011-05-05 10:00:45 +000049#define ciL (sizeof(t_uint)) /* chars in limb */
Paul Bakker5121ce52009-01-03 21:22:43 +000050#define biL (ciL << 3) /* bits in limb */
51#define biH (ciL << 2) /* half limb size */
52
53/*
54 * Convert between bits/chars and number of limbs
55 */
56#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
57#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
58
59/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000060 * Initialize one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000061 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000062void mpi_init( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000063{
Paul Bakker6c591fa2011-05-05 11:49:20 +000064 if( X == NULL )
65 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000066
Paul Bakker6c591fa2011-05-05 11:49:20 +000067 X->s = 1;
68 X->n = 0;
69 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000070}
71
72/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000073 * Unallocate one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000074 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000075void mpi_free( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000076{
Paul Bakker6c591fa2011-05-05 11:49:20 +000077 if( X == NULL )
78 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000079
Paul Bakker6c591fa2011-05-05 11:49:20 +000080 if( X->p != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +000081 {
Paul Bakker6c591fa2011-05-05 11:49:20 +000082 memset( X->p, 0, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +020083 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +000084 }
85
Paul Bakker6c591fa2011-05-05 11:49:20 +000086 X->s = 1;
87 X->n = 0;
88 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000089}
90
91/*
92 * Enlarge to the specified number of limbs
93 */
Paul Bakker23986e52011-04-24 08:57:21 +000094int mpi_grow( mpi *X, size_t nblimbs )
Paul Bakker5121ce52009-01-03 21:22:43 +000095{
Paul Bakkera755ca12011-04-24 09:11:17 +000096 t_uint *p;
Paul Bakker5121ce52009-01-03 21:22:43 +000097
Paul Bakkerf9688572011-05-05 10:00:45 +000098 if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
Paul Bakker69e095c2011-12-10 21:55:01 +000099 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakkerf9688572011-05-05 10:00:45 +0000100
Paul Bakker5121ce52009-01-03 21:22:43 +0000101 if( X->n < nblimbs )
102 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200103 if( ( p = (t_uint *) polarssl_malloc( nblimbs * ciL ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000104 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000105
106 memset( p, 0, nblimbs * ciL );
107
108 if( X->p != NULL )
109 {
110 memcpy( p, X->p, X->n * ciL );
111 memset( X->p, 0, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +0200112 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000113 }
114
115 X->n = nblimbs;
116 X->p = p;
117 }
118
119 return( 0 );
120}
121
122/*
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100123 * Resize down as much as possible,
124 * while keeping at least the specified number of limbs
125 */
126int mpi_shrink( mpi *X, size_t nblimbs )
127{
128 t_uint *p;
129 size_t i;
130
131 /* Actually resize up in this case */
132 if( X->n <= nblimbs )
133 return( mpi_grow( X, nblimbs ) );
134
135 for( i = X->n - 1; i > 0; i-- )
136 if( X->p[i] != 0 )
137 break;
138 i++;
139
140 if( i < nblimbs )
141 i = nblimbs;
142
143 if( ( p = (t_uint *) polarssl_malloc( i * ciL ) ) == NULL )
144 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
145
146 memset( p, 0, i * ciL );
147
148 if( X->p != NULL )
149 {
150 memcpy( p, X->p, i * ciL );
151 memset( X->p, 0, X->n * ciL );
152 polarssl_free( X->p );
153 }
154
155 X->n = i;
156 X->p = p;
157
158 return( 0 );
159}
160
161/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000162 * Copy the contents of Y into X
163 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000164int mpi_copy( mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000165{
Paul Bakker23986e52011-04-24 08:57:21 +0000166 int ret;
167 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000168
169 if( X == Y )
170 return( 0 );
171
Manuel Pégourié-Gonnardf4999932013-08-12 17:02:59 +0200172 if( Y->p == NULL )
173 {
174 mpi_free( X );
175 return( 0 );
176 }
177
Paul Bakker5121ce52009-01-03 21:22:43 +0000178 for( i = Y->n - 1; i > 0; i-- )
179 if( Y->p[i] != 0 )
180 break;
181 i++;
182
183 X->s = Y->s;
184
185 MPI_CHK( mpi_grow( X, i ) );
186
187 memset( X->p, 0, X->n * ciL );
188 memcpy( X->p, Y->p, i * ciL );
189
190cleanup:
191
192 return( ret );
193}
194
195/*
196 * Swap the contents of X and Y
197 */
198void mpi_swap( mpi *X, mpi *Y )
199{
200 mpi T;
201
202 memcpy( &T, X, sizeof( mpi ) );
203 memcpy( X, Y, sizeof( mpi ) );
204 memcpy( Y, &T, sizeof( mpi ) );
205}
206
207/*
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100208 * Conditionally assign X = Y, without leaking information
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100209 * about whether the assignment was made or not.
210 * (Leaking information about the respective sizes of X and Y is ok however.)
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100211 */
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100212int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign )
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100213{
214 int ret = 0;
215 size_t i;
216
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100217 /* make sure assign is 0 or 1 */
218 assign = ( assign != 0 );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100219
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100220 MPI_CHK( mpi_grow( X, Y->n ) );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100221
Manuel Pégourié-Gonnard3e3d2b82013-11-21 21:12:26 +0100222 X->s = X->s * (1 - assign) + Y->s * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100223
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100224 for( i = 0; i < Y->n; i++ )
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100225 X->p[i] = X->p[i] * (1 - assign) + Y->p[i] * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100226
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100227 for( ; i < X->n; i++ )
228 X->p[i] *= (1 - assign);
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100229
230cleanup:
231 return( ret );
232}
233
234/*
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100235 * Conditionally swap X and Y, without leaking information
236 * about whether the swap was made or not.
237 * Here it is not ok to simply swap the pointers, which whould lead to
238 * different memory access patterns when X and Y are used afterwards.
239 */
240int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char swap )
241{
242 int ret, s;
243 size_t i;
244 t_uint tmp;
245
246 if( X == Y )
247 return( 0 );
248
249 /* make sure swap is 0 or 1 */
250 swap = ( swap != 0 );
251
252 MPI_CHK( mpi_grow( X, Y->n ) );
253 MPI_CHK( mpi_grow( Y, X->n ) );
254
255 s = X->s;
256 X->s = X->s * (1 - swap) + Y->s * swap;
257 Y->s = Y->s * (1 - swap) + s * swap;
258
259
260 for( i = 0; i < X->n; i++ )
261 {
262 tmp = X->p[i];
263 X->p[i] = X->p[i] * (1 - swap) + Y->p[i] * swap;
264 Y->p[i] = Y->p[i] * (1 - swap) + tmp * swap;
265 }
266
267cleanup:
268 return( ret );
269}
270
271/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000272 * Set value from integer
273 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000274int mpi_lset( mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000275{
276 int ret;
277
278 MPI_CHK( mpi_grow( X, 1 ) );
279 memset( X->p, 0, X->n * ciL );
280
281 X->p[0] = ( z < 0 ) ? -z : z;
282 X->s = ( z < 0 ) ? -1 : 1;
283
284cleanup:
285
286 return( ret );
287}
288
289/*
Paul Bakker2f5947e2011-05-18 15:47:11 +0000290 * Get a specific bit
291 */
Paul Bakker6b906e52012-05-08 12:01:43 +0000292int mpi_get_bit( const mpi *X, size_t pos )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000293{
294 if( X->n * biL <= pos )
295 return( 0 );
296
297 return ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01;
298}
299
300/*
301 * Set a bit to a specific value of 0 or 1
302 */
303int mpi_set_bit( mpi *X, size_t pos, unsigned char val )
304{
305 int ret = 0;
306 size_t off = pos / biL;
307 size_t idx = pos % biL;
308
309 if( val != 0 && val != 1 )
310 return POLARSSL_ERR_MPI_BAD_INPUT_DATA;
311
312 if( X->n * biL <= pos )
313 {
314 if( val == 0 )
315 return ( 0 );
316
317 MPI_CHK( mpi_grow( X, off + 1 ) );
318 }
319
Manuel Pégourié-Gonnard9a4a5ac2013-12-04 18:05:29 +0100320 X->p[off] &= ~( (t_uint) 0x01 << idx );
321 X->p[off] |= (t_uint) val << idx;
Paul Bakker2f5947e2011-05-18 15:47:11 +0000322
323cleanup:
324
325 return( ret );
326}
327
328/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000329 * Return the number of least significant bits
330 */
Paul Bakker23986e52011-04-24 08:57:21 +0000331size_t mpi_lsb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000332{
Paul Bakker23986e52011-04-24 08:57:21 +0000333 size_t i, j, count = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000334
335 for( i = 0; i < X->n; i++ )
Paul Bakkerf9688572011-05-05 10:00:45 +0000336 for( j = 0; j < biL; j++, count++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000337 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
338 return( count );
339
340 return( 0 );
341}
342
343/*
344 * Return the number of most significant bits
345 */
Paul Bakker23986e52011-04-24 08:57:21 +0000346size_t mpi_msb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000347{
Paul Bakker23986e52011-04-24 08:57:21 +0000348 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000349
350 for( i = X->n - 1; i > 0; i-- )
351 if( X->p[i] != 0 )
352 break;
353
Paul Bakker23986e52011-04-24 08:57:21 +0000354 for( j = biL; j > 0; j-- )
355 if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000356 break;
357
Paul Bakker23986e52011-04-24 08:57:21 +0000358 return( ( i * biL ) + j );
Paul Bakker5121ce52009-01-03 21:22:43 +0000359}
360
361/*
362 * Return the total size in bytes
363 */
Paul Bakker23986e52011-04-24 08:57:21 +0000364size_t mpi_size( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000365{
366 return( ( mpi_msb( X ) + 7 ) >> 3 );
367}
368
369/*
370 * Convert an ASCII character to digit value
371 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000372static int mpi_get_digit( t_uint *d, int radix, char c )
Paul Bakker5121ce52009-01-03 21:22:43 +0000373{
374 *d = 255;
375
376 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
377 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
378 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
379
Paul Bakkera755ca12011-04-24 09:11:17 +0000380 if( *d >= (t_uint) radix )
Paul Bakker40e46942009-01-03 21:51:57 +0000381 return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000382
383 return( 0 );
384}
385
386/*
387 * Import from an ASCII string
388 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000389int mpi_read_string( mpi *X, int radix, const char *s )
Paul Bakker5121ce52009-01-03 21:22:43 +0000390{
Paul Bakker23986e52011-04-24 08:57:21 +0000391 int ret;
392 size_t i, j, slen, n;
Paul Bakkera755ca12011-04-24 09:11:17 +0000393 t_uint d;
Paul Bakker5121ce52009-01-03 21:22:43 +0000394 mpi T;
395
396 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000397 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000398
Paul Bakker6c591fa2011-05-05 11:49:20 +0000399 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000400
Paul Bakkerff60ee62010-03-16 21:09:09 +0000401 slen = strlen( s );
402
Paul Bakker5121ce52009-01-03 21:22:43 +0000403 if( radix == 16 )
404 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000405 n = BITS_TO_LIMBS( slen << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000406
407 MPI_CHK( mpi_grow( X, n ) );
408 MPI_CHK( mpi_lset( X, 0 ) );
409
Paul Bakker23986e52011-04-24 08:57:21 +0000410 for( i = slen, j = 0; i > 0; i--, j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000411 {
Paul Bakker23986e52011-04-24 08:57:21 +0000412 if( i == 1 && s[i - 1] == '-' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000413 {
414 X->s = -1;
415 break;
416 }
417
Paul Bakker23986e52011-04-24 08:57:21 +0000418 MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000419 X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 );
420 }
421 }
422 else
423 {
424 MPI_CHK( mpi_lset( X, 0 ) );
425
Paul Bakkerff60ee62010-03-16 21:09:09 +0000426 for( i = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 {
428 if( i == 0 && s[i] == '-' )
429 {
430 X->s = -1;
431 continue;
432 }
433
434 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
435 MPI_CHK( mpi_mul_int( &T, X, radix ) );
Paul Bakker05feca62009-06-20 08:22:43 +0000436
437 if( X->s == 1 )
438 {
439 MPI_CHK( mpi_add_int( X, &T, d ) );
440 }
441 else
442 {
443 MPI_CHK( mpi_sub_int( X, &T, d ) );
444 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000445 }
446 }
447
448cleanup:
449
Paul Bakker6c591fa2011-05-05 11:49:20 +0000450 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000451
452 return( ret );
453}
454
455/*
456 * Helper to write the digits high-order first
457 */
458static int mpi_write_hlp( mpi *X, int radix, char **p )
459{
460 int ret;
Paul Bakkera755ca12011-04-24 09:11:17 +0000461 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +0000462
463 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000464 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000465
466 MPI_CHK( mpi_mod_int( &r, X, radix ) );
467 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
468
469 if( mpi_cmp_int( X, 0 ) != 0 )
470 MPI_CHK( mpi_write_hlp( X, radix, p ) );
471
472 if( r < 10 )
473 *(*p)++ = (char)( r + 0x30 );
474 else
475 *(*p)++ = (char)( r + 0x37 );
476
477cleanup:
478
479 return( ret );
480}
481
482/*
483 * Export into an ASCII string
484 */
Paul Bakker23986e52011-04-24 08:57:21 +0000485int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000486{
Paul Bakker23986e52011-04-24 08:57:21 +0000487 int ret = 0;
488 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000489 char *p;
490 mpi T;
491
492 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000493 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
495 n = mpi_msb( X );
496 if( radix >= 4 ) n >>= 1;
497 if( radix >= 16 ) n >>= 1;
498 n += 3;
499
500 if( *slen < n )
501 {
502 *slen = n;
Paul Bakker40e46942009-01-03 21:51:57 +0000503 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000504 }
505
506 p = s;
Paul Bakker6c591fa2011-05-05 11:49:20 +0000507 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000508
509 if( X->s == -1 )
510 *p++ = '-';
511
512 if( radix == 16 )
513 {
Paul Bakker23986e52011-04-24 08:57:21 +0000514 int c;
515 size_t i, j, k;
Paul Bakker5121ce52009-01-03 21:22:43 +0000516
Paul Bakker23986e52011-04-24 08:57:21 +0000517 for( i = X->n, k = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000518 {
Paul Bakker23986e52011-04-24 08:57:21 +0000519 for( j = ciL; j > 0; j-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000520 {
Paul Bakker23986e52011-04-24 08:57:21 +0000521 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000522
Paul Bakker23986e52011-04-24 08:57:21 +0000523 if( c == 0 && k == 0 && ( i + j + 3 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000524 continue;
525
Paul Bakker98fe5ea2012-10-24 11:17:48 +0000526 *(p++) = "0123456789ABCDEF" [c / 16];
Paul Bakkerd2c167e2012-10-30 07:49:19 +0000527 *(p++) = "0123456789ABCDEF" [c % 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000528 k = 1;
529 }
530 }
531 }
532 else
533 {
534 MPI_CHK( mpi_copy( &T, X ) );
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000535
536 if( T.s == -1 )
537 T.s = 1;
538
Paul Bakker5121ce52009-01-03 21:22:43 +0000539 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
540 }
541
542 *p++ = '\0';
543 *slen = p - s;
544
545cleanup:
546
Paul Bakker6c591fa2011-05-05 11:49:20 +0000547 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000548
549 return( ret );
550}
551
Paul Bakker335db3f2011-04-25 15:28:35 +0000552#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000553/*
554 * Read X from an opened file
555 */
556int mpi_read_file( mpi *X, int radix, FILE *fin )
557{
Paul Bakkera755ca12011-04-24 09:11:17 +0000558 t_uint d;
Paul Bakker23986e52011-04-24 08:57:21 +0000559 size_t slen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000560 char *p;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000561 /*
Paul Bakkercb37aa52011-11-30 16:00:20 +0000562 * Buffer should have space for (short) label and decimal formatted MPI,
563 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000564 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000565 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000566
567 memset( s, 0, sizeof( s ) );
568 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000569 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000570
571 slen = strlen( s );
Paul Bakkercb37aa52011-11-30 16:00:20 +0000572 if( slen == sizeof( s ) - 2 )
573 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
574
Paul Bakker5121ce52009-01-03 21:22:43 +0000575 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
576 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
577
578 p = s + slen;
579 while( --p >= s )
580 if( mpi_get_digit( &d, radix, *p ) != 0 )
581 break;
582
583 return( mpi_read_string( X, radix, p + 1 ) );
584}
585
586/*
587 * Write X into an opened file (or stdout if fout == NULL)
588 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000589int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
Paul Bakker5121ce52009-01-03 21:22:43 +0000590{
Paul Bakker23986e52011-04-24 08:57:21 +0000591 int ret;
592 size_t n, slen, plen;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000593 /*
Paul Bakker5531c6d2012-09-26 19:20:46 +0000594 * Buffer should have space for (short) label and decimal formatted MPI,
595 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000596 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000597 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000598
599 n = sizeof( s );
600 memset( s, 0, n );
601 n -= 2;
602
Paul Bakker23986e52011-04-24 08:57:21 +0000603 MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000604
605 if( p == NULL ) p = "";
606
607 plen = strlen( p );
608 slen = strlen( s );
609 s[slen++] = '\r';
610 s[slen++] = '\n';
611
612 if( fout != NULL )
613 {
614 if( fwrite( p, 1, plen, fout ) != plen ||
615 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000616 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000617 }
618 else
619 printf( "%s%s", p, s );
620
621cleanup:
622
623 return( ret );
624}
Paul Bakker335db3f2011-04-25 15:28:35 +0000625#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000626
627/*
628 * Import X from unsigned binary data, big endian
629 */
Paul Bakker23986e52011-04-24 08:57:21 +0000630int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000631{
Paul Bakker23986e52011-04-24 08:57:21 +0000632 int ret;
633 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000634
635 for( n = 0; n < buflen; n++ )
636 if( buf[n] != 0 )
637 break;
638
639 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
640 MPI_CHK( mpi_lset( X, 0 ) );
641
Paul Bakker23986e52011-04-24 08:57:21 +0000642 for( i = buflen, j = 0; i > n; i--, j++ )
Paul Bakkera755ca12011-04-24 09:11:17 +0000643 X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000644
645cleanup:
646
647 return( ret );
648}
649
650/*
651 * Export X into unsigned binary data, big endian
652 */
Paul Bakker23986e52011-04-24 08:57:21 +0000653int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000654{
Paul Bakker23986e52011-04-24 08:57:21 +0000655 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000656
657 n = mpi_size( X );
658
659 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000660 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
662 memset( buf, 0, buflen );
663
664 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
665 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
666
667 return( 0 );
668}
669
670/*
671 * Left-shift: X <<= count
672 */
Paul Bakker23986e52011-04-24 08:57:21 +0000673int mpi_shift_l( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000674{
Paul Bakker23986e52011-04-24 08:57:21 +0000675 int ret;
676 size_t i, v0, t1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000677 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000678
679 v0 = count / (biL );
680 t1 = count & (biL - 1);
681
682 i = mpi_msb( X ) + count;
683
Paul Bakkerf9688572011-05-05 10:00:45 +0000684 if( X->n * biL < i )
Paul Bakker5121ce52009-01-03 21:22:43 +0000685 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
686
687 ret = 0;
688
689 /*
690 * shift by count / limb_size
691 */
692 if( v0 > 0 )
693 {
Paul Bakker23986e52011-04-24 08:57:21 +0000694 for( i = X->n; i > v0; i-- )
695 X->p[i - 1] = X->p[i - v0 - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000696
Paul Bakker23986e52011-04-24 08:57:21 +0000697 for( ; i > 0; i-- )
698 X->p[i - 1] = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000699 }
700
701 /*
702 * shift by count % limb_size
703 */
704 if( t1 > 0 )
705 {
706 for( i = v0; i < X->n; i++ )
707 {
708 r1 = X->p[i] >> (biL - t1);
709 X->p[i] <<= t1;
710 X->p[i] |= r0;
711 r0 = r1;
712 }
713 }
714
715cleanup:
716
717 return( ret );
718}
719
720/*
721 * Right-shift: X >>= count
722 */
Paul Bakker23986e52011-04-24 08:57:21 +0000723int mpi_shift_r( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000724{
Paul Bakker23986e52011-04-24 08:57:21 +0000725 size_t i, v0, v1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000726 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000727
728 v0 = count / biL;
729 v1 = count & (biL - 1);
730
Manuel Pégourié-Gonnarde44ec102012-11-17 12:42:51 +0100731 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
732 return mpi_lset( X, 0 );
733
Paul Bakker5121ce52009-01-03 21:22:43 +0000734 /*
735 * shift by count / limb_size
736 */
737 if( v0 > 0 )
738 {
739 for( i = 0; i < X->n - v0; i++ )
740 X->p[i] = X->p[i + v0];
741
742 for( ; i < X->n; i++ )
743 X->p[i] = 0;
744 }
745
746 /*
747 * shift by count % limb_size
748 */
749 if( v1 > 0 )
750 {
Paul Bakker23986e52011-04-24 08:57:21 +0000751 for( i = X->n; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000752 {
Paul Bakker23986e52011-04-24 08:57:21 +0000753 r1 = X->p[i - 1] << (biL - v1);
754 X->p[i - 1] >>= v1;
755 X->p[i - 1] |= r0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000756 r0 = r1;
757 }
758 }
759
760 return( 0 );
761}
762
763/*
764 * Compare unsigned values
765 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000766int mpi_cmp_abs( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000767{
Paul Bakker23986e52011-04-24 08:57:21 +0000768 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000769
Paul Bakker23986e52011-04-24 08:57:21 +0000770 for( i = X->n; i > 0; i-- )
771 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000772 break;
773
Paul Bakker23986e52011-04-24 08:57:21 +0000774 for( j = Y->n; j > 0; j-- )
775 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000776 break;
777
Paul Bakker23986e52011-04-24 08:57:21 +0000778 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000779 return( 0 );
780
781 if( i > j ) return( 1 );
782 if( j > i ) return( -1 );
783
Paul Bakker23986e52011-04-24 08:57:21 +0000784 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000785 {
Paul Bakker23986e52011-04-24 08:57:21 +0000786 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
787 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000788 }
789
790 return( 0 );
791}
792
793/*
794 * Compare signed values
795 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000796int mpi_cmp_mpi( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000797{
Paul Bakker23986e52011-04-24 08:57:21 +0000798 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000799
Paul Bakker23986e52011-04-24 08:57:21 +0000800 for( i = X->n; i > 0; i-- )
801 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000802 break;
803
Paul Bakker23986e52011-04-24 08:57:21 +0000804 for( j = Y->n; j > 0; j-- )
805 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000806 break;
807
Paul Bakker23986e52011-04-24 08:57:21 +0000808 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000809 return( 0 );
810
811 if( i > j ) return( X->s );
Paul Bakker0c8f73b2012-03-22 14:08:57 +0000812 if( j > i ) return( -Y->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000813
814 if( X->s > 0 && Y->s < 0 ) return( 1 );
815 if( Y->s > 0 && X->s < 0 ) return( -1 );
816
Paul Bakker23986e52011-04-24 08:57:21 +0000817 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000818 {
Paul Bakker23986e52011-04-24 08:57:21 +0000819 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
820 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000821 }
822
823 return( 0 );
824}
825
826/*
827 * Compare signed values
828 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000829int mpi_cmp_int( const mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000830{
831 mpi Y;
Paul Bakkera755ca12011-04-24 09:11:17 +0000832 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000833
834 *p = ( z < 0 ) ? -z : z;
835 Y.s = ( z < 0 ) ? -1 : 1;
836 Y.n = 1;
837 Y.p = p;
838
839 return( mpi_cmp_mpi( X, &Y ) );
840}
841
842/*
843 * Unsigned addition: X = |A| + |B| (HAC 14.7)
844 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000845int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000846{
Paul Bakker23986e52011-04-24 08:57:21 +0000847 int ret;
848 size_t i, j;
Paul Bakkera755ca12011-04-24 09:11:17 +0000849 t_uint *o, *p, c;
Paul Bakker5121ce52009-01-03 21:22:43 +0000850
851 if( X == B )
852 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000853 const mpi *T = A; A = X; B = T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000854 }
855
856 if( X != A )
857 MPI_CHK( mpi_copy( X, A ) );
Paul Bakkerf7ca7b92009-06-20 10:31:06 +0000858
859 /*
860 * X should always be positive as a result of unsigned additions.
861 */
862 X->s = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000863
Paul Bakker23986e52011-04-24 08:57:21 +0000864 for( j = B->n; j > 0; j-- )
865 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000866 break;
867
Paul Bakker23986e52011-04-24 08:57:21 +0000868 MPI_CHK( mpi_grow( X, j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000869
870 o = B->p; p = X->p; c = 0;
871
Paul Bakker23986e52011-04-24 08:57:21 +0000872 for( i = 0; i < j; i++, o++, p++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000873 {
874 *p += c; c = ( *p < c );
875 *p += *o; c += ( *p < *o );
876 }
877
878 while( c != 0 )
879 {
880 if( i >= X->n )
881 {
882 MPI_CHK( mpi_grow( X, i + 1 ) );
883 p = X->p + i;
884 }
885
Paul Bakker2d319fd2012-09-16 21:34:26 +0000886 *p += c; c = ( *p < c ); i++; p++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000887 }
888
889cleanup:
890
891 return( ret );
892}
893
894/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100895 * Helper for mpi subtraction
Paul Bakker5121ce52009-01-03 21:22:43 +0000896 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000897static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
Paul Bakker5121ce52009-01-03 21:22:43 +0000898{
Paul Bakker23986e52011-04-24 08:57:21 +0000899 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +0000900 t_uint c, z;
Paul Bakker5121ce52009-01-03 21:22:43 +0000901
902 for( i = c = 0; i < n; i++, s++, d++ )
903 {
904 z = ( *d < c ); *d -= c;
905 c = ( *d < *s ) + z; *d -= *s;
906 }
907
908 while( c != 0 )
909 {
910 z = ( *d < c ); *d -= c;
911 c = z; i++; d++;
912 }
913}
914
915/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100916 * Unsigned subtraction: X = |A| - |B| (HAC 14.9)
Paul Bakker5121ce52009-01-03 21:22:43 +0000917 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000918int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000919{
920 mpi TB;
Paul Bakker23986e52011-04-24 08:57:21 +0000921 int ret;
922 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000923
924 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000925 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000926
Paul Bakker6c591fa2011-05-05 11:49:20 +0000927 mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000928
929 if( X == B )
930 {
931 MPI_CHK( mpi_copy( &TB, B ) );
932 B = &TB;
933 }
934
935 if( X != A )
936 MPI_CHK( mpi_copy( X, A ) );
937
Paul Bakker1ef7a532009-06-20 10:50:55 +0000938 /*
Paul Bakker60b1d102013-10-29 10:02:51 +0100939 * X should always be positive as a result of unsigned subtractions.
Paul Bakker1ef7a532009-06-20 10:50:55 +0000940 */
941 X->s = 1;
942
Paul Bakker5121ce52009-01-03 21:22:43 +0000943 ret = 0;
944
Paul Bakker23986e52011-04-24 08:57:21 +0000945 for( n = B->n; n > 0; n-- )
946 if( B->p[n - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000947 break;
948
Paul Bakker23986e52011-04-24 08:57:21 +0000949 mpi_sub_hlp( n, B->p, X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000950
951cleanup:
952
Paul Bakker6c591fa2011-05-05 11:49:20 +0000953 mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000954
955 return( ret );
956}
957
958/*
959 * Signed addition: X = A + B
960 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000961int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000962{
963 int ret, s = A->s;
964
965 if( A->s * B->s < 0 )
966 {
967 if( mpi_cmp_abs( A, B ) >= 0 )
968 {
969 MPI_CHK( mpi_sub_abs( X, A, B ) );
970 X->s = s;
971 }
972 else
973 {
974 MPI_CHK( mpi_sub_abs( X, B, A ) );
975 X->s = -s;
976 }
977 }
978 else
979 {
980 MPI_CHK( mpi_add_abs( X, A, B ) );
981 X->s = s;
982 }
983
984cleanup:
985
986 return( ret );
987}
988
989/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100990 * Signed subtraction: X = A - B
Paul Bakker5121ce52009-01-03 21:22:43 +0000991 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000992int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000993{
994 int ret, s = A->s;
995
996 if( A->s * B->s > 0 )
997 {
998 if( mpi_cmp_abs( A, B ) >= 0 )
999 {
1000 MPI_CHK( mpi_sub_abs( X, A, B ) );
1001 X->s = s;
1002 }
1003 else
1004 {
1005 MPI_CHK( mpi_sub_abs( X, B, A ) );
1006 X->s = -s;
1007 }
1008 }
1009 else
1010 {
1011 MPI_CHK( mpi_add_abs( X, A, B ) );
1012 X->s = s;
1013 }
1014
1015cleanup:
1016
1017 return( ret );
1018}
1019
1020/*
1021 * Signed addition: X = A + b
1022 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001023int mpi_add_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001024{
1025 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001026 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001027
1028 p[0] = ( b < 0 ) ? -b : b;
1029 _B.s = ( b < 0 ) ? -1 : 1;
1030 _B.n = 1;
1031 _B.p = p;
1032
1033 return( mpi_add_mpi( X, A, &_B ) );
1034}
1035
1036/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001037 * Signed subtraction: X = A - b
Paul Bakker5121ce52009-01-03 21:22:43 +00001038 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001039int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001040{
1041 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001042 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001043
1044 p[0] = ( b < 0 ) ? -b : b;
1045 _B.s = ( b < 0 ) ? -1 : 1;
1046 _B.n = 1;
1047 _B.p = p;
1048
1049 return( mpi_sub_mpi( X, A, &_B ) );
1050}
1051
1052/*
1053 * Helper for mpi multiplication
Paul Bakkerfc4f46f2013-06-24 19:23:56 +02001054 */
1055static
1056#if defined(__APPLE__) && defined(__arm__)
1057/*
1058 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1059 * appears to need this to prevent bad ARM code generation at -O3.
1060 */
1061__attribute__ ((noinline))
1062#endif
1063void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001064{
Paul Bakkera755ca12011-04-24 09:11:17 +00001065 t_uint c = 0, t = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001066
1067#if defined(MULADDC_HUIT)
1068 for( ; i >= 8; i -= 8 )
1069 {
1070 MULADDC_INIT
1071 MULADDC_HUIT
1072 MULADDC_STOP
1073 }
1074
1075 for( ; i > 0; i-- )
1076 {
1077 MULADDC_INIT
1078 MULADDC_CORE
1079 MULADDC_STOP
1080 }
1081#else
1082 for( ; i >= 16; i -= 16 )
1083 {
1084 MULADDC_INIT
1085 MULADDC_CORE MULADDC_CORE
1086 MULADDC_CORE MULADDC_CORE
1087 MULADDC_CORE MULADDC_CORE
1088 MULADDC_CORE MULADDC_CORE
1089
1090 MULADDC_CORE MULADDC_CORE
1091 MULADDC_CORE MULADDC_CORE
1092 MULADDC_CORE MULADDC_CORE
1093 MULADDC_CORE MULADDC_CORE
1094 MULADDC_STOP
1095 }
1096
1097 for( ; i >= 8; i -= 8 )
1098 {
1099 MULADDC_INIT
1100 MULADDC_CORE MULADDC_CORE
1101 MULADDC_CORE MULADDC_CORE
1102
1103 MULADDC_CORE MULADDC_CORE
1104 MULADDC_CORE MULADDC_CORE
1105 MULADDC_STOP
1106 }
1107
1108 for( ; i > 0; i-- )
1109 {
1110 MULADDC_INIT
1111 MULADDC_CORE
1112 MULADDC_STOP
1113 }
1114#endif
1115
1116 t++;
1117
1118 do {
1119 *d += c; c = ( *d < c ); d++;
1120 }
1121 while( c != 0 );
1122}
1123
1124/*
1125 * Baseline multiplication: X = A * B (HAC 14.12)
1126 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001127int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001128{
Paul Bakker23986e52011-04-24 08:57:21 +00001129 int ret;
1130 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00001131 mpi TA, TB;
1132
Paul Bakker6c591fa2011-05-05 11:49:20 +00001133 mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001134
1135 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
1136 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
1137
Paul Bakker23986e52011-04-24 08:57:21 +00001138 for( i = A->n; i > 0; i-- )
1139 if( A->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001140 break;
1141
Paul Bakker23986e52011-04-24 08:57:21 +00001142 for( j = B->n; j > 0; j-- )
1143 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001144 break;
1145
Paul Bakker23986e52011-04-24 08:57:21 +00001146 MPI_CHK( mpi_grow( X, i + j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001147 MPI_CHK( mpi_lset( X, 0 ) );
1148
Paul Bakker23986e52011-04-24 08:57:21 +00001149 for( i++; j > 0; j-- )
1150 mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001151
1152 X->s = A->s * B->s;
1153
1154cleanup:
1155
Paul Bakker6c591fa2011-05-05 11:49:20 +00001156 mpi_free( &TB ); mpi_free( &TA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001157
1158 return( ret );
1159}
1160
1161/*
1162 * Baseline multiplication: X = A * b
1163 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001164int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001165{
1166 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001167 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001168
1169 _B.s = 1;
1170 _B.n = 1;
1171 _B.p = p;
1172 p[0] = b;
1173
1174 return( mpi_mul_mpi( X, A, &_B ) );
1175}
1176
1177/*
1178 * Division by mpi: A = Q * B + R (HAC 14.20)
1179 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001180int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001181{
Paul Bakker23986e52011-04-24 08:57:21 +00001182 int ret;
1183 size_t i, n, t, k;
Paul Bakker5121ce52009-01-03 21:22:43 +00001184 mpi X, Y, Z, T1, T2;
1185
1186 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001187 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001188
Paul Bakker6c591fa2011-05-05 11:49:20 +00001189 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
1190 mpi_init( &T1 ); mpi_init( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001191
1192 if( mpi_cmp_abs( A, B ) < 0 )
1193 {
1194 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1195 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1196 return( 0 );
1197 }
1198
1199 MPI_CHK( mpi_copy( &X, A ) );
1200 MPI_CHK( mpi_copy( &Y, B ) );
1201 X.s = Y.s = 1;
1202
1203 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1204 MPI_CHK( mpi_lset( &Z, 0 ) );
1205 MPI_CHK( mpi_grow( &T1, 2 ) );
1206 MPI_CHK( mpi_grow( &T2, 3 ) );
1207
1208 k = mpi_msb( &Y ) % biL;
Paul Bakkerf9688572011-05-05 10:00:45 +00001209 if( k < biL - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001210 {
1211 k = biL - 1 - k;
1212 MPI_CHK( mpi_shift_l( &X, k ) );
1213 MPI_CHK( mpi_shift_l( &Y, k ) );
1214 }
1215 else k = 0;
1216
1217 n = X.n - 1;
1218 t = Y.n - 1;
Paul Bakkerc110d022012-10-19 12:15:08 +00001219 MPI_CHK( mpi_shift_l( &Y, biL * (n - t) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001220
1221 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1222 {
1223 Z.p[n - t]++;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001224 MPI_CHK( mpi_sub_mpi( &X, &X, &Y ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001225 }
Paul Bakker6ea1a952013-12-31 11:16:03 +01001226 MPI_CHK( mpi_shift_r( &Y, biL * (n - t) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001227
1228 for( i = n; i > t ; i-- )
1229 {
1230 if( X.p[i] >= Y.p[t] )
1231 Z.p[i - t - 1] = ~0;
1232 else
1233 {
Paul Bakker62261d62012-10-02 12:19:31 +00001234#if defined(POLARSSL_HAVE_UDBL)
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001235 t_udbl r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001236
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001237 r = (t_udbl) X.p[i] << biL;
1238 r |= (t_udbl) X.p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001239 r /= Y.p[t];
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001240 if( r > ((t_udbl) 1 << biL) - 1)
1241 r = ((t_udbl) 1 << biL) - 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001242
Paul Bakkera755ca12011-04-24 09:11:17 +00001243 Z.p[i - t - 1] = (t_uint) r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001244#else
1245 /*
1246 * __udiv_qrnnd_c, from gmp/longlong.h
1247 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001248 t_uint q0, q1, r0, r1;
1249 t_uint d0, d1, d, m;
Paul Bakker5121ce52009-01-03 21:22:43 +00001250
1251 d = Y.p[t];
1252 d0 = ( d << biH ) >> biH;
1253 d1 = ( d >> biH );
1254
1255 q1 = X.p[i] / d1;
1256 r1 = X.p[i] - d1 * q1;
1257 r1 <<= biH;
1258 r1 |= ( X.p[i - 1] >> biH );
1259
1260 m = q1 * d0;
1261 if( r1 < m )
1262 {
1263 q1--, r1 += d;
1264 while( r1 >= d && r1 < m )
1265 q1--, r1 += d;
1266 }
1267 r1 -= m;
1268
1269 q0 = r1 / d1;
1270 r0 = r1 - d1 * q0;
1271 r0 <<= biH;
1272 r0 |= ( X.p[i - 1] << biH ) >> biH;
1273
1274 m = q0 * d0;
1275 if( r0 < m )
1276 {
1277 q0--, r0 += d;
1278 while( r0 >= d && r0 < m )
1279 q0--, r0 += d;
1280 }
1281 r0 -= m;
1282
1283 Z.p[i - t - 1] = ( q1 << biH ) | q0;
1284#endif
1285 }
1286
1287 Z.p[i - t - 1]++;
1288 do
1289 {
1290 Z.p[i - t - 1]--;
1291
1292 MPI_CHK( mpi_lset( &T1, 0 ) );
1293 T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
1294 T1.p[1] = Y.p[t];
1295 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1296
1297 MPI_CHK( mpi_lset( &T2, 0 ) );
1298 T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
1299 T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
1300 T2.p[2] = X.p[i];
1301 }
1302 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1303
1304 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1305 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1306 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1307
1308 if( mpi_cmp_int( &X, 0 ) < 0 )
1309 {
1310 MPI_CHK( mpi_copy( &T1, &Y ) );
1311 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1312 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1313 Z.p[i - t - 1]--;
1314 }
1315 }
1316
1317 if( Q != NULL )
1318 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001319 MPI_CHK( mpi_copy( Q, &Z ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001320 Q->s = A->s * B->s;
1321 }
1322
1323 if( R != NULL )
1324 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001325 MPI_CHK( mpi_shift_r( &X, k ) );
Paul Bakkerf02c5642012-11-13 10:25:21 +00001326 X.s = A->s;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001327 MPI_CHK( mpi_copy( R, &X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001328
Paul Bakker5121ce52009-01-03 21:22:43 +00001329 if( mpi_cmp_int( R, 0 ) == 0 )
1330 R->s = 1;
1331 }
1332
1333cleanup:
1334
Paul Bakker6c591fa2011-05-05 11:49:20 +00001335 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
1336 mpi_free( &T1 ); mpi_free( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001337
1338 return( ret );
1339}
1340
1341/*
1342 * Division by int: A = Q * b + R
Paul Bakker5121ce52009-01-03 21:22:43 +00001343 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001344int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001345{
1346 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001347 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001348
1349 p[0] = ( b < 0 ) ? -b : b;
1350 _B.s = ( b < 0 ) ? -1 : 1;
1351 _B.n = 1;
1352 _B.p = p;
1353
1354 return( mpi_div_mpi( Q, R, A, &_B ) );
1355}
1356
1357/*
1358 * Modulo: R = A mod B
1359 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001360int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001361{
1362 int ret;
1363
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001364 if( mpi_cmp_int( B, 0 ) < 0 )
1365 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
1366
Paul Bakker5121ce52009-01-03 21:22:43 +00001367 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1368
1369 while( mpi_cmp_int( R, 0 ) < 0 )
1370 MPI_CHK( mpi_add_mpi( R, R, B ) );
1371
1372 while( mpi_cmp_mpi( R, B ) >= 0 )
1373 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1374
1375cleanup:
1376
1377 return( ret );
1378}
1379
1380/*
1381 * Modulo: r = A mod b
1382 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001383int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001384{
Paul Bakker23986e52011-04-24 08:57:21 +00001385 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +00001386 t_uint x, y, z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001387
1388 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001389 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001390
1391 if( b < 0 )
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001392 return POLARSSL_ERR_MPI_NEGATIVE_VALUE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001393
1394 /*
1395 * handle trivial cases
1396 */
1397 if( b == 1 )
1398 {
1399 *r = 0;
1400 return( 0 );
1401 }
1402
1403 if( b == 2 )
1404 {
1405 *r = A->p[0] & 1;
1406 return( 0 );
1407 }
1408
1409 /*
1410 * general case
1411 */
Paul Bakker23986e52011-04-24 08:57:21 +00001412 for( i = A->n, y = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001413 {
Paul Bakker23986e52011-04-24 08:57:21 +00001414 x = A->p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001415 y = ( y << biH ) | ( x >> biH );
1416 z = y / b;
1417 y -= z * b;
1418
1419 x <<= biH;
1420 y = ( y << biH ) | ( x >> biH );
1421 z = y / b;
1422 y -= z * b;
1423 }
1424
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001425 /*
1426 * If A is negative, then the current y represents a negative value.
1427 * Flipping it to the positive side.
1428 */
1429 if( A->s < 0 && y != 0 )
1430 y = b - y;
1431
Paul Bakker5121ce52009-01-03 21:22:43 +00001432 *r = y;
1433
1434 return( 0 );
1435}
1436
1437/*
1438 * Fast Montgomery initialization (thanks to Tom St Denis)
1439 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001440static void mpi_montg_init( t_uint *mm, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001441{
Paul Bakkera755ca12011-04-24 09:11:17 +00001442 t_uint x, m0 = N->p[0];
Paul Bakker5121ce52009-01-03 21:22:43 +00001443
1444 x = m0;
1445 x += ( ( m0 + 2 ) & 4 ) << 1;
1446 x *= ( 2 - ( m0 * x ) );
1447
1448 if( biL >= 16 ) x *= ( 2 - ( m0 * x ) );
1449 if( biL >= 32 ) x *= ( 2 - ( m0 * x ) );
1450 if( biL >= 64 ) x *= ( 2 - ( m0 * x ) );
1451
1452 *mm = ~x + 1;
1453}
1454
1455/*
1456 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1457 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001458static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001459{
Paul Bakker23986e52011-04-24 08:57:21 +00001460 size_t i, n, m;
Paul Bakkera755ca12011-04-24 09:11:17 +00001461 t_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00001462
1463 memset( T->p, 0, T->n * ciL );
1464
1465 d = T->p;
1466 n = N->n;
1467 m = ( B->n < n ) ? B->n : n;
1468
1469 for( i = 0; i < n; i++ )
1470 {
1471 /*
1472 * T = (T + u0*B + u1*N) / 2^biL
1473 */
1474 u0 = A->p[i];
1475 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1476
1477 mpi_mul_hlp( m, B->p, d, u0 );
1478 mpi_mul_hlp( n, N->p, d, u1 );
1479
1480 *d++ = u0; d[n + 1] = 0;
1481 }
1482
1483 memcpy( A->p, d, (n + 1) * ciL );
1484
1485 if( mpi_cmp_abs( A, N ) >= 0 )
1486 mpi_sub_hlp( n, N->p, A->p );
1487 else
1488 /* prevent timing attacks */
1489 mpi_sub_hlp( n, A->p, T->p );
1490}
1491
1492/*
1493 * Montgomery reduction: A = A * R^-1 mod N
1494 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001495static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001496{
Paul Bakkera755ca12011-04-24 09:11:17 +00001497 t_uint z = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001498 mpi U;
1499
Paul Bakker8ddb6452013-02-27 14:56:33 +01001500 U.n = U.s = (int) z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001501 U.p = &z;
1502
1503 mpi_montmul( A, &U, N, mm, T );
1504}
1505
1506/*
1507 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1508 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001509int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00001510{
Paul Bakker23986e52011-04-24 08:57:21 +00001511 int ret;
1512 size_t wbits, wsize, one = 1;
1513 size_t i, j, nblimbs;
1514 size_t bufsize, nbits;
Paul Bakkera755ca12011-04-24 09:11:17 +00001515 t_uint ei, mm, state;
Paul Bakkerf6198c12012-05-16 08:02:29 +00001516 mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos;
1517 int neg;
Paul Bakker5121ce52009-01-03 21:22:43 +00001518
1519 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001520 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001521
Paul Bakkerf6198c12012-05-16 08:02:29 +00001522 if( mpi_cmp_int( E, 0 ) < 0 )
1523 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
1524
1525 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001526 * Init temps and window size
1527 */
1528 mpi_montg_init( &mm, N );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001529 mpi_init( &RR ); mpi_init( &T );
Manuel Pégourié-Gonnardfd6a1912014-01-18 19:05:23 +01001530 mpi_init( &Apos );
Paul Bakker5121ce52009-01-03 21:22:43 +00001531 memset( W, 0, sizeof( W ) );
1532
1533 i = mpi_msb( E );
1534
1535 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1536 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1537
Paul Bakkerb6d5f082011-11-25 11:52:11 +00001538 if( wsize > POLARSSL_MPI_WINDOW_SIZE )
1539 wsize = POLARSSL_MPI_WINDOW_SIZE;
1540
Paul Bakker5121ce52009-01-03 21:22:43 +00001541 j = N->n + 1;
1542 MPI_CHK( mpi_grow( X, j ) );
1543 MPI_CHK( mpi_grow( &W[1], j ) );
1544 MPI_CHK( mpi_grow( &T, j * 2 ) );
1545
1546 /*
Paul Bakker50546922012-05-19 08:40:49 +00001547 * Compensate for negative A (and correct at the end)
1548 */
1549 neg = ( A->s == -1 );
Paul Bakker50546922012-05-19 08:40:49 +00001550 if( neg )
1551 {
1552 MPI_CHK( mpi_copy( &Apos, A ) );
1553 Apos.s = 1;
1554 A = &Apos;
1555 }
1556
1557 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001558 * If 1st call, pre-compute R^2 mod N
1559 */
1560 if( _RR == NULL || _RR->p == NULL )
1561 {
1562 MPI_CHK( mpi_lset( &RR, 1 ) );
1563 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1564 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1565
1566 if( _RR != NULL )
1567 memcpy( _RR, &RR, sizeof( mpi ) );
1568 }
1569 else
1570 memcpy( &RR, _RR, sizeof( mpi ) );
1571
1572 /*
1573 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1574 */
1575 if( mpi_cmp_mpi( A, N ) >= 0 )
1576 mpi_mod_mpi( &W[1], A, N );
1577 else mpi_copy( &W[1], A );
1578
1579 mpi_montmul( &W[1], &RR, N, mm, &T );
1580
1581 /*
1582 * X = R^2 * R^-1 mod N = R mod N
1583 */
1584 MPI_CHK( mpi_copy( X, &RR ) );
1585 mpi_montred( X, N, mm, &T );
1586
1587 if( wsize > 1 )
1588 {
1589 /*
1590 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1591 */
Paul Bakker23986e52011-04-24 08:57:21 +00001592 j = one << (wsize - 1);
Paul Bakker5121ce52009-01-03 21:22:43 +00001593
1594 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1595 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1596
1597 for( i = 0; i < wsize - 1; i++ )
1598 mpi_montmul( &W[j], &W[j], N, mm, &T );
Paul Bakker0d7702c2013-10-29 16:18:35 +01001599
Paul Bakker5121ce52009-01-03 21:22:43 +00001600 /*
1601 * W[i] = W[i - 1] * W[1]
1602 */
Paul Bakker23986e52011-04-24 08:57:21 +00001603 for( i = j + 1; i < (one << wsize); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001604 {
1605 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1606 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1607
1608 mpi_montmul( &W[i], &W[1], N, mm, &T );
1609 }
1610 }
1611
1612 nblimbs = E->n;
1613 bufsize = 0;
1614 nbits = 0;
1615 wbits = 0;
1616 state = 0;
1617
1618 while( 1 )
1619 {
1620 if( bufsize == 0 )
1621 {
Paul Bakker0d7702c2013-10-29 16:18:35 +01001622 if( nblimbs == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001623 break;
1624
Paul Bakker0d7702c2013-10-29 16:18:35 +01001625 nblimbs--;
1626
Paul Bakkera755ca12011-04-24 09:11:17 +00001627 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001628 }
1629
1630 bufsize--;
1631
1632 ei = (E->p[nblimbs] >> bufsize) & 1;
1633
1634 /*
1635 * skip leading 0s
1636 */
1637 if( ei == 0 && state == 0 )
1638 continue;
1639
1640 if( ei == 0 && state == 1 )
1641 {
1642 /*
1643 * out of window, square X
1644 */
1645 mpi_montmul( X, X, N, mm, &T );
1646 continue;
1647 }
1648
1649 /*
1650 * add ei to current window
1651 */
1652 state = 2;
1653
1654 nbits++;
1655 wbits |= (ei << (wsize - nbits));
1656
1657 if( nbits == wsize )
1658 {
1659 /*
1660 * X = X^wsize R^-1 mod N
1661 */
1662 for( i = 0; i < wsize; i++ )
1663 mpi_montmul( X, X, N, mm, &T );
1664
1665 /*
1666 * X = X * W[wbits] R^-1 mod N
1667 */
1668 mpi_montmul( X, &W[wbits], N, mm, &T );
1669
1670 state--;
1671 nbits = 0;
1672 wbits = 0;
1673 }
1674 }
1675
1676 /*
1677 * process the remaining bits
1678 */
1679 for( i = 0; i < nbits; i++ )
1680 {
1681 mpi_montmul( X, X, N, mm, &T );
1682
1683 wbits <<= 1;
1684
Paul Bakker23986e52011-04-24 08:57:21 +00001685 if( (wbits & (one << wsize)) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001686 mpi_montmul( X, &W[1], N, mm, &T );
1687 }
1688
1689 /*
1690 * X = A^E * R * R^-1 mod N = A^E mod N
1691 */
1692 mpi_montred( X, N, mm, &T );
1693
Paul Bakkerf6198c12012-05-16 08:02:29 +00001694 if( neg )
1695 {
1696 X->s = -1;
1697 mpi_add_mpi( X, N, X );
1698 }
1699
Paul Bakker5121ce52009-01-03 21:22:43 +00001700cleanup:
1701
Paul Bakker23986e52011-04-24 08:57:21 +00001702 for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001703 mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001704
Paul Bakkerf6198c12012-05-16 08:02:29 +00001705 mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001706
1707 if( _RR == NULL )
1708 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001709
1710 return( ret );
1711}
1712
Paul Bakker5121ce52009-01-03 21:22:43 +00001713/*
1714 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1715 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001716int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001717{
Paul Bakker23986e52011-04-24 08:57:21 +00001718 int ret;
1719 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001720 mpi TG, TA, TB;
1721
Paul Bakker6c591fa2011-05-05 11:49:20 +00001722 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001723
Paul Bakker5121ce52009-01-03 21:22:43 +00001724 MPI_CHK( mpi_copy( &TA, A ) );
1725 MPI_CHK( mpi_copy( &TB, B ) );
1726
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001727 lz = mpi_lsb( &TA );
1728 lzt = mpi_lsb( &TB );
1729
1730 if ( lzt < lz )
1731 lz = lzt;
1732
1733 MPI_CHK( mpi_shift_r( &TA, lz ) );
1734 MPI_CHK( mpi_shift_r( &TB, lz ) );
1735
Paul Bakker5121ce52009-01-03 21:22:43 +00001736 TA.s = TB.s = 1;
1737
1738 while( mpi_cmp_int( &TA, 0 ) != 0 )
1739 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001740 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1741 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001742
1743 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1744 {
1745 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1746 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1747 }
1748 else
1749 {
1750 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1751 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1752 }
1753 }
1754
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001755 MPI_CHK( mpi_shift_l( &TB, lz ) );
1756 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001757
1758cleanup:
1759
Paul Bakker6c591fa2011-05-05 11:49:20 +00001760 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001761
1762 return( ret );
1763}
1764
Paul Bakkera3d195c2011-11-27 21:07:34 +00001765int mpi_fill_random( mpi *X, size_t size,
1766 int (*f_rng)(void *, unsigned char *, size_t),
1767 void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001768{
Paul Bakker23986e52011-04-24 08:57:21 +00001769 int ret;
Paul Bakker287781a2011-03-26 13:18:49 +00001770
Paul Bakker39dfdac2012-02-12 17:17:27 +00001771 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( size ) ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001772 MPI_CHK( mpi_lset( X, 0 ) );
1773
Paul Bakker39dfdac2012-02-12 17:17:27 +00001774 MPI_CHK( f_rng( p_rng, (unsigned char *) X->p, size ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001775
1776cleanup:
1777 return( ret );
1778}
1779
Paul Bakker5121ce52009-01-03 21:22:43 +00001780/*
1781 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1782 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001783int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001784{
1785 int ret;
1786 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1787
1788 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001789 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001790
Paul Bakker6c591fa2011-05-05 11:49:20 +00001791 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1792 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1793 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001794
1795 MPI_CHK( mpi_gcd( &G, A, N ) );
1796
1797 if( mpi_cmp_int( &G, 1 ) != 0 )
1798 {
Paul Bakker40e46942009-01-03 21:51:57 +00001799 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001800 goto cleanup;
1801 }
1802
1803 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1804 MPI_CHK( mpi_copy( &TU, &TA ) );
1805 MPI_CHK( mpi_copy( &TB, N ) );
1806 MPI_CHK( mpi_copy( &TV, N ) );
1807
1808 MPI_CHK( mpi_lset( &U1, 1 ) );
1809 MPI_CHK( mpi_lset( &U2, 0 ) );
1810 MPI_CHK( mpi_lset( &V1, 0 ) );
1811 MPI_CHK( mpi_lset( &V2, 1 ) );
1812
1813 do
1814 {
1815 while( ( TU.p[0] & 1 ) == 0 )
1816 {
1817 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1818
1819 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1820 {
1821 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1822 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1823 }
1824
1825 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1826 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1827 }
1828
1829 while( ( TV.p[0] & 1 ) == 0 )
1830 {
1831 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1832
1833 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1834 {
1835 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1836 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1837 }
1838
1839 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1840 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1841 }
1842
1843 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1844 {
1845 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1846 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1847 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1848 }
1849 else
1850 {
1851 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1852 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1853 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1854 }
1855 }
1856 while( mpi_cmp_int( &TU, 0 ) != 0 );
1857
1858 while( mpi_cmp_int( &V1, 0 ) < 0 )
1859 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1860
1861 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1862 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1863
1864 MPI_CHK( mpi_copy( X, &V1 ) );
1865
1866cleanup:
1867
Paul Bakker6c591fa2011-05-05 11:49:20 +00001868 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1869 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1870 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001871
1872 return( ret );
1873}
1874
Paul Bakkerd9374b02012-11-02 11:02:58 +00001875#if defined(POLARSSL_GENPRIME)
1876
Paul Bakker5121ce52009-01-03 21:22:43 +00001877static const int small_prime[] =
1878{
1879 3, 5, 7, 11, 13, 17, 19, 23,
1880 29, 31, 37, 41, 43, 47, 53, 59,
1881 61, 67, 71, 73, 79, 83, 89, 97,
1882 101, 103, 107, 109, 113, 127, 131, 137,
1883 139, 149, 151, 157, 163, 167, 173, 179,
1884 181, 191, 193, 197, 199, 211, 223, 227,
1885 229, 233, 239, 241, 251, 257, 263, 269,
1886 271, 277, 281, 283, 293, 307, 311, 313,
1887 317, 331, 337, 347, 349, 353, 359, 367,
1888 373, 379, 383, 389, 397, 401, 409, 419,
1889 421, 431, 433, 439, 443, 449, 457, 461,
1890 463, 467, 479, 487, 491, 499, 503, 509,
1891 521, 523, 541, 547, 557, 563, 569, 571,
1892 577, 587, 593, 599, 601, 607, 613, 617,
1893 619, 631, 641, 643, 647, 653, 659, 661,
1894 673, 677, 683, 691, 701, 709, 719, 727,
1895 733, 739, 743, 751, 757, 761, 769, 773,
1896 787, 797, 809, 811, 821, 823, 827, 829,
1897 839, 853, 857, 859, 863, 877, 881, 883,
1898 887, 907, 911, 919, 929, 937, 941, 947,
1899 953, 967, 971, 977, 983, 991, 997, -103
1900};
1901
1902/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001903 * Small divisors test (X must be positive)
1904 *
1905 * Return values:
1906 * 0: no small factor (possible prime, more tests needed)
1907 * 1: certain prime
1908 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
1909 * other negative: error
Paul Bakker5121ce52009-01-03 21:22:43 +00001910 */
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001911static int mpi_check_small_factors( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +00001912{
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001913 int ret = 0;
1914 size_t i;
1915 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001916
Paul Bakker5121ce52009-01-03 21:22:43 +00001917 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001918 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001919
1920 for( i = 0; small_prime[i] > 0; i++ )
1921 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001922 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001923 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001924
1925 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1926
1927 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001928 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001929 }
1930
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001931cleanup:
1932 return( ret );
1933}
1934
1935/*
1936 * Miller-Rabin pseudo-primality test (HAC 4.24)
1937 */
1938static int mpi_miller_rabin( const mpi *X,
1939 int (*f_rng)(void *, unsigned char *, size_t),
1940 void *p_rng )
1941{
1942 int ret;
1943 size_t i, j, n, s;
1944 mpi W, R, T, A, RR;
1945
1946 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1947 mpi_init( &RR );
1948
Paul Bakker5121ce52009-01-03 21:22:43 +00001949 /*
1950 * W = |X| - 1
1951 * R = W >> lsb( W )
1952 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001953 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001954 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001955 MPI_CHK( mpi_copy( &R, &W ) );
1956 MPI_CHK( mpi_shift_r( &R, s ) );
1957
1958 i = mpi_msb( X );
1959 /*
1960 * HAC, table 4.4
1961 */
1962 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1963 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1964 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1965
1966 for( i = 0; i < n; i++ )
1967 {
1968 /*
1969 * pick a random A, 1 < A < |X| - 1
1970 */
Paul Bakker901c6562012-04-20 13:25:38 +00001971 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001972
Paul Bakkerb94081b2011-01-05 15:53:06 +00001973 if( mpi_cmp_mpi( &A, &W ) >= 0 )
1974 {
1975 j = mpi_msb( &A ) - mpi_msb( &W );
1976 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
1977 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001978 A.p[0] |= 3;
1979
1980 /*
1981 * A = A^R mod |X|
1982 */
1983 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
1984
1985 if( mpi_cmp_mpi( &A, &W ) == 0 ||
1986 mpi_cmp_int( &A, 1 ) == 0 )
1987 continue;
1988
1989 j = 1;
1990 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
1991 {
1992 /*
1993 * A = A * A mod |X|
1994 */
1995 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
1996 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
1997
1998 if( mpi_cmp_int( &A, 1 ) == 0 )
1999 break;
2000
2001 j++;
2002 }
2003
2004 /*
2005 * not prime if A != |X| - 1 or A == 1
2006 */
2007 if( mpi_cmp_mpi( &A, &W ) != 0 ||
2008 mpi_cmp_int( &A, 1 ) == 0 )
2009 {
Paul Bakker40e46942009-01-03 21:51:57 +00002010 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002011 break;
2012 }
2013 }
2014
2015cleanup:
Paul Bakker6c591fa2011-05-05 11:49:20 +00002016 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
2017 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002018
2019 return( ret );
2020}
2021
2022/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002023 * Pseudo-primality test: small factors, then Miller-Rabin
2024 */
Paul Bakker45f457d2013-11-25 14:26:52 +01002025int mpi_is_prime( mpi *X,
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002026 int (*f_rng)(void *, unsigned char *, size_t),
2027 void *p_rng )
2028{
2029 int ret;
2030 const mpi XX = { 1, X->n, X->p }; /* Abs(X) */
2031
2032 if( mpi_cmp_int( &XX, 0 ) == 0 ||
2033 mpi_cmp_int( &XX, 1 ) == 0 )
2034 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
2035
2036 if( mpi_cmp_int( &XX, 2 ) == 0 )
2037 return( 0 );
2038
2039 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2040 {
2041 if( ret == 1 )
2042 return( 0 );
2043
2044 return( ret );
2045 }
2046
2047 return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
2048}
2049
2050/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002051 * Prime number generation
2052 */
Paul Bakker23986e52011-04-24 08:57:21 +00002053int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002054 int (*f_rng)(void *, unsigned char *, size_t),
2055 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +00002056{
Paul Bakker23986e52011-04-24 08:57:21 +00002057 int ret;
2058 size_t k, n;
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002059 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002060 mpi Y;
2061
Paul Bakkerfe3256e2011-11-25 12:11:43 +00002062 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
Paul Bakker40e46942009-01-03 21:51:57 +00002063 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002064
Paul Bakker6c591fa2011-05-05 11:49:20 +00002065 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002066
2067 n = BITS_TO_LIMBS( nbits );
2068
Paul Bakker901c6562012-04-20 13:25:38 +00002069 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002070
2071 k = mpi_msb( X );
2072 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
2073 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
2074
2075 X->p[0] |= 3;
2076
2077 if( dh_flag == 0 )
2078 {
2079 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
2080 {
Paul Bakker40e46942009-01-03 21:51:57 +00002081 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002082 goto cleanup;
2083
2084 MPI_CHK( mpi_add_int( X, X, 2 ) );
2085 }
2086 }
2087 else
2088 {
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002089 /*
2090 * An necessary condition for Y and X = 2Y + 1 to be prime
2091 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2092 * Make sure it is satisfied, while keeping X = 3 mod 4
2093 */
2094 MPI_CHK( mpi_mod_int( &r, X, 3 ) );
2095 if( r == 0 )
2096 MPI_CHK( mpi_add_int( X, X, 8 ) );
2097 else if( r == 1 )
2098 MPI_CHK( mpi_add_int( X, X, 4 ) );
2099
2100 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2101 MPI_CHK( mpi_copy( &Y, X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002102 MPI_CHK( mpi_shift_r( &Y, 1 ) );
2103
2104 while( 1 )
2105 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002106 /*
2107 * First, check small factors for X and Y
2108 * before doing Miller-Rabin on any of them
2109 */
2110 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2111 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2112 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
2113 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002114 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002115 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002116 }
2117
Paul Bakker40e46942009-01-03 21:51:57 +00002118 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002119 goto cleanup;
2120
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002121 /*
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002122 * Next candidates. We want to preserve Y = (X-1) / 2 and
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002123 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2124 * so up Y by 6 and X by 12.
2125 */
2126 MPI_CHK( mpi_add_int( X, X, 12 ) );
2127 MPI_CHK( mpi_add_int( &Y, &Y, 6 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002128 }
2129 }
2130
2131cleanup:
2132
Paul Bakker6c591fa2011-05-05 11:49:20 +00002133 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002134
2135 return( ret );
2136}
2137
Manuel Pégourié-Gonnarddf0142b2013-08-22 18:29:07 +02002138#endif /* POLARSSL_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00002139
Paul Bakker40e46942009-01-03 21:51:57 +00002140#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002141
Paul Bakker23986e52011-04-24 08:57:21 +00002142#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002143
2144static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2145{
2146 { 693, 609, 21 },
2147 { 1764, 868, 28 },
2148 { 768454923, 542167814, 1 }
2149};
2150
Paul Bakker5121ce52009-01-03 21:22:43 +00002151/*
2152 * Checkup routine
2153 */
2154int mpi_self_test( int verbose )
2155{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002156 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00002157 mpi A, E, N, X, Y, U, V;
2158
Paul Bakker6c591fa2011-05-05 11:49:20 +00002159 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
2160 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002161
2162 MPI_CHK( mpi_read_string( &A, 16,
2163 "EFE021C2645FD1DC586E69184AF4A31E" \
2164 "D5F53E93B5F123FA41680867BA110131" \
2165 "944FE7952E2517337780CB0DB80E61AA" \
2166 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2167
2168 MPI_CHK( mpi_read_string( &E, 16,
2169 "B2E7EFD37075B9F03FF989C7C5051C20" \
2170 "34D2A323810251127E7BF8625A4F49A5" \
2171 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2172 "5B5C25763222FEFCCFC38B832366C29E" ) );
2173
2174 MPI_CHK( mpi_read_string( &N, 16,
2175 "0066A198186C18C10B2F5ED9B522752A" \
2176 "9830B69916E535C8F047518A889A43A5" \
2177 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2178
2179 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
2180
2181 MPI_CHK( mpi_read_string( &U, 16,
2182 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2183 "9E857EA95A03512E2BAE7391688D264A" \
2184 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2185 "8001B72E848A38CAE1C65F78E56ABDEF" \
2186 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2187 "ECF677152EF804370C1A305CAF3B5BF1" \
2188 "30879B56C61DE584A0F53A2447A51E" ) );
2189
2190 if( verbose != 0 )
2191 printf( " MPI test #1 (mul_mpi): " );
2192
2193 if( mpi_cmp_mpi( &X, &U ) != 0 )
2194 {
2195 if( verbose != 0 )
2196 printf( "failed\n" );
2197
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002198 ret = 1;
2199 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002200 }
2201
2202 if( verbose != 0 )
2203 printf( "passed\n" );
2204
2205 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
2206
2207 MPI_CHK( mpi_read_string( &U, 16,
2208 "256567336059E52CAE22925474705F39A94" ) );
2209
2210 MPI_CHK( mpi_read_string( &V, 16,
2211 "6613F26162223DF488E9CD48CC132C7A" \
2212 "0AC93C701B001B092E4E5B9F73BCD27B" \
2213 "9EE50D0657C77F374E903CDFA4C642" ) );
2214
2215 if( verbose != 0 )
2216 printf( " MPI test #2 (div_mpi): " );
2217
2218 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2219 mpi_cmp_mpi( &Y, &V ) != 0 )
2220 {
2221 if( verbose != 0 )
2222 printf( "failed\n" );
2223
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002224 ret = 1;
2225 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002226 }
2227
2228 if( verbose != 0 )
2229 printf( "passed\n" );
2230
2231 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2232
2233 MPI_CHK( mpi_read_string( &U, 16,
2234 "36E139AEA55215609D2816998ED020BB" \
2235 "BD96C37890F65171D948E9BC7CBAA4D9" \
2236 "325D24D6A3C12710F10A09FA08AB87" ) );
2237
2238 if( verbose != 0 )
2239 printf( " MPI test #3 (exp_mod): " );
2240
2241 if( mpi_cmp_mpi( &X, &U ) != 0 )
2242 {
2243 if( verbose != 0 )
2244 printf( "failed\n" );
2245
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002246 ret = 1;
2247 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002248 }
2249
2250 if( verbose != 0 )
2251 printf( "passed\n" );
2252
2253 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2254
2255 MPI_CHK( mpi_read_string( &U, 16,
2256 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2257 "C3DBA76456363A10869622EAC2DD84EC" \
2258 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2259
2260 if( verbose != 0 )
2261 printf( " MPI test #4 (inv_mod): " );
2262
2263 if( mpi_cmp_mpi( &X, &U ) != 0 )
2264 {
2265 if( verbose != 0 )
2266 printf( "failed\n" );
2267
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002268 ret = 1;
2269 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002270 }
2271
2272 if( verbose != 0 )
2273 printf( "passed\n" );
2274
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002275 if( verbose != 0 )
2276 printf( " MPI test #5 (simple gcd): " );
2277
2278 for ( i = 0; i < GCD_PAIR_COUNT; i++)
2279 {
2280 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002281 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002282
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002283 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002284
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002285 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2286 {
2287 if( verbose != 0 )
2288 printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002289
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002290 ret = 1;
2291 goto cleanup;
2292 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002293 }
2294
2295 if( verbose != 0 )
2296 printf( "passed\n" );
2297
Paul Bakker5121ce52009-01-03 21:22:43 +00002298cleanup:
2299
2300 if( ret != 0 && verbose != 0 )
2301 printf( "Unexpected error, return code = %08X\n", ret );
2302
Paul Bakker6c591fa2011-05-05 11:49:20 +00002303 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2304 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002305
2306 if( verbose != 0 )
2307 printf( "\n" );
2308
2309 return( ret );
2310}
2311
2312#endif
2313
2314#endif