blob: 0a956073424c01736ad1c756b0453bf1336d29fd [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 */
Simon Butchere4ed3472015-12-22 15:26:57 +000022
Paul Bakker5121ce52009-01-03 21:22:43 +000023/*
Simon Butchere4ed3472015-12-22 15:26:57 +000024 * The following sources were referenced in the design of this Multi-precision
25 * Integer library:
Paul Bakker5121ce52009-01-03 21:22:43 +000026 *
Simon Butchere4ed3472015-12-22 15:26:57 +000027 * [1] Handbook of Applied Cryptography - 1997
28 * Menezes, van Oorschot and Vanstone
29 *
30 * [2] Multi-Precision Math
31 * Tom St Denis
32 * https://github.com/libtom/libtommath/blob/develop/tommath.pdf
33 *
34 * [3] GNU Multi-Precision Arithmetic Library
35 * https://gmplib.org/manual/index.html
36 *
Simon Butcher14400c82016-01-02 00:08:13 +000037 */
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020039#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker40e46942009-01-03 21:51:57 +000040#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020041#else
42#include POLARSSL_CONFIG_FILE
43#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000044
Paul Bakker40e46942009-01-03 21:51:57 +000045#if defined(POLARSSL_BIGNUM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000046
Paul Bakker40e46942009-01-03 21:51:57 +000047#include "polarssl/bignum.h"
48#include "polarssl/bn_mul.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000049
Rich Evans00ab4702015-02-06 13:43:58 +000050#include <string.h>
51
Paul Bakker7dc4c442014-02-01 22:50:26 +010052#if defined(POLARSSL_PLATFORM_C)
53#include "polarssl/platform.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020054#else
Rich Evans00ab4702015-02-06 13:43:58 +000055#include <stdio.h>
56#include <stdlib.h>
Paul Bakker7dc4c442014-02-01 22:50:26 +010057#define polarssl_printf printf
Paul Bakker6e339b52013-07-03 13:37:05 +020058#define polarssl_malloc malloc
59#define polarssl_free free
60#endif
61
Paul Bakker34617722014-06-13 17:20:13 +020062/* Implementation that should never be optimized out by the compiler */
63static void polarssl_zeroize( void *v, size_t n ) {
64 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
65}
66
Paul Bakkerf9688572011-05-05 10:00:45 +000067#define ciL (sizeof(t_uint)) /* chars in limb */
Paul Bakker5121ce52009-01-03 21:22:43 +000068#define biL (ciL << 3) /* bits in limb */
69#define biH (ciL << 2) /* half limb size */
70
Manuel Pégourié-Gonnardfa647a72015-10-05 15:23:11 +010071#define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
72
Paul Bakker5121ce52009-01-03 21:22:43 +000073/*
74 * Convert between bits/chars and number of limbs
Manuel Pégourié-Gonnard59efb6a2015-09-28 13:48:04 +020075 * Divide first in order to avoid potential overflows
Paul Bakker5121ce52009-01-03 21:22:43 +000076 */
Manuel Pégourié-Gonnard59efb6a2015-09-28 13:48:04 +020077#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
78#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
Paul Bakker5121ce52009-01-03 21:22:43 +000079
80/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000081 * Initialize one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000082 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000083void mpi_init( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000084{
Paul Bakker6c591fa2011-05-05 11:49:20 +000085 if( X == NULL )
86 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000087
Paul Bakker6c591fa2011-05-05 11:49:20 +000088 X->s = 1;
89 X->n = 0;
90 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000091}
92
93/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000094 * Unallocate one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000095 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000096void mpi_free( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000097{
Paul Bakker6c591fa2011-05-05 11:49:20 +000098 if( X == NULL )
99 return;
Paul Bakker5121ce52009-01-03 21:22:43 +0000100
Paul Bakker6c591fa2011-05-05 11:49:20 +0000101 if( X->p != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +0000102 {
Paul Bakker34617722014-06-13 17:20:13 +0200103 polarssl_zeroize( X->p, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +0200104 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000105 }
106
Paul Bakker6c591fa2011-05-05 11:49:20 +0000107 X->s = 1;
108 X->n = 0;
109 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +0000110}
111
112/*
113 * Enlarge to the specified number of limbs
114 */
Paul Bakker23986e52011-04-24 08:57:21 +0000115int mpi_grow( mpi *X, size_t nblimbs )
Paul Bakker5121ce52009-01-03 21:22:43 +0000116{
Paul Bakkera755ca12011-04-24 09:11:17 +0000117 t_uint *p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000118
Paul Bakkerf9688572011-05-05 10:00:45 +0000119 if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
Paul Bakker69e095c2011-12-10 21:55:01 +0000120 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakkerf9688572011-05-05 10:00:45 +0000121
Paul Bakker5121ce52009-01-03 21:22:43 +0000122 if( X->n < nblimbs )
123 {
Mansour Moufidc531b4a2015-02-15 17:35:38 -0500124 if( ( p = polarssl_malloc( nblimbs * ciL ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000125 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000126
127 memset( p, 0, nblimbs * ciL );
128
129 if( X->p != NULL )
130 {
131 memcpy( p, X->p, X->n * ciL );
Paul Bakker34617722014-06-13 17:20:13 +0200132 polarssl_zeroize( X->p, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +0200133 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000134 }
135
136 X->n = nblimbs;
137 X->p = p;
138 }
139
140 return( 0 );
141}
142
143/*
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100144 * Resize down as much as possible,
145 * while keeping at least the specified number of limbs
146 */
147int mpi_shrink( mpi *X, size_t nblimbs )
148{
149 t_uint *p;
150 size_t i;
151
152 /* Actually resize up in this case */
153 if( X->n <= nblimbs )
154 return( mpi_grow( X, nblimbs ) );
155
156 for( i = X->n - 1; i > 0; i-- )
157 if( X->p[i] != 0 )
158 break;
159 i++;
160
161 if( i < nblimbs )
162 i = nblimbs;
163
Mansour Moufidc531b4a2015-02-15 17:35:38 -0500164 if( ( p = polarssl_malloc( i * ciL ) ) == NULL )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100165 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
166
167 memset( p, 0, i * ciL );
168
169 if( X->p != NULL )
170 {
171 memcpy( p, X->p, i * ciL );
Paul Bakker34617722014-06-13 17:20:13 +0200172 polarssl_zeroize( X->p, X->n * ciL );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100173 polarssl_free( X->p );
174 }
175
176 X->n = i;
177 X->p = p;
178
179 return( 0 );
180}
181
182/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000183 * Copy the contents of Y into X
184 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000185int mpi_copy( mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000186{
Paul Bakker23986e52011-04-24 08:57:21 +0000187 int ret;
188 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000189
190 if( X == Y )
191 return( 0 );
192
Manuel Pégourié-Gonnardf4999932013-08-12 17:02:59 +0200193 if( Y->p == NULL )
194 {
195 mpi_free( X );
196 return( 0 );
197 }
198
Paul Bakker5121ce52009-01-03 21:22:43 +0000199 for( i = Y->n - 1; i > 0; i-- )
200 if( Y->p[i] != 0 )
201 break;
202 i++;
203
204 X->s = Y->s;
205
206 MPI_CHK( mpi_grow( X, i ) );
207
208 memset( X->p, 0, X->n * ciL );
209 memcpy( X->p, Y->p, i * ciL );
210
211cleanup:
212
213 return( ret );
214}
215
216/*
217 * Swap the contents of X and Y
218 */
219void mpi_swap( mpi *X, mpi *Y )
220{
221 mpi T;
222
223 memcpy( &T, X, sizeof( mpi ) );
224 memcpy( X, Y, sizeof( mpi ) );
225 memcpy( Y, &T, sizeof( mpi ) );
226}
227
228/*
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100229 * Conditionally assign X = Y, without leaking information
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100230 * about whether the assignment was made or not.
231 * (Leaking information about the respective sizes of X and Y is ok however.)
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100232 */
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100233int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign )
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100234{
235 int ret = 0;
236 size_t i;
237
Pascal Junodb99183d2015-03-11 16:49:45 +0100238 /* make sure assign is 0 or 1 in a time-constant manner */
239 assign = (assign | (unsigned char)-assign) >> 7;
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100240
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100241 MPI_CHK( mpi_grow( X, Y->n ) );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100242
Paul Bakker66d5d072014-06-17 16:39:18 +0200243 X->s = X->s * ( 1 - assign ) + Y->s * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100244
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100245 for( i = 0; i < Y->n; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200246 X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100247
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100248 for( ; i < X->n; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200249 X->p[i] *= ( 1 - assign );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100250
251cleanup:
252 return( ret );
253}
254
255/*
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100256 * Conditionally swap X and Y, without leaking information
257 * about whether the swap was made or not.
258 * Here it is not ok to simply swap the pointers, which whould lead to
259 * different memory access patterns when X and Y are used afterwards.
260 */
261int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char swap )
262{
263 int ret, s;
264 size_t i;
265 t_uint tmp;
266
267 if( X == Y )
268 return( 0 );
269
Pascal Junodb99183d2015-03-11 16:49:45 +0100270 /* make sure swap is 0 or 1 in a time-constant manner */
271 swap = (swap | (unsigned char)-swap) >> 7;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100272
273 MPI_CHK( mpi_grow( X, Y->n ) );
274 MPI_CHK( mpi_grow( Y, X->n ) );
275
276 s = X->s;
Paul Bakker66d5d072014-06-17 16:39:18 +0200277 X->s = X->s * ( 1 - swap ) + Y->s * swap;
278 Y->s = Y->s * ( 1 - swap ) + s * swap;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100279
280
281 for( i = 0; i < X->n; i++ )
282 {
283 tmp = X->p[i];
Paul Bakker66d5d072014-06-17 16:39:18 +0200284 X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap;
285 Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100286 }
287
288cleanup:
289 return( ret );
290}
291
292/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000293 * Set value from integer
294 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000295int mpi_lset( mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000296{
297 int ret;
298
299 MPI_CHK( mpi_grow( X, 1 ) );
300 memset( X->p, 0, X->n * ciL );
301
302 X->p[0] = ( z < 0 ) ? -z : z;
303 X->s = ( z < 0 ) ? -1 : 1;
304
305cleanup:
306
307 return( ret );
308}
309
310/*
Paul Bakker2f5947e2011-05-18 15:47:11 +0000311 * Get a specific bit
312 */
Paul Bakker6b906e52012-05-08 12:01:43 +0000313int mpi_get_bit( const mpi *X, size_t pos )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000314{
315 if( X->n * biL <= pos )
316 return( 0 );
317
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200318 return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000319}
320
321/*
322 * Set a bit to a specific value of 0 or 1
323 */
324int mpi_set_bit( mpi *X, size_t pos, unsigned char val )
325{
326 int ret = 0;
327 size_t off = pos / biL;
328 size_t idx = pos % biL;
329
330 if( val != 0 && val != 1 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200331 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker9af723c2014-05-01 13:03:14 +0200332
Paul Bakker2f5947e2011-05-18 15:47:11 +0000333 if( X->n * biL <= pos )
334 {
335 if( val == 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200336 return( 0 );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000337
338 MPI_CHK( mpi_grow( X, off + 1 ) );
339 }
340
Manuel Pégourié-Gonnard9a4a5ac2013-12-04 18:05:29 +0100341 X->p[off] &= ~( (t_uint) 0x01 << idx );
342 X->p[off] |= (t_uint) val << idx;
Paul Bakker2f5947e2011-05-18 15:47:11 +0000343
344cleanup:
Paul Bakker9af723c2014-05-01 13:03:14 +0200345
Paul Bakker2f5947e2011-05-18 15:47:11 +0000346 return( ret );
347}
348
349/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000350 * Return the number of least significant bits
351 */
Paul Bakker23986e52011-04-24 08:57:21 +0000352size_t mpi_lsb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000353{
Paul Bakker23986e52011-04-24 08:57:21 +0000354 size_t i, j, count = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000355
356 for( i = 0; i < X->n; i++ )
Paul Bakkerf9688572011-05-05 10:00:45 +0000357 for( j = 0; j < biL; j++, count++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000358 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
359 return( count );
360
361 return( 0 );
362}
363
364/*
Simon Butchere4ed3472015-12-22 15:26:57 +0000365 * Count leading zero bits in a given integer
366 */
367static size_t int_clz( const t_uint x )
368{
369 size_t j;
370 t_uint mask = (t_uint) 1 << (biL - 1);
371
372 for( j = 0; j < biL; j++ )
373 {
374 if( x & mask ) break;
375
376 mask >>= 1;
377 }
378
379 return j;
380}
381
382/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000383 * Return the number of most significant bits
384 */
Paul Bakker23986e52011-04-24 08:57:21 +0000385size_t mpi_msb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000386{
Paul Bakker23986e52011-04-24 08:57:21 +0000387 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000388
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200389 if( X->n == 0 )
390 return( 0 );
391
Paul Bakker5121ce52009-01-03 21:22:43 +0000392 for( i = X->n - 1; i > 0; i-- )
393 if( X->p[i] != 0 )
394 break;
395
Simon Butchere4ed3472015-12-22 15:26:57 +0000396 j = biL - int_clz( X->p[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000397
Paul Bakker23986e52011-04-24 08:57:21 +0000398 return( ( i * biL ) + j );
Paul Bakker5121ce52009-01-03 21:22:43 +0000399}
400
401/*
402 * Return the total size in bytes
403 */
Paul Bakker23986e52011-04-24 08:57:21 +0000404size_t mpi_size( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000405{
406 return( ( mpi_msb( X ) + 7 ) >> 3 );
407}
408
409/*
410 * Convert an ASCII character to digit value
411 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000412static int mpi_get_digit( t_uint *d, int radix, char c )
Paul Bakker5121ce52009-01-03 21:22:43 +0000413{
414 *d = 255;
415
416 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
417 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
418 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
419
Paul Bakkera755ca12011-04-24 09:11:17 +0000420 if( *d >= (t_uint) radix )
Paul Bakker40e46942009-01-03 21:51:57 +0000421 return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000422
423 return( 0 );
424}
425
426/*
427 * Import from an ASCII string
428 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000429int mpi_read_string( mpi *X, int radix, const char *s )
Paul Bakker5121ce52009-01-03 21:22:43 +0000430{
Paul Bakker23986e52011-04-24 08:57:21 +0000431 int ret;
432 size_t i, j, slen, n;
Paul Bakkera755ca12011-04-24 09:11:17 +0000433 t_uint d;
Paul Bakker5121ce52009-01-03 21:22:43 +0000434 mpi T;
435
436 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000437 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000438
Paul Bakker6c591fa2011-05-05 11:49:20 +0000439 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000440
Paul Bakkerff60ee62010-03-16 21:09:09 +0000441 slen = strlen( s );
442
Paul Bakker5121ce52009-01-03 21:22:43 +0000443 if( radix == 16 )
444 {
Manuel Pégourié-Gonnardfa647a72015-10-05 15:23:11 +0100445 if( slen > MPI_SIZE_T_MAX >> 2 )
Manuel Pégourié-Gonnard59efb6a2015-09-28 13:48:04 +0200446 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
447
Paul Bakkerff60ee62010-03-16 21:09:09 +0000448 n = BITS_TO_LIMBS( slen << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000449
450 MPI_CHK( mpi_grow( X, n ) );
451 MPI_CHK( mpi_lset( X, 0 ) );
452
Paul Bakker23986e52011-04-24 08:57:21 +0000453 for( i = slen, j = 0; i > 0; i--, j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000454 {
Paul Bakker23986e52011-04-24 08:57:21 +0000455 if( i == 1 && s[i - 1] == '-' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000456 {
457 X->s = -1;
458 break;
459 }
460
Paul Bakker23986e52011-04-24 08:57:21 +0000461 MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
Paul Bakker66d5d072014-06-17 16:39:18 +0200462 X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000463 }
464 }
465 else
466 {
467 MPI_CHK( mpi_lset( X, 0 ) );
468
Paul Bakkerff60ee62010-03-16 21:09:09 +0000469 for( i = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000470 {
471 if( i == 0 && s[i] == '-' )
472 {
473 X->s = -1;
474 continue;
475 }
476
477 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
478 MPI_CHK( mpi_mul_int( &T, X, radix ) );
Paul Bakker05feca62009-06-20 08:22:43 +0000479
480 if( X->s == 1 )
481 {
482 MPI_CHK( mpi_add_int( X, &T, d ) );
483 }
484 else
485 {
486 MPI_CHK( mpi_sub_int( X, &T, d ) );
487 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000488 }
489 }
490
491cleanup:
492
Paul Bakker6c591fa2011-05-05 11:49:20 +0000493 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
495 return( ret );
496}
497
498/*
499 * Helper to write the digits high-order first
500 */
501static int mpi_write_hlp( mpi *X, int radix, char **p )
502{
503 int ret;
Paul Bakkera755ca12011-04-24 09:11:17 +0000504 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +0000505
506 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000507 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000508
509 MPI_CHK( mpi_mod_int( &r, X, radix ) );
510 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
511
512 if( mpi_cmp_int( X, 0 ) != 0 )
513 MPI_CHK( mpi_write_hlp( X, radix, p ) );
514
515 if( r < 10 )
516 *(*p)++ = (char)( r + 0x30 );
517 else
518 *(*p)++ = (char)( r + 0x37 );
519
520cleanup:
521
522 return( ret );
523}
524
525/*
526 * Export into an ASCII string
527 */
Paul Bakker23986e52011-04-24 08:57:21 +0000528int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000529{
Paul Bakker23986e52011-04-24 08:57:21 +0000530 int ret = 0;
531 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000532 char *p;
533 mpi T;
534
535 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000536 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000537
538 n = mpi_msb( X );
539 if( radix >= 4 ) n >>= 1;
540 if( radix >= 16 ) n >>= 1;
Andres AG2b2fc112017-03-01 14:04:08 +0000541 /*
542 * Round up the buffer length to an even value to ensure that there is
543 * enough room for hexadecimal values that can be represented in an odd
544 * number of digits.
545 */
546 n += 3 + ( ( n + 1 ) & 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000547
548 if( *slen < n )
549 {
550 *slen = n;
Paul Bakker40e46942009-01-03 21:51:57 +0000551 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000552 }
553
554 p = s;
Paul Bakker6c591fa2011-05-05 11:49:20 +0000555 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000556
557 if( X->s == -1 )
558 *p++ = '-';
559
560 if( radix == 16 )
561 {
Paul Bakker23986e52011-04-24 08:57:21 +0000562 int c;
563 size_t i, j, k;
Paul Bakker5121ce52009-01-03 21:22:43 +0000564
Paul Bakker23986e52011-04-24 08:57:21 +0000565 for( i = X->n, k = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000566 {
Paul Bakker23986e52011-04-24 08:57:21 +0000567 for( j = ciL; j > 0; j-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000568 {
Paul Bakker23986e52011-04-24 08:57:21 +0000569 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000570
Paul Bakker6c343d72014-07-10 14:36:19 +0200571 if( c == 0 && k == 0 && ( i + j ) != 2 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000572 continue;
573
Paul Bakker98fe5ea2012-10-24 11:17:48 +0000574 *(p++) = "0123456789ABCDEF" [c / 16];
Paul Bakkerd2c167e2012-10-30 07:49:19 +0000575 *(p++) = "0123456789ABCDEF" [c % 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000576 k = 1;
577 }
578 }
579 }
580 else
581 {
582 MPI_CHK( mpi_copy( &T, X ) );
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000583
584 if( T.s == -1 )
585 T.s = 1;
586
Paul Bakker5121ce52009-01-03 21:22:43 +0000587 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
588 }
589
590 *p++ = '\0';
591 *slen = p - s;
592
593cleanup:
594
Paul Bakker6c591fa2011-05-05 11:49:20 +0000595 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000596
597 return( ret );
598}
599
Paul Bakker335db3f2011-04-25 15:28:35 +0000600#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000601/*
602 * Read X from an opened file
603 */
604int mpi_read_file( mpi *X, int radix, FILE *fin )
605{
Paul Bakkera755ca12011-04-24 09:11:17 +0000606 t_uint d;
Paul Bakker23986e52011-04-24 08:57:21 +0000607 size_t slen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000608 char *p;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000609 /*
Paul Bakkercb37aa52011-11-30 16:00:20 +0000610 * Buffer should have space for (short) label and decimal formatted MPI,
611 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000612 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000613 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000614
615 memset( s, 0, sizeof( s ) );
616 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000617 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000618
619 slen = strlen( s );
Paul Bakkercb37aa52011-11-30 16:00:20 +0000620 if( slen == sizeof( s ) - 2 )
621 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
622
Hanno Becker8c7698b2017-05-12 07:26:01 +0100623 if( slen > 0 && s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
624 if( slen > 0 && s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
Paul Bakker5121ce52009-01-03 21:22:43 +0000625
626 p = s + slen;
Hanno Becker8c7698b2017-05-12 07:26:01 +0100627 while( p-- > s )
Paul Bakker5121ce52009-01-03 21:22:43 +0000628 if( mpi_get_digit( &d, radix, *p ) != 0 )
629 break;
630
631 return( mpi_read_string( X, radix, p + 1 ) );
632}
633
634/*
635 * Write X into an opened file (or stdout if fout == NULL)
636 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000637int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
Paul Bakker5121ce52009-01-03 21:22:43 +0000638{
Paul Bakker23986e52011-04-24 08:57:21 +0000639 int ret;
640 size_t n, slen, plen;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000641 /*
Paul Bakker5531c6d2012-09-26 19:20:46 +0000642 * Buffer should have space for (short) label and decimal formatted MPI,
643 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000644 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000645 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000646
647 n = sizeof( s );
648 memset( s, 0, n );
649 n -= 2;
650
Paul Bakker23986e52011-04-24 08:57:21 +0000651 MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000652
653 if( p == NULL ) p = "";
654
655 plen = strlen( p );
656 slen = strlen( s );
657 s[slen++] = '\r';
658 s[slen++] = '\n';
659
660 if( fout != NULL )
661 {
662 if( fwrite( p, 1, plen, fout ) != plen ||
663 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000664 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000665 }
666 else
Paul Bakker7dc4c442014-02-01 22:50:26 +0100667 polarssl_printf( "%s%s", p, s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000668
669cleanup:
670
671 return( ret );
672}
Paul Bakker335db3f2011-04-25 15:28:35 +0000673#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000674
675/*
676 * Import X from unsigned binary data, big endian
677 */
Paul Bakker23986e52011-04-24 08:57:21 +0000678int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000679{
Paul Bakker23986e52011-04-24 08:57:21 +0000680 int ret;
Hanno Becker0727ca42017-10-25 16:07:09 +0100681 size_t i, j;
682 size_t const limbs = CHARS_TO_LIMBS( buflen );
Paul Bakker5121ce52009-01-03 21:22:43 +0000683
Hanno Becker0727ca42017-10-25 16:07:09 +0100684 /* Ensure that target MPI has exactly the necessary number of limbs */
685 if( X->n != limbs )
686 {
687 mpi_free( X );
688 mpi_init( X );
689 MPI_CHK( mpi_grow( X, limbs ) );
690 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000691
Paul Bakker5121ce52009-01-03 21:22:43 +0000692 MPI_CHK( mpi_lset( X, 0 ) );
693
Hanno Becker0727ca42017-10-25 16:07:09 +0100694 for( i = buflen, j = 0; i > 0; i--, j++ )
Paul Bakkera755ca12011-04-24 09:11:17 +0000695 X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000696
697cleanup:
698
699 return( ret );
700}
701
702/*
703 * Export X into unsigned binary data, big endian
704 */
Paul Bakker23986e52011-04-24 08:57:21 +0000705int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000706{
Paul Bakker23986e52011-04-24 08:57:21 +0000707 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000708
709 n = mpi_size( X );
710
711 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000712 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000713
714 memset( buf, 0, buflen );
715
716 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
717 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
718
719 return( 0 );
720}
721
722/*
723 * Left-shift: X <<= count
724 */
Paul Bakker23986e52011-04-24 08:57:21 +0000725int mpi_shift_l( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000726{
Paul Bakker23986e52011-04-24 08:57:21 +0000727 int ret;
728 size_t i, v0, t1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000729 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000730
731 v0 = count / (biL );
732 t1 = count & (biL - 1);
733
734 i = mpi_msb( X ) + count;
735
Paul Bakkerf9688572011-05-05 10:00:45 +0000736 if( X->n * biL < i )
Paul Bakker5121ce52009-01-03 21:22:43 +0000737 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
738
739 ret = 0;
740
741 /*
742 * shift by count / limb_size
743 */
744 if( v0 > 0 )
745 {
Paul Bakker23986e52011-04-24 08:57:21 +0000746 for( i = X->n; i > v0; i-- )
747 X->p[i - 1] = X->p[i - v0 - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000748
Paul Bakker23986e52011-04-24 08:57:21 +0000749 for( ; i > 0; i-- )
750 X->p[i - 1] = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000751 }
752
753 /*
754 * shift by count % limb_size
755 */
756 if( t1 > 0 )
757 {
758 for( i = v0; i < X->n; i++ )
759 {
760 r1 = X->p[i] >> (biL - t1);
761 X->p[i] <<= t1;
762 X->p[i] |= r0;
763 r0 = r1;
764 }
765 }
766
767cleanup:
768
769 return( ret );
770}
771
772/*
773 * Right-shift: X >>= count
774 */
Paul Bakker23986e52011-04-24 08:57:21 +0000775int mpi_shift_r( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000776{
Paul Bakker23986e52011-04-24 08:57:21 +0000777 size_t i, v0, v1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000778 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000779
780 v0 = count / biL;
781 v1 = count & (biL - 1);
782
Manuel Pégourié-Gonnarde44ec102012-11-17 12:42:51 +0100783 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
784 return mpi_lset( X, 0 );
785
Paul Bakker5121ce52009-01-03 21:22:43 +0000786 /*
787 * shift by count / limb_size
788 */
789 if( v0 > 0 )
790 {
791 for( i = 0; i < X->n - v0; i++ )
792 X->p[i] = X->p[i + v0];
793
794 for( ; i < X->n; i++ )
795 X->p[i] = 0;
796 }
797
798 /*
799 * shift by count % limb_size
800 */
801 if( v1 > 0 )
802 {
Paul Bakker23986e52011-04-24 08:57:21 +0000803 for( i = X->n; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000804 {
Paul Bakker23986e52011-04-24 08:57:21 +0000805 r1 = X->p[i - 1] << (biL - v1);
806 X->p[i - 1] >>= v1;
807 X->p[i - 1] |= r0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000808 r0 = r1;
809 }
810 }
811
812 return( 0 );
813}
814
815/*
816 * Compare unsigned values
817 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000818int mpi_cmp_abs( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000819{
Paul Bakker23986e52011-04-24 08:57:21 +0000820 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000821
Paul Bakker23986e52011-04-24 08:57:21 +0000822 for( i = X->n; i > 0; i-- )
823 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000824 break;
825
Paul Bakker23986e52011-04-24 08:57:21 +0000826 for( j = Y->n; j > 0; j-- )
827 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000828 break;
829
Paul Bakker23986e52011-04-24 08:57:21 +0000830 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000831 return( 0 );
832
833 if( i > j ) return( 1 );
834 if( j > i ) return( -1 );
835
Paul Bakker23986e52011-04-24 08:57:21 +0000836 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000837 {
Paul Bakker23986e52011-04-24 08:57:21 +0000838 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
839 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000840 }
841
842 return( 0 );
843}
844
845/*
846 * Compare signed values
847 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000848int mpi_cmp_mpi( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000849{
Paul Bakker23986e52011-04-24 08:57:21 +0000850 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000851
Paul Bakker23986e52011-04-24 08:57:21 +0000852 for( i = X->n; i > 0; i-- )
853 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000854 break;
855
Paul Bakker23986e52011-04-24 08:57:21 +0000856 for( j = Y->n; j > 0; j-- )
857 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000858 break;
859
Paul Bakker23986e52011-04-24 08:57:21 +0000860 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000861 return( 0 );
862
863 if( i > j ) return( X->s );
Paul Bakker0c8f73b2012-03-22 14:08:57 +0000864 if( j > i ) return( -Y->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000865
866 if( X->s > 0 && Y->s < 0 ) return( 1 );
867 if( Y->s > 0 && X->s < 0 ) return( -1 );
868
Paul Bakker23986e52011-04-24 08:57:21 +0000869 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000870 {
Paul Bakker23986e52011-04-24 08:57:21 +0000871 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
872 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000873 }
874
875 return( 0 );
876}
877
878/*
879 * Compare signed values
880 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000881int mpi_cmp_int( const mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000882{
883 mpi Y;
Paul Bakkera755ca12011-04-24 09:11:17 +0000884 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000885
886 *p = ( z < 0 ) ? -z : z;
887 Y.s = ( z < 0 ) ? -1 : 1;
888 Y.n = 1;
889 Y.p = p;
890
891 return( mpi_cmp_mpi( X, &Y ) );
892}
893
894/*
895 * Unsigned addition: X = |A| + |B| (HAC 14.7)
896 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000897int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000898{
Paul Bakker23986e52011-04-24 08:57:21 +0000899 int ret;
900 size_t i, j;
Manuel Pégourié-Gonnardfaae6d22016-01-08 15:24:46 +0100901 t_uint *o, *p, c, tmp;
Paul Bakker5121ce52009-01-03 21:22:43 +0000902
903 if( X == B )
904 {
Janos Follath2db440d2015-10-30 17:43:11 +0100905 const mpi *T = A; A = X; B = T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000906 }
907
908 if( X != A )
909 MPI_CHK( mpi_copy( X, A ) );
Paul Bakker9af723c2014-05-01 13:03:14 +0200910
Paul Bakkerf7ca7b92009-06-20 10:31:06 +0000911 /*
912 * X should always be positive as a result of unsigned additions.
913 */
914 X->s = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000915
Paul Bakker23986e52011-04-24 08:57:21 +0000916 for( j = B->n; j > 0; j-- )
917 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000918 break;
919
Paul Bakker23986e52011-04-24 08:57:21 +0000920 MPI_CHK( mpi_grow( X, j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000921
922 o = B->p; p = X->p; c = 0;
923
Janos Follath2db440d2015-10-30 17:43:11 +0100924 /*
925 * tmp is used because it might happen that p == o
926 */
Paul Bakker23986e52011-04-24 08:57:21 +0000927 for( i = 0; i < j; i++, o++, p++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000928 {
Janos Follath2db440d2015-10-30 17:43:11 +0100929 tmp= *o;
Paul Bakker5121ce52009-01-03 21:22:43 +0000930 *p += c; c = ( *p < c );
Janos Follath2db440d2015-10-30 17:43:11 +0100931 *p += tmp; c += ( *p < tmp );
Paul Bakker5121ce52009-01-03 21:22:43 +0000932 }
933
934 while( c != 0 )
935 {
936 if( i >= X->n )
937 {
938 MPI_CHK( mpi_grow( X, i + 1 ) );
939 p = X->p + i;
940 }
941
Paul Bakker2d319fd2012-09-16 21:34:26 +0000942 *p += c; c = ( *p < c ); i++; p++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000943 }
944
945cleanup:
Paul Bakker5121ce52009-01-03 21:22:43 +0000946 return( ret );
947}
948
949/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100950 * Helper for mpi subtraction
Paul Bakker5121ce52009-01-03 21:22:43 +0000951 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000952static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
Paul Bakker5121ce52009-01-03 21:22:43 +0000953{
Paul Bakker23986e52011-04-24 08:57:21 +0000954 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +0000955 t_uint c, z;
Paul Bakker5121ce52009-01-03 21:22:43 +0000956
957 for( i = c = 0; i < n; i++, s++, d++ )
958 {
959 z = ( *d < c ); *d -= c;
960 c = ( *d < *s ) + z; *d -= *s;
961 }
962
963 while( c != 0 )
964 {
965 z = ( *d < c ); *d -= c;
966 c = z; i++; d++;
967 }
968}
969
970/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100971 * Unsigned subtraction: X = |A| - |B| (HAC 14.9)
Paul Bakker5121ce52009-01-03 21:22:43 +0000972 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000973int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000974{
975 mpi TB;
Paul Bakker23986e52011-04-24 08:57:21 +0000976 int ret;
977 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000978
979 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000980 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000981
Paul Bakker6c591fa2011-05-05 11:49:20 +0000982 mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000983
984 if( X == B )
985 {
986 MPI_CHK( mpi_copy( &TB, B ) );
987 B = &TB;
988 }
989
990 if( X != A )
991 MPI_CHK( mpi_copy( X, A ) );
992
Paul Bakker1ef7a532009-06-20 10:50:55 +0000993 /*
Paul Bakker60b1d102013-10-29 10:02:51 +0100994 * X should always be positive as a result of unsigned subtractions.
Paul Bakker1ef7a532009-06-20 10:50:55 +0000995 */
996 X->s = 1;
997
Paul Bakker5121ce52009-01-03 21:22:43 +0000998 ret = 0;
999
Paul Bakker23986e52011-04-24 08:57:21 +00001000 for( n = B->n; n > 0; n-- )
1001 if( B->p[n - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001002 break;
1003
Paul Bakker23986e52011-04-24 08:57:21 +00001004 mpi_sub_hlp( n, B->p, X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +00001005
1006cleanup:
1007
Paul Bakker6c591fa2011-05-05 11:49:20 +00001008 mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001009
1010 return( ret );
1011}
1012
1013/*
1014 * Signed addition: X = A + B
1015 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001016int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001017{
1018 int ret, s = A->s;
1019
1020 if( A->s * B->s < 0 )
1021 {
1022 if( mpi_cmp_abs( A, B ) >= 0 )
1023 {
1024 MPI_CHK( mpi_sub_abs( X, A, B ) );
1025 X->s = s;
1026 }
1027 else
1028 {
1029 MPI_CHK( mpi_sub_abs( X, B, A ) );
1030 X->s = -s;
1031 }
1032 }
1033 else
1034 {
1035 MPI_CHK( mpi_add_abs( X, A, B ) );
1036 X->s = s;
1037 }
1038
1039cleanup:
1040
1041 return( ret );
1042}
1043
1044/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001045 * Signed subtraction: X = A - B
Paul Bakker5121ce52009-01-03 21:22:43 +00001046 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001047int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001048{
1049 int ret, s = A->s;
1050
1051 if( A->s * B->s > 0 )
1052 {
1053 if( mpi_cmp_abs( A, B ) >= 0 )
1054 {
1055 MPI_CHK( mpi_sub_abs( X, A, B ) );
1056 X->s = s;
1057 }
1058 else
1059 {
1060 MPI_CHK( mpi_sub_abs( X, B, A ) );
1061 X->s = -s;
1062 }
1063 }
1064 else
1065 {
1066 MPI_CHK( mpi_add_abs( X, A, B ) );
1067 X->s = s;
1068 }
1069
1070cleanup:
1071
1072 return( ret );
1073}
1074
1075/*
1076 * Signed addition: X = A + b
1077 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001078int mpi_add_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001079{
1080 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001081 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001082
1083 p[0] = ( b < 0 ) ? -b : b;
1084 _B.s = ( b < 0 ) ? -1 : 1;
1085 _B.n = 1;
1086 _B.p = p;
1087
1088 return( mpi_add_mpi( X, A, &_B ) );
1089}
1090
1091/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001092 * Signed subtraction: X = A - b
Paul Bakker5121ce52009-01-03 21:22:43 +00001093 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001094int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001095{
1096 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001097 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001098
1099 p[0] = ( b < 0 ) ? -b : b;
1100 _B.s = ( b < 0 ) ? -1 : 1;
1101 _B.n = 1;
1102 _B.p = p;
1103
1104 return( mpi_sub_mpi( X, A, &_B ) );
1105}
1106
1107/*
1108 * Helper for mpi multiplication
Paul Bakkerfc4f46f2013-06-24 19:23:56 +02001109 */
1110static
1111#if defined(__APPLE__) && defined(__arm__)
1112/*
1113 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1114 * appears to need this to prevent bad ARM code generation at -O3.
1115 */
1116__attribute__ ((noinline))
1117#endif
1118void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001119{
Paul Bakkera755ca12011-04-24 09:11:17 +00001120 t_uint c = 0, t = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001121
1122#if defined(MULADDC_HUIT)
1123 for( ; i >= 8; i -= 8 )
1124 {
1125 MULADDC_INIT
1126 MULADDC_HUIT
1127 MULADDC_STOP
1128 }
1129
1130 for( ; i > 0; i-- )
1131 {
1132 MULADDC_INIT
1133 MULADDC_CORE
1134 MULADDC_STOP
1135 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001136#else /* MULADDC_HUIT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001137 for( ; i >= 16; i -= 16 )
1138 {
1139 MULADDC_INIT
1140 MULADDC_CORE MULADDC_CORE
1141 MULADDC_CORE MULADDC_CORE
1142 MULADDC_CORE MULADDC_CORE
1143 MULADDC_CORE MULADDC_CORE
1144
1145 MULADDC_CORE MULADDC_CORE
1146 MULADDC_CORE MULADDC_CORE
1147 MULADDC_CORE MULADDC_CORE
1148 MULADDC_CORE MULADDC_CORE
1149 MULADDC_STOP
1150 }
1151
1152 for( ; i >= 8; i -= 8 )
1153 {
1154 MULADDC_INIT
1155 MULADDC_CORE MULADDC_CORE
1156 MULADDC_CORE MULADDC_CORE
1157
1158 MULADDC_CORE MULADDC_CORE
1159 MULADDC_CORE MULADDC_CORE
1160 MULADDC_STOP
1161 }
1162
1163 for( ; i > 0; i-- )
1164 {
1165 MULADDC_INIT
1166 MULADDC_CORE
1167 MULADDC_STOP
1168 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001169#endif /* MULADDC_HUIT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001170
1171 t++;
1172
1173 do {
1174 *d += c; c = ( *d < c ); d++;
1175 }
1176 while( c != 0 );
1177}
1178
1179/*
1180 * Baseline multiplication: X = A * B (HAC 14.12)
1181 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001182int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001183{
Paul Bakker23986e52011-04-24 08:57:21 +00001184 int ret;
1185 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00001186 mpi TA, TB;
1187
Paul Bakker6c591fa2011-05-05 11:49:20 +00001188 mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001189
1190 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
1191 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
1192
Paul Bakker23986e52011-04-24 08:57:21 +00001193 for( i = A->n; i > 0; i-- )
1194 if( A->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001195 break;
1196
Paul Bakker23986e52011-04-24 08:57:21 +00001197 for( j = B->n; j > 0; j-- )
1198 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001199 break;
1200
Paul Bakker23986e52011-04-24 08:57:21 +00001201 MPI_CHK( mpi_grow( X, i + j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001202 MPI_CHK( mpi_lset( X, 0 ) );
1203
Paul Bakker23986e52011-04-24 08:57:21 +00001204 for( i++; j > 0; j-- )
1205 mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001206
1207 X->s = A->s * B->s;
1208
1209cleanup:
1210
Paul Bakker6c591fa2011-05-05 11:49:20 +00001211 mpi_free( &TB ); mpi_free( &TA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001212
1213 return( ret );
1214}
1215
1216/*
1217 * Baseline multiplication: X = A * b
1218 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001219int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001220{
1221 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001222 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001223
1224 _B.s = 1;
1225 _B.n = 1;
1226 _B.p = p;
1227 p[0] = b;
1228
1229 return( mpi_mul_mpi( X, A, &_B ) );
1230}
1231
1232/*
Simon Butcher14400c82016-01-02 00:08:13 +00001233 * Unsigned integer divide - double t_uint, dividend, u1/u0, and t_uint
1234 * divisor, d
Simon Butchere4ed3472015-12-22 15:26:57 +00001235 */
Simon Butcher14400c82016-01-02 00:08:13 +00001236static t_uint int_div_int( t_uint u1, t_uint u0, t_uint d, t_uint *r )
Simon Butchere4ed3472015-12-22 15:26:57 +00001237{
1238#if defined(POLARSSL_HAVE_UDBL)
1239 t_udbl dividend, quotient;
Simon Butcher14400c82016-01-02 00:08:13 +00001240#else
Simon Butcherd7fe6fb2016-01-03 22:39:18 +00001241 const t_uint radix = (t_uint) 1 << biH;
1242 const t_uint uint_halfword_mask = ( (t_uint) 1 << biH ) - 1;
Simon Butcher14400c82016-01-02 00:08:13 +00001243 t_uint d0, d1, q0, q1, rAX, r0, quotient;
1244 t_uint u0_msw, u0_lsw;
Simon Butcherd7fe6fb2016-01-03 22:39:18 +00001245 size_t s;
Simon Butchere4ed3472015-12-22 15:26:57 +00001246#endif
1247
1248 /*
1249 * Check for overflow
1250 */
Simon Butcher14400c82016-01-02 00:08:13 +00001251 if( 0 == d || u1 >= d )
Simon Butchere4ed3472015-12-22 15:26:57 +00001252 {
Simon Butcher14400c82016-01-02 00:08:13 +00001253 if ( r != NULL ) *r = ~0;
Simon Butchere4ed3472015-12-22 15:26:57 +00001254
Simon Butcher14400c82016-01-02 00:08:13 +00001255 return ( ~0 );
Simon Butchere4ed3472015-12-22 15:26:57 +00001256 }
1257
1258#if defined(POLARSSL_HAVE_UDBL)
1259 dividend = (t_udbl) u1 << biL;
1260 dividend |= (t_udbl) u0;
1261 quotient = dividend / d;
1262 if( quotient > ( (t_udbl) 1 << biL ) - 1 )
1263 quotient = ( (t_udbl) 1 << biL ) - 1;
1264
1265 if( r != NULL )
Simon Butcherd7fe6fb2016-01-03 22:39:18 +00001266 *r = (t_uint)( dividend - (quotient * d ) );
Simon Butchere4ed3472015-12-22 15:26:57 +00001267
1268 return (t_uint) quotient;
1269#else
Simon Butchere4ed3472015-12-22 15:26:57 +00001270
1271 /*
1272 * Algorithm D, Section 4.3.1 - The Art of Computer Programming
1273 * Vol. 2 - Seminumerical Algorithms, Knuth
1274 */
1275
1276 /*
1277 * Normalize the divisor, d, and dividend, u0, u1
1278 */
1279 s = int_clz( d );
1280 d = d << s;
1281
1282 u1 = u1 << s;
Simon Butcherd7fe6fb2016-01-03 22:39:18 +00001283 u1 |= ( u0 >> ( biL - s ) ) & ( -(t_sint)s >> ( biL - 1 ) );
Simon Butchere4ed3472015-12-22 15:26:57 +00001284 u0 = u0 << s;
1285
1286 d1 = d >> biH;
Simon Butcherd7fe6fb2016-01-03 22:39:18 +00001287 d0 = d & uint_halfword_mask;
Simon Butchere4ed3472015-12-22 15:26:57 +00001288
1289 u0_msw = u0 >> biH;
Simon Butcherd7fe6fb2016-01-03 22:39:18 +00001290 u0_lsw = u0 & uint_halfword_mask;
Simon Butchere4ed3472015-12-22 15:26:57 +00001291
1292 /*
1293 * Find the first quotient and remainder
1294 */
1295 q1 = u1 / d1;
1296 r0 = u1 - d1 * q1;
1297
1298 while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) )
1299 {
1300 q1 -= 1;
1301 r0 += d1;
1302
1303 if ( r0 >= radix ) break;
1304 }
1305
Simon Butcher14400c82016-01-02 00:08:13 +00001306 rAX = ( u1 * radix ) + ( u0_msw - q1 * d );
Simon Butchere4ed3472015-12-22 15:26:57 +00001307 q0 = rAX / d1;
1308 r0 = rAX - q0 * d1;
1309
1310 while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) )
1311 {
1312 q0 -= 1;
1313 r0 += d1;
1314
1315 if ( r0 >= radix ) break;
1316 }
1317
1318 if (r != NULL)
Simon Butcher14400c82016-01-02 00:08:13 +00001319 *r = ( rAX * radix + u0_lsw - q0 * d ) >> s;
Simon Butchere4ed3472015-12-22 15:26:57 +00001320
1321 quotient = q1 * radix + q0;
1322
1323 return quotient;
1324#endif
1325}
1326
1327/*
Paul Bakker5121ce52009-01-03 21:22:43 +00001328 * Division by mpi: A = Q * B + R (HAC 14.20)
1329 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001330int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001331{
Paul Bakker23986e52011-04-24 08:57:21 +00001332 int ret;
1333 size_t i, n, t, k;
Paul Bakker5121ce52009-01-03 21:22:43 +00001334 mpi X, Y, Z, T1, T2;
1335
1336 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001337 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001338
Paul Bakker6c591fa2011-05-05 11:49:20 +00001339 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
1340 mpi_init( &T1 ); mpi_init( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001341
1342 if( mpi_cmp_abs( A, B ) < 0 )
1343 {
1344 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1345 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1346 return( 0 );
1347 }
1348
1349 MPI_CHK( mpi_copy( &X, A ) );
1350 MPI_CHK( mpi_copy( &Y, B ) );
1351 X.s = Y.s = 1;
1352
1353 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1354 MPI_CHK( mpi_lset( &Z, 0 ) );
1355 MPI_CHK( mpi_grow( &T1, 2 ) );
1356 MPI_CHK( mpi_grow( &T2, 3 ) );
1357
1358 k = mpi_msb( &Y ) % biL;
Paul Bakkerf9688572011-05-05 10:00:45 +00001359 if( k < biL - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001360 {
1361 k = biL - 1 - k;
1362 MPI_CHK( mpi_shift_l( &X, k ) );
1363 MPI_CHK( mpi_shift_l( &Y, k ) );
1364 }
1365 else k = 0;
1366
1367 n = X.n - 1;
1368 t = Y.n - 1;
Paul Bakker66d5d072014-06-17 16:39:18 +02001369 MPI_CHK( mpi_shift_l( &Y, biL * ( n - t ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001370
1371 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1372 {
1373 Z.p[n - t]++;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001374 MPI_CHK( mpi_sub_mpi( &X, &X, &Y ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001375 }
Paul Bakker66d5d072014-06-17 16:39:18 +02001376 MPI_CHK( mpi_shift_r( &Y, biL * ( n - t ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001377
1378 for( i = n; i > t ; i-- )
1379 {
1380 if( X.p[i] >= Y.p[t] )
1381 Z.p[i - t - 1] = ~0;
1382 else
1383 {
Simon Butchere4ed3472015-12-22 15:26:57 +00001384 Z.p[i - t - 1] = int_div_int( X.p[i], X.p[i - 1], Y.p[t], NULL);
Paul Bakker5121ce52009-01-03 21:22:43 +00001385 }
1386
1387 Z.p[i - t - 1]++;
1388 do
1389 {
1390 Z.p[i - t - 1]--;
1391
1392 MPI_CHK( mpi_lset( &T1, 0 ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001393 T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001394 T1.p[1] = Y.p[t];
1395 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1396
1397 MPI_CHK( mpi_lset( &T2, 0 ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001398 T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
1399 T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001400 T2.p[2] = X.p[i];
1401 }
1402 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1403
1404 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001405 MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001406 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1407
1408 if( mpi_cmp_int( &X, 0 ) < 0 )
1409 {
1410 MPI_CHK( mpi_copy( &T1, &Y ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001411 MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001412 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1413 Z.p[i - t - 1]--;
1414 }
1415 }
1416
1417 if( Q != NULL )
1418 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001419 MPI_CHK( mpi_copy( Q, &Z ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001420 Q->s = A->s * B->s;
1421 }
1422
1423 if( R != NULL )
1424 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001425 MPI_CHK( mpi_shift_r( &X, k ) );
Paul Bakkerf02c5642012-11-13 10:25:21 +00001426 X.s = A->s;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001427 MPI_CHK( mpi_copy( R, &X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001428
Paul Bakker5121ce52009-01-03 21:22:43 +00001429 if( mpi_cmp_int( R, 0 ) == 0 )
1430 R->s = 1;
1431 }
1432
1433cleanup:
1434
Paul Bakker6c591fa2011-05-05 11:49:20 +00001435 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
1436 mpi_free( &T1 ); mpi_free( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001437
1438 return( ret );
1439}
1440
1441/*
1442 * Division by int: A = Q * b + R
Paul Bakker5121ce52009-01-03 21:22:43 +00001443 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001444int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001445{
1446 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001447 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001448
1449 p[0] = ( b < 0 ) ? -b : b;
1450 _B.s = ( b < 0 ) ? -1 : 1;
1451 _B.n = 1;
1452 _B.p = p;
1453
1454 return( mpi_div_mpi( Q, R, A, &_B ) );
1455}
1456
1457/*
1458 * Modulo: R = A mod B
1459 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001460int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001461{
1462 int ret;
1463
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001464 if( mpi_cmp_int( B, 0 ) < 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001465 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001466
Paul Bakker5121ce52009-01-03 21:22:43 +00001467 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1468
1469 while( mpi_cmp_int( R, 0 ) < 0 )
1470 MPI_CHK( mpi_add_mpi( R, R, B ) );
1471
1472 while( mpi_cmp_mpi( R, B ) >= 0 )
1473 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1474
1475cleanup:
1476
1477 return( ret );
1478}
1479
1480/*
1481 * Modulo: r = A mod b
1482 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001483int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001484{
Paul Bakker23986e52011-04-24 08:57:21 +00001485 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +00001486 t_uint x, y, z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001487
1488 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001489 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001490
1491 if( b < 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001492 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001493
1494 /*
1495 * handle trivial cases
1496 */
1497 if( b == 1 )
1498 {
1499 *r = 0;
1500 return( 0 );
1501 }
1502
1503 if( b == 2 )
1504 {
1505 *r = A->p[0] & 1;
1506 return( 0 );
1507 }
1508
1509 /*
1510 * general case
1511 */
Paul Bakker23986e52011-04-24 08:57:21 +00001512 for( i = A->n, y = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001513 {
Paul Bakker23986e52011-04-24 08:57:21 +00001514 x = A->p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001515 y = ( y << biH ) | ( x >> biH );
1516 z = y / b;
1517 y -= z * b;
1518
1519 x <<= biH;
1520 y = ( y << biH ) | ( x >> biH );
1521 z = y / b;
1522 y -= z * b;
1523 }
1524
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001525 /*
1526 * If A is negative, then the current y represents a negative value.
1527 * Flipping it to the positive side.
1528 */
1529 if( A->s < 0 && y != 0 )
1530 y = b - y;
1531
Paul Bakker5121ce52009-01-03 21:22:43 +00001532 *r = y;
1533
1534 return( 0 );
1535}
1536
1537/*
1538 * Fast Montgomery initialization (thanks to Tom St Denis)
1539 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001540static void mpi_montg_init( t_uint *mm, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001541{
Paul Bakkera755ca12011-04-24 09:11:17 +00001542 t_uint x, m0 = N->p[0];
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001543 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001544
1545 x = m0;
1546 x += ( ( m0 + 2 ) & 4 ) << 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001547
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001548 for( i = biL; i >= 8; i /= 2 )
1549 x *= ( 2 - ( m0 * x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001550
1551 *mm = ~x + 1;
1552}
1553
1554/*
1555 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1556 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +02001557static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm,
1558 const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001559{
Paul Bakker23986e52011-04-24 08:57:21 +00001560 size_t i, n, m;
Paul Bakkera755ca12011-04-24 09:11:17 +00001561 t_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00001562
1563 memset( T->p, 0, T->n * ciL );
1564
1565 d = T->p;
1566 n = N->n;
1567 m = ( B->n < n ) ? B->n : n;
1568
1569 for( i = 0; i < n; i++ )
1570 {
1571 /*
1572 * T = (T + u0*B + u1*N) / 2^biL
1573 */
1574 u0 = A->p[i];
1575 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1576
1577 mpi_mul_hlp( m, B->p, d, u0 );
1578 mpi_mul_hlp( n, N->p, d, u1 );
1579
1580 *d++ = u0; d[n + 1] = 0;
1581 }
1582
Paul Bakker66d5d072014-06-17 16:39:18 +02001583 memcpy( A->p, d, ( n + 1 ) * ciL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001584
1585 if( mpi_cmp_abs( A, N ) >= 0 )
1586 mpi_sub_hlp( n, N->p, A->p );
1587 else
1588 /* prevent timing attacks */
1589 mpi_sub_hlp( n, A->p, T->p );
1590}
1591
1592/*
1593 * Montgomery reduction: A = A * R^-1 mod N
1594 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001595static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001596{
Paul Bakkera755ca12011-04-24 09:11:17 +00001597 t_uint z = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001598 mpi U;
1599
Paul Bakker8ddb6452013-02-27 14:56:33 +01001600 U.n = U.s = (int) z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001601 U.p = &z;
1602
1603 mpi_montmul( A, &U, N, mm, T );
1604}
1605
1606/*
1607 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1608 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001609int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00001610{
Paul Bakker23986e52011-04-24 08:57:21 +00001611 int ret;
1612 size_t wbits, wsize, one = 1;
1613 size_t i, j, nblimbs;
1614 size_t bufsize, nbits;
Paul Bakkera755ca12011-04-24 09:11:17 +00001615 t_uint ei, mm, state;
Paul Bakkerf6198c12012-05-16 08:02:29 +00001616 mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos;
1617 int neg;
Paul Bakker5121ce52009-01-03 21:22:43 +00001618
1619 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001620 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001621
Paul Bakkerf6198c12012-05-16 08:02:29 +00001622 if( mpi_cmp_int( E, 0 ) < 0 )
1623 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
1624
1625 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001626 * Init temps and window size
1627 */
1628 mpi_montg_init( &mm, N );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001629 mpi_init( &RR ); mpi_init( &T );
Manuel Pégourié-Gonnardfd6a1912014-01-18 19:05:23 +01001630 mpi_init( &Apos );
Paul Bakker5121ce52009-01-03 21:22:43 +00001631 memset( W, 0, sizeof( W ) );
1632
1633 i = mpi_msb( E );
1634
1635 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1636 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1637
Paul Bakkerb6d5f082011-11-25 11:52:11 +00001638 if( wsize > POLARSSL_MPI_WINDOW_SIZE )
1639 wsize = POLARSSL_MPI_WINDOW_SIZE;
1640
Paul Bakker5121ce52009-01-03 21:22:43 +00001641 j = N->n + 1;
1642 MPI_CHK( mpi_grow( X, j ) );
1643 MPI_CHK( mpi_grow( &W[1], j ) );
1644 MPI_CHK( mpi_grow( &T, j * 2 ) );
1645
1646 /*
Paul Bakker50546922012-05-19 08:40:49 +00001647 * Compensate for negative A (and correct at the end)
1648 */
1649 neg = ( A->s == -1 );
Paul Bakker50546922012-05-19 08:40:49 +00001650 if( neg )
1651 {
1652 MPI_CHK( mpi_copy( &Apos, A ) );
1653 Apos.s = 1;
1654 A = &Apos;
1655 }
1656
1657 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001658 * If 1st call, pre-compute R^2 mod N
1659 */
1660 if( _RR == NULL || _RR->p == NULL )
1661 {
1662 MPI_CHK( mpi_lset( &RR, 1 ) );
1663 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1664 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1665
1666 if( _RR != NULL )
1667 memcpy( _RR, &RR, sizeof( mpi ) );
1668 }
1669 else
1670 memcpy( &RR, _RR, sizeof( mpi ) );
1671
1672 /*
1673 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1674 */
1675 if( mpi_cmp_mpi( A, N ) >= 0 )
Paul Bakkerc2024f42014-01-23 20:38:35 +01001676 MPI_CHK( mpi_mod_mpi( &W[1], A, N ) );
1677 else
1678 MPI_CHK( mpi_copy( &W[1], A ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001679
1680 mpi_montmul( &W[1], &RR, N, mm, &T );
1681
1682 /*
1683 * X = R^2 * R^-1 mod N = R mod N
1684 */
1685 MPI_CHK( mpi_copy( X, &RR ) );
1686 mpi_montred( X, N, mm, &T );
1687
1688 if( wsize > 1 )
1689 {
1690 /*
1691 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1692 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001693 j = one << ( wsize - 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001694
1695 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1696 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1697
1698 for( i = 0; i < wsize - 1; i++ )
1699 mpi_montmul( &W[j], &W[j], N, mm, &T );
Paul Bakker0d7702c2013-10-29 16:18:35 +01001700
Paul Bakker5121ce52009-01-03 21:22:43 +00001701 /*
1702 * W[i] = W[i - 1] * W[1]
1703 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001704 for( i = j + 1; i < ( one << wsize ); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001705 {
1706 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1707 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1708
1709 mpi_montmul( &W[i], &W[1], N, mm, &T );
1710 }
1711 }
1712
1713 nblimbs = E->n;
1714 bufsize = 0;
1715 nbits = 0;
1716 wbits = 0;
1717 state = 0;
1718
1719 while( 1 )
1720 {
1721 if( bufsize == 0 )
1722 {
Paul Bakker0d7702c2013-10-29 16:18:35 +01001723 if( nblimbs == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001724 break;
1725
Paul Bakker0d7702c2013-10-29 16:18:35 +01001726 nblimbs--;
1727
Paul Bakkera755ca12011-04-24 09:11:17 +00001728 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001729 }
1730
1731 bufsize--;
1732
1733 ei = (E->p[nblimbs] >> bufsize) & 1;
1734
1735 /*
1736 * skip leading 0s
1737 */
1738 if( ei == 0 && state == 0 )
1739 continue;
1740
1741 if( ei == 0 && state == 1 )
1742 {
1743 /*
1744 * out of window, square X
1745 */
1746 mpi_montmul( X, X, N, mm, &T );
1747 continue;
1748 }
1749
1750 /*
1751 * add ei to current window
1752 */
1753 state = 2;
1754
1755 nbits++;
Paul Bakker66d5d072014-06-17 16:39:18 +02001756 wbits |= ( ei << ( wsize - nbits ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001757
1758 if( nbits == wsize )
1759 {
1760 /*
1761 * X = X^wsize R^-1 mod N
1762 */
1763 for( i = 0; i < wsize; i++ )
1764 mpi_montmul( X, X, N, mm, &T );
1765
1766 /*
1767 * X = X * W[wbits] R^-1 mod N
1768 */
1769 mpi_montmul( X, &W[wbits], N, mm, &T );
1770
1771 state--;
1772 nbits = 0;
1773 wbits = 0;
1774 }
1775 }
1776
1777 /*
1778 * process the remaining bits
1779 */
1780 for( i = 0; i < nbits; i++ )
1781 {
1782 mpi_montmul( X, X, N, mm, &T );
1783
1784 wbits <<= 1;
1785
Paul Bakker66d5d072014-06-17 16:39:18 +02001786 if( ( wbits & ( one << wsize ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001787 mpi_montmul( X, &W[1], N, mm, &T );
1788 }
1789
1790 /*
1791 * X = A^E * R * R^-1 mod N = A^E mod N
1792 */
1793 mpi_montred( X, N, mm, &T );
1794
Hanno Becker88bbab22017-05-11 15:57:15 +01001795 if( neg && E->n != 0 && ( E->p[0] & 1 ) != 0 )
Paul Bakkerf6198c12012-05-16 08:02:29 +00001796 {
1797 X->s = -1;
Paul Bakkerc2024f42014-01-23 20:38:35 +01001798 MPI_CHK( mpi_add_mpi( X, N, X ) );
Paul Bakkerf6198c12012-05-16 08:02:29 +00001799 }
1800
Paul Bakker5121ce52009-01-03 21:22:43 +00001801cleanup:
1802
Paul Bakker66d5d072014-06-17 16:39:18 +02001803 for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001804 mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001805
Paul Bakkerf6198c12012-05-16 08:02:29 +00001806 mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001807
Paul Bakker75a28602014-03-31 12:08:17 +02001808 if( _RR == NULL || _RR->p == NULL )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001809 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001810
1811 return( ret );
1812}
1813
Paul Bakker5121ce52009-01-03 21:22:43 +00001814/*
1815 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1816 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001817int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001818{
Paul Bakker23986e52011-04-24 08:57:21 +00001819 int ret;
1820 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001821 mpi TG, TA, TB;
1822
Paul Bakker6c591fa2011-05-05 11:49:20 +00001823 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001824
Paul Bakker5121ce52009-01-03 21:22:43 +00001825 MPI_CHK( mpi_copy( &TA, A ) );
1826 MPI_CHK( mpi_copy( &TB, B ) );
1827
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001828 lz = mpi_lsb( &TA );
1829 lzt = mpi_lsb( &TB );
1830
Paul Bakker66d5d072014-06-17 16:39:18 +02001831 if( lzt < lz )
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001832 lz = lzt;
1833
1834 MPI_CHK( mpi_shift_r( &TA, lz ) );
1835 MPI_CHK( mpi_shift_r( &TB, lz ) );
1836
Paul Bakker5121ce52009-01-03 21:22:43 +00001837 TA.s = TB.s = 1;
1838
1839 while( mpi_cmp_int( &TA, 0 ) != 0 )
1840 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001841 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1842 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001843
1844 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1845 {
1846 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1847 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1848 }
1849 else
1850 {
1851 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1852 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1853 }
1854 }
1855
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001856 MPI_CHK( mpi_shift_l( &TB, lz ) );
1857 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001858
1859cleanup:
1860
Paul Bakker6c591fa2011-05-05 11:49:20 +00001861 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001862
1863 return( ret );
1864}
1865
Paul Bakker33dc46b2014-04-30 16:11:39 +02001866/*
1867 * Fill X with size bytes of random.
1868 *
1869 * Use a temporary bytes representation to make sure the result is the same
Paul Bakkerc37b0ac2014-05-01 14:19:23 +02001870 * regardless of the platform endianness (useful when f_rng is actually
Paul Bakker33dc46b2014-04-30 16:11:39 +02001871 * deterministic, eg for tests).
1872 */
Paul Bakkera3d195c2011-11-27 21:07:34 +00001873int mpi_fill_random( mpi *X, size_t size,
1874 int (*f_rng)(void *, unsigned char *, size_t),
1875 void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001876{
Paul Bakker23986e52011-04-24 08:57:21 +00001877 int ret;
Paul Bakker33dc46b2014-04-30 16:11:39 +02001878 unsigned char buf[POLARSSL_MPI_MAX_SIZE];
1879
1880 if( size > POLARSSL_MPI_MAX_SIZE )
1881 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker287781a2011-03-26 13:18:49 +00001882
Paul Bakker33dc46b2014-04-30 16:11:39 +02001883 MPI_CHK( f_rng( p_rng, buf, size ) );
1884 MPI_CHK( mpi_read_binary( X, buf, size ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001885
1886cleanup:
Hanno Beckerc2102892017-10-25 16:09:08 +01001887 polarssl_zeroize( buf, sizeof( buf ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001888 return( ret );
1889}
1890
Paul Bakker5121ce52009-01-03 21:22:43 +00001891/*
1892 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1893 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001894int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001895{
1896 int ret;
1897 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1898
Hanno Becker1c6339f2017-05-11 15:59:11 +01001899 if( mpi_cmp_int( N, 1 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001900 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001901
Paul Bakker6c591fa2011-05-05 11:49:20 +00001902 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1903 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1904 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001905
1906 MPI_CHK( mpi_gcd( &G, A, N ) );
1907
1908 if( mpi_cmp_int( &G, 1 ) != 0 )
1909 {
Paul Bakker40e46942009-01-03 21:51:57 +00001910 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001911 goto cleanup;
1912 }
1913
1914 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1915 MPI_CHK( mpi_copy( &TU, &TA ) );
1916 MPI_CHK( mpi_copy( &TB, N ) );
1917 MPI_CHK( mpi_copy( &TV, N ) );
1918
1919 MPI_CHK( mpi_lset( &U1, 1 ) );
1920 MPI_CHK( mpi_lset( &U2, 0 ) );
1921 MPI_CHK( mpi_lset( &V1, 0 ) );
1922 MPI_CHK( mpi_lset( &V2, 1 ) );
1923
1924 do
1925 {
1926 while( ( TU.p[0] & 1 ) == 0 )
1927 {
1928 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1929
1930 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1931 {
1932 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1933 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1934 }
1935
1936 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1937 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1938 }
1939
1940 while( ( TV.p[0] & 1 ) == 0 )
1941 {
1942 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1943
1944 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1945 {
1946 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1947 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1948 }
1949
1950 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1951 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1952 }
1953
1954 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1955 {
1956 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1957 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1958 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1959 }
1960 else
1961 {
1962 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1963 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1964 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1965 }
1966 }
1967 while( mpi_cmp_int( &TU, 0 ) != 0 );
1968
1969 while( mpi_cmp_int( &V1, 0 ) < 0 )
1970 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1971
1972 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1973 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1974
1975 MPI_CHK( mpi_copy( X, &V1 ) );
1976
1977cleanup:
1978
Paul Bakker6c591fa2011-05-05 11:49:20 +00001979 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1980 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1981 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001982
1983 return( ret );
1984}
1985
Paul Bakkerd9374b02012-11-02 11:02:58 +00001986#if defined(POLARSSL_GENPRIME)
1987
Paul Bakker5121ce52009-01-03 21:22:43 +00001988static const int small_prime[] =
1989{
1990 3, 5, 7, 11, 13, 17, 19, 23,
1991 29, 31, 37, 41, 43, 47, 53, 59,
1992 61, 67, 71, 73, 79, 83, 89, 97,
1993 101, 103, 107, 109, 113, 127, 131, 137,
1994 139, 149, 151, 157, 163, 167, 173, 179,
1995 181, 191, 193, 197, 199, 211, 223, 227,
1996 229, 233, 239, 241, 251, 257, 263, 269,
1997 271, 277, 281, 283, 293, 307, 311, 313,
1998 317, 331, 337, 347, 349, 353, 359, 367,
1999 373, 379, 383, 389, 397, 401, 409, 419,
2000 421, 431, 433, 439, 443, 449, 457, 461,
2001 463, 467, 479, 487, 491, 499, 503, 509,
2002 521, 523, 541, 547, 557, 563, 569, 571,
2003 577, 587, 593, 599, 601, 607, 613, 617,
2004 619, 631, 641, 643, 647, 653, 659, 661,
2005 673, 677, 683, 691, 701, 709, 719, 727,
2006 733, 739, 743, 751, 757, 761, 769, 773,
2007 787, 797, 809, 811, 821, 823, 827, 829,
2008 839, 853, 857, 859, 863, 877, 881, 883,
2009 887, 907, 911, 919, 929, 937, 941, 947,
2010 953, 967, 971, 977, 983, 991, 997, -103
2011};
2012
2013/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002014 * Small divisors test (X must be positive)
2015 *
2016 * Return values:
2017 * 0: no small factor (possible prime, more tests needed)
2018 * 1: certain prime
2019 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
2020 * other negative: error
Paul Bakker5121ce52009-01-03 21:22:43 +00002021 */
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002022static int mpi_check_small_factors( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +00002023{
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002024 int ret = 0;
2025 size_t i;
2026 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002027
Paul Bakker5121ce52009-01-03 21:22:43 +00002028 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00002029 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002030
2031 for( i = 0; small_prime[i] > 0; i++ )
2032 {
Paul Bakker5121ce52009-01-03 21:22:43 +00002033 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002034 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002035
2036 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
2037
2038 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00002039 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002040 }
2041
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002042cleanup:
2043 return( ret );
2044}
2045
2046/*
2047 * Miller-Rabin pseudo-primality test (HAC 4.24)
2048 */
2049static int mpi_miller_rabin( const mpi *X,
2050 int (*f_rng)(void *, unsigned char *, size_t),
2051 void *p_rng )
2052{
Pascal Junodb99183d2015-03-11 16:49:45 +01002053 int ret, count;
2054 size_t i, j, k, n, s;
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002055 mpi W, R, T, A, RR;
2056
2057 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
2058 mpi_init( &RR );
2059
Paul Bakker5121ce52009-01-03 21:22:43 +00002060 /*
2061 * W = |X| - 1
2062 * R = W >> lsb( W )
2063 */
Paul Bakker5121ce52009-01-03 21:22:43 +00002064 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00002065 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00002066 MPI_CHK( mpi_copy( &R, &W ) );
2067 MPI_CHK( mpi_shift_r( &R, s ) );
2068
2069 i = mpi_msb( X );
2070 /*
2071 * HAC, table 4.4
2072 */
2073 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
2074 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
2075 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
2076
2077 for( i = 0; i < n; i++ )
2078 {
2079 /*
2080 * pick a random A, 1 < A < |X| - 1
2081 */
Paul Bakker5121ce52009-01-03 21:22:43 +00002082
Pascal Junodb99183d2015-03-11 16:49:45 +01002083 count = 0;
2084 do {
2085 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
2086
2087 j = mpi_msb( &A );
2088 k = mpi_msb( &W );
2089 if (j > k) {
2090 MPI_CHK( mpi_shift_r( &A, j - k ) );
2091 }
2092
2093 if (count++ > 30) {
2094 return POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
2095 }
2096
2097 } while ( (mpi_cmp_mpi( &A, &W ) >= 0) ||
2098 (mpi_cmp_int( &A, 1 ) <= 0) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002099
2100 /*
2101 * A = A^R mod |X|
2102 */
2103 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
2104
2105 if( mpi_cmp_mpi( &A, &W ) == 0 ||
2106 mpi_cmp_int( &A, 1 ) == 0 )
2107 continue;
2108
2109 j = 1;
2110 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
2111 {
2112 /*
2113 * A = A * A mod |X|
2114 */
2115 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
2116 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
2117
2118 if( mpi_cmp_int( &A, 1 ) == 0 )
2119 break;
2120
2121 j++;
2122 }
2123
2124 /*
2125 * not prime if A != |X| - 1 or A == 1
2126 */
2127 if( mpi_cmp_mpi( &A, &W ) != 0 ||
2128 mpi_cmp_int( &A, 1 ) == 0 )
2129 {
Paul Bakker40e46942009-01-03 21:51:57 +00002130 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002131 break;
2132 }
2133 }
2134
2135cleanup:
Paul Bakker6c591fa2011-05-05 11:49:20 +00002136 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
2137 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002138
2139 return( ret );
2140}
2141
2142/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002143 * Pseudo-primality test: small factors, then Miller-Rabin
2144 */
Paul Bakker45f457d2013-11-25 14:26:52 +01002145int mpi_is_prime( mpi *X,
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002146 int (*f_rng)(void *, unsigned char *, size_t),
2147 void *p_rng )
2148{
2149 int ret;
Manuel Pégourié-Gonnard7f4ed672014-10-14 20:56:02 +02002150 mpi XX;
2151
2152 XX.s = 1;
2153 XX.n = X->n;
2154 XX.p = X->p;
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002155
2156 if( mpi_cmp_int( &XX, 0 ) == 0 ||
2157 mpi_cmp_int( &XX, 1 ) == 0 )
2158 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
2159
2160 if( mpi_cmp_int( &XX, 2 ) == 0 )
2161 return( 0 );
2162
2163 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2164 {
2165 if( ret == 1 )
2166 return( 0 );
2167
2168 return( ret );
2169 }
2170
2171 return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
2172}
2173
2174/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002175 * Prime number generation
2176 */
Paul Bakker23986e52011-04-24 08:57:21 +00002177int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002178 int (*f_rng)(void *, unsigned char *, size_t),
2179 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +00002180{
Paul Bakker23986e52011-04-24 08:57:21 +00002181 int ret;
2182 size_t k, n;
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002183 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002184 mpi Y;
2185
Paul Bakkerfe3256e2011-11-25 12:11:43 +00002186 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
Paul Bakker40e46942009-01-03 21:51:57 +00002187 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002188
Paul Bakker6c591fa2011-05-05 11:49:20 +00002189 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002190
2191 n = BITS_TO_LIMBS( nbits );
2192
Paul Bakker901c6562012-04-20 13:25:38 +00002193 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002194
2195 k = mpi_msb( X );
Pascal Junodb99183d2015-03-11 16:49:45 +01002196 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits + 1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002197
Pascal Junodb99183d2015-03-11 16:49:45 +01002198 mpi_set_bit( X, nbits-1, 1 );
2199
2200 X->p[0] |= 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002201
2202 if( dh_flag == 0 )
2203 {
2204 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
2205 {
Paul Bakker40e46942009-01-03 21:51:57 +00002206 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002207 goto cleanup;
2208
2209 MPI_CHK( mpi_add_int( X, X, 2 ) );
2210 }
2211 }
2212 else
2213 {
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002214 /*
2215 * An necessary condition for Y and X = 2Y + 1 to be prime
2216 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2217 * Make sure it is satisfied, while keeping X = 3 mod 4
2218 */
Pascal Junodb99183d2015-03-11 16:49:45 +01002219
2220 X->p[0] |= 2;
2221
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002222 MPI_CHK( mpi_mod_int( &r, X, 3 ) );
2223 if( r == 0 )
2224 MPI_CHK( mpi_add_int( X, X, 8 ) );
2225 else if( r == 1 )
2226 MPI_CHK( mpi_add_int( X, X, 4 ) );
2227
2228 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2229 MPI_CHK( mpi_copy( &Y, X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002230 MPI_CHK( mpi_shift_r( &Y, 1 ) );
2231
2232 while( 1 )
2233 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002234 /*
2235 * First, check small factors for X and Y
2236 * before doing Miller-Rabin on any of them
2237 */
2238 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2239 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2240 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
2241 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002242 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002243 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002244 }
2245
Paul Bakker40e46942009-01-03 21:51:57 +00002246 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002247 goto cleanup;
2248
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002249 /*
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002250 * Next candidates. We want to preserve Y = (X-1) / 2 and
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002251 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2252 * so up Y by 6 and X by 12.
2253 */
2254 MPI_CHK( mpi_add_int( X, X, 12 ) );
2255 MPI_CHK( mpi_add_int( &Y, &Y, 6 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002256 }
2257 }
2258
2259cleanup:
2260
Paul Bakker6c591fa2011-05-05 11:49:20 +00002261 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002262
2263 return( ret );
2264}
2265
Manuel Pégourié-Gonnarddf0142b2013-08-22 18:29:07 +02002266#endif /* POLARSSL_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00002267
Paul Bakker40e46942009-01-03 21:51:57 +00002268#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002269
Paul Bakker23986e52011-04-24 08:57:21 +00002270#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002271
2272static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2273{
2274 { 693, 609, 21 },
2275 { 1764, 868, 28 },
2276 { 768454923, 542167814, 1 }
2277};
2278
Paul Bakker5121ce52009-01-03 21:22:43 +00002279/*
2280 * Checkup routine
2281 */
2282int mpi_self_test( int verbose )
2283{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002284 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00002285 mpi A, E, N, X, Y, U, V;
2286
Paul Bakker6c591fa2011-05-05 11:49:20 +00002287 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
2288 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002289
2290 MPI_CHK( mpi_read_string( &A, 16,
2291 "EFE021C2645FD1DC586E69184AF4A31E" \
2292 "D5F53E93B5F123FA41680867BA110131" \
2293 "944FE7952E2517337780CB0DB80E61AA" \
2294 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2295
2296 MPI_CHK( mpi_read_string( &E, 16,
2297 "B2E7EFD37075B9F03FF989C7C5051C20" \
2298 "34D2A323810251127E7BF8625A4F49A5" \
2299 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2300 "5B5C25763222FEFCCFC38B832366C29E" ) );
2301
2302 MPI_CHK( mpi_read_string( &N, 16,
2303 "0066A198186C18C10B2F5ED9B522752A" \
2304 "9830B69916E535C8F047518A889A43A5" \
2305 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2306
2307 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
2308
2309 MPI_CHK( mpi_read_string( &U, 16,
2310 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2311 "9E857EA95A03512E2BAE7391688D264A" \
2312 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2313 "8001B72E848A38CAE1C65F78E56ABDEF" \
2314 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2315 "ECF677152EF804370C1A305CAF3B5BF1" \
2316 "30879B56C61DE584A0F53A2447A51E" ) );
2317
2318 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002319 polarssl_printf( " MPI test #1 (mul_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002320
2321 if( mpi_cmp_mpi( &X, &U ) != 0 )
2322 {
2323 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002324 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002325
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002326 ret = 1;
2327 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002328 }
2329
2330 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002331 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002332
2333 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
2334
2335 MPI_CHK( mpi_read_string( &U, 16,
2336 "256567336059E52CAE22925474705F39A94" ) );
2337
2338 MPI_CHK( mpi_read_string( &V, 16,
2339 "6613F26162223DF488E9CD48CC132C7A" \
2340 "0AC93C701B001B092E4E5B9F73BCD27B" \
2341 "9EE50D0657C77F374E903CDFA4C642" ) );
2342
2343 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002344 polarssl_printf( " MPI test #2 (div_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002345
2346 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2347 mpi_cmp_mpi( &Y, &V ) != 0 )
2348 {
2349 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002350 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002351
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002352 ret = 1;
2353 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002354 }
2355
2356 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002357 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002358
2359 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2360
2361 MPI_CHK( mpi_read_string( &U, 16,
2362 "36E139AEA55215609D2816998ED020BB" \
2363 "BD96C37890F65171D948E9BC7CBAA4D9" \
2364 "325D24D6A3C12710F10A09FA08AB87" ) );
2365
2366 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002367 polarssl_printf( " MPI test #3 (exp_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002368
2369 if( mpi_cmp_mpi( &X, &U ) != 0 )
2370 {
2371 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002372 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002373
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002374 ret = 1;
2375 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002376 }
2377
2378 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002379 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002380
2381 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2382
2383 MPI_CHK( mpi_read_string( &U, 16,
2384 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2385 "C3DBA76456363A10869622EAC2DD84EC" \
2386 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2387
2388 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002389 polarssl_printf( " MPI test #4 (inv_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002390
2391 if( mpi_cmp_mpi( &X, &U ) != 0 )
2392 {
2393 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002394 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002395
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002396 ret = 1;
2397 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002398 }
2399
2400 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002401 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002402
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002403 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002404 polarssl_printf( " MPI test #5 (simple gcd): " );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002405
Paul Bakker66d5d072014-06-17 16:39:18 +02002406 for( i = 0; i < GCD_PAIR_COUNT; i++ )
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002407 {
2408 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002409 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002410
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002411 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002412
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002413 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2414 {
2415 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002416 polarssl_printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002417
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002418 ret = 1;
2419 goto cleanup;
2420 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002421 }
2422
2423 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002424 polarssl_printf( "passed\n" );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002425
Paul Bakker5121ce52009-01-03 21:22:43 +00002426cleanup:
2427
2428 if( ret != 0 && verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002429 polarssl_printf( "Unexpected error, return code = %08X\n", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002430
Paul Bakker6c591fa2011-05-05 11:49:20 +00002431 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2432 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002433
2434 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002435 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002436
2437 return( ret );
2438}
2439
Paul Bakker9af723c2014-05-01 13:03:14 +02002440#endif /* POLARSSL_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002441
Paul Bakker9af723c2014-05-01 13:03:14 +02002442#endif /* POLARSSL_BIGNUM_C */