blob: 0eb95ee4eb5f46de7a0f605308bbf7f00d72186c [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é-Gonnard860b5162015-01-28 17:12:07 +00006 * This file is part of mbed TLS (https://polarssl.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
Paul Bakker7dc4c442014-02-01 22:50:26 +010041#if defined(POLARSSL_PLATFORM_C)
42#include "polarssl/platform.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020043#else
Paul Bakker7dc4c442014-02-01 22:50:26 +010044#define polarssl_printf printf
Paul Bakker6e339b52013-07-03 13:37:05 +020045#define polarssl_malloc malloc
46#define polarssl_free free
47#endif
48
Paul Bakker5121ce52009-01-03 21:22:43 +000049#include <stdlib.h>
Paul Bakker5121ce52009-01-03 21:22:43 +000050
Paul Bakker34617722014-06-13 17:20:13 +020051/* Implementation that should never be optimized out by the compiler */
52static void polarssl_zeroize( void *v, size_t n ) {
53 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
54}
55
Paul Bakkerf9688572011-05-05 10:00:45 +000056#define ciL (sizeof(t_uint)) /* chars in limb */
Paul Bakker5121ce52009-01-03 21:22:43 +000057#define biL (ciL << 3) /* bits in limb */
58#define biH (ciL << 2) /* half limb size */
59
60/*
61 * Convert between bits/chars and number of limbs
62 */
63#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
64#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
65
66/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000067 * Initialize one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000068 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000069void mpi_init( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000070{
Paul Bakker6c591fa2011-05-05 11:49:20 +000071 if( X == NULL )
72 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000073
Paul Bakker6c591fa2011-05-05 11:49:20 +000074 X->s = 1;
75 X->n = 0;
76 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000077}
78
79/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000080 * Unallocate one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000081 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000082void mpi_free( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000083{
Paul Bakker6c591fa2011-05-05 11:49:20 +000084 if( X == NULL )
85 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000086
Paul Bakker6c591fa2011-05-05 11:49:20 +000087 if( X->p != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +000088 {
Paul Bakker34617722014-06-13 17:20:13 +020089 polarssl_zeroize( X->p, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +020090 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +000091 }
92
Paul Bakker6c591fa2011-05-05 11:49:20 +000093 X->s = 1;
94 X->n = 0;
95 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000096}
97
98/*
99 * Enlarge to the specified number of limbs
100 */
Paul Bakker23986e52011-04-24 08:57:21 +0000101int mpi_grow( mpi *X, size_t nblimbs )
Paul Bakker5121ce52009-01-03 21:22:43 +0000102{
Paul Bakkera755ca12011-04-24 09:11:17 +0000103 t_uint *p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000104
Paul Bakkerf9688572011-05-05 10:00:45 +0000105 if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
Paul Bakker69e095c2011-12-10 21:55:01 +0000106 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakkerf9688572011-05-05 10:00:45 +0000107
Paul Bakker5121ce52009-01-03 21:22:43 +0000108 if( X->n < nblimbs )
109 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200110 if( ( p = (t_uint *) polarssl_malloc( nblimbs * ciL ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000111 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000112
113 memset( p, 0, nblimbs * ciL );
114
115 if( X->p != NULL )
116 {
117 memcpy( p, X->p, X->n * ciL );
Paul Bakker34617722014-06-13 17:20:13 +0200118 polarssl_zeroize( X->p, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +0200119 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000120 }
121
122 X->n = nblimbs;
123 X->p = p;
124 }
125
126 return( 0 );
127}
128
129/*
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100130 * Resize down as much as possible,
131 * while keeping at least the specified number of limbs
132 */
133int mpi_shrink( mpi *X, size_t nblimbs )
134{
135 t_uint *p;
136 size_t i;
137
138 /* Actually resize up in this case */
139 if( X->n <= nblimbs )
140 return( mpi_grow( X, nblimbs ) );
141
142 for( i = X->n - 1; i > 0; i-- )
143 if( X->p[i] != 0 )
144 break;
145 i++;
146
147 if( i < nblimbs )
148 i = nblimbs;
149
150 if( ( p = (t_uint *) polarssl_malloc( i * ciL ) ) == NULL )
151 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
152
153 memset( p, 0, i * ciL );
154
155 if( X->p != NULL )
156 {
157 memcpy( p, X->p, i * ciL );
Paul Bakker34617722014-06-13 17:20:13 +0200158 polarssl_zeroize( X->p, X->n * ciL );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100159 polarssl_free( X->p );
160 }
161
162 X->n = i;
163 X->p = p;
164
165 return( 0 );
166}
167
168/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000169 * Copy the contents of Y into X
170 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000171int mpi_copy( mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000172{
Paul Bakker23986e52011-04-24 08:57:21 +0000173 int ret;
174 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000175
176 if( X == Y )
177 return( 0 );
178
Manuel Pégourié-Gonnardf4999932013-08-12 17:02:59 +0200179 if( Y->p == NULL )
180 {
181 mpi_free( X );
182 return( 0 );
183 }
184
Paul Bakker5121ce52009-01-03 21:22:43 +0000185 for( i = Y->n - 1; i > 0; i-- )
186 if( Y->p[i] != 0 )
187 break;
188 i++;
189
190 X->s = Y->s;
191
192 MPI_CHK( mpi_grow( X, i ) );
193
194 memset( X->p, 0, X->n * ciL );
195 memcpy( X->p, Y->p, i * ciL );
196
197cleanup:
198
199 return( ret );
200}
201
202/*
203 * Swap the contents of X and Y
204 */
205void mpi_swap( mpi *X, mpi *Y )
206{
207 mpi T;
208
209 memcpy( &T, X, sizeof( mpi ) );
210 memcpy( X, Y, sizeof( mpi ) );
211 memcpy( Y, &T, sizeof( mpi ) );
212}
213
214/*
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100215 * Conditionally assign X = Y, without leaking information
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100216 * about whether the assignment was made or not.
217 * (Leaking information about the respective sizes of X and Y is ok however.)
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100218 */
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100219int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign )
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100220{
221 int ret = 0;
222 size_t i;
223
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100224 /* make sure assign is 0 or 1 */
225 assign = ( assign != 0 );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100226
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100227 MPI_CHK( mpi_grow( X, Y->n ) );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100228
Paul Bakker66d5d072014-06-17 16:39:18 +0200229 X->s = X->s * ( 1 - assign ) + Y->s * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100230
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100231 for( i = 0; i < Y->n; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200232 X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100233
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100234 for( ; i < X->n; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200235 X->p[i] *= ( 1 - assign );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100236
237cleanup:
238 return( ret );
239}
240
241/*
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100242 * Conditionally swap X and Y, without leaking information
243 * about whether the swap was made or not.
244 * Here it is not ok to simply swap the pointers, which whould lead to
245 * different memory access patterns when X and Y are used afterwards.
246 */
247int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char swap )
248{
249 int ret, s;
250 size_t i;
251 t_uint tmp;
252
253 if( X == Y )
254 return( 0 );
255
256 /* make sure swap is 0 or 1 */
257 swap = ( swap != 0 );
258
259 MPI_CHK( mpi_grow( X, Y->n ) );
260 MPI_CHK( mpi_grow( Y, X->n ) );
261
262 s = X->s;
Paul Bakker66d5d072014-06-17 16:39:18 +0200263 X->s = X->s * ( 1 - swap ) + Y->s * swap;
264 Y->s = Y->s * ( 1 - swap ) + s * swap;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100265
266
267 for( i = 0; i < X->n; i++ )
268 {
269 tmp = X->p[i];
Paul Bakker66d5d072014-06-17 16:39:18 +0200270 X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap;
271 Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100272 }
273
274cleanup:
275 return( ret );
276}
277
278/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000279 * Set value from integer
280 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000281int mpi_lset( mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000282{
283 int ret;
284
285 MPI_CHK( mpi_grow( X, 1 ) );
286 memset( X->p, 0, X->n * ciL );
287
288 X->p[0] = ( z < 0 ) ? -z : z;
289 X->s = ( z < 0 ) ? -1 : 1;
290
291cleanup:
292
293 return( ret );
294}
295
296/*
Paul Bakker2f5947e2011-05-18 15:47:11 +0000297 * Get a specific bit
298 */
Paul Bakker6b906e52012-05-08 12:01:43 +0000299int mpi_get_bit( const mpi *X, size_t pos )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000300{
301 if( X->n * biL <= pos )
302 return( 0 );
303
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200304 return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000305}
306
307/*
308 * Set a bit to a specific value of 0 or 1
309 */
310int mpi_set_bit( mpi *X, size_t pos, unsigned char val )
311{
312 int ret = 0;
313 size_t off = pos / biL;
314 size_t idx = pos % biL;
315
316 if( val != 0 && val != 1 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200317 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker9af723c2014-05-01 13:03:14 +0200318
Paul Bakker2f5947e2011-05-18 15:47:11 +0000319 if( X->n * biL <= pos )
320 {
321 if( val == 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200322 return( 0 );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000323
324 MPI_CHK( mpi_grow( X, off + 1 ) );
325 }
326
Manuel Pégourié-Gonnard9a4a5ac2013-12-04 18:05:29 +0100327 X->p[off] &= ~( (t_uint) 0x01 << idx );
328 X->p[off] |= (t_uint) val << idx;
Paul Bakker2f5947e2011-05-18 15:47:11 +0000329
330cleanup:
Paul Bakker9af723c2014-05-01 13:03:14 +0200331
Paul Bakker2f5947e2011-05-18 15:47:11 +0000332 return( ret );
333}
334
335/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000336 * Return the number of least significant bits
337 */
Paul Bakker23986e52011-04-24 08:57:21 +0000338size_t mpi_lsb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000339{
Paul Bakker23986e52011-04-24 08:57:21 +0000340 size_t i, j, count = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000341
342 for( i = 0; i < X->n; i++ )
Paul Bakkerf9688572011-05-05 10:00:45 +0000343 for( j = 0; j < biL; j++, count++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000344 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
345 return( count );
346
347 return( 0 );
348}
349
350/*
351 * Return the number of most significant bits
352 */
Paul Bakker23986e52011-04-24 08:57:21 +0000353size_t mpi_msb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000354{
Paul Bakker23986e52011-04-24 08:57:21 +0000355 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000356
357 for( i = X->n - 1; i > 0; i-- )
358 if( X->p[i] != 0 )
359 break;
360
Paul Bakker23986e52011-04-24 08:57:21 +0000361 for( j = biL; j > 0; j-- )
362 if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000363 break;
364
Paul Bakker23986e52011-04-24 08:57:21 +0000365 return( ( i * biL ) + j );
Paul Bakker5121ce52009-01-03 21:22:43 +0000366}
367
368/*
369 * Return the total size in bytes
370 */
Paul Bakker23986e52011-04-24 08:57:21 +0000371size_t mpi_size( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000372{
373 return( ( mpi_msb( X ) + 7 ) >> 3 );
374}
375
376/*
377 * Convert an ASCII character to digit value
378 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000379static int mpi_get_digit( t_uint *d, int radix, char c )
Paul Bakker5121ce52009-01-03 21:22:43 +0000380{
381 *d = 255;
382
383 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
384 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
385 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
386
Paul Bakkera755ca12011-04-24 09:11:17 +0000387 if( *d >= (t_uint) radix )
Paul Bakker40e46942009-01-03 21:51:57 +0000388 return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000389
390 return( 0 );
391}
392
393/*
394 * Import from an ASCII string
395 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000396int mpi_read_string( mpi *X, int radix, const char *s )
Paul Bakker5121ce52009-01-03 21:22:43 +0000397{
Paul Bakker23986e52011-04-24 08:57:21 +0000398 int ret;
399 size_t i, j, slen, n;
Paul Bakkera755ca12011-04-24 09:11:17 +0000400 t_uint d;
Paul Bakker5121ce52009-01-03 21:22:43 +0000401 mpi T;
402
403 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000404 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000405
Paul Bakker6c591fa2011-05-05 11:49:20 +0000406 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000407
Paul Bakkerff60ee62010-03-16 21:09:09 +0000408 slen = strlen( s );
409
Paul Bakker5121ce52009-01-03 21:22:43 +0000410 if( radix == 16 )
411 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000412 n = BITS_TO_LIMBS( slen << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000413
414 MPI_CHK( mpi_grow( X, n ) );
415 MPI_CHK( mpi_lset( X, 0 ) );
416
Paul Bakker23986e52011-04-24 08:57:21 +0000417 for( i = slen, j = 0; i > 0; i--, j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000418 {
Paul Bakker23986e52011-04-24 08:57:21 +0000419 if( i == 1 && s[i - 1] == '-' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000420 {
421 X->s = -1;
422 break;
423 }
424
Paul Bakker23986e52011-04-24 08:57:21 +0000425 MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
Paul Bakker66d5d072014-06-17 16:39:18 +0200426 X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000427 }
428 }
429 else
430 {
431 MPI_CHK( mpi_lset( X, 0 ) );
432
Paul Bakkerff60ee62010-03-16 21:09:09 +0000433 for( i = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000434 {
435 if( i == 0 && s[i] == '-' )
436 {
437 X->s = -1;
438 continue;
439 }
440
441 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
442 MPI_CHK( mpi_mul_int( &T, X, radix ) );
Paul Bakker05feca62009-06-20 08:22:43 +0000443
444 if( X->s == 1 )
445 {
446 MPI_CHK( mpi_add_int( X, &T, d ) );
447 }
448 else
449 {
450 MPI_CHK( mpi_sub_int( X, &T, d ) );
451 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000452 }
453 }
454
455cleanup:
456
Paul Bakker6c591fa2011-05-05 11:49:20 +0000457 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000458
459 return( ret );
460}
461
462/*
463 * Helper to write the digits high-order first
464 */
465static int mpi_write_hlp( mpi *X, int radix, char **p )
466{
467 int ret;
Paul Bakkera755ca12011-04-24 09:11:17 +0000468 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +0000469
470 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000471 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
473 MPI_CHK( mpi_mod_int( &r, X, radix ) );
474 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
475
476 if( mpi_cmp_int( X, 0 ) != 0 )
477 MPI_CHK( mpi_write_hlp( X, radix, p ) );
478
479 if( r < 10 )
480 *(*p)++ = (char)( r + 0x30 );
481 else
482 *(*p)++ = (char)( r + 0x37 );
483
484cleanup:
485
486 return( ret );
487}
488
489/*
490 * Export into an ASCII string
491 */
Paul Bakker23986e52011-04-24 08:57:21 +0000492int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000493{
Paul Bakker23986e52011-04-24 08:57:21 +0000494 int ret = 0;
495 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000496 char *p;
497 mpi T;
498
499 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000500 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000501
502 n = mpi_msb( X );
503 if( radix >= 4 ) n >>= 1;
504 if( radix >= 16 ) n >>= 1;
505 n += 3;
506
507 if( *slen < n )
508 {
509 *slen = n;
Paul Bakker40e46942009-01-03 21:51:57 +0000510 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000511 }
512
513 p = s;
Paul Bakker6c591fa2011-05-05 11:49:20 +0000514 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000515
516 if( X->s == -1 )
517 *p++ = '-';
518
519 if( radix == 16 )
520 {
Paul Bakker23986e52011-04-24 08:57:21 +0000521 int c;
522 size_t i, j, k;
Paul Bakker5121ce52009-01-03 21:22:43 +0000523
Paul Bakker23986e52011-04-24 08:57:21 +0000524 for( i = X->n, k = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000525 {
Paul Bakker23986e52011-04-24 08:57:21 +0000526 for( j = ciL; j > 0; j-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000527 {
Paul Bakker23986e52011-04-24 08:57:21 +0000528 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000529
Paul Bakker6c343d72014-07-10 14:36:19 +0200530 if( c == 0 && k == 0 && ( i + j ) != 2 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000531 continue;
532
Paul Bakker98fe5ea2012-10-24 11:17:48 +0000533 *(p++) = "0123456789ABCDEF" [c / 16];
Paul Bakkerd2c167e2012-10-30 07:49:19 +0000534 *(p++) = "0123456789ABCDEF" [c % 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000535 k = 1;
536 }
537 }
538 }
539 else
540 {
541 MPI_CHK( mpi_copy( &T, X ) );
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000542
543 if( T.s == -1 )
544 T.s = 1;
545
Paul Bakker5121ce52009-01-03 21:22:43 +0000546 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
547 }
548
549 *p++ = '\0';
550 *slen = p - s;
551
552cleanup:
553
Paul Bakker6c591fa2011-05-05 11:49:20 +0000554 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000555
556 return( ret );
557}
558
Paul Bakker335db3f2011-04-25 15:28:35 +0000559#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000560/*
561 * Read X from an opened file
562 */
563int mpi_read_file( mpi *X, int radix, FILE *fin )
564{
Paul Bakkera755ca12011-04-24 09:11:17 +0000565 t_uint d;
Paul Bakker23986e52011-04-24 08:57:21 +0000566 size_t slen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000567 char *p;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000568 /*
Paul Bakkercb37aa52011-11-30 16:00:20 +0000569 * Buffer should have space for (short) label and decimal formatted MPI,
570 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000571 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000572 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000573
574 memset( s, 0, sizeof( s ) );
575 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000576 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000577
578 slen = strlen( s );
Paul Bakkercb37aa52011-11-30 16:00:20 +0000579 if( slen == sizeof( s ) - 2 )
580 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
581
Paul Bakker5121ce52009-01-03 21:22:43 +0000582 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
583 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
584
585 p = s + slen;
586 while( --p >= s )
587 if( mpi_get_digit( &d, radix, *p ) != 0 )
588 break;
589
590 return( mpi_read_string( X, radix, p + 1 ) );
591}
592
593/*
594 * Write X into an opened file (or stdout if fout == NULL)
595 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000596int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
Paul Bakker5121ce52009-01-03 21:22:43 +0000597{
Paul Bakker23986e52011-04-24 08:57:21 +0000598 int ret;
599 size_t n, slen, plen;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000600 /*
Paul Bakker5531c6d2012-09-26 19:20:46 +0000601 * Buffer should have space for (short) label and decimal formatted MPI,
602 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000603 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000604 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000605
606 n = sizeof( s );
607 memset( s, 0, n );
608 n -= 2;
609
Paul Bakker23986e52011-04-24 08:57:21 +0000610 MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000611
612 if( p == NULL ) p = "";
613
614 plen = strlen( p );
615 slen = strlen( s );
616 s[slen++] = '\r';
617 s[slen++] = '\n';
618
619 if( fout != NULL )
620 {
621 if( fwrite( p, 1, plen, fout ) != plen ||
622 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000623 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000624 }
625 else
Paul Bakker7dc4c442014-02-01 22:50:26 +0100626 polarssl_printf( "%s%s", p, s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000627
628cleanup:
629
630 return( ret );
631}
Paul Bakker335db3f2011-04-25 15:28:35 +0000632#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000633
634/*
635 * Import X from unsigned binary data, big endian
636 */
Paul Bakker23986e52011-04-24 08:57:21 +0000637int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000638{
Paul Bakker23986e52011-04-24 08:57:21 +0000639 int ret;
640 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000641
642 for( n = 0; n < buflen; n++ )
643 if( buf[n] != 0 )
644 break;
645
646 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
647 MPI_CHK( mpi_lset( X, 0 ) );
648
Paul Bakker23986e52011-04-24 08:57:21 +0000649 for( i = buflen, j = 0; i > n; i--, j++ )
Paul Bakkera755ca12011-04-24 09:11:17 +0000650 X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000651
652cleanup:
653
654 return( ret );
655}
656
657/*
658 * Export X into unsigned binary data, big endian
659 */
Paul Bakker23986e52011-04-24 08:57:21 +0000660int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000661{
Paul Bakker23986e52011-04-24 08:57:21 +0000662 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000663
664 n = mpi_size( X );
665
666 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000667 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000668
669 memset( buf, 0, buflen );
670
671 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
672 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
673
674 return( 0 );
675}
676
677/*
678 * Left-shift: X <<= count
679 */
Paul Bakker23986e52011-04-24 08:57:21 +0000680int mpi_shift_l( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000681{
Paul Bakker23986e52011-04-24 08:57:21 +0000682 int ret;
683 size_t i, v0, t1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000684 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000685
686 v0 = count / (biL );
687 t1 = count & (biL - 1);
688
689 i = mpi_msb( X ) + count;
690
Paul Bakkerf9688572011-05-05 10:00:45 +0000691 if( X->n * biL < i )
Paul Bakker5121ce52009-01-03 21:22:43 +0000692 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
693
694 ret = 0;
695
696 /*
697 * shift by count / limb_size
698 */
699 if( v0 > 0 )
700 {
Paul Bakker23986e52011-04-24 08:57:21 +0000701 for( i = X->n; i > v0; i-- )
702 X->p[i - 1] = X->p[i - v0 - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000703
Paul Bakker23986e52011-04-24 08:57:21 +0000704 for( ; i > 0; i-- )
705 X->p[i - 1] = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000706 }
707
708 /*
709 * shift by count % limb_size
710 */
711 if( t1 > 0 )
712 {
713 for( i = v0; i < X->n; i++ )
714 {
715 r1 = X->p[i] >> (biL - t1);
716 X->p[i] <<= t1;
717 X->p[i] |= r0;
718 r0 = r1;
719 }
720 }
721
722cleanup:
723
724 return( ret );
725}
726
727/*
728 * Right-shift: X >>= count
729 */
Paul Bakker23986e52011-04-24 08:57:21 +0000730int mpi_shift_r( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000731{
Paul Bakker23986e52011-04-24 08:57:21 +0000732 size_t i, v0, v1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000733 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000734
735 v0 = count / biL;
736 v1 = count & (biL - 1);
737
Manuel Pégourié-Gonnarde44ec102012-11-17 12:42:51 +0100738 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
739 return mpi_lset( X, 0 );
740
Paul Bakker5121ce52009-01-03 21:22:43 +0000741 /*
742 * shift by count / limb_size
743 */
744 if( v0 > 0 )
745 {
746 for( i = 0; i < X->n - v0; i++ )
747 X->p[i] = X->p[i + v0];
748
749 for( ; i < X->n; i++ )
750 X->p[i] = 0;
751 }
752
753 /*
754 * shift by count % limb_size
755 */
756 if( v1 > 0 )
757 {
Paul Bakker23986e52011-04-24 08:57:21 +0000758 for( i = X->n; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000759 {
Paul Bakker23986e52011-04-24 08:57:21 +0000760 r1 = X->p[i - 1] << (biL - v1);
761 X->p[i - 1] >>= v1;
762 X->p[i - 1] |= r0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000763 r0 = r1;
764 }
765 }
766
767 return( 0 );
768}
769
770/*
771 * Compare unsigned values
772 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000773int mpi_cmp_abs( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000774{
Paul Bakker23986e52011-04-24 08:57:21 +0000775 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000776
Paul Bakker23986e52011-04-24 08:57:21 +0000777 for( i = X->n; i > 0; i-- )
778 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000779 break;
780
Paul Bakker23986e52011-04-24 08:57:21 +0000781 for( j = Y->n; j > 0; j-- )
782 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000783 break;
784
Paul Bakker23986e52011-04-24 08:57:21 +0000785 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000786 return( 0 );
787
788 if( i > j ) return( 1 );
789 if( j > i ) return( -1 );
790
Paul Bakker23986e52011-04-24 08:57:21 +0000791 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000792 {
Paul Bakker23986e52011-04-24 08:57:21 +0000793 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
794 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000795 }
796
797 return( 0 );
798}
799
800/*
801 * Compare signed values
802 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000803int mpi_cmp_mpi( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000804{
Paul Bakker23986e52011-04-24 08:57:21 +0000805 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000806
Paul Bakker23986e52011-04-24 08:57:21 +0000807 for( i = X->n; i > 0; i-- )
808 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000809 break;
810
Paul Bakker23986e52011-04-24 08:57:21 +0000811 for( j = Y->n; j > 0; j-- )
812 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000813 break;
814
Paul Bakker23986e52011-04-24 08:57:21 +0000815 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000816 return( 0 );
817
818 if( i > j ) return( X->s );
Paul Bakker0c8f73b2012-03-22 14:08:57 +0000819 if( j > i ) return( -Y->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000820
821 if( X->s > 0 && Y->s < 0 ) return( 1 );
822 if( Y->s > 0 && X->s < 0 ) return( -1 );
823
Paul Bakker23986e52011-04-24 08:57:21 +0000824 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000825 {
Paul Bakker23986e52011-04-24 08:57:21 +0000826 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
827 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000828 }
829
830 return( 0 );
831}
832
833/*
834 * Compare signed values
835 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000836int mpi_cmp_int( const mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000837{
838 mpi Y;
Paul Bakkera755ca12011-04-24 09:11:17 +0000839 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000840
841 *p = ( z < 0 ) ? -z : z;
842 Y.s = ( z < 0 ) ? -1 : 1;
843 Y.n = 1;
844 Y.p = p;
845
846 return( mpi_cmp_mpi( X, &Y ) );
847}
848
849/*
850 * Unsigned addition: X = |A| + |B| (HAC 14.7)
851 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000852int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000853{
Paul Bakker23986e52011-04-24 08:57:21 +0000854 int ret;
855 size_t i, j;
Paul Bakkera755ca12011-04-24 09:11:17 +0000856 t_uint *o, *p, c;
Paul Bakker5121ce52009-01-03 21:22:43 +0000857
858 if( X == B )
859 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000860 const mpi *T = A; A = X; B = T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000861 }
862
863 if( X != A )
864 MPI_CHK( mpi_copy( X, A ) );
Paul Bakker9af723c2014-05-01 13:03:14 +0200865
Paul Bakkerf7ca7b92009-06-20 10:31:06 +0000866 /*
867 * X should always be positive as a result of unsigned additions.
868 */
869 X->s = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000870
Paul Bakker23986e52011-04-24 08:57:21 +0000871 for( j = B->n; j > 0; j-- )
872 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000873 break;
874
Paul Bakker23986e52011-04-24 08:57:21 +0000875 MPI_CHK( mpi_grow( X, j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000876
877 o = B->p; p = X->p; c = 0;
878
Paul Bakker23986e52011-04-24 08:57:21 +0000879 for( i = 0; i < j; i++, o++, p++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000880 {
881 *p += c; c = ( *p < c );
882 *p += *o; c += ( *p < *o );
883 }
884
885 while( c != 0 )
886 {
887 if( i >= X->n )
888 {
889 MPI_CHK( mpi_grow( X, i + 1 ) );
890 p = X->p + i;
891 }
892
Paul Bakker2d319fd2012-09-16 21:34:26 +0000893 *p += c; c = ( *p < c ); i++; p++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000894 }
895
896cleanup:
897
898 return( ret );
899}
900
901/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100902 * Helper for mpi subtraction
Paul Bakker5121ce52009-01-03 21:22:43 +0000903 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000904static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
Paul Bakker5121ce52009-01-03 21:22:43 +0000905{
Paul Bakker23986e52011-04-24 08:57:21 +0000906 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +0000907 t_uint c, z;
Paul Bakker5121ce52009-01-03 21:22:43 +0000908
909 for( i = c = 0; i < n; i++, s++, d++ )
910 {
911 z = ( *d < c ); *d -= c;
912 c = ( *d < *s ) + z; *d -= *s;
913 }
914
915 while( c != 0 )
916 {
917 z = ( *d < c ); *d -= c;
918 c = z; i++; d++;
919 }
920}
921
922/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100923 * Unsigned subtraction: X = |A| - |B| (HAC 14.9)
Paul Bakker5121ce52009-01-03 21:22:43 +0000924 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000925int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000926{
927 mpi TB;
Paul Bakker23986e52011-04-24 08:57:21 +0000928 int ret;
929 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000930
931 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000932 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000933
Paul Bakker6c591fa2011-05-05 11:49:20 +0000934 mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000935
936 if( X == B )
937 {
938 MPI_CHK( mpi_copy( &TB, B ) );
939 B = &TB;
940 }
941
942 if( X != A )
943 MPI_CHK( mpi_copy( X, A ) );
944
Paul Bakker1ef7a532009-06-20 10:50:55 +0000945 /*
Paul Bakker60b1d102013-10-29 10:02:51 +0100946 * X should always be positive as a result of unsigned subtractions.
Paul Bakker1ef7a532009-06-20 10:50:55 +0000947 */
948 X->s = 1;
949
Paul Bakker5121ce52009-01-03 21:22:43 +0000950 ret = 0;
951
Paul Bakker23986e52011-04-24 08:57:21 +0000952 for( n = B->n; n > 0; n-- )
953 if( B->p[n - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000954 break;
955
Paul Bakker23986e52011-04-24 08:57:21 +0000956 mpi_sub_hlp( n, B->p, X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000957
958cleanup:
959
Paul Bakker6c591fa2011-05-05 11:49:20 +0000960 mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000961
962 return( ret );
963}
964
965/*
966 * Signed addition: X = A + B
967 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000968int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000969{
970 int ret, s = A->s;
971
972 if( A->s * B->s < 0 )
973 {
974 if( mpi_cmp_abs( A, B ) >= 0 )
975 {
976 MPI_CHK( mpi_sub_abs( X, A, B ) );
977 X->s = s;
978 }
979 else
980 {
981 MPI_CHK( mpi_sub_abs( X, B, A ) );
982 X->s = -s;
983 }
984 }
985 else
986 {
987 MPI_CHK( mpi_add_abs( X, A, B ) );
988 X->s = s;
989 }
990
991cleanup:
992
993 return( ret );
994}
995
996/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100997 * Signed subtraction: X = A - B
Paul Bakker5121ce52009-01-03 21:22:43 +0000998 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000999int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001000{
1001 int ret, s = A->s;
1002
1003 if( A->s * B->s > 0 )
1004 {
1005 if( mpi_cmp_abs( A, B ) >= 0 )
1006 {
1007 MPI_CHK( mpi_sub_abs( X, A, B ) );
1008 X->s = s;
1009 }
1010 else
1011 {
1012 MPI_CHK( mpi_sub_abs( X, B, A ) );
1013 X->s = -s;
1014 }
1015 }
1016 else
1017 {
1018 MPI_CHK( mpi_add_abs( X, A, B ) );
1019 X->s = s;
1020 }
1021
1022cleanup:
1023
1024 return( ret );
1025}
1026
1027/*
1028 * Signed addition: X = A + b
1029 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001030int mpi_add_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001031{
1032 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001033 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001034
1035 p[0] = ( b < 0 ) ? -b : b;
1036 _B.s = ( b < 0 ) ? -1 : 1;
1037 _B.n = 1;
1038 _B.p = p;
1039
1040 return( mpi_add_mpi( X, A, &_B ) );
1041}
1042
1043/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001044 * Signed subtraction: X = A - b
Paul Bakker5121ce52009-01-03 21:22:43 +00001045 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001046int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001047{
1048 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001049 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001050
1051 p[0] = ( b < 0 ) ? -b : b;
1052 _B.s = ( b < 0 ) ? -1 : 1;
1053 _B.n = 1;
1054 _B.p = p;
1055
1056 return( mpi_sub_mpi( X, A, &_B ) );
1057}
1058
1059/*
1060 * Helper for mpi multiplication
Paul Bakkerfc4f46f2013-06-24 19:23:56 +02001061 */
1062static
1063#if defined(__APPLE__) && defined(__arm__)
1064/*
1065 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1066 * appears to need this to prevent bad ARM code generation at -O3.
1067 */
1068__attribute__ ((noinline))
1069#endif
1070void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001071{
Paul Bakkera755ca12011-04-24 09:11:17 +00001072 t_uint c = 0, t = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001073
1074#if defined(MULADDC_HUIT)
1075 for( ; i >= 8; i -= 8 )
1076 {
1077 MULADDC_INIT
1078 MULADDC_HUIT
1079 MULADDC_STOP
1080 }
1081
1082 for( ; i > 0; i-- )
1083 {
1084 MULADDC_INIT
1085 MULADDC_CORE
1086 MULADDC_STOP
1087 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001088#else /* MULADDC_HUIT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001089 for( ; i >= 16; i -= 16 )
1090 {
1091 MULADDC_INIT
1092 MULADDC_CORE MULADDC_CORE
1093 MULADDC_CORE MULADDC_CORE
1094 MULADDC_CORE MULADDC_CORE
1095 MULADDC_CORE MULADDC_CORE
1096
1097 MULADDC_CORE MULADDC_CORE
1098 MULADDC_CORE MULADDC_CORE
1099 MULADDC_CORE MULADDC_CORE
1100 MULADDC_CORE MULADDC_CORE
1101 MULADDC_STOP
1102 }
1103
1104 for( ; i >= 8; i -= 8 )
1105 {
1106 MULADDC_INIT
1107 MULADDC_CORE MULADDC_CORE
1108 MULADDC_CORE MULADDC_CORE
1109
1110 MULADDC_CORE MULADDC_CORE
1111 MULADDC_CORE MULADDC_CORE
1112 MULADDC_STOP
1113 }
1114
1115 for( ; i > 0; i-- )
1116 {
1117 MULADDC_INIT
1118 MULADDC_CORE
1119 MULADDC_STOP
1120 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001121#endif /* MULADDC_HUIT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001122
1123 t++;
1124
1125 do {
1126 *d += c; c = ( *d < c ); d++;
1127 }
1128 while( c != 0 );
1129}
1130
1131/*
1132 * Baseline multiplication: X = A * B (HAC 14.12)
1133 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001134int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001135{
Paul Bakker23986e52011-04-24 08:57:21 +00001136 int ret;
1137 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00001138 mpi TA, TB;
1139
Paul Bakker6c591fa2011-05-05 11:49:20 +00001140 mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001141
1142 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
1143 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
1144
Paul Bakker23986e52011-04-24 08:57:21 +00001145 for( i = A->n; i > 0; i-- )
1146 if( A->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001147 break;
1148
Paul Bakker23986e52011-04-24 08:57:21 +00001149 for( j = B->n; j > 0; j-- )
1150 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001151 break;
1152
Paul Bakker23986e52011-04-24 08:57:21 +00001153 MPI_CHK( mpi_grow( X, i + j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001154 MPI_CHK( mpi_lset( X, 0 ) );
1155
Paul Bakker23986e52011-04-24 08:57:21 +00001156 for( i++; j > 0; j-- )
1157 mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001158
1159 X->s = A->s * B->s;
1160
1161cleanup:
1162
Paul Bakker6c591fa2011-05-05 11:49:20 +00001163 mpi_free( &TB ); mpi_free( &TA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001164
1165 return( ret );
1166}
1167
1168/*
1169 * Baseline multiplication: X = A * b
1170 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001171int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001172{
1173 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001174 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001175
1176 _B.s = 1;
1177 _B.n = 1;
1178 _B.p = p;
1179 p[0] = b;
1180
1181 return( mpi_mul_mpi( X, A, &_B ) );
1182}
1183
1184/*
1185 * Division by mpi: A = Q * B + R (HAC 14.20)
1186 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001187int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001188{
Paul Bakker23986e52011-04-24 08:57:21 +00001189 int ret;
1190 size_t i, n, t, k;
Paul Bakker5121ce52009-01-03 21:22:43 +00001191 mpi X, Y, Z, T1, T2;
1192
1193 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001194 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001195
Paul Bakker6c591fa2011-05-05 11:49:20 +00001196 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
1197 mpi_init( &T1 ); mpi_init( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001198
1199 if( mpi_cmp_abs( A, B ) < 0 )
1200 {
1201 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1202 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1203 return( 0 );
1204 }
1205
1206 MPI_CHK( mpi_copy( &X, A ) );
1207 MPI_CHK( mpi_copy( &Y, B ) );
1208 X.s = Y.s = 1;
1209
1210 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1211 MPI_CHK( mpi_lset( &Z, 0 ) );
1212 MPI_CHK( mpi_grow( &T1, 2 ) );
1213 MPI_CHK( mpi_grow( &T2, 3 ) );
1214
1215 k = mpi_msb( &Y ) % biL;
Paul Bakkerf9688572011-05-05 10:00:45 +00001216 if( k < biL - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001217 {
1218 k = biL - 1 - k;
1219 MPI_CHK( mpi_shift_l( &X, k ) );
1220 MPI_CHK( mpi_shift_l( &Y, k ) );
1221 }
1222 else k = 0;
1223
1224 n = X.n - 1;
1225 t = Y.n - 1;
Paul Bakker66d5d072014-06-17 16:39:18 +02001226 MPI_CHK( mpi_shift_l( &Y, biL * ( n - t ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001227
1228 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1229 {
1230 Z.p[n - t]++;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001231 MPI_CHK( mpi_sub_mpi( &X, &X, &Y ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001232 }
Paul Bakker66d5d072014-06-17 16:39:18 +02001233 MPI_CHK( mpi_shift_r( &Y, biL * ( n - t ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001234
1235 for( i = n; i > t ; i-- )
1236 {
1237 if( X.p[i] >= Y.p[t] )
1238 Z.p[i - t - 1] = ~0;
1239 else
1240 {
Manuel Pégourié-Gonnardbb8661e2014-03-14 09:21:20 +01001241 /*
Manuel Pégourié-Gonnard2eea2922014-03-14 18:23:26 +01001242 * The version of Clang shipped by Apple with Mavericks around
1243 * 2014-03 can't handle 128-bit division properly. Disable
1244 * 128-bits division for this version. Let's be optimistic and
1245 * assume it'll be fixed in the next minor version (next
1246 * patchlevel is probably a bit too optimistic).
Manuel Pégourié-Gonnardbb8661e2014-03-14 09:21:20 +01001247 */
Manuel Pégourié-Gonnard2eea2922014-03-14 18:23:26 +01001248#if defined(POLARSSL_HAVE_UDBL) && \
1249 ! ( defined(__x86_64__) && defined(__APPLE__) && \
1250 defined(__clang_major__) && __clang_major__ == 5 && \
1251 defined(__clang_minor__) && __clang_minor__ == 0 )
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{
1969 int ret;
1970 size_t i, j, n, s;
1971 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 Bakker901c6562012-04-20 13:25:38 +00001998 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001999
Paul Bakkerb94081b2011-01-05 15:53:06 +00002000 if( mpi_cmp_mpi( &A, &W ) >= 0 )
2001 {
2002 j = mpi_msb( &A ) - mpi_msb( &W );
2003 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
2004 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002005 A.p[0] |= 3;
2006
2007 /*
2008 * A = A^R mod |X|
2009 */
2010 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
2011
2012 if( mpi_cmp_mpi( &A, &W ) == 0 ||
2013 mpi_cmp_int( &A, 1 ) == 0 )
2014 continue;
2015
2016 j = 1;
2017 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
2018 {
2019 /*
2020 * A = A * A mod |X|
2021 */
2022 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
2023 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
2024
2025 if( mpi_cmp_int( &A, 1 ) == 0 )
2026 break;
2027
2028 j++;
2029 }
2030
2031 /*
2032 * not prime if A != |X| - 1 or A == 1
2033 */
2034 if( mpi_cmp_mpi( &A, &W ) != 0 ||
2035 mpi_cmp_int( &A, 1 ) == 0 )
2036 {
Paul Bakker40e46942009-01-03 21:51:57 +00002037 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002038 break;
2039 }
2040 }
2041
2042cleanup:
Paul Bakker6c591fa2011-05-05 11:49:20 +00002043 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
2044 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002045
2046 return( ret );
2047}
2048
2049/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002050 * Pseudo-primality test: small factors, then Miller-Rabin
2051 */
Paul Bakker45f457d2013-11-25 14:26:52 +01002052int mpi_is_prime( mpi *X,
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002053 int (*f_rng)(void *, unsigned char *, size_t),
2054 void *p_rng )
2055{
2056 int ret;
Manuel Pégourié-Gonnard7f4ed672014-10-14 20:56:02 +02002057 mpi XX;
2058
2059 XX.s = 1;
2060 XX.n = X->n;
2061 XX.p = X->p;
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002062
2063 if( mpi_cmp_int( &XX, 0 ) == 0 ||
2064 mpi_cmp_int( &XX, 1 ) == 0 )
2065 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
2066
2067 if( mpi_cmp_int( &XX, 2 ) == 0 )
2068 return( 0 );
2069
2070 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2071 {
2072 if( ret == 1 )
2073 return( 0 );
2074
2075 return( ret );
2076 }
2077
2078 return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
2079}
2080
2081/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002082 * Prime number generation
2083 */
Paul Bakker23986e52011-04-24 08:57:21 +00002084int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002085 int (*f_rng)(void *, unsigned char *, size_t),
2086 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +00002087{
Paul Bakker23986e52011-04-24 08:57:21 +00002088 int ret;
2089 size_t k, n;
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002090 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002091 mpi Y;
2092
Paul Bakkerfe3256e2011-11-25 12:11:43 +00002093 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
Paul Bakker40e46942009-01-03 21:51:57 +00002094 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002095
Paul Bakker6c591fa2011-05-05 11:49:20 +00002096 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002097
2098 n = BITS_TO_LIMBS( nbits );
2099
Paul Bakker901c6562012-04-20 13:25:38 +00002100 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002101
2102 k = mpi_msb( X );
2103 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
2104 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
2105
2106 X->p[0] |= 3;
2107
2108 if( dh_flag == 0 )
2109 {
2110 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
2111 {
Paul Bakker40e46942009-01-03 21:51:57 +00002112 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002113 goto cleanup;
2114
2115 MPI_CHK( mpi_add_int( X, X, 2 ) );
2116 }
2117 }
2118 else
2119 {
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002120 /*
2121 * An necessary condition for Y and X = 2Y + 1 to be prime
2122 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2123 * Make sure it is satisfied, while keeping X = 3 mod 4
2124 */
2125 MPI_CHK( mpi_mod_int( &r, X, 3 ) );
2126 if( r == 0 )
2127 MPI_CHK( mpi_add_int( X, X, 8 ) );
2128 else if( r == 1 )
2129 MPI_CHK( mpi_add_int( X, X, 4 ) );
2130
2131 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2132 MPI_CHK( mpi_copy( &Y, X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002133 MPI_CHK( mpi_shift_r( &Y, 1 ) );
2134
2135 while( 1 )
2136 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002137 /*
2138 * First, check small factors for X and Y
2139 * before doing Miller-Rabin on any of them
2140 */
2141 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2142 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2143 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
2144 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002145 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002146 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002147 }
2148
Paul Bakker40e46942009-01-03 21:51:57 +00002149 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002150 goto cleanup;
2151
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002152 /*
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002153 * Next candidates. We want to preserve Y = (X-1) / 2 and
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002154 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2155 * so up Y by 6 and X by 12.
2156 */
2157 MPI_CHK( mpi_add_int( X, X, 12 ) );
2158 MPI_CHK( mpi_add_int( &Y, &Y, 6 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002159 }
2160 }
2161
2162cleanup:
2163
Paul Bakker6c591fa2011-05-05 11:49:20 +00002164 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002165
2166 return( ret );
2167}
2168
Manuel Pégourié-Gonnarddf0142b2013-08-22 18:29:07 +02002169#endif /* POLARSSL_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00002170
Paul Bakker40e46942009-01-03 21:51:57 +00002171#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002172
Paul Bakker23986e52011-04-24 08:57:21 +00002173#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002174
2175static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2176{
2177 { 693, 609, 21 },
2178 { 1764, 868, 28 },
2179 { 768454923, 542167814, 1 }
2180};
2181
Paul Bakker5121ce52009-01-03 21:22:43 +00002182/*
2183 * Checkup routine
2184 */
2185int mpi_self_test( int verbose )
2186{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002187 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00002188 mpi A, E, N, X, Y, U, V;
2189
Paul Bakker6c591fa2011-05-05 11:49:20 +00002190 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
2191 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002192
2193 MPI_CHK( mpi_read_string( &A, 16,
2194 "EFE021C2645FD1DC586E69184AF4A31E" \
2195 "D5F53E93B5F123FA41680867BA110131" \
2196 "944FE7952E2517337780CB0DB80E61AA" \
2197 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2198
2199 MPI_CHK( mpi_read_string( &E, 16,
2200 "B2E7EFD37075B9F03FF989C7C5051C20" \
2201 "34D2A323810251127E7BF8625A4F49A5" \
2202 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2203 "5B5C25763222FEFCCFC38B832366C29E" ) );
2204
2205 MPI_CHK( mpi_read_string( &N, 16,
2206 "0066A198186C18C10B2F5ED9B522752A" \
2207 "9830B69916E535C8F047518A889A43A5" \
2208 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2209
2210 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
2211
2212 MPI_CHK( mpi_read_string( &U, 16,
2213 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2214 "9E857EA95A03512E2BAE7391688D264A" \
2215 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2216 "8001B72E848A38CAE1C65F78E56ABDEF" \
2217 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2218 "ECF677152EF804370C1A305CAF3B5BF1" \
2219 "30879B56C61DE584A0F53A2447A51E" ) );
2220
2221 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002222 polarssl_printf( " MPI test #1 (mul_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002223
2224 if( mpi_cmp_mpi( &X, &U ) != 0 )
2225 {
2226 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002227 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002228
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002229 ret = 1;
2230 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002231 }
2232
2233 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002234 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002235
2236 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
2237
2238 MPI_CHK( mpi_read_string( &U, 16,
2239 "256567336059E52CAE22925474705F39A94" ) );
2240
2241 MPI_CHK( mpi_read_string( &V, 16,
2242 "6613F26162223DF488E9CD48CC132C7A" \
2243 "0AC93C701B001B092E4E5B9F73BCD27B" \
2244 "9EE50D0657C77F374E903CDFA4C642" ) );
2245
2246 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002247 polarssl_printf( " MPI test #2 (div_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002248
2249 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2250 mpi_cmp_mpi( &Y, &V ) != 0 )
2251 {
2252 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002253 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002254
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002255 ret = 1;
2256 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002257 }
2258
2259 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002260 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002261
2262 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2263
2264 MPI_CHK( mpi_read_string( &U, 16,
2265 "36E139AEA55215609D2816998ED020BB" \
2266 "BD96C37890F65171D948E9BC7CBAA4D9" \
2267 "325D24D6A3C12710F10A09FA08AB87" ) );
2268
2269 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002270 polarssl_printf( " MPI test #3 (exp_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002271
2272 if( mpi_cmp_mpi( &X, &U ) != 0 )
2273 {
2274 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002275 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002276
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002277 ret = 1;
2278 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002279 }
2280
2281 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002282 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002283
2284 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2285
2286 MPI_CHK( mpi_read_string( &U, 16,
2287 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2288 "C3DBA76456363A10869622EAC2DD84EC" \
2289 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2290
2291 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002292 polarssl_printf( " MPI test #4 (inv_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002293
2294 if( mpi_cmp_mpi( &X, &U ) != 0 )
2295 {
2296 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002297 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002298
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002299 ret = 1;
2300 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002301 }
2302
2303 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002304 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002305
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002306 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002307 polarssl_printf( " MPI test #5 (simple gcd): " );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002308
Paul Bakker66d5d072014-06-17 16:39:18 +02002309 for( i = 0; i < GCD_PAIR_COUNT; i++ )
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002310 {
2311 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002312 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002313
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002314 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002315
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002316 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2317 {
2318 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002319 polarssl_printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002320
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002321 ret = 1;
2322 goto cleanup;
2323 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002324 }
2325
2326 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002327 polarssl_printf( "passed\n" );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002328
Paul Bakker5121ce52009-01-03 21:22:43 +00002329cleanup:
2330
2331 if( ret != 0 && verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002332 polarssl_printf( "Unexpected error, return code = %08X\n", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002333
Paul Bakker6c591fa2011-05-05 11:49:20 +00002334 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2335 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002336
2337 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002338 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002339
2340 return( ret );
2341}
2342
Paul Bakker9af723c2014-05-01 13:03:14 +02002343#endif /* POLARSSL_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002344
Paul Bakker9af723c2014-05-01 13:03:14 +02002345#endif /* POLARSSL_BIGNUM_C */