blob: e7b8d6d6a9993950cecdf4101254909b2c4157be [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Multi-precision integer library
3 *
Paul Bakker7dc4c442014-02-01 22:50:26 +01004 * Copyright (C) 2006-2014, Brainspark B.V.
Paul Bakkerb96f1542010-07-18 20:36:00 +00005 *
6 * This file is part of PolarSSL (http://www.polarssl.org)
Paul Bakker84f12b72010-07-18 10:13:04 +00007 * Lead Maintainer: Paul Bakker <polarssl_maintainer at polarssl.org>
Paul Bakkerb96f1542010-07-18 20:36:00 +00008 *
Paul Bakker77b385e2009-07-28 17:23:11 +00009 * All rights reserved.
Paul Bakkere0ccd0a2009-01-04 16:27:10 +000010 *
Paul Bakker5121ce52009-01-03 21:22:43 +000011 * This program is free software; you can redistribute it and/or modify
12 * it under the terms of the GNU General Public License as published by
13 * the Free Software Foundation; either version 2 of the License, or
14 * (at your option) any later version.
15 *
16 * This program is distributed in the hope that it will be useful,
17 * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 * GNU General Public License for more details.
20 *
21 * You should have received a copy of the GNU General Public License along
22 * with this program; if not, write to the Free Software Foundation, Inc.,
23 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24 */
25/*
26 * This MPI implementation is based on:
27 *
28 * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
29 * http://www.stillhq.com/extracted/gnupg-api/mpi/
30 * http://math.libtomcrypt.com/files/tommath.pdf
31 */
32
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020033#if !defined(POLARSSL_CONFIG_FILE)
Paul Bakker40e46942009-01-03 21:51:57 +000034#include "polarssl/config.h"
Manuel Pégourié-Gonnardcef4ad22014-04-29 12:39:06 +020035#else
36#include POLARSSL_CONFIG_FILE
37#endif
Paul Bakker5121ce52009-01-03 21:22:43 +000038
Paul Bakker40e46942009-01-03 21:51:57 +000039#if defined(POLARSSL_BIGNUM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000040
Paul Bakker40e46942009-01-03 21:51:57 +000041#include "polarssl/bignum.h"
42#include "polarssl/bn_mul.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000043
Paul Bakker7dc4c442014-02-01 22:50:26 +010044#if defined(POLARSSL_PLATFORM_C)
45#include "polarssl/platform.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020046#else
Paul Bakker7dc4c442014-02-01 22:50:26 +010047#define polarssl_printf printf
Paul Bakker6e339b52013-07-03 13:37:05 +020048#define polarssl_malloc malloc
49#define polarssl_free free
50#endif
51
Paul Bakker5121ce52009-01-03 21:22:43 +000052#include <stdlib.h>
Paul Bakker5121ce52009-01-03 21:22:43 +000053
Paul Bakker34617722014-06-13 17:20:13 +020054/* Implementation that should never be optimized out by the compiler */
55static void polarssl_zeroize( void *v, size_t n ) {
56 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
57}
58
Paul Bakkerf9688572011-05-05 10:00:45 +000059#define ciL (sizeof(t_uint)) /* chars in limb */
Paul Bakker5121ce52009-01-03 21:22:43 +000060#define biL (ciL << 3) /* bits in limb */
61#define biH (ciL << 2) /* half limb size */
62
63/*
64 * Convert between bits/chars and number of limbs
65 */
66#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
67#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
68
69/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000070 * Initialize one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000071 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000072void mpi_init( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000073{
Paul Bakker6c591fa2011-05-05 11:49:20 +000074 if( X == NULL )
75 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000076
Paul Bakker6c591fa2011-05-05 11:49:20 +000077 X->s = 1;
78 X->n = 0;
79 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000080}
81
82/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000083 * Unallocate one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000084 */
Paul Bakker6c591fa2011-05-05 11:49:20 +000085void mpi_free( mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000086{
Paul Bakker6c591fa2011-05-05 11:49:20 +000087 if( X == NULL )
88 return;
Paul Bakker5121ce52009-01-03 21:22:43 +000089
Paul Bakker6c591fa2011-05-05 11:49:20 +000090 if( X->p != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +000091 {
Paul Bakker34617722014-06-13 17:20:13 +020092 polarssl_zeroize( X->p, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +020093 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +000094 }
95
Paul Bakker6c591fa2011-05-05 11:49:20 +000096 X->s = 1;
97 X->n = 0;
98 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000099}
100
101/*
102 * Enlarge to the specified number of limbs
103 */
Paul Bakker23986e52011-04-24 08:57:21 +0000104int mpi_grow( mpi *X, size_t nblimbs )
Paul Bakker5121ce52009-01-03 21:22:43 +0000105{
Paul Bakkera755ca12011-04-24 09:11:17 +0000106 t_uint *p;
Paul Bakker5121ce52009-01-03 21:22:43 +0000107
Paul Bakkerf9688572011-05-05 10:00:45 +0000108 if( nblimbs > POLARSSL_MPI_MAX_LIMBS )
Paul Bakker69e095c2011-12-10 21:55:01 +0000109 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakkerf9688572011-05-05 10:00:45 +0000110
Paul Bakker5121ce52009-01-03 21:22:43 +0000111 if( X->n < nblimbs )
112 {
Paul Bakker6e339b52013-07-03 13:37:05 +0200113 if( ( p = (t_uint *) polarssl_malloc( nblimbs * ciL ) ) == NULL )
Paul Bakker69e095c2011-12-10 21:55:01 +0000114 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000115
116 memset( p, 0, nblimbs * ciL );
117
118 if( X->p != NULL )
119 {
120 memcpy( p, X->p, X->n * ciL );
Paul Bakker34617722014-06-13 17:20:13 +0200121 polarssl_zeroize( X->p, X->n * ciL );
Paul Bakker6e339b52013-07-03 13:37:05 +0200122 polarssl_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000123 }
124
125 X->n = nblimbs;
126 X->p = p;
127 }
128
129 return( 0 );
130}
131
132/*
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100133 * Resize down as much as possible,
134 * while keeping at least the specified number of limbs
135 */
136int mpi_shrink( mpi *X, size_t nblimbs )
137{
138 t_uint *p;
139 size_t i;
140
141 /* Actually resize up in this case */
142 if( X->n <= nblimbs )
143 return( mpi_grow( X, nblimbs ) );
144
145 for( i = X->n - 1; i > 0; i-- )
146 if( X->p[i] != 0 )
147 break;
148 i++;
149
150 if( i < nblimbs )
151 i = nblimbs;
152
153 if( ( p = (t_uint *) polarssl_malloc( i * ciL ) ) == NULL )
154 return( POLARSSL_ERR_MPI_MALLOC_FAILED );
155
156 memset( p, 0, i * ciL );
157
158 if( X->p != NULL )
159 {
160 memcpy( p, X->p, i * ciL );
Paul Bakker34617722014-06-13 17:20:13 +0200161 polarssl_zeroize( X->p, X->n * ciL );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100162 polarssl_free( X->p );
163 }
164
165 X->n = i;
166 X->p = p;
167
168 return( 0 );
169}
170
171/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000172 * Copy the contents of Y into X
173 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000174int mpi_copy( mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000175{
Paul Bakker23986e52011-04-24 08:57:21 +0000176 int ret;
177 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000178
179 if( X == Y )
180 return( 0 );
181
Manuel Pégourié-Gonnardf4999932013-08-12 17:02:59 +0200182 if( Y->p == NULL )
183 {
184 mpi_free( X );
185 return( 0 );
186 }
187
Paul Bakker5121ce52009-01-03 21:22:43 +0000188 for( i = Y->n - 1; i > 0; i-- )
189 if( Y->p[i] != 0 )
190 break;
191 i++;
192
193 X->s = Y->s;
194
195 MPI_CHK( mpi_grow( X, i ) );
196
197 memset( X->p, 0, X->n * ciL );
198 memcpy( X->p, Y->p, i * ciL );
199
200cleanup:
201
202 return( ret );
203}
204
205/*
206 * Swap the contents of X and Y
207 */
208void mpi_swap( mpi *X, mpi *Y )
209{
210 mpi T;
211
212 memcpy( &T, X, sizeof( mpi ) );
213 memcpy( X, Y, sizeof( mpi ) );
214 memcpy( Y, &T, sizeof( mpi ) );
215}
216
217/*
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100218 * Conditionally assign X = Y, without leaking information
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100219 * about whether the assignment was made or not.
220 * (Leaking information about the respective sizes of X and Y is ok however.)
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100221 */
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100222int mpi_safe_cond_assign( mpi *X, const mpi *Y, unsigned char assign )
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100223{
224 int ret = 0;
225 size_t i;
226
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100227 /* make sure assign is 0 or 1 */
228 assign = ( assign != 0 );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100229
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100230 MPI_CHK( mpi_grow( X, Y->n ) );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100231
Paul Bakker66d5d072014-06-17 16:39:18 +0200232 X->s = X->s * ( 1 - assign ) + Y->s * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100233
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100234 for( i = 0; i < Y->n; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200235 X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100236
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100237 for( ; i < X->n; i++ )
Paul Bakker66d5d072014-06-17 16:39:18 +0200238 X->p[i] *= ( 1 - assign );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100239
240cleanup:
241 return( ret );
242}
243
244/*
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100245 * Conditionally swap X and Y, without leaking information
246 * about whether the swap was made or not.
247 * Here it is not ok to simply swap the pointers, which whould lead to
248 * different memory access patterns when X and Y are used afterwards.
249 */
250int mpi_safe_cond_swap( mpi *X, mpi *Y, unsigned char swap )
251{
252 int ret, s;
253 size_t i;
254 t_uint tmp;
255
256 if( X == Y )
257 return( 0 );
258
259 /* make sure swap is 0 or 1 */
260 swap = ( swap != 0 );
261
262 MPI_CHK( mpi_grow( X, Y->n ) );
263 MPI_CHK( mpi_grow( Y, X->n ) );
264
265 s = X->s;
Paul Bakker66d5d072014-06-17 16:39:18 +0200266 X->s = X->s * ( 1 - swap ) + Y->s * swap;
267 Y->s = Y->s * ( 1 - swap ) + s * swap;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100268
269
270 for( i = 0; i < X->n; i++ )
271 {
272 tmp = X->p[i];
Paul Bakker66d5d072014-06-17 16:39:18 +0200273 X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap;
274 Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100275 }
276
277cleanup:
278 return( ret );
279}
280
281/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000282 * Set value from integer
283 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000284int mpi_lset( mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000285{
286 int ret;
287
288 MPI_CHK( mpi_grow( X, 1 ) );
289 memset( X->p, 0, X->n * ciL );
290
291 X->p[0] = ( z < 0 ) ? -z : z;
292 X->s = ( z < 0 ) ? -1 : 1;
293
294cleanup:
295
296 return( ret );
297}
298
299/*
Paul Bakker2f5947e2011-05-18 15:47:11 +0000300 * Get a specific bit
301 */
Paul Bakker6b906e52012-05-08 12:01:43 +0000302int mpi_get_bit( const mpi *X, size_t pos )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000303{
304 if( X->n * biL <= pos )
305 return( 0 );
306
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200307 return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000308}
309
310/*
311 * Set a bit to a specific value of 0 or 1
312 */
313int mpi_set_bit( mpi *X, size_t pos, unsigned char val )
314{
315 int ret = 0;
316 size_t off = pos / biL;
317 size_t idx = pos % biL;
318
319 if( val != 0 && val != 1 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200320 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker9af723c2014-05-01 13:03:14 +0200321
Paul Bakker2f5947e2011-05-18 15:47:11 +0000322 if( X->n * biL <= pos )
323 {
324 if( val == 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200325 return( 0 );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000326
327 MPI_CHK( mpi_grow( X, off + 1 ) );
328 }
329
Manuel Pégourié-Gonnard9a4a5ac2013-12-04 18:05:29 +0100330 X->p[off] &= ~( (t_uint) 0x01 << idx );
331 X->p[off] |= (t_uint) val << idx;
Paul Bakker2f5947e2011-05-18 15:47:11 +0000332
333cleanup:
Paul Bakker9af723c2014-05-01 13:03:14 +0200334
Paul Bakker2f5947e2011-05-18 15:47:11 +0000335 return( ret );
336}
337
338/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000339 * Return the number of least significant bits
340 */
Paul Bakker23986e52011-04-24 08:57:21 +0000341size_t mpi_lsb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000342{
Paul Bakker23986e52011-04-24 08:57:21 +0000343 size_t i, j, count = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000344
345 for( i = 0; i < X->n; i++ )
Paul Bakkerf9688572011-05-05 10:00:45 +0000346 for( j = 0; j < biL; j++, count++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000347 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
348 return( count );
349
350 return( 0 );
351}
352
353/*
354 * Return the number of most significant bits
355 */
Paul Bakker23986e52011-04-24 08:57:21 +0000356size_t mpi_msb( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000357{
Paul Bakker23986e52011-04-24 08:57:21 +0000358 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000359
360 for( i = X->n - 1; i > 0; i-- )
361 if( X->p[i] != 0 )
362 break;
363
Paul Bakker23986e52011-04-24 08:57:21 +0000364 for( j = biL; j > 0; j-- )
365 if( ( ( X->p[i] >> ( j - 1 ) ) & 1 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000366 break;
367
Paul Bakker23986e52011-04-24 08:57:21 +0000368 return( ( i * biL ) + j );
Paul Bakker5121ce52009-01-03 21:22:43 +0000369}
370
371/*
372 * Return the total size in bytes
373 */
Paul Bakker23986e52011-04-24 08:57:21 +0000374size_t mpi_size( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000375{
376 return( ( mpi_msb( X ) + 7 ) >> 3 );
377}
378
379/*
380 * Convert an ASCII character to digit value
381 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000382static int mpi_get_digit( t_uint *d, int radix, char c )
Paul Bakker5121ce52009-01-03 21:22:43 +0000383{
384 *d = 255;
385
386 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
387 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
388 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
389
Paul Bakkera755ca12011-04-24 09:11:17 +0000390 if( *d >= (t_uint) radix )
Paul Bakker40e46942009-01-03 21:51:57 +0000391 return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000392
393 return( 0 );
394}
395
396/*
397 * Import from an ASCII string
398 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000399int mpi_read_string( mpi *X, int radix, const char *s )
Paul Bakker5121ce52009-01-03 21:22:43 +0000400{
Paul Bakker23986e52011-04-24 08:57:21 +0000401 int ret;
402 size_t i, j, slen, n;
Paul Bakkera755ca12011-04-24 09:11:17 +0000403 t_uint d;
Paul Bakker5121ce52009-01-03 21:22:43 +0000404 mpi T;
405
406 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000407 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000408
Paul Bakker6c591fa2011-05-05 11:49:20 +0000409 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000410
Paul Bakkerff60ee62010-03-16 21:09:09 +0000411 slen = strlen( s );
412
Paul Bakker5121ce52009-01-03 21:22:43 +0000413 if( radix == 16 )
414 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000415 n = BITS_TO_LIMBS( slen << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000416
417 MPI_CHK( mpi_grow( X, n ) );
418 MPI_CHK( mpi_lset( X, 0 ) );
419
Paul Bakker23986e52011-04-24 08:57:21 +0000420 for( i = slen, j = 0; i > 0; i--, j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000421 {
Paul Bakker23986e52011-04-24 08:57:21 +0000422 if( i == 1 && s[i - 1] == '-' )
Paul Bakker5121ce52009-01-03 21:22:43 +0000423 {
424 X->s = -1;
425 break;
426 }
427
Paul Bakker23986e52011-04-24 08:57:21 +0000428 MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
Paul Bakker66d5d072014-06-17 16:39:18 +0200429 X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000430 }
431 }
432 else
433 {
434 MPI_CHK( mpi_lset( X, 0 ) );
435
Paul Bakkerff60ee62010-03-16 21:09:09 +0000436 for( i = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000437 {
438 if( i == 0 && s[i] == '-' )
439 {
440 X->s = -1;
441 continue;
442 }
443
444 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
445 MPI_CHK( mpi_mul_int( &T, X, radix ) );
Paul Bakker05feca62009-06-20 08:22:43 +0000446
447 if( X->s == 1 )
448 {
449 MPI_CHK( mpi_add_int( X, &T, d ) );
450 }
451 else
452 {
453 MPI_CHK( mpi_sub_int( X, &T, d ) );
454 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000455 }
456 }
457
458cleanup:
459
Paul Bakker6c591fa2011-05-05 11:49:20 +0000460 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000461
462 return( ret );
463}
464
465/*
466 * Helper to write the digits high-order first
467 */
468static int mpi_write_hlp( mpi *X, int radix, char **p )
469{
470 int ret;
Paul Bakkera755ca12011-04-24 09:11:17 +0000471 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +0000472
473 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000474 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000475
476 MPI_CHK( mpi_mod_int( &r, X, radix ) );
477 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
478
479 if( mpi_cmp_int( X, 0 ) != 0 )
480 MPI_CHK( mpi_write_hlp( X, radix, p ) );
481
482 if( r < 10 )
483 *(*p)++ = (char)( r + 0x30 );
484 else
485 *(*p)++ = (char)( r + 0x37 );
486
487cleanup:
488
489 return( ret );
490}
491
492/*
493 * Export into an ASCII string
494 */
Paul Bakker23986e52011-04-24 08:57:21 +0000495int mpi_write_string( const mpi *X, int radix, char *s, size_t *slen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000496{
Paul Bakker23986e52011-04-24 08:57:21 +0000497 int ret = 0;
498 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000499 char *p;
500 mpi T;
501
502 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000503 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000504
505 n = mpi_msb( X );
506 if( radix >= 4 ) n >>= 1;
507 if( radix >= 16 ) n >>= 1;
508 n += 3;
509
510 if( *slen < n )
511 {
512 *slen = n;
Paul Bakker40e46942009-01-03 21:51:57 +0000513 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000514 }
515
516 p = s;
Paul Bakker6c591fa2011-05-05 11:49:20 +0000517 mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000518
519 if( X->s == -1 )
520 *p++ = '-';
521
522 if( radix == 16 )
523 {
Paul Bakker23986e52011-04-24 08:57:21 +0000524 int c;
525 size_t i, j, k;
Paul Bakker5121ce52009-01-03 21:22:43 +0000526
Paul Bakker23986e52011-04-24 08:57:21 +0000527 for( i = X->n, k = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000528 {
Paul Bakker23986e52011-04-24 08:57:21 +0000529 for( j = ciL; j > 0; j-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000530 {
Paul Bakker23986e52011-04-24 08:57:21 +0000531 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000532
Paul Bakker23986e52011-04-24 08:57:21 +0000533 if( c == 0 && k == 0 && ( i + j + 3 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000534 continue;
535
Paul Bakker98fe5ea2012-10-24 11:17:48 +0000536 *(p++) = "0123456789ABCDEF" [c / 16];
Paul Bakkerd2c167e2012-10-30 07:49:19 +0000537 *(p++) = "0123456789ABCDEF" [c % 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000538 k = 1;
539 }
540 }
541 }
542 else
543 {
544 MPI_CHK( mpi_copy( &T, X ) );
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000545
546 if( T.s == -1 )
547 T.s = 1;
548
Paul Bakker5121ce52009-01-03 21:22:43 +0000549 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
550 }
551
552 *p++ = '\0';
553 *slen = p - s;
554
555cleanup:
556
Paul Bakker6c591fa2011-05-05 11:49:20 +0000557 mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000558
559 return( ret );
560}
561
Paul Bakker335db3f2011-04-25 15:28:35 +0000562#if defined(POLARSSL_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000563/*
564 * Read X from an opened file
565 */
566int mpi_read_file( mpi *X, int radix, FILE *fin )
567{
Paul Bakkera755ca12011-04-24 09:11:17 +0000568 t_uint d;
Paul Bakker23986e52011-04-24 08:57:21 +0000569 size_t slen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000570 char *p;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000571 /*
Paul Bakkercb37aa52011-11-30 16:00:20 +0000572 * Buffer should have space for (short) label and decimal formatted MPI,
573 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000574 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000575 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000576
577 memset( s, 0, sizeof( s ) );
578 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000579 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000580
581 slen = strlen( s );
Paul Bakkercb37aa52011-11-30 16:00:20 +0000582 if( slen == sizeof( s ) - 2 )
583 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
584
Paul Bakker5121ce52009-01-03 21:22:43 +0000585 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
586 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
587
588 p = s + slen;
589 while( --p >= s )
590 if( mpi_get_digit( &d, radix, *p ) != 0 )
591 break;
592
593 return( mpi_read_string( X, radix, p + 1 ) );
594}
595
596/*
597 * Write X into an opened file (or stdout if fout == NULL)
598 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000599int mpi_write_file( const char *p, const mpi *X, int radix, FILE *fout )
Paul Bakker5121ce52009-01-03 21:22:43 +0000600{
Paul Bakker23986e52011-04-24 08:57:21 +0000601 int ret;
602 size_t n, slen, plen;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000603 /*
Paul Bakker5531c6d2012-09-26 19:20:46 +0000604 * Buffer should have space for (short) label and decimal formatted MPI,
605 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000606 */
Paul Bakker5531c6d2012-09-26 19:20:46 +0000607 char s[ POLARSSL_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000608
609 n = sizeof( s );
610 memset( s, 0, n );
611 n -= 2;
612
Paul Bakker23986e52011-04-24 08:57:21 +0000613 MPI_CHK( mpi_write_string( X, radix, s, (size_t *) &n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000614
615 if( p == NULL ) p = "";
616
617 plen = strlen( p );
618 slen = strlen( s );
619 s[slen++] = '\r';
620 s[slen++] = '\n';
621
622 if( fout != NULL )
623 {
624 if( fwrite( p, 1, plen, fout ) != plen ||
625 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000626 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000627 }
628 else
Paul Bakker7dc4c442014-02-01 22:50:26 +0100629 polarssl_printf( "%s%s", p, s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000630
631cleanup:
632
633 return( ret );
634}
Paul Bakker335db3f2011-04-25 15:28:35 +0000635#endif /* POLARSSL_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000636
637/*
638 * Import X from unsigned binary data, big endian
639 */
Paul Bakker23986e52011-04-24 08:57:21 +0000640int mpi_read_binary( mpi *X, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000641{
Paul Bakker23986e52011-04-24 08:57:21 +0000642 int ret;
643 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000644
645 for( n = 0; n < buflen; n++ )
646 if( buf[n] != 0 )
647 break;
648
649 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
650 MPI_CHK( mpi_lset( X, 0 ) );
651
Paul Bakker23986e52011-04-24 08:57:21 +0000652 for( i = buflen, j = 0; i > n; i--, j++ )
Paul Bakkera755ca12011-04-24 09:11:17 +0000653 X->p[j / ciL] |= ((t_uint) buf[i - 1]) << ((j % ciL) << 3);
Paul Bakker5121ce52009-01-03 21:22:43 +0000654
655cleanup:
656
657 return( ret );
658}
659
660/*
661 * Export X into unsigned binary data, big endian
662 */
Paul Bakker23986e52011-04-24 08:57:21 +0000663int mpi_write_binary( const mpi *X, unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000664{
Paul Bakker23986e52011-04-24 08:57:21 +0000665 size_t i, j, n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000666
667 n = mpi_size( X );
668
669 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000670 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000671
672 memset( buf, 0, buflen );
673
674 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
675 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
676
677 return( 0 );
678}
679
680/*
681 * Left-shift: X <<= count
682 */
Paul Bakker23986e52011-04-24 08:57:21 +0000683int mpi_shift_l( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000684{
Paul Bakker23986e52011-04-24 08:57:21 +0000685 int ret;
686 size_t i, v0, t1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000687 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000688
689 v0 = count / (biL );
690 t1 = count & (biL - 1);
691
692 i = mpi_msb( X ) + count;
693
Paul Bakkerf9688572011-05-05 10:00:45 +0000694 if( X->n * biL < i )
Paul Bakker5121ce52009-01-03 21:22:43 +0000695 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
696
697 ret = 0;
698
699 /*
700 * shift by count / limb_size
701 */
702 if( v0 > 0 )
703 {
Paul Bakker23986e52011-04-24 08:57:21 +0000704 for( i = X->n; i > v0; i-- )
705 X->p[i - 1] = X->p[i - v0 - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000706
Paul Bakker23986e52011-04-24 08:57:21 +0000707 for( ; i > 0; i-- )
708 X->p[i - 1] = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000709 }
710
711 /*
712 * shift by count % limb_size
713 */
714 if( t1 > 0 )
715 {
716 for( i = v0; i < X->n; i++ )
717 {
718 r1 = X->p[i] >> (biL - t1);
719 X->p[i] <<= t1;
720 X->p[i] |= r0;
721 r0 = r1;
722 }
723 }
724
725cleanup:
726
727 return( ret );
728}
729
730/*
731 * Right-shift: X >>= count
732 */
Paul Bakker23986e52011-04-24 08:57:21 +0000733int mpi_shift_r( mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +0000734{
Paul Bakker23986e52011-04-24 08:57:21 +0000735 size_t i, v0, v1;
Paul Bakkera755ca12011-04-24 09:11:17 +0000736 t_uint r0 = 0, r1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000737
738 v0 = count / biL;
739 v1 = count & (biL - 1);
740
Manuel Pégourié-Gonnarde44ec102012-11-17 12:42:51 +0100741 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
742 return mpi_lset( X, 0 );
743
Paul Bakker5121ce52009-01-03 21:22:43 +0000744 /*
745 * shift by count / limb_size
746 */
747 if( v0 > 0 )
748 {
749 for( i = 0; i < X->n - v0; i++ )
750 X->p[i] = X->p[i + v0];
751
752 for( ; i < X->n; i++ )
753 X->p[i] = 0;
754 }
755
756 /*
757 * shift by count % limb_size
758 */
759 if( v1 > 0 )
760 {
Paul Bakker23986e52011-04-24 08:57:21 +0000761 for( i = X->n; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000762 {
Paul Bakker23986e52011-04-24 08:57:21 +0000763 r1 = X->p[i - 1] << (biL - v1);
764 X->p[i - 1] >>= v1;
765 X->p[i - 1] |= r0;
Paul Bakker5121ce52009-01-03 21:22:43 +0000766 r0 = r1;
767 }
768 }
769
770 return( 0 );
771}
772
773/*
774 * Compare unsigned values
775 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000776int mpi_cmp_abs( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000777{
Paul Bakker23986e52011-04-24 08:57:21 +0000778 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000779
Paul Bakker23986e52011-04-24 08:57:21 +0000780 for( i = X->n; i > 0; i-- )
781 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000782 break;
783
Paul Bakker23986e52011-04-24 08:57:21 +0000784 for( j = Y->n; j > 0; j-- )
785 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000786 break;
787
Paul Bakker23986e52011-04-24 08:57:21 +0000788 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000789 return( 0 );
790
791 if( i > j ) return( 1 );
792 if( j > i ) return( -1 );
793
Paul Bakker23986e52011-04-24 08:57:21 +0000794 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000795 {
Paul Bakker23986e52011-04-24 08:57:21 +0000796 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
797 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000798 }
799
800 return( 0 );
801}
802
803/*
804 * Compare signed values
805 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000806int mpi_cmp_mpi( const mpi *X, const mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000807{
Paul Bakker23986e52011-04-24 08:57:21 +0000808 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000809
Paul Bakker23986e52011-04-24 08:57:21 +0000810 for( i = X->n; i > 0; i-- )
811 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000812 break;
813
Paul Bakker23986e52011-04-24 08:57:21 +0000814 for( j = Y->n; j > 0; j-- )
815 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000816 break;
817
Paul Bakker23986e52011-04-24 08:57:21 +0000818 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000819 return( 0 );
820
821 if( i > j ) return( X->s );
Paul Bakker0c8f73b2012-03-22 14:08:57 +0000822 if( j > i ) return( -Y->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000823
824 if( X->s > 0 && Y->s < 0 ) return( 1 );
825 if( Y->s > 0 && X->s < 0 ) return( -1 );
826
Paul Bakker23986e52011-04-24 08:57:21 +0000827 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000828 {
Paul Bakker23986e52011-04-24 08:57:21 +0000829 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
830 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000831 }
832
833 return( 0 );
834}
835
836/*
837 * Compare signed values
838 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000839int mpi_cmp_int( const mpi *X, t_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000840{
841 mpi Y;
Paul Bakkera755ca12011-04-24 09:11:17 +0000842 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +0000843
844 *p = ( z < 0 ) ? -z : z;
845 Y.s = ( z < 0 ) ? -1 : 1;
846 Y.n = 1;
847 Y.p = p;
848
849 return( mpi_cmp_mpi( X, &Y ) );
850}
851
852/*
853 * Unsigned addition: X = |A| + |B| (HAC 14.7)
854 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000855int mpi_add_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000856{
Paul Bakker23986e52011-04-24 08:57:21 +0000857 int ret;
858 size_t i, j;
Paul Bakkera755ca12011-04-24 09:11:17 +0000859 t_uint *o, *p, c;
Paul Bakker5121ce52009-01-03 21:22:43 +0000860
861 if( X == B )
862 {
Paul Bakkerff60ee62010-03-16 21:09:09 +0000863 const mpi *T = A; A = X; B = T;
Paul Bakker5121ce52009-01-03 21:22:43 +0000864 }
865
866 if( X != A )
867 MPI_CHK( mpi_copy( X, A ) );
Paul Bakker9af723c2014-05-01 13:03:14 +0200868
Paul Bakkerf7ca7b92009-06-20 10:31:06 +0000869 /*
870 * X should always be positive as a result of unsigned additions.
871 */
872 X->s = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +0000873
Paul Bakker23986e52011-04-24 08:57:21 +0000874 for( j = B->n; j > 0; j-- )
875 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000876 break;
877
Paul Bakker23986e52011-04-24 08:57:21 +0000878 MPI_CHK( mpi_grow( X, j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000879
880 o = B->p; p = X->p; c = 0;
881
Paul Bakker23986e52011-04-24 08:57:21 +0000882 for( i = 0; i < j; i++, o++, p++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000883 {
884 *p += c; c = ( *p < c );
885 *p += *o; c += ( *p < *o );
886 }
887
888 while( c != 0 )
889 {
890 if( i >= X->n )
891 {
892 MPI_CHK( mpi_grow( X, i + 1 ) );
893 p = X->p + i;
894 }
895
Paul Bakker2d319fd2012-09-16 21:34:26 +0000896 *p += c; c = ( *p < c ); i++; p++;
Paul Bakker5121ce52009-01-03 21:22:43 +0000897 }
898
899cleanup:
900
901 return( ret );
902}
903
904/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100905 * Helper for mpi subtraction
Paul Bakker5121ce52009-01-03 21:22:43 +0000906 */
Paul Bakkera755ca12011-04-24 09:11:17 +0000907static void mpi_sub_hlp( size_t n, t_uint *s, t_uint *d )
Paul Bakker5121ce52009-01-03 21:22:43 +0000908{
Paul Bakker23986e52011-04-24 08:57:21 +0000909 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +0000910 t_uint c, z;
Paul Bakker5121ce52009-01-03 21:22:43 +0000911
912 for( i = c = 0; i < n; i++, s++, d++ )
913 {
914 z = ( *d < c ); *d -= c;
915 c = ( *d < *s ) + z; *d -= *s;
916 }
917
918 while( c != 0 )
919 {
920 z = ( *d < c ); *d -= c;
921 c = z; i++; d++;
922 }
923}
924
925/*
Paul Bakker60b1d102013-10-29 10:02:51 +0100926 * Unsigned subtraction: X = |A| - |B| (HAC 14.9)
Paul Bakker5121ce52009-01-03 21:22:43 +0000927 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000928int mpi_sub_abs( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000929{
930 mpi TB;
Paul Bakker23986e52011-04-24 08:57:21 +0000931 int ret;
932 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000933
934 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000935 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000936
Paul Bakker6c591fa2011-05-05 11:49:20 +0000937 mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000938
939 if( X == B )
940 {
941 MPI_CHK( mpi_copy( &TB, B ) );
942 B = &TB;
943 }
944
945 if( X != A )
946 MPI_CHK( mpi_copy( X, A ) );
947
Paul Bakker1ef7a532009-06-20 10:50:55 +0000948 /*
Paul Bakker60b1d102013-10-29 10:02:51 +0100949 * X should always be positive as a result of unsigned subtractions.
Paul Bakker1ef7a532009-06-20 10:50:55 +0000950 */
951 X->s = 1;
952
Paul Bakker5121ce52009-01-03 21:22:43 +0000953 ret = 0;
954
Paul Bakker23986e52011-04-24 08:57:21 +0000955 for( n = B->n; n > 0; n-- )
956 if( B->p[n - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000957 break;
958
Paul Bakker23986e52011-04-24 08:57:21 +0000959 mpi_sub_hlp( n, B->p, X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000960
961cleanup:
962
Paul Bakker6c591fa2011-05-05 11:49:20 +0000963 mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +0000964
965 return( ret );
966}
967
968/*
969 * Signed addition: X = A + B
970 */
Paul Bakkerff60ee62010-03-16 21:09:09 +0000971int mpi_add_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +0000972{
973 int ret, s = A->s;
974
975 if( A->s * B->s < 0 )
976 {
977 if( mpi_cmp_abs( A, B ) >= 0 )
978 {
979 MPI_CHK( mpi_sub_abs( X, A, B ) );
980 X->s = s;
981 }
982 else
983 {
984 MPI_CHK( mpi_sub_abs( X, B, A ) );
985 X->s = -s;
986 }
987 }
988 else
989 {
990 MPI_CHK( mpi_add_abs( X, A, B ) );
991 X->s = s;
992 }
993
994cleanup:
995
996 return( ret );
997}
998
999/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001000 * Signed subtraction: X = A - B
Paul Bakker5121ce52009-01-03 21:22:43 +00001001 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001002int mpi_sub_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001003{
1004 int ret, s = A->s;
1005
1006 if( A->s * B->s > 0 )
1007 {
1008 if( mpi_cmp_abs( A, B ) >= 0 )
1009 {
1010 MPI_CHK( mpi_sub_abs( X, A, B ) );
1011 X->s = s;
1012 }
1013 else
1014 {
1015 MPI_CHK( mpi_sub_abs( X, B, A ) );
1016 X->s = -s;
1017 }
1018 }
1019 else
1020 {
1021 MPI_CHK( mpi_add_abs( X, A, B ) );
1022 X->s = s;
1023 }
1024
1025cleanup:
1026
1027 return( ret );
1028}
1029
1030/*
1031 * Signed addition: X = A + b
1032 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001033int mpi_add_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001034{
1035 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001036 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001037
1038 p[0] = ( b < 0 ) ? -b : b;
1039 _B.s = ( b < 0 ) ? -1 : 1;
1040 _B.n = 1;
1041 _B.p = p;
1042
1043 return( mpi_add_mpi( X, A, &_B ) );
1044}
1045
1046/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001047 * Signed subtraction: X = A - b
Paul Bakker5121ce52009-01-03 21:22:43 +00001048 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001049int mpi_sub_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001050{
1051 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001052 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001053
1054 p[0] = ( b < 0 ) ? -b : b;
1055 _B.s = ( b < 0 ) ? -1 : 1;
1056 _B.n = 1;
1057 _B.p = p;
1058
1059 return( mpi_sub_mpi( X, A, &_B ) );
1060}
1061
1062/*
1063 * Helper for mpi multiplication
Paul Bakkerfc4f46f2013-06-24 19:23:56 +02001064 */
1065static
1066#if defined(__APPLE__) && defined(__arm__)
1067/*
1068 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1069 * appears to need this to prevent bad ARM code generation at -O3.
1070 */
1071__attribute__ ((noinline))
1072#endif
1073void mpi_mul_hlp( size_t i, t_uint *s, t_uint *d, t_uint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001074{
Paul Bakkera755ca12011-04-24 09:11:17 +00001075 t_uint c = 0, t = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001076
1077#if defined(MULADDC_HUIT)
1078 for( ; i >= 8; i -= 8 )
1079 {
1080 MULADDC_INIT
1081 MULADDC_HUIT
1082 MULADDC_STOP
1083 }
1084
1085 for( ; i > 0; i-- )
1086 {
1087 MULADDC_INIT
1088 MULADDC_CORE
1089 MULADDC_STOP
1090 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001091#else /* MULADDC_HUIT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001092 for( ; i >= 16; i -= 16 )
1093 {
1094 MULADDC_INIT
1095 MULADDC_CORE MULADDC_CORE
1096 MULADDC_CORE MULADDC_CORE
1097 MULADDC_CORE MULADDC_CORE
1098 MULADDC_CORE MULADDC_CORE
1099
1100 MULADDC_CORE MULADDC_CORE
1101 MULADDC_CORE MULADDC_CORE
1102 MULADDC_CORE MULADDC_CORE
1103 MULADDC_CORE MULADDC_CORE
1104 MULADDC_STOP
1105 }
1106
1107 for( ; i >= 8; i -= 8 )
1108 {
1109 MULADDC_INIT
1110 MULADDC_CORE MULADDC_CORE
1111 MULADDC_CORE MULADDC_CORE
1112
1113 MULADDC_CORE MULADDC_CORE
1114 MULADDC_CORE MULADDC_CORE
1115 MULADDC_STOP
1116 }
1117
1118 for( ; i > 0; i-- )
1119 {
1120 MULADDC_INIT
1121 MULADDC_CORE
1122 MULADDC_STOP
1123 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001124#endif /* MULADDC_HUIT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001125
1126 t++;
1127
1128 do {
1129 *d += c; c = ( *d < c ); d++;
1130 }
1131 while( c != 0 );
1132}
1133
1134/*
1135 * Baseline multiplication: X = A * B (HAC 14.12)
1136 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001137int mpi_mul_mpi( mpi *X, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001138{
Paul Bakker23986e52011-04-24 08:57:21 +00001139 int ret;
1140 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +00001141 mpi TA, TB;
1142
Paul Bakker6c591fa2011-05-05 11:49:20 +00001143 mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001144
1145 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
1146 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
1147
Paul Bakker23986e52011-04-24 08:57:21 +00001148 for( i = A->n; i > 0; i-- )
1149 if( A->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001150 break;
1151
Paul Bakker23986e52011-04-24 08:57:21 +00001152 for( j = B->n; j > 0; j-- )
1153 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001154 break;
1155
Paul Bakker23986e52011-04-24 08:57:21 +00001156 MPI_CHK( mpi_grow( X, i + j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001157 MPI_CHK( mpi_lset( X, 0 ) );
1158
Paul Bakker23986e52011-04-24 08:57:21 +00001159 for( i++; j > 0; j-- )
1160 mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001161
1162 X->s = A->s * B->s;
1163
1164cleanup:
1165
Paul Bakker6c591fa2011-05-05 11:49:20 +00001166 mpi_free( &TB ); mpi_free( &TA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001167
1168 return( ret );
1169}
1170
1171/*
1172 * Baseline multiplication: X = A * b
1173 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001174int mpi_mul_int( mpi *X, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001175{
1176 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001177 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001178
1179 _B.s = 1;
1180 _B.n = 1;
1181 _B.p = p;
1182 p[0] = b;
1183
1184 return( mpi_mul_mpi( X, A, &_B ) );
1185}
1186
1187/*
1188 * Division by mpi: A = Q * B + R (HAC 14.20)
1189 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001190int mpi_div_mpi( mpi *Q, mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001191{
Paul Bakker23986e52011-04-24 08:57:21 +00001192 int ret;
1193 size_t i, n, t, k;
Paul Bakker5121ce52009-01-03 21:22:43 +00001194 mpi X, Y, Z, T1, T2;
1195
1196 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001197 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001198
Paul Bakker6c591fa2011-05-05 11:49:20 +00001199 mpi_init( &X ); mpi_init( &Y ); mpi_init( &Z );
1200 mpi_init( &T1 ); mpi_init( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001201
1202 if( mpi_cmp_abs( A, B ) < 0 )
1203 {
1204 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1205 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1206 return( 0 );
1207 }
1208
1209 MPI_CHK( mpi_copy( &X, A ) );
1210 MPI_CHK( mpi_copy( &Y, B ) );
1211 X.s = Y.s = 1;
1212
1213 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1214 MPI_CHK( mpi_lset( &Z, 0 ) );
1215 MPI_CHK( mpi_grow( &T1, 2 ) );
1216 MPI_CHK( mpi_grow( &T2, 3 ) );
1217
1218 k = mpi_msb( &Y ) % biL;
Paul Bakkerf9688572011-05-05 10:00:45 +00001219 if( k < biL - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001220 {
1221 k = biL - 1 - k;
1222 MPI_CHK( mpi_shift_l( &X, k ) );
1223 MPI_CHK( mpi_shift_l( &Y, k ) );
1224 }
1225 else k = 0;
1226
1227 n = X.n - 1;
1228 t = Y.n - 1;
Paul Bakker66d5d072014-06-17 16:39:18 +02001229 MPI_CHK( mpi_shift_l( &Y, biL * ( n - t ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001230
1231 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1232 {
1233 Z.p[n - t]++;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001234 MPI_CHK( mpi_sub_mpi( &X, &X, &Y ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001235 }
Paul Bakker66d5d072014-06-17 16:39:18 +02001236 MPI_CHK( mpi_shift_r( &Y, biL * ( n - t ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001237
1238 for( i = n; i > t ; i-- )
1239 {
1240 if( X.p[i] >= Y.p[t] )
1241 Z.p[i - t - 1] = ~0;
1242 else
1243 {
Manuel Pégourié-Gonnardbb8661e2014-03-14 09:21:20 +01001244 /*
Manuel Pégourié-Gonnard2eea2922014-03-14 18:23:26 +01001245 * The version of Clang shipped by Apple with Mavericks around
1246 * 2014-03 can't handle 128-bit division properly. Disable
1247 * 128-bits division for this version. Let's be optimistic and
1248 * assume it'll be fixed in the next minor version (next
1249 * patchlevel is probably a bit too optimistic).
Manuel Pégourié-Gonnardbb8661e2014-03-14 09:21:20 +01001250 */
Manuel Pégourié-Gonnard2eea2922014-03-14 18:23:26 +01001251#if defined(POLARSSL_HAVE_UDBL) && \
1252 ! ( defined(__x86_64__) && defined(__APPLE__) && \
1253 defined(__clang_major__) && __clang_major__ == 5 && \
1254 defined(__clang_minor__) && __clang_minor__ == 0 )
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001255 t_udbl r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001256
Paul Bakkeradb7ce12011-08-23 14:55:55 +00001257 r = (t_udbl) X.p[i] << biL;
1258 r |= (t_udbl) X.p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001259 r /= Y.p[t];
Paul Bakker66d5d072014-06-17 16:39:18 +02001260 if( r > ( (t_udbl) 1 << biL ) - 1 )
1261 r = ( (t_udbl) 1 << biL ) - 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001262
Paul Bakkera755ca12011-04-24 09:11:17 +00001263 Z.p[i - t - 1] = (t_uint) r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001264#else
1265 /*
1266 * __udiv_qrnnd_c, from gmp/longlong.h
1267 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001268 t_uint q0, q1, r0, r1;
1269 t_uint d0, d1, d, m;
Paul Bakker5121ce52009-01-03 21:22:43 +00001270
1271 d = Y.p[t];
1272 d0 = ( d << biH ) >> biH;
1273 d1 = ( d >> biH );
1274
1275 q1 = X.p[i] / d1;
1276 r1 = X.p[i] - d1 * q1;
1277 r1 <<= biH;
1278 r1 |= ( X.p[i - 1] >> biH );
1279
1280 m = q1 * d0;
1281 if( r1 < m )
1282 {
1283 q1--, r1 += d;
1284 while( r1 >= d && r1 < m )
1285 q1--, r1 += d;
1286 }
1287 r1 -= m;
1288
1289 q0 = r1 / d1;
1290 r0 = r1 - d1 * q0;
1291 r0 <<= biH;
1292 r0 |= ( X.p[i - 1] << biH ) >> biH;
1293
1294 m = q0 * d0;
1295 if( r0 < m )
1296 {
1297 q0--, r0 += d;
1298 while( r0 >= d && r0 < m )
1299 q0--, r0 += d;
1300 }
1301 r0 -= m;
1302
1303 Z.p[i - t - 1] = ( q1 << biH ) | q0;
Paul Bakkerdb20c102014-06-17 14:34:44 +02001304#endif /* POLARSSL_HAVE_UDBL && !64-bit Apple with Clang 5.0 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001305 }
1306
1307 Z.p[i - t - 1]++;
1308 do
1309 {
1310 Z.p[i - t - 1]--;
1311
1312 MPI_CHK( mpi_lset( &T1, 0 ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001313 T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001314 T1.p[1] = Y.p[t];
1315 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1316
1317 MPI_CHK( mpi_lset( &T2, 0 ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001318 T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
1319 T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001320 T2.p[2] = X.p[i];
1321 }
1322 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1323
1324 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001325 MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001326 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1327
1328 if( mpi_cmp_int( &X, 0 ) < 0 )
1329 {
1330 MPI_CHK( mpi_copy( &T1, &Y ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001331 MPI_CHK( mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001332 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1333 Z.p[i - t - 1]--;
1334 }
1335 }
1336
1337 if( Q != NULL )
1338 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001339 MPI_CHK( mpi_copy( Q, &Z ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001340 Q->s = A->s * B->s;
1341 }
1342
1343 if( R != NULL )
1344 {
Paul Bakker6ea1a952013-12-31 11:16:03 +01001345 MPI_CHK( mpi_shift_r( &X, k ) );
Paul Bakkerf02c5642012-11-13 10:25:21 +00001346 X.s = A->s;
Paul Bakker6ea1a952013-12-31 11:16:03 +01001347 MPI_CHK( mpi_copy( R, &X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001348
Paul Bakker5121ce52009-01-03 21:22:43 +00001349 if( mpi_cmp_int( R, 0 ) == 0 )
1350 R->s = 1;
1351 }
1352
1353cleanup:
1354
Paul Bakker6c591fa2011-05-05 11:49:20 +00001355 mpi_free( &X ); mpi_free( &Y ); mpi_free( &Z );
1356 mpi_free( &T1 ); mpi_free( &T2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001357
1358 return( ret );
1359}
1360
1361/*
1362 * Division by int: A = Q * b + R
Paul Bakker5121ce52009-01-03 21:22:43 +00001363 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001364int mpi_div_int( mpi *Q, mpi *R, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001365{
1366 mpi _B;
Paul Bakkera755ca12011-04-24 09:11:17 +00001367 t_uint p[1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001368
1369 p[0] = ( b < 0 ) ? -b : b;
1370 _B.s = ( b < 0 ) ? -1 : 1;
1371 _B.n = 1;
1372 _B.p = p;
1373
1374 return( mpi_div_mpi( Q, R, A, &_B ) );
1375}
1376
1377/*
1378 * Modulo: R = A mod B
1379 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001380int mpi_mod_mpi( mpi *R, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001381{
1382 int ret;
1383
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001384 if( mpi_cmp_int( B, 0 ) < 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001385 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001386
Paul Bakker5121ce52009-01-03 21:22:43 +00001387 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1388
1389 while( mpi_cmp_int( R, 0 ) < 0 )
1390 MPI_CHK( mpi_add_mpi( R, R, B ) );
1391
1392 while( mpi_cmp_mpi( R, B ) >= 0 )
1393 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1394
1395cleanup:
1396
1397 return( ret );
1398}
1399
1400/*
1401 * Modulo: r = A mod b
1402 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001403int mpi_mod_int( t_uint *r, const mpi *A, t_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001404{
Paul Bakker23986e52011-04-24 08:57:21 +00001405 size_t i;
Paul Bakkera755ca12011-04-24 09:11:17 +00001406 t_uint x, y, z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001407
1408 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001409 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001410
1411 if( b < 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +02001412 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001413
1414 /*
1415 * handle trivial cases
1416 */
1417 if( b == 1 )
1418 {
1419 *r = 0;
1420 return( 0 );
1421 }
1422
1423 if( b == 2 )
1424 {
1425 *r = A->p[0] & 1;
1426 return( 0 );
1427 }
1428
1429 /*
1430 * general case
1431 */
Paul Bakker23986e52011-04-24 08:57:21 +00001432 for( i = A->n, y = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001433 {
Paul Bakker23986e52011-04-24 08:57:21 +00001434 x = A->p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001435 y = ( y << biH ) | ( x >> biH );
1436 z = y / b;
1437 y -= z * b;
1438
1439 x <<= biH;
1440 y = ( y << biH ) | ( x >> biH );
1441 z = y / b;
1442 y -= z * b;
1443 }
1444
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001445 /*
1446 * If A is negative, then the current y represents a negative value.
1447 * Flipping it to the positive side.
1448 */
1449 if( A->s < 0 && y != 0 )
1450 y = b - y;
1451
Paul Bakker5121ce52009-01-03 21:22:43 +00001452 *r = y;
1453
1454 return( 0 );
1455}
1456
1457/*
1458 * Fast Montgomery initialization (thanks to Tom St Denis)
1459 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001460static void mpi_montg_init( t_uint *mm, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001461{
Paul Bakkera755ca12011-04-24 09:11:17 +00001462 t_uint x, m0 = N->p[0];
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001463 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001464
1465 x = m0;
1466 x += ( ( m0 + 2 ) & 4 ) << 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001467
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01001468 for( i = biL; i >= 8; i /= 2 )
1469 x *= ( 2 - ( m0 * x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001470
1471 *mm = ~x + 1;
1472}
1473
1474/*
1475 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1476 */
Paul Bakkerb9e4e2c2014-05-01 14:18:25 +02001477static void mpi_montmul( mpi *A, const mpi *B, const mpi *N, t_uint mm,
1478 const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001479{
Paul Bakker23986e52011-04-24 08:57:21 +00001480 size_t i, n, m;
Paul Bakkera755ca12011-04-24 09:11:17 +00001481 t_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00001482
1483 memset( T->p, 0, T->n * ciL );
1484
1485 d = T->p;
1486 n = N->n;
1487 m = ( B->n < n ) ? B->n : n;
1488
1489 for( i = 0; i < n; i++ )
1490 {
1491 /*
1492 * T = (T + u0*B + u1*N) / 2^biL
1493 */
1494 u0 = A->p[i];
1495 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1496
1497 mpi_mul_hlp( m, B->p, d, u0 );
1498 mpi_mul_hlp( n, N->p, d, u1 );
1499
1500 *d++ = u0; d[n + 1] = 0;
1501 }
1502
Paul Bakker66d5d072014-06-17 16:39:18 +02001503 memcpy( A->p, d, ( n + 1 ) * ciL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001504
1505 if( mpi_cmp_abs( A, N ) >= 0 )
1506 mpi_sub_hlp( n, N->p, A->p );
1507 else
1508 /* prevent timing attacks */
1509 mpi_sub_hlp( n, A->p, T->p );
1510}
1511
1512/*
1513 * Montgomery reduction: A = A * R^-1 mod N
1514 */
Paul Bakkera755ca12011-04-24 09:11:17 +00001515static void mpi_montred( mpi *A, const mpi *N, t_uint mm, const mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00001516{
Paul Bakkera755ca12011-04-24 09:11:17 +00001517 t_uint z = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001518 mpi U;
1519
Paul Bakker8ddb6452013-02-27 14:56:33 +01001520 U.n = U.s = (int) z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001521 U.p = &z;
1522
1523 mpi_montmul( A, &U, N, mm, T );
1524}
1525
1526/*
1527 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1528 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001529int mpi_exp_mod( mpi *X, const mpi *A, const mpi *E, const mpi *N, mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00001530{
Paul Bakker23986e52011-04-24 08:57:21 +00001531 int ret;
1532 size_t wbits, wsize, one = 1;
1533 size_t i, j, nblimbs;
1534 size_t bufsize, nbits;
Paul Bakkera755ca12011-04-24 09:11:17 +00001535 t_uint ei, mm, state;
Paul Bakkerf6198c12012-05-16 08:02:29 +00001536 mpi RR, T, W[ 2 << POLARSSL_MPI_WINDOW_SIZE ], Apos;
1537 int neg;
Paul Bakker5121ce52009-01-03 21:22:43 +00001538
1539 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001540 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001541
Paul Bakkerf6198c12012-05-16 08:02:29 +00001542 if( mpi_cmp_int( E, 0 ) < 0 )
1543 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
1544
1545 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001546 * Init temps and window size
1547 */
1548 mpi_montg_init( &mm, N );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001549 mpi_init( &RR ); mpi_init( &T );
Manuel Pégourié-Gonnardfd6a1912014-01-18 19:05:23 +01001550 mpi_init( &Apos );
Paul Bakker5121ce52009-01-03 21:22:43 +00001551 memset( W, 0, sizeof( W ) );
1552
1553 i = mpi_msb( E );
1554
1555 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1556 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1557
Paul Bakkerb6d5f082011-11-25 11:52:11 +00001558 if( wsize > POLARSSL_MPI_WINDOW_SIZE )
1559 wsize = POLARSSL_MPI_WINDOW_SIZE;
1560
Paul Bakker5121ce52009-01-03 21:22:43 +00001561 j = N->n + 1;
1562 MPI_CHK( mpi_grow( X, j ) );
1563 MPI_CHK( mpi_grow( &W[1], j ) );
1564 MPI_CHK( mpi_grow( &T, j * 2 ) );
1565
1566 /*
Paul Bakker50546922012-05-19 08:40:49 +00001567 * Compensate for negative A (and correct at the end)
1568 */
1569 neg = ( A->s == -1 );
Paul Bakker50546922012-05-19 08:40:49 +00001570 if( neg )
1571 {
1572 MPI_CHK( mpi_copy( &Apos, A ) );
1573 Apos.s = 1;
1574 A = &Apos;
1575 }
1576
1577 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00001578 * If 1st call, pre-compute R^2 mod N
1579 */
1580 if( _RR == NULL || _RR->p == NULL )
1581 {
1582 MPI_CHK( mpi_lset( &RR, 1 ) );
1583 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1584 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1585
1586 if( _RR != NULL )
1587 memcpy( _RR, &RR, sizeof( mpi ) );
1588 }
1589 else
1590 memcpy( &RR, _RR, sizeof( mpi ) );
1591
1592 /*
1593 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1594 */
1595 if( mpi_cmp_mpi( A, N ) >= 0 )
Paul Bakkerc2024f42014-01-23 20:38:35 +01001596 MPI_CHK( mpi_mod_mpi( &W[1], A, N ) );
1597 else
1598 MPI_CHK( mpi_copy( &W[1], A ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001599
1600 mpi_montmul( &W[1], &RR, N, mm, &T );
1601
1602 /*
1603 * X = R^2 * R^-1 mod N = R mod N
1604 */
1605 MPI_CHK( mpi_copy( X, &RR ) );
1606 mpi_montred( X, N, mm, &T );
1607
1608 if( wsize > 1 )
1609 {
1610 /*
1611 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1612 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001613 j = one << ( wsize - 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001614
1615 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1616 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1617
1618 for( i = 0; i < wsize - 1; i++ )
1619 mpi_montmul( &W[j], &W[j], N, mm, &T );
Paul Bakker0d7702c2013-10-29 16:18:35 +01001620
Paul Bakker5121ce52009-01-03 21:22:43 +00001621 /*
1622 * W[i] = W[i - 1] * W[1]
1623 */
Paul Bakker66d5d072014-06-17 16:39:18 +02001624 for( i = j + 1; i < ( one << wsize ); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001625 {
1626 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1627 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1628
1629 mpi_montmul( &W[i], &W[1], N, mm, &T );
1630 }
1631 }
1632
1633 nblimbs = E->n;
1634 bufsize = 0;
1635 nbits = 0;
1636 wbits = 0;
1637 state = 0;
1638
1639 while( 1 )
1640 {
1641 if( bufsize == 0 )
1642 {
Paul Bakker0d7702c2013-10-29 16:18:35 +01001643 if( nblimbs == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001644 break;
1645
Paul Bakker0d7702c2013-10-29 16:18:35 +01001646 nblimbs--;
1647
Paul Bakkera755ca12011-04-24 09:11:17 +00001648 bufsize = sizeof( t_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00001649 }
1650
1651 bufsize--;
1652
1653 ei = (E->p[nblimbs] >> bufsize) & 1;
1654
1655 /*
1656 * skip leading 0s
1657 */
1658 if( ei == 0 && state == 0 )
1659 continue;
1660
1661 if( ei == 0 && state == 1 )
1662 {
1663 /*
1664 * out of window, square X
1665 */
1666 mpi_montmul( X, X, N, mm, &T );
1667 continue;
1668 }
1669
1670 /*
1671 * add ei to current window
1672 */
1673 state = 2;
1674
1675 nbits++;
Paul Bakker66d5d072014-06-17 16:39:18 +02001676 wbits |= ( ei << ( wsize - nbits ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001677
1678 if( nbits == wsize )
1679 {
1680 /*
1681 * X = X^wsize R^-1 mod N
1682 */
1683 for( i = 0; i < wsize; i++ )
1684 mpi_montmul( X, X, N, mm, &T );
1685
1686 /*
1687 * X = X * W[wbits] R^-1 mod N
1688 */
1689 mpi_montmul( X, &W[wbits], N, mm, &T );
1690
1691 state--;
1692 nbits = 0;
1693 wbits = 0;
1694 }
1695 }
1696
1697 /*
1698 * process the remaining bits
1699 */
1700 for( i = 0; i < nbits; i++ )
1701 {
1702 mpi_montmul( X, X, N, mm, &T );
1703
1704 wbits <<= 1;
1705
Paul Bakker66d5d072014-06-17 16:39:18 +02001706 if( ( wbits & ( one << wsize ) ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001707 mpi_montmul( X, &W[1], N, mm, &T );
1708 }
1709
1710 /*
1711 * X = A^E * R * R^-1 mod N = A^E mod N
1712 */
1713 mpi_montred( X, N, mm, &T );
1714
Paul Bakkerf6198c12012-05-16 08:02:29 +00001715 if( neg )
1716 {
1717 X->s = -1;
Paul Bakkerc2024f42014-01-23 20:38:35 +01001718 MPI_CHK( mpi_add_mpi( X, N, X ) );
Paul Bakkerf6198c12012-05-16 08:02:29 +00001719 }
1720
Paul Bakker5121ce52009-01-03 21:22:43 +00001721cleanup:
1722
Paul Bakker66d5d072014-06-17 16:39:18 +02001723 for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001724 mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001725
Paul Bakkerf6198c12012-05-16 08:02:29 +00001726 mpi_free( &W[1] ); mpi_free( &T ); mpi_free( &Apos );
Paul Bakker6c591fa2011-05-05 11:49:20 +00001727
Paul Bakker75a28602014-03-31 12:08:17 +02001728 if( _RR == NULL || _RR->p == NULL )
Paul Bakker6c591fa2011-05-05 11:49:20 +00001729 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00001730
1731 return( ret );
1732}
1733
Paul Bakker5121ce52009-01-03 21:22:43 +00001734/*
1735 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1736 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001737int mpi_gcd( mpi *G, const mpi *A, const mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001738{
Paul Bakker23986e52011-04-24 08:57:21 +00001739 int ret;
1740 size_t lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001741 mpi TG, TA, TB;
1742
Paul Bakker6c591fa2011-05-05 11:49:20 +00001743 mpi_init( &TG ); mpi_init( &TA ); mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001744
Paul Bakker5121ce52009-01-03 21:22:43 +00001745 MPI_CHK( mpi_copy( &TA, A ) );
1746 MPI_CHK( mpi_copy( &TB, B ) );
1747
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001748 lz = mpi_lsb( &TA );
1749 lzt = mpi_lsb( &TB );
1750
Paul Bakker66d5d072014-06-17 16:39:18 +02001751 if( lzt < lz )
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001752 lz = lzt;
1753
1754 MPI_CHK( mpi_shift_r( &TA, lz ) );
1755 MPI_CHK( mpi_shift_r( &TB, lz ) );
1756
Paul Bakker5121ce52009-01-03 21:22:43 +00001757 TA.s = TB.s = 1;
1758
1759 while( mpi_cmp_int( &TA, 0 ) != 0 )
1760 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001761 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1762 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001763
1764 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1765 {
1766 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1767 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1768 }
1769 else
1770 {
1771 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1772 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1773 }
1774 }
1775
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001776 MPI_CHK( mpi_shift_l( &TB, lz ) );
1777 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001778
1779cleanup:
1780
Paul Bakker6c591fa2011-05-05 11:49:20 +00001781 mpi_free( &TG ); mpi_free( &TA ); mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001782
1783 return( ret );
1784}
1785
Paul Bakker33dc46b2014-04-30 16:11:39 +02001786/*
1787 * Fill X with size bytes of random.
1788 *
1789 * Use a temporary bytes representation to make sure the result is the same
Paul Bakkerc37b0ac2014-05-01 14:19:23 +02001790 * regardless of the platform endianness (useful when f_rng is actually
Paul Bakker33dc46b2014-04-30 16:11:39 +02001791 * deterministic, eg for tests).
1792 */
Paul Bakkera3d195c2011-11-27 21:07:34 +00001793int mpi_fill_random( mpi *X, size_t size,
1794 int (*f_rng)(void *, unsigned char *, size_t),
1795 void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00001796{
Paul Bakker23986e52011-04-24 08:57:21 +00001797 int ret;
Paul Bakker33dc46b2014-04-30 16:11:39 +02001798 unsigned char buf[POLARSSL_MPI_MAX_SIZE];
1799
1800 if( size > POLARSSL_MPI_MAX_SIZE )
1801 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker287781a2011-03-26 13:18:49 +00001802
Paul Bakker33dc46b2014-04-30 16:11:39 +02001803 MPI_CHK( f_rng( p_rng, buf, size ) );
1804 MPI_CHK( mpi_read_binary( X, buf, size ) );
Paul Bakker287781a2011-03-26 13:18:49 +00001805
1806cleanup:
1807 return( ret );
1808}
1809
Paul Bakker5121ce52009-01-03 21:22:43 +00001810/*
1811 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1812 */
Paul Bakkerff60ee62010-03-16 21:09:09 +00001813int mpi_inv_mod( mpi *X, const mpi *A, const mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00001814{
1815 int ret;
1816 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1817
1818 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001819 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001820
Paul Bakker6c591fa2011-05-05 11:49:20 +00001821 mpi_init( &TA ); mpi_init( &TU ); mpi_init( &U1 ); mpi_init( &U2 );
1822 mpi_init( &G ); mpi_init( &TB ); mpi_init( &TV );
1823 mpi_init( &V1 ); mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001824
1825 MPI_CHK( mpi_gcd( &G, A, N ) );
1826
1827 if( mpi_cmp_int( &G, 1 ) != 0 )
1828 {
Paul Bakker40e46942009-01-03 21:51:57 +00001829 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001830 goto cleanup;
1831 }
1832
1833 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1834 MPI_CHK( mpi_copy( &TU, &TA ) );
1835 MPI_CHK( mpi_copy( &TB, N ) );
1836 MPI_CHK( mpi_copy( &TV, N ) );
1837
1838 MPI_CHK( mpi_lset( &U1, 1 ) );
1839 MPI_CHK( mpi_lset( &U2, 0 ) );
1840 MPI_CHK( mpi_lset( &V1, 0 ) );
1841 MPI_CHK( mpi_lset( &V2, 1 ) );
1842
1843 do
1844 {
1845 while( ( TU.p[0] & 1 ) == 0 )
1846 {
1847 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1848
1849 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1850 {
1851 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1852 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1853 }
1854
1855 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1856 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1857 }
1858
1859 while( ( TV.p[0] & 1 ) == 0 )
1860 {
1861 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1862
1863 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1864 {
1865 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1866 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1867 }
1868
1869 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1870 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1871 }
1872
1873 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1874 {
1875 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1876 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1877 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1878 }
1879 else
1880 {
1881 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1882 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1883 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1884 }
1885 }
1886 while( mpi_cmp_int( &TU, 0 ) != 0 );
1887
1888 while( mpi_cmp_int( &V1, 0 ) < 0 )
1889 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1890
1891 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1892 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1893
1894 MPI_CHK( mpi_copy( X, &V1 ) );
1895
1896cleanup:
1897
Paul Bakker6c591fa2011-05-05 11:49:20 +00001898 mpi_free( &TA ); mpi_free( &TU ); mpi_free( &U1 ); mpi_free( &U2 );
1899 mpi_free( &G ); mpi_free( &TB ); mpi_free( &TV );
1900 mpi_free( &V1 ); mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001901
1902 return( ret );
1903}
1904
Paul Bakkerd9374b02012-11-02 11:02:58 +00001905#if defined(POLARSSL_GENPRIME)
1906
Paul Bakker5121ce52009-01-03 21:22:43 +00001907static const int small_prime[] =
1908{
1909 3, 5, 7, 11, 13, 17, 19, 23,
1910 29, 31, 37, 41, 43, 47, 53, 59,
1911 61, 67, 71, 73, 79, 83, 89, 97,
1912 101, 103, 107, 109, 113, 127, 131, 137,
1913 139, 149, 151, 157, 163, 167, 173, 179,
1914 181, 191, 193, 197, 199, 211, 223, 227,
1915 229, 233, 239, 241, 251, 257, 263, 269,
1916 271, 277, 281, 283, 293, 307, 311, 313,
1917 317, 331, 337, 347, 349, 353, 359, 367,
1918 373, 379, 383, 389, 397, 401, 409, 419,
1919 421, 431, 433, 439, 443, 449, 457, 461,
1920 463, 467, 479, 487, 491, 499, 503, 509,
1921 521, 523, 541, 547, 557, 563, 569, 571,
1922 577, 587, 593, 599, 601, 607, 613, 617,
1923 619, 631, 641, 643, 647, 653, 659, 661,
1924 673, 677, 683, 691, 701, 709, 719, 727,
1925 733, 739, 743, 751, 757, 761, 769, 773,
1926 787, 797, 809, 811, 821, 823, 827, 829,
1927 839, 853, 857, 859, 863, 877, 881, 883,
1928 887, 907, 911, 919, 929, 937, 941, 947,
1929 953, 967, 971, 977, 983, 991, 997, -103
1930};
1931
1932/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001933 * Small divisors test (X must be positive)
1934 *
1935 * Return values:
1936 * 0: no small factor (possible prime, more tests needed)
1937 * 1: certain prime
1938 * POLARSSL_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
1939 * other negative: error
Paul Bakker5121ce52009-01-03 21:22:43 +00001940 */
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001941static int mpi_check_small_factors( const mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +00001942{
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001943 int ret = 0;
1944 size_t i;
1945 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00001946
Paul Bakker5121ce52009-01-03 21:22:43 +00001947 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001948 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001949
1950 for( i = 0; small_prime[i] > 0; i++ )
1951 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001952 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001953 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001954
1955 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1956
1957 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001958 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001959 }
1960
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01001961cleanup:
1962 return( ret );
1963}
1964
1965/*
1966 * Miller-Rabin pseudo-primality test (HAC 4.24)
1967 */
1968static int mpi_miller_rabin( const mpi *X,
1969 int (*f_rng)(void *, unsigned char *, size_t),
1970 void *p_rng )
1971{
1972 int ret;
1973 size_t i, j, n, s;
1974 mpi W, R, T, A, RR;
1975
1976 mpi_init( &W ); mpi_init( &R ); mpi_init( &T ); mpi_init( &A );
1977 mpi_init( &RR );
1978
Paul Bakker5121ce52009-01-03 21:22:43 +00001979 /*
1980 * W = |X| - 1
1981 * R = W >> lsb( W )
1982 */
Paul Bakker5121ce52009-01-03 21:22:43 +00001983 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
Paul Bakker41d13f42010-03-16 21:26:36 +00001984 s = mpi_lsb( &W );
Paul Bakker5121ce52009-01-03 21:22:43 +00001985 MPI_CHK( mpi_copy( &R, &W ) );
1986 MPI_CHK( mpi_shift_r( &R, s ) );
1987
1988 i = mpi_msb( X );
1989 /*
1990 * HAC, table 4.4
1991 */
1992 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1993 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1994 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1995
1996 for( i = 0; i < n; i++ )
1997 {
1998 /*
1999 * pick a random A, 1 < A < |X| - 1
2000 */
Paul Bakker901c6562012-04-20 13:25:38 +00002001 MPI_CHK( mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002002
Paul Bakkerb94081b2011-01-05 15:53:06 +00002003 if( mpi_cmp_mpi( &A, &W ) >= 0 )
2004 {
2005 j = mpi_msb( &A ) - mpi_msb( &W );
2006 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
2007 }
Paul Bakker5121ce52009-01-03 21:22:43 +00002008 A.p[0] |= 3;
2009
2010 /*
2011 * A = A^R mod |X|
2012 */
2013 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
2014
2015 if( mpi_cmp_mpi( &A, &W ) == 0 ||
2016 mpi_cmp_int( &A, 1 ) == 0 )
2017 continue;
2018
2019 j = 1;
2020 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
2021 {
2022 /*
2023 * A = A * A mod |X|
2024 */
2025 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
2026 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
2027
2028 if( mpi_cmp_int( &A, 1 ) == 0 )
2029 break;
2030
2031 j++;
2032 }
2033
2034 /*
2035 * not prime if A != |X| - 1 or A == 1
2036 */
2037 if( mpi_cmp_mpi( &A, &W ) != 0 ||
2038 mpi_cmp_int( &A, 1 ) == 0 )
2039 {
Paul Bakker40e46942009-01-03 21:51:57 +00002040 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002041 break;
2042 }
2043 }
2044
2045cleanup:
Paul Bakker6c591fa2011-05-05 11:49:20 +00002046 mpi_free( &W ); mpi_free( &R ); mpi_free( &T ); mpi_free( &A );
2047 mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002048
2049 return( ret );
2050}
2051
2052/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002053 * Pseudo-primality test: small factors, then Miller-Rabin
2054 */
Paul Bakker45f457d2013-11-25 14:26:52 +01002055int mpi_is_prime( mpi *X,
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002056 int (*f_rng)(void *, unsigned char *, size_t),
2057 void *p_rng )
2058{
2059 int ret;
2060 const mpi XX = { 1, X->n, X->p }; /* Abs(X) */
2061
2062 if( mpi_cmp_int( &XX, 0 ) == 0 ||
2063 mpi_cmp_int( &XX, 1 ) == 0 )
2064 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
2065
2066 if( mpi_cmp_int( &XX, 2 ) == 0 )
2067 return( 0 );
2068
2069 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2070 {
2071 if( ret == 1 )
2072 return( 0 );
2073
2074 return( ret );
2075 }
2076
2077 return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
2078}
2079
2080/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002081 * Prime number generation
2082 */
Paul Bakker23986e52011-04-24 08:57:21 +00002083int mpi_gen_prime( mpi *X, size_t nbits, int dh_flag,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002084 int (*f_rng)(void *, unsigned char *, size_t),
2085 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +00002086{
Paul Bakker23986e52011-04-24 08:57:21 +00002087 int ret;
2088 size_t k, n;
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002089 t_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002090 mpi Y;
2091
Paul Bakkerfe3256e2011-11-25 12:11:43 +00002092 if( nbits < 3 || nbits > POLARSSL_MPI_MAX_BITS )
Paul Bakker40e46942009-01-03 21:51:57 +00002093 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002094
Paul Bakker6c591fa2011-05-05 11:49:20 +00002095 mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002096
2097 n = BITS_TO_LIMBS( nbits );
2098
Paul Bakker901c6562012-04-20 13:25:38 +00002099 MPI_CHK( mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002100
2101 k = mpi_msb( X );
2102 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
2103 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
2104
2105 X->p[0] |= 3;
2106
2107 if( dh_flag == 0 )
2108 {
2109 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
2110 {
Paul Bakker40e46942009-01-03 21:51:57 +00002111 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002112 goto cleanup;
2113
2114 MPI_CHK( mpi_add_int( X, X, 2 ) );
2115 }
2116 }
2117 else
2118 {
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002119 /*
2120 * An necessary condition for Y and X = 2Y + 1 to be prime
2121 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2122 * Make sure it is satisfied, while keeping X = 3 mod 4
2123 */
2124 MPI_CHK( mpi_mod_int( &r, X, 3 ) );
2125 if( r == 0 )
2126 MPI_CHK( mpi_add_int( X, X, 8 ) );
2127 else if( r == 1 )
2128 MPI_CHK( mpi_add_int( X, X, 4 ) );
2129
2130 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2131 MPI_CHK( mpi_copy( &Y, X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002132 MPI_CHK( mpi_shift_r( &Y, 1 ) );
2133
2134 while( 1 )
2135 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002136 /*
2137 * First, check small factors for X and Y
2138 * before doing Miller-Rabin on any of them
2139 */
2140 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2141 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2142 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
2143 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002144 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002145 break;
Paul Bakker5121ce52009-01-03 21:22:43 +00002146 }
2147
Paul Bakker40e46942009-01-03 21:51:57 +00002148 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00002149 goto cleanup;
2150
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002151 /*
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01002152 * Next candidates. We want to preserve Y = (X-1) / 2 and
Manuel Pégourié-Gonnard0160eac2013-11-22 17:54:59 +01002153 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2154 * so up Y by 6 and X by 12.
2155 */
2156 MPI_CHK( mpi_add_int( X, X, 12 ) );
2157 MPI_CHK( mpi_add_int( &Y, &Y, 6 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002158 }
2159 }
2160
2161cleanup:
2162
Paul Bakker6c591fa2011-05-05 11:49:20 +00002163 mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002164
2165 return( ret );
2166}
2167
Manuel Pégourié-Gonnarddf0142b2013-08-22 18:29:07 +02002168#endif /* POLARSSL_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00002169
Paul Bakker40e46942009-01-03 21:51:57 +00002170#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00002171
Paul Bakker23986e52011-04-24 08:57:21 +00002172#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002173
2174static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2175{
2176 { 693, 609, 21 },
2177 { 1764, 868, 28 },
2178 { 768454923, 542167814, 1 }
2179};
2180
Paul Bakker5121ce52009-01-03 21:22:43 +00002181/*
2182 * Checkup routine
2183 */
2184int mpi_self_test( int verbose )
2185{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002186 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00002187 mpi A, E, N, X, Y, U, V;
2188
Paul Bakker6c591fa2011-05-05 11:49:20 +00002189 mpi_init( &A ); mpi_init( &E ); mpi_init( &N ); mpi_init( &X );
2190 mpi_init( &Y ); mpi_init( &U ); mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002191
2192 MPI_CHK( mpi_read_string( &A, 16,
2193 "EFE021C2645FD1DC586E69184AF4A31E" \
2194 "D5F53E93B5F123FA41680867BA110131" \
2195 "944FE7952E2517337780CB0DB80E61AA" \
2196 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2197
2198 MPI_CHK( mpi_read_string( &E, 16,
2199 "B2E7EFD37075B9F03FF989C7C5051C20" \
2200 "34D2A323810251127E7BF8625A4F49A5" \
2201 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2202 "5B5C25763222FEFCCFC38B832366C29E" ) );
2203
2204 MPI_CHK( mpi_read_string( &N, 16,
2205 "0066A198186C18C10B2F5ED9B522752A" \
2206 "9830B69916E535C8F047518A889A43A5" \
2207 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2208
2209 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
2210
2211 MPI_CHK( mpi_read_string( &U, 16,
2212 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2213 "9E857EA95A03512E2BAE7391688D264A" \
2214 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2215 "8001B72E848A38CAE1C65F78E56ABDEF" \
2216 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2217 "ECF677152EF804370C1A305CAF3B5BF1" \
2218 "30879B56C61DE584A0F53A2447A51E" ) );
2219
2220 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002221 polarssl_printf( " MPI test #1 (mul_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002222
2223 if( mpi_cmp_mpi( &X, &U ) != 0 )
2224 {
2225 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002226 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002227
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002228 ret = 1;
2229 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002230 }
2231
2232 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002233 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002234
2235 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
2236
2237 MPI_CHK( mpi_read_string( &U, 16,
2238 "256567336059E52CAE22925474705F39A94" ) );
2239
2240 MPI_CHK( mpi_read_string( &V, 16,
2241 "6613F26162223DF488E9CD48CC132C7A" \
2242 "0AC93C701B001B092E4E5B9F73BCD27B" \
2243 "9EE50D0657C77F374E903CDFA4C642" ) );
2244
2245 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002246 polarssl_printf( " MPI test #2 (div_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002247
2248 if( mpi_cmp_mpi( &X, &U ) != 0 ||
2249 mpi_cmp_mpi( &Y, &V ) != 0 )
2250 {
2251 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002252 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002253
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002254 ret = 1;
2255 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002256 }
2257
2258 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002259 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002260
2261 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2262
2263 MPI_CHK( mpi_read_string( &U, 16,
2264 "36E139AEA55215609D2816998ED020BB" \
2265 "BD96C37890F65171D948E9BC7CBAA4D9" \
2266 "325D24D6A3C12710F10A09FA08AB87" ) );
2267
2268 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002269 polarssl_printf( " MPI test #3 (exp_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002270
2271 if( mpi_cmp_mpi( &X, &U ) != 0 )
2272 {
2273 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002274 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002275
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002276 ret = 1;
2277 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002278 }
2279
2280 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002281 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002282
2283 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
2284
2285 MPI_CHK( mpi_read_string( &U, 16,
2286 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2287 "C3DBA76456363A10869622EAC2DD84EC" \
2288 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2289
2290 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002291 polarssl_printf( " MPI test #4 (inv_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00002292
2293 if( mpi_cmp_mpi( &X, &U ) != 0 )
2294 {
2295 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002296 polarssl_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002297
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002298 ret = 1;
2299 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00002300 }
2301
2302 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002303 polarssl_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002304
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002305 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002306 polarssl_printf( " MPI test #5 (simple gcd): " );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002307
Paul Bakker66d5d072014-06-17 16:39:18 +02002308 for( i = 0; i < GCD_PAIR_COUNT; i++ )
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002309 {
2310 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
Paul Bakker23986e52011-04-24 08:57:21 +00002311 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002312
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002313 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002314
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002315 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2316 {
2317 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002318 polarssl_printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002319
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01002320 ret = 1;
2321 goto cleanup;
2322 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002323 }
2324
2325 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002326 polarssl_printf( "passed\n" );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002327
Paul Bakker5121ce52009-01-03 21:22:43 +00002328cleanup:
2329
2330 if( ret != 0 && verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002331 polarssl_printf( "Unexpected error, return code = %08X\n", ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00002332
Paul Bakker6c591fa2011-05-05 11:49:20 +00002333 mpi_free( &A ); mpi_free( &E ); mpi_free( &N ); mpi_free( &X );
2334 mpi_free( &Y ); mpi_free( &U ); mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00002335
2336 if( verbose != 0 )
Paul Bakker7dc4c442014-02-01 22:50:26 +01002337 polarssl_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00002338
2339 return( ret );
2340}
2341
Paul Bakker9af723c2014-05-01 13:03:14 +02002342#endif /* POLARSSL_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00002343
Paul Bakker9af723c2014-05-01 13:03:14 +02002344#endif /* POLARSSL_BIGNUM_C */