blob: c97f16d368cbda1810dea339e2a73a40d9b005d5 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Multi-precision integer library
3 *
Manuel Pégourié-Gonnarda658a402015-01-23 09:45:19 +00004 * Copyright (C) 2006-2014, ARM Limited, All Rights Reserved
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
Manuel Pégourié-Gonnardfe446432015-03-06 13:17:10 +00006 * This file is part of mbed TLS (https://tls.mbed.org)
Paul Bakkerb96f1542010-07-18 20:36:00 +00007 *
Paul Bakker5121ce52009-01-03 21:22:43 +00008 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22/*
23 * This MPI implementation is based on:
24 *
25 * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
26 * http://www.stillhq.com/extracted/gnupg-api/mpi/
27 * http://math.libtomcrypt.com/files/tommath.pdf
28 */
29
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020030#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker40e46942009-01-03 21:51:57 +000031#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020032#else
33#include POLARSSL_CONFIG_FILE
34#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Paul Bakker40e46942009-01-03 21:51:57 +000036#if defined(POLARSSL_BIGNUM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Paul Bakker40e46942009-01-03 21:51:57 +000038#include "polarssl/bignum.h"
39#include "polarssl/bn_mul.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Rich Evans00ab4702015-02-06 13:43:58 +000041#include <string.h>
42
Paul Bakker7dc4c442014-02-01 22:50:26 +010043#if defined(POLARSSL_PLATFORM_C)
44#include "polarssl/platform.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020045#else
Rich Evans00ab4702015-02-06 13:43:58 +000046#include <stdio.h>
47#include <stdlib.h>
Paul Bakker7dc4c442014-02-01 22:50:26 +010048#define polarssl_printf printf
Paul Bakker6e339b52013-07-03 13:37:05 +020049#define polarssl_malloc malloc
50#define polarssl_free free
51#endif
52
Paul Bakker34617722014-06-13 17:20:13 +020053/* Implementation that should never be optimized out by the compiler */
54static void polarssl_zeroize( void *v, size_t n ) {
55 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
56}
57
Paul Bakkerf9688572011-05-05 10:00:45 +000058#define ciL (sizeof(t_uint)) /* chars in limb */
Paul Bakker5121ce52009-01-03 21:22:43 +000059#define biL (ciL << 3) /* bits in limb */
60#define biH (ciL << 2) /* half limb size */
61
Manuel Pégourié-Gonnardfa647a72015-10-05 15:23:11 +010062#define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
63
Paul Bakker5121ce52009-01-03 21:22:43 +000064/*
65 * Convert between bits/chars and number of limbs
Manuel Pégourié-Gonnard59efb6a2015-09-28 13:48:04 +020066 * Divide first in order to avoid potential overflows
Paul Bakker5121ce52009-01-03 21:22:43 +000067 */
Manuel Pégourié-Gonnard59efb6a2015-09-28 13:48:04 +020068#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
69#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
Paul Bakker5121ce52009-01-03 21:22:43 +000070
71/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000072 * Initialize one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000073 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000074void mpi_init( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000075{
Paul Bakker6c591fa2011-05-05 11:49:20 +000076 if( X == NULL )
77 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000078
Paul Bakker6c591fa2011-05-05 11:49:20 +000079 X->s = 1;
80 X->n = 0;
81 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000082}
83
84/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000085 * Unallocate one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000086 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000087void mpi_free( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000088{
Paul Bakker6c591fa2011-05-05 11:49:20 +000089 if( X == NULL )
90 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000091
Paul Bakker6c591fa2011-05-05 11:49:20 +000092 if( X->p != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +000093 {
Paul Bakker34617722014-06-13 17:20:13 +020094 polarssl_zeroize( X->p, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +020095 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +000096 }
97
Paul Bakker6c591fa2011-05-05 11:49:20 +000098 X->s = 1;
99 X->n = 0;
100 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +0000101}
102
103/*
104 * Enlarge to the specified number of limbs
105 */
Paul Bakker23986e52011-04-24 08:57:21 +0000106int mpi_grow( mpi *X, size_t nblimbs )
Paul Bakker5121ce52009-01-03 21:22:43 +0000107{
Paul Bakkera755ca12011-04-24 09:11:17 +0000108 t_uint *p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000109
Paul Bakkerf9688572011-05-05 10:00:45 +0000110 if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
Paul Bakker69e095c2011-12-10 21:55:01 +0000111 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakkerf9688572011-05-05 10:00:45 +0000112
Paul Bakker5121ce52009-01-03 21:22:43 +0000113 if( X->n < nblimbs )
114 {
Mansour Moufidc531b4a2015-02-15 17:35:38 -0500115 if( ( p = polarssl_malloc( nblimbs * ciL ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000116 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000117
118 memset( p, 0, nblimbs * ciL );
119
120 if( X->p != NULL )
121 {
122 memcpy( p, X->p, X->n * ciL );
Paul Bakker34617722014-06-13 17:20:13 +0200123 polarssl_zeroize( X->p, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +0200124 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000125 }
126
127 X->n = nblimbs;
128 X->p = p;
129 }
130
131 return( 0 );
132}
133
134/*
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100135 * Resize down as much as possible,
136 * while keeping at least the specified number of limbs
137 */
138int mpi_shrink( mpi *X, size_t nblimbs )
139{
140 t_uint *p;
141 size_t i;
142
143 /* Actually resize up in this case */
144 if( X->n <= nblimbs )
145 return( mpi_grow( X, nblimbs ) );
146
147 for( i = X->n - 1; i > 0; i-- )
148 if( X->p[i] != 0 )
149 break;
150 i++;
151
152 if( i < nblimbs )
153 i = nblimbs;
154
Mansour Moufidc531b4a2015-02-15 17:35:38 -0500155 if( ( p = polarssl_malloc( i * ciL ) ) == NULL )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100156 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
157
158 memset( p, 0, i * ciL );
159
160 if( X->p != NULL )
161 {
162 memcpy( p, X->p, i * ciL );
Paul Bakker34617722014-06-13 17:20:13 +0200163 polarssl_zeroize( X->p, X->n * ciL );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100164 polarssl_free( X->p );
165 }
166
167 X->n = i;
168 X->p = p;
169
170 return( 0 );
171}
172
173/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000174 * Copy the contents of Y into X
175 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000176int mpi_copy( mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000177{
Paul Bakker23986e52011-04-24 08:57:21 +0000178 int ret;
179 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000180
181 if( X == Y )
182 return( 0 );
183
Manuel Pégourié-Gonnardf4999932013-08-12 17:02:59 +0200184 if( Y->p == NULL )
185 {
186 mpi_free( X );
187 return( 0 );
188 }
189
Paul Bakker5121ce52009-01-03 21:22:43 +0000190 for( i = Y->n - 1; i > 0; i-- )
191 if( Y->p[i] != 0 )
192 break;
193 i++;
194
195 X->s = Y->s;
196
197 MPI_CHK( mpi_grow( X, i ) );
198
199 memset( X->p, 0, X->n * ciL );
200 memcpy( X->p, Y->p, i * ciL );
201
202cleanup:
203
204 return( ret );
205}
206
207/*
208 * Swap the contents of X and Y
209 */
210void mpi_swap( mpi *X, mpi *Y )
211{
212 mpi T;
213
214 memcpy( &T, X, sizeof( mpi ) );
215 memcpy( X, Y, sizeof( mpi ) );
216 memcpy( Y, &T, sizeof( mpi ) );
217}
218
219/*
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100220 * Conditionally assign X = Y, without leaking information
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100221 * about whether the assignment was made or not.
222 * (Leaking information about the respective sizes of X and Y is ok however.)
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100223 */
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100224int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign )
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100225{
226 int ret = 0;
227 size_t i;
228
Pascal Junodb99183d2015-03-11 16:49:45 +0100229 /* make sure assign is 0 or 1 in a time-constant manner */
230 assign = (assign | (unsigned char)-assign) >> 7;
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100231
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100232 MPI_CHK( mpi_grow( X, Y->n ) );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100233
Paul Bakker66d5d072014-06-17 16:39:18 +0200234 X->s = X->s * ( 1 - assign ) + Y->s * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100235
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100236 for( i = 0; i < Y->n; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200237 X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100238
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100239 for( ; i < X->n; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200240 X->p[i] *= ( 1 - assign );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100241
242cleanup:
243 return( ret );
244}
245
246/*
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100247 * Conditionally swap X and Y, without leaking information
248 * about whether the swap was made or not.
249 * Here it is not ok to simply swap the pointers, which whould lead to
250 * different memory access patterns when X and Y are used afterwards.
251 */
252int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char swap )
253{
254 int ret, s;
255 size_t i;
256 t_uint tmp;
257
258 if( X == Y )
259 return( 0 );
260
Pascal Junodb99183d2015-03-11 16:49:45 +0100261 /* make sure swap is 0 or 1 in a time-constant manner */
262 swap = (swap | (unsigned char)-swap) >> 7;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100263
264 MPI_CHK( mpi_grow( X, Y->n ) );
265 MPI_CHK( mpi_grow( Y, X->n ) );
266
267 s = X->s;
Paul Bakker66d5d072014-06-17 16:39:18 +0200268 X->s = X->s * ( 1 - swap ) + Y->s * swap;
269 Y->s = Y->s * ( 1 - swap ) + s * swap;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100270
271
272 for( i = 0; i < X->n; i++ )
273 {
274 tmp = X->p[i];
Paul Bakker66d5d072014-06-17 16:39:18 +0200275 X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap;
276 Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100277 }
278
279cleanup:
280 return( ret );
281}
282
283/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000284 * Set value from integer
285 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000286int mpi_lset( mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000287{
288 int ret;
289
290 MPI_CHK( mpi_grow( X, 1 ) );
291 memset( X->p, 0, X->n * ciL );
292
293 X->p[0] = ( z < 0 ) ? -z : z;
294 X->s = ( z < 0 ) ? -1 : 1;
295
296cleanup:
297
298 return( ret );
299}
300
301/*
Paul Bakker2f5947e2011-05-18 15:47:11 +0000302 * Get a specific bit
303 */
Paul Bakker6b906e52012-05-08 12:01:43 +0000304int mpi_get_bit( const mpi *X, size_t pos )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000305{
306 if( X->n * biL <= pos )
307 return( 0 );
308
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200309 return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000310}
311
312/*
313 * Set a bit to a specific value of 0 or 1
314 */
315int mpi_set_bit( mpi *X, size_t pos, unsigned char val )
316{
317 int ret = 0;
318 size_t off = pos / biL;
319 size_t idx = pos % biL;
320
321 if( val != 0 && val != 1 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200322 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker9af723c2014-05-01 13:03:14 +0200323
Paul Bakker2f5947e2011-05-18 15:47:11 +0000324 if( X->n * biL <= pos )
325 {
326 if( val == 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200327 return( 0 );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000328
329 MPI_CHK( mpi_grow( X, off + 1 ) );
330 }
331
Manuel Pégourié-Gonnard9a4a5ac2013-12-04 18:05:29 +0100332 X->p[off] &= ~( (t_uint) 0x01 << idx );
333 X->p[off] |= (t_uint) val << idx;
Paul Bakker2f5947e2011-05-18 15:47:11 +0000334
335cleanup:
Paul Bakker9af723c2014-05-01 13:03:14 +0200336
Paul Bakker2f5947e2011-05-18 15:47:11 +0000337 return( ret );
338}
339
340/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000341 * Return the number of least significant bits
342 */
Paul Bakker23986e52011-04-24 08:57:21 +0000343size_t mpi_lsb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000344{
Paul Bakker23986e52011-04-24 08:57:21 +0000345 size_t i, j, count = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
347 for( i = 0; i < X->n; i++ )
Paul Bakkerf9688572011-05-05 10:00:45 +0000348 for( j = 0; j < biL; j++, count++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000349 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
350 return( count );
351
352 return( 0 );
353}
354
355/*
356 * Return the number of most significant bits
357 */
Paul Bakker23986e52011-04-24 08:57:21 +0000358size_t mpi_msb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000359{
Paul Bakker23986e52011-04-24 08:57:21 +0000360 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000361
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200362 if( X->n == 0 )
363 return( 0 );
364
Paul Bakker5121ce52009-01-03 21:22:43 +0000365 for( i = X->n - 1; i > 0; i-- )
366 if( X->p[i] != 0 )
367 break;
368
Paul Bakker23986e52011-04-24 08:57:21 +0000369 for( j = biL; j > 0; j-- )
370 if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000371 break;
372
Paul Bakker23986e52011-04-24 08:57:21 +0000373 return( ( i * biL ) + j );
Paul Bakker5121ce52009-01-03 21:22:43 +0000374}
375
376/*
377 * Return the total size in bytes
378 */
Paul Bakker23986e52011-04-24 08:57:21 +0000379size_t mpi_size( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000380{
381 return( ( mpi_msb( X ) + 7 ) >> 3 );
382}
383
384/*
385 * Convert an ASCII character to digit value
386 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000387static int mpi_get_digit( t_uint *d, int radix, char c )
Paul Bakker5121ce52009-01-03 21:22:43 +0000388{
389 *d = 255;
390
391 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
392 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
393 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
394
Paul Bakkera755ca12011-04-24 09:11:17 +0000395 if( *d >= (t_uint) radix )
Paul Bakker40e46942009-01-03 21:51:57 +0000396 return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000397
398 return( 0 );
399}
400
401/*
402 * Import from an ASCII string
403 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000404int mpi_read_string( mpi *X, int radix, const char *s )
Paul Bakker5121ce52009-01-03 21:22:43 +0000405{
Paul Bakker23986e52011-04-24 08:57:21 +0000406 int ret;
407 size_t i, j, slen, n;
Paul Bakkera755ca12011-04-24 09:11:17 +0000408 t_uint d;
Paul Bakker5121ce52009-01-03 21:22:43 +0000409 mpi T;
410
411 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000412 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000413
Paul Bakker6c591fa2011-05-05 11:49:20 +0000414 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000415
Paul Bakkerff60ee62010-03-16 21:09:09 +0000416 slen = strlen( s );
417
Paul Bakker5121ce52009-01-03 21:22:43 +0000418 if( radix == 16 )
419 {
Manuel Pégourié-Gonnardfa647a72015-10-05 15:23:11 +0100420 if( slen > MPI_SIZE_T_MAX >> 2 )
Manuel Pégourié-Gonnard59efb6a2015-09-28 13:48:04 +0200421 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
422
Paul Bakkerff60ee62010-03-16 21:09:09 +0000423 n = BITS_TO_LIMBS( slen << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000424
425 MPI_CHK( mpi_grow( X, n ) );
426 MPI_CHK( mpi_lset( X, 0 ) );
427
Paul Bakker23986e52011-04-24 08:57:21 +0000428 for( i = slen, j = 0; i > 0; i--, j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000429 {
Paul Bakker23986e52011-04-24 08:57:21 +0000430 if( i == 1 && s[i - 1] == '-' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000431 {
432 X->s = -1;
433 break;
434 }
435
Paul Bakker23986e52011-04-24 08:57:21 +0000436 MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
Paul Bakker66d5d072014-06-17 16:39:18 +0200437 X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000438 }
439 }
440 else
441 {
442 MPI_CHK( mpi_lset( X, 0 ) );
443
Paul Bakkerff60ee62010-03-16 21:09:09 +0000444 for( i = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000445 {
446 if( i == 0 && s[i] == '-' )
447 {
448 X->s = -1;
449 continue;
450 }
451
452 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
453 MPI_CHK( mpi_mul_int( &T, X, radix ) );
Paul Bakker05feca62009-06-20 08:22:43 +0000454
455 if( X->s == 1 )
456 {
457 MPI_CHK( mpi_add_int( X, &T, d ) );
458 }
459 else
460 {
461 MPI_CHK( mpi_sub_int( X, &T, d ) );
462 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000463 }
464 }
465
466cleanup:
467
Paul Bakker6c591fa2011-05-05 11:49:20 +0000468 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
470 return( ret );
471}
472
473/*
474 * Helper to write the digits high-order first
475 */
476static int mpi_write_hlp( mpi *X, int radix, char **p )
477{
478 int ret;
Paul Bakkera755ca12011-04-24 09:11:17 +0000479 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
481 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000482 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000483
484 MPI_CHK( mpi_mod_int( &r, X, radix ) );
485 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
486
487 if( mpi_cmp_int( X, 0 ) != 0 )
488 MPI_CHK( mpi_write_hlp( X, radix, p ) );
489
490 if( r < 10 )
491 *(*p)++ = (char)( r + 0x30 );
492 else
493 *(*p)++ = (char)( r + 0x37 );
494
495cleanup:
496
497 return( ret );
498}
499
500/*
501 * Export into an ASCII string
502 */
Paul Bakker23986e52011-04-24 08:57:21 +0000503int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000504{
Paul Bakker23986e52011-04-24 08:57:21 +0000505 int ret = 0;
506 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000507 char *p;
508 mpi T;
509
510 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000511 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000512
513 n = mpi_msb( X );
514 if( radix >= 4 ) n >>= 1;
515 if( radix >= 16 ) n >>= 1;
516 n += 3;
517
518 if( *slen < n )
519 {
520 *slen = n;
Paul Bakker40e46942009-01-03 21:51:57 +0000521 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000522 }
523
524 p = s;
Paul Bakker6c591fa2011-05-05 11:49:20 +0000525 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000526
527 if( X->s == -1 )
528 *p++ = '-';
529
530 if( radix == 16 )
531 {
Paul Bakker23986e52011-04-24 08:57:21 +0000532 int c;
533 size_t i, j, k;
Paul Bakker5121ce52009-01-03 21:22:43 +0000534
Paul Bakker23986e52011-04-24 08:57:21 +0000535 for( i = X->n, k = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000536 {
Paul Bakker23986e52011-04-24 08:57:21 +0000537 for( j = ciL; j > 0; j-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000538 {
Paul Bakker23986e52011-04-24 08:57:21 +0000539 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000540
Paul Bakker6c343d72014-07-10 14:36:19 +0200541 if( c == 0 && k == 0 && ( i + j ) != 2 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000542 continue;
543
Paul Bakker98fe5ea2012-10-24 11:17:48 +0000544 *(p++) = "0123456789ABCDEF" [c / 16];
Paul Bakkerd2c167e2012-10-30 07:49:19 +0000545 *(p++) = "0123456789ABCDEF" [c % 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000546 k = 1;
547 }
548 }
549 }
550 else
551 {
552 MPI_CHK( mpi_copy( &T, X ) );
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000553
554 if( T.s == -1 )
555 T.s = 1;
556
Paul Bakker5121ce52009-01-03 21:22:43 +0000557 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
558 }
559
560 *p++ = '\0';
561 *slen = p - s;
562
563cleanup:
564
Paul Bakker6c591fa2011-05-05 11:49:20 +0000565 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000566
567 return( ret );
568}
569
Paul Bakker335db3f2011-04-25 15:28:35 +0000570#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000571/*
572 * Read X from an opened file
573 */
574int mpi_read_file( mpi *X, int radix, FILE *fin )
575{
Paul Bakkera755ca12011-04-24 09:11:17 +0000576 t_uint d;
Paul Bakker23986e52011-04-24 08:57:21 +0000577 size_t slen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000578 char *p;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000579 /*
Paul Bakkercb37aa52011-11-30 16:00:20 +0000580 * Buffer should have space for (short) label and decimal formatted MPI,
581 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000582 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000583 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000584
585 memset( s, 0, sizeof( s ) );
586 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000587 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000588
589 slen = strlen( s );
Paul Bakkercb37aa52011-11-30 16:00:20 +0000590 if( slen == sizeof( s ) - 2 )
591 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
592
Paul Bakker5121ce52009-01-03 21:22:43 +0000593 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
594 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
595
596 p = s + slen;
597 while( --p >= s )
598 if( mpi_get_digit( &d, radix, *p ) != 0 )
599 break;
600
601 return( mpi_read_string( X, radix, p + 1 ) );
602}
603
604/*
605 * Write X into an opened file (or stdout if fout == NULL)
606 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000607int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
Paul Bakker5121ce52009-01-03 21:22:43 +0000608{
Paul Bakker23986e52011-04-24 08:57:21 +0000609 int ret;
610 size_t n, slen, plen;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000611 /*
Paul Bakker5531c6d2012-09-26 19:20:46 +0000612 * Buffer should have space for (short) label and decimal formatted MPI,
613 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000614 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000615 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000616
617 n = sizeof( s );
618 memset( s, 0, n );
619 n -= 2;
620
Paul Bakker23986e52011-04-24 08:57:21 +0000621 MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000622
623 if( p == NULL ) p = "";
624
625 plen = strlen( p );
626 slen = strlen( s );
627 s[slen++] = '\r';
628 s[slen++] = '\n';
629
630 if( fout != NULL )
631 {
632 if( fwrite( p, 1, plen, fout ) != plen ||
633 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000634 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000635 }
636 else
Paul Bakker7dc4c442014-02-01 22:50:26 +0100637 polarssl_printf( "%s%s", p, s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000638
639cleanup:
640
641 return( ret );
642}
Paul Bakker335db3f2011-04-25 15:28:35 +0000643#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000644
645/*
646 * Import X from unsigned binary data, big endian
647 */
Paul Bakker23986e52011-04-24 08:57:21 +0000648int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000649{
Paul Bakker23986e52011-04-24 08:57:21 +0000650 int ret;
651 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000652
653 for( n = 0; n < buflen; n++ )
654 if( buf[n] != 0 )
655 break;
656
657 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
658 MPI_CHK( mpi_lset( X, 0 ) );
659
Paul Bakker23986e52011-04-24 08:57:21 +0000660 for( i = buflen, j = 0; i > n; i--, j++ )
Paul Bakkera755ca12011-04-24 09:11:17 +0000661 X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000662
663cleanup:
664
665 return( ret );
666}
667
668/*
669 * Export X into unsigned binary data, big endian
670 */
Paul Bakker23986e52011-04-24 08:57:21 +0000671int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000672{
Paul Bakker23986e52011-04-24 08:57:21 +0000673 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000674
675 n = mpi_size( X );
676
677 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000678 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000679
680 memset( buf, 0, buflen );
681
682 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
683 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
684
685 return( 0 );
686}
687
688/*
689 * Left-shift: X <<= count
690 */
Paul Bakker23986e52011-04-24 08:57:21 +0000691int mpi_shift_l( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000692{
Paul Bakker23986e52011-04-24 08:57:21 +0000693 int ret;
694 size_t i, v0, t1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000695 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000696
697 v0 = count / (biL );
698 t1 = count & (biL - 1);
699
700 i = mpi_msb( X ) + count;
701
Paul Bakkerf9688572011-05-05 10:00:45 +0000702 if( X->n * biL < i )
Paul Bakker5121ce52009-01-03 21:22:43 +0000703 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
704
705 ret = 0;
706
707 /*
708 * shift by count / limb_size
709 */
710 if( v0 > 0 )
711 {
Paul Bakker23986e52011-04-24 08:57:21 +0000712 for( i = X->n; i > v0; i-- )
713 X->p[i - 1] = X->p[i - v0 - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000714
Paul Bakker23986e52011-04-24 08:57:21 +0000715 for( ; i > 0; i-- )
716 X->p[i - 1] = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000717 }
718
719 /*
720 * shift by count % limb_size
721 */
722 if( t1 > 0 )
723 {
724 for( i = v0; i < X->n; i++ )
725 {
726 r1 = X->p[i] >> (biL - t1);
727 X->p[i] <<= t1;
728 X->p[i] |= r0;
729 r0 = r1;
730 }
731 }
732
733cleanup:
734
735 return( ret );
736}
737
738/*
739 * Right-shift: X >>= count
740 */
Paul Bakker23986e52011-04-24 08:57:21 +0000741int mpi_shift_r( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000742{
Paul Bakker23986e52011-04-24 08:57:21 +0000743 size_t i, v0, v1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000744 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000745
746 v0 = count / biL;
747 v1 = count & (biL - 1);
748
Manuel Pégourié-Gonnarde44ec102012-11-17 12:42:51 +0100749 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
750 return mpi_lset( X, 0 );
751
Paul Bakker5121ce52009-01-03 21:22:43 +0000752 /*
753 * shift by count / limb_size
754 */
755 if( v0 > 0 )
756 {
757 for( i = 0; i < X->n - v0; i++ )
758 X->p[i] = X->p[i + v0];
759
760 for( ; i < X->n; i++ )
761 X->p[i] = 0;
762 }
763
764 /*
765 * shift by count % limb_size
766 */
767 if( v1 > 0 )
768 {
Paul Bakker23986e52011-04-24 08:57:21 +0000769 for( i = X->n; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000770 {
Paul Bakker23986e52011-04-24 08:57:21 +0000771 r1 = X->p[i - 1] << (biL - v1);
772 X->p[i - 1] >>= v1;
773 X->p[i - 1] |= r0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000774 r0 = r1;
775 }
776 }
777
778 return( 0 );
779}
780
781/*
782 * Compare unsigned values
783 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000784int mpi_cmp_abs( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000785{
Paul Bakker23986e52011-04-24 08:57:21 +0000786 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000787
Paul Bakker23986e52011-04-24 08:57:21 +0000788 for( i = X->n; i > 0; i-- )
789 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000790 break;
791
Paul Bakker23986e52011-04-24 08:57:21 +0000792 for( j = Y->n; j > 0; j-- )
793 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000794 break;
795
Paul Bakker23986e52011-04-24 08:57:21 +0000796 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000797 return( 0 );
798
799 if( i > j ) return( 1 );
800 if( j > i ) return( -1 );
801
Paul Bakker23986e52011-04-24 08:57:21 +0000802 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000803 {
Paul Bakker23986e52011-04-24 08:57:21 +0000804 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
805 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000806 }
807
808 return( 0 );
809}
810
811/*
812 * Compare signed values
813 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000814int mpi_cmp_mpi( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000815{
Paul Bakker23986e52011-04-24 08:57:21 +0000816 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000817
Paul Bakker23986e52011-04-24 08:57:21 +0000818 for( i = X->n; i > 0; i-- )
819 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000820 break;
821
Paul Bakker23986e52011-04-24 08:57:21 +0000822 for( j = Y->n; j > 0; j-- )
823 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000824 break;
825
Paul Bakker23986e52011-04-24 08:57:21 +0000826 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000827 return( 0 );
828
829 if( i > j ) return( X->s );
Paul Bakker0c8f73b2012-03-22 14:08:57 +0000830 if( j > i ) return( -Y->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000831
832 if( X->s > 0 && Y->s < 0 ) return( 1 );
833 if( Y->s > 0 && X->s < 0 ) return( -1 );
834
Paul Bakker23986e52011-04-24 08:57:21 +0000835 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000836 {
Paul Bakker23986e52011-04-24 08:57:21 +0000837 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
838 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000839 }
840
841 return( 0 );
842}
843
844/*
845 * Compare signed values
846 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000847int mpi_cmp_int( const mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000848{
849 mpi Y;
Paul Bakkera755ca12011-04-24 09:11:17 +0000850 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000851
852 *p = ( z < 0 ) ? -z : z;
853 Y.s = ( z < 0 ) ? -1 : 1;
854 Y.n = 1;
855 Y.p = p;
856
857 return( mpi_cmp_mpi( X, &Y ) );
858}
859
860/*
861 * Unsigned addition: X = |A| + |B| (HAC 14.7)
862 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000863int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000864{
Paul Bakker23986e52011-04-24 08:57:21 +0000865 int ret;
866 size_t i, j;
Paul Bakkera755ca12011-04-24 09:11:17 +0000867 t_uint *o, *p, c;
Paul Bakker5121ce52009-01-03 21:22:43 +0000868
869 if( X == B )
870 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000871 const mpi *T = A; A = X; B = T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000872 }
873
874 if( X != A )
875 MPI_CHK( mpi_copy( X, A ) );
Paul Bakker9af723c2014-05-01 13:03:14 +0200876
Paul Bakkerf7ca7b92009-06-20 10:31:06 +0000877 /*
878 * X should always be positive as a result of unsigned additions.
879 */
880 X->s = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000881
Paul Bakker23986e52011-04-24 08:57:21 +0000882 for( j = B->n; j > 0; j-- )
883 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000884 break;
885
Paul Bakker23986e52011-04-24 08:57:21 +0000886 MPI_CHK( mpi_grow( X, j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000887
888 o = B->p; p = X->p; c = 0;
889
Paul Bakker23986e52011-04-24 08:57:21 +0000890 for( i = 0; i < j; i++, o++, p++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000891 {
892 *p += c; c = ( *p < c );
893 *p += *o; c += ( *p < *o );
894 }
895
896 while( c != 0 )
897 {
898 if( i >= X->n )
899 {
900 MPI_CHK( mpi_grow( X, i + 1 ) );
901 p = X->p + i;
902 }
903
Paul Bakker2d319fd2012-09-16 21:34:26 +0000904 *p += c; c = ( *p < c ); i++; p++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000905 }
906
907cleanup:
908
909 return( ret );
910}
911
912/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100913 * Helper for mpi subtraction
Paul Bakker5121ce52009-01-03 21:22:43 +0000914 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000915static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
Paul Bakker5121ce52009-01-03 21:22:43 +0000916{
Paul Bakker23986e52011-04-24 08:57:21 +0000917 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +0000918 t_uint c, z;
Paul Bakker5121ce52009-01-03 21:22:43 +0000919
920 for( i = c = 0; i < n; i++, s++, d++ )
921 {
922 z = ( *d < c ); *d -= c;
923 c = ( *d < *s ) + z; *d -= *s;
924 }
925
926 while( c != 0 )
927 {
928 z = ( *d < c ); *d -= c;
929 c = z; i++; d++;
930 }
931}
932
933/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100934 * Unsigned subtraction: X = |A| - |B| (HAC 14.9)
Paul Bakker5121ce52009-01-03 21:22:43 +0000935 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000936int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000937{
938 mpi TB;
Paul Bakker23986e52011-04-24 08:57:21 +0000939 int ret;
940 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000941
942 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000943 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000944
Paul Bakker6c591fa2011-05-05 11:49:20 +0000945 mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000946
947 if( X == B )
948 {
949 MPI_CHK( mpi_copy( &TB, B ) );
950 B = &TB;
951 }
952
953 if( X != A )
954 MPI_CHK( mpi_copy( X, A ) );
955
Paul Bakker1ef7a532009-06-20 10:50:55 +0000956 /*
Paul Bakker60b1d102013-10-29 10:02:51 +0100957 * X should always be positive as a result of unsigned subtractions.
Paul Bakker1ef7a532009-06-20 10:50:55 +0000958 */
959 X->s = 1;
960
Paul Bakker5121ce52009-01-03 21:22:43 +0000961 ret = 0;
962
Paul Bakker23986e52011-04-24 08:57:21 +0000963 for( n = B->n; n > 0; n-- )
964 if( B->p[n - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000965 break;
966
Paul Bakker23986e52011-04-24 08:57:21 +0000967 mpi_sub_hlp( n, B->p, X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000968
969cleanup:
970
Paul Bakker6c591fa2011-05-05 11:49:20 +0000971 mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000972
973 return( ret );
974}
975
976/*
977 * Signed addition: X = A + B
978 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000979int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000980{
981 int ret, s = A->s;
982
983 if( A->s * B->s < 0 )
984 {
985 if( mpi_cmp_abs( A, B ) >= 0 )
986 {
987 MPI_CHK( mpi_sub_abs( X, A, B ) );
988 X->s = s;
989 }
990 else
991 {
992 MPI_CHK( mpi_sub_abs( X, B, A ) );
993 X->s = -s;
994 }
995 }
996 else
997 {
998 MPI_CHK( mpi_add_abs( X, A, B ) );
999 X->s = s;
1000 }
1001
1002cleanup:
1003
1004 return( ret );
1005}
1006
1007/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001008 * Signed subtraction: X = A - B
Paul Bakker5121ce52009-01-03 21:22:43 +00001009 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001010int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001011{
1012 int ret, s = A->s;
1013
1014 if( A->s * B->s > 0 )
1015 {
1016 if( mpi_cmp_abs( A, B ) >= 0 )
1017 {
1018 MPI_CHK( mpi_sub_abs( X, A, B ) );
1019 X->s = s;
1020 }
1021 else
1022 {
1023 MPI_CHK( mpi_sub_abs( X, B, A ) );
1024 X->s = -s;
1025 }
1026 }
1027 else
1028 {
1029 MPI_CHK( mpi_add_abs( X, A, B ) );
1030 X->s = s;
1031 }
1032
1033cleanup:
1034
1035 return( ret );
1036}
1037
1038/*
1039 * Signed addition: X = A + b
1040 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001041int mpi_add_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001042{
1043 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001044 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001045
1046 p[0] = ( b < 0 ) ? -b : b;
1047 _B.s = ( b < 0 ) ? -1 : 1;
1048 _B.n = 1;
1049 _B.p = p;
1050
1051 return( mpi_add_mpi( X, A, &_B ) );
1052}
1053
1054/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001055 * Signed subtraction: X = A - b
Paul Bakker5121ce52009-01-03 21:22:43 +00001056 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001057int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001058{
1059 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001060 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001061
1062 p[0] = ( b < 0 ) ? -b : b;
1063 _B.s = ( b < 0 ) ? -1 : 1;
1064 _B.n = 1;
1065 _B.p = p;
1066
1067 return( mpi_sub_mpi( X, A, &_B ) );
1068}
1069
1070/*
1071 * Helper for mpi multiplication
Paul Bakkerfc4f46f2013-06-24 19:23:56 +02001072 */
1073static
1074#if defined(__APPLE__) && defined(__arm__)
1075/*
1076 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1077 * appears to need this to prevent bad ARM code generation at -O3.
1078 */
1079__attribute__ ((noinline))
1080#endif
1081void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001082{
Paul Bakkera755ca12011-04-24 09:11:17 +00001083 t_uint c = 0, t = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001084
1085#if defined(MULADDC_HUIT)
1086 for( ; i >= 8; i -= 8 )
1087 {
1088 MULADDC_INIT
1089 MULADDC_HUIT
1090 MULADDC_STOP
1091 }
1092
1093 for( ; i > 0; i-- )
1094 {
1095 MULADDC_INIT
1096 MULADDC_CORE
1097 MULADDC_STOP
1098 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001099#else /* MULADDC_HUIT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001100 for( ; i >= 16; i -= 16 )
1101 {
1102 MULADDC_INIT
1103 MULADDC_CORE MULADDC_CORE
1104 MULADDC_CORE MULADDC_CORE
1105 MULADDC_CORE MULADDC_CORE
1106 MULADDC_CORE MULADDC_CORE
1107
1108 MULADDC_CORE MULADDC_CORE
1109 MULADDC_CORE MULADDC_CORE
1110 MULADDC_CORE MULADDC_CORE
1111 MULADDC_CORE MULADDC_CORE
1112 MULADDC_STOP
1113 }
1114
1115 for( ; i >= 8; i -= 8 )
1116 {
1117 MULADDC_INIT
1118 MULADDC_CORE MULADDC_CORE
1119 MULADDC_CORE MULADDC_CORE
1120
1121 MULADDC_CORE MULADDC_CORE
1122 MULADDC_CORE MULADDC_CORE
1123 MULADDC_STOP
1124 }
1125
1126 for( ; i > 0; i-- )
1127 {
1128 MULADDC_INIT
1129 MULADDC_CORE
1130 MULADDC_STOP
1131 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001132#endif /* MULADDC_HUIT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001133
1134 t++;
1135
1136 do {
1137 *d += c; c = ( *d < c ); d++;
1138 }
1139 while( c != 0 );
1140}
1141
1142/*
1143 * Baseline multiplication: X = A * B (HAC 14.12)
1144 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001145int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001146{
Paul Bakker23986e52011-04-24 08:57:21 +00001147 int ret;
1148 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00001149 mpi TA, TB;
1150
Paul Bakker6c591fa2011-05-05 11:49:20 +00001151 mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001152
1153 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
1154 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
1155
Paul Bakker23986e52011-04-24 08:57:21 +00001156 for( i = A->n; i > 0; i-- )
1157 if( A->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001158 break;
1159
Paul Bakker23986e52011-04-24 08:57:21 +00001160 for( j = B->n; j > 0; j-- )
1161 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001162 break;
1163
Paul Bakker23986e52011-04-24 08:57:21 +00001164 MPI_CHK( mpi_grow( X, i + j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001165 MPI_CHK( mpi_lset( X, 0 ) );
1166
Paul Bakker23986e52011-04-24 08:57:21 +00001167 for( i++; j > 0; j-- )
1168 mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001169
1170 X->s = A->s * B->s;
1171
1172cleanup:
1173
Paul Bakker6c591fa2011-05-05 11:49:20 +00001174 mpi_free( &TB ); mpi_free( &TA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001175
1176 return( ret );
1177}
1178
1179/*
1180 * Baseline multiplication: X = A * b
1181 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001182int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001183{
1184 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001185 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001186
1187 _B.s = 1;
1188 _B.n = 1;
1189 _B.p = p;
1190 p[0] = b;
1191
1192 return( mpi_mul_mpi( X, A, &_B ) );
1193}
1194
1195/*
1196 * Division by mpi: A = Q * B + R (HAC 14.20)
1197 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001198int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001199{
Paul Bakker23986e52011-04-24 08:57:21 +00001200 int ret;
1201 size_t i, n, t, k;
Paul Bakker5121ce52009-01-03 21:22:43 +00001202 mpi X, Y, Z, T1, T2;
1203
1204 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001205 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001206
Paul Bakker6c591fa2011-05-05 11:49:20 +00001207 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
1208 mpi_init( &T1 ); mpi_init( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001209
1210 if( mpi_cmp_abs( A, B ) < 0 )
1211 {
1212 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1213 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1214 return( 0 );
1215 }
1216
1217 MPI_CHK( mpi_copy( &X, A ) );
1218 MPI_CHK( mpi_copy( &Y, B ) );
1219 X.s = Y.s = 1;
1220
1221 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1222 MPI_CHK( mpi_lset( &Z, 0 ) );
1223 MPI_CHK( mpi_grow( &T1, 2 ) );
1224 MPI_CHK( mpi_grow( &T2, 3 ) );
1225
1226 k = mpi_msb( &Y ) % biL;
Paul Bakkerf9688572011-05-05 10:00:45 +00001227 if( k < biL - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001228 {
1229 k = biL - 1 - k;
1230 MPI_CHK( mpi_shift_l( &X, k ) );
1231 MPI_CHK( mpi_shift_l( &Y, k ) );
1232 }
1233 else k = 0;
1234
1235 n = X.n - 1;
1236 t = Y.n - 1;
Paul Bakker66d5d072014-06-17 16:39:18 +02001237 MPI_CHK( mpi_shift_l( &Y, biL * ( n - t ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001238
1239 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1240 {
1241 Z.p[n - t]++;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001242 MPI_CHK( mpi_sub_mpi( &X, &X, &Y ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001243 }
Paul Bakker66d5d072014-06-17 16:39:18 +02001244 MPI_CHK( mpi_shift_r( &Y, biL * ( n - t ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001245
1246 for( i = n; i > t ; i-- )
1247 {
1248 if( X.p[i] >= Y.p[t] )
1249 Z.p[i - t - 1] = ~0;
1250 else
1251 {
Manuel Pégourié-Gonnardd72704b2015-02-12 09:38:54 +00001252#if defined(POLARSSL_HAVE_UDBL)
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001253 t_udbl r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001254
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001255 r = (t_udbl) X.p[i] << biL;
1256 r |= (t_udbl) X.p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001257 r /= Y.p[t];
Paul Bakker66d5d072014-06-17 16:39:18 +02001258 if( r > ( (t_udbl) 1 << biL ) - 1 )
1259 r = ( (t_udbl) 1 << biL ) - 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001260
Paul Bakkera755ca12011-04-24 09:11:17 +00001261 Z.p[i - t - 1] = (t_uint) r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001262#else
1263 /*
1264 * __udiv_qrnnd_c, from gmp/longlong.h
1265 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001266 t_uint q0, q1, r0, r1;
1267 t_uint d0, d1, d, m;
Paul Bakker5121ce52009-01-03 21:22:43 +00001268
1269 d = Y.p[t];
1270 d0 = ( d << biH ) >> biH;
1271 d1 = ( d >> biH );
1272
1273 q1 = X.p[i] / d1;
1274 r1 = X.p[i] - d1 * q1;
1275 r1 <<= biH;
1276 r1 |= ( X.p[i - 1] >> biH );
1277
1278 m = q1 * d0;
1279 if( r1 < m )
1280 {
1281 q1--, r1 += d;
1282 while( r1 >= d && r1 < m )
1283 q1--, r1 += d;
1284 }
1285 r1 -= m;
1286
1287 q0 = r1 / d1;
1288 r0 = r1 - d1 * q0;
1289 r0 <<= biH;
1290 r0 |= ( X.p[i - 1] << biH ) >> biH;
1291
1292 m = q0 * d0;
1293 if( r0 < m )
1294 {
1295 q0--, r0 += d;
1296 while( r0 >= d && r0 < m )
1297 q0--, r0 += d;
1298 }
1299 r0 -= m;
1300
1301 Z.p[i - t - 1] = ( q1 << biH ) | q0;
Paul Bakkerdb20c102014-06-17 14:34:44 +02001302#endif /* POLARSSL_HAVE_UDBL && !64-bit Apple with Clang 5.0 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001303 }
1304
1305 Z.p[i - t - 1]++;
1306 do
1307 {
1308 Z.p[i - t - 1]--;
1309
1310 MPI_CHK( mpi_lset( &T1, 0 ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001311 T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001312 T1.p[1] = Y.p[t];
1313 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1314
1315 MPI_CHK( mpi_lset( &T2, 0 ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001316 T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
1317 T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001318 T2.p[2] = X.p[i];
1319 }
1320 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1321
1322 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001323 MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001324 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1325
1326 if( mpi_cmp_int( &X, 0 ) < 0 )
1327 {
1328 MPI_CHK( mpi_copy( &T1, &Y ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001329 MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001330 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1331 Z.p[i - t - 1]--;
1332 }
1333 }
1334
1335 if( Q != NULL )
1336 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001337 MPI_CHK( mpi_copy( Q, &Z ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001338 Q->s = A->s * B->s;
1339 }
1340
1341 if( R != NULL )
1342 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001343 MPI_CHK( mpi_shift_r( &X, k ) );
Paul Bakkerf02c5642012-11-13 10:25:21 +00001344 X.s = A->s;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001345 MPI_CHK( mpi_copy( R, &X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001346
Paul Bakker5121ce52009-01-03 21:22:43 +00001347 if( mpi_cmp_int( R, 0 ) == 0 )
1348 R->s = 1;
1349 }
1350
1351cleanup:
1352
Paul Bakker6c591fa2011-05-05 11:49:20 +00001353 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
1354 mpi_free( &T1 ); mpi_free( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001355
1356 return( ret );
1357}
1358
1359/*
1360 * Division by int: A = Q * b + R
Paul Bakker5121ce52009-01-03 21:22:43 +00001361 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001362int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001363{
1364 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001365 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001366
1367 p[0] = ( b < 0 ) ? -b : b;
1368 _B.s = ( b < 0 ) ? -1 : 1;
1369 _B.n = 1;
1370 _B.p = p;
1371
1372 return( mpi_div_mpi( Q, R, A, &_B ) );
1373}
1374
1375/*
1376 * Modulo: R = A mod B
1377 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001378int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001379{
1380 int ret;
1381
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001382 if( mpi_cmp_int( B, 0 ) < 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001383 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001384
Paul Bakker5121ce52009-01-03 21:22:43 +00001385 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1386
1387 while( mpi_cmp_int( R, 0 ) < 0 )
1388 MPI_CHK( mpi_add_mpi( R, R, B ) );
1389
1390 while( mpi_cmp_mpi( R, B ) >= 0 )
1391 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1392
1393cleanup:
1394
1395 return( ret );
1396}
1397
1398/*
1399 * Modulo: r = A mod b
1400 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001401int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001402{
Paul Bakker23986e52011-04-24 08:57:21 +00001403 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +00001404 t_uint x, y, z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001405
1406 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001407 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001408
1409 if( b < 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001410 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001411
1412 /*
1413 * handle trivial cases
1414 */
1415 if( b == 1 )
1416 {
1417 *r = 0;
1418 return( 0 );
1419 }
1420
1421 if( b == 2 )
1422 {
1423 *r = A->p[0] & 1;
1424 return( 0 );
1425 }
1426
1427 /*
1428 * general case
1429 */
Paul Bakker23986e52011-04-24 08:57:21 +00001430 for( i = A->n, y = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001431 {
Paul Bakker23986e52011-04-24 08:57:21 +00001432 x = A->p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001433 y = ( y << biH ) | ( x >> biH );
1434 z = y / b;
1435 y -= z * b;
1436
1437 x <<= biH;
1438 y = ( y << biH ) | ( x >> biH );
1439 z = y / b;
1440 y -= z * b;
1441 }
1442
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001443 /*
1444 * If A is negative, then the current y represents a negative value.
1445 * Flipping it to the positive side.
1446 */
1447 if( A->s < 0 && y != 0 )
1448 y = b - y;
1449
Paul Bakker5121ce52009-01-03 21:22:43 +00001450 *r = y;
1451
1452 return( 0 );
1453}
1454
1455/*
1456 * Fast Montgomery initialization (thanks to Tom St Denis)
1457 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001458static void mpi_montg_init( t_uint *mm, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001459{
Paul Bakkera755ca12011-04-24 09:11:17 +00001460 t_uint x, m0 = N->p[0];
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001461 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001462
1463 x = m0;
1464 x += ( ( m0 + 2 ) & 4 ) << 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001465
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001466 for( i = biL; i >= 8; i /= 2 )
1467 x *= ( 2 - ( m0 * x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001468
1469 *mm = ~x + 1;
1470}
1471
1472/*
1473 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1474 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +02001475static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm,
1476 const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001477{
Paul Bakker23986e52011-04-24 08:57:21 +00001478 size_t i, n, m;
Paul Bakkera755ca12011-04-24 09:11:17 +00001479 t_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00001480
1481 memset( T->p, 0, T->n * ciL );
1482
1483 d = T->p;
1484 n = N->n;
1485 m = ( B->n < n ) ? B->n : n;
1486
1487 for( i = 0; i < n; i++ )
1488 {
1489 /*
1490 * T = (T + u0*B + u1*N) / 2^biL
1491 */
1492 u0 = A->p[i];
1493 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1494
1495 mpi_mul_hlp( m, B->p, d, u0 );
1496 mpi_mul_hlp( n, N->p, d, u1 );
1497
1498 *d++ = u0; d[n + 1] = 0;
1499 }
1500
Paul Bakker66d5d072014-06-17 16:39:18 +02001501 memcpy( A->p, d, ( n + 1 ) * ciL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001502
1503 if( mpi_cmp_abs( A, N ) >= 0 )
1504 mpi_sub_hlp( n, N->p, A->p );
1505 else
1506 /* prevent timing attacks */
1507 mpi_sub_hlp( n, A->p, T->p );
1508}
1509
1510/*
1511 * Montgomery reduction: A = A * R^-1 mod N
1512 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001513static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001514{
Paul Bakkera755ca12011-04-24 09:11:17 +00001515 t_uint z = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001516 mpi U;
1517
Paul Bakker8ddb6452013-02-27 14:56:33 +01001518 U.n = U.s = (int) z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001519 U.p = &z;
1520
1521 mpi_montmul( A, &U, N, mm, T );
1522}
1523
1524/*
1525 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1526 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001527int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00001528{
Paul Bakker23986e52011-04-24 08:57:21 +00001529 int ret;
1530 size_t wbits, wsize, one = 1;
1531 size_t i, j, nblimbs;
1532 size_t bufsize, nbits;
Paul Bakkera755ca12011-04-24 09:11:17 +00001533 t_uint ei, mm, state;
Paul Bakkerf6198c12012-05-16 08:02:29 +00001534 mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos;
1535 int neg;
Paul Bakker5121ce52009-01-03 21:22:43 +00001536
1537 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001538 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001539
Paul Bakkerf6198c12012-05-16 08:02:29 +00001540 if( mpi_cmp_int( E, 0 ) < 0 )
1541 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
1542
1543 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001544 * Init temps and window size
1545 */
1546 mpi_montg_init( &mm, N );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001547 mpi_init( &RR ); mpi_init( &T );
Manuel Pégourié-Gonnardfd6a1912014-01-18 19:05:23 +01001548 mpi_init( &Apos );
Paul Bakker5121ce52009-01-03 21:22:43 +00001549 memset( W, 0, sizeof( W ) );
1550
1551 i = mpi_msb( E );
1552
1553 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1554 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1555
Paul Bakkerb6d5f082011-11-25 11:52:11 +00001556 if( wsize > POLARSSL_MPI_WINDOW_SIZE )
1557 wsize = POLARSSL_MPI_WINDOW_SIZE;
1558
Paul Bakker5121ce52009-01-03 21:22:43 +00001559 j = N->n + 1;
1560 MPI_CHK( mpi_grow( X, j ) );
1561 MPI_CHK( mpi_grow( &W[1], j ) );
1562 MPI_CHK( mpi_grow( &T, j * 2 ) );
1563
1564 /*
Paul Bakker50546922012-05-19 08:40:49 +00001565 * Compensate for negative A (and correct at the end)
1566 */
1567 neg = ( A->s == -1 );
Paul Bakker50546922012-05-19 08:40:49 +00001568 if( neg )
1569 {
1570 MPI_CHK( mpi_copy( &Apos, A ) );
1571 Apos.s = 1;
1572 A = &Apos;
1573 }
1574
1575 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001576 * If 1st call, pre-compute R^2 mod N
1577 */
1578 if( _RR == NULL || _RR->p == NULL )
1579 {
1580 MPI_CHK( mpi_lset( &RR, 1 ) );
1581 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1582 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1583
1584 if( _RR != NULL )
1585 memcpy( _RR, &RR, sizeof( mpi ) );
1586 }
1587 else
1588 memcpy( &RR, _RR, sizeof( mpi ) );
1589
1590 /*
1591 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1592 */
1593 if( mpi_cmp_mpi( A, N ) >= 0 )
Paul Bakkerc2024f42014-01-23 20:38:35 +01001594 MPI_CHK( mpi_mod_mpi( &W[1], A, N ) );
1595 else
1596 MPI_CHK( mpi_copy( &W[1], A ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001597
1598 mpi_montmul( &W[1], &RR, N, mm, &T );
1599
1600 /*
1601 * X = R^2 * R^-1 mod N = R mod N
1602 */
1603 MPI_CHK( mpi_copy( X, &RR ) );
1604 mpi_montred( X, N, mm, &T );
1605
1606 if( wsize > 1 )
1607 {
1608 /*
1609 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1610 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001611 j = one << ( wsize - 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001612
1613 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1614 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1615
1616 for( i = 0; i < wsize - 1; i++ )
1617 mpi_montmul( &W[j], &W[j], N, mm, &T );
Paul Bakker0d7702c2013-10-29 16:18:35 +01001618
Paul Bakker5121ce52009-01-03 21:22:43 +00001619 /*
1620 * W[i] = W[i - 1] * W[1]
1621 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001622 for( i = j + 1; i < ( one << wsize ); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001623 {
1624 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1625 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1626
1627 mpi_montmul( &W[i], &W[1], N, mm, &T );
1628 }
1629 }
1630
1631 nblimbs = E->n;
1632 bufsize = 0;
1633 nbits = 0;
1634 wbits = 0;
1635 state = 0;
1636
1637 while( 1 )
1638 {
1639 if( bufsize == 0 )
1640 {
Paul Bakker0d7702c2013-10-29 16:18:35 +01001641 if( nblimbs == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001642 break;
1643
Paul Bakker0d7702c2013-10-29 16:18:35 +01001644 nblimbs--;
1645
Paul Bakkera755ca12011-04-24 09:11:17 +00001646 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001647 }
1648
1649 bufsize--;
1650
1651 ei = (E->p[nblimbs] >> bufsize) & 1;
1652
1653 /*
1654 * skip leading 0s
1655 */
1656 if( ei == 0 && state == 0 )
1657 continue;
1658
1659 if( ei == 0 && state == 1 )
1660 {
1661 /*
1662 * out of window, square X
1663 */
1664 mpi_montmul( X, X, N, mm, &T );
1665 continue;
1666 }
1667
1668 /*
1669 * add ei to current window
1670 */
1671 state = 2;
1672
1673 nbits++;
Paul Bakker66d5d072014-06-17 16:39:18 +02001674 wbits |= ( ei << ( wsize - nbits ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001675
1676 if( nbits == wsize )
1677 {
1678 /*
1679 * X = X^wsize R^-1 mod N
1680 */
1681 for( i = 0; i < wsize; i++ )
1682 mpi_montmul( X, X, N, mm, &T );
1683
1684 /*
1685 * X = X * W[wbits] R^-1 mod N
1686 */
1687 mpi_montmul( X, &W[wbits], N, mm, &T );
1688
1689 state--;
1690 nbits = 0;
1691 wbits = 0;
1692 }
1693 }
1694
1695 /*
1696 * process the remaining bits
1697 */
1698 for( i = 0; i < nbits; i++ )
1699 {
1700 mpi_montmul( X, X, N, mm, &T );
1701
1702 wbits <<= 1;
1703
Paul Bakker66d5d072014-06-17 16:39:18 +02001704 if( ( wbits & ( one << wsize ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001705 mpi_montmul( X, &W[1], N, mm, &T );
1706 }
1707
1708 /*
1709 * X = A^E * R * R^-1 mod N = A^E mod N
1710 */
1711 mpi_montred( X, N, mm, &T );
1712
Paul Bakkerf6198c12012-05-16 08:02:29 +00001713 if( neg )
1714 {
1715 X->s = -1;
Paul Bakkerc2024f42014-01-23 20:38:35 +01001716 MPI_CHK( mpi_add_mpi( X, N, X ) );
Paul Bakkerf6198c12012-05-16 08:02:29 +00001717 }
1718
Paul Bakker5121ce52009-01-03 21:22:43 +00001719cleanup:
1720
Paul Bakker66d5d072014-06-17 16:39:18 +02001721 for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001722 mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001723
Paul Bakkerf6198c12012-05-16 08:02:29 +00001724 mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001725
Paul Bakker75a28602014-03-31 12:08:17 +02001726 if( _RR == NULL || _RR->p == NULL )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001727 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001728
1729 return( ret );
1730}
1731
Paul Bakker5121ce52009-01-03 21:22:43 +00001732/*
1733 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1734 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001735int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001736{
Paul Bakker23986e52011-04-24 08:57:21 +00001737 int ret;
1738 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001739 mpi TG, TA, TB;
1740
Paul Bakker6c591fa2011-05-05 11:49:20 +00001741 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001742
Paul Bakker5121ce52009-01-03 21:22:43 +00001743 MPI_CHK( mpi_copy( &TA, A ) );
1744 MPI_CHK( mpi_copy( &TB, B ) );
1745
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001746 lz = mpi_lsb( &TA );
1747 lzt = mpi_lsb( &TB );
1748
Paul Bakker66d5d072014-06-17 16:39:18 +02001749 if( lzt < lz )
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001750 lz = lzt;
1751
1752 MPI_CHK( mpi_shift_r( &TA, lz ) );
1753 MPI_CHK( mpi_shift_r( &TB, lz ) );
1754
Paul Bakker5121ce52009-01-03 21:22:43 +00001755 TA.s = TB.s = 1;
1756
1757 while( mpi_cmp_int( &TA, 0 ) != 0 )
1758 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001759 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1760 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001761
1762 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1763 {
1764 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1765 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1766 }
1767 else
1768 {
1769 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1770 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1771 }
1772 }
1773
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001774 MPI_CHK( mpi_shift_l( &TB, lz ) );
1775 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001776
1777cleanup:
1778
Paul Bakker6c591fa2011-05-05 11:49:20 +00001779 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001780
1781 return( ret );
1782}
1783
Paul Bakker33dc46b2014-04-30 16:11:39 +02001784/*
1785 * Fill X with size bytes of random.
1786 *
1787 * Use a temporary bytes representation to make sure the result is the same
Paul Bakkerc37b0ac2014-05-01 14:19:23 +02001788 * regardless of the platform endianness (useful when f_rng is actually
Paul Bakker33dc46b2014-04-30 16:11:39 +02001789 * deterministic, eg for tests).
1790 */
Paul Bakkera3d195c2011-11-27 21:07:34 +00001791int mpi_fill_random( mpi *X, size_t size,
1792 int (*f_rng)(void *, unsigned char *, size_t),
1793 void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001794{
Paul Bakker23986e52011-04-24 08:57:21 +00001795 int ret;
Paul Bakker33dc46b2014-04-30 16:11:39 +02001796 unsigned char buf[POLARSSL_MPI_MAX_SIZE];
1797
1798 if( size > POLARSSL_MPI_MAX_SIZE )
1799 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker287781a2011-03-26 13:18:49 +00001800
Paul Bakker33dc46b2014-04-30 16:11:39 +02001801 MPI_CHK( f_rng( p_rng, buf, size ) );
1802 MPI_CHK( mpi_read_binary( X, buf, size ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001803
1804cleanup:
1805 return( ret );
1806}
1807
Paul Bakker5121ce52009-01-03 21:22:43 +00001808/*
1809 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1810 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001811int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001812{
1813 int ret;
1814 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1815
1816 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001817 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001818
Paul Bakker6c591fa2011-05-05 11:49:20 +00001819 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1820 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1821 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001822
1823 MPI_CHK( mpi_gcd( &G, A, N ) );
1824
1825 if( mpi_cmp_int( &G, 1 ) != 0 )
1826 {
Paul Bakker40e46942009-01-03 21:51:57 +00001827 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001828 goto cleanup;
1829 }
1830
1831 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1832 MPI_CHK( mpi_copy( &TU, &TA ) );
1833 MPI_CHK( mpi_copy( &TB, N ) );
1834 MPI_CHK( mpi_copy( &TV, N ) );
1835
1836 MPI_CHK( mpi_lset( &U1, 1 ) );
1837 MPI_CHK( mpi_lset( &U2, 0 ) );
1838 MPI_CHK( mpi_lset( &V1, 0 ) );
1839 MPI_CHK( mpi_lset( &V2, 1 ) );
1840
1841 do
1842 {
1843 while( ( TU.p[0] & 1 ) == 0 )
1844 {
1845 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1846
1847 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1848 {
1849 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1850 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1851 }
1852
1853 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1854 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1855 }
1856
1857 while( ( TV.p[0] & 1 ) == 0 )
1858 {
1859 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1860
1861 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1862 {
1863 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1864 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1865 }
1866
1867 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1868 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1869 }
1870
1871 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1872 {
1873 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1874 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1875 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1876 }
1877 else
1878 {
1879 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1880 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1881 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1882 }
1883 }
1884 while( mpi_cmp_int( &TU, 0 ) != 0 );
1885
1886 while( mpi_cmp_int( &V1, 0 ) < 0 )
1887 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1888
1889 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1890 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1891
1892 MPI_CHK( mpi_copy( X, &V1 ) );
1893
1894cleanup:
1895
Paul Bakker6c591fa2011-05-05 11:49:20 +00001896 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1897 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1898 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001899
1900 return( ret );
1901}
1902
Paul Bakkerd9374b02012-11-02 11:02:58 +00001903#if defined(POLARSSL_GENPRIME)
1904
Paul Bakker5121ce52009-01-03 21:22:43 +00001905static const int small_prime[] =
1906{
1907 3, 5, 7, 11, 13, 17, 19, 23,
1908 29, 31, 37, 41, 43, 47, 53, 59,
1909 61, 67, 71, 73, 79, 83, 89, 97,
1910 101, 103, 107, 109, 113, 127, 131, 137,
1911 139, 149, 151, 157, 163, 167, 173, 179,
1912 181, 191, 193, 197, 199, 211, 223, 227,
1913 229, 233, 239, 241, 251, 257, 263, 269,
1914 271, 277, 281, 283, 293, 307, 311, 313,
1915 317, 331, 337, 347, 349, 353, 359, 367,
1916 373, 379, 383, 389, 397, 401, 409, 419,
1917 421, 431, 433, 439, 443, 449, 457, 461,
1918 463, 467, 479, 487, 491, 499, 503, 509,
1919 521, 523, 541, 547, 557, 563, 569, 571,
1920 577, 587, 593, 599, 601, 607, 613, 617,
1921 619, 631, 641, 643, 647, 653, 659, 661,
1922 673, 677, 683, 691, 701, 709, 719, 727,
1923 733, 739, 743, 751, 757, 761, 769, 773,
1924 787, 797, 809, 811, 821, 823, 827, 829,
1925 839, 853, 857, 859, 863, 877, 881, 883,
1926 887, 907, 911, 919, 929, 937, 941, 947,
1927 953, 967, 971, 977, 983, 991, 997, -103
1928};
1929
1930/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001931 * Small divisors test (X must be positive)
1932 *
1933 * Return values:
1934 * 0: no small factor (possible prime, more tests needed)
1935 * 1: certain prime
1936 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
1937 * other negative: error
Paul Bakker5121ce52009-01-03 21:22:43 +00001938 */
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001939static int mpi_check_small_factors( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +00001940{
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001941 int ret = 0;
1942 size_t i;
1943 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001944
Paul Bakker5121ce52009-01-03 21:22:43 +00001945 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001946 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001947
1948 for( i = 0; small_prime[i] > 0; i++ )
1949 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001950 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001951 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001952
1953 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1954
1955 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001956 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001957 }
1958
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001959cleanup:
1960 return( ret );
1961}
1962
1963/*
1964 * Miller-Rabin pseudo-primality test (HAC 4.24)
1965 */
1966static int mpi_miller_rabin( const mpi *X,
1967 int (*f_rng)(void *, unsigned char *, size_t),
1968 void *p_rng )
1969{
Pascal Junodb99183d2015-03-11 16:49:45 +01001970 int ret, count;
1971 size_t i, j, k, n, s;
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001972 mpi W, R, T, A, RR;
1973
1974 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1975 mpi_init( &RR );
1976
Paul Bakker5121ce52009-01-03 21:22:43 +00001977 /*
1978 * W = |X| - 1
1979 * R = W >> lsb( W )
1980 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001981 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001982 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001983 MPI_CHK( mpi_copy( &R, &W ) );
1984 MPI_CHK( mpi_shift_r( &R, s ) );
1985
1986 i = mpi_msb( X );
1987 /*
1988 * HAC, table 4.4
1989 */
1990 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1991 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1992 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1993
1994 for( i = 0; i < n; i++ )
1995 {
1996 /*
1997 * pick a random A, 1 < A < |X| - 1
1998 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001999
Pascal Junodb99183d2015-03-11 16:49:45 +01002000 count = 0;
2001 do {
2002 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
2003
2004 j = mpi_msb( &A );
2005 k = mpi_msb( &W );
2006 if (j > k) {
2007 MPI_CHK( mpi_shift_r( &A, j - k ) );
2008 }
2009
2010 if (count++ > 30) {
2011 return POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
2012 }
2013
2014 } while ( (mpi_cmp_mpi( &A, &W ) >= 0) ||
2015 (mpi_cmp_int( &A, 1 ) <= 0) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002016
2017 /*
2018 * A = A^R mod |X|
2019 */
2020 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
2021
2022 if( mpi_cmp_mpi( &A, &W ) == 0 ||
2023 mpi_cmp_int( &A, 1 ) == 0 )
2024 continue;
2025
2026 j = 1;
2027 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
2028 {
2029 /*
2030 * A = A * A mod |X|
2031 */
2032 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
2033 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
2034
2035 if( mpi_cmp_int( &A, 1 ) == 0 )
2036 break;
2037
2038 j++;
2039 }
2040
2041 /*
2042 * not prime if A != |X| - 1 or A == 1
2043 */
2044 if( mpi_cmp_mpi( &A, &W ) != 0 ||
2045 mpi_cmp_int( &A, 1 ) == 0 )
2046 {
Paul Bakker40e46942009-01-03 21:51:57 +00002047 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002048 break;
2049 }
2050 }
2051
2052cleanup:
Paul Bakker6c591fa2011-05-05 11:49:20 +00002053 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
2054 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002055
2056 return( ret );
2057}
2058
2059/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002060 * Pseudo-primality test: small factors, then Miller-Rabin
2061 */
Paul Bakker45f457d2013-11-25 14:26:52 +01002062int mpi_is_prime( mpi *X,
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002063 int (*f_rng)(void *, unsigned char *, size_t),
2064 void *p_rng )
2065{
2066 int ret;
Manuel Pégourié-Gonnard7f4ed672014-10-14 20:56:02 +02002067 mpi XX;
2068
2069 XX.s = 1;
2070 XX.n = X->n;
2071 XX.p = X->p;
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002072
2073 if( mpi_cmp_int( &XX, 0 ) == 0 ||
2074 mpi_cmp_int( &XX, 1 ) == 0 )
2075 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
2076
2077 if( mpi_cmp_int( &XX, 2 ) == 0 )
2078 return( 0 );
2079
2080 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2081 {
2082 if( ret == 1 )
2083 return( 0 );
2084
2085 return( ret );
2086 }
2087
2088 return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
2089}
2090
2091/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002092 * Prime number generation
2093 */
Paul Bakker23986e52011-04-24 08:57:21 +00002094int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002095 int (*f_rng)(void *, unsigned char *, size_t),
2096 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +00002097{
Paul Bakker23986e52011-04-24 08:57:21 +00002098 int ret;
2099 size_t k, n;
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002100 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002101 mpi Y;
2102
Paul Bakkerfe3256e2011-11-25 12:11:43 +00002103 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
Paul Bakker40e46942009-01-03 21:51:57 +00002104 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002105
Paul Bakker6c591fa2011-05-05 11:49:20 +00002106 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002107
2108 n = BITS_TO_LIMBS( nbits );
2109
Paul Bakker901c6562012-04-20 13:25:38 +00002110 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002111
2112 k = mpi_msb( X );
Pascal Junodb99183d2015-03-11 16:49:45 +01002113 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits + 1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002114
Pascal Junodb99183d2015-03-11 16:49:45 +01002115 mpi_set_bit( X, nbits-1, 1 );
2116
2117 X->p[0] |= 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002118
2119 if( dh_flag == 0 )
2120 {
2121 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
2122 {
Paul Bakker40e46942009-01-03 21:51:57 +00002123 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002124 goto cleanup;
2125
2126 MPI_CHK( mpi_add_int( X, X, 2 ) );
2127 }
2128 }
2129 else
2130 {
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002131 /*
2132 * An necessary condition for Y and X = 2Y + 1 to be prime
2133 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2134 * Make sure it is satisfied, while keeping X = 3 mod 4
2135 */
Pascal Junodb99183d2015-03-11 16:49:45 +01002136
2137 X->p[0] |= 2;
2138
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002139 MPI_CHK( mpi_mod_int( &r, X, 3 ) );
2140 if( r == 0 )
2141 MPI_CHK( mpi_add_int( X, X, 8 ) );
2142 else if( r == 1 )
2143 MPI_CHK( mpi_add_int( X, X, 4 ) );
2144
2145 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2146 MPI_CHK( mpi_copy( &Y, X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002147 MPI_CHK( mpi_shift_r( &Y, 1 ) );
2148
2149 while( 1 )
2150 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002151 /*
2152 * First, check small factors for X and Y
2153 * before doing Miller-Rabin on any of them
2154 */
2155 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2156 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2157 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
2158 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002159 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002160 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002161 }
2162
Paul Bakker40e46942009-01-03 21:51:57 +00002163 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002164 goto cleanup;
2165
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002166 /*
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002167 * Next candidates. We want to preserve Y = (X-1) / 2 and
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002168 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2169 * so up Y by 6 and X by 12.
2170 */
2171 MPI_CHK( mpi_add_int( X, X, 12 ) );
2172 MPI_CHK( mpi_add_int( &Y, &Y, 6 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002173 }
2174 }
2175
2176cleanup:
2177
Paul Bakker6c591fa2011-05-05 11:49:20 +00002178 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002179
2180 return( ret );
2181}
2182
Manuel Pégourié-Gonnarddf0142b2013-08-22 18:29:07 +02002183#endif /* POLARSSL_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00002184
Paul Bakker40e46942009-01-03 21:51:57 +00002185#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002186
Paul Bakker23986e52011-04-24 08:57:21 +00002187#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002188
2189static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2190{
2191 { 693, 609, 21 },
2192 { 1764, 868, 28 },
2193 { 768454923, 542167814, 1 }
2194};
2195
Paul Bakker5121ce52009-01-03 21:22:43 +00002196/*
2197 * Checkup routine
2198 */
2199int mpi_self_test( int verbose )
2200{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002201 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00002202 mpi A, E, N, X, Y, U, V;
2203
Paul Bakker6c591fa2011-05-05 11:49:20 +00002204 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
2205 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002206
2207 MPI_CHK( mpi_read_string( &A, 16,
2208 "EFE021C2645FD1DC586E69184AF4A31E" \
2209 "D5F53E93B5F123FA41680867BA110131" \
2210 "944FE7952E2517337780CB0DB80E61AA" \
2211 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2212
2213 MPI_CHK( mpi_read_string( &E, 16,
2214 "B2E7EFD37075B9F03FF989C7C5051C20" \
2215 "34D2A323810251127E7BF8625A4F49A5" \
2216 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2217 "5B5C25763222FEFCCFC38B832366C29E" ) );
2218
2219 MPI_CHK( mpi_read_string( &N, 16,
2220 "0066A198186C18C10B2F5ED9B522752A" \
2221 "9830B69916E535C8F047518A889A43A5" \
2222 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2223
2224 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
2225
2226 MPI_CHK( mpi_read_string( &U, 16,
2227 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2228 "9E857EA95A03512E2BAE7391688D264A" \
2229 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2230 "8001B72E848A38CAE1C65F78E56ABDEF" \
2231 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2232 "ECF677152EF804370C1A305CAF3B5BF1" \
2233 "30879B56C61DE584A0F53A2447A51E" ) );
2234
2235 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002236 polarssl_printf( " MPI test #1 (mul_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002237
2238 if( mpi_cmp_mpi( &X, &U ) != 0 )
2239 {
2240 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002241 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002242
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002243 ret = 1;
2244 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002245 }
2246
2247 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002248 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002249
2250 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
2251
2252 MPI_CHK( mpi_read_string( &U, 16,
2253 "256567336059E52CAE22925474705F39A94" ) );
2254
2255 MPI_CHK( mpi_read_string( &V, 16,
2256 "6613F26162223DF488E9CD48CC132C7A" \
2257 "0AC93C701B001B092E4E5B9F73BCD27B" \
2258 "9EE50D0657C77F374E903CDFA4C642" ) );
2259
2260 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002261 polarssl_printf( " MPI test #2 (div_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002262
2263 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2264 mpi_cmp_mpi( &Y, &V ) != 0 )
2265 {
2266 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002267 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002268
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002269 ret = 1;
2270 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002271 }
2272
2273 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002274 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002275
2276 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2277
2278 MPI_CHK( mpi_read_string( &U, 16,
2279 "36E139AEA55215609D2816998ED020BB" \
2280 "BD96C37890F65171D948E9BC7CBAA4D9" \
2281 "325D24D6A3C12710F10A09FA08AB87" ) );
2282
2283 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002284 polarssl_printf( " MPI test #3 (exp_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002285
2286 if( mpi_cmp_mpi( &X, &U ) != 0 )
2287 {
2288 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002289 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002290
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002291 ret = 1;
2292 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002293 }
2294
2295 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002296 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002297
2298 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2299
2300 MPI_CHK( mpi_read_string( &U, 16,
2301 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2302 "C3DBA76456363A10869622EAC2DD84EC" \
2303 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2304
2305 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002306 polarssl_printf( " MPI test #4 (inv_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002307
2308 if( mpi_cmp_mpi( &X, &U ) != 0 )
2309 {
2310 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002311 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002312
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002313 ret = 1;
2314 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002315 }
2316
2317 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002318 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002319
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002320 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002321 polarssl_printf( " MPI test #5 (simple gcd): " );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002322
Paul Bakker66d5d072014-06-17 16:39:18 +02002323 for( i = 0; i < GCD_PAIR_COUNT; i++ )
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002324 {
2325 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002326 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002327
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002328 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002329
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002330 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2331 {
2332 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002333 polarssl_printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002334
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002335 ret = 1;
2336 goto cleanup;
2337 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002338 }
2339
2340 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002341 polarssl_printf( "passed\n" );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002342
Paul Bakker5121ce52009-01-03 21:22:43 +00002343cleanup:
2344
2345 if( ret != 0 && verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002346 polarssl_printf( "Unexpected error, return code = %08X\n", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002347
Paul Bakker6c591fa2011-05-05 11:49:20 +00002348 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2349 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002350
2351 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002352 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002353
2354 return( ret );
2355}
2356
Paul Bakker9af723c2014-05-01 13:03:14 +02002357#endif /* POLARSSL_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002358
Paul Bakker9af723c2014-05-01 13:03:14 +02002359#endif /* POLARSSL_BIGNUM_C */