blob: 674026b357ddecce0068515adeb631e809150dad [file] [log] [blame]
Edison Ai7b079202018-02-28 15:01:47 +08001// SPDX-License-Identifier: Apache-2.0
Jens Wiklander817466c2018-05-22 13:49:31 +02002/*
3 * Multi-precision integer library
4 *
5 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Jens Wiklander817466c2018-05-22 13:49:31 +02006 *
7 * Licensed under the Apache License, Version 2.0 (the "License"); you may
8 * not use this file except in compliance with the License.
9 * You may obtain a copy of the License at
10 *
11 * http://www.apache.org/licenses/LICENSE-2.0
12 *
13 * Unless required by applicable law or agreed to in writing, software
14 * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
15 * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
16 * See the License for the specific language governing permissions and
17 * limitations under the License.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22/*
23 * The following sources were referenced in the design of this Multi-precision
24 * Integer library:
25 *
26 * [1] Handbook of Applied Cryptography - 1997
27 * Menezes, van Oorschot and Vanstone
28 *
29 * [2] Multi-Precision Math
30 * Tom St Denis
31 * https://github.com/libtom/libtommath/blob/develop/tommath.pdf
32 *
33 * [3] GNU Multi-Precision Arithmetic Library
34 * https://gmplib.org/manual/index.html
35 *
36 */
37
38#if !defined(MBEDTLS_CONFIG_FILE)
39#include "mbedtls/config.h"
40#else
41#include MBEDTLS_CONFIG_FILE
42#endif
43
44#if defined(MBEDTLS_BIGNUM_C)
45
46#include "mbedtls/bignum.h"
47#include "mbedtls/bn_mul.h"
Jens Wiklander50a57cf2019-03-13 10:41:54 +010048#include "mbedtls/platform_util.h"
Jens Wiklander817466c2018-05-22 13:49:31 +020049
50#include <string.h>
51
52#if defined(MBEDTLS_PLATFORM_C)
53#include "mbedtls/platform.h"
54#else
55#include <stdio.h>
56#include <stdlib.h>
57#define mbedtls_printf printf
58#define mbedtls_calloc calloc
59#define mbedtls_free free
60#endif
61
Jens Wiklander50a57cf2019-03-13 10:41:54 +010062#define MPI_VALIDATE_RET( cond ) \
63 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
64#define MPI_VALIDATE( cond ) \
65 MBEDTLS_INTERNAL_VALIDATE( cond )
Jens Wiklander817466c2018-05-22 13:49:31 +020066
67#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
68#define biL (ciL << 3) /* bits in limb */
69#define biH (ciL << 2) /* half limb size */
70
71#define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
72
73/*
74 * Convert between bits/chars and number of limbs
75 * Divide first in order to avoid potential overflows
76 */
77#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
78#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
79
Jens Wiklander50a57cf2019-03-13 10:41:54 +010080/* Implementation that should never be optimized out by the compiler */
81static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n )
82{
83 mbedtls_platform_zeroize( v, ciL * n );
84}
Jens Wiklander98bd5fe2018-11-08 11:18:22 +010085
Jens Wiklander817466c2018-05-22 13:49:31 +020086/*
87 * Initialize one MPI
88 */
Jens Wiklander98bd5fe2018-11-08 11:18:22 +010089void mbedtls_mpi_init( mbedtls_mpi *X )
90{
Jens Wiklander50a57cf2019-03-13 10:41:54 +010091 MPI_VALIDATE( X != NULL );
Jens Wiklander98bd5fe2018-11-08 11:18:22 +010092
Jens Wiklander50a57cf2019-03-13 10:41:54 +010093 X->s = 1;
94 X->n = 0;
95 X->p = NULL;
Jens Wiklander98bd5fe2018-11-08 11:18:22 +010096}
97
Jens Wiklander817466c2018-05-22 13:49:31 +020098/*
99 * Unallocate one MPI
100 */
101void mbedtls_mpi_free( mbedtls_mpi *X )
102{
103 if( X == NULL )
104 return;
105
106 if( X->p != NULL )
107 {
108 mbedtls_mpi_zeroize( X->p, X->n );
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100109 mbedtls_free( X->p );
Jens Wiklander817466c2018-05-22 13:49:31 +0200110 }
111
112 X->s = 1;
113 X->n = 0;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100114 X->p = NULL;
Jens Wiklander817466c2018-05-22 13:49:31 +0200115}
116
117/*
118 * Enlarge to the specified number of limbs
119 */
120int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs )
121{
122 mbedtls_mpi_uint *p;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100123 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200124
125 if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
126 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
127
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100128 if( X->n < nblimbs )
129 {
130 if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL )
Jens Wiklander18c51482018-11-12 13:53:08 +0100131 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100132
133 if( X->p != NULL )
134 {
135 memcpy( p, X->p, X->n * ciL );
136 mbedtls_mpi_zeroize( X->p, X->n );
137 mbedtls_free( X->p );
138 }
139
140 X->n = nblimbs;
141 X->p = p;
Jens Wiklander817466c2018-05-22 13:49:31 +0200142 }
143
144 return( 0 );
145}
146
147/*
148 * Resize down as much as possible,
149 * while keeping at least the specified number of limbs
150 */
151int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs )
152{
153 mbedtls_mpi_uint *p;
154 size_t i;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100155 MPI_VALIDATE_RET( X != NULL );
156
157 if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
158 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
Jens Wiklander817466c2018-05-22 13:49:31 +0200159
160 /* Actually resize up in this case */
161 if( X->n <= nblimbs )
162 return( mbedtls_mpi_grow( X, nblimbs ) );
163
164 for( i = X->n - 1; i > 0; i-- )
165 if( X->p[i] != 0 )
166 break;
167 i++;
168
169 if( i < nblimbs )
170 i = nblimbs;
171
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100172 if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( i, ciL ) ) == NULL )
173 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
Jens Wiklander817466c2018-05-22 13:49:31 +0200174
175 if( X->p != NULL )
176 {
177 memcpy( p, X->p, i * ciL );
178 mbedtls_mpi_zeroize( X->p, X->n );
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100179 mbedtls_free( X->p );
Jens Wiklander817466c2018-05-22 13:49:31 +0200180 }
181
Jens Wiklander18c51482018-11-12 13:53:08 +0100182 X->n = i;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100183 X->p = p;
Jens Wiklander817466c2018-05-22 13:49:31 +0200184
185 return( 0 );
186}
187
188/*
189 * Copy the contents of Y into X
190 */
191int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
192{
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100193 int ret = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200194 size_t i;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100195 MPI_VALIDATE_RET( X != NULL );
196 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200197
198 if( X == Y )
199 return( 0 );
200
201 if( Y->p == NULL )
202 {
203 mbedtls_mpi_free( X );
204 return( 0 );
205 }
206
207 for( i = Y->n - 1; i > 0; i-- )
208 if( Y->p[i] != 0 )
209 break;
210 i++;
211
212 X->s = Y->s;
213
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100214 if( X->n < i )
215 {
216 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) );
217 }
218 else
219 {
220 memset( X->p + i, 0, ( X->n - i ) * ciL );
221 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200222
Jens Wiklander817466c2018-05-22 13:49:31 +0200223 memcpy( X->p, Y->p, i * ciL );
224
225cleanup:
226
227 return( ret );
228}
229
230/*
231 * Swap the contents of X and Y
232 */
233void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
234{
235 mbedtls_mpi T;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100236 MPI_VALIDATE( X != NULL );
237 MPI_VALIDATE( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200238
239 memcpy( &T, X, sizeof( mbedtls_mpi ) );
240 memcpy( X, Y, sizeof( mbedtls_mpi ) );
241 memcpy( Y, &T, sizeof( mbedtls_mpi ) );
242}
243
244/*
245 * Conditionally assign X = Y, without leaking information
246 * about whether the assignment was made or not.
247 * (Leaking information about the respective sizes of X and Y is ok however.)
248 */
249int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign )
250{
251 int ret = 0;
252 size_t i;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100253 MPI_VALIDATE_RET( X != NULL );
254 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200255
256 /* make sure assign is 0 or 1 in a time-constant manner */
257 assign = (assign | (unsigned char)-assign) >> 7;
258
259 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
260
261 X->s = X->s * ( 1 - assign ) + Y->s * assign;
262
263 for( i = 0; i < Y->n; i++ )
264 X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign;
265
266 for( ; i < X->n; i++ )
267 X->p[i] *= ( 1 - assign );
268
269cleanup:
270 return( ret );
271}
272
273/*
274 * Conditionally swap X and Y, without leaking information
275 * about whether the swap was made or not.
276 * Here it is not ok to simply swap the pointers, which whould lead to
277 * different memory access patterns when X and Y are used afterwards.
278 */
279int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap )
280{
281 int ret, s;
282 size_t i;
283 mbedtls_mpi_uint tmp;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100284 MPI_VALIDATE_RET( X != NULL );
285 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200286
287 if( X == Y )
288 return( 0 );
289
290 /* make sure swap is 0 or 1 in a time-constant manner */
291 swap = (swap | (unsigned char)-swap) >> 7;
292
293 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
294 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
295
296 s = X->s;
297 X->s = X->s * ( 1 - swap ) + Y->s * swap;
298 Y->s = Y->s * ( 1 - swap ) + s * swap;
299
300
301 for( i = 0; i < X->n; i++ )
302 {
303 tmp = X->p[i];
304 X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap;
305 Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap;
306 }
307
308cleanup:
309 return( ret );
310}
311
312/*
313 * Set value from integer
314 */
315int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z )
316{
317 int ret;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100318 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200319
320 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) );
321 memset( X->p, 0, X->n * ciL );
322
323 X->p[0] = ( z < 0 ) ? -z : z;
324 X->s = ( z < 0 ) ? -1 : 1;
325
326cleanup:
327
328 return( ret );
329}
330
331/*
332 * Get a specific bit
333 */
334int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
335{
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100336 MPI_VALIDATE_RET( X != NULL );
337
Jens Wiklander817466c2018-05-22 13:49:31 +0200338 if( X->n * biL <= pos )
339 return( 0 );
340
341 return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
342}
343
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100344/* Get a specific byte, without range checks. */
345#define GET_BYTE( X, i ) \
346 ( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff )
347
Jens Wiklander817466c2018-05-22 13:49:31 +0200348/*
349 * Set a bit to a specific value of 0 or 1
350 */
351int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val )
352{
353 int ret = 0;
354 size_t off = pos / biL;
355 size_t idx = pos % biL;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100356 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200357
358 if( val != 0 && val != 1 )
359 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
360
361 if( X->n * biL <= pos )
362 {
363 if( val == 0 )
364 return( 0 );
365
366 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, off + 1 ) );
367 }
368
369 X->p[off] &= ~( (mbedtls_mpi_uint) 0x01 << idx );
370 X->p[off] |= (mbedtls_mpi_uint) val << idx;
371
372cleanup:
373
374 return( ret );
375}
376
377/*
378 * Return the number of less significant zero-bits
379 */
380size_t mbedtls_mpi_lsb( const mbedtls_mpi *X )
381{
382 size_t i, j, count = 0;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100383 MBEDTLS_INTERNAL_VALIDATE_RET( X != NULL, 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200384
385 for( i = 0; i < X->n; i++ )
386 for( j = 0; j < biL; j++, count++ )
387 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
388 return( count );
389
390 return( 0 );
391}
392
393/*
394 * Count leading zero bits in a given integer
395 */
396static size_t mbedtls_clz( const mbedtls_mpi_uint x )
397{
398 size_t j;
399 mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);
400
401 for( j = 0; j < biL; j++ )
402 {
403 if( x & mask ) break;
404
405 mask >>= 1;
406 }
407
408 return j;
409}
410
411/*
412 * Return the number of bits
413 */
414size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X )
415{
416 size_t i, j;
417
418 if( X->n == 0 )
419 return( 0 );
420
421 for( i = X->n - 1; i > 0; i-- )
422 if( X->p[i] != 0 )
423 break;
424
425 j = biL - mbedtls_clz( X->p[i] );
426
427 return( ( i * biL ) + j );
428}
429
430/*
431 * Return the total size in bytes
432 */
433size_t mbedtls_mpi_size( const mbedtls_mpi *X )
434{
435 return( ( mbedtls_mpi_bitlen( X ) + 7 ) >> 3 );
436}
437
438/*
439 * Convert an ASCII character to digit value
440 */
441static int mpi_get_digit( mbedtls_mpi_uint *d, int radix, char c )
442{
443 *d = 255;
444
445 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
446 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
447 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
448
449 if( *d >= (mbedtls_mpi_uint) radix )
450 return( MBEDTLS_ERR_MPI_INVALID_CHARACTER );
451
452 return( 0 );
453}
454
455/*
456 * Import from an ASCII string
457 */
458int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
459{
460 int ret;
461 size_t i, j, slen, n;
462 mbedtls_mpi_uint d;
463 mbedtls_mpi T;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100464 MPI_VALIDATE_RET( X != NULL );
465 MPI_VALIDATE_RET( s != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200466
467 if( radix < 2 || radix > 16 )
468 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
469
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100470 mbedtls_mpi_init( &T );
Jens Wiklander817466c2018-05-22 13:49:31 +0200471
472 slen = strlen( s );
473
474 if( radix == 16 )
475 {
476 if( slen > MPI_SIZE_T_MAX >> 2 )
477 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
478
479 n = BITS_TO_LIMBS( slen << 2 );
480
481 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) );
482 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
483
484 for( i = slen, j = 0; i > 0; i--, j++ )
485 {
486 if( i == 1 && s[i - 1] == '-' )
487 {
488 X->s = -1;
489 break;
490 }
491
492 MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
493 X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
494 }
495 }
496 else
497 {
498 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
499
500 for( i = 0; i < slen; i++ )
501 {
502 if( i == 0 && s[i] == '-' )
503 {
504 X->s = -1;
505 continue;
506 }
507
508 MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
509 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T, X, radix ) );
510
511 if( X->s == 1 )
512 {
513 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) );
514 }
515 else
516 {
517 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( X, &T, d ) );
518 }
519 }
520 }
521
522cleanup:
523
524 mbedtls_mpi_free( &T );
525
526 return( ret );
527}
528
529/*
530 * Helper to write the digits high-order first
531 */
532static int mpi_write_hlp( mbedtls_mpi *X, int radix, char **p )
533{
534 int ret;
535 mbedtls_mpi_uint r;
536
537 if( radix < 2 || radix > 16 )
538 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
539
540 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) );
541 MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) );
542
543 if( mbedtls_mpi_cmp_int( X, 0 ) != 0 )
544 MBEDTLS_MPI_CHK( mpi_write_hlp( X, radix, p ) );
545
546 if( r < 10 )
547 *(*p)++ = (char)( r + 0x30 );
548 else
549 *(*p)++ = (char)( r + 0x37 );
550
551cleanup:
552
553 return( ret );
554}
555
556/*
557 * Export into an ASCII string
558 */
559int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
560 char *buf, size_t buflen, size_t *olen )
561{
562 int ret = 0;
563 size_t n;
564 char *p;
565 mbedtls_mpi T;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100566 MPI_VALIDATE_RET( X != NULL );
567 MPI_VALIDATE_RET( olen != NULL );
568 MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200569
570 if( radix < 2 || radix > 16 )
571 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
572
573 n = mbedtls_mpi_bitlen( X );
574 if( radix >= 4 ) n >>= 1;
575 if( radix >= 16 ) n >>= 1;
576 /*
577 * Round up the buffer length to an even value to ensure that there is
578 * enough room for hexadecimal values that can be represented in an odd
579 * number of digits.
580 */
581 n += 3 + ( ( n + 1 ) & 1 );
582
583 if( buflen < n )
584 {
585 *olen = n;
586 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
587 }
588
589 p = buf;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100590 mbedtls_mpi_init( &T );
Jens Wiklander817466c2018-05-22 13:49:31 +0200591
592 if( X->s == -1 )
593 *p++ = '-';
594
595 if( radix == 16 )
596 {
597 int c;
598 size_t i, j, k;
599
600 for( i = X->n, k = 0; i > 0; i-- )
601 {
602 for( j = ciL; j > 0; j-- )
603 {
604 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
605
606 if( c == 0 && k == 0 && ( i + j ) != 2 )
607 continue;
608
609 *(p++) = "0123456789ABCDEF" [c / 16];
610 *(p++) = "0123456789ABCDEF" [c % 16];
611 k = 1;
612 }
613 }
614 }
615 else
616 {
617 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T, X ) );
618
619 if( T.s == -1 )
620 T.s = 1;
621
622 MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
623 }
624
625 *p++ = '\0';
626 *olen = p - buf;
627
628cleanup:
629
630 mbedtls_mpi_free( &T );
631
632 return( ret );
633}
634
635#if defined(MBEDTLS_FS_IO)
636/*
637 * Read X from an opened file
638 */
639int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin )
640{
641 mbedtls_mpi_uint d;
642 size_t slen;
643 char *p;
644 /*
645 * Buffer should have space for (short) label and decimal formatted MPI,
646 * newline characters and '\0'
647 */
648 char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
649
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100650 MPI_VALIDATE_RET( X != NULL );
651 MPI_VALIDATE_RET( fin != NULL );
652
653 if( radix < 2 || radix > 16 )
654 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
655
Jens Wiklander817466c2018-05-22 13:49:31 +0200656 memset( s, 0, sizeof( s ) );
657 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
658 return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
659
660 slen = strlen( s );
661 if( slen == sizeof( s ) - 2 )
662 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
663
664 if( slen > 0 && s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
665 if( slen > 0 && s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
666
667 p = s + slen;
668 while( p-- > s )
669 if( mpi_get_digit( &d, radix, *p ) != 0 )
670 break;
671
672 return( mbedtls_mpi_read_string( X, radix, p + 1 ) );
673}
674
675/*
676 * Write X into an opened file (or stdout if fout == NULL)
677 */
678int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout )
679{
680 int ret;
681 size_t n, slen, plen;
682 /*
683 * Buffer should have space for (short) label and decimal formatted MPI,
684 * newline characters and '\0'
685 */
686 char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100687 MPI_VALIDATE_RET( X != NULL );
688
689 if( radix < 2 || radix > 16 )
690 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
Jens Wiklander817466c2018-05-22 13:49:31 +0200691
692 memset( s, 0, sizeof( s ) );
693
694 MBEDTLS_MPI_CHK( mbedtls_mpi_write_string( X, radix, s, sizeof( s ) - 2, &n ) );
695
696 if( p == NULL ) p = "";
697
698 plen = strlen( p );
699 slen = strlen( s );
700 s[slen++] = '\r';
701 s[slen++] = '\n';
702
703 if( fout != NULL )
704 {
705 if( fwrite( p, 1, plen, fout ) != plen ||
706 fwrite( s, 1, slen, fout ) != slen )
707 return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
708 }
709 else
710 mbedtls_printf( "%s%s", p, s );
711
712cleanup:
713
714 return( ret );
715}
716#endif /* MBEDTLS_FS_IO */
717
718/*
719 * Import X from unsigned binary data, big endian
720 */
721int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
722{
723 int ret;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100724 size_t i, j;
725 size_t const limbs = CHARS_TO_LIMBS( buflen );
Jens Wiklander817466c2018-05-22 13:49:31 +0200726
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100727 MPI_VALIDATE_RET( X != NULL );
728 MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200729
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100730 /* Ensure that target MPI has exactly the necessary number of limbs */
731 if( X->n != limbs )
732 {
733 mbedtls_mpi_free( X );
734 mbedtls_mpi_init( X );
735 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
736 }
737
Jens Wiklander817466c2018-05-22 13:49:31 +0200738 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
739
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100740 for( i = buflen, j = 0; i > 0; i--, j++ )
Jens Wiklander817466c2018-05-22 13:49:31 +0200741 X->p[j / ciL] |= ((mbedtls_mpi_uint) buf[i - 1]) << ((j % ciL) << 3);
742
743cleanup:
744
745 return( ret );
746}
747
748/*
749 * Export X into unsigned binary data, big endian
750 */
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100751int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
752 unsigned char *buf, size_t buflen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200753{
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100754 size_t stored_bytes;
755 size_t bytes_to_copy;
756 unsigned char *p;
757 size_t i;
Jens Wiklander817466c2018-05-22 13:49:31 +0200758
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100759 MPI_VALIDATE_RET( X != NULL );
760 MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200761
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100762 stored_bytes = X->n * ciL;
Jens Wiklander817466c2018-05-22 13:49:31 +0200763
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100764 if( stored_bytes < buflen )
765 {
766 /* There is enough space in the output buffer. Write initial
767 * null bytes and record the position at which to start
768 * writing the significant bytes. In this case, the execution
769 * trace of this function does not depend on the value of the
770 * number. */
771 bytes_to_copy = stored_bytes;
772 p = buf + buflen - stored_bytes;
773 memset( buf, 0, buflen - stored_bytes );
774 }
775 else
776 {
777 /* The output buffer is smaller than the allocated size of X.
778 * However X may fit if its leading bytes are zero. */
779 bytes_to_copy = buflen;
780 p = buf;
781 for( i = bytes_to_copy; i < stored_bytes; i++ )
782 {
783 if( GET_BYTE( X, i ) != 0 )
784 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
785 }
786 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200787
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100788 for( i = 0; i < bytes_to_copy; i++ )
789 p[bytes_to_copy - i - 1] = GET_BYTE( X, i );
Jens Wiklander817466c2018-05-22 13:49:31 +0200790
791 return( 0 );
792}
793
794/*
795 * Left-shift: X <<= count
796 */
797int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count )
798{
799 int ret;
800 size_t i, v0, t1;
801 mbedtls_mpi_uint r0 = 0, r1;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100802 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200803
804 v0 = count / (biL );
805 t1 = count & (biL - 1);
806
807 i = mbedtls_mpi_bitlen( X ) + count;
808
809 if( X->n * biL < i )
810 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, BITS_TO_LIMBS( i ) ) );
811
812 ret = 0;
813
814 /*
815 * shift by count / limb_size
816 */
817 if( v0 > 0 )
818 {
819 for( i = X->n; i > v0; i-- )
820 X->p[i - 1] = X->p[i - v0 - 1];
821
822 for( ; i > 0; i-- )
823 X->p[i - 1] = 0;
824 }
825
826 /*
827 * shift by count % limb_size
828 */
829 if( t1 > 0 )
830 {
831 for( i = v0; i < X->n; i++ )
832 {
833 r1 = X->p[i] >> (biL - t1);
834 X->p[i] <<= t1;
835 X->p[i] |= r0;
836 r0 = r1;
837 }
838 }
839
840cleanup:
841
842 return( ret );
843}
844
845/*
846 * Right-shift: X >>= count
847 */
848int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count )
849{
850 size_t i, v0, v1;
851 mbedtls_mpi_uint r0 = 0, r1;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100852 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200853
854 v0 = count / biL;
855 v1 = count & (biL - 1);
856
857 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
858 return mbedtls_mpi_lset( X, 0 );
859
860 /*
861 * shift by count / limb_size
862 */
863 if( v0 > 0 )
864 {
865 for( i = 0; i < X->n - v0; i++ )
866 X->p[i] = X->p[i + v0];
867
868 for( ; i < X->n; i++ )
869 X->p[i] = 0;
870 }
871
872 /*
873 * shift by count % limb_size
874 */
875 if( v1 > 0 )
876 {
877 for( i = X->n; i > 0; i-- )
878 {
879 r1 = X->p[i - 1] << (biL - v1);
880 X->p[i - 1] >>= v1;
881 X->p[i - 1] |= r0;
882 r0 = r1;
883 }
884 }
885
886 return( 0 );
887}
888
889/*
890 * Compare unsigned values
891 */
892int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y )
893{
894 size_t i, j;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100895 MPI_VALIDATE_RET( X != NULL );
896 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200897
898 for( i = X->n; i > 0; i-- )
899 if( X->p[i - 1] != 0 )
900 break;
901
902 for( j = Y->n; j > 0; j-- )
903 if( Y->p[j - 1] != 0 )
904 break;
905
906 if( i == 0 && j == 0 )
907 return( 0 );
908
909 if( i > j ) return( 1 );
910 if( j > i ) return( -1 );
911
912 for( ; i > 0; i-- )
913 {
914 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
915 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
916 }
917
918 return( 0 );
919}
920
921/*
922 * Compare signed values
923 */
924int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
925{
926 size_t i, j;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100927 MPI_VALIDATE_RET( X != NULL );
928 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200929
930 for( i = X->n; i > 0; i-- )
931 if( X->p[i - 1] != 0 )
932 break;
933
934 for( j = Y->n; j > 0; j-- )
935 if( Y->p[j - 1] != 0 )
936 break;
937
938 if( i == 0 && j == 0 )
939 return( 0 );
940
941 if( i > j ) return( X->s );
942 if( j > i ) return( -Y->s );
943
944 if( X->s > 0 && Y->s < 0 ) return( 1 );
945 if( Y->s > 0 && X->s < 0 ) return( -1 );
946
947 for( ; i > 0; i-- )
948 {
949 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
950 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
951 }
952
953 return( 0 );
954}
955
956/*
957 * Compare signed values
958 */
959int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z )
960{
961 mbedtls_mpi Y;
962 mbedtls_mpi_uint p[1];
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100963 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200964
965 *p = ( z < 0 ) ? -z : z;
966 Y.s = ( z < 0 ) ? -1 : 1;
967 Y.n = 1;
968 Y.p = p;
969
970 return( mbedtls_mpi_cmp_mpi( X, &Y ) );
971}
972
973/*
974 * Unsigned addition: X = |A| + |B| (HAC 14.7)
975 */
976int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
977{
978 int ret;
979 size_t i, j;
980 mbedtls_mpi_uint *o, *p, c, tmp;
Jens Wiklander50a57cf2019-03-13 10:41:54 +0100981 MPI_VALIDATE_RET( X != NULL );
982 MPI_VALIDATE_RET( A != NULL );
983 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200984
985 if( X == B )
986 {
987 const mbedtls_mpi *T = A; A = X; B = T;
988 }
989
990 if( X != A )
991 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
992
993 /*
994 * X should always be positive as a result of unsigned additions.
995 */
996 X->s = 1;
997
998 for( j = B->n; j > 0; j-- )
999 if( B->p[j - 1] != 0 )
1000 break;
1001
1002 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
1003
1004 o = B->p; p = X->p; c = 0;
1005
1006 /*
1007 * tmp is used because it might happen that p == o
1008 */
1009 for( i = 0; i < j; i++, o++, p++ )
1010 {
1011 tmp= *o;
1012 *p += c; c = ( *p < c );
1013 *p += tmp; c += ( *p < tmp );
1014 }
1015
1016 while( c != 0 )
1017 {
1018 if( i >= X->n )
1019 {
1020 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + 1 ) );
1021 p = X->p + i;
1022 }
1023
1024 *p += c; c = ( *p < c ); i++; p++;
1025 }
1026
1027cleanup:
1028
1029 return( ret );
1030}
1031
1032/*
1033 * Helper for mbedtls_mpi subtraction
1034 */
1035static void mpi_sub_hlp( size_t n, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d )
1036{
1037 size_t i;
1038 mbedtls_mpi_uint c, z;
1039
1040 for( i = c = 0; i < n; i++, s++, d++ )
1041 {
1042 z = ( *d < c ); *d -= c;
1043 c = ( *d < *s ) + z; *d -= *s;
1044 }
1045
1046 while( c != 0 )
1047 {
1048 z = ( *d < c ); *d -= c;
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001049 c = z; d++;
Jens Wiklander817466c2018-05-22 13:49:31 +02001050 }
1051}
1052
1053/*
1054 * Unsigned subtraction: X = |A| - |B| (HAC 14.9)
1055 */
1056int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1057{
1058 mbedtls_mpi TB;
1059 int ret;
1060 size_t n;
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001061 MPI_VALIDATE_RET( X != NULL );
1062 MPI_VALIDATE_RET( A != NULL );
1063 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001064
1065 if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
1066 return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
1067
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001068 mbedtls_mpi_init( &TB );
Jens Wiklander817466c2018-05-22 13:49:31 +02001069
1070 if( X == B )
1071 {
1072 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
1073 B = &TB;
1074 }
1075
1076 if( X != A )
1077 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
1078
1079 /*
1080 * X should always be positive as a result of unsigned subtractions.
1081 */
1082 X->s = 1;
1083
1084 ret = 0;
1085
1086 for( n = B->n; n > 0; n-- )
1087 if( B->p[n - 1] != 0 )
1088 break;
1089
1090 mpi_sub_hlp( n, B->p, X->p );
1091
1092cleanup:
1093
1094 mbedtls_mpi_free( &TB );
1095
1096 return( ret );
1097}
1098
1099/*
1100 * Signed addition: X = A + B
1101 */
1102int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1103{
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001104 int ret, s;
1105 MPI_VALIDATE_RET( X != NULL );
1106 MPI_VALIDATE_RET( A != NULL );
1107 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001108
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001109 s = A->s;
Jens Wiklander817466c2018-05-22 13:49:31 +02001110 if( A->s * B->s < 0 )
1111 {
1112 if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
1113 {
1114 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
1115 X->s = s;
1116 }
1117 else
1118 {
1119 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
1120 X->s = -s;
1121 }
1122 }
1123 else
1124 {
1125 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
1126 X->s = s;
1127 }
1128
1129cleanup:
1130
1131 return( ret );
1132}
1133
1134/*
1135 * Signed subtraction: X = A - B
1136 */
1137int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1138{
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001139 int ret, s;
1140 MPI_VALIDATE_RET( X != NULL );
1141 MPI_VALIDATE_RET( A != NULL );
1142 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001143
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001144 s = A->s;
Jens Wiklander817466c2018-05-22 13:49:31 +02001145 if( A->s * B->s > 0 )
1146 {
1147 if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
1148 {
1149 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
1150 X->s = s;
1151 }
1152 else
1153 {
1154 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
1155 X->s = -s;
1156 }
1157 }
1158 else
1159 {
1160 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
1161 X->s = s;
1162 }
1163
1164cleanup:
1165
1166 return( ret );
1167}
1168
1169/*
1170 * Signed addition: X = A + b
1171 */
1172int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
1173{
1174 mbedtls_mpi _B;
1175 mbedtls_mpi_uint p[1];
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001176 MPI_VALIDATE_RET( X != NULL );
1177 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001178
1179 p[0] = ( b < 0 ) ? -b : b;
1180 _B.s = ( b < 0 ) ? -1 : 1;
1181 _B.n = 1;
1182 _B.p = p;
1183
1184 return( mbedtls_mpi_add_mpi( X, A, &_B ) );
1185}
1186
1187/*
1188 * Signed subtraction: X = A - b
1189 */
1190int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
1191{
1192 mbedtls_mpi _B;
1193 mbedtls_mpi_uint p[1];
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001194 MPI_VALIDATE_RET( X != NULL );
1195 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001196
1197 p[0] = ( b < 0 ) ? -b : b;
1198 _B.s = ( b < 0 ) ? -1 : 1;
1199 _B.n = 1;
1200 _B.p = p;
1201
1202 return( mbedtls_mpi_sub_mpi( X, A, &_B ) );
1203}
1204
1205/*
1206 * Helper for mbedtls_mpi multiplication
1207 */
1208static
1209#if defined(__APPLE__) && defined(__arm__)
1210/*
1211 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1212 * appears to need this to prevent bad ARM code generation at -O3.
1213 */
1214__attribute__ ((noinline))
1215#endif
1216void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mpi_uint b )
1217{
1218 mbedtls_mpi_uint c = 0, t = 0;
1219
1220#if defined(MULADDC_HUIT)
1221 for( ; i >= 8; i -= 8 )
1222 {
1223 MULADDC_INIT
1224 MULADDC_HUIT
1225 MULADDC_STOP
1226 }
1227
1228 for( ; i > 0; i-- )
1229 {
1230 MULADDC_INIT
1231 MULADDC_CORE
1232 MULADDC_STOP
1233 }
1234#else /* MULADDC_HUIT */
1235 for( ; i >= 16; i -= 16 )
1236 {
1237 MULADDC_INIT
1238 MULADDC_CORE MULADDC_CORE
1239 MULADDC_CORE MULADDC_CORE
1240 MULADDC_CORE MULADDC_CORE
1241 MULADDC_CORE MULADDC_CORE
1242
1243 MULADDC_CORE MULADDC_CORE
1244 MULADDC_CORE MULADDC_CORE
1245 MULADDC_CORE MULADDC_CORE
1246 MULADDC_CORE MULADDC_CORE
1247 MULADDC_STOP
1248 }
1249
1250 for( ; i >= 8; i -= 8 )
1251 {
1252 MULADDC_INIT
1253 MULADDC_CORE MULADDC_CORE
1254 MULADDC_CORE MULADDC_CORE
1255
1256 MULADDC_CORE MULADDC_CORE
1257 MULADDC_CORE MULADDC_CORE
1258 MULADDC_STOP
1259 }
1260
1261 for( ; i > 0; i-- )
1262 {
1263 MULADDC_INIT
1264 MULADDC_CORE
1265 MULADDC_STOP
1266 }
1267#endif /* MULADDC_HUIT */
1268
1269 t++;
1270
1271 do {
1272 *d += c; c = ( *d < c ); d++;
1273 }
1274 while( c != 0 );
1275}
1276
1277/*
1278 * Baseline multiplication: X = A * B (HAC 14.12)
1279 */
1280int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1281{
1282 int ret;
1283 size_t i, j;
1284 mbedtls_mpi TA, TB;
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001285 MPI_VALIDATE_RET( X != NULL );
1286 MPI_VALIDATE_RET( A != NULL );
1287 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001288
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001289 mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
Jens Wiklander817466c2018-05-22 13:49:31 +02001290
1291 if( X == A ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); A = &TA; }
1292 if( X == B ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); B = &TB; }
1293
1294 for( i = A->n; i > 0; i-- )
1295 if( A->p[i - 1] != 0 )
1296 break;
1297
1298 for( j = B->n; j > 0; j-- )
1299 if( B->p[j - 1] != 0 )
1300 break;
1301
1302 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
1303 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
1304
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001305 for( ; j > 0; j-- )
1306 mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] );
Jens Wiklander817466c2018-05-22 13:49:31 +02001307
1308 X->s = A->s * B->s;
1309
1310cleanup:
1311
1312 mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TA );
1313
1314 return( ret );
1315}
1316
1317/*
1318 * Baseline multiplication: X = A * b
1319 */
1320int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b )
1321{
1322 mbedtls_mpi _B;
1323 mbedtls_mpi_uint p[1];
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001324 MPI_VALIDATE_RET( X != NULL );
1325 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001326
1327 _B.s = 1;
1328 _B.n = 1;
1329 _B.p = p;
1330 p[0] = b;
1331
1332 return( mbedtls_mpi_mul_mpi( X, A, &_B ) );
1333}
1334
1335/*
1336 * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and
1337 * mbedtls_mpi_uint divisor, d
1338 */
1339static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1,
1340 mbedtls_mpi_uint u0, mbedtls_mpi_uint d, mbedtls_mpi_uint *r )
1341{
1342#if defined(MBEDTLS_HAVE_UDBL)
1343 mbedtls_t_udbl dividend, quotient;
1344#else
1345 const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH;
1346 const mbedtls_mpi_uint uint_halfword_mask = ( (mbedtls_mpi_uint) 1 << biH ) - 1;
1347 mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient;
1348 mbedtls_mpi_uint u0_msw, u0_lsw;
1349 size_t s;
1350#endif
1351
1352 /*
1353 * Check for overflow
1354 */
1355 if( 0 == d || u1 >= d )
1356 {
1357 if (r != NULL) *r = ~0;
1358
1359 return ( ~0 );
1360 }
1361
1362#if defined(MBEDTLS_HAVE_UDBL)
1363 dividend = (mbedtls_t_udbl) u1 << biL;
1364 dividend |= (mbedtls_t_udbl) u0;
1365 quotient = dividend / d;
1366 if( quotient > ( (mbedtls_t_udbl) 1 << biL ) - 1 )
1367 quotient = ( (mbedtls_t_udbl) 1 << biL ) - 1;
1368
1369 if( r != NULL )
1370 *r = (mbedtls_mpi_uint)( dividend - (quotient * d ) );
1371
1372 return (mbedtls_mpi_uint) quotient;
1373#else
1374
1375 /*
1376 * Algorithm D, Section 4.3.1 - The Art of Computer Programming
1377 * Vol. 2 - Seminumerical Algorithms, Knuth
1378 */
1379
1380 /*
1381 * Normalize the divisor, d, and dividend, u0, u1
1382 */
1383 s = mbedtls_clz( d );
1384 d = d << s;
1385
1386 u1 = u1 << s;
1387 u1 |= ( u0 >> ( biL - s ) ) & ( -(mbedtls_mpi_sint)s >> ( biL - 1 ) );
1388 u0 = u0 << s;
1389
1390 d1 = d >> biH;
1391 d0 = d & uint_halfword_mask;
1392
1393 u0_msw = u0 >> biH;
1394 u0_lsw = u0 & uint_halfword_mask;
1395
1396 /*
1397 * Find the first quotient and remainder
1398 */
1399 q1 = u1 / d1;
1400 r0 = u1 - d1 * q1;
1401
1402 while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) )
1403 {
1404 q1 -= 1;
1405 r0 += d1;
1406
1407 if ( r0 >= radix ) break;
1408 }
1409
1410 rAX = ( u1 * radix ) + ( u0_msw - q1 * d );
1411 q0 = rAX / d1;
1412 r0 = rAX - q0 * d1;
1413
1414 while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) )
1415 {
1416 q0 -= 1;
1417 r0 += d1;
1418
1419 if ( r0 >= radix ) break;
1420 }
1421
1422 if (r != NULL)
1423 *r = ( rAX * radix + u0_lsw - q0 * d ) >> s;
1424
1425 quotient = q1 * radix + q0;
1426
1427 return quotient;
1428#endif
1429}
1430
1431/*
1432 * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20)
1433 */
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001434int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
1435 const mbedtls_mpi *B )
Jens Wiklander817466c2018-05-22 13:49:31 +02001436{
1437 int ret;
1438 size_t i, n, t, k;
1439 mbedtls_mpi X, Y, Z, T1, T2;
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001440 MPI_VALIDATE_RET( A != NULL );
1441 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001442
1443 if( mbedtls_mpi_cmp_int( B, 0 ) == 0 )
1444 return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
1445
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001446 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
1447 mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
Jens Wiklander817466c2018-05-22 13:49:31 +02001448
1449 if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
1450 {
1451 if( Q != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_lset( Q, 0 ) );
1452 if( R != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, A ) );
1453 return( 0 );
1454 }
1455
1456 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &X, A ) );
1457 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, B ) );
1458 X.s = Y.s = 1;
1459
1460 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &Z, A->n + 2 ) );
1461 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Z, 0 ) );
1462 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, 2 ) );
1463 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T2, 3 ) );
1464
1465 k = mbedtls_mpi_bitlen( &Y ) % biL;
1466 if( k < biL - 1 )
1467 {
1468 k = biL - 1 - k;
1469 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &X, k ) );
1470 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, k ) );
1471 }
1472 else k = 0;
1473
1474 n = X.n - 1;
1475 t = Y.n - 1;
1476 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, biL * ( n - t ) ) );
1477
1478 while( mbedtls_mpi_cmp_mpi( &X, &Y ) >= 0 )
1479 {
1480 Z.p[n - t]++;
1481 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &Y ) );
1482 }
1483 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, biL * ( n - t ) ) );
1484
1485 for( i = n; i > t ; i-- )
1486 {
1487 if( X.p[i] >= Y.p[t] )
1488 Z.p[i - t - 1] = ~0;
1489 else
1490 {
1491 Z.p[i - t - 1] = mbedtls_int_div_int( X.p[i], X.p[i - 1],
1492 Y.p[t], NULL);
1493 }
1494
1495 Z.p[i - t - 1]++;
1496 do
1497 {
1498 Z.p[i - t - 1]--;
1499
1500 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T1, 0 ) );
1501 T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1];
1502 T1.p[1] = Y.p[t];
1503 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1504
1505 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T2, 0 ) );
1506 T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
1507 T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
1508 T2.p[2] = X.p[i];
1509 }
1510 while( mbedtls_mpi_cmp_mpi( &T1, &T2 ) > 0 );
1511
1512 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1513 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
1514 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) );
1515
1516 if( mbedtls_mpi_cmp_int( &X, 0 ) < 0 )
1517 {
1518 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &Y ) );
1519 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
1520 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &X, &X, &T1 ) );
1521 Z.p[i - t - 1]--;
1522 }
1523 }
1524
1525 if( Q != NULL )
1526 {
1527 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( Q, &Z ) );
1528 Q->s = A->s * B->s;
1529 }
1530
1531 if( R != NULL )
1532 {
1533 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &X, k ) );
1534 X.s = A->s;
1535 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, &X ) );
1536
1537 if( mbedtls_mpi_cmp_int( R, 0 ) == 0 )
1538 R->s = 1;
1539 }
1540
1541cleanup:
1542
1543 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
1544 mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
1545
1546 return( ret );
1547}
1548
1549/*
1550 * Division by int: A = Q * b + R
1551 */
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001552int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R,
1553 const mbedtls_mpi *A,
1554 mbedtls_mpi_sint b )
Jens Wiklander817466c2018-05-22 13:49:31 +02001555{
1556 mbedtls_mpi _B;
1557 mbedtls_mpi_uint p[1];
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001558 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001559
1560 p[0] = ( b < 0 ) ? -b : b;
1561 _B.s = ( b < 0 ) ? -1 : 1;
1562 _B.n = 1;
1563 _B.p = p;
1564
1565 return( mbedtls_mpi_div_mpi( Q, R, A, &_B ) );
1566}
1567
1568/*
1569 * Modulo: R = A mod B
1570 */
1571int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
1572{
1573 int ret;
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001574 MPI_VALIDATE_RET( R != NULL );
1575 MPI_VALIDATE_RET( A != NULL );
1576 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001577
1578 if( mbedtls_mpi_cmp_int( B, 0 ) < 0 )
1579 return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
1580
1581 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( NULL, R, A, B ) );
1582
1583 while( mbedtls_mpi_cmp_int( R, 0 ) < 0 )
1584 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) );
1585
1586 while( mbedtls_mpi_cmp_mpi( R, B ) >= 0 )
1587 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) );
1588
1589cleanup:
1590
1591 return( ret );
1592}
1593
1594/*
1595 * Modulo: r = A mod b
1596 */
1597int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b )
1598{
1599 size_t i;
1600 mbedtls_mpi_uint x, y, z;
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001601 MPI_VALIDATE_RET( r != NULL );
1602 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001603
1604 if( b == 0 )
1605 return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
1606
1607 if( b < 0 )
1608 return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
1609
1610 /*
1611 * handle trivial cases
1612 */
1613 if( b == 1 )
1614 {
1615 *r = 0;
1616 return( 0 );
1617 }
1618
1619 if( b == 2 )
1620 {
1621 *r = A->p[0] & 1;
1622 return( 0 );
1623 }
1624
1625 /*
1626 * general case
1627 */
1628 for( i = A->n, y = 0; i > 0; i-- )
1629 {
1630 x = A->p[i - 1];
1631 y = ( y << biH ) | ( x >> biH );
1632 z = y / b;
1633 y -= z * b;
1634
1635 x <<= biH;
1636 y = ( y << biH ) | ( x >> biH );
1637 z = y / b;
1638 y -= z * b;
1639 }
1640
1641 /*
1642 * If A is negative, then the current y represents a negative value.
1643 * Flipping it to the positive side.
1644 */
1645 if( A->s < 0 && y != 0 )
1646 y = b - y;
1647
1648 *r = y;
1649
1650 return( 0 );
1651}
1652
1653/*
1654 * Fast Montgomery initialization (thanks to Tom St Denis)
1655 */
Jens Wiklanderdf0f4882018-11-07 08:11:29 +01001656void mbedtls_mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
Jens Wiklander817466c2018-05-22 13:49:31 +02001657{
1658 mbedtls_mpi_uint x, m0 = N->p[0];
1659 unsigned int i;
1660
1661 x = m0;
1662 x += ( ( m0 + 2 ) & 4 ) << 1;
1663
1664 for( i = biL; i >= 8; i /= 2 )
1665 x *= ( 2 - ( m0 * x ) );
1666
1667 *mm = ~x + 1;
1668}
1669
1670/*
1671 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1672 */
Jens Wiklanderdf0f4882018-11-07 08:11:29 +01001673int mbedtls_mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B,
1674 const mbedtls_mpi *N, mbedtls_mpi_uint mm,
Jens Wiklander817466c2018-05-22 13:49:31 +02001675 const mbedtls_mpi *T )
1676{
1677 size_t i, n, m;
1678 mbedtls_mpi_uint u0, u1, *d;
1679
1680 if( T->n < N->n + 1 || T->p == NULL )
1681 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
1682
1683 memset( T->p, 0, T->n * ciL );
1684
1685 d = T->p;
1686 n = N->n;
1687 m = ( B->n < n ) ? B->n : n;
1688
1689 for( i = 0; i < n; i++ )
1690 {
1691 /*
1692 * T = (T + u0*B + u1*N) / 2^biL
1693 */
1694 u0 = A->p[i];
1695 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1696
1697 mpi_mul_hlp( m, B->p, d, u0 );
1698 mpi_mul_hlp( n, N->p, d, u1 );
1699
1700 *d++ = u0; d[n + 1] = 0;
1701 }
1702
1703 memcpy( A->p, d, ( n + 1 ) * ciL );
1704
1705 if( mbedtls_mpi_cmp_abs( A, N ) >= 0 )
1706 mpi_sub_hlp( n, N->p, A->p );
1707 else
1708 /* prevent timing attacks */
1709 mpi_sub_hlp( n, A->p, T->p );
1710
1711 return( 0 );
1712}
1713
1714/*
1715 * Montgomery reduction: A = A * R^-1 mod N
1716 */
Jens Wiklanderdf0f4882018-11-07 08:11:29 +01001717int mbedtls_mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
1718 mbedtls_mpi_uint mm, const mbedtls_mpi *T )
Jens Wiklander817466c2018-05-22 13:49:31 +02001719{
1720 mbedtls_mpi_uint z = 1;
1721 mbedtls_mpi U;
1722
1723 U.n = U.s = (int) z;
1724 U.p = &z;
1725
Jens Wiklanderdf0f4882018-11-07 08:11:29 +01001726 return( mbedtls_mpi_montmul( A, &U, N, mm, T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001727}
1728
1729/*
1730 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1731 */
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001732int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
1733 const mbedtls_mpi *E, const mbedtls_mpi *N,
1734 mbedtls_mpi *_RR )
Jens Wiklander817466c2018-05-22 13:49:31 +02001735{
1736 int ret;
1737 size_t wbits, wsize, one = 1;
1738 size_t i, j, nblimbs;
1739 size_t bufsize, nbits;
1740 mbedtls_mpi_uint ei, mm, state;
1741 mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
1742 int neg;
1743
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001744 MPI_VALIDATE_RET( X != NULL );
1745 MPI_VALIDATE_RET( A != NULL );
1746 MPI_VALIDATE_RET( E != NULL );
1747 MPI_VALIDATE_RET( N != NULL );
1748
1749 if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02001750 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
1751
1752 if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
1753 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
1754
1755 /*
1756 * Init temps and window size
1757 */
Jens Wiklanderdf0f4882018-11-07 08:11:29 +01001758 mbedtls_mpi_montg_init( &mm, N );
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001759 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T );
1760 mbedtls_mpi_init( &Apos );
Jens Wiklander817466c2018-05-22 13:49:31 +02001761 memset( W, 0, sizeof( W ) );
1762
1763 i = mbedtls_mpi_bitlen( E );
1764
1765 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1766 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1767
1768 if( wsize > MBEDTLS_MPI_WINDOW_SIZE )
1769 wsize = MBEDTLS_MPI_WINDOW_SIZE;
1770
1771 j = N->n + 1;
1772 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
1773 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) );
1774 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
1775
1776 /*
1777 * Compensate for negative A (and correct at the end)
1778 */
1779 neg = ( A->s == -1 );
1780 if( neg )
1781 {
1782 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Apos, A ) );
1783 Apos.s = 1;
1784 A = &Apos;
1785 }
1786
1787 /*
1788 * If 1st call, pre-compute R^2 mod N
1789 */
1790 if( _RR == NULL || _RR->p == NULL )
1791 {
1792 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &RR, 1 ) );
1793 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &RR, N->n * 2 * biL ) );
1794 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) );
1795
1796 if( _RR != NULL )
1797 memcpy( _RR, &RR, sizeof( mbedtls_mpi ) );
1798 }
1799 else
1800 memcpy( &RR, _RR, sizeof( mbedtls_mpi ) );
1801
1802 /*
1803 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1804 */
1805 if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 )
1806 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
1807 else
1808 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
1809
Jens Wiklanderdf0f4882018-11-07 08:11:29 +01001810 MBEDTLS_MPI_CHK( mbedtls_mpi_montmul( &W[1], &RR, N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001811
1812 /*
1813 * X = R^2 * R^-1 mod N = R mod N
1814 */
1815 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) );
Jens Wiklanderdf0f4882018-11-07 08:11:29 +01001816 MBEDTLS_MPI_CHK( mbedtls_mpi_montred( X, N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001817
1818 if( wsize > 1 )
1819 {
1820 /*
1821 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1822 */
1823 j = one << ( wsize - 1 );
1824
1825 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) );
1826 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) );
1827
1828 for( i = 0; i < wsize - 1; i++ )
Jens Wiklanderdf0f4882018-11-07 08:11:29 +01001829 MBEDTLS_MPI_CHK( mbedtls_mpi_montmul( &W[j], &W[j], N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001830
1831 /*
1832 * W[i] = W[i - 1] * W[1]
1833 */
1834 for( i = j + 1; i < ( one << wsize ); i++ )
1835 {
1836 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) );
1837 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) );
1838
Jens Wiklanderdf0f4882018-11-07 08:11:29 +01001839 MBEDTLS_MPI_CHK( mbedtls_mpi_montmul( &W[i], &W[1], N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001840 }
1841 }
1842
1843 nblimbs = E->n;
1844 bufsize = 0;
1845 nbits = 0;
1846 wbits = 0;
1847 state = 0;
1848
1849 while( 1 )
1850 {
1851 if( bufsize == 0 )
1852 {
1853 if( nblimbs == 0 )
1854 break;
1855
1856 nblimbs--;
1857
1858 bufsize = sizeof( mbedtls_mpi_uint ) << 3;
1859 }
1860
1861 bufsize--;
1862
1863 ei = (E->p[nblimbs] >> bufsize) & 1;
1864
1865 /*
1866 * skip leading 0s
1867 */
1868 if( ei == 0 && state == 0 )
1869 continue;
1870
1871 if( ei == 0 && state == 1 )
1872 {
1873 /*
1874 * out of window, square X
1875 */
Jens Wiklanderdf0f4882018-11-07 08:11:29 +01001876 MBEDTLS_MPI_CHK( mbedtls_mpi_montmul( X, X, N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001877 continue;
1878 }
1879
1880 /*
1881 * add ei to current window
1882 */
1883 state = 2;
1884
1885 nbits++;
1886 wbits |= ( ei << ( wsize - nbits ) );
1887
1888 if( nbits == wsize )
1889 {
1890 /*
1891 * X = X^wsize R^-1 mod N
1892 */
1893 for( i = 0; i < wsize; i++ )
Jens Wiklanderdf0f4882018-11-07 08:11:29 +01001894 MBEDTLS_MPI_CHK( mbedtls_mpi_montmul( X, X, N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001895
1896 /*
1897 * X = X * W[wbits] R^-1 mod N
1898 */
Jens Wiklanderdf0f4882018-11-07 08:11:29 +01001899 MBEDTLS_MPI_CHK( mbedtls_mpi_montmul( X, &W[wbits], N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001900
1901 state--;
1902 nbits = 0;
1903 wbits = 0;
1904 }
1905 }
1906
1907 /*
1908 * process the remaining bits
1909 */
1910 for( i = 0; i < nbits; i++ )
1911 {
Jens Wiklanderdf0f4882018-11-07 08:11:29 +01001912 MBEDTLS_MPI_CHK( mbedtls_mpi_montmul( X, X, N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001913
1914 wbits <<= 1;
1915
1916 if( ( wbits & ( one << wsize ) ) != 0 )
Jens Wiklanderdf0f4882018-11-07 08:11:29 +01001917 MBEDTLS_MPI_CHK( mbedtls_mpi_montmul( X, &W[1], N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001918 }
1919
1920 /*
1921 * X = A^E * R * R^-1 mod N = A^E mod N
1922 */
Jens Wiklanderdf0f4882018-11-07 08:11:29 +01001923 MBEDTLS_MPI_CHK( mbedtls_mpi_montred( X, N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001924
1925 if( neg && E->n != 0 && ( E->p[0] & 1 ) != 0 )
1926 {
1927 X->s = -1;
1928 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) );
1929 }
1930
1931cleanup:
1932
1933 for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
1934 mbedtls_mpi_free( &W[i] );
1935
1936 mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
1937
1938 if( _RR == NULL || _RR->p == NULL )
1939 mbedtls_mpi_free( &RR );
1940
1941 return( ret );
1942}
1943
1944/*
1945 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1946 */
1947int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B )
1948{
1949 int ret;
1950 size_t lz, lzt;
1951 mbedtls_mpi TG, TA, TB;
1952
Jens Wiklander50a57cf2019-03-13 10:41:54 +01001953 MPI_VALIDATE_RET( G != NULL );
1954 MPI_VALIDATE_RET( A != NULL );
1955 MPI_VALIDATE_RET( B != NULL );
1956
1957 mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
Jens Wiklander817466c2018-05-22 13:49:31 +02001958
1959 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) );
1960 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
1961
1962 lz = mbedtls_mpi_lsb( &TA );
1963 lzt = mbedtls_mpi_lsb( &TB );
1964
1965 if( lzt < lz )
1966 lz = lzt;
1967
1968 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, lz ) );
1969 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, lz ) );
1970
1971 TA.s = TB.s = 1;
1972
1973 while( mbedtls_mpi_cmp_int( &TA, 0 ) != 0 )
1974 {
1975 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, mbedtls_mpi_lsb( &TA ) ) );
1976 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, mbedtls_mpi_lsb( &TB ) ) );
1977
1978 if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 )
1979 {
1980 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TA, &TA, &TB ) );
1981 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, 1 ) );
1982 }
1983 else
1984 {
1985 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TB, &TB, &TA ) );
1986 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, 1 ) );
1987 }
1988 }
1989
1990 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &TB, lz ) );
1991 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( G, &TB ) );
1992
1993cleanup:
1994
1995 mbedtls_mpi_free( &TG ); mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB );
1996
1997 return( ret );
1998}
1999
2000/*
2001 * Fill X with size bytes of random.
2002 *
2003 * Use a temporary bytes representation to make sure the result is the same
2004 * regardless of the platform endianness (useful when f_rng is actually
2005 * deterministic, eg for tests).
2006 */
2007int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
2008 int (*f_rng)(void *, unsigned char *, size_t),
2009 void *p_rng )
2010{
2011 int ret;
2012 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002013 MPI_VALIDATE_RET( X != NULL );
2014 MPI_VALIDATE_RET( f_rng != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002015
2016 if( size > MBEDTLS_MPI_MAX_SIZE )
2017 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2018
2019 MBEDTLS_MPI_CHK( f_rng( p_rng, buf, size ) );
2020 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, buf, size ) );
2021
2022cleanup:
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002023 mbedtls_platform_zeroize( buf, sizeof( buf ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002024 return( ret );
2025}
2026
2027/*
2028 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
2029 */
2030int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N )
2031{
2032 int ret;
2033 mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002034 MPI_VALIDATE_RET( X != NULL );
2035 MPI_VALIDATE_RET( A != NULL );
2036 MPI_VALIDATE_RET( N != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002037
2038 if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 )
2039 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2040
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002041 mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TU ); mbedtls_mpi_init( &U1 ); mbedtls_mpi_init( &U2 );
2042 mbedtls_mpi_init( &G ); mbedtls_mpi_init( &TB ); mbedtls_mpi_init( &TV );
2043 mbedtls_mpi_init( &V1 ); mbedtls_mpi_init( &V2 );
Jens Wiklander817466c2018-05-22 13:49:31 +02002044
2045 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, A, N ) );
2046
2047 if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
2048 {
2049 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2050 goto cleanup;
2051 }
2052
2053 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &TA, A, N ) );
2054 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TU, &TA ) );
2055 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, N ) );
2056 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TV, N ) );
2057
2058 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U1, 1 ) );
2059 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U2, 0 ) );
2060 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V1, 0 ) );
2061 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V2, 1 ) );
2062
2063 do
2064 {
2065 while( ( TU.p[0] & 1 ) == 0 )
2066 {
2067 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TU, 1 ) );
2068
2069 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
2070 {
2071 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &U1, &U1, &TB ) );
2072 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &TA ) );
2073 }
2074
2075 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U1, 1 ) );
2076 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U2, 1 ) );
2077 }
2078
2079 while( ( TV.p[0] & 1 ) == 0 )
2080 {
2081 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TV, 1 ) );
2082
2083 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
2084 {
2085 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, &TB ) );
2086 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &TA ) );
2087 }
2088
2089 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V1, 1 ) );
2090 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V2, 1 ) );
2091 }
2092
2093 if( mbedtls_mpi_cmp_mpi( &TU, &TV ) >= 0 )
2094 {
2095 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TU, &TU, &TV ) );
2096 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U1, &U1, &V1 ) );
2097 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &V2 ) );
2098 }
2099 else
2100 {
2101 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TV, &TV, &TU ) );
2102 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, &U1 ) );
2103 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &U2 ) );
2104 }
2105 }
2106 while( mbedtls_mpi_cmp_int( &TU, 0 ) != 0 );
2107
2108 while( mbedtls_mpi_cmp_int( &V1, 0 ) < 0 )
2109 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, N ) );
2110
2111 while( mbedtls_mpi_cmp_mpi( &V1, N ) >= 0 )
2112 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, N ) );
2113
2114 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &V1 ) );
2115
2116cleanup:
2117
2118 mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TU ); mbedtls_mpi_free( &U1 ); mbedtls_mpi_free( &U2 );
2119 mbedtls_mpi_free( &G ); mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TV );
2120 mbedtls_mpi_free( &V1 ); mbedtls_mpi_free( &V2 );
2121
2122 return( ret );
2123}
2124
2125#if defined(MBEDTLS_GENPRIME)
2126
2127static const int small_prime[] =
2128{
2129 3, 5, 7, 11, 13, 17, 19, 23,
2130 29, 31, 37, 41, 43, 47, 53, 59,
2131 61, 67, 71, 73, 79, 83, 89, 97,
2132 101, 103, 107, 109, 113, 127, 131, 137,
2133 139, 149, 151, 157, 163, 167, 173, 179,
2134 181, 191, 193, 197, 199, 211, 223, 227,
2135 229, 233, 239, 241, 251, 257, 263, 269,
2136 271, 277, 281, 283, 293, 307, 311, 313,
2137 317, 331, 337, 347, 349, 353, 359, 367,
2138 373, 379, 383, 389, 397, 401, 409, 419,
2139 421, 431, 433, 439, 443, 449, 457, 461,
2140 463, 467, 479, 487, 491, 499, 503, 509,
2141 521, 523, 541, 547, 557, 563, 569, 571,
2142 577, 587, 593, 599, 601, 607, 613, 617,
2143 619, 631, 641, 643, 647, 653, 659, 661,
2144 673, 677, 683, 691, 701, 709, 719, 727,
2145 733, 739, 743, 751, 757, 761, 769, 773,
2146 787, 797, 809, 811, 821, 823, 827, 829,
2147 839, 853, 857, 859, 863, 877, 881, 883,
2148 887, 907, 911, 919, 929, 937, 941, 947,
2149 953, 967, 971, 977, 983, 991, 997, -103
2150};
2151
2152/*
2153 * Small divisors test (X must be positive)
2154 *
2155 * Return values:
2156 * 0: no small factor (possible prime, more tests needed)
2157 * 1: certain prime
2158 * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
2159 * other negative: error
2160 */
2161static int mpi_check_small_factors( const mbedtls_mpi *X )
2162{
2163 int ret = 0;
2164 size_t i;
2165 mbedtls_mpi_uint r;
2166
2167 if( ( X->p[0] & 1 ) == 0 )
2168 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
2169
2170 for( i = 0; small_prime[i] > 0; i++ )
2171 {
2172 if( mbedtls_mpi_cmp_int( X, small_prime[i] ) <= 0 )
2173 return( 1 );
2174
2175 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, small_prime[i] ) );
2176
2177 if( r == 0 )
2178 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
2179 }
2180
2181cleanup:
2182 return( ret );
2183}
2184
2185/*
2186 * Miller-Rabin pseudo-primality test (HAC 4.24)
2187 */
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002188static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds,
Jens Wiklander817466c2018-05-22 13:49:31 +02002189 int (*f_rng)(void *, unsigned char *, size_t),
2190 void *p_rng )
2191{
2192 int ret, count;
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002193 size_t i, j, k, s;
Jens Wiklander817466c2018-05-22 13:49:31 +02002194 mbedtls_mpi W, R, T, A, RR;
2195
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002196 MPI_VALIDATE_RET( X != NULL );
2197 MPI_VALIDATE_RET( f_rng != NULL );
2198
2199 mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R );
2200 mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A );
2201 mbedtls_mpi_init( &RR );
Jens Wiklander817466c2018-05-22 13:49:31 +02002202
2203 /*
2204 * W = |X| - 1
2205 * R = W >> lsb( W )
2206 */
2207 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &W, X, 1 ) );
2208 s = mbedtls_mpi_lsb( &W );
2209 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R, &W ) );
2210 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) );
2211
2212 i = mbedtls_mpi_bitlen( X );
Jens Wiklander817466c2018-05-22 13:49:31 +02002213
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002214 for( i = 0; i < rounds; i++ )
Jens Wiklander817466c2018-05-22 13:49:31 +02002215 {
2216 /*
2217 * pick a random A, 1 < A < |X| - 1
2218 */
Jens Wiklander817466c2018-05-22 13:49:31 +02002219 count = 0;
2220 do {
2221 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
2222
2223 j = mbedtls_mpi_bitlen( &A );
2224 k = mbedtls_mpi_bitlen( &W );
2225 if (j > k) {
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002226 A.p[A.n - 1] &= ( (mbedtls_mpi_uint) 1 << ( k - ( A.n - 1 ) * biL - 1 ) ) - 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02002227 }
2228
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002229 if (count++ > 30) {
2230 return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
Jens Wiklander817466c2018-05-22 13:49:31 +02002231 }
2232
2233 } while ( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 ||
2234 mbedtls_mpi_cmp_int( &A, 1 ) <= 0 );
2235
2236 /*
2237 * A = A^R mod |X|
2238 */
2239 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &A, &A, &R, X, &RR ) );
2240
2241 if( mbedtls_mpi_cmp_mpi( &A, &W ) == 0 ||
2242 mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
2243 continue;
2244
2245 j = 1;
2246 while( j < s && mbedtls_mpi_cmp_mpi( &A, &W ) != 0 )
2247 {
2248 /*
2249 * A = A * A mod |X|
2250 */
2251 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &A, &A ) );
2252 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &A, &T, X ) );
2253
2254 if( mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
2255 break;
2256
2257 j++;
2258 }
2259
2260 /*
2261 * not prime if A != |X| - 1 or A == 1
2262 */
2263 if( mbedtls_mpi_cmp_mpi( &A, &W ) != 0 ||
2264 mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
2265 {
2266 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2267 break;
2268 }
2269 }
2270
2271cleanup:
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002272 mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R );
2273 mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A );
Jens Wiklander817466c2018-05-22 13:49:31 +02002274 mbedtls_mpi_free( &RR );
2275
2276 return( ret );
2277}
2278
2279/*
2280 * Pseudo-primality test: small factors, then Miller-Rabin
2281 */
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002282int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds,
2283 int (*f_rng)(void *, unsigned char *, size_t),
2284 void *p_rng )
Jens Wiklander817466c2018-05-22 13:49:31 +02002285{
2286 int ret;
2287 mbedtls_mpi XX;
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002288 MPI_VALIDATE_RET( X != NULL );
2289 MPI_VALIDATE_RET( f_rng != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002290
2291 XX.s = 1;
2292 XX.n = X->n;
2293 XX.p = X->p;
2294
2295 if( mbedtls_mpi_cmp_int( &XX, 0 ) == 0 ||
2296 mbedtls_mpi_cmp_int( &XX, 1 ) == 0 )
2297 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
2298
2299 if( mbedtls_mpi_cmp_int( &XX, 2 ) == 0 )
2300 return( 0 );
2301
2302 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2303 {
2304 if( ret == 1 )
2305 return( 0 );
2306
2307 return( ret );
2308 }
2309
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002310 return( mpi_miller_rabin( &XX, rounds, f_rng, p_rng ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002311}
2312
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002313#if !defined(MBEDTLS_DEPRECATED_REMOVED)
2314/*
2315 * Pseudo-primality test, error probability 2^-80
2316 */
2317int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
2318 int (*f_rng)(void *, unsigned char *, size_t),
2319 void *p_rng )
2320{
2321 MPI_VALIDATE_RET( X != NULL );
2322 MPI_VALIDATE_RET( f_rng != NULL );
2323
2324 /*
2325 * In the past our key generation aimed for an error rate of at most
2326 * 2^-80. Since this function is deprecated, aim for the same certainty
2327 * here as well.
2328 */
2329 return( mbedtls_mpi_is_prime_ext( X, 40, f_rng, p_rng ) );
2330}
2331#endif
2332
Jens Wiklander817466c2018-05-22 13:49:31 +02002333/*
2334 * Prime number generation
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002335 *
2336 * To generate an RSA key in a way recommended by FIPS 186-4, both primes must
2337 * be either 1024 bits or 1536 bits long, and flags must contain
2338 * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR.
Jens Wiklander817466c2018-05-22 13:49:31 +02002339 */
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002340int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags,
Jens Wiklander817466c2018-05-22 13:49:31 +02002341 int (*f_rng)(void *, unsigned char *, size_t),
2342 void *p_rng )
2343{
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002344#ifdef MBEDTLS_HAVE_INT64
2345// ceil(2^63.5)
2346#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL
2347#else
2348// ceil(2^31.5)
2349#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U
2350#endif
2351 int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
Jens Wiklander817466c2018-05-22 13:49:31 +02002352 size_t k, n;
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002353 int rounds;
Jens Wiklander817466c2018-05-22 13:49:31 +02002354 mbedtls_mpi_uint r;
2355 mbedtls_mpi Y;
2356
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002357 MPI_VALIDATE_RET( X != NULL );
2358 MPI_VALIDATE_RET( f_rng != NULL );
2359
Jens Wiklander817466c2018-05-22 13:49:31 +02002360 if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS )
2361 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2362
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002363 mbedtls_mpi_init( &Y );
Jens Wiklander817466c2018-05-22 13:49:31 +02002364
2365 n = BITS_TO_LIMBS( nbits );
2366
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002367 if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR ) == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02002368 {
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002369 /*
2370 * 2^-80 error probability, number of rounds chosen per HAC, table 4.4
2371 */
2372 rounds = ( ( nbits >= 1300 ) ? 2 : ( nbits >= 850 ) ? 3 :
2373 ( nbits >= 650 ) ? 4 : ( nbits >= 350 ) ? 8 :
2374 ( nbits >= 250 ) ? 12 : ( nbits >= 150 ) ? 18 : 27 );
Jens Wiklander817466c2018-05-22 13:49:31 +02002375 }
2376 else
2377 {
2378 /*
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002379 * 2^-100 error probability, number of rounds computed based on HAC,
2380 * fact 4.48
Jens Wiklander817466c2018-05-22 13:49:31 +02002381 */
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002382 rounds = ( ( nbits >= 1450 ) ? 4 : ( nbits >= 1150 ) ? 5 :
2383 ( nbits >= 1000 ) ? 6 : ( nbits >= 850 ) ? 7 :
2384 ( nbits >= 750 ) ? 8 : ( nbits >= 500 ) ? 13 :
2385 ( nbits >= 250 ) ? 28 : ( nbits >= 150 ) ? 40 : 51 );
2386 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002387
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002388 while( 1 )
2389 {
2390 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
2391 /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */
2392 if( X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2 ) continue;
Jens Wiklander817466c2018-05-22 13:49:31 +02002393
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002394 k = n * biL;
2395 if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits ) );
2396 X->p[0] |= 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02002397
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002398 if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH ) == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02002399 {
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002400 ret = mbedtls_mpi_is_prime_ext( X, rounds, f_rng, p_rng );
Jens Wiklander817466c2018-05-22 13:49:31 +02002401
2402 if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
2403 goto cleanup;
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002404 }
2405 else
2406 {
Jens Wiklander817466c2018-05-22 13:49:31 +02002407 /*
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002408 * An necessary condition for Y and X = 2Y + 1 to be prime
2409 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2410 * Make sure it is satisfied, while keeping X = 3 mod 4
Jens Wiklander817466c2018-05-22 13:49:31 +02002411 */
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002412
2413 X->p[0] |= 2;
2414
2415 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) );
2416 if( r == 0 )
2417 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) );
2418 else if( r == 1 )
2419 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) );
2420
2421 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2422 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) );
2423 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) );
2424
2425 while( 1 )
2426 {
2427 /*
2428 * First, check small factors for X and Y
2429 * before doing Miller-Rabin on any of them
2430 */
2431 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2432 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2433 ( ret = mpi_miller_rabin( X, rounds, f_rng, p_rng ) )
2434 == 0 &&
2435 ( ret = mpi_miller_rabin( &Y, rounds, f_rng, p_rng ) )
2436 == 0 )
2437 goto cleanup;
2438
2439 if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
2440 goto cleanup;
2441
2442 /*
2443 * Next candidates. We want to preserve Y = (X-1) / 2 and
2444 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2445 * so up Y by 6 and X by 12.
2446 */
2447 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 12 ) );
2448 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) );
2449 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002450 }
2451 }
2452
2453cleanup:
2454
2455 mbedtls_mpi_free( &Y );
2456
2457 return( ret );
2458}
2459
2460#endif /* MBEDTLS_GENPRIME */
2461
2462#if defined(MBEDTLS_SELF_TEST)
2463
2464#define GCD_PAIR_COUNT 3
2465
2466static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2467{
2468 { 693, 609, 21 },
2469 { 1764, 868, 28 },
2470 { 768454923, 542167814, 1 }
2471};
2472
2473/*
2474 * Checkup routine
2475 */
2476int mbedtls_mpi_self_test( int verbose )
2477{
2478 int ret, i;
2479 mbedtls_mpi A, E, N, X, Y, U, V;
2480
Jens Wiklander50a57cf2019-03-13 10:41:54 +01002481 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N ); mbedtls_mpi_init( &X );
2482 mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &U ); mbedtls_mpi_init( &V );
Jens Wiklander817466c2018-05-22 13:49:31 +02002483
2484 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &A, 16,
2485 "EFE021C2645FD1DC586E69184AF4A31E" \
2486 "D5F53E93B5F123FA41680867BA110131" \
2487 "944FE7952E2517337780CB0DB80E61AA" \
2488 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2489
2490 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &E, 16,
2491 "B2E7EFD37075B9F03FF989C7C5051C20" \
2492 "34D2A323810251127E7BF8625A4F49A5" \
2493 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2494 "5B5C25763222FEFCCFC38B832366C29E" ) );
2495
2496 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &N, 16,
2497 "0066A198186C18C10B2F5ED9B522752A" \
2498 "9830B69916E535C8F047518A889A43A5" \
2499 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2500
2501 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &A, &N ) );
2502
2503 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
2504 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2505 "9E857EA95A03512E2BAE7391688D264A" \
2506 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2507 "8001B72E848A38CAE1C65F78E56ABDEF" \
2508 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2509 "ECF677152EF804370C1A305CAF3B5BF1" \
2510 "30879B56C61DE584A0F53A2447A51E" ) );
2511
2512 if( verbose != 0 )
2513 mbedtls_printf( " MPI test #1 (mul_mpi): " );
2514
2515 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
2516 {
2517 if( verbose != 0 )
2518 mbedtls_printf( "failed\n" );
2519
2520 ret = 1;
2521 goto cleanup;
2522 }
2523
2524 if( verbose != 0 )
2525 mbedtls_printf( "passed\n" );
2526
2527 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &X, &Y, &A, &N ) );
2528
2529 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
2530 "256567336059E52CAE22925474705F39A94" ) );
2531
2532 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &V, 16,
2533 "6613F26162223DF488E9CD48CC132C7A" \
2534 "0AC93C701B001B092E4E5B9F73BCD27B" \
2535 "9EE50D0657C77F374E903CDFA4C642" ) );
2536
2537 if( verbose != 0 )
2538 mbedtls_printf( " MPI test #2 (div_mpi): " );
2539
2540 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ||
2541 mbedtls_mpi_cmp_mpi( &Y, &V ) != 0 )
2542 {
2543 if( verbose != 0 )
2544 mbedtls_printf( "failed\n" );
2545
2546 ret = 1;
2547 goto cleanup;
2548 }
2549
2550 if( verbose != 0 )
2551 mbedtls_printf( "passed\n" );
2552
2553 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2554
2555 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
2556 "36E139AEA55215609D2816998ED020BB" \
2557 "BD96C37890F65171D948E9BC7CBAA4D9" \
2558 "325D24D6A3C12710F10A09FA08AB87" ) );
2559
2560 if( verbose != 0 )
2561 mbedtls_printf( " MPI test #3 (exp_mod): " );
2562
2563 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
2564 {
2565 if( verbose != 0 )
2566 mbedtls_printf( "failed\n" );
2567
2568 ret = 1;
2569 goto cleanup;
2570 }
2571
2572 if( verbose != 0 )
2573 mbedtls_printf( "passed\n" );
2574
2575 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &X, &A, &N ) );
2576
2577 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
2578 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2579 "C3DBA76456363A10869622EAC2DD84EC" \
2580 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2581
2582 if( verbose != 0 )
2583 mbedtls_printf( " MPI test #4 (inv_mod): " );
2584
2585 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
2586 {
2587 if( verbose != 0 )
2588 mbedtls_printf( "failed\n" );
2589
2590 ret = 1;
2591 goto cleanup;
2592 }
2593
2594 if( verbose != 0 )
2595 mbedtls_printf( "passed\n" );
2596
2597 if( verbose != 0 )
2598 mbedtls_printf( " MPI test #5 (simple gcd): " );
2599
2600 for( i = 0; i < GCD_PAIR_COUNT; i++ )
2601 {
2602 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &X, gcd_pairs[i][0] ) );
2603 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Y, gcd_pairs[i][1] ) );
2604
2605 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &A, &X, &Y ) );
2606
2607 if( mbedtls_mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2608 {
2609 if( verbose != 0 )
2610 mbedtls_printf( "failed at %d\n", i );
2611
2612 ret = 1;
2613 goto cleanup;
2614 }
2615 }
2616
2617 if( verbose != 0 )
2618 mbedtls_printf( "passed\n" );
2619
2620cleanup:
2621
2622 if( ret != 0 && verbose != 0 )
2623 mbedtls_printf( "Unexpected error, return code = %08X\n", ret );
2624
2625 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N ); mbedtls_mpi_free( &X );
2626 mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &U ); mbedtls_mpi_free( &V );
2627
2628 if( verbose != 0 )
2629 mbedtls_printf( "\n" );
2630
2631 return( ret );
2632}
2633
2634#endif /* MBEDTLS_SELF_TEST */
2635
2636#endif /* MBEDTLS_BIGNUM_C */