blob: dd5c0bfdd8ddb9bcb854f8b9048e7afa1180dbbb [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]++;
1224 mpi_sub_mpi( &X, &X, &Y );
1225 }
1226 mpi_shift_r( &Y, biL * (n - t) );
1227
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 {
1319 mpi_copy( Q, &Z );
1320 Q->s = A->s * B->s;
1321 }
1322
1323 if( R != NULL )
1324 {
1325 mpi_shift_r( &X, k );
Paul Bakkerf02c5642012-11-13 10:25:21 +00001326 X.s = A->s;
Paul Bakker5121ce52009-01-03 21:22:43 +00001327 mpi_copy( R, &X );
1328
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 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001530 memset( W, 0, sizeof( W ) );
1531
1532 i = mpi_msb( E );
1533
1534 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1535 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1536
Paul Bakkerb6d5f082011-11-25 11:52:11 +00001537 if( wsize > POLARSSL_MPI_WINDOW_SIZE )
1538 wsize = POLARSSL_MPI_WINDOW_SIZE;
1539
Paul Bakker5121ce52009-01-03 21:22:43 +00001540 j = N->n + 1;
1541 MPI_CHK( mpi_grow( X, j ) );
1542 MPI_CHK( mpi_grow( &W[1], j ) );
1543 MPI_CHK( mpi_grow( &T, j * 2 ) );
1544
1545 /*
Paul Bakker50546922012-05-19 08:40:49 +00001546 * Compensate for negative A (and correct at the end)
1547 */
1548 neg = ( A->s == -1 );
1549
1550 mpi_init( &Apos );
1551 if( neg )
1552 {
1553 MPI_CHK( mpi_copy( &Apos, A ) );
1554 Apos.s = 1;
1555 A = &Apos;
1556 }
1557
1558 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001559 * If 1st call, pre-compute R^2 mod N
1560 */
1561 if( _RR == NULL || _RR->p == NULL )
1562 {
1563 MPI_CHK( mpi_lset( &RR, 1 ) );
1564 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1565 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1566
1567 if( _RR != NULL )
1568 memcpy( _RR, &RR, sizeof( mpi ) );
1569 }
1570 else
1571 memcpy( &RR, _RR, sizeof( mpi ) );
1572
1573 /*
1574 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1575 */
1576 if( mpi_cmp_mpi( A, N ) >= 0 )
1577 mpi_mod_mpi( &W[1], A, N );
1578 else mpi_copy( &W[1], A );
1579
1580 mpi_montmul( &W[1], &RR, N, mm, &T );
1581
1582 /*
1583 * X = R^2 * R^-1 mod N = R mod N
1584 */
1585 MPI_CHK( mpi_copy( X, &RR ) );
1586 mpi_montred( X, N, mm, &T );
1587
1588 if( wsize > 1 )
1589 {
1590 /*
1591 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1592 */
Paul Bakker23986e52011-04-24 08:57:21 +00001593 j = one << (wsize - 1);
Paul Bakker5121ce52009-01-03 21:22:43 +00001594
1595 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1596 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1597
1598 for( i = 0; i < wsize - 1; i++ )
1599 mpi_montmul( &W[j], &W[j], N, mm, &T );
Paul Bakker0d7702c2013-10-29 16:18:35 +01001600
Paul Bakker5121ce52009-01-03 21:22:43 +00001601 /*
1602 * W[i] = W[i - 1] * W[1]
1603 */
Paul Bakker23986e52011-04-24 08:57:21 +00001604 for( i = j + 1; i < (one << wsize); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001605 {
1606 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1607 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1608
1609 mpi_montmul( &W[i], &W[1], N, mm, &T );
1610 }
1611 }
1612
1613 nblimbs = E->n;
1614 bufsize = 0;
1615 nbits = 0;
1616 wbits = 0;
1617 state = 0;
1618
1619 while( 1 )
1620 {
1621 if( bufsize == 0 )
1622 {
Paul Bakker0d7702c2013-10-29 16:18:35 +01001623 if( nblimbs == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001624 break;
1625
Paul Bakker0d7702c2013-10-29 16:18:35 +01001626 nblimbs--;
1627
Paul Bakkera755ca12011-04-24 09:11:17 +00001628 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001629 }
1630
1631 bufsize--;
1632
1633 ei = (E->p[nblimbs] >> bufsize) & 1;
1634
1635 /*
1636 * skip leading 0s
1637 */
1638 if( ei == 0 && state == 0 )
1639 continue;
1640
1641 if( ei == 0 && state == 1 )
1642 {
1643 /*
1644 * out of window, square X
1645 */
1646 mpi_montmul( X, X, N, mm, &T );
1647 continue;
1648 }
1649
1650 /*
1651 * add ei to current window
1652 */
1653 state = 2;
1654
1655 nbits++;
1656 wbits |= (ei << (wsize - nbits));
1657
1658 if( nbits == wsize )
1659 {
1660 /*
1661 * X = X^wsize R^-1 mod N
1662 */
1663 for( i = 0; i < wsize; i++ )
1664 mpi_montmul( X, X, N, mm, &T );
1665
1666 /*
1667 * X = X * W[wbits] R^-1 mod N
1668 */
1669 mpi_montmul( X, &W[wbits], N, mm, &T );
1670
1671 state--;
1672 nbits = 0;
1673 wbits = 0;
1674 }
1675 }
1676
1677 /*
1678 * process the remaining bits
1679 */
1680 for( i = 0; i < nbits; i++ )
1681 {
1682 mpi_montmul( X, X, N, mm, &T );
1683
1684 wbits <<= 1;
1685
Paul Bakker23986e52011-04-24 08:57:21 +00001686 if( (wbits & (one << wsize)) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001687 mpi_montmul( X, &W[1], N, mm, &T );
1688 }
1689
1690 /*
1691 * X = A^E * R * R^-1 mod N = A^E mod N
1692 */
1693 mpi_montred( X, N, mm, &T );
1694
Paul Bakkerf6198c12012-05-16 08:02:29 +00001695 if( neg )
1696 {
1697 X->s = -1;
1698 mpi_add_mpi( X, N, X );
1699 }
1700
Paul Bakker5121ce52009-01-03 21:22:43 +00001701cleanup:
1702
Paul Bakker23986e52011-04-24 08:57:21 +00001703 for( i = (one << (wsize - 1)); i < (one << wsize); i++ )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001704 mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001705
Paul Bakkerf6198c12012-05-16 08:02:29 +00001706 mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001707
1708 if( _RR == NULL )
1709 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001710
1711 return( ret );
1712}
1713
Paul Bakker5121ce52009-01-03 21:22:43 +00001714/*
1715 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1716 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001717int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001718{
Paul Bakker23986e52011-04-24 08:57:21 +00001719 int ret;
1720 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001721 mpi TG, TA, TB;
1722
Paul Bakker6c591fa2011-05-05 11:49:20 +00001723 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001724
Paul Bakker5121ce52009-01-03 21:22:43 +00001725 MPI_CHK( mpi_copy( &TA, A ) );
1726 MPI_CHK( mpi_copy( &TB, B ) );
1727
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001728 lz = mpi_lsb( &TA );
1729 lzt = mpi_lsb( &TB );
1730
1731 if ( lzt < lz )
1732 lz = lzt;
1733
1734 MPI_CHK( mpi_shift_r( &TA, lz ) );
1735 MPI_CHK( mpi_shift_r( &TB, lz ) );
1736
Paul Bakker5121ce52009-01-03 21:22:43 +00001737 TA.s = TB.s = 1;
1738
1739 while( mpi_cmp_int( &TA, 0 ) != 0 )
1740 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001741 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1742 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001743
1744 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1745 {
1746 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1747 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1748 }
1749 else
1750 {
1751 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1752 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1753 }
1754 }
1755
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001756 MPI_CHK( mpi_shift_l( &TB, lz ) );
1757 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001758
1759cleanup:
1760
Paul Bakker6c591fa2011-05-05 11:49:20 +00001761 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001762
1763 return( ret );
1764}
1765
Paul Bakkera3d195c2011-11-27 21:07:34 +00001766int mpi_fill_random( mpi *X, size_t size,
1767 int (*f_rng)(void *, unsigned char *, size_t),
1768 void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001769{
Paul Bakker23986e52011-04-24 08:57:21 +00001770 int ret;
Paul Bakker287781a2011-03-26 13:18:49 +00001771
Paul Bakker39dfdac2012-02-12 17:17:27 +00001772 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( size ) ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001773 MPI_CHK( mpi_lset( X, 0 ) );
1774
Paul Bakker39dfdac2012-02-12 17:17:27 +00001775 MPI_CHK( f_rng( p_rng, (unsigned char *) X->p, size ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001776
1777cleanup:
1778 return( ret );
1779}
1780
Paul Bakker5121ce52009-01-03 21:22:43 +00001781/*
1782 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1783 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001784int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001785{
1786 int ret;
1787 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1788
1789 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001790 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001791
Paul Bakker6c591fa2011-05-05 11:49:20 +00001792 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1793 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1794 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001795
1796 MPI_CHK( mpi_gcd( &G, A, N ) );
1797
1798 if( mpi_cmp_int( &G, 1 ) != 0 )
1799 {
Paul Bakker40e46942009-01-03 21:51:57 +00001800 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001801 goto cleanup;
1802 }
1803
1804 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1805 MPI_CHK( mpi_copy( &TU, &TA ) );
1806 MPI_CHK( mpi_copy( &TB, N ) );
1807 MPI_CHK( mpi_copy( &TV, N ) );
1808
1809 MPI_CHK( mpi_lset( &U1, 1 ) );
1810 MPI_CHK( mpi_lset( &U2, 0 ) );
1811 MPI_CHK( mpi_lset( &V1, 0 ) );
1812 MPI_CHK( mpi_lset( &V2, 1 ) );
1813
1814 do
1815 {
1816 while( ( TU.p[0] & 1 ) == 0 )
1817 {
1818 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1819
1820 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1821 {
1822 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1823 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1824 }
1825
1826 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1827 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1828 }
1829
1830 while( ( TV.p[0] & 1 ) == 0 )
1831 {
1832 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1833
1834 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1835 {
1836 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1837 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1838 }
1839
1840 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1841 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1842 }
1843
1844 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1845 {
1846 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1847 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1848 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1849 }
1850 else
1851 {
1852 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1853 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1854 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1855 }
1856 }
1857 while( mpi_cmp_int( &TU, 0 ) != 0 );
1858
1859 while( mpi_cmp_int( &V1, 0 ) < 0 )
1860 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1861
1862 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1863 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1864
1865 MPI_CHK( mpi_copy( X, &V1 ) );
1866
1867cleanup:
1868
Paul Bakker6c591fa2011-05-05 11:49:20 +00001869 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1870 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1871 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001872
1873 return( ret );
1874}
1875
Paul Bakkerd9374b02012-11-02 11:02:58 +00001876#if defined(POLARSSL_GENPRIME)
1877
Paul Bakker5121ce52009-01-03 21:22:43 +00001878static const int small_prime[] =
1879{
1880 3, 5, 7, 11, 13, 17, 19, 23,
1881 29, 31, 37, 41, 43, 47, 53, 59,
1882 61, 67, 71, 73, 79, 83, 89, 97,
1883 101, 103, 107, 109, 113, 127, 131, 137,
1884 139, 149, 151, 157, 163, 167, 173, 179,
1885 181, 191, 193, 197, 199, 211, 223, 227,
1886 229, 233, 239, 241, 251, 257, 263, 269,
1887 271, 277, 281, 283, 293, 307, 311, 313,
1888 317, 331, 337, 347, 349, 353, 359, 367,
1889 373, 379, 383, 389, 397, 401, 409, 419,
1890 421, 431, 433, 439, 443, 449, 457, 461,
1891 463, 467, 479, 487, 491, 499, 503, 509,
1892 521, 523, 541, 547, 557, 563, 569, 571,
1893 577, 587, 593, 599, 601, 607, 613, 617,
1894 619, 631, 641, 643, 647, 653, 659, 661,
1895 673, 677, 683, 691, 701, 709, 719, 727,
1896 733, 739, 743, 751, 757, 761, 769, 773,
1897 787, 797, 809, 811, 821, 823, 827, 829,
1898 839, 853, 857, 859, 863, 877, 881, 883,
1899 887, 907, 911, 919, 929, 937, 941, 947,
1900 953, 967, 971, 977, 983, 991, 997, -103
1901};
1902
1903/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001904 * Small divisors test (X must be positive)
1905 *
1906 * Return values:
1907 * 0: no small factor (possible prime, more tests needed)
1908 * 1: certain prime
1909 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
1910 * other negative: error
Paul Bakker5121ce52009-01-03 21:22:43 +00001911 */
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001912static int mpi_check_small_factors( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +00001913{
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001914 int ret = 0;
1915 size_t i;
1916 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001917
Paul Bakker5121ce52009-01-03 21:22:43 +00001918 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001919 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001920
1921 for( i = 0; small_prime[i] > 0; i++ )
1922 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001923 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001924 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001925
1926 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1927
1928 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001929 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001930 }
1931
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001932cleanup:
1933 return( ret );
1934}
1935
1936/*
1937 * Miller-Rabin pseudo-primality test (HAC 4.24)
1938 */
1939static int mpi_miller_rabin( const mpi *X,
1940 int (*f_rng)(void *, unsigned char *, size_t),
1941 void *p_rng )
1942{
1943 int ret;
1944 size_t i, j, n, s;
1945 mpi W, R, T, A, RR;
1946
1947 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1948 mpi_init( &RR );
1949
Paul Bakker5121ce52009-01-03 21:22:43 +00001950 /*
1951 * W = |X| - 1
1952 * R = W >> lsb( W )
1953 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001954 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001955 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001956 MPI_CHK( mpi_copy( &R, &W ) );
1957 MPI_CHK( mpi_shift_r( &R, s ) );
1958
1959 i = mpi_msb( X );
1960 /*
1961 * HAC, table 4.4
1962 */
1963 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1964 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1965 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1966
1967 for( i = 0; i < n; i++ )
1968 {
1969 /*
1970 * pick a random A, 1 < A < |X| - 1
1971 */
Paul Bakker901c6562012-04-20 13:25:38 +00001972 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001973
Paul Bakkerb94081b2011-01-05 15:53:06 +00001974 if( mpi_cmp_mpi( &A, &W ) >= 0 )
1975 {
1976 j = mpi_msb( &A ) - mpi_msb( &W );
1977 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
1978 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001979 A.p[0] |= 3;
1980
1981 /*
1982 * A = A^R mod |X|
1983 */
1984 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
1985
1986 if( mpi_cmp_mpi( &A, &W ) == 0 ||
1987 mpi_cmp_int( &A, 1 ) == 0 )
1988 continue;
1989
1990 j = 1;
1991 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
1992 {
1993 /*
1994 * A = A * A mod |X|
1995 */
1996 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
1997 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
1998
1999 if( mpi_cmp_int( &A, 1 ) == 0 )
2000 break;
2001
2002 j++;
2003 }
2004
2005 /*
2006 * not prime if A != |X| - 1 or A == 1
2007 */
2008 if( mpi_cmp_mpi( &A, &W ) != 0 ||
2009 mpi_cmp_int( &A, 1 ) == 0 )
2010 {
Paul Bakker40e46942009-01-03 21:51:57 +00002011 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002012 break;
2013 }
2014 }
2015
2016cleanup:
Paul Bakker6c591fa2011-05-05 11:49:20 +00002017 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
2018 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002019
2020 return( ret );
2021}
2022
2023/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002024 * Pseudo-primality test: small factors, then Miller-Rabin
2025 */
Paul Bakker45f457d2013-11-25 14:26:52 +01002026int mpi_is_prime( mpi *X,
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002027 int (*f_rng)(void *, unsigned char *, size_t),
2028 void *p_rng )
2029{
2030 int ret;
2031 const mpi XX = { 1, X->n, X->p }; /* Abs(X) */
2032
2033 if( mpi_cmp_int( &XX, 0 ) == 0 ||
2034 mpi_cmp_int( &XX, 1 ) == 0 )
2035 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
2036
2037 if( mpi_cmp_int( &XX, 2 ) == 0 )
2038 return( 0 );
2039
2040 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2041 {
2042 if( ret == 1 )
2043 return( 0 );
2044
2045 return( ret );
2046 }
2047
2048 return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
2049}
2050
2051/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002052 * Prime number generation
2053 */
Paul Bakker23986e52011-04-24 08:57:21 +00002054int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002055 int (*f_rng)(void *, unsigned char *, size_t),
2056 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +00002057{
Paul Bakker23986e52011-04-24 08:57:21 +00002058 int ret;
2059 size_t k, n;
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002060 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002061 mpi Y;
2062
Paul Bakkerfe3256e2011-11-25 12:11:43 +00002063 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
Paul Bakker40e46942009-01-03 21:51:57 +00002064 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002065
Paul Bakker6c591fa2011-05-05 11:49:20 +00002066 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002067
2068 n = BITS_TO_LIMBS( nbits );
2069
Paul Bakker901c6562012-04-20 13:25:38 +00002070 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002071
2072 k = mpi_msb( X );
2073 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
2074 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
2075
2076 X->p[0] |= 3;
2077
2078 if( dh_flag == 0 )
2079 {
2080 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
2081 {
Paul Bakker40e46942009-01-03 21:51:57 +00002082 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002083 goto cleanup;
2084
2085 MPI_CHK( mpi_add_int( X, X, 2 ) );
2086 }
2087 }
2088 else
2089 {
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002090 /*
2091 * An necessary condition for Y and X = 2Y + 1 to be prime
2092 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2093 * Make sure it is satisfied, while keeping X = 3 mod 4
2094 */
2095 MPI_CHK( mpi_mod_int( &r, X, 3 ) );
2096 if( r == 0 )
2097 MPI_CHK( mpi_add_int( X, X, 8 ) );
2098 else if( r == 1 )
2099 MPI_CHK( mpi_add_int( X, X, 4 ) );
2100
2101 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2102 MPI_CHK( mpi_copy( &Y, X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002103 MPI_CHK( mpi_shift_r( &Y, 1 ) );
2104
2105 while( 1 )
2106 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002107 /*
2108 * First, check small factors for X and Y
2109 * before doing Miller-Rabin on any of them
2110 */
2111 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2112 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2113 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
2114 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002115 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002116 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002117 }
2118
Paul Bakker40e46942009-01-03 21:51:57 +00002119 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002120 goto cleanup;
2121
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002122 /*
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002123 * Next candidates. We want to preserve Y = (X-1) / 2 and
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002124 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2125 * so up Y by 6 and X by 12.
2126 */
2127 MPI_CHK( mpi_add_int( X, X, 12 ) );
2128 MPI_CHK( mpi_add_int( &Y, &Y, 6 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002129 }
2130 }
2131
2132cleanup:
2133
Paul Bakker6c591fa2011-05-05 11:49:20 +00002134 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002135
2136 return( ret );
2137}
2138
Manuel Pégourié-Gonnarddf0142b2013-08-22 18:29:07 +02002139#endif /* POLARSSL_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00002140
Paul Bakker40e46942009-01-03 21:51:57 +00002141#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002142
Paul Bakker23986e52011-04-24 08:57:21 +00002143#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002144
2145static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2146{
2147 { 693, 609, 21 },
2148 { 1764, 868, 28 },
2149 { 768454923, 542167814, 1 }
2150};
2151
Paul Bakker5121ce52009-01-03 21:22:43 +00002152/*
2153 * Checkup routine
2154 */
2155int mpi_self_test( int verbose )
2156{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002157 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00002158 mpi A, E, N, X, Y, U, V;
2159
Paul Bakker6c591fa2011-05-05 11:49:20 +00002160 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
2161 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002162
2163 MPI_CHK( mpi_read_string( &A, 16,
2164 "EFE021C2645FD1DC586E69184AF4A31E" \
2165 "D5F53E93B5F123FA41680867BA110131" \
2166 "944FE7952E2517337780CB0DB80E61AA" \
2167 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2168
2169 MPI_CHK( mpi_read_string( &E, 16,
2170 "B2E7EFD37075B9F03FF989C7C5051C20" \
2171 "34D2A323810251127E7BF8625A4F49A5" \
2172 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2173 "5B5C25763222FEFCCFC38B832366C29E" ) );
2174
2175 MPI_CHK( mpi_read_string( &N, 16,
2176 "0066A198186C18C10B2F5ED9B522752A" \
2177 "9830B69916E535C8F047518A889A43A5" \
2178 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2179
2180 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
2181
2182 MPI_CHK( mpi_read_string( &U, 16,
2183 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2184 "9E857EA95A03512E2BAE7391688D264A" \
2185 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2186 "8001B72E848A38CAE1C65F78E56ABDEF" \
2187 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2188 "ECF677152EF804370C1A305CAF3B5BF1" \
2189 "30879B56C61DE584A0F53A2447A51E" ) );
2190
2191 if( verbose != 0 )
2192 printf( " MPI test #1 (mul_mpi): " );
2193
2194 if( mpi_cmp_mpi( &X, &U ) != 0 )
2195 {
2196 if( verbose != 0 )
2197 printf( "failed\n" );
2198
2199 return( 1 );
2200 }
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
2224 return( 1 );
2225 }
2226
2227 if( verbose != 0 )
2228 printf( "passed\n" );
2229
2230 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2231
2232 MPI_CHK( mpi_read_string( &U, 16,
2233 "36E139AEA55215609D2816998ED020BB" \
2234 "BD96C37890F65171D948E9BC7CBAA4D9" \
2235 "325D24D6A3C12710F10A09FA08AB87" ) );
2236
2237 if( verbose != 0 )
2238 printf( " MPI test #3 (exp_mod): " );
2239
2240 if( mpi_cmp_mpi( &X, &U ) != 0 )
2241 {
2242 if( verbose != 0 )
2243 printf( "failed\n" );
2244
2245 return( 1 );
2246 }
2247
2248 if( verbose != 0 )
2249 printf( "passed\n" );
2250
2251 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2252
2253 MPI_CHK( mpi_read_string( &U, 16,
2254 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2255 "C3DBA76456363A10869622EAC2DD84EC" \
2256 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2257
2258 if( verbose != 0 )
2259 printf( " MPI test #4 (inv_mod): " );
2260
2261 if( mpi_cmp_mpi( &X, &U ) != 0 )
2262 {
2263 if( verbose != 0 )
2264 printf( "failed\n" );
2265
2266 return( 1 );
2267 }
2268
2269 if( verbose != 0 )
2270 printf( "passed\n" );
2271
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002272 if( verbose != 0 )
2273 printf( " MPI test #5 (simple gcd): " );
2274
2275 for ( i = 0; i < GCD_PAIR_COUNT; i++)
2276 {
2277 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002278 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002279
Paul Bakker23986e52011-04-24 08:57:21 +00002280 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002281
Paul Bakker23986e52011-04-24 08:57:21 +00002282 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2283 {
2284 if( verbose != 0 )
2285 printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002286
Paul Bakker23986e52011-04-24 08:57:21 +00002287 return( 1 );
2288 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002289 }
2290
2291 if( verbose != 0 )
2292 printf( "passed\n" );
2293
Paul Bakker5121ce52009-01-03 21:22:43 +00002294cleanup:
2295
2296 if( ret != 0 && verbose != 0 )
2297 printf( "Unexpected error, return code = %08X\n", ret );
2298
Paul Bakker6c591fa2011-05-05 11:49:20 +00002299 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2300 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002301
2302 if( verbose != 0 )
2303 printf( "\n" );
2304
2305 return( ret );
2306}
2307
2308#endif
2309
2310#endif