blob: f479bc9edcdd1c95e1ae2e6b6280693c681bc71d [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Multi-precision integer library
3 *
Manuel Pégourié-Gonnarda658a402015-01-23 09:45:19 +00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +00006 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakkerb96f1542010-07-18 20:36:00 +00007 *
Paul Bakker5121ce52009-01-03 21:22:43 +00008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22/*
23 * This MPI implementation is based on:
24 *
25 * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
26 * http://www.stillhq.com/extracted/gnupg-api/mpi/
27 * http://math.libtomcrypt.com/files/tommath.pdf
28 */
29
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker40e46942009-01-03 21:51:57 +000031#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#else
33#include POLARSSL_CONFIG_FILE
34#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Paul Bakker40e46942009-01-03 21:51:57 +000036#if defined(POLARSSL_BIGNUM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Paul Bakker40e46942009-01-03 21:51:57 +000038#include "polarssl/bignum.h"
39#include "polarssl/bn_mul.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Rich Evans00ab4702015-02-06 13:43:58 +000041#include <string.h>
42
Paul Bakker7dc4c442014-02-01 22:50:26 +010043#if defined(POLARSSL_PLATFORM_C)
44#include "polarssl/platform.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020045#else
Rich Evans00ab4702015-02-06 13:43:58 +000046#include <stdio.h>
47#include <stdlib.h>
Paul Bakker7dc4c442014-02-01 22:50:26 +010048#define polarssl_printf printf
Paul Bakker6e339b52013-07-03 13:37:05 +020049#define polarssl_malloc malloc
50#define polarssl_free free
51#endif
52
Paul Bakker34617722014-06-13 17:20:13 +020053/* Implementation that should never be optimized out by the compiler */
54static void polarssl_zeroize( void *v, size_t n ) {
55 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
56}
57
Paul Bakkerf9688572011-05-05 10:00:45 +000058#define ciL (sizeof(t_uint)) /* chars in limb */
Paul Bakker5121ce52009-01-03 21:22:43 +000059#define biL (ciL << 3) /* bits in limb */
60#define biH (ciL << 2) /* half limb size */
61
62/*
63 * Convert between bits/chars and number of limbs
64 */
65#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
66#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
67
68/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000069 * Initialize one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000070 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000071void mpi_init( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000072{
Paul Bakker6c591fa2011-05-05 11:49:20 +000073 if( X == NULL )
74 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000075
Paul Bakker6c591fa2011-05-05 11:49:20 +000076 X->s = 1;
77 X->n = 0;
78 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000079}
80
81/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000082 * Unallocate one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000083 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000084void mpi_free( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000085{
Paul Bakker6c591fa2011-05-05 11:49:20 +000086 if( X == NULL )
87 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000088
Paul Bakker6c591fa2011-05-05 11:49:20 +000089 if( X->p != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +000090 {
Paul Bakker34617722014-06-13 17:20:13 +020091 polarssl_zeroize( X->p, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +020092 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +000093 }
94
Paul Bakker6c591fa2011-05-05 11:49:20 +000095 X->s = 1;
96 X->n = 0;
97 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000098}
99
100/*
101 * Enlarge to the specified number of limbs
102 */
Paul Bakker23986e52011-04-24 08:57:21 +0000103int mpi_grow( mpi *X, size_t nblimbs )
Paul Bakker5121ce52009-01-03 21:22:43 +0000104{
Paul Bakkera755ca12011-04-24 09:11:17 +0000105 t_uint *p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000106
Paul Bakkerf9688572011-05-05 10:00:45 +0000107 if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
Paul Bakker69e095c2011-12-10 21:55:01 +0000108 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakkerf9688572011-05-05 10:00:45 +0000109
Paul Bakker5121ce52009-01-03 21:22:43 +0000110 if( X->n < nblimbs )
111 {
Mansour Moufidc531b4a2015-02-15 17:35:38 -0500112 if( ( p = polarssl_malloc( nblimbs * ciL ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000113 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000114
115 memset( p, 0, nblimbs * ciL );
116
117 if( X->p != NULL )
118 {
119 memcpy( p, X->p, X->n * ciL );
Paul Bakker34617722014-06-13 17:20:13 +0200120 polarssl_zeroize( X->p, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +0200121 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000122 }
123
124 X->n = nblimbs;
125 X->p = p;
126 }
127
128 return( 0 );
129}
130
131/*
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100132 * Resize down as much as possible,
133 * while keeping at least the specified number of limbs
134 */
135int mpi_shrink( mpi *X, size_t nblimbs )
136{
137 t_uint *p;
138 size_t i;
139
140 /* Actually resize up in this case */
141 if( X->n <= nblimbs )
142 return( mpi_grow( X, nblimbs ) );
143
144 for( i = X->n - 1; i > 0; i-- )
145 if( X->p[i] != 0 )
146 break;
147 i++;
148
149 if( i < nblimbs )
150 i = nblimbs;
151
Mansour Moufidc531b4a2015-02-15 17:35:38 -0500152 if( ( p = polarssl_malloc( i * ciL ) ) == NULL )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100153 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
154
155 memset( p, 0, i * ciL );
156
157 if( X->p != NULL )
158 {
159 memcpy( p, X->p, i * ciL );
Paul Bakker34617722014-06-13 17:20:13 +0200160 polarssl_zeroize( X->p, X->n * ciL );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100161 polarssl_free( X->p );
162 }
163
164 X->n = i;
165 X->p = p;
166
167 return( 0 );
168}
169
170/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000171 * Copy the contents of Y into X
172 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000173int mpi_copy( mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000174{
Paul Bakker23986e52011-04-24 08:57:21 +0000175 int ret;
176 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000177
178 if( X == Y )
179 return( 0 );
180
Manuel Pégourié-Gonnardf4999932013-08-12 17:02:59 +0200181 if( Y->p == NULL )
182 {
183 mpi_free( X );
184 return( 0 );
185 }
186
Paul Bakker5121ce52009-01-03 21:22:43 +0000187 for( i = Y->n - 1; i > 0; i-- )
188 if( Y->p[i] != 0 )
189 break;
190 i++;
191
192 X->s = Y->s;
193
194 MPI_CHK( mpi_grow( X, i ) );
195
196 memset( X->p, 0, X->n * ciL );
197 memcpy( X->p, Y->p, i * ciL );
198
199cleanup:
200
201 return( ret );
202}
203
204/*
205 * Swap the contents of X and Y
206 */
207void mpi_swap( mpi *X, mpi *Y )
208{
209 mpi T;
210
211 memcpy( &T, X, sizeof( mpi ) );
212 memcpy( X, Y, sizeof( mpi ) );
213 memcpy( Y, &T, sizeof( mpi ) );
214}
215
216/*
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100217 * Conditionally assign X = Y, without leaking information
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100218 * about whether the assignment was made or not.
219 * (Leaking information about the respective sizes of X and Y is ok however.)
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100220 */
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100221int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign )
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100222{
223 int ret = 0;
224 size_t i;
225
Pascal Junodb99183d2015-03-11 16:49:45 +0100226 /* make sure assign is 0 or 1 in a time-constant manner */
227 assign = (assign | (unsigned char)-assign) >> 7;
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100228
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100229 MPI_CHK( mpi_grow( X, Y->n ) );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100230
Paul Bakker66d5d072014-06-17 16:39:18 +0200231 X->s = X->s * ( 1 - assign ) + Y->s * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100232
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100233 for( i = 0; i < Y->n; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200234 X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100235
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100236 for( ; i < X->n; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200237 X->p[i] *= ( 1 - assign );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100238
239cleanup:
240 return( ret );
241}
242
243/*
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100244 * Conditionally swap X and Y, without leaking information
245 * about whether the swap was made or not.
246 * Here it is not ok to simply swap the pointers, which whould lead to
247 * different memory access patterns when X and Y are used afterwards.
248 */
249int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char swap )
250{
251 int ret, s;
252 size_t i;
253 t_uint tmp;
254
255 if( X == Y )
256 return( 0 );
257
Pascal Junodb99183d2015-03-11 16:49:45 +0100258 /* make sure swap is 0 or 1 in a time-constant manner */
259 swap = (swap | (unsigned char)-swap) >> 7;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100260
261 MPI_CHK( mpi_grow( X, Y->n ) );
262 MPI_CHK( mpi_grow( Y, X->n ) );
263
264 s = X->s;
Paul Bakker66d5d072014-06-17 16:39:18 +0200265 X->s = X->s * ( 1 - swap ) + Y->s * swap;
266 Y->s = Y->s * ( 1 - swap ) + s * swap;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100267
268
269 for( i = 0; i < X->n; i++ )
270 {
271 tmp = X->p[i];
Paul Bakker66d5d072014-06-17 16:39:18 +0200272 X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap;
273 Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100274 }
275
276cleanup:
277 return( ret );
278}
279
280/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000281 * Set value from integer
282 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000283int mpi_lset( mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000284{
285 int ret;
286
287 MPI_CHK( mpi_grow( X, 1 ) );
288 memset( X->p, 0, X->n * ciL );
289
290 X->p[0] = ( z < 0 ) ? -z : z;
291 X->s = ( z < 0 ) ? -1 : 1;
292
293cleanup:
294
295 return( ret );
296}
297
298/*
Paul Bakker2f5947e2011-05-18 15:47:11 +0000299 * Get a specific bit
300 */
Paul Bakker6b906e52012-05-08 12:01:43 +0000301int mpi_get_bit( const mpi *X, size_t pos )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000302{
303 if( X->n * biL <= pos )
304 return( 0 );
305
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200306 return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000307}
308
309/*
310 * Set a bit to a specific value of 0 or 1
311 */
312int mpi_set_bit( mpi *X, size_t pos, unsigned char val )
313{
314 int ret = 0;
315 size_t off = pos / biL;
316 size_t idx = pos % biL;
317
318 if( val != 0 && val != 1 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200319 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker9af723c2014-05-01 13:03:14 +0200320
Paul Bakker2f5947e2011-05-18 15:47:11 +0000321 if( X->n * biL <= pos )
322 {
323 if( val == 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200324 return( 0 );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000325
326 MPI_CHK( mpi_grow( X, off + 1 ) );
327 }
328
Manuel Pégourié-Gonnard9a4a5ac2013-12-04 18:05:29 +0100329 X->p[off] &= ~( (t_uint) 0x01 << idx );
330 X->p[off] |= (t_uint) val << idx;
Paul Bakker2f5947e2011-05-18 15:47:11 +0000331
332cleanup:
Paul Bakker9af723c2014-05-01 13:03:14 +0200333
Paul Bakker2f5947e2011-05-18 15:47:11 +0000334 return( ret );
335}
336
337/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000338 * Return the number of least significant bits
339 */
Paul Bakker23986e52011-04-24 08:57:21 +0000340size_t mpi_lsb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000341{
Paul Bakker23986e52011-04-24 08:57:21 +0000342 size_t i, j, count = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000343
344 for( i = 0; i < X->n; i++ )
Paul Bakkerf9688572011-05-05 10:00:45 +0000345 for( j = 0; j < biL; j++, count++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000346 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
347 return( count );
348
349 return( 0 );
350}
351
352/*
353 * Return the number of most significant bits
354 */
Paul Bakker23986e52011-04-24 08:57:21 +0000355size_t mpi_msb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000356{
Paul Bakker23986e52011-04-24 08:57:21 +0000357 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000358
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200359 if( X->n == 0 )
360 return( 0 );
361
Paul Bakker5121ce52009-01-03 21:22:43 +0000362 for( i = X->n - 1; i > 0; i-- )
363 if( X->p[i] != 0 )
364 break;
365
Paul Bakker23986e52011-04-24 08:57:21 +0000366 for( j = biL; j > 0; j-- )
367 if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000368 break;
369
Paul Bakker23986e52011-04-24 08:57:21 +0000370 return( ( i * biL ) + j );
Paul Bakker5121ce52009-01-03 21:22:43 +0000371}
372
373/*
374 * Return the total size in bytes
375 */
Paul Bakker23986e52011-04-24 08:57:21 +0000376size_t mpi_size( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000377{
378 return( ( mpi_msb( X ) + 7 ) >> 3 );
379}
380
381/*
382 * Convert an ASCII character to digit value
383 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000384static int mpi_get_digit( t_uint *d, int radix, char c )
Paul Bakker5121ce52009-01-03 21:22:43 +0000385{
386 *d = 255;
387
388 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
389 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
390 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
391
Paul Bakkera755ca12011-04-24 09:11:17 +0000392 if( *d >= (t_uint) radix )
Paul Bakker40e46942009-01-03 21:51:57 +0000393 return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000394
395 return( 0 );
396}
397
398/*
399 * Import from an ASCII string
400 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000401int mpi_read_string( mpi *X, int radix, const char *s )
Paul Bakker5121ce52009-01-03 21:22:43 +0000402{
Paul Bakker23986e52011-04-24 08:57:21 +0000403 int ret;
404 size_t i, j, slen, n;
Paul Bakkera755ca12011-04-24 09:11:17 +0000405 t_uint d;
Paul Bakker5121ce52009-01-03 21:22:43 +0000406 mpi T;
407
408 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000409 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
Paul Bakker6c591fa2011-05-05 11:49:20 +0000411 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000412
Paul Bakkerff60ee62010-03-16 21:09:09 +0000413 slen = strlen( s );
414
Paul Bakker5121ce52009-01-03 21:22:43 +0000415 if( radix == 16 )
416 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000417 n = BITS_TO_LIMBS( slen << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000418
419 MPI_CHK( mpi_grow( X, n ) );
420 MPI_CHK( mpi_lset( X, 0 ) );
421
Paul Bakker23986e52011-04-24 08:57:21 +0000422 for( i = slen, j = 0; i > 0; i--, j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000423 {
Paul Bakker23986e52011-04-24 08:57:21 +0000424 if( i == 1 && s[i - 1] == '-' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000425 {
426 X->s = -1;
427 break;
428 }
429
Paul Bakker23986e52011-04-24 08:57:21 +0000430 MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
Paul Bakker66d5d072014-06-17 16:39:18 +0200431 X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000432 }
433 }
434 else
435 {
436 MPI_CHK( mpi_lset( X, 0 ) );
437
Paul Bakkerff60ee62010-03-16 21:09:09 +0000438 for( i = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000439 {
440 if( i == 0 && s[i] == '-' )
441 {
442 X->s = -1;
443 continue;
444 }
445
446 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
447 MPI_CHK( mpi_mul_int( &T, X, radix ) );
Paul Bakker05feca62009-06-20 08:22:43 +0000448
449 if( X->s == 1 )
450 {
451 MPI_CHK( mpi_add_int( X, &T, d ) );
452 }
453 else
454 {
455 MPI_CHK( mpi_sub_int( X, &T, d ) );
456 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000457 }
458 }
459
460cleanup:
461
Paul Bakker6c591fa2011-05-05 11:49:20 +0000462 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000463
464 return( ret );
465}
466
467/*
468 * Helper to write the digits high-order first
469 */
470static int mpi_write_hlp( mpi *X, int radix, char **p )
471{
472 int ret;
Paul Bakkera755ca12011-04-24 09:11:17 +0000473 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +0000474
475 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000476 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000477
478 MPI_CHK( mpi_mod_int( &r, X, radix ) );
479 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
480
481 if( mpi_cmp_int( X, 0 ) != 0 )
482 MPI_CHK( mpi_write_hlp( X, radix, p ) );
483
484 if( r < 10 )
485 *(*p)++ = (char)( r + 0x30 );
486 else
487 *(*p)++ = (char)( r + 0x37 );
488
489cleanup:
490
491 return( ret );
492}
493
494/*
495 * Export into an ASCII string
496 */
Paul Bakker23986e52011-04-24 08:57:21 +0000497int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000498{
Paul Bakker23986e52011-04-24 08:57:21 +0000499 int ret = 0;
500 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000501 char *p;
502 mpi T;
503
504 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000505 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000506
507 n = mpi_msb( X );
508 if( radix >= 4 ) n >>= 1;
509 if( radix >= 16 ) n >>= 1;
510 n += 3;
511
512 if( *slen < n )
513 {
514 *slen = n;
Paul Bakker40e46942009-01-03 21:51:57 +0000515 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000516 }
517
518 p = s;
Paul Bakker6c591fa2011-05-05 11:49:20 +0000519 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000520
521 if( X->s == -1 )
522 *p++ = '-';
523
524 if( radix == 16 )
525 {
Paul Bakker23986e52011-04-24 08:57:21 +0000526 int c;
527 size_t i, j, k;
Paul Bakker5121ce52009-01-03 21:22:43 +0000528
Paul Bakker23986e52011-04-24 08:57:21 +0000529 for( i = X->n, k = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000530 {
Paul Bakker23986e52011-04-24 08:57:21 +0000531 for( j = ciL; j > 0; j-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000532 {
Paul Bakker23986e52011-04-24 08:57:21 +0000533 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000534
Paul Bakker6c343d72014-07-10 14:36:19 +0200535 if( c == 0 && k == 0 && ( i + j ) != 2 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000536 continue;
537
Paul Bakker98fe5ea2012-10-24 11:17:48 +0000538 *(p++) = "0123456789ABCDEF" [c / 16];
Paul Bakkerd2c167e2012-10-30 07:49:19 +0000539 *(p++) = "0123456789ABCDEF" [c % 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000540 k = 1;
541 }
542 }
543 }
544 else
545 {
546 MPI_CHK( mpi_copy( &T, X ) );
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000547
548 if( T.s == -1 )
549 T.s = 1;
550
Paul Bakker5121ce52009-01-03 21:22:43 +0000551 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
552 }
553
554 *p++ = '\0';
555 *slen = p - s;
556
557cleanup:
558
Paul Bakker6c591fa2011-05-05 11:49:20 +0000559 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000560
561 return( ret );
562}
563
Paul Bakker335db3f2011-04-25 15:28:35 +0000564#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000565/*
566 * Read X from an opened file
567 */
568int mpi_read_file( mpi *X, int radix, FILE *fin )
569{
Paul Bakkera755ca12011-04-24 09:11:17 +0000570 t_uint d;
Paul Bakker23986e52011-04-24 08:57:21 +0000571 size_t slen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000572 char *p;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000573 /*
Paul Bakkercb37aa52011-11-30 16:00:20 +0000574 * Buffer should have space for (short) label and decimal formatted MPI,
575 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000576 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000577 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000578
579 memset( s, 0, sizeof( s ) );
580 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000581 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000582
583 slen = strlen( s );
Paul Bakkercb37aa52011-11-30 16:00:20 +0000584 if( slen == sizeof( s ) - 2 )
585 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
586
Paul Bakker5121ce52009-01-03 21:22:43 +0000587 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
588 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
589
590 p = s + slen;
591 while( --p >= s )
592 if( mpi_get_digit( &d, radix, *p ) != 0 )
593 break;
594
595 return( mpi_read_string( X, radix, p + 1 ) );
596}
597
598/*
599 * Write X into an opened file (or stdout if fout == NULL)
600 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000601int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
Paul Bakker5121ce52009-01-03 21:22:43 +0000602{
Paul Bakker23986e52011-04-24 08:57:21 +0000603 int ret;
604 size_t n, slen, plen;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000605 /*
Paul Bakker5531c6d2012-09-26 19:20:46 +0000606 * Buffer should have space for (short) label and decimal formatted MPI,
607 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000608 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000609 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000610
611 n = sizeof( s );
612 memset( s, 0, n );
613 n -= 2;
614
Paul Bakker23986e52011-04-24 08:57:21 +0000615 MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
617 if( p == NULL ) p = "";
618
619 plen = strlen( p );
620 slen = strlen( s );
621 s[slen++] = '\r';
622 s[slen++] = '\n';
623
624 if( fout != NULL )
625 {
626 if( fwrite( p, 1, plen, fout ) != plen ||
627 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000628 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000629 }
630 else
Paul Bakker7dc4c442014-02-01 22:50:26 +0100631 polarssl_printf( "%s%s", p, s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000632
633cleanup:
634
635 return( ret );
636}
Paul Bakker335db3f2011-04-25 15:28:35 +0000637#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000638
639/*
640 * Import X from unsigned binary data, big endian
641 */
Paul Bakker23986e52011-04-24 08:57:21 +0000642int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000643{
Paul Bakker23986e52011-04-24 08:57:21 +0000644 int ret;
645 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000646
647 for( n = 0; n < buflen; n++ )
648 if( buf[n] != 0 )
649 break;
650
651 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
652 MPI_CHK( mpi_lset( X, 0 ) );
653
Paul Bakker23986e52011-04-24 08:57:21 +0000654 for( i = buflen, j = 0; i > n; i--, j++ )
Paul Bakkera755ca12011-04-24 09:11:17 +0000655 X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000656
657cleanup:
658
659 return( ret );
660}
661
662/*
663 * Export X into unsigned binary data, big endian
664 */
Paul Bakker23986e52011-04-24 08:57:21 +0000665int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000666{
Paul Bakker23986e52011-04-24 08:57:21 +0000667 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000668
669 n = mpi_size( X );
670
671 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000672 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000673
674 memset( buf, 0, buflen );
675
676 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
677 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
678
679 return( 0 );
680}
681
682/*
683 * Left-shift: X <<= count
684 */
Paul Bakker23986e52011-04-24 08:57:21 +0000685int mpi_shift_l( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000686{
Paul Bakker23986e52011-04-24 08:57:21 +0000687 int ret;
688 size_t i, v0, t1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000689 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000690
691 v0 = count / (biL );
692 t1 = count & (biL - 1);
693
694 i = mpi_msb( X ) + count;
695
Paul Bakkerf9688572011-05-05 10:00:45 +0000696 if( X->n * biL < i )
Paul Bakker5121ce52009-01-03 21:22:43 +0000697 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
698
699 ret = 0;
700
701 /*
702 * shift by count / limb_size
703 */
704 if( v0 > 0 )
705 {
Paul Bakker23986e52011-04-24 08:57:21 +0000706 for( i = X->n; i > v0; i-- )
707 X->p[i - 1] = X->p[i - v0 - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000708
Paul Bakker23986e52011-04-24 08:57:21 +0000709 for( ; i > 0; i-- )
710 X->p[i - 1] = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000711 }
712
713 /*
714 * shift by count % limb_size
715 */
716 if( t1 > 0 )
717 {
718 for( i = v0; i < X->n; i++ )
719 {
720 r1 = X->p[i] >> (biL - t1);
721 X->p[i] <<= t1;
722 X->p[i] |= r0;
723 r0 = r1;
724 }
725 }
726
727cleanup:
728
729 return( ret );
730}
731
732/*
733 * Right-shift: X >>= count
734 */
Paul Bakker23986e52011-04-24 08:57:21 +0000735int mpi_shift_r( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000736{
Paul Bakker23986e52011-04-24 08:57:21 +0000737 size_t i, v0, v1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000738 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000739
740 v0 = count / biL;
741 v1 = count & (biL - 1);
742
Manuel Pégourié-Gonnarde44ec102012-11-17 12:42:51 +0100743 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
744 return mpi_lset( X, 0 );
745
Paul Bakker5121ce52009-01-03 21:22:43 +0000746 /*
747 * shift by count / limb_size
748 */
749 if( v0 > 0 )
750 {
751 for( i = 0; i < X->n - v0; i++ )
752 X->p[i] = X->p[i + v0];
753
754 for( ; i < X->n; i++ )
755 X->p[i] = 0;
756 }
757
758 /*
759 * shift by count % limb_size
760 */
761 if( v1 > 0 )
762 {
Paul Bakker23986e52011-04-24 08:57:21 +0000763 for( i = X->n; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000764 {
Paul Bakker23986e52011-04-24 08:57:21 +0000765 r1 = X->p[i - 1] << (biL - v1);
766 X->p[i - 1] >>= v1;
767 X->p[i - 1] |= r0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000768 r0 = r1;
769 }
770 }
771
772 return( 0 );
773}
774
775/*
776 * Compare unsigned values
777 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000778int mpi_cmp_abs( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000779{
Paul Bakker23986e52011-04-24 08:57:21 +0000780 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000781
Paul Bakker23986e52011-04-24 08:57:21 +0000782 for( i = X->n; i > 0; i-- )
783 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000784 break;
785
Paul Bakker23986e52011-04-24 08:57:21 +0000786 for( j = Y->n; j > 0; j-- )
787 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000788 break;
789
Paul Bakker23986e52011-04-24 08:57:21 +0000790 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000791 return( 0 );
792
793 if( i > j ) return( 1 );
794 if( j > i ) return( -1 );
795
Paul Bakker23986e52011-04-24 08:57:21 +0000796 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000797 {
Paul Bakker23986e52011-04-24 08:57:21 +0000798 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
799 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000800 }
801
802 return( 0 );
803}
804
805/*
806 * Compare signed values
807 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000808int mpi_cmp_mpi( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000809{
Paul Bakker23986e52011-04-24 08:57:21 +0000810 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000811
Paul Bakker23986e52011-04-24 08:57:21 +0000812 for( i = X->n; i > 0; i-- )
813 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000814 break;
815
Paul Bakker23986e52011-04-24 08:57:21 +0000816 for( j = Y->n; j > 0; j-- )
817 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000818 break;
819
Paul Bakker23986e52011-04-24 08:57:21 +0000820 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000821 return( 0 );
822
823 if( i > j ) return( X->s );
Paul Bakker0c8f73b2012-03-22 14:08:57 +0000824 if( j > i ) return( -Y->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000825
826 if( X->s > 0 && Y->s < 0 ) return( 1 );
827 if( Y->s > 0 && X->s < 0 ) return( -1 );
828
Paul Bakker23986e52011-04-24 08:57:21 +0000829 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000830 {
Paul Bakker23986e52011-04-24 08:57:21 +0000831 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
832 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000833 }
834
835 return( 0 );
836}
837
838/*
839 * Compare signed values
840 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000841int mpi_cmp_int( const mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000842{
843 mpi Y;
Paul Bakkera755ca12011-04-24 09:11:17 +0000844 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000845
846 *p = ( z < 0 ) ? -z : z;
847 Y.s = ( z < 0 ) ? -1 : 1;
848 Y.n = 1;
849 Y.p = p;
850
851 return( mpi_cmp_mpi( X, &Y ) );
852}
853
854/*
855 * Unsigned addition: X = |A| + |B| (HAC 14.7)
856 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000857int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000858{
Paul Bakker23986e52011-04-24 08:57:21 +0000859 int ret;
860 size_t i, j;
Paul Bakkera755ca12011-04-24 09:11:17 +0000861 t_uint *o, *p, c;
Paul Bakker5121ce52009-01-03 21:22:43 +0000862
863 if( X == B )
864 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000865 const mpi *T = A; A = X; B = T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000866 }
867
868 if( X != A )
869 MPI_CHK( mpi_copy( X, A ) );
Paul Bakker9af723c2014-05-01 13:03:14 +0200870
Paul Bakkerf7ca7b92009-06-20 10:31:06 +0000871 /*
872 * X should always be positive as a result of unsigned additions.
873 */
874 X->s = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000875
Paul Bakker23986e52011-04-24 08:57:21 +0000876 for( j = B->n; j > 0; j-- )
877 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000878 break;
879
Paul Bakker23986e52011-04-24 08:57:21 +0000880 MPI_CHK( mpi_grow( X, j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000881
882 o = B->p; p = X->p; c = 0;
883
Paul Bakker23986e52011-04-24 08:57:21 +0000884 for( i = 0; i < j; i++, o++, p++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000885 {
886 *p += c; c = ( *p < c );
887 *p += *o; c += ( *p < *o );
888 }
889
890 while( c != 0 )
891 {
892 if( i >= X->n )
893 {
894 MPI_CHK( mpi_grow( X, i + 1 ) );
895 p = X->p + i;
896 }
897
Paul Bakker2d319fd2012-09-16 21:34:26 +0000898 *p += c; c = ( *p < c ); i++; p++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000899 }
900
901cleanup:
902
903 return( ret );
904}
905
906/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100907 * Helper for mpi subtraction
Paul Bakker5121ce52009-01-03 21:22:43 +0000908 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000909static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
Paul Bakker5121ce52009-01-03 21:22:43 +0000910{
Paul Bakker23986e52011-04-24 08:57:21 +0000911 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +0000912 t_uint c, z;
Paul Bakker5121ce52009-01-03 21:22:43 +0000913
914 for( i = c = 0; i < n; i++, s++, d++ )
915 {
916 z = ( *d < c ); *d -= c;
917 c = ( *d < *s ) + z; *d -= *s;
918 }
919
920 while( c != 0 )
921 {
922 z = ( *d < c ); *d -= c;
923 c = z; i++; d++;
924 }
925}
926
927/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100928 * Unsigned subtraction: X = |A| - |B| (HAC 14.9)
Paul Bakker5121ce52009-01-03 21:22:43 +0000929 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000930int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000931{
932 mpi TB;
Paul Bakker23986e52011-04-24 08:57:21 +0000933 int ret;
934 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000935
936 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000937 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000938
Paul Bakker6c591fa2011-05-05 11:49:20 +0000939 mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000940
941 if( X == B )
942 {
943 MPI_CHK( mpi_copy( &TB, B ) );
944 B = &TB;
945 }
946
947 if( X != A )
948 MPI_CHK( mpi_copy( X, A ) );
949
Paul Bakker1ef7a532009-06-20 10:50:55 +0000950 /*
Paul Bakker60b1d102013-10-29 10:02:51 +0100951 * X should always be positive as a result of unsigned subtractions.
Paul Bakker1ef7a532009-06-20 10:50:55 +0000952 */
953 X->s = 1;
954
Paul Bakker5121ce52009-01-03 21:22:43 +0000955 ret = 0;
956
Paul Bakker23986e52011-04-24 08:57:21 +0000957 for( n = B->n; n > 0; n-- )
958 if( B->p[n - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000959 break;
960
Paul Bakker23986e52011-04-24 08:57:21 +0000961 mpi_sub_hlp( n, B->p, X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000962
963cleanup:
964
Paul Bakker6c591fa2011-05-05 11:49:20 +0000965 mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000966
967 return( ret );
968}
969
970/*
971 * Signed addition: X = A + B
972 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000973int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000974{
975 int ret, s = A->s;
976
977 if( A->s * B->s < 0 )
978 {
979 if( mpi_cmp_abs( A, B ) >= 0 )
980 {
981 MPI_CHK( mpi_sub_abs( X, A, B ) );
982 X->s = s;
983 }
984 else
985 {
986 MPI_CHK( mpi_sub_abs( X, B, A ) );
987 X->s = -s;
988 }
989 }
990 else
991 {
992 MPI_CHK( mpi_add_abs( X, A, B ) );
993 X->s = s;
994 }
995
996cleanup:
997
998 return( ret );
999}
1000
1001/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001002 * Signed subtraction: X = A - B
Paul Bakker5121ce52009-01-03 21:22:43 +00001003 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001004int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001005{
1006 int ret, s = A->s;
1007
1008 if( A->s * B->s > 0 )
1009 {
1010 if( mpi_cmp_abs( A, B ) >= 0 )
1011 {
1012 MPI_CHK( mpi_sub_abs( X, A, B ) );
1013 X->s = s;
1014 }
1015 else
1016 {
1017 MPI_CHK( mpi_sub_abs( X, B, A ) );
1018 X->s = -s;
1019 }
1020 }
1021 else
1022 {
1023 MPI_CHK( mpi_add_abs( X, A, B ) );
1024 X->s = s;
1025 }
1026
1027cleanup:
1028
1029 return( ret );
1030}
1031
1032/*
1033 * Signed addition: X = A + b
1034 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001035int mpi_add_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001036{
1037 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001038 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001039
1040 p[0] = ( b < 0 ) ? -b : b;
1041 _B.s = ( b < 0 ) ? -1 : 1;
1042 _B.n = 1;
1043 _B.p = p;
1044
1045 return( mpi_add_mpi( X, A, &_B ) );
1046}
1047
1048/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001049 * Signed subtraction: X = A - b
Paul Bakker5121ce52009-01-03 21:22:43 +00001050 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001051int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001052{
1053 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001054 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001055
1056 p[0] = ( b < 0 ) ? -b : b;
1057 _B.s = ( b < 0 ) ? -1 : 1;
1058 _B.n = 1;
1059 _B.p = p;
1060
1061 return( mpi_sub_mpi( X, A, &_B ) );
1062}
1063
1064/*
1065 * Helper for mpi multiplication
Paul Bakkerfc4f46f2013-06-24 19:23:56 +02001066 */
1067static
1068#if defined(__APPLE__) && defined(__arm__)
1069/*
1070 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1071 * appears to need this to prevent bad ARM code generation at -O3.
1072 */
1073__attribute__ ((noinline))
1074#endif
1075void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001076{
Paul Bakkera755ca12011-04-24 09:11:17 +00001077 t_uint c = 0, t = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001078
1079#if defined(MULADDC_HUIT)
1080 for( ; i >= 8; i -= 8 )
1081 {
1082 MULADDC_INIT
1083 MULADDC_HUIT
1084 MULADDC_STOP
1085 }
1086
1087 for( ; i > 0; i-- )
1088 {
1089 MULADDC_INIT
1090 MULADDC_CORE
1091 MULADDC_STOP
1092 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001093#else /* MULADDC_HUIT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001094 for( ; i >= 16; i -= 16 )
1095 {
1096 MULADDC_INIT
1097 MULADDC_CORE MULADDC_CORE
1098 MULADDC_CORE MULADDC_CORE
1099 MULADDC_CORE MULADDC_CORE
1100 MULADDC_CORE MULADDC_CORE
1101
1102 MULADDC_CORE MULADDC_CORE
1103 MULADDC_CORE MULADDC_CORE
1104 MULADDC_CORE MULADDC_CORE
1105 MULADDC_CORE MULADDC_CORE
1106 MULADDC_STOP
1107 }
1108
1109 for( ; i >= 8; i -= 8 )
1110 {
1111 MULADDC_INIT
1112 MULADDC_CORE MULADDC_CORE
1113 MULADDC_CORE MULADDC_CORE
1114
1115 MULADDC_CORE MULADDC_CORE
1116 MULADDC_CORE MULADDC_CORE
1117 MULADDC_STOP
1118 }
1119
1120 for( ; i > 0; i-- )
1121 {
1122 MULADDC_INIT
1123 MULADDC_CORE
1124 MULADDC_STOP
1125 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001126#endif /* MULADDC_HUIT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001127
1128 t++;
1129
1130 do {
1131 *d += c; c = ( *d < c ); d++;
1132 }
1133 while( c != 0 );
1134}
1135
1136/*
1137 * Baseline multiplication: X = A * B (HAC 14.12)
1138 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001139int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001140{
Paul Bakker23986e52011-04-24 08:57:21 +00001141 int ret;
1142 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00001143 mpi TA, TB;
1144
Paul Bakker6c591fa2011-05-05 11:49:20 +00001145 mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001146
1147 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
1148 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
1149
Paul Bakker23986e52011-04-24 08:57:21 +00001150 for( i = A->n; i > 0; i-- )
1151 if( A->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001152 break;
1153
Paul Bakker23986e52011-04-24 08:57:21 +00001154 for( j = B->n; j > 0; j-- )
1155 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001156 break;
1157
Paul Bakker23986e52011-04-24 08:57:21 +00001158 MPI_CHK( mpi_grow( X, i + j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001159 MPI_CHK( mpi_lset( X, 0 ) );
1160
Paul Bakker23986e52011-04-24 08:57:21 +00001161 for( i++; j > 0; j-- )
1162 mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001163
1164 X->s = A->s * B->s;
1165
1166cleanup:
1167
Paul Bakker6c591fa2011-05-05 11:49:20 +00001168 mpi_free( &TB ); mpi_free( &TA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001169
1170 return( ret );
1171}
1172
1173/*
1174 * Baseline multiplication: X = A * b
1175 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001176int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001177{
1178 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001179 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001180
1181 _B.s = 1;
1182 _B.n = 1;
1183 _B.p = p;
1184 p[0] = b;
1185
1186 return( mpi_mul_mpi( X, A, &_B ) );
1187}
1188
1189/*
1190 * Division by mpi: A = Q * B + R (HAC 14.20)
1191 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001192int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001193{
Paul Bakker23986e52011-04-24 08:57:21 +00001194 int ret;
1195 size_t i, n, t, k;
Paul Bakker5121ce52009-01-03 21:22:43 +00001196 mpi X, Y, Z, T1, T2;
1197
1198 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001199 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001200
Paul Bakker6c591fa2011-05-05 11:49:20 +00001201 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
1202 mpi_init( &T1 ); mpi_init( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001203
1204 if( mpi_cmp_abs( A, B ) < 0 )
1205 {
1206 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1207 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1208 return( 0 );
1209 }
1210
1211 MPI_CHK( mpi_copy( &X, A ) );
1212 MPI_CHK( mpi_copy( &Y, B ) );
1213 X.s = Y.s = 1;
1214
1215 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1216 MPI_CHK( mpi_lset( &Z, 0 ) );
1217 MPI_CHK( mpi_grow( &T1, 2 ) );
1218 MPI_CHK( mpi_grow( &T2, 3 ) );
1219
1220 k = mpi_msb( &Y ) % biL;
Paul Bakkerf9688572011-05-05 10:00:45 +00001221 if( k < biL - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001222 {
1223 k = biL - 1 - k;
1224 MPI_CHK( mpi_shift_l( &X, k ) );
1225 MPI_CHK( mpi_shift_l( &Y, k ) );
1226 }
1227 else k = 0;
1228
1229 n = X.n - 1;
1230 t = Y.n - 1;
Paul Bakker66d5d072014-06-17 16:39:18 +02001231 MPI_CHK( mpi_shift_l( &Y, biL * ( n - t ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001232
1233 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1234 {
1235 Z.p[n - t]++;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001236 MPI_CHK( mpi_sub_mpi( &X, &X, &Y ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001237 }
Paul Bakker66d5d072014-06-17 16:39:18 +02001238 MPI_CHK( mpi_shift_r( &Y, biL * ( n - t ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001239
1240 for( i = n; i > t ; i-- )
1241 {
1242 if( X.p[i] >= Y.p[t] )
1243 Z.p[i - t - 1] = ~0;
1244 else
1245 {
Manuel Pégourié-Gonnardd72704b2015-02-12 09:38:54 +00001246#if defined(POLARSSL_HAVE_UDBL)
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001247 t_udbl r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001248
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001249 r = (t_udbl) X.p[i] << biL;
1250 r |= (t_udbl) X.p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001251 r /= Y.p[t];
Paul Bakker66d5d072014-06-17 16:39:18 +02001252 if( r > ( (t_udbl) 1 << biL ) - 1 )
1253 r = ( (t_udbl) 1 << biL ) - 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001254
Paul Bakkera755ca12011-04-24 09:11:17 +00001255 Z.p[i - t - 1] = (t_uint) r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001256#else
1257 /*
1258 * __udiv_qrnnd_c, from gmp/longlong.h
1259 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001260 t_uint q0, q1, r0, r1;
1261 t_uint d0, d1, d, m;
Paul Bakker5121ce52009-01-03 21:22:43 +00001262
1263 d = Y.p[t];
1264 d0 = ( d << biH ) >> biH;
1265 d1 = ( d >> biH );
1266
1267 q1 = X.p[i] / d1;
1268 r1 = X.p[i] - d1 * q1;
1269 r1 <<= biH;
1270 r1 |= ( X.p[i - 1] >> biH );
1271
1272 m = q1 * d0;
1273 if( r1 < m )
1274 {
1275 q1--, r1 += d;
1276 while( r1 >= d && r1 < m )
1277 q1--, r1 += d;
1278 }
1279 r1 -= m;
1280
1281 q0 = r1 / d1;
1282 r0 = r1 - d1 * q0;
1283 r0 <<= biH;
1284 r0 |= ( X.p[i - 1] << biH ) >> biH;
1285
1286 m = q0 * d0;
1287 if( r0 < m )
1288 {
1289 q0--, r0 += d;
1290 while( r0 >= d && r0 < m )
1291 q0--, r0 += d;
1292 }
1293 r0 -= m;
1294
1295 Z.p[i - t - 1] = ( q1 << biH ) | q0;
Paul Bakkerdb20c102014-06-17 14:34:44 +02001296#endif /* POLARSSL_HAVE_UDBL && !64-bit Apple with Clang 5.0 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001297 }
1298
1299 Z.p[i - t - 1]++;
1300 do
1301 {
1302 Z.p[i - t - 1]--;
1303
1304 MPI_CHK( mpi_lset( &T1, 0 ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001305 T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001306 T1.p[1] = Y.p[t];
1307 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1308
1309 MPI_CHK( mpi_lset( &T2, 0 ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001310 T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
1311 T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001312 T2.p[2] = X.p[i];
1313 }
1314 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1315
1316 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001317 MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001318 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1319
1320 if( mpi_cmp_int( &X, 0 ) < 0 )
1321 {
1322 MPI_CHK( mpi_copy( &T1, &Y ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001323 MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001324 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1325 Z.p[i - t - 1]--;
1326 }
1327 }
1328
1329 if( Q != NULL )
1330 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001331 MPI_CHK( mpi_copy( Q, &Z ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001332 Q->s = A->s * B->s;
1333 }
1334
1335 if( R != NULL )
1336 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001337 MPI_CHK( mpi_shift_r( &X, k ) );
Paul Bakkerf02c5642012-11-13 10:25:21 +00001338 X.s = A->s;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001339 MPI_CHK( mpi_copy( R, &X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001340
Paul Bakker5121ce52009-01-03 21:22:43 +00001341 if( mpi_cmp_int( R, 0 ) == 0 )
1342 R->s = 1;
1343 }
1344
1345cleanup:
1346
Paul Bakker6c591fa2011-05-05 11:49:20 +00001347 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
1348 mpi_free( &T1 ); mpi_free( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001349
1350 return( ret );
1351}
1352
1353/*
1354 * Division by int: A = Q * b + R
Paul Bakker5121ce52009-01-03 21:22:43 +00001355 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001356int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001357{
1358 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001359 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001360
1361 p[0] = ( b < 0 ) ? -b : b;
1362 _B.s = ( b < 0 ) ? -1 : 1;
1363 _B.n = 1;
1364 _B.p = p;
1365
1366 return( mpi_div_mpi( Q, R, A, &_B ) );
1367}
1368
1369/*
1370 * Modulo: R = A mod B
1371 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001372int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001373{
1374 int ret;
1375
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001376 if( mpi_cmp_int( B, 0 ) < 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001377 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001378
Paul Bakker5121ce52009-01-03 21:22:43 +00001379 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1380
1381 while( mpi_cmp_int( R, 0 ) < 0 )
1382 MPI_CHK( mpi_add_mpi( R, R, B ) );
1383
1384 while( mpi_cmp_mpi( R, B ) >= 0 )
1385 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1386
1387cleanup:
1388
1389 return( ret );
1390}
1391
1392/*
1393 * Modulo: r = A mod b
1394 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001395int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001396{
Paul Bakker23986e52011-04-24 08:57:21 +00001397 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +00001398 t_uint x, y, z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001399
1400 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001401 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001402
1403 if( b < 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001404 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001405
1406 /*
1407 * handle trivial cases
1408 */
1409 if( b == 1 )
1410 {
1411 *r = 0;
1412 return( 0 );
1413 }
1414
1415 if( b == 2 )
1416 {
1417 *r = A->p[0] & 1;
1418 return( 0 );
1419 }
1420
1421 /*
1422 * general case
1423 */
Paul Bakker23986e52011-04-24 08:57:21 +00001424 for( i = A->n, y = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001425 {
Paul Bakker23986e52011-04-24 08:57:21 +00001426 x = A->p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001427 y = ( y << biH ) | ( x >> biH );
1428 z = y / b;
1429 y -= z * b;
1430
1431 x <<= biH;
1432 y = ( y << biH ) | ( x >> biH );
1433 z = y / b;
1434 y -= z * b;
1435 }
1436
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001437 /*
1438 * If A is negative, then the current y represents a negative value.
1439 * Flipping it to the positive side.
1440 */
1441 if( A->s < 0 && y != 0 )
1442 y = b - y;
1443
Paul Bakker5121ce52009-01-03 21:22:43 +00001444 *r = y;
1445
1446 return( 0 );
1447}
1448
1449/*
1450 * Fast Montgomery initialization (thanks to Tom St Denis)
1451 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001452static void mpi_montg_init( t_uint *mm, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001453{
Paul Bakkera755ca12011-04-24 09:11:17 +00001454 t_uint x, m0 = N->p[0];
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001455 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001456
1457 x = m0;
1458 x += ( ( m0 + 2 ) & 4 ) << 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001459
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001460 for( i = biL; i >= 8; i /= 2 )
1461 x *= ( 2 - ( m0 * x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001462
1463 *mm = ~x + 1;
1464}
1465
1466/*
1467 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1468 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +02001469static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm,
1470 const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001471{
Paul Bakker23986e52011-04-24 08:57:21 +00001472 size_t i, n, m;
Paul Bakkera755ca12011-04-24 09:11:17 +00001473 t_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00001474
1475 memset( T->p, 0, T->n * ciL );
1476
1477 d = T->p;
1478 n = N->n;
1479 m = ( B->n < n ) ? B->n : n;
1480
1481 for( i = 0; i < n; i++ )
1482 {
1483 /*
1484 * T = (T + u0*B + u1*N) / 2^biL
1485 */
1486 u0 = A->p[i];
1487 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1488
1489 mpi_mul_hlp( m, B->p, d, u0 );
1490 mpi_mul_hlp( n, N->p, d, u1 );
1491
1492 *d++ = u0; d[n + 1] = 0;
1493 }
1494
Paul Bakker66d5d072014-06-17 16:39:18 +02001495 memcpy( A->p, d, ( n + 1 ) * ciL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001496
1497 if( mpi_cmp_abs( A, N ) >= 0 )
1498 mpi_sub_hlp( n, N->p, A->p );
1499 else
1500 /* prevent timing attacks */
1501 mpi_sub_hlp( n, A->p, T->p );
1502}
1503
1504/*
1505 * Montgomery reduction: A = A * R^-1 mod N
1506 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001507static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001508{
Paul Bakkera755ca12011-04-24 09:11:17 +00001509 t_uint z = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001510 mpi U;
1511
Paul Bakker8ddb6452013-02-27 14:56:33 +01001512 U.n = U.s = (int) z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001513 U.p = &z;
1514
1515 mpi_montmul( A, &U, N, mm, T );
1516}
1517
1518/*
1519 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1520 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001521int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00001522{
Paul Bakker23986e52011-04-24 08:57:21 +00001523 int ret;
1524 size_t wbits, wsize, one = 1;
1525 size_t i, j, nblimbs;
1526 size_t bufsize, nbits;
Paul Bakkera755ca12011-04-24 09:11:17 +00001527 t_uint ei, mm, state;
Paul Bakkerf6198c12012-05-16 08:02:29 +00001528 mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos;
1529 int neg;
Paul Bakker5121ce52009-01-03 21:22:43 +00001530
1531 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001532 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001533
Paul Bakkerf6198c12012-05-16 08:02:29 +00001534 if( mpi_cmp_int( E, 0 ) < 0 )
1535 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
1536
1537 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001538 * Init temps and window size
1539 */
1540 mpi_montg_init( &mm, N );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001541 mpi_init( &RR ); mpi_init( &T );
Manuel Pégourié-Gonnardfd6a1912014-01-18 19:05:23 +01001542 mpi_init( &Apos );
Paul Bakker5121ce52009-01-03 21:22:43 +00001543 memset( W, 0, sizeof( W ) );
1544
1545 i = mpi_msb( E );
1546
1547 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1548 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1549
Paul Bakkerb6d5f082011-11-25 11:52:11 +00001550 if( wsize > POLARSSL_MPI_WINDOW_SIZE )
1551 wsize = POLARSSL_MPI_WINDOW_SIZE;
1552
Paul Bakker5121ce52009-01-03 21:22:43 +00001553 j = N->n + 1;
1554 MPI_CHK( mpi_grow( X, j ) );
1555 MPI_CHK( mpi_grow( &W[1], j ) );
1556 MPI_CHK( mpi_grow( &T, j * 2 ) );
1557
1558 /*
Paul Bakker50546922012-05-19 08:40:49 +00001559 * Compensate for negative A (and correct at the end)
1560 */
1561 neg = ( A->s == -1 );
Paul Bakker50546922012-05-19 08:40:49 +00001562 if( neg )
1563 {
1564 MPI_CHK( mpi_copy( &Apos, A ) );
1565 Apos.s = 1;
1566 A = &Apos;
1567 }
1568
1569 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001570 * If 1st call, pre-compute R^2 mod N
1571 */
1572 if( _RR == NULL || _RR->p == NULL )
1573 {
1574 MPI_CHK( mpi_lset( &RR, 1 ) );
1575 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1576 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1577
1578 if( _RR != NULL )
1579 memcpy( _RR, &RR, sizeof( mpi ) );
1580 }
1581 else
1582 memcpy( &RR, _RR, sizeof( mpi ) );
1583
1584 /*
1585 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1586 */
1587 if( mpi_cmp_mpi( A, N ) >= 0 )
Paul Bakkerc2024f42014-01-23 20:38:35 +01001588 MPI_CHK( mpi_mod_mpi( &W[1], A, N ) );
1589 else
1590 MPI_CHK( mpi_copy( &W[1], A ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001591
1592 mpi_montmul( &W[1], &RR, N, mm, &T );
1593
1594 /*
1595 * X = R^2 * R^-1 mod N = R mod N
1596 */
1597 MPI_CHK( mpi_copy( X, &RR ) );
1598 mpi_montred( X, N, mm, &T );
1599
1600 if( wsize > 1 )
1601 {
1602 /*
1603 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1604 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001605 j = one << ( wsize - 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001606
1607 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1608 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1609
1610 for( i = 0; i < wsize - 1; i++ )
1611 mpi_montmul( &W[j], &W[j], N, mm, &T );
Paul Bakker0d7702c2013-10-29 16:18:35 +01001612
Paul Bakker5121ce52009-01-03 21:22:43 +00001613 /*
1614 * W[i] = W[i - 1] * W[1]
1615 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001616 for( i = j + 1; i < ( one << wsize ); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001617 {
1618 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1619 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1620
1621 mpi_montmul( &W[i], &W[1], N, mm, &T );
1622 }
1623 }
1624
1625 nblimbs = E->n;
1626 bufsize = 0;
1627 nbits = 0;
1628 wbits = 0;
1629 state = 0;
1630
1631 while( 1 )
1632 {
1633 if( bufsize == 0 )
1634 {
Paul Bakker0d7702c2013-10-29 16:18:35 +01001635 if( nblimbs == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001636 break;
1637
Paul Bakker0d7702c2013-10-29 16:18:35 +01001638 nblimbs--;
1639
Paul Bakkera755ca12011-04-24 09:11:17 +00001640 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001641 }
1642
1643 bufsize--;
1644
1645 ei = (E->p[nblimbs] >> bufsize) & 1;
1646
1647 /*
1648 * skip leading 0s
1649 */
1650 if( ei == 0 && state == 0 )
1651 continue;
1652
1653 if( ei == 0 && state == 1 )
1654 {
1655 /*
1656 * out of window, square X
1657 */
1658 mpi_montmul( X, X, N, mm, &T );
1659 continue;
1660 }
1661
1662 /*
1663 * add ei to current window
1664 */
1665 state = 2;
1666
1667 nbits++;
Paul Bakker66d5d072014-06-17 16:39:18 +02001668 wbits |= ( ei << ( wsize - nbits ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001669
1670 if( nbits == wsize )
1671 {
1672 /*
1673 * X = X^wsize R^-1 mod N
1674 */
1675 for( i = 0; i < wsize; i++ )
1676 mpi_montmul( X, X, N, mm, &T );
1677
1678 /*
1679 * X = X * W[wbits] R^-1 mod N
1680 */
1681 mpi_montmul( X, &W[wbits], N, mm, &T );
1682
1683 state--;
1684 nbits = 0;
1685 wbits = 0;
1686 }
1687 }
1688
1689 /*
1690 * process the remaining bits
1691 */
1692 for( i = 0; i < nbits; i++ )
1693 {
1694 mpi_montmul( X, X, N, mm, &T );
1695
1696 wbits <<= 1;
1697
Paul Bakker66d5d072014-06-17 16:39:18 +02001698 if( ( wbits & ( one << wsize ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001699 mpi_montmul( X, &W[1], N, mm, &T );
1700 }
1701
1702 /*
1703 * X = A^E * R * R^-1 mod N = A^E mod N
1704 */
1705 mpi_montred( X, N, mm, &T );
1706
Paul Bakkerf6198c12012-05-16 08:02:29 +00001707 if( neg )
1708 {
1709 X->s = -1;
Paul Bakkerc2024f42014-01-23 20:38:35 +01001710 MPI_CHK( mpi_add_mpi( X, N, X ) );
Paul Bakkerf6198c12012-05-16 08:02:29 +00001711 }
1712
Paul Bakker5121ce52009-01-03 21:22:43 +00001713cleanup:
1714
Paul Bakker66d5d072014-06-17 16:39:18 +02001715 for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001716 mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001717
Paul Bakkerf6198c12012-05-16 08:02:29 +00001718 mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001719
Paul Bakker75a28602014-03-31 12:08:17 +02001720 if( _RR == NULL || _RR->p == NULL )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001721 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001722
1723 return( ret );
1724}
1725
Paul Bakker5121ce52009-01-03 21:22:43 +00001726/*
1727 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1728 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001729int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001730{
Paul Bakker23986e52011-04-24 08:57:21 +00001731 int ret;
1732 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001733 mpi TG, TA, TB;
1734
Paul Bakker6c591fa2011-05-05 11:49:20 +00001735 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001736
Paul Bakker5121ce52009-01-03 21:22:43 +00001737 MPI_CHK( mpi_copy( &TA, A ) );
1738 MPI_CHK( mpi_copy( &TB, B ) );
1739
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001740 lz = mpi_lsb( &TA );
1741 lzt = mpi_lsb( &TB );
1742
Paul Bakker66d5d072014-06-17 16:39:18 +02001743 if( lzt < lz )
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001744 lz = lzt;
1745
1746 MPI_CHK( mpi_shift_r( &TA, lz ) );
1747 MPI_CHK( mpi_shift_r( &TB, lz ) );
1748
Paul Bakker5121ce52009-01-03 21:22:43 +00001749 TA.s = TB.s = 1;
1750
1751 while( mpi_cmp_int( &TA, 0 ) != 0 )
1752 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001753 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1754 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001755
1756 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1757 {
1758 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1759 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1760 }
1761 else
1762 {
1763 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1764 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1765 }
1766 }
1767
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001768 MPI_CHK( mpi_shift_l( &TB, lz ) );
1769 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001770
1771cleanup:
1772
Paul Bakker6c591fa2011-05-05 11:49:20 +00001773 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001774
1775 return( ret );
1776}
1777
Paul Bakker33dc46b2014-04-30 16:11:39 +02001778/*
1779 * Fill X with size bytes of random.
1780 *
1781 * Use a temporary bytes representation to make sure the result is the same
Paul Bakkerc37b0ac2014-05-01 14:19:23 +02001782 * regardless of the platform endianness (useful when f_rng is actually
Paul Bakker33dc46b2014-04-30 16:11:39 +02001783 * deterministic, eg for tests).
1784 */
Paul Bakkera3d195c2011-11-27 21:07:34 +00001785int mpi_fill_random( mpi *X, size_t size,
1786 int (*f_rng)(void *, unsigned char *, size_t),
1787 void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001788{
Paul Bakker23986e52011-04-24 08:57:21 +00001789 int ret;
Paul Bakker33dc46b2014-04-30 16:11:39 +02001790 unsigned char buf[POLARSSL_MPI_MAX_SIZE];
1791
1792 if( size > POLARSSL_MPI_MAX_SIZE )
1793 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker287781a2011-03-26 13:18:49 +00001794
Paul Bakker33dc46b2014-04-30 16:11:39 +02001795 MPI_CHK( f_rng( p_rng, buf, size ) );
1796 MPI_CHK( mpi_read_binary( X, buf, size ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001797
1798cleanup:
1799 return( ret );
1800}
1801
Paul Bakker5121ce52009-01-03 21:22:43 +00001802/*
1803 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1804 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001805int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001806{
1807 int ret;
1808 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1809
1810 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001811 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001812
Paul Bakker6c591fa2011-05-05 11:49:20 +00001813 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1814 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1815 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001816
1817 MPI_CHK( mpi_gcd( &G, A, N ) );
1818
1819 if( mpi_cmp_int( &G, 1 ) != 0 )
1820 {
Paul Bakker40e46942009-01-03 21:51:57 +00001821 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001822 goto cleanup;
1823 }
1824
1825 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1826 MPI_CHK( mpi_copy( &TU, &TA ) );
1827 MPI_CHK( mpi_copy( &TB, N ) );
1828 MPI_CHK( mpi_copy( &TV, N ) );
1829
1830 MPI_CHK( mpi_lset( &U1, 1 ) );
1831 MPI_CHK( mpi_lset( &U2, 0 ) );
1832 MPI_CHK( mpi_lset( &V1, 0 ) );
1833 MPI_CHK( mpi_lset( &V2, 1 ) );
1834
1835 do
1836 {
1837 while( ( TU.p[0] & 1 ) == 0 )
1838 {
1839 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1840
1841 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1842 {
1843 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1844 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1845 }
1846
1847 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1848 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1849 }
1850
1851 while( ( TV.p[0] & 1 ) == 0 )
1852 {
1853 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1854
1855 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1856 {
1857 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1858 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1859 }
1860
1861 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1862 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1863 }
1864
1865 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1866 {
1867 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1868 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1869 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1870 }
1871 else
1872 {
1873 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1874 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1875 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1876 }
1877 }
1878 while( mpi_cmp_int( &TU, 0 ) != 0 );
1879
1880 while( mpi_cmp_int( &V1, 0 ) < 0 )
1881 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1882
1883 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1884 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1885
1886 MPI_CHK( mpi_copy( X, &V1 ) );
1887
1888cleanup:
1889
Paul Bakker6c591fa2011-05-05 11:49:20 +00001890 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1891 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1892 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001893
1894 return( ret );
1895}
1896
Paul Bakkerd9374b02012-11-02 11:02:58 +00001897#if defined(POLARSSL_GENPRIME)
1898
Paul Bakker5121ce52009-01-03 21:22:43 +00001899static const int small_prime[] =
1900{
1901 3, 5, 7, 11, 13, 17, 19, 23,
1902 29, 31, 37, 41, 43, 47, 53, 59,
1903 61, 67, 71, 73, 79, 83, 89, 97,
1904 101, 103, 107, 109, 113, 127, 131, 137,
1905 139, 149, 151, 157, 163, 167, 173, 179,
1906 181, 191, 193, 197, 199, 211, 223, 227,
1907 229, 233, 239, 241, 251, 257, 263, 269,
1908 271, 277, 281, 283, 293, 307, 311, 313,
1909 317, 331, 337, 347, 349, 353, 359, 367,
1910 373, 379, 383, 389, 397, 401, 409, 419,
1911 421, 431, 433, 439, 443, 449, 457, 461,
1912 463, 467, 479, 487, 491, 499, 503, 509,
1913 521, 523, 541, 547, 557, 563, 569, 571,
1914 577, 587, 593, 599, 601, 607, 613, 617,
1915 619, 631, 641, 643, 647, 653, 659, 661,
1916 673, 677, 683, 691, 701, 709, 719, 727,
1917 733, 739, 743, 751, 757, 761, 769, 773,
1918 787, 797, 809, 811, 821, 823, 827, 829,
1919 839, 853, 857, 859, 863, 877, 881, 883,
1920 887, 907, 911, 919, 929, 937, 941, 947,
1921 953, 967, 971, 977, 983, 991, 997, -103
1922};
1923
1924/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001925 * Small divisors test (X must be positive)
1926 *
1927 * Return values:
1928 * 0: no small factor (possible prime, more tests needed)
1929 * 1: certain prime
1930 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
1931 * other negative: error
Paul Bakker5121ce52009-01-03 21:22:43 +00001932 */
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001933static int mpi_check_small_factors( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +00001934{
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001935 int ret = 0;
1936 size_t i;
1937 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001938
Paul Bakker5121ce52009-01-03 21:22:43 +00001939 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001940 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001941
1942 for( i = 0; small_prime[i] > 0; i++ )
1943 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001944 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001945 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001946
1947 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1948
1949 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001950 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001951 }
1952
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001953cleanup:
1954 return( ret );
1955}
1956
1957/*
1958 * Miller-Rabin pseudo-primality test (HAC 4.24)
1959 */
1960static int mpi_miller_rabin( const mpi *X,
1961 int (*f_rng)(void *, unsigned char *, size_t),
1962 void *p_rng )
1963{
Pascal Junodb99183d2015-03-11 16:49:45 +01001964 int ret, count;
1965 size_t i, j, k, n, s;
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001966 mpi W, R, T, A, RR;
1967
1968 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1969 mpi_init( &RR );
1970
Paul Bakker5121ce52009-01-03 21:22:43 +00001971 /*
1972 * W = |X| - 1
1973 * R = W >> lsb( W )
1974 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001975 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001976 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001977 MPI_CHK( mpi_copy( &R, &W ) );
1978 MPI_CHK( mpi_shift_r( &R, s ) );
1979
1980 i = mpi_msb( X );
1981 /*
1982 * HAC, table 4.4
1983 */
1984 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1985 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1986 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1987
1988 for( i = 0; i < n; i++ )
1989 {
1990 /*
1991 * pick a random A, 1 < A < |X| - 1
1992 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001993
Pascal Junodb99183d2015-03-11 16:49:45 +01001994 count = 0;
1995 do {
1996 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
1997
1998 j = mpi_msb( &A );
1999 k = mpi_msb( &W );
2000 if (j > k) {
2001 MPI_CHK( mpi_shift_r( &A, j - k ) );
2002 }
2003
2004 if (count++ > 30) {
2005 return POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
2006 }
2007
2008 } while ( (mpi_cmp_mpi( &A, &W ) >= 0) ||
2009 (mpi_cmp_int( &A, 1 ) <= 0) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002010
2011 /*
2012 * A = A^R mod |X|
2013 */
2014 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
2015
2016 if( mpi_cmp_mpi( &A, &W ) == 0 ||
2017 mpi_cmp_int( &A, 1 ) == 0 )
2018 continue;
2019
2020 j = 1;
2021 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
2022 {
2023 /*
2024 * A = A * A mod |X|
2025 */
2026 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
2027 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
2028
2029 if( mpi_cmp_int( &A, 1 ) == 0 )
2030 break;
2031
2032 j++;
2033 }
2034
2035 /*
2036 * not prime if A != |X| - 1 or A == 1
2037 */
2038 if( mpi_cmp_mpi( &A, &W ) != 0 ||
2039 mpi_cmp_int( &A, 1 ) == 0 )
2040 {
Paul Bakker40e46942009-01-03 21:51:57 +00002041 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002042 break;
2043 }
2044 }
2045
2046cleanup:
Paul Bakker6c591fa2011-05-05 11:49:20 +00002047 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
2048 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002049
2050 return( ret );
2051}
2052
2053/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002054 * Pseudo-primality test: small factors, then Miller-Rabin
2055 */
Paul Bakker45f457d2013-11-25 14:26:52 +01002056int mpi_is_prime( mpi *X,
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002057 int (*f_rng)(void *, unsigned char *, size_t),
2058 void *p_rng )
2059{
2060 int ret;
Manuel Pégourié-Gonnard7f4ed672014-10-14 20:56:02 +02002061 mpi XX;
2062
2063 XX.s = 1;
2064 XX.n = X->n;
2065 XX.p = X->p;
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002066
2067 if( mpi_cmp_int( &XX, 0 ) == 0 ||
2068 mpi_cmp_int( &XX, 1 ) == 0 )
2069 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
2070
2071 if( mpi_cmp_int( &XX, 2 ) == 0 )
2072 return( 0 );
2073
2074 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2075 {
2076 if( ret == 1 )
2077 return( 0 );
2078
2079 return( ret );
2080 }
2081
2082 return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
2083}
2084
2085/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002086 * Prime number generation
2087 */
Paul Bakker23986e52011-04-24 08:57:21 +00002088int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002089 int (*f_rng)(void *, unsigned char *, size_t),
2090 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +00002091{
Paul Bakker23986e52011-04-24 08:57:21 +00002092 int ret;
2093 size_t k, n;
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002094 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002095 mpi Y;
2096
Paul Bakkerfe3256e2011-11-25 12:11:43 +00002097 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
Paul Bakker40e46942009-01-03 21:51:57 +00002098 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002099
Paul Bakker6c591fa2011-05-05 11:49:20 +00002100 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002101
2102 n = BITS_TO_LIMBS( nbits );
2103
Paul Bakker901c6562012-04-20 13:25:38 +00002104 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002105
2106 k = mpi_msb( X );
Pascal Junodb99183d2015-03-11 16:49:45 +01002107 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits + 1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002108
Pascal Junodb99183d2015-03-11 16:49:45 +01002109 mpi_set_bit( X, nbits-1, 1 );
2110
2111 X->p[0] |= 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002112
2113 if( dh_flag == 0 )
2114 {
2115 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
2116 {
Paul Bakker40e46942009-01-03 21:51:57 +00002117 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002118 goto cleanup;
2119
2120 MPI_CHK( mpi_add_int( X, X, 2 ) );
2121 }
2122 }
2123 else
2124 {
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002125 /*
2126 * An necessary condition for Y and X = 2Y + 1 to be prime
2127 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2128 * Make sure it is satisfied, while keeping X = 3 mod 4
2129 */
Pascal Junodb99183d2015-03-11 16:49:45 +01002130
2131 X->p[0] |= 2;
2132
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002133 MPI_CHK( mpi_mod_int( &r, X, 3 ) );
2134 if( r == 0 )
2135 MPI_CHK( mpi_add_int( X, X, 8 ) );
2136 else if( r == 1 )
2137 MPI_CHK( mpi_add_int( X, X, 4 ) );
2138
2139 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2140 MPI_CHK( mpi_copy( &Y, X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002141 MPI_CHK( mpi_shift_r( &Y, 1 ) );
2142
2143 while( 1 )
2144 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002145 /*
2146 * First, check small factors for X and Y
2147 * before doing Miller-Rabin on any of them
2148 */
2149 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2150 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2151 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
2152 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002153 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002154 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002155 }
2156
Paul Bakker40e46942009-01-03 21:51:57 +00002157 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002158 goto cleanup;
2159
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002160 /*
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002161 * Next candidates. We want to preserve Y = (X-1) / 2 and
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002162 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2163 * so up Y by 6 and X by 12.
2164 */
2165 MPI_CHK( mpi_add_int( X, X, 12 ) );
2166 MPI_CHK( mpi_add_int( &Y, &Y, 6 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002167 }
2168 }
2169
2170cleanup:
2171
Paul Bakker6c591fa2011-05-05 11:49:20 +00002172 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002173
2174 return( ret );
2175}
2176
Manuel Pégourié-Gonnarddf0142b2013-08-22 18:29:07 +02002177#endif /* POLARSSL_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00002178
Paul Bakker40e46942009-01-03 21:51:57 +00002179#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002180
Paul Bakker23986e52011-04-24 08:57:21 +00002181#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002182
2183static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2184{
2185 { 693, 609, 21 },
2186 { 1764, 868, 28 },
2187 { 768454923, 542167814, 1 }
2188};
2189
Paul Bakker5121ce52009-01-03 21:22:43 +00002190/*
2191 * Checkup routine
2192 */
2193int mpi_self_test( int verbose )
2194{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002195 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00002196 mpi A, E, N, X, Y, U, V;
2197
Paul Bakker6c591fa2011-05-05 11:49:20 +00002198 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
2199 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002200
2201 MPI_CHK( mpi_read_string( &A, 16,
2202 "EFE021C2645FD1DC586E69184AF4A31E" \
2203 "D5F53E93B5F123FA41680867BA110131" \
2204 "944FE7952E2517337780CB0DB80E61AA" \
2205 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2206
2207 MPI_CHK( mpi_read_string( &E, 16,
2208 "B2E7EFD37075B9F03FF989C7C5051C20" \
2209 "34D2A323810251127E7BF8625A4F49A5" \
2210 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2211 "5B5C25763222FEFCCFC38B832366C29E" ) );
2212
2213 MPI_CHK( mpi_read_string( &N, 16,
2214 "0066A198186C18C10B2F5ED9B522752A" \
2215 "9830B69916E535C8F047518A889A43A5" \
2216 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2217
2218 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
2219
2220 MPI_CHK( mpi_read_string( &U, 16,
2221 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2222 "9E857EA95A03512E2BAE7391688D264A" \
2223 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2224 "8001B72E848A38CAE1C65F78E56ABDEF" \
2225 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2226 "ECF677152EF804370C1A305CAF3B5BF1" \
2227 "30879B56C61DE584A0F53A2447A51E" ) );
2228
2229 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002230 polarssl_printf( " MPI test #1 (mul_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002231
2232 if( mpi_cmp_mpi( &X, &U ) != 0 )
2233 {
2234 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002235 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002236
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002237 ret = 1;
2238 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002239 }
2240
2241 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002242 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002243
2244 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
2245
2246 MPI_CHK( mpi_read_string( &U, 16,
2247 "256567336059E52CAE22925474705F39A94" ) );
2248
2249 MPI_CHK( mpi_read_string( &V, 16,
2250 "6613F26162223DF488E9CD48CC132C7A" \
2251 "0AC93C701B001B092E4E5B9F73BCD27B" \
2252 "9EE50D0657C77F374E903CDFA4C642" ) );
2253
2254 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002255 polarssl_printf( " MPI test #2 (div_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002256
2257 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2258 mpi_cmp_mpi( &Y, &V ) != 0 )
2259 {
2260 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002261 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002262
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002263 ret = 1;
2264 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002265 }
2266
2267 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002268 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002269
2270 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2271
2272 MPI_CHK( mpi_read_string( &U, 16,
2273 "36E139AEA55215609D2816998ED020BB" \
2274 "BD96C37890F65171D948E9BC7CBAA4D9" \
2275 "325D24D6A3C12710F10A09FA08AB87" ) );
2276
2277 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002278 polarssl_printf( " MPI test #3 (exp_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002279
2280 if( mpi_cmp_mpi( &X, &U ) != 0 )
2281 {
2282 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002283 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002284
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002285 ret = 1;
2286 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002287 }
2288
2289 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002290 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002291
2292 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2293
2294 MPI_CHK( mpi_read_string( &U, 16,
2295 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2296 "C3DBA76456363A10869622EAC2DD84EC" \
2297 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2298
2299 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002300 polarssl_printf( " MPI test #4 (inv_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002301
2302 if( mpi_cmp_mpi( &X, &U ) != 0 )
2303 {
2304 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002305 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002306
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002307 ret = 1;
2308 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002309 }
2310
2311 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002312 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002313
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002314 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002315 polarssl_printf( " MPI test #5 (simple gcd): " );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002316
Paul Bakker66d5d072014-06-17 16:39:18 +02002317 for( i = 0; i < GCD_PAIR_COUNT; i++ )
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002318 {
2319 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002320 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002321
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002322 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002323
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002324 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2325 {
2326 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002327 polarssl_printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002328
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002329 ret = 1;
2330 goto cleanup;
2331 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002332 }
2333
2334 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002335 polarssl_printf( "passed\n" );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002336
Paul Bakker5121ce52009-01-03 21:22:43 +00002337cleanup:
2338
2339 if( ret != 0 && verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002340 polarssl_printf( "Unexpected error, return code = %08X\n", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002341
Paul Bakker6c591fa2011-05-05 11:49:20 +00002342 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2343 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002344
2345 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002346 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002347
2348 return( ret );
2349}
2350
Paul Bakker9af723c2014-05-01 13:03:14 +02002351#endif /* POLARSSL_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002352
Paul Bakker9af723c2014-05-01 13:03:14 +02002353#endif /* POLARSSL_BIGNUM_C */