blob: 2b1155bb9a54f5cb01a7605cbf44143cf72e897a [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>
Manuel Pégourié-Gonnard59efb6a2015-09-28 13:48:04 +020042#include <limits.h>
Rich Evans00ab4702015-02-06 13:43:58 +000043
Paul Bakker7dc4c442014-02-01 22:50:26 +010044#if defined(POLARSSL_PLATFORM_C)
45#include "polarssl/platform.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020046#else
Rich Evans00ab4702015-02-06 13:43:58 +000047#include <stdio.h>
48#include <stdlib.h>
Paul Bakker7dc4c442014-02-01 22:50:26 +010049#define polarssl_printf printf
Paul Bakker6e339b52013-07-03 13:37:05 +020050#define polarssl_malloc malloc
51#define polarssl_free free
52#endif
53
Paul Bakker34617722014-06-13 17:20:13 +020054/* Implementation that should never be optimized out by the compiler */
55static void polarssl_zeroize( void *v, size_t n ) {
56 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
57}
58
Paul Bakkerf9688572011-05-05 10:00:45 +000059#define ciL (sizeof(t_uint)) /* chars in limb */
Paul Bakker5121ce52009-01-03 21:22:43 +000060#define biL (ciL << 3) /* bits in limb */
61#define biH (ciL << 2) /* half limb size */
62
63/*
64 * Convert between bits/chars and number of limbs
Manuel Pégourié-Gonnard59efb6a2015-09-28 13:48:04 +020065 * Divide first in order to avoid potential overflows
Paul Bakker5121ce52009-01-03 21:22:43 +000066 */
Manuel Pégourié-Gonnard59efb6a2015-09-28 13:48:04 +020067#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
68#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
Paul Bakker5121ce52009-01-03 21:22:43 +000069
70/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000071 * Initialize one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000072 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000073void mpi_init( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000074{
Paul Bakker6c591fa2011-05-05 11:49:20 +000075 if( X == NULL )
76 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000077
Paul Bakker6c591fa2011-05-05 11:49:20 +000078 X->s = 1;
79 X->n = 0;
80 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000081}
82
83/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000084 * Unallocate one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000085 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000086void mpi_free( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000087{
Paul Bakker6c591fa2011-05-05 11:49:20 +000088 if( X == NULL )
89 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000090
Paul Bakker6c591fa2011-05-05 11:49:20 +000091 if( X->p != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +000092 {
Paul Bakker34617722014-06-13 17:20:13 +020093 polarssl_zeroize( X->p, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +020094 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +000095 }
96
Paul Bakker6c591fa2011-05-05 11:49:20 +000097 X->s = 1;
98 X->n = 0;
99 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +0000100}
101
102/*
103 * Enlarge to the specified number of limbs
104 */
Paul Bakker23986e52011-04-24 08:57:21 +0000105int mpi_grow( mpi *X, size_t nblimbs )
Paul Bakker5121ce52009-01-03 21:22:43 +0000106{
Paul Bakkera755ca12011-04-24 09:11:17 +0000107 t_uint *p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000108
Paul Bakkerf9688572011-05-05 10:00:45 +0000109 if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
Paul Bakker69e095c2011-12-10 21:55:01 +0000110 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakkerf9688572011-05-05 10:00:45 +0000111
Paul Bakker5121ce52009-01-03 21:22:43 +0000112 if( X->n < nblimbs )
113 {
Mansour Moufidc531b4a2015-02-15 17:35:38 -0500114 if( ( p = polarssl_malloc( nblimbs * ciL ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000115 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000116
117 memset( p, 0, nblimbs * ciL );
118
119 if( X->p != NULL )
120 {
121 memcpy( p, X->p, X->n * ciL );
Paul Bakker34617722014-06-13 17:20:13 +0200122 polarssl_zeroize( X->p, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +0200123 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000124 }
125
126 X->n = nblimbs;
127 X->p = p;
128 }
129
130 return( 0 );
131}
132
133/*
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100134 * Resize down as much as possible,
135 * while keeping at least the specified number of limbs
136 */
137int mpi_shrink( mpi *X, size_t nblimbs )
138{
139 t_uint *p;
140 size_t i;
141
142 /* Actually resize up in this case */
143 if( X->n <= nblimbs )
144 return( mpi_grow( X, nblimbs ) );
145
146 for( i = X->n - 1; i > 0; i-- )
147 if( X->p[i] != 0 )
148 break;
149 i++;
150
151 if( i < nblimbs )
152 i = nblimbs;
153
Mansour Moufidc531b4a2015-02-15 17:35:38 -0500154 if( ( p = polarssl_malloc( i * ciL ) ) == NULL )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100155 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
156
157 memset( p, 0, i * ciL );
158
159 if( X->p != NULL )
160 {
161 memcpy( p, X->p, i * ciL );
Paul Bakker34617722014-06-13 17:20:13 +0200162 polarssl_zeroize( X->p, X->n * ciL );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100163 polarssl_free( X->p );
164 }
165
166 X->n = i;
167 X->p = p;
168
169 return( 0 );
170}
171
172/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000173 * Copy the contents of Y into X
174 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000175int mpi_copy( mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000176{
Paul Bakker23986e52011-04-24 08:57:21 +0000177 int ret;
178 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000179
180 if( X == Y )
181 return( 0 );
182
Manuel Pégourié-Gonnardf4999932013-08-12 17:02:59 +0200183 if( Y->p == NULL )
184 {
185 mpi_free( X );
186 return( 0 );
187 }
188
Paul Bakker5121ce52009-01-03 21:22:43 +0000189 for( i = Y->n - 1; i > 0; i-- )
190 if( Y->p[i] != 0 )
191 break;
192 i++;
193
194 X->s = Y->s;
195
196 MPI_CHK( mpi_grow( X, i ) );
197
198 memset( X->p, 0, X->n * ciL );
199 memcpy( X->p, Y->p, i * ciL );
200
201cleanup:
202
203 return( ret );
204}
205
206/*
207 * Swap the contents of X and Y
208 */
209void mpi_swap( mpi *X, mpi *Y )
210{
211 mpi T;
212
213 memcpy( &T, X, sizeof( mpi ) );
214 memcpy( X, Y, sizeof( mpi ) );
215 memcpy( Y, &T, sizeof( mpi ) );
216}
217
218/*
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100219 * Conditionally assign X = Y, without leaking information
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100220 * about whether the assignment was made or not.
221 * (Leaking information about the respective sizes of X and Y is ok however.)
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100222 */
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100223int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign )
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100224{
225 int ret = 0;
226 size_t i;
227
Pascal Junodb99183d2015-03-11 16:49:45 +0100228 /* make sure assign is 0 or 1 in a time-constant manner */
229 assign = (assign | (unsigned char)-assign) >> 7;
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100230
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100231 MPI_CHK( mpi_grow( X, Y->n ) );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100232
Paul Bakker66d5d072014-06-17 16:39:18 +0200233 X->s = X->s * ( 1 - assign ) + Y->s * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100234
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100235 for( i = 0; i < Y->n; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200236 X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100237
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100238 for( ; i < X->n; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200239 X->p[i] *= ( 1 - assign );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100240
241cleanup:
242 return( ret );
243}
244
245/*
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100246 * Conditionally swap X and Y, without leaking information
247 * about whether the swap was made or not.
248 * Here it is not ok to simply swap the pointers, which whould lead to
249 * different memory access patterns when X and Y are used afterwards.
250 */
251int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char swap )
252{
253 int ret, s;
254 size_t i;
255 t_uint tmp;
256
257 if( X == Y )
258 return( 0 );
259
Pascal Junodb99183d2015-03-11 16:49:45 +0100260 /* make sure swap is 0 or 1 in a time-constant manner */
261 swap = (swap | (unsigned char)-swap) >> 7;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100262
263 MPI_CHK( mpi_grow( X, Y->n ) );
264 MPI_CHK( mpi_grow( Y, X->n ) );
265
266 s = X->s;
Paul Bakker66d5d072014-06-17 16:39:18 +0200267 X->s = X->s * ( 1 - swap ) + Y->s * swap;
268 Y->s = Y->s * ( 1 - swap ) + s * swap;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100269
270
271 for( i = 0; i < X->n; i++ )
272 {
273 tmp = X->p[i];
Paul Bakker66d5d072014-06-17 16:39:18 +0200274 X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap;
275 Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100276 }
277
278cleanup:
279 return( ret );
280}
281
282/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000283 * Set value from integer
284 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000285int mpi_lset( mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000286{
287 int ret;
288
289 MPI_CHK( mpi_grow( X, 1 ) );
290 memset( X->p, 0, X->n * ciL );
291
292 X->p[0] = ( z < 0 ) ? -z : z;
293 X->s = ( z < 0 ) ? -1 : 1;
294
295cleanup:
296
297 return( ret );
298}
299
300/*
Paul Bakker2f5947e2011-05-18 15:47:11 +0000301 * Get a specific bit
302 */
Paul Bakker6b906e52012-05-08 12:01:43 +0000303int mpi_get_bit( const mpi *X, size_t pos )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000304{
305 if( X->n * biL <= pos )
306 return( 0 );
307
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200308 return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000309}
310
311/*
312 * Set a bit to a specific value of 0 or 1
313 */
314int mpi_set_bit( mpi *X, size_t pos, unsigned char val )
315{
316 int ret = 0;
317 size_t off = pos / biL;
318 size_t idx = pos % biL;
319
320 if( val != 0 && val != 1 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200321 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker9af723c2014-05-01 13:03:14 +0200322
Paul Bakker2f5947e2011-05-18 15:47:11 +0000323 if( X->n * biL <= pos )
324 {
325 if( val == 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200326 return( 0 );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000327
328 MPI_CHK( mpi_grow( X, off + 1 ) );
329 }
330
Manuel Pégourié-Gonnard9a4a5ac2013-12-04 18:05:29 +0100331 X->p[off] &= ~( (t_uint) 0x01 << idx );
332 X->p[off] |= (t_uint) val << idx;
Paul Bakker2f5947e2011-05-18 15:47:11 +0000333
334cleanup:
Paul Bakker9af723c2014-05-01 13:03:14 +0200335
Paul Bakker2f5947e2011-05-18 15:47:11 +0000336 return( ret );
337}
338
339/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000340 * Return the number of least significant bits
341 */
Paul Bakker23986e52011-04-24 08:57:21 +0000342size_t mpi_lsb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000343{
Paul Bakker23986e52011-04-24 08:57:21 +0000344 size_t i, j, count = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000345
346 for( i = 0; i < X->n; i++ )
Paul Bakkerf9688572011-05-05 10:00:45 +0000347 for( j = 0; j < biL; j++, count++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000348 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
349 return( count );
350
351 return( 0 );
352}
353
354/*
355 * Return the number of most significant bits
356 */
Paul Bakker23986e52011-04-24 08:57:21 +0000357size_t mpi_msb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000358{
Paul Bakker23986e52011-04-24 08:57:21 +0000359 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000360
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200361 if( X->n == 0 )
362 return( 0 );
363
Paul Bakker5121ce52009-01-03 21:22:43 +0000364 for( i = X->n - 1; i > 0; i-- )
365 if( X->p[i] != 0 )
366 break;
367
Paul Bakker23986e52011-04-24 08:57:21 +0000368 for( j = biL; j > 0; j-- )
369 if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000370 break;
371
Paul Bakker23986e52011-04-24 08:57:21 +0000372 return( ( i * biL ) + j );
Paul Bakker5121ce52009-01-03 21:22:43 +0000373}
374
375/*
376 * Return the total size in bytes
377 */
Paul Bakker23986e52011-04-24 08:57:21 +0000378size_t mpi_size( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000379{
380 return( ( mpi_msb( X ) + 7 ) >> 3 );
381}
382
383/*
384 * Convert an ASCII character to digit value
385 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000386static int mpi_get_digit( t_uint *d, int radix, char c )
Paul Bakker5121ce52009-01-03 21:22:43 +0000387{
388 *d = 255;
389
390 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
391 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
392 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
393
Paul Bakkera755ca12011-04-24 09:11:17 +0000394 if( *d >= (t_uint) radix )
Paul Bakker40e46942009-01-03 21:51:57 +0000395 return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000396
397 return( 0 );
398}
399
400/*
401 * Import from an ASCII string
402 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000403int mpi_read_string( mpi *X, int radix, const char *s )
Paul Bakker5121ce52009-01-03 21:22:43 +0000404{
Paul Bakker23986e52011-04-24 08:57:21 +0000405 int ret;
406 size_t i, j, slen, n;
Paul Bakkera755ca12011-04-24 09:11:17 +0000407 t_uint d;
Paul Bakker5121ce52009-01-03 21:22:43 +0000408 mpi T;
409
410 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000411 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000412
Paul Bakker6c591fa2011-05-05 11:49:20 +0000413 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000414
Paul Bakkerff60ee62010-03-16 21:09:09 +0000415 slen = strlen( s );
416
Paul Bakker5121ce52009-01-03 21:22:43 +0000417 if( radix == 16 )
418 {
Manuel Pégourié-Gonnard59efb6a2015-09-28 13:48:04 +0200419 if( slen > SIZE_T_MAX >> 2 )
420 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
421
Paul Bakkerff60ee62010-03-16 21:09:09 +0000422 n = BITS_TO_LIMBS( slen << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000423
424 MPI_CHK( mpi_grow( X, n ) );
425 MPI_CHK( mpi_lset( X, 0 ) );
426
Paul Bakker23986e52011-04-24 08:57:21 +0000427 for( i = slen, j = 0; i > 0; i--, j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000428 {
Paul Bakker23986e52011-04-24 08:57:21 +0000429 if( i == 1 && s[i - 1] == '-' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000430 {
431 X->s = -1;
432 break;
433 }
434
Paul Bakker23986e52011-04-24 08:57:21 +0000435 MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
Paul Bakker66d5d072014-06-17 16:39:18 +0200436 X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000437 }
438 }
439 else
440 {
441 MPI_CHK( mpi_lset( X, 0 ) );
442
Paul Bakkerff60ee62010-03-16 21:09:09 +0000443 for( i = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000444 {
445 if( i == 0 && s[i] == '-' )
446 {
447 X->s = -1;
448 continue;
449 }
450
451 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
452 MPI_CHK( mpi_mul_int( &T, X, radix ) );
Paul Bakker05feca62009-06-20 08:22:43 +0000453
454 if( X->s == 1 )
455 {
456 MPI_CHK( mpi_add_int( X, &T, d ) );
457 }
458 else
459 {
460 MPI_CHK( mpi_sub_int( X, &T, d ) );
461 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000462 }
463 }
464
465cleanup:
466
Paul Bakker6c591fa2011-05-05 11:49:20 +0000467 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000468
469 return( ret );
470}
471
472/*
473 * Helper to write the digits high-order first
474 */
475static int mpi_write_hlp( mpi *X, int radix, char **p )
476{
477 int ret;
Paul Bakkera755ca12011-04-24 09:11:17 +0000478 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +0000479
480 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000481 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000482
483 MPI_CHK( mpi_mod_int( &r, X, radix ) );
484 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
485
486 if( mpi_cmp_int( X, 0 ) != 0 )
487 MPI_CHK( mpi_write_hlp( X, radix, p ) );
488
489 if( r < 10 )
490 *(*p)++ = (char)( r + 0x30 );
491 else
492 *(*p)++ = (char)( r + 0x37 );
493
494cleanup:
495
496 return( ret );
497}
498
499/*
500 * Export into an ASCII string
501 */
Paul Bakker23986e52011-04-24 08:57:21 +0000502int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000503{
Paul Bakker23986e52011-04-24 08:57:21 +0000504 int ret = 0;
505 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000506 char *p;
507 mpi T;
508
509 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000510 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000511
512 n = mpi_msb( X );
513 if( radix >= 4 ) n >>= 1;
514 if( radix >= 16 ) n >>= 1;
515 n += 3;
516
517 if( *slen < n )
518 {
519 *slen = n;
Paul Bakker40e46942009-01-03 21:51:57 +0000520 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000521 }
522
523 p = s;
Paul Bakker6c591fa2011-05-05 11:49:20 +0000524 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000525
526 if( X->s == -1 )
527 *p++ = '-';
528
529 if( radix == 16 )
530 {
Paul Bakker23986e52011-04-24 08:57:21 +0000531 int c;
532 size_t i, j, k;
Paul Bakker5121ce52009-01-03 21:22:43 +0000533
Paul Bakker23986e52011-04-24 08:57:21 +0000534 for( i = X->n, k = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000535 {
Paul Bakker23986e52011-04-24 08:57:21 +0000536 for( j = ciL; j > 0; j-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000537 {
Paul Bakker23986e52011-04-24 08:57:21 +0000538 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000539
Paul Bakker6c343d72014-07-10 14:36:19 +0200540 if( c == 0 && k == 0 && ( i + j ) != 2 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000541 continue;
542
Paul Bakker98fe5ea2012-10-24 11:17:48 +0000543 *(p++) = "0123456789ABCDEF" [c / 16];
Paul Bakkerd2c167e2012-10-30 07:49:19 +0000544 *(p++) = "0123456789ABCDEF" [c % 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000545 k = 1;
546 }
547 }
548 }
549 else
550 {
551 MPI_CHK( mpi_copy( &T, X ) );
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000552
553 if( T.s == -1 )
554 T.s = 1;
555
Paul Bakker5121ce52009-01-03 21:22:43 +0000556 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
557 }
558
559 *p++ = '\0';
560 *slen = p - s;
561
562cleanup:
563
Paul Bakker6c591fa2011-05-05 11:49:20 +0000564 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000565
566 return( ret );
567}
568
Paul Bakker335db3f2011-04-25 15:28:35 +0000569#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000570/*
571 * Read X from an opened file
572 */
573int mpi_read_file( mpi *X, int radix, FILE *fin )
574{
Paul Bakkera755ca12011-04-24 09:11:17 +0000575 t_uint d;
Paul Bakker23986e52011-04-24 08:57:21 +0000576 size_t slen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000577 char *p;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000578 /*
Paul Bakkercb37aa52011-11-30 16:00:20 +0000579 * Buffer should have space for (short) label and decimal formatted MPI,
580 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000581 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000582 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000583
584 memset( s, 0, sizeof( s ) );
585 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000586 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000587
588 slen = strlen( s );
Paul Bakkercb37aa52011-11-30 16:00:20 +0000589 if( slen == sizeof( s ) - 2 )
590 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
591
Paul Bakker5121ce52009-01-03 21:22:43 +0000592 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
593 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
594
595 p = s + slen;
596 while( --p >= s )
597 if( mpi_get_digit( &d, radix, *p ) != 0 )
598 break;
599
600 return( mpi_read_string( X, radix, p + 1 ) );
601}
602
603/*
604 * Write X into an opened file (or stdout if fout == NULL)
605 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000606int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
Paul Bakker5121ce52009-01-03 21:22:43 +0000607{
Paul Bakker23986e52011-04-24 08:57:21 +0000608 int ret;
609 size_t n, slen, plen;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000610 /*
Paul Bakker5531c6d2012-09-26 19:20:46 +0000611 * Buffer should have space for (short) label and decimal formatted MPI,
612 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000613 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000614 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
616 n = sizeof( s );
617 memset( s, 0, n );
618 n -= 2;
619
Paul Bakker23986e52011-04-24 08:57:21 +0000620 MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000621
622 if( p == NULL ) p = "";
623
624 plen = strlen( p );
625 slen = strlen( s );
626 s[slen++] = '\r';
627 s[slen++] = '\n';
628
629 if( fout != NULL )
630 {
631 if( fwrite( p, 1, plen, fout ) != plen ||
632 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000633 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000634 }
635 else
Paul Bakker7dc4c442014-02-01 22:50:26 +0100636 polarssl_printf( "%s%s", p, s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
638cleanup:
639
640 return( ret );
641}
Paul Bakker335db3f2011-04-25 15:28:35 +0000642#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000643
644/*
645 * Import X from unsigned binary data, big endian
646 */
Paul Bakker23986e52011-04-24 08:57:21 +0000647int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000648{
Paul Bakker23986e52011-04-24 08:57:21 +0000649 int ret;
650 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000651
652 for( n = 0; n < buflen; n++ )
653 if( buf[n] != 0 )
654 break;
655
656 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
657 MPI_CHK( mpi_lset( X, 0 ) );
658
Paul Bakker23986e52011-04-24 08:57:21 +0000659 for( i = buflen, j = 0; i > n; i--, j++ )
Paul Bakkera755ca12011-04-24 09:11:17 +0000660 X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
662cleanup:
663
664 return( ret );
665}
666
667/*
668 * Export X into unsigned binary data, big endian
669 */
Paul Bakker23986e52011-04-24 08:57:21 +0000670int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000671{
Paul Bakker23986e52011-04-24 08:57:21 +0000672 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000673
674 n = mpi_size( X );
675
676 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000677 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000678
679 memset( buf, 0, buflen );
680
681 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
682 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
683
684 return( 0 );
685}
686
687/*
688 * Left-shift: X <<= count
689 */
Paul Bakker23986e52011-04-24 08:57:21 +0000690int mpi_shift_l( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000691{
Paul Bakker23986e52011-04-24 08:57:21 +0000692 int ret;
693 size_t i, v0, t1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000694 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000695
696 v0 = count / (biL );
697 t1 = count & (biL - 1);
698
699 i = mpi_msb( X ) + count;
700
Paul Bakkerf9688572011-05-05 10:00:45 +0000701 if( X->n * biL < i )
Paul Bakker5121ce52009-01-03 21:22:43 +0000702 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
703
704 ret = 0;
705
706 /*
707 * shift by count / limb_size
708 */
709 if( v0 > 0 )
710 {
Paul Bakker23986e52011-04-24 08:57:21 +0000711 for( i = X->n; i > v0; i-- )
712 X->p[i - 1] = X->p[i - v0 - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000713
Paul Bakker23986e52011-04-24 08:57:21 +0000714 for( ; i > 0; i-- )
715 X->p[i - 1] = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000716 }
717
718 /*
719 * shift by count % limb_size
720 */
721 if( t1 > 0 )
722 {
723 for( i = v0; i < X->n; i++ )
724 {
725 r1 = X->p[i] >> (biL - t1);
726 X->p[i] <<= t1;
727 X->p[i] |= r0;
728 r0 = r1;
729 }
730 }
731
732cleanup:
733
734 return( ret );
735}
736
737/*
738 * Right-shift: X >>= count
739 */
Paul Bakker23986e52011-04-24 08:57:21 +0000740int mpi_shift_r( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000741{
Paul Bakker23986e52011-04-24 08:57:21 +0000742 size_t i, v0, v1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000743 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000744
745 v0 = count / biL;
746 v1 = count & (biL - 1);
747
Manuel Pégourié-Gonnarde44ec102012-11-17 12:42:51 +0100748 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
749 return mpi_lset( X, 0 );
750
Paul Bakker5121ce52009-01-03 21:22:43 +0000751 /*
752 * shift by count / limb_size
753 */
754 if( v0 > 0 )
755 {
756 for( i = 0; i < X->n - v0; i++ )
757 X->p[i] = X->p[i + v0];
758
759 for( ; i < X->n; i++ )
760 X->p[i] = 0;
761 }
762
763 /*
764 * shift by count % limb_size
765 */
766 if( v1 > 0 )
767 {
Paul Bakker23986e52011-04-24 08:57:21 +0000768 for( i = X->n; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000769 {
Paul Bakker23986e52011-04-24 08:57:21 +0000770 r1 = X->p[i - 1] << (biL - v1);
771 X->p[i - 1] >>= v1;
772 X->p[i - 1] |= r0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000773 r0 = r1;
774 }
775 }
776
777 return( 0 );
778}
779
780/*
781 * Compare unsigned values
782 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000783int mpi_cmp_abs( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000784{
Paul Bakker23986e52011-04-24 08:57:21 +0000785 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000786
Paul Bakker23986e52011-04-24 08:57:21 +0000787 for( i = X->n; i > 0; i-- )
788 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000789 break;
790
Paul Bakker23986e52011-04-24 08:57:21 +0000791 for( j = Y->n; j > 0; j-- )
792 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000793 break;
794
Paul Bakker23986e52011-04-24 08:57:21 +0000795 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000796 return( 0 );
797
798 if( i > j ) return( 1 );
799 if( j > i ) return( -1 );
800
Paul Bakker23986e52011-04-24 08:57:21 +0000801 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000802 {
Paul Bakker23986e52011-04-24 08:57:21 +0000803 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
804 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000805 }
806
807 return( 0 );
808}
809
810/*
811 * Compare signed values
812 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000813int mpi_cmp_mpi( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000814{
Paul Bakker23986e52011-04-24 08:57:21 +0000815 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000816
Paul Bakker23986e52011-04-24 08:57:21 +0000817 for( i = X->n; i > 0; i-- )
818 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000819 break;
820
Paul Bakker23986e52011-04-24 08:57:21 +0000821 for( j = Y->n; j > 0; j-- )
822 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000823 break;
824
Paul Bakker23986e52011-04-24 08:57:21 +0000825 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000826 return( 0 );
827
828 if( i > j ) return( X->s );
Paul Bakker0c8f73b2012-03-22 14:08:57 +0000829 if( j > i ) return( -Y->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000830
831 if( X->s > 0 && Y->s < 0 ) return( 1 );
832 if( Y->s > 0 && X->s < 0 ) return( -1 );
833
Paul Bakker23986e52011-04-24 08:57:21 +0000834 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000835 {
Paul Bakker23986e52011-04-24 08:57:21 +0000836 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
837 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000838 }
839
840 return( 0 );
841}
842
843/*
844 * Compare signed values
845 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000846int mpi_cmp_int( const mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000847{
848 mpi Y;
Paul Bakkera755ca12011-04-24 09:11:17 +0000849 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000850
851 *p = ( z < 0 ) ? -z : z;
852 Y.s = ( z < 0 ) ? -1 : 1;
853 Y.n = 1;
854 Y.p = p;
855
856 return( mpi_cmp_mpi( X, &Y ) );
857}
858
859/*
860 * Unsigned addition: X = |A| + |B| (HAC 14.7)
861 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000862int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000863{
Paul Bakker23986e52011-04-24 08:57:21 +0000864 int ret;
865 size_t i, j;
Paul Bakkera755ca12011-04-24 09:11:17 +0000866 t_uint *o, *p, c;
Paul Bakker5121ce52009-01-03 21:22:43 +0000867
868 if( X == B )
869 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000870 const mpi *T = A; A = X; B = T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000871 }
872
873 if( X != A )
874 MPI_CHK( mpi_copy( X, A ) );
Paul Bakker9af723c2014-05-01 13:03:14 +0200875
Paul Bakkerf7ca7b92009-06-20 10:31:06 +0000876 /*
877 * X should always be positive as a result of unsigned additions.
878 */
879 X->s = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000880
Paul Bakker23986e52011-04-24 08:57:21 +0000881 for( j = B->n; j > 0; j-- )
882 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000883 break;
884
Paul Bakker23986e52011-04-24 08:57:21 +0000885 MPI_CHK( mpi_grow( X, j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000886
887 o = B->p; p = X->p; c = 0;
888
Paul Bakker23986e52011-04-24 08:57:21 +0000889 for( i = 0; i < j; i++, o++, p++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000890 {
891 *p += c; c = ( *p < c );
892 *p += *o; c += ( *p < *o );
893 }
894
895 while( c != 0 )
896 {
897 if( i >= X->n )
898 {
899 MPI_CHK( mpi_grow( X, i + 1 ) );
900 p = X->p + i;
901 }
902
Paul Bakker2d319fd2012-09-16 21:34:26 +0000903 *p += c; c = ( *p < c ); i++; p++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000904 }
905
906cleanup:
907
908 return( ret );
909}
910
911/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100912 * Helper for mpi subtraction
Paul Bakker5121ce52009-01-03 21:22:43 +0000913 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000914static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
Paul Bakker5121ce52009-01-03 21:22:43 +0000915{
Paul Bakker23986e52011-04-24 08:57:21 +0000916 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +0000917 t_uint c, z;
Paul Bakker5121ce52009-01-03 21:22:43 +0000918
919 for( i = c = 0; i < n; i++, s++, d++ )
920 {
921 z = ( *d < c ); *d -= c;
922 c = ( *d < *s ) + z; *d -= *s;
923 }
924
925 while( c != 0 )
926 {
927 z = ( *d < c ); *d -= c;
928 c = z; i++; d++;
929 }
930}
931
932/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100933 * Unsigned subtraction: X = |A| - |B| (HAC 14.9)
Paul Bakker5121ce52009-01-03 21:22:43 +0000934 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000935int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000936{
937 mpi TB;
Paul Bakker23986e52011-04-24 08:57:21 +0000938 int ret;
939 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000940
941 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000942 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000943
Paul Bakker6c591fa2011-05-05 11:49:20 +0000944 mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000945
946 if( X == B )
947 {
948 MPI_CHK( mpi_copy( &TB, B ) );
949 B = &TB;
950 }
951
952 if( X != A )
953 MPI_CHK( mpi_copy( X, A ) );
954
Paul Bakker1ef7a532009-06-20 10:50:55 +0000955 /*
Paul Bakker60b1d102013-10-29 10:02:51 +0100956 * X should always be positive as a result of unsigned subtractions.
Paul Bakker1ef7a532009-06-20 10:50:55 +0000957 */
958 X->s = 1;
959
Paul Bakker5121ce52009-01-03 21:22:43 +0000960 ret = 0;
961
Paul Bakker23986e52011-04-24 08:57:21 +0000962 for( n = B->n; n > 0; n-- )
963 if( B->p[n - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000964 break;
965
Paul Bakker23986e52011-04-24 08:57:21 +0000966 mpi_sub_hlp( n, B->p, X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000967
968cleanup:
969
Paul Bakker6c591fa2011-05-05 11:49:20 +0000970 mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000971
972 return( ret );
973}
974
975/*
976 * Signed addition: X = A + B
977 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000978int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000979{
980 int ret, s = A->s;
981
982 if( A->s * B->s < 0 )
983 {
984 if( mpi_cmp_abs( A, B ) >= 0 )
985 {
986 MPI_CHK( mpi_sub_abs( X, A, B ) );
987 X->s = s;
988 }
989 else
990 {
991 MPI_CHK( mpi_sub_abs( X, B, A ) );
992 X->s = -s;
993 }
994 }
995 else
996 {
997 MPI_CHK( mpi_add_abs( X, A, B ) );
998 X->s = s;
999 }
1000
1001cleanup:
1002
1003 return( ret );
1004}
1005
1006/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001007 * Signed subtraction: X = A - B
Paul Bakker5121ce52009-01-03 21:22:43 +00001008 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001009int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001010{
1011 int ret, s = A->s;
1012
1013 if( A->s * B->s > 0 )
1014 {
1015 if( mpi_cmp_abs( A, B ) >= 0 )
1016 {
1017 MPI_CHK( mpi_sub_abs( X, A, B ) );
1018 X->s = s;
1019 }
1020 else
1021 {
1022 MPI_CHK( mpi_sub_abs( X, B, A ) );
1023 X->s = -s;
1024 }
1025 }
1026 else
1027 {
1028 MPI_CHK( mpi_add_abs( X, A, B ) );
1029 X->s = s;
1030 }
1031
1032cleanup:
1033
1034 return( ret );
1035}
1036
1037/*
1038 * Signed addition: X = A + b
1039 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001040int mpi_add_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001041{
1042 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001043 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001044
1045 p[0] = ( b < 0 ) ? -b : b;
1046 _B.s = ( b < 0 ) ? -1 : 1;
1047 _B.n = 1;
1048 _B.p = p;
1049
1050 return( mpi_add_mpi( X, A, &_B ) );
1051}
1052
1053/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001054 * Signed subtraction: X = A - b
Paul Bakker5121ce52009-01-03 21:22:43 +00001055 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001056int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001057{
1058 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001059 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001060
1061 p[0] = ( b < 0 ) ? -b : b;
1062 _B.s = ( b < 0 ) ? -1 : 1;
1063 _B.n = 1;
1064 _B.p = p;
1065
1066 return( mpi_sub_mpi( X, A, &_B ) );
1067}
1068
1069/*
1070 * Helper for mpi multiplication
Paul Bakkerfc4f46f2013-06-24 19:23:56 +02001071 */
1072static
1073#if defined(__APPLE__) && defined(__arm__)
1074/*
1075 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1076 * appears to need this to prevent bad ARM code generation at -O3.
1077 */
1078__attribute__ ((noinline))
1079#endif
1080void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001081{
Paul Bakkera755ca12011-04-24 09:11:17 +00001082 t_uint c = 0, t = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001083
1084#if defined(MULADDC_HUIT)
1085 for( ; i >= 8; i -= 8 )
1086 {
1087 MULADDC_INIT
1088 MULADDC_HUIT
1089 MULADDC_STOP
1090 }
1091
1092 for( ; i > 0; i-- )
1093 {
1094 MULADDC_INIT
1095 MULADDC_CORE
1096 MULADDC_STOP
1097 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001098#else /* MULADDC_HUIT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001099 for( ; i >= 16; i -= 16 )
1100 {
1101 MULADDC_INIT
1102 MULADDC_CORE MULADDC_CORE
1103 MULADDC_CORE MULADDC_CORE
1104 MULADDC_CORE MULADDC_CORE
1105 MULADDC_CORE MULADDC_CORE
1106
1107 MULADDC_CORE MULADDC_CORE
1108 MULADDC_CORE MULADDC_CORE
1109 MULADDC_CORE MULADDC_CORE
1110 MULADDC_CORE MULADDC_CORE
1111 MULADDC_STOP
1112 }
1113
1114 for( ; i >= 8; i -= 8 )
1115 {
1116 MULADDC_INIT
1117 MULADDC_CORE MULADDC_CORE
1118 MULADDC_CORE MULADDC_CORE
1119
1120 MULADDC_CORE MULADDC_CORE
1121 MULADDC_CORE MULADDC_CORE
1122 MULADDC_STOP
1123 }
1124
1125 for( ; i > 0; i-- )
1126 {
1127 MULADDC_INIT
1128 MULADDC_CORE
1129 MULADDC_STOP
1130 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001131#endif /* MULADDC_HUIT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001132
1133 t++;
1134
1135 do {
1136 *d += c; c = ( *d < c ); d++;
1137 }
1138 while( c != 0 );
1139}
1140
1141/*
1142 * Baseline multiplication: X = A * B (HAC 14.12)
1143 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001144int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001145{
Paul Bakker23986e52011-04-24 08:57:21 +00001146 int ret;
1147 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00001148 mpi TA, TB;
1149
Paul Bakker6c591fa2011-05-05 11:49:20 +00001150 mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001151
1152 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
1153 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
1154
Paul Bakker23986e52011-04-24 08:57:21 +00001155 for( i = A->n; i > 0; i-- )
1156 if( A->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001157 break;
1158
Paul Bakker23986e52011-04-24 08:57:21 +00001159 for( j = B->n; j > 0; j-- )
1160 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001161 break;
1162
Paul Bakker23986e52011-04-24 08:57:21 +00001163 MPI_CHK( mpi_grow( X, i + j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001164 MPI_CHK( mpi_lset( X, 0 ) );
1165
Paul Bakker23986e52011-04-24 08:57:21 +00001166 for( i++; j > 0; j-- )
1167 mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001168
1169 X->s = A->s * B->s;
1170
1171cleanup:
1172
Paul Bakker6c591fa2011-05-05 11:49:20 +00001173 mpi_free( &TB ); mpi_free( &TA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001174
1175 return( ret );
1176}
1177
1178/*
1179 * Baseline multiplication: X = A * b
1180 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001181int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001182{
1183 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001184 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001185
1186 _B.s = 1;
1187 _B.n = 1;
1188 _B.p = p;
1189 p[0] = b;
1190
1191 return( mpi_mul_mpi( X, A, &_B ) );
1192}
1193
1194/*
1195 * Division by mpi: A = Q * B + R (HAC 14.20)
1196 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001197int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001198{
Paul Bakker23986e52011-04-24 08:57:21 +00001199 int ret;
1200 size_t i, n, t, k;
Paul Bakker5121ce52009-01-03 21:22:43 +00001201 mpi X, Y, Z, T1, T2;
1202
1203 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001204 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001205
Paul Bakker6c591fa2011-05-05 11:49:20 +00001206 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
1207 mpi_init( &T1 ); mpi_init( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001208
1209 if( mpi_cmp_abs( A, B ) < 0 )
1210 {
1211 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1212 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1213 return( 0 );
1214 }
1215
1216 MPI_CHK( mpi_copy( &X, A ) );
1217 MPI_CHK( mpi_copy( &Y, B ) );
1218 X.s = Y.s = 1;
1219
1220 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1221 MPI_CHK( mpi_lset( &Z, 0 ) );
1222 MPI_CHK( mpi_grow( &T1, 2 ) );
1223 MPI_CHK( mpi_grow( &T2, 3 ) );
1224
1225 k = mpi_msb( &Y ) % biL;
Paul Bakkerf9688572011-05-05 10:00:45 +00001226 if( k < biL - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001227 {
1228 k = biL - 1 - k;
1229 MPI_CHK( mpi_shift_l( &X, k ) );
1230 MPI_CHK( mpi_shift_l( &Y, k ) );
1231 }
1232 else k = 0;
1233
1234 n = X.n - 1;
1235 t = Y.n - 1;
Paul Bakker66d5d072014-06-17 16:39:18 +02001236 MPI_CHK( mpi_shift_l( &Y, biL * ( n - t ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001237
1238 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1239 {
1240 Z.p[n - t]++;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001241 MPI_CHK( mpi_sub_mpi( &X, &X, &Y ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001242 }
Paul Bakker66d5d072014-06-17 16:39:18 +02001243 MPI_CHK( mpi_shift_r( &Y, biL * ( n - t ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001244
1245 for( i = n; i > t ; i-- )
1246 {
1247 if( X.p[i] >= Y.p[t] )
1248 Z.p[i - t - 1] = ~0;
1249 else
1250 {
Manuel Pégourié-Gonnardd72704b2015-02-12 09:38:54 +00001251#if defined(POLARSSL_HAVE_UDBL)
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001252 t_udbl r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001253
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001254 r = (t_udbl) X.p[i] << biL;
1255 r |= (t_udbl) X.p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001256 r /= Y.p[t];
Paul Bakker66d5d072014-06-17 16:39:18 +02001257 if( r > ( (t_udbl) 1 << biL ) - 1 )
1258 r = ( (t_udbl) 1 << biL ) - 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001259
Paul Bakkera755ca12011-04-24 09:11:17 +00001260 Z.p[i - t - 1] = (t_uint) r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001261#else
1262 /*
1263 * __udiv_qrnnd_c, from gmp/longlong.h
1264 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001265 t_uint q0, q1, r0, r1;
1266 t_uint d0, d1, d, m;
Paul Bakker5121ce52009-01-03 21:22:43 +00001267
1268 d = Y.p[t];
1269 d0 = ( d << biH ) >> biH;
1270 d1 = ( d >> biH );
1271
1272 q1 = X.p[i] / d1;
1273 r1 = X.p[i] - d1 * q1;
1274 r1 <<= biH;
1275 r1 |= ( X.p[i - 1] >> biH );
1276
1277 m = q1 * d0;
1278 if( r1 < m )
1279 {
1280 q1--, r1 += d;
1281 while( r1 >= d && r1 < m )
1282 q1--, r1 += d;
1283 }
1284 r1 -= m;
1285
1286 q0 = r1 / d1;
1287 r0 = r1 - d1 * q0;
1288 r0 <<= biH;
1289 r0 |= ( X.p[i - 1] << biH ) >> biH;
1290
1291 m = q0 * d0;
1292 if( r0 < m )
1293 {
1294 q0--, r0 += d;
1295 while( r0 >= d && r0 < m )
1296 q0--, r0 += d;
1297 }
1298 r0 -= m;
1299
1300 Z.p[i - t - 1] = ( q1 << biH ) | q0;
Paul Bakkerdb20c102014-06-17 14:34:44 +02001301#endif /* POLARSSL_HAVE_UDBL && !64-bit Apple with Clang 5.0 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001302 }
1303
1304 Z.p[i - t - 1]++;
1305 do
1306 {
1307 Z.p[i - t - 1]--;
1308
1309 MPI_CHK( mpi_lset( &T1, 0 ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001310 T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001311 T1.p[1] = Y.p[t];
1312 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1313
1314 MPI_CHK( mpi_lset( &T2, 0 ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001315 T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
1316 T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001317 T2.p[2] = X.p[i];
1318 }
1319 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1320
1321 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001322 MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001323 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1324
1325 if( mpi_cmp_int( &X, 0 ) < 0 )
1326 {
1327 MPI_CHK( mpi_copy( &T1, &Y ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001328 MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001329 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1330 Z.p[i - t - 1]--;
1331 }
1332 }
1333
1334 if( Q != NULL )
1335 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001336 MPI_CHK( mpi_copy( Q, &Z ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001337 Q->s = A->s * B->s;
1338 }
1339
1340 if( R != NULL )
1341 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001342 MPI_CHK( mpi_shift_r( &X, k ) );
Paul Bakkerf02c5642012-11-13 10:25:21 +00001343 X.s = A->s;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001344 MPI_CHK( mpi_copy( R, &X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001345
Paul Bakker5121ce52009-01-03 21:22:43 +00001346 if( mpi_cmp_int( R, 0 ) == 0 )
1347 R->s = 1;
1348 }
1349
1350cleanup:
1351
Paul Bakker6c591fa2011-05-05 11:49:20 +00001352 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
1353 mpi_free( &T1 ); mpi_free( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001354
1355 return( ret );
1356}
1357
1358/*
1359 * Division by int: A = Q * b + R
Paul Bakker5121ce52009-01-03 21:22:43 +00001360 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001361int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001362{
1363 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001364 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001365
1366 p[0] = ( b < 0 ) ? -b : b;
1367 _B.s = ( b < 0 ) ? -1 : 1;
1368 _B.n = 1;
1369 _B.p = p;
1370
1371 return( mpi_div_mpi( Q, R, A, &_B ) );
1372}
1373
1374/*
1375 * Modulo: R = A mod B
1376 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001377int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001378{
1379 int ret;
1380
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001381 if( mpi_cmp_int( B, 0 ) < 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001382 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001383
Paul Bakker5121ce52009-01-03 21:22:43 +00001384 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1385
1386 while( mpi_cmp_int( R, 0 ) < 0 )
1387 MPI_CHK( mpi_add_mpi( R, R, B ) );
1388
1389 while( mpi_cmp_mpi( R, B ) >= 0 )
1390 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1391
1392cleanup:
1393
1394 return( ret );
1395}
1396
1397/*
1398 * Modulo: r = A mod b
1399 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001400int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001401{
Paul Bakker23986e52011-04-24 08:57:21 +00001402 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +00001403 t_uint x, y, z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001404
1405 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001406 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001407
1408 if( b < 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001409 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001410
1411 /*
1412 * handle trivial cases
1413 */
1414 if( b == 1 )
1415 {
1416 *r = 0;
1417 return( 0 );
1418 }
1419
1420 if( b == 2 )
1421 {
1422 *r = A->p[0] & 1;
1423 return( 0 );
1424 }
1425
1426 /*
1427 * general case
1428 */
Paul Bakker23986e52011-04-24 08:57:21 +00001429 for( i = A->n, y = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001430 {
Paul Bakker23986e52011-04-24 08:57:21 +00001431 x = A->p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001432 y = ( y << biH ) | ( x >> biH );
1433 z = y / b;
1434 y -= z * b;
1435
1436 x <<= biH;
1437 y = ( y << biH ) | ( x >> biH );
1438 z = y / b;
1439 y -= z * b;
1440 }
1441
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001442 /*
1443 * If A is negative, then the current y represents a negative value.
1444 * Flipping it to the positive side.
1445 */
1446 if( A->s < 0 && y != 0 )
1447 y = b - y;
1448
Paul Bakker5121ce52009-01-03 21:22:43 +00001449 *r = y;
1450
1451 return( 0 );
1452}
1453
1454/*
1455 * Fast Montgomery initialization (thanks to Tom St Denis)
1456 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001457static void mpi_montg_init( t_uint *mm, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001458{
Paul Bakkera755ca12011-04-24 09:11:17 +00001459 t_uint x, m0 = N->p[0];
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001460 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001461
1462 x = m0;
1463 x += ( ( m0 + 2 ) & 4 ) << 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001464
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001465 for( i = biL; i >= 8; i /= 2 )
1466 x *= ( 2 - ( m0 * x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001467
1468 *mm = ~x + 1;
1469}
1470
1471/*
1472 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1473 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +02001474static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm,
1475 const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001476{
Paul Bakker23986e52011-04-24 08:57:21 +00001477 size_t i, n, m;
Paul Bakkera755ca12011-04-24 09:11:17 +00001478 t_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00001479
1480 memset( T->p, 0, T->n * ciL );
1481
1482 d = T->p;
1483 n = N->n;
1484 m = ( B->n < n ) ? B->n : n;
1485
1486 for( i = 0; i < n; i++ )
1487 {
1488 /*
1489 * T = (T + u0*B + u1*N) / 2^biL
1490 */
1491 u0 = A->p[i];
1492 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1493
1494 mpi_mul_hlp( m, B->p, d, u0 );
1495 mpi_mul_hlp( n, N->p, d, u1 );
1496
1497 *d++ = u0; d[n + 1] = 0;
1498 }
1499
Paul Bakker66d5d072014-06-17 16:39:18 +02001500 memcpy( A->p, d, ( n + 1 ) * ciL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001501
1502 if( mpi_cmp_abs( A, N ) >= 0 )
1503 mpi_sub_hlp( n, N->p, A->p );
1504 else
1505 /* prevent timing attacks */
1506 mpi_sub_hlp( n, A->p, T->p );
1507}
1508
1509/*
1510 * Montgomery reduction: A = A * R^-1 mod N
1511 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001512static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001513{
Paul Bakkera755ca12011-04-24 09:11:17 +00001514 t_uint z = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001515 mpi U;
1516
Paul Bakker8ddb6452013-02-27 14:56:33 +01001517 U.n = U.s = (int) z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001518 U.p = &z;
1519
1520 mpi_montmul( A, &U, N, mm, T );
1521}
1522
1523/*
1524 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1525 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001526int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00001527{
Paul Bakker23986e52011-04-24 08:57:21 +00001528 int ret;
1529 size_t wbits, wsize, one = 1;
1530 size_t i, j, nblimbs;
1531 size_t bufsize, nbits;
Paul Bakkera755ca12011-04-24 09:11:17 +00001532 t_uint ei, mm, state;
Paul Bakkerf6198c12012-05-16 08:02:29 +00001533 mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos;
1534 int neg;
Paul Bakker5121ce52009-01-03 21:22:43 +00001535
1536 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001537 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001538
Paul Bakkerf6198c12012-05-16 08:02:29 +00001539 if( mpi_cmp_int( E, 0 ) < 0 )
1540 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
1541
1542 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001543 * Init temps and window size
1544 */
1545 mpi_montg_init( &mm, N );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001546 mpi_init( &RR ); mpi_init( &T );
Manuel Pégourié-Gonnardfd6a1912014-01-18 19:05:23 +01001547 mpi_init( &Apos );
Paul Bakker5121ce52009-01-03 21:22:43 +00001548 memset( W, 0, sizeof( W ) );
1549
1550 i = mpi_msb( E );
1551
1552 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1553 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1554
Paul Bakkerb6d5f082011-11-25 11:52:11 +00001555 if( wsize > POLARSSL_MPI_WINDOW_SIZE )
1556 wsize = POLARSSL_MPI_WINDOW_SIZE;
1557
Paul Bakker5121ce52009-01-03 21:22:43 +00001558 j = N->n + 1;
1559 MPI_CHK( mpi_grow( X, j ) );
1560 MPI_CHK( mpi_grow( &W[1], j ) );
1561 MPI_CHK( mpi_grow( &T, j * 2 ) );
1562
1563 /*
Paul Bakker50546922012-05-19 08:40:49 +00001564 * Compensate for negative A (and correct at the end)
1565 */
1566 neg = ( A->s == -1 );
Paul Bakker50546922012-05-19 08:40:49 +00001567 if( neg )
1568 {
1569 MPI_CHK( mpi_copy( &Apos, A ) );
1570 Apos.s = 1;
1571 A = &Apos;
1572 }
1573
1574 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001575 * If 1st call, pre-compute R^2 mod N
1576 */
1577 if( _RR == NULL || _RR->p == NULL )
1578 {
1579 MPI_CHK( mpi_lset( &RR, 1 ) );
1580 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1581 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1582
1583 if( _RR != NULL )
1584 memcpy( _RR, &RR, sizeof( mpi ) );
1585 }
1586 else
1587 memcpy( &RR, _RR, sizeof( mpi ) );
1588
1589 /*
1590 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1591 */
1592 if( mpi_cmp_mpi( A, N ) >= 0 )
Paul Bakkerc2024f42014-01-23 20:38:35 +01001593 MPI_CHK( mpi_mod_mpi( &W[1], A, N ) );
1594 else
1595 MPI_CHK( mpi_copy( &W[1], A ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001596
1597 mpi_montmul( &W[1], &RR, N, mm, &T );
1598
1599 /*
1600 * X = R^2 * R^-1 mod N = R mod N
1601 */
1602 MPI_CHK( mpi_copy( X, &RR ) );
1603 mpi_montred( X, N, mm, &T );
1604
1605 if( wsize > 1 )
1606 {
1607 /*
1608 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1609 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001610 j = one << ( wsize - 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001611
1612 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1613 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1614
1615 for( i = 0; i < wsize - 1; i++ )
1616 mpi_montmul( &W[j], &W[j], N, mm, &T );
Paul Bakker0d7702c2013-10-29 16:18:35 +01001617
Paul Bakker5121ce52009-01-03 21:22:43 +00001618 /*
1619 * W[i] = W[i - 1] * W[1]
1620 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001621 for( i = j + 1; i < ( one << wsize ); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001622 {
1623 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1624 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1625
1626 mpi_montmul( &W[i], &W[1], N, mm, &T );
1627 }
1628 }
1629
1630 nblimbs = E->n;
1631 bufsize = 0;
1632 nbits = 0;
1633 wbits = 0;
1634 state = 0;
1635
1636 while( 1 )
1637 {
1638 if( bufsize == 0 )
1639 {
Paul Bakker0d7702c2013-10-29 16:18:35 +01001640 if( nblimbs == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001641 break;
1642
Paul Bakker0d7702c2013-10-29 16:18:35 +01001643 nblimbs--;
1644
Paul Bakkera755ca12011-04-24 09:11:17 +00001645 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001646 }
1647
1648 bufsize--;
1649
1650 ei = (E->p[nblimbs] >> bufsize) & 1;
1651
1652 /*
1653 * skip leading 0s
1654 */
1655 if( ei == 0 && state == 0 )
1656 continue;
1657
1658 if( ei == 0 && state == 1 )
1659 {
1660 /*
1661 * out of window, square X
1662 */
1663 mpi_montmul( X, X, N, mm, &T );
1664 continue;
1665 }
1666
1667 /*
1668 * add ei to current window
1669 */
1670 state = 2;
1671
1672 nbits++;
Paul Bakker66d5d072014-06-17 16:39:18 +02001673 wbits |= ( ei << ( wsize - nbits ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001674
1675 if( nbits == wsize )
1676 {
1677 /*
1678 * X = X^wsize R^-1 mod N
1679 */
1680 for( i = 0; i < wsize; i++ )
1681 mpi_montmul( X, X, N, mm, &T );
1682
1683 /*
1684 * X = X * W[wbits] R^-1 mod N
1685 */
1686 mpi_montmul( X, &W[wbits], N, mm, &T );
1687
1688 state--;
1689 nbits = 0;
1690 wbits = 0;
1691 }
1692 }
1693
1694 /*
1695 * process the remaining bits
1696 */
1697 for( i = 0; i < nbits; i++ )
1698 {
1699 mpi_montmul( X, X, N, mm, &T );
1700
1701 wbits <<= 1;
1702
Paul Bakker66d5d072014-06-17 16:39:18 +02001703 if( ( wbits & ( one << wsize ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001704 mpi_montmul( X, &W[1], N, mm, &T );
1705 }
1706
1707 /*
1708 * X = A^E * R * R^-1 mod N = A^E mod N
1709 */
1710 mpi_montred( X, N, mm, &T );
1711
Paul Bakkerf6198c12012-05-16 08:02:29 +00001712 if( neg )
1713 {
1714 X->s = -1;
Paul Bakkerc2024f42014-01-23 20:38:35 +01001715 MPI_CHK( mpi_add_mpi( X, N, X ) );
Paul Bakkerf6198c12012-05-16 08:02:29 +00001716 }
1717
Paul Bakker5121ce52009-01-03 21:22:43 +00001718cleanup:
1719
Paul Bakker66d5d072014-06-17 16:39:18 +02001720 for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001721 mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001722
Paul Bakkerf6198c12012-05-16 08:02:29 +00001723 mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001724
Paul Bakker75a28602014-03-31 12:08:17 +02001725 if( _RR == NULL || _RR->p == NULL )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001726 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001727
1728 return( ret );
1729}
1730
Paul Bakker5121ce52009-01-03 21:22:43 +00001731/*
1732 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1733 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001734int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001735{
Paul Bakker23986e52011-04-24 08:57:21 +00001736 int ret;
1737 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001738 mpi TG, TA, TB;
1739
Paul Bakker6c591fa2011-05-05 11:49:20 +00001740 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001741
Paul Bakker5121ce52009-01-03 21:22:43 +00001742 MPI_CHK( mpi_copy( &TA, A ) );
1743 MPI_CHK( mpi_copy( &TB, B ) );
1744
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001745 lz = mpi_lsb( &TA );
1746 lzt = mpi_lsb( &TB );
1747
Paul Bakker66d5d072014-06-17 16:39:18 +02001748 if( lzt < lz )
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001749 lz = lzt;
1750
1751 MPI_CHK( mpi_shift_r( &TA, lz ) );
1752 MPI_CHK( mpi_shift_r( &TB, lz ) );
1753
Paul Bakker5121ce52009-01-03 21:22:43 +00001754 TA.s = TB.s = 1;
1755
1756 while( mpi_cmp_int( &TA, 0 ) != 0 )
1757 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001758 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1759 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001760
1761 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1762 {
1763 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1764 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1765 }
1766 else
1767 {
1768 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1769 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1770 }
1771 }
1772
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001773 MPI_CHK( mpi_shift_l( &TB, lz ) );
1774 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001775
1776cleanup:
1777
Paul Bakker6c591fa2011-05-05 11:49:20 +00001778 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001779
1780 return( ret );
1781}
1782
Paul Bakker33dc46b2014-04-30 16:11:39 +02001783/*
1784 * Fill X with size bytes of random.
1785 *
1786 * Use a temporary bytes representation to make sure the result is the same
Paul Bakkerc37b0ac2014-05-01 14:19:23 +02001787 * regardless of the platform endianness (useful when f_rng is actually
Paul Bakker33dc46b2014-04-30 16:11:39 +02001788 * deterministic, eg for tests).
1789 */
Paul Bakkera3d195c2011-11-27 21:07:34 +00001790int mpi_fill_random( mpi *X, size_t size,
1791 int (*f_rng)(void *, unsigned char *, size_t),
1792 void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001793{
Paul Bakker23986e52011-04-24 08:57:21 +00001794 int ret;
Paul Bakker33dc46b2014-04-30 16:11:39 +02001795 unsigned char buf[POLARSSL_MPI_MAX_SIZE];
1796
1797 if( size > POLARSSL_MPI_MAX_SIZE )
1798 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker287781a2011-03-26 13:18:49 +00001799
Paul Bakker33dc46b2014-04-30 16:11:39 +02001800 MPI_CHK( f_rng( p_rng, buf, size ) );
1801 MPI_CHK( mpi_read_binary( X, buf, size ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001802
1803cleanup:
1804 return( ret );
1805}
1806
Paul Bakker5121ce52009-01-03 21:22:43 +00001807/*
1808 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1809 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001810int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001811{
1812 int ret;
1813 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1814
1815 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001816 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001817
Paul Bakker6c591fa2011-05-05 11:49:20 +00001818 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1819 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1820 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001821
1822 MPI_CHK( mpi_gcd( &G, A, N ) );
1823
1824 if( mpi_cmp_int( &G, 1 ) != 0 )
1825 {
Paul Bakker40e46942009-01-03 21:51:57 +00001826 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001827 goto cleanup;
1828 }
1829
1830 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1831 MPI_CHK( mpi_copy( &TU, &TA ) );
1832 MPI_CHK( mpi_copy( &TB, N ) );
1833 MPI_CHK( mpi_copy( &TV, N ) );
1834
1835 MPI_CHK( mpi_lset( &U1, 1 ) );
1836 MPI_CHK( mpi_lset( &U2, 0 ) );
1837 MPI_CHK( mpi_lset( &V1, 0 ) );
1838 MPI_CHK( mpi_lset( &V2, 1 ) );
1839
1840 do
1841 {
1842 while( ( TU.p[0] & 1 ) == 0 )
1843 {
1844 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1845
1846 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1847 {
1848 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1849 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1850 }
1851
1852 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1853 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1854 }
1855
1856 while( ( TV.p[0] & 1 ) == 0 )
1857 {
1858 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1859
1860 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1861 {
1862 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1863 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1864 }
1865
1866 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1867 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1868 }
1869
1870 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1871 {
1872 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1873 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1874 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1875 }
1876 else
1877 {
1878 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1879 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1880 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1881 }
1882 }
1883 while( mpi_cmp_int( &TU, 0 ) != 0 );
1884
1885 while( mpi_cmp_int( &V1, 0 ) < 0 )
1886 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1887
1888 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1889 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1890
1891 MPI_CHK( mpi_copy( X, &V1 ) );
1892
1893cleanup:
1894
Paul Bakker6c591fa2011-05-05 11:49:20 +00001895 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1896 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1897 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001898
1899 return( ret );
1900}
1901
Paul Bakkerd9374b02012-11-02 11:02:58 +00001902#if defined(POLARSSL_GENPRIME)
1903
Paul Bakker5121ce52009-01-03 21:22:43 +00001904static const int small_prime[] =
1905{
1906 3, 5, 7, 11, 13, 17, 19, 23,
1907 29, 31, 37, 41, 43, 47, 53, 59,
1908 61, 67, 71, 73, 79, 83, 89, 97,
1909 101, 103, 107, 109, 113, 127, 131, 137,
1910 139, 149, 151, 157, 163, 167, 173, 179,
1911 181, 191, 193, 197, 199, 211, 223, 227,
1912 229, 233, 239, 241, 251, 257, 263, 269,
1913 271, 277, 281, 283, 293, 307, 311, 313,
1914 317, 331, 337, 347, 349, 353, 359, 367,
1915 373, 379, 383, 389, 397, 401, 409, 419,
1916 421, 431, 433, 439, 443, 449, 457, 461,
1917 463, 467, 479, 487, 491, 499, 503, 509,
1918 521, 523, 541, 547, 557, 563, 569, 571,
1919 577, 587, 593, 599, 601, 607, 613, 617,
1920 619, 631, 641, 643, 647, 653, 659, 661,
1921 673, 677, 683, 691, 701, 709, 719, 727,
1922 733, 739, 743, 751, 757, 761, 769, 773,
1923 787, 797, 809, 811, 821, 823, 827, 829,
1924 839, 853, 857, 859, 863, 877, 881, 883,
1925 887, 907, 911, 919, 929, 937, 941, 947,
1926 953, 967, 971, 977, 983, 991, 997, -103
1927};
1928
1929/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001930 * Small divisors test (X must be positive)
1931 *
1932 * Return values:
1933 * 0: no small factor (possible prime, more tests needed)
1934 * 1: certain prime
1935 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
1936 * other negative: error
Paul Bakker5121ce52009-01-03 21:22:43 +00001937 */
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001938static int mpi_check_small_factors( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +00001939{
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001940 int ret = 0;
1941 size_t i;
1942 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001943
Paul Bakker5121ce52009-01-03 21:22:43 +00001944 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001945 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001946
1947 for( i = 0; small_prime[i] > 0; i++ )
1948 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001949 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001950 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001951
1952 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1953
1954 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001955 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001956 }
1957
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001958cleanup:
1959 return( ret );
1960}
1961
1962/*
1963 * Miller-Rabin pseudo-primality test (HAC 4.24)
1964 */
1965static int mpi_miller_rabin( const mpi *X,
1966 int (*f_rng)(void *, unsigned char *, size_t),
1967 void *p_rng )
1968{
Pascal Junodb99183d2015-03-11 16:49:45 +01001969 int ret, count;
1970 size_t i, j, k, n, s;
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001971 mpi W, R, T, A, RR;
1972
1973 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1974 mpi_init( &RR );
1975
Paul Bakker5121ce52009-01-03 21:22:43 +00001976 /*
1977 * W = |X| - 1
1978 * R = W >> lsb( W )
1979 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001980 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001981 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001982 MPI_CHK( mpi_copy( &R, &W ) );
1983 MPI_CHK( mpi_shift_r( &R, s ) );
1984
1985 i = mpi_msb( X );
1986 /*
1987 * HAC, table 4.4
1988 */
1989 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1990 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1991 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1992
1993 for( i = 0; i < n; i++ )
1994 {
1995 /*
1996 * pick a random A, 1 < A < |X| - 1
1997 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001998
Pascal Junodb99183d2015-03-11 16:49:45 +01001999 count = 0;
2000 do {
2001 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
2002
2003 j = mpi_msb( &A );
2004 k = mpi_msb( &W );
2005 if (j > k) {
2006 MPI_CHK( mpi_shift_r( &A, j - k ) );
2007 }
2008
2009 if (count++ > 30) {
2010 return POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
2011 }
2012
2013 } while ( (mpi_cmp_mpi( &A, &W ) >= 0) ||
2014 (mpi_cmp_int( &A, 1 ) <= 0) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002015
2016 /*
2017 * A = A^R mod |X|
2018 */
2019 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
2020
2021 if( mpi_cmp_mpi( &A, &W ) == 0 ||
2022 mpi_cmp_int( &A, 1 ) == 0 )
2023 continue;
2024
2025 j = 1;
2026 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
2027 {
2028 /*
2029 * A = A * A mod |X|
2030 */
2031 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
2032 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
2033
2034 if( mpi_cmp_int( &A, 1 ) == 0 )
2035 break;
2036
2037 j++;
2038 }
2039
2040 /*
2041 * not prime if A != |X| - 1 or A == 1
2042 */
2043 if( mpi_cmp_mpi( &A, &W ) != 0 ||
2044 mpi_cmp_int( &A, 1 ) == 0 )
2045 {
Paul Bakker40e46942009-01-03 21:51:57 +00002046 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002047 break;
2048 }
2049 }
2050
2051cleanup:
Paul Bakker6c591fa2011-05-05 11:49:20 +00002052 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
2053 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002054
2055 return( ret );
2056}
2057
2058/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002059 * Pseudo-primality test: small factors, then Miller-Rabin
2060 */
Paul Bakker45f457d2013-11-25 14:26:52 +01002061int mpi_is_prime( mpi *X,
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002062 int (*f_rng)(void *, unsigned char *, size_t),
2063 void *p_rng )
2064{
2065 int ret;
Manuel Pégourié-Gonnard7f4ed672014-10-14 20:56:02 +02002066 mpi XX;
2067
2068 XX.s = 1;
2069 XX.n = X->n;
2070 XX.p = X->p;
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002071
2072 if( mpi_cmp_int( &XX, 0 ) == 0 ||
2073 mpi_cmp_int( &XX, 1 ) == 0 )
2074 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
2075
2076 if( mpi_cmp_int( &XX, 2 ) == 0 )
2077 return( 0 );
2078
2079 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2080 {
2081 if( ret == 1 )
2082 return( 0 );
2083
2084 return( ret );
2085 }
2086
2087 return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
2088}
2089
2090/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002091 * Prime number generation
2092 */
Paul Bakker23986e52011-04-24 08:57:21 +00002093int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002094 int (*f_rng)(void *, unsigned char *, size_t),
2095 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +00002096{
Paul Bakker23986e52011-04-24 08:57:21 +00002097 int ret;
2098 size_t k, n;
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002099 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002100 mpi Y;
2101
Paul Bakkerfe3256e2011-11-25 12:11:43 +00002102 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
Paul Bakker40e46942009-01-03 21:51:57 +00002103 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002104
Paul Bakker6c591fa2011-05-05 11:49:20 +00002105 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002106
2107 n = BITS_TO_LIMBS( nbits );
2108
Paul Bakker901c6562012-04-20 13:25:38 +00002109 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002110
2111 k = mpi_msb( X );
Pascal Junodb99183d2015-03-11 16:49:45 +01002112 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits + 1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002113
Pascal Junodb99183d2015-03-11 16:49:45 +01002114 mpi_set_bit( X, nbits-1, 1 );
2115
2116 X->p[0] |= 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002117
2118 if( dh_flag == 0 )
2119 {
2120 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
2121 {
Paul Bakker40e46942009-01-03 21:51:57 +00002122 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002123 goto cleanup;
2124
2125 MPI_CHK( mpi_add_int( X, X, 2 ) );
2126 }
2127 }
2128 else
2129 {
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002130 /*
2131 * An necessary condition for Y and X = 2Y + 1 to be prime
2132 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2133 * Make sure it is satisfied, while keeping X = 3 mod 4
2134 */
Pascal Junodb99183d2015-03-11 16:49:45 +01002135
2136 X->p[0] |= 2;
2137
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002138 MPI_CHK( mpi_mod_int( &r, X, 3 ) );
2139 if( r == 0 )
2140 MPI_CHK( mpi_add_int( X, X, 8 ) );
2141 else if( r == 1 )
2142 MPI_CHK( mpi_add_int( X, X, 4 ) );
2143
2144 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2145 MPI_CHK( mpi_copy( &Y, X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002146 MPI_CHK( mpi_shift_r( &Y, 1 ) );
2147
2148 while( 1 )
2149 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002150 /*
2151 * First, check small factors for X and Y
2152 * before doing Miller-Rabin on any of them
2153 */
2154 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2155 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2156 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
2157 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002158 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002159 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002160 }
2161
Paul Bakker40e46942009-01-03 21:51:57 +00002162 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002163 goto cleanup;
2164
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002165 /*
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002166 * Next candidates. We want to preserve Y = (X-1) / 2 and
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002167 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2168 * so up Y by 6 and X by 12.
2169 */
2170 MPI_CHK( mpi_add_int( X, X, 12 ) );
2171 MPI_CHK( mpi_add_int( &Y, &Y, 6 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002172 }
2173 }
2174
2175cleanup:
2176
Paul Bakker6c591fa2011-05-05 11:49:20 +00002177 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002178
2179 return( ret );
2180}
2181
Manuel Pégourié-Gonnarddf0142b2013-08-22 18:29:07 +02002182#endif /* POLARSSL_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00002183
Paul Bakker40e46942009-01-03 21:51:57 +00002184#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002185
Paul Bakker23986e52011-04-24 08:57:21 +00002186#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002187
2188static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2189{
2190 { 693, 609, 21 },
2191 { 1764, 868, 28 },
2192 { 768454923, 542167814, 1 }
2193};
2194
Paul Bakker5121ce52009-01-03 21:22:43 +00002195/*
2196 * Checkup routine
2197 */
2198int mpi_self_test( int verbose )
2199{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002200 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00002201 mpi A, E, N, X, Y, U, V;
2202
Paul Bakker6c591fa2011-05-05 11:49:20 +00002203 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
2204 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002205
2206 MPI_CHK( mpi_read_string( &A, 16,
2207 "EFE021C2645FD1DC586E69184AF4A31E" \
2208 "D5F53E93B5F123FA41680867BA110131" \
2209 "944FE7952E2517337780CB0DB80E61AA" \
2210 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2211
2212 MPI_CHK( mpi_read_string( &E, 16,
2213 "B2E7EFD37075B9F03FF989C7C5051C20" \
2214 "34D2A323810251127E7BF8625A4F49A5" \
2215 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2216 "5B5C25763222FEFCCFC38B832366C29E" ) );
2217
2218 MPI_CHK( mpi_read_string( &N, 16,
2219 "0066A198186C18C10B2F5ED9B522752A" \
2220 "9830B69916E535C8F047518A889A43A5" \
2221 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2222
2223 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
2224
2225 MPI_CHK( mpi_read_string( &U, 16,
2226 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2227 "9E857EA95A03512E2BAE7391688D264A" \
2228 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2229 "8001B72E848A38CAE1C65F78E56ABDEF" \
2230 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2231 "ECF677152EF804370C1A305CAF3B5BF1" \
2232 "30879B56C61DE584A0F53A2447A51E" ) );
2233
2234 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002235 polarssl_printf( " MPI test #1 (mul_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002236
2237 if( mpi_cmp_mpi( &X, &U ) != 0 )
2238 {
2239 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002240 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002241
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002242 ret = 1;
2243 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002244 }
2245
2246 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002247 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002248
2249 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
2250
2251 MPI_CHK( mpi_read_string( &U, 16,
2252 "256567336059E52CAE22925474705F39A94" ) );
2253
2254 MPI_CHK( mpi_read_string( &V, 16,
2255 "6613F26162223DF488E9CD48CC132C7A" \
2256 "0AC93C701B001B092E4E5B9F73BCD27B" \
2257 "9EE50D0657C77F374E903CDFA4C642" ) );
2258
2259 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002260 polarssl_printf( " MPI test #2 (div_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002261
2262 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2263 mpi_cmp_mpi( &Y, &V ) != 0 )
2264 {
2265 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002266 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002267
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002268 ret = 1;
2269 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002270 }
2271
2272 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002273 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002274
2275 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2276
2277 MPI_CHK( mpi_read_string( &U, 16,
2278 "36E139AEA55215609D2816998ED020BB" \
2279 "BD96C37890F65171D948E9BC7CBAA4D9" \
2280 "325D24D6A3C12710F10A09FA08AB87" ) );
2281
2282 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002283 polarssl_printf( " MPI test #3 (exp_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002284
2285 if( mpi_cmp_mpi( &X, &U ) != 0 )
2286 {
2287 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002288 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002289
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002290 ret = 1;
2291 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002292 }
2293
2294 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002295 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002296
2297 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2298
2299 MPI_CHK( mpi_read_string( &U, 16,
2300 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2301 "C3DBA76456363A10869622EAC2DD84EC" \
2302 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2303
2304 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002305 polarssl_printf( " MPI test #4 (inv_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002306
2307 if( mpi_cmp_mpi( &X, &U ) != 0 )
2308 {
2309 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002310 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002311
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002312 ret = 1;
2313 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002314 }
2315
2316 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002317 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002318
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002319 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002320 polarssl_printf( " MPI test #5 (simple gcd): " );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002321
Paul Bakker66d5d072014-06-17 16:39:18 +02002322 for( i = 0; i < GCD_PAIR_COUNT; i++ )
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002323 {
2324 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002325 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002326
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002327 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002328
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002329 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2330 {
2331 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002332 polarssl_printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002333
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002334 ret = 1;
2335 goto cleanup;
2336 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002337 }
2338
2339 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002340 polarssl_printf( "passed\n" );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002341
Paul Bakker5121ce52009-01-03 21:22:43 +00002342cleanup:
2343
2344 if( ret != 0 && verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002345 polarssl_printf( "Unexpected error, return code = %08X\n", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002346
Paul Bakker6c591fa2011-05-05 11:49:20 +00002347 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2348 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002349
2350 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002351 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002352
2353 return( ret );
2354}
2355
Paul Bakker9af723c2014-05-01 13:03:14 +02002356#endif /* POLARSSL_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002357
Paul Bakker9af723c2014-05-01 13:03:14 +02002358#endif /* POLARSSL_BIGNUM_C */