blob: 87ccf42fad9a97b58c83843a92ff55d703ed15e7 [file] [log] [blame]
Jens Wiklander817466c2018-05-22 13:49:31 +02001/*
2 * Multi-precision integer library
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
Jerome Forissier84f74672020-03-30 17:42:28 +02005 * SPDX-License-Identifier: Apache-2.0
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 Wiklander3d3b0592019-03-20 15:30:29 +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 Wiklander3d3b0592019-03-20 15:30:29 +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 Wiklander3d3b0592019-03-20 15:30:29 +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}
85
Jens Wiklander817466c2018-05-22 13:49:31 +020086/*
87 * Initialize one MPI
88 */
Jerome Forissier84f74672020-03-30 17:42:28 +020089void mbedtls_mpi_init( mbedtls_mpi *X )
Jens Wiklander817466c2018-05-22 13:49:31 +020090{
Jens Wiklander3d3b0592019-03-20 15:30:29 +010091 MPI_VALIDATE( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +020092
Jens Wiklander3d3b0592019-03-20 15:30:29 +010093 X->s = 1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +010094 X->n = 0;
95 X->p = NULL;
Jens Wiklander817466c2018-05-22 13:49:31 +020096}
97
98/*
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 );
Jerome Forissier84f74672020-03-30 17:42:28 +0200109 mbedtls_free( X->p );
Jens Wiklander817466c2018-05-22 13:49:31 +0200110 }
111
112 X->s = 1;
113 X->n = 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +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 Wiklander3d3b0592019-03-20 15:30:29 +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 Wiklander3d3b0592019-03-20 15:30:29 +0100128 if( X->n < nblimbs )
129 {
Jerome Forissier84f74672020-03-30 17:42:28 +0200130 if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL )
131 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
Jens Wiklander817466c2018-05-22 13:49:31 +0200132
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100133 if( X->p != NULL )
134 {
135 memcpy( p, X->p, X->n * ciL );
136 mbedtls_mpi_zeroize( X->p, X->n );
Jerome Forissier84f74672020-03-30 17:42:28 +0200137 mbedtls_free( X->p );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100138 }
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 Wiklander3d3b0592019-03-20 15:30:29 +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
Jerome Forissier84f74672020-03-30 17:42:28 +0200160 /* Actually resize up if there are currently fewer than nblimbs limbs. */
Jens Wiklander817466c2018-05-22 13:49:31 +0200161 if( X->n <= nblimbs )
162 return( mbedtls_mpi_grow( X, nblimbs ) );
Jerome Forissier84f74672020-03-30 17:42:28 +0200163 /* After this point, then X->n > nblimbs and in particular X->n > 0. */
Jens Wiklander817466c2018-05-22 13:49:31 +0200164
165 for( i = X->n - 1; i > 0; i-- )
166 if( X->p[i] != 0 )
167 break;
168 i++;
169
170 if( i < nblimbs )
171 i = nblimbs;
172
Jerome Forissier84f74672020-03-30 17:42:28 +0200173 if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( i, ciL ) ) == NULL )
174 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
Jens Wiklander817466c2018-05-22 13:49:31 +0200175
176 if( X->p != NULL )
177 {
178 memcpy( p, X->p, i * ciL );
179 mbedtls_mpi_zeroize( X->p, X->n );
Jerome Forissier84f74672020-03-30 17:42:28 +0200180 mbedtls_free( X->p );
Jens Wiklander817466c2018-05-22 13:49:31 +0200181 }
182
Jens Wiklander18c51482018-11-12 13:53:08 +0100183 X->n = i;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100184 X->p = p;
Jens Wiklander817466c2018-05-22 13:49:31 +0200185
186 return( 0 );
187}
188
189/*
190 * Copy the contents of Y into X
191 */
192int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
193{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100194 int ret = 0;
Jens Wiklander817466c2018-05-22 13:49:31 +0200195 size_t i;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100196 MPI_VALIDATE_RET( X != NULL );
197 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200198
199 if( X == Y )
200 return( 0 );
201
Jerome Forissier84f74672020-03-30 17:42:28 +0200202 if( Y->n == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +0200203 {
204 mbedtls_mpi_free( X );
205 return( 0 );
206 }
207
208 for( i = Y->n - 1; i > 0; i-- )
209 if( Y->p[i] != 0 )
210 break;
211 i++;
212
213 X->s = Y->s;
214
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100215 if( X->n < i )
216 {
217 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) );
218 }
219 else
220 {
221 memset( X->p + i, 0, ( X->n - i ) * ciL );
222 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200223
Jens Wiklander817466c2018-05-22 13:49:31 +0200224 memcpy( X->p, Y->p, i * ciL );
225
226cleanup:
227
228 return( ret );
229}
230
231/*
232 * Swap the contents of X and Y
233 */
234void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
235{
236 mbedtls_mpi T;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100237 MPI_VALIDATE( X != NULL );
238 MPI_VALIDATE( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200239
240 memcpy( &T, X, sizeof( mbedtls_mpi ) );
241 memcpy( X, Y, sizeof( mbedtls_mpi ) );
242 memcpy( Y, &T, sizeof( mbedtls_mpi ) );
243}
244
245/*
246 * Conditionally assign X = Y, without leaking information
247 * about whether the assignment was made or not.
248 * (Leaking information about the respective sizes of X and Y is ok however.)
249 */
250int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign )
251{
252 int ret = 0;
253 size_t i;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100254 MPI_VALIDATE_RET( X != NULL );
255 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200256
257 /* make sure assign is 0 or 1 in a time-constant manner */
258 assign = (assign | (unsigned char)-assign) >> 7;
259
260 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
261
262 X->s = X->s * ( 1 - assign ) + Y->s * assign;
263
264 for( i = 0; i < Y->n; i++ )
265 X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign;
266
267 for( ; i < X->n; i++ )
268 X->p[i] *= ( 1 - assign );
269
270cleanup:
271 return( ret );
272}
273
274/*
275 * Conditionally swap X and Y, without leaking information
276 * about whether the swap was made or not.
277 * Here it is not ok to simply swap the pointers, which whould lead to
278 * different memory access patterns when X and Y are used afterwards.
279 */
280int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap )
281{
282 int ret, s;
283 size_t i;
284 mbedtls_mpi_uint tmp;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100285 MPI_VALIDATE_RET( X != NULL );
286 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200287
288 if( X == Y )
289 return( 0 );
290
291 /* make sure swap is 0 or 1 in a time-constant manner */
292 swap = (swap | (unsigned char)-swap) >> 7;
293
294 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
295 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
296
297 s = X->s;
298 X->s = X->s * ( 1 - swap ) + Y->s * swap;
299 Y->s = Y->s * ( 1 - swap ) + s * swap;
300
301
302 for( i = 0; i < X->n; i++ )
303 {
304 tmp = X->p[i];
305 X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap;
306 Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap;
307 }
308
309cleanup:
310 return( ret );
311}
312
313/*
314 * Set value from integer
315 */
316int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z )
317{
318 int ret;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100319 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200320
321 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) );
322 memset( X->p, 0, X->n * ciL );
323
324 X->p[0] = ( z < 0 ) ? -z : z;
325 X->s = ( z < 0 ) ? -1 : 1;
326
327cleanup:
328
329 return( ret );
330}
331
332/*
333 * Get a specific bit
334 */
335int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
336{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100337 MPI_VALIDATE_RET( X != NULL );
338
Jens Wiklander817466c2018-05-22 13:49:31 +0200339 if( X->n * biL <= pos )
340 return( 0 );
341
342 return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
343}
344
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100345/* Get a specific byte, without range checks. */
346#define GET_BYTE( X, i ) \
347 ( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff )
348
Jens Wiklander817466c2018-05-22 13:49:31 +0200349/*
350 * Set a bit to a specific value of 0 or 1
351 */
352int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val )
353{
354 int ret = 0;
355 size_t off = pos / biL;
356 size_t idx = pos % biL;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100357 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200358
359 if( val != 0 && val != 1 )
360 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
361
362 if( X->n * biL <= pos )
363 {
364 if( val == 0 )
365 return( 0 );
366
367 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, off + 1 ) );
368 }
369
370 X->p[off] &= ~( (mbedtls_mpi_uint) 0x01 << idx );
371 X->p[off] |= (mbedtls_mpi_uint) val << idx;
372
373cleanup:
374
375 return( ret );
376}
377
378/*
379 * Return the number of less significant zero-bits
380 */
381size_t mbedtls_mpi_lsb( const mbedtls_mpi *X )
382{
383 size_t i, j, count = 0;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100384 MBEDTLS_INTERNAL_VALIDATE_RET( X != NULL, 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200385
386 for( i = 0; i < X->n; i++ )
387 for( j = 0; j < biL; j++, count++ )
388 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
389 return( count );
390
391 return( 0 );
392}
393
394/*
395 * Count leading zero bits in a given integer
396 */
397static size_t mbedtls_clz( const mbedtls_mpi_uint x )
398{
399 size_t j;
400 mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);
401
402 for( j = 0; j < biL; j++ )
403 {
404 if( x & mask ) break;
405
406 mask >>= 1;
407 }
408
409 return j;
410}
411
412/*
413 * Return the number of bits
414 */
415size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X )
416{
417 size_t i, j;
418
419 if( X->n == 0 )
420 return( 0 );
421
422 for( i = X->n - 1; i > 0; i-- )
423 if( X->p[i] != 0 )
424 break;
425
426 j = biL - mbedtls_clz( X->p[i] );
427
428 return( ( i * biL ) + j );
429}
430
431/*
432 * Return the total size in bytes
433 */
434size_t mbedtls_mpi_size( const mbedtls_mpi *X )
435{
436 return( ( mbedtls_mpi_bitlen( X ) + 7 ) >> 3 );
437}
438
439/*
440 * Convert an ASCII character to digit value
441 */
442static int mpi_get_digit( mbedtls_mpi_uint *d, int radix, char c )
443{
444 *d = 255;
445
446 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
447 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
448 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
449
450 if( *d >= (mbedtls_mpi_uint) radix )
451 return( MBEDTLS_ERR_MPI_INVALID_CHARACTER );
452
453 return( 0 );
454}
455
456/*
457 * Import from an ASCII string
458 */
459int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
460{
461 int ret;
462 size_t i, j, slen, n;
463 mbedtls_mpi_uint d;
464 mbedtls_mpi T;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100465 MPI_VALIDATE_RET( X != NULL );
466 MPI_VALIDATE_RET( s != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200467
468 if( radix < 2 || radix > 16 )
469 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
470
Jerome Forissier84f74672020-03-30 17:42:28 +0200471 mbedtls_mpi_init( &T );
Jens Wiklander817466c2018-05-22 13:49:31 +0200472
473 slen = strlen( s );
474
475 if( radix == 16 )
476 {
477 if( slen > MPI_SIZE_T_MAX >> 2 )
478 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
479
480 n = BITS_TO_LIMBS( slen << 2 );
481
482 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) );
483 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
484
485 for( i = slen, j = 0; i > 0; i--, j++ )
486 {
487 if( i == 1 && s[i - 1] == '-' )
488 {
489 X->s = -1;
490 break;
491 }
492
493 MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
494 X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
495 }
496 }
497 else
498 {
499 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
500
501 for( i = 0; i < slen; i++ )
502 {
503 if( i == 0 && s[i] == '-' )
504 {
505 X->s = -1;
506 continue;
507 }
508
509 MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
510 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T, X, radix ) );
511
512 if( X->s == 1 )
513 {
514 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) );
515 }
516 else
517 {
518 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( X, &T, d ) );
519 }
520 }
521 }
522
523cleanup:
524
525 mbedtls_mpi_free( &T );
526
527 return( ret );
528}
529
530/*
Jerome Forissier84f74672020-03-30 17:42:28 +0200531 * Helper to write the digits high-order first.
Jens Wiklander817466c2018-05-22 13:49:31 +0200532 */
Jerome Forissier84f74672020-03-30 17:42:28 +0200533static int mpi_write_hlp( mbedtls_mpi *X, int radix,
534 char **p, const size_t buflen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200535{
536 int ret;
537 mbedtls_mpi_uint r;
Jerome Forissier84f74672020-03-30 17:42:28 +0200538 size_t length = 0;
539 char *p_end = *p + buflen;
Jens Wiklander817466c2018-05-22 13:49:31 +0200540
Jerome Forissier84f74672020-03-30 17:42:28 +0200541 do
542 {
543 if( length >= buflen )
544 {
545 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
546 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200547
Jerome Forissier84f74672020-03-30 17:42:28 +0200548 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) );
549 MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) );
550 /*
551 * Write the residue in the current position, as an ASCII character.
552 */
553 if( r < 0xA )
554 *(--p_end) = (char)( '0' + r );
555 else
556 *(--p_end) = (char)( 'A' + ( r - 0xA ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200557
Jerome Forissier84f74672020-03-30 17:42:28 +0200558 length++;
559 } while( mbedtls_mpi_cmp_int( X, 0 ) != 0 );
Jens Wiklander817466c2018-05-22 13:49:31 +0200560
Jerome Forissier84f74672020-03-30 17:42:28 +0200561 memmove( *p, p_end, length );
562 *p += length;
Jens Wiklander817466c2018-05-22 13:49:31 +0200563
564cleanup:
565
566 return( ret );
567}
568
569/*
570 * Export into an ASCII string
571 */
572int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
573 char *buf, size_t buflen, size_t *olen )
574{
575 int ret = 0;
576 size_t n;
577 char *p;
578 mbedtls_mpi T;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100579 MPI_VALIDATE_RET( X != NULL );
580 MPI_VALIDATE_RET( olen != NULL );
581 MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200582
583 if( radix < 2 || radix > 16 )
584 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
585
Jerome Forissier84f74672020-03-30 17:42:28 +0200586 n = mbedtls_mpi_bitlen( X ); /* Number of bits necessary to present `n`. */
587 if( radix >= 4 ) n >>= 1; /* Number of 4-adic digits necessary to present
588 * `n`. If radix > 4, this might be a strict
589 * overapproximation of the number of
590 * radix-adic digits needed to present `n`. */
591 if( radix >= 16 ) n >>= 1; /* Number of hexadecimal digits necessary to
592 * present `n`. */
593
594 n += 1; /* Terminating null byte */
595 n += 1; /* Compensate for the divisions above, which round down `n`
596 * in case it's not even. */
597 n += 1; /* Potential '-'-sign. */
598 n += ( n & 1 ); /* Make n even to have enough space for hexadecimal writing,
599 * which always uses an even number of hex-digits. */
Jens Wiklander817466c2018-05-22 13:49:31 +0200600
601 if( buflen < n )
602 {
603 *olen = n;
604 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
605 }
606
607 p = buf;
Jerome Forissier84f74672020-03-30 17:42:28 +0200608 mbedtls_mpi_init( &T );
Jens Wiklander817466c2018-05-22 13:49:31 +0200609
610 if( X->s == -1 )
Jerome Forissier84f74672020-03-30 17:42:28 +0200611 {
Jens Wiklander817466c2018-05-22 13:49:31 +0200612 *p++ = '-';
Jerome Forissier84f74672020-03-30 17:42:28 +0200613 buflen--;
614 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200615
616 if( radix == 16 )
617 {
618 int c;
619 size_t i, j, k;
620
621 for( i = X->n, k = 0; i > 0; i-- )
622 {
623 for( j = ciL; j > 0; j-- )
624 {
625 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
626
627 if( c == 0 && k == 0 && ( i + j ) != 2 )
628 continue;
629
630 *(p++) = "0123456789ABCDEF" [c / 16];
631 *(p++) = "0123456789ABCDEF" [c % 16];
632 k = 1;
633 }
634 }
635 }
636 else
637 {
638 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T, X ) );
639
640 if( T.s == -1 )
641 T.s = 1;
642
Jerome Forissier84f74672020-03-30 17:42:28 +0200643 MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p, buflen ) );
Jens Wiklander817466c2018-05-22 13:49:31 +0200644 }
645
646 *p++ = '\0';
647 *olen = p - buf;
648
649cleanup:
650
651 mbedtls_mpi_free( &T );
652
653 return( ret );
654}
655
656#if defined(MBEDTLS_FS_IO)
657/*
658 * Read X from an opened file
659 */
660int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin )
661{
662 mbedtls_mpi_uint d;
663 size_t slen;
664 char *p;
665 /*
666 * Buffer should have space for (short) label and decimal formatted MPI,
667 * newline characters and '\0'
668 */
669 char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
670
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100671 MPI_VALIDATE_RET( X != NULL );
672 MPI_VALIDATE_RET( fin != NULL );
673
674 if( radix < 2 || radix > 16 )
675 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
676
Jens Wiklander817466c2018-05-22 13:49:31 +0200677 memset( s, 0, sizeof( s ) );
678 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
679 return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
680
681 slen = strlen( s );
682 if( slen == sizeof( s ) - 2 )
683 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
684
685 if( slen > 0 && s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
686 if( slen > 0 && s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
687
688 p = s + slen;
689 while( p-- > s )
690 if( mpi_get_digit( &d, radix, *p ) != 0 )
691 break;
692
693 return( mbedtls_mpi_read_string( X, radix, p + 1 ) );
694}
695
696/*
697 * Write X into an opened file (or stdout if fout == NULL)
698 */
699int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout )
700{
701 int ret;
702 size_t n, slen, plen;
703 /*
704 * Buffer should have space for (short) label and decimal formatted MPI,
705 * newline characters and '\0'
706 */
707 char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100708 MPI_VALIDATE_RET( X != NULL );
709
710 if( radix < 2 || radix > 16 )
711 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
Jens Wiklander817466c2018-05-22 13:49:31 +0200712
713 memset( s, 0, sizeof( s ) );
714
715 MBEDTLS_MPI_CHK( mbedtls_mpi_write_string( X, radix, s, sizeof( s ) - 2, &n ) );
716
717 if( p == NULL ) p = "";
718
719 plen = strlen( p );
720 slen = strlen( s );
721 s[slen++] = '\r';
722 s[slen++] = '\n';
723
724 if( fout != NULL )
725 {
726 if( fwrite( p, 1, plen, fout ) != plen ||
727 fwrite( s, 1, slen, fout ) != slen )
728 return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
729 }
730 else
731 mbedtls_printf( "%s%s", p, s );
732
733cleanup:
734
735 return( ret );
736}
737#endif /* MBEDTLS_FS_IO */
738
Jerome Forissier84f74672020-03-30 17:42:28 +0200739
740/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint
741 * into the storage form used by mbedtls_mpi. */
742
743static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c( mbedtls_mpi_uint x )
744{
745 uint8_t i;
746 unsigned char *x_ptr;
747 mbedtls_mpi_uint tmp = 0;
748
749 for( i = 0, x_ptr = (unsigned char*) &x; i < ciL; i++, x_ptr++ )
750 {
751 tmp <<= CHAR_BIT;
752 tmp |= (mbedtls_mpi_uint) *x_ptr;
753 }
754
755 return( tmp );
756}
757
758static mbedtls_mpi_uint mpi_uint_bigendian_to_host( mbedtls_mpi_uint x )
759{
760#if defined(__BYTE_ORDER__)
761
762/* Nothing to do on bigendian systems. */
763#if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ )
764 return( x );
765#endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */
766
767#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ )
768
769/* For GCC and Clang, have builtins for byte swapping. */
770#if defined(__GNUC__) && defined(__GNUC_PREREQ)
771#if __GNUC_PREREQ(4,3)
772#define have_bswap
773#endif
774#endif
775
776#if defined(__clang__) && defined(__has_builtin)
777#if __has_builtin(__builtin_bswap32) && \
778 __has_builtin(__builtin_bswap64)
779#define have_bswap
780#endif
781#endif
782
783#if defined(have_bswap)
784 /* The compiler is hopefully able to statically evaluate this! */
785 switch( sizeof(mbedtls_mpi_uint) )
786 {
787 case 4:
788 return( __builtin_bswap32(x) );
789 case 8:
790 return( __builtin_bswap64(x) );
791 }
792#endif
793#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
794#endif /* __BYTE_ORDER__ */
795
796 /* Fall back to C-based reordering if we don't know the byte order
797 * or we couldn't use a compiler-specific builtin. */
798 return( mpi_uint_bigendian_to_host_c( x ) );
799}
800
801static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs )
802{
803 mbedtls_mpi_uint *cur_limb_left;
804 mbedtls_mpi_uint *cur_limb_right;
805 if( limbs == 0 )
806 return;
807
808 /*
809 * Traverse limbs and
810 * - adapt byte-order in each limb
811 * - swap the limbs themselves.
812 * For that, simultaneously traverse the limbs from left to right
813 * and from right to left, as long as the left index is not bigger
814 * than the right index (it's not a problem if limbs is odd and the
815 * indices coincide in the last iteration).
816 */
817 for( cur_limb_left = p, cur_limb_right = p + ( limbs - 1 );
818 cur_limb_left <= cur_limb_right;
819 cur_limb_left++, cur_limb_right-- )
820 {
821 mbedtls_mpi_uint tmp;
822 /* Note that if cur_limb_left == cur_limb_right,
823 * this code effectively swaps the bytes only once. */
824 tmp = mpi_uint_bigendian_to_host( *cur_limb_left );
825 *cur_limb_left = mpi_uint_bigendian_to_host( *cur_limb_right );
826 *cur_limb_right = tmp;
827 }
828}
829
Jens Wiklander817466c2018-05-22 13:49:31 +0200830/*
831 * Import X from unsigned binary data, big endian
832 */
833int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
834{
835 int ret;
Jerome Forissier84f74672020-03-30 17:42:28 +0200836 size_t const limbs = CHARS_TO_LIMBS( buflen );
837 size_t const overhead = ( limbs * ciL ) - buflen;
838 unsigned char *Xp;
Jens Wiklander817466c2018-05-22 13:49:31 +0200839
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100840 MPI_VALIDATE_RET( X != NULL );
841 MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200842
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100843 /* Ensure that target MPI has exactly the necessary number of limbs */
844 if( X->n != limbs )
845 {
846 mbedtls_mpi_free( X );
Jerome Forissier84f74672020-03-30 17:42:28 +0200847 mbedtls_mpi_init( X );
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100848 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
849 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200850 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
851
Jerome Forissier84f74672020-03-30 17:42:28 +0200852 /* Avoid calling `memcpy` with NULL source argument,
853 * even if buflen is 0. */
854 if( buf != NULL )
855 {
856 Xp = (unsigned char*) X->p;
857 memcpy( Xp + overhead, buf, buflen );
858
859 mpi_bigendian_to_host( X->p, limbs );
860 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200861
862cleanup:
863
864 return( ret );
865}
866
867/*
868 * Export X into unsigned binary data, big endian
869 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100870int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
871 unsigned char *buf, size_t buflen )
Jens Wiklander817466c2018-05-22 13:49:31 +0200872{
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100873 size_t stored_bytes;
874 size_t bytes_to_copy;
875 unsigned char *p;
876 size_t i;
Jens Wiklander817466c2018-05-22 13:49:31 +0200877
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100878 MPI_VALIDATE_RET( X != NULL );
879 MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200880
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100881 stored_bytes = X->n * ciL;
Jens Wiklander817466c2018-05-22 13:49:31 +0200882
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100883 if( stored_bytes < buflen )
884 {
885 /* There is enough space in the output buffer. Write initial
886 * null bytes and record the position at which to start
887 * writing the significant bytes. In this case, the execution
888 * trace of this function does not depend on the value of the
889 * number. */
890 bytes_to_copy = stored_bytes;
891 p = buf + buflen - stored_bytes;
892 memset( buf, 0, buflen - stored_bytes );
893 }
894 else
895 {
896 /* The output buffer is smaller than the allocated size of X.
897 * However X may fit if its leading bytes are zero. */
898 bytes_to_copy = buflen;
899 p = buf;
900 for( i = bytes_to_copy; i < stored_bytes; i++ )
901 {
902 if( GET_BYTE( X, i ) != 0 )
903 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
904 }
905 }
Jens Wiklander817466c2018-05-22 13:49:31 +0200906
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100907 for( i = 0; i < bytes_to_copy; i++ )
908 p[bytes_to_copy - i - 1] = GET_BYTE( X, i );
Jens Wiklander817466c2018-05-22 13:49:31 +0200909
910 return( 0 );
911}
912
913/*
914 * Left-shift: X <<= count
915 */
916int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count )
917{
918 int ret;
919 size_t i, v0, t1;
920 mbedtls_mpi_uint r0 = 0, r1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100921 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200922
923 v0 = count / (biL );
924 t1 = count & (biL - 1);
925
926 i = mbedtls_mpi_bitlen( X ) + count;
927
928 if( X->n * biL < i )
929 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, BITS_TO_LIMBS( i ) ) );
930
931 ret = 0;
932
933 /*
934 * shift by count / limb_size
935 */
936 if( v0 > 0 )
937 {
938 for( i = X->n; i > v0; i-- )
939 X->p[i - 1] = X->p[i - v0 - 1];
940
941 for( ; i > 0; i-- )
942 X->p[i - 1] = 0;
943 }
944
945 /*
946 * shift by count % limb_size
947 */
948 if( t1 > 0 )
949 {
950 for( i = v0; i < X->n; i++ )
951 {
952 r1 = X->p[i] >> (biL - t1);
953 X->p[i] <<= t1;
954 X->p[i] |= r0;
955 r0 = r1;
956 }
957 }
958
959cleanup:
960
961 return( ret );
962}
963
964/*
965 * Right-shift: X >>= count
966 */
967int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count )
968{
969 size_t i, v0, v1;
970 mbedtls_mpi_uint r0 = 0, r1;
Jens Wiklander3d3b0592019-03-20 15:30:29 +0100971 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +0200972
973 v0 = count / biL;
974 v1 = count & (biL - 1);
975
976 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
977 return mbedtls_mpi_lset( X, 0 );
978
979 /*
980 * shift by count / limb_size
981 */
982 if( v0 > 0 )
983 {
984 for( i = 0; i < X->n - v0; i++ )
985 X->p[i] = X->p[i + v0];
986
987 for( ; i < X->n; i++ )
988 X->p[i] = 0;
989 }
990
991 /*
992 * shift by count % limb_size
993 */
994 if( v1 > 0 )
995 {
996 for( i = X->n; i > 0; i-- )
997 {
998 r1 = X->p[i - 1] << (biL - v1);
999 X->p[i - 1] >>= v1;
1000 X->p[i - 1] |= r0;
1001 r0 = r1;
1002 }
1003 }
1004
1005 return( 0 );
1006}
1007
1008/*
1009 * Compare unsigned values
1010 */
1011int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y )
1012{
1013 size_t i, j;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001014 MPI_VALIDATE_RET( X != NULL );
1015 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001016
1017 for( i = X->n; i > 0; i-- )
1018 if( X->p[i - 1] != 0 )
1019 break;
1020
1021 for( j = Y->n; j > 0; j-- )
1022 if( Y->p[j - 1] != 0 )
1023 break;
1024
1025 if( i == 0 && j == 0 )
1026 return( 0 );
1027
1028 if( i > j ) return( 1 );
1029 if( j > i ) return( -1 );
1030
1031 for( ; i > 0; i-- )
1032 {
1033 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
1034 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
1035 }
1036
1037 return( 0 );
1038}
1039
1040/*
1041 * Compare signed values
1042 */
1043int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
1044{
1045 size_t i, j;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001046 MPI_VALIDATE_RET( X != NULL );
1047 MPI_VALIDATE_RET( Y != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001048
1049 for( i = X->n; i > 0; i-- )
1050 if( X->p[i - 1] != 0 )
1051 break;
1052
1053 for( j = Y->n; j > 0; j-- )
1054 if( Y->p[j - 1] != 0 )
1055 break;
1056
1057 if( i == 0 && j == 0 )
1058 return( 0 );
1059
1060 if( i > j ) return( X->s );
1061 if( j > i ) return( -Y->s );
1062
1063 if( X->s > 0 && Y->s < 0 ) return( 1 );
1064 if( Y->s > 0 && X->s < 0 ) return( -1 );
1065
1066 for( ; i > 0; i-- )
1067 {
1068 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
1069 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
1070 }
1071
1072 return( 0 );
1073}
1074
Jerome Forissier84f74672020-03-30 17:42:28 +02001075/** Decide if an integer is less than the other, without branches.
1076 *
1077 * \param x First integer.
1078 * \param y Second integer.
1079 *
1080 * \return 1 if \p x is less than \p y, 0 otherwise
1081 */
1082static unsigned ct_lt_mpi_uint( const mbedtls_mpi_uint x,
1083 const mbedtls_mpi_uint y )
1084{
1085 mbedtls_mpi_uint ret;
1086 mbedtls_mpi_uint cond;
1087
1088 /*
1089 * Check if the most significant bits (MSB) of the operands are different.
1090 */
1091 cond = ( x ^ y );
1092 /*
1093 * If the MSB are the same then the difference x-y will be negative (and
1094 * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
1095 */
1096 ret = ( x - y ) & ~cond;
1097 /*
1098 * If the MSB are different, then the operand with the MSB of 1 is the
1099 * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
1100 * the MSB of y is 0.)
1101 */
1102 ret |= y & cond;
1103
1104
1105 ret = ret >> ( biL - 1 );
1106
1107 return (unsigned) ret;
1108}
1109
1110/*
1111 * Compare signed values in constant time
1112 */
1113int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
1114 unsigned *ret )
1115{
1116 size_t i;
1117 /* The value of any of these variables is either 0 or 1 at all times. */
1118 unsigned cond, done, X_is_negative, Y_is_negative;
1119
1120 MPI_VALIDATE_RET( X != NULL );
1121 MPI_VALIDATE_RET( Y != NULL );
1122 MPI_VALIDATE_RET( ret != NULL );
1123
1124 if( X->n != Y->n )
1125 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1126
1127 /*
1128 * Set sign_N to 1 if N >= 0, 0 if N < 0.
1129 * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
1130 */
1131 X_is_negative = ( X->s & 2 ) >> 1;
1132 Y_is_negative = ( Y->s & 2 ) >> 1;
1133
1134 /*
1135 * If the signs are different, then the positive operand is the bigger.
1136 * That is if X is negative (X_is_negative == 1), then X < Y is true and it
1137 * is false if X is positive (X_is_negative == 0).
1138 */
1139 cond = ( X_is_negative ^ Y_is_negative );
1140 *ret = cond & X_is_negative;
1141
1142 /*
1143 * This is a constant-time function. We might have the result, but we still
1144 * need to go through the loop. Record if we have the result already.
1145 */
1146 done = cond;
1147
1148 for( i = X->n; i > 0; i-- )
1149 {
1150 /*
1151 * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
1152 * X and Y are negative.
1153 *
1154 * Again even if we can make a decision, we just mark the result and
1155 * the fact that we are done and continue looping.
1156 */
1157 cond = ct_lt_mpi_uint( Y->p[i - 1], X->p[i - 1] );
1158 *ret |= cond & ( 1 - done ) & X_is_negative;
1159 done |= cond;
1160
1161 /*
1162 * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
1163 * X and Y are positive.
1164 *
1165 * Again even if we can make a decision, we just mark the result and
1166 * the fact that we are done and continue looping.
1167 */
1168 cond = ct_lt_mpi_uint( X->p[i - 1], Y->p[i - 1] );
1169 *ret |= cond & ( 1 - done ) & ( 1 - X_is_negative );
1170 done |= cond;
1171 }
1172
1173 return( 0 );
1174}
1175
Jens Wiklander817466c2018-05-22 13:49:31 +02001176/*
1177 * Compare signed values
1178 */
1179int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z )
1180{
1181 mbedtls_mpi Y;
1182 mbedtls_mpi_uint p[1];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001183 MPI_VALIDATE_RET( X != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001184
1185 *p = ( z < 0 ) ? -z : z;
1186 Y.s = ( z < 0 ) ? -1 : 1;
1187 Y.n = 1;
1188 Y.p = p;
1189
1190 return( mbedtls_mpi_cmp_mpi( X, &Y ) );
1191}
1192
1193/*
1194 * Unsigned addition: X = |A| + |B| (HAC 14.7)
1195 */
1196int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1197{
1198 int ret;
1199 size_t i, j;
1200 mbedtls_mpi_uint *o, *p, c, tmp;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001201 MPI_VALIDATE_RET( X != NULL );
1202 MPI_VALIDATE_RET( A != NULL );
1203 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001204
1205 if( X == B )
1206 {
1207 const mbedtls_mpi *T = A; A = X; B = T;
1208 }
1209
1210 if( X != A )
1211 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
1212
1213 /*
1214 * X should always be positive as a result of unsigned additions.
1215 */
1216 X->s = 1;
1217
1218 for( j = B->n; j > 0; j-- )
1219 if( B->p[j - 1] != 0 )
1220 break;
1221
1222 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
1223
1224 o = B->p; p = X->p; c = 0;
1225
1226 /*
1227 * tmp is used because it might happen that p == o
1228 */
1229 for( i = 0; i < j; i++, o++, p++ )
1230 {
1231 tmp= *o;
1232 *p += c; c = ( *p < c );
1233 *p += tmp; c += ( *p < tmp );
1234 }
1235
1236 while( c != 0 )
1237 {
1238 if( i >= X->n )
1239 {
1240 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + 1 ) );
1241 p = X->p + i;
1242 }
1243
1244 *p += c; c = ( *p < c ); i++; p++;
1245 }
1246
1247cleanup:
1248
1249 return( ret );
1250}
1251
1252/*
1253 * Helper for mbedtls_mpi subtraction
1254 */
1255static void mpi_sub_hlp( size_t n, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d )
1256{
1257 size_t i;
1258 mbedtls_mpi_uint c, z;
1259
1260 for( i = c = 0; i < n; i++, s++, d++ )
1261 {
1262 z = ( *d < c ); *d -= c;
1263 c = ( *d < *s ) + z; *d -= *s;
1264 }
1265
1266 while( c != 0 )
1267 {
1268 z = ( *d < c ); *d -= c;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001269 c = z; d++;
Jens Wiklander817466c2018-05-22 13:49:31 +02001270 }
1271}
1272
1273/*
1274 * Unsigned subtraction: X = |A| - |B| (HAC 14.9)
1275 */
1276int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1277{
1278 mbedtls_mpi TB;
1279 int ret;
1280 size_t n;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001281 MPI_VALIDATE_RET( X != NULL );
1282 MPI_VALIDATE_RET( A != NULL );
1283 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001284
1285 if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
1286 return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
1287
Jerome Forissier84f74672020-03-30 17:42:28 +02001288 mbedtls_mpi_init( &TB );
Jens Wiklander817466c2018-05-22 13:49:31 +02001289
1290 if( X == B )
1291 {
1292 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
1293 B = &TB;
1294 }
1295
1296 if( X != A )
1297 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
1298
1299 /*
1300 * X should always be positive as a result of unsigned subtractions.
1301 */
1302 X->s = 1;
1303
1304 ret = 0;
1305
1306 for( n = B->n; n > 0; n-- )
1307 if( B->p[n - 1] != 0 )
1308 break;
1309
1310 mpi_sub_hlp( n, B->p, X->p );
1311
1312cleanup:
1313
1314 mbedtls_mpi_free( &TB );
1315
1316 return( ret );
1317}
1318
1319/*
1320 * Signed addition: X = A + B
1321 */
1322int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1323{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001324 int ret, s;
1325 MPI_VALIDATE_RET( X != NULL );
1326 MPI_VALIDATE_RET( A != NULL );
1327 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001328
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001329 s = A->s;
Jens Wiklander817466c2018-05-22 13:49:31 +02001330 if( A->s * B->s < 0 )
1331 {
1332 if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
1333 {
1334 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
1335 X->s = s;
1336 }
1337 else
1338 {
1339 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
1340 X->s = -s;
1341 }
1342 }
1343 else
1344 {
1345 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
1346 X->s = s;
1347 }
1348
1349cleanup:
1350
1351 return( ret );
1352}
1353
1354/*
1355 * Signed subtraction: X = A - B
1356 */
1357int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1358{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001359 int ret, s;
1360 MPI_VALIDATE_RET( X != NULL );
1361 MPI_VALIDATE_RET( A != NULL );
1362 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001363
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001364 s = A->s;
Jens Wiklander817466c2018-05-22 13:49:31 +02001365 if( A->s * B->s > 0 )
1366 {
1367 if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
1368 {
1369 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
1370 X->s = s;
1371 }
1372 else
1373 {
1374 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
1375 X->s = -s;
1376 }
1377 }
1378 else
1379 {
1380 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
1381 X->s = s;
1382 }
1383
1384cleanup:
1385
1386 return( ret );
1387}
1388
1389/*
1390 * Signed addition: X = A + b
1391 */
1392int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
1393{
1394 mbedtls_mpi _B;
1395 mbedtls_mpi_uint p[1];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001396 MPI_VALIDATE_RET( X != NULL );
1397 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001398
1399 p[0] = ( b < 0 ) ? -b : b;
1400 _B.s = ( b < 0 ) ? -1 : 1;
1401 _B.n = 1;
1402 _B.p = p;
1403
1404 return( mbedtls_mpi_add_mpi( X, A, &_B ) );
1405}
1406
1407/*
1408 * Signed subtraction: X = A - b
1409 */
1410int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
1411{
1412 mbedtls_mpi _B;
1413 mbedtls_mpi_uint p[1];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001414 MPI_VALIDATE_RET( X != NULL );
1415 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001416
1417 p[0] = ( b < 0 ) ? -b : b;
1418 _B.s = ( b < 0 ) ? -1 : 1;
1419 _B.n = 1;
1420 _B.p = p;
1421
1422 return( mbedtls_mpi_sub_mpi( X, A, &_B ) );
1423}
1424
1425/*
1426 * Helper for mbedtls_mpi multiplication
1427 */
1428static
1429#if defined(__APPLE__) && defined(__arm__)
1430/*
1431 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1432 * appears to need this to prevent bad ARM code generation at -O3.
1433 */
1434__attribute__ ((noinline))
1435#endif
1436void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mpi_uint b )
1437{
1438 mbedtls_mpi_uint c = 0, t = 0;
1439
1440#if defined(MULADDC_HUIT)
1441 for( ; i >= 8; i -= 8 )
1442 {
1443 MULADDC_INIT
1444 MULADDC_HUIT
1445 MULADDC_STOP
1446 }
1447
1448 for( ; i > 0; i-- )
1449 {
1450 MULADDC_INIT
1451 MULADDC_CORE
1452 MULADDC_STOP
1453 }
1454#else /* MULADDC_HUIT */
1455 for( ; i >= 16; i -= 16 )
1456 {
1457 MULADDC_INIT
1458 MULADDC_CORE MULADDC_CORE
1459 MULADDC_CORE MULADDC_CORE
1460 MULADDC_CORE MULADDC_CORE
1461 MULADDC_CORE MULADDC_CORE
1462
1463 MULADDC_CORE MULADDC_CORE
1464 MULADDC_CORE MULADDC_CORE
1465 MULADDC_CORE MULADDC_CORE
1466 MULADDC_CORE MULADDC_CORE
1467 MULADDC_STOP
1468 }
1469
1470 for( ; i >= 8; i -= 8 )
1471 {
1472 MULADDC_INIT
1473 MULADDC_CORE MULADDC_CORE
1474 MULADDC_CORE MULADDC_CORE
1475
1476 MULADDC_CORE MULADDC_CORE
1477 MULADDC_CORE MULADDC_CORE
1478 MULADDC_STOP
1479 }
1480
1481 for( ; i > 0; i-- )
1482 {
1483 MULADDC_INIT
1484 MULADDC_CORE
1485 MULADDC_STOP
1486 }
1487#endif /* MULADDC_HUIT */
1488
1489 t++;
1490
1491 do {
1492 *d += c; c = ( *d < c ); d++;
1493 }
1494 while( c != 0 );
1495}
1496
1497/*
1498 * Baseline multiplication: X = A * B (HAC 14.12)
1499 */
1500int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1501{
1502 int ret;
1503 size_t i, j;
1504 mbedtls_mpi TA, TB;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001505 MPI_VALIDATE_RET( X != NULL );
1506 MPI_VALIDATE_RET( A != NULL );
1507 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001508
Jerome Forissier84f74672020-03-30 17:42:28 +02001509 mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
Jens Wiklander817466c2018-05-22 13:49:31 +02001510
1511 if( X == A ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); A = &TA; }
1512 if( X == B ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); B = &TB; }
1513
1514 for( i = A->n; i > 0; i-- )
1515 if( A->p[i - 1] != 0 )
1516 break;
1517
1518 for( j = B->n; j > 0; j-- )
1519 if( B->p[j - 1] != 0 )
1520 break;
1521
1522 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
1523 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
1524
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001525 for( ; j > 0; j-- )
1526 mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] );
Jens Wiklander817466c2018-05-22 13:49:31 +02001527
1528 X->s = A->s * B->s;
1529
1530cleanup:
1531
1532 mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TA );
1533
1534 return( ret );
1535}
1536
1537/*
1538 * Baseline multiplication: X = A * b
1539 */
1540int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b )
1541{
1542 mbedtls_mpi _B;
1543 mbedtls_mpi_uint p[1];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001544 MPI_VALIDATE_RET( X != NULL );
1545 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001546
1547 _B.s = 1;
1548 _B.n = 1;
1549 _B.p = p;
1550 p[0] = b;
1551
1552 return( mbedtls_mpi_mul_mpi( X, A, &_B ) );
1553}
1554
1555/*
1556 * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and
1557 * mbedtls_mpi_uint divisor, d
1558 */
1559static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1,
1560 mbedtls_mpi_uint u0, mbedtls_mpi_uint d, mbedtls_mpi_uint *r )
1561{
1562#if defined(MBEDTLS_HAVE_UDBL)
1563 mbedtls_t_udbl dividend, quotient;
1564#else
1565 const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH;
1566 const mbedtls_mpi_uint uint_halfword_mask = ( (mbedtls_mpi_uint) 1 << biH ) - 1;
1567 mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient;
1568 mbedtls_mpi_uint u0_msw, u0_lsw;
1569 size_t s;
1570#endif
1571
1572 /*
1573 * Check for overflow
1574 */
1575 if( 0 == d || u1 >= d )
1576 {
1577 if (r != NULL) *r = ~0;
1578
1579 return ( ~0 );
1580 }
1581
1582#if defined(MBEDTLS_HAVE_UDBL)
1583 dividend = (mbedtls_t_udbl) u1 << biL;
1584 dividend |= (mbedtls_t_udbl) u0;
1585 quotient = dividend / d;
1586 if( quotient > ( (mbedtls_t_udbl) 1 << biL ) - 1 )
1587 quotient = ( (mbedtls_t_udbl) 1 << biL ) - 1;
1588
1589 if( r != NULL )
1590 *r = (mbedtls_mpi_uint)( dividend - (quotient * d ) );
1591
1592 return (mbedtls_mpi_uint) quotient;
1593#else
1594
1595 /*
1596 * Algorithm D, Section 4.3.1 - The Art of Computer Programming
1597 * Vol. 2 - Seminumerical Algorithms, Knuth
1598 */
1599
1600 /*
1601 * Normalize the divisor, d, and dividend, u0, u1
1602 */
1603 s = mbedtls_clz( d );
1604 d = d << s;
1605
1606 u1 = u1 << s;
1607 u1 |= ( u0 >> ( biL - s ) ) & ( -(mbedtls_mpi_sint)s >> ( biL - 1 ) );
1608 u0 = u0 << s;
1609
1610 d1 = d >> biH;
1611 d0 = d & uint_halfword_mask;
1612
1613 u0_msw = u0 >> biH;
1614 u0_lsw = u0 & uint_halfword_mask;
1615
1616 /*
1617 * Find the first quotient and remainder
1618 */
1619 q1 = u1 / d1;
1620 r0 = u1 - d1 * q1;
1621
1622 while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) )
1623 {
1624 q1 -= 1;
1625 r0 += d1;
1626
1627 if ( r0 >= radix ) break;
1628 }
1629
1630 rAX = ( u1 * radix ) + ( u0_msw - q1 * d );
1631 q0 = rAX / d1;
1632 r0 = rAX - q0 * d1;
1633
1634 while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) )
1635 {
1636 q0 -= 1;
1637 r0 += d1;
1638
1639 if ( r0 >= radix ) break;
1640 }
1641
1642 if (r != NULL)
1643 *r = ( rAX * radix + u0_lsw - q0 * d ) >> s;
1644
1645 quotient = q1 * radix + q0;
1646
1647 return quotient;
1648#endif
1649}
1650
1651/*
1652 * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20)
1653 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001654int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
1655 const mbedtls_mpi *B )
Jens Wiklander817466c2018-05-22 13:49:31 +02001656{
1657 int ret;
1658 size_t i, n, t, k;
1659 mbedtls_mpi X, Y, Z, T1, T2;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001660 MPI_VALIDATE_RET( A != NULL );
1661 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001662
1663 if( mbedtls_mpi_cmp_int( B, 0 ) == 0 )
1664 return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
1665
Jerome Forissier84f74672020-03-30 17:42:28 +02001666 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
1667 mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
Jens Wiklander817466c2018-05-22 13:49:31 +02001668
1669 if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
1670 {
1671 if( Q != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_lset( Q, 0 ) );
1672 if( R != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, A ) );
1673 return( 0 );
1674 }
1675
1676 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &X, A ) );
1677 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, B ) );
1678 X.s = Y.s = 1;
1679
1680 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &Z, A->n + 2 ) );
1681 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Z, 0 ) );
1682 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, 2 ) );
1683 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T2, 3 ) );
1684
1685 k = mbedtls_mpi_bitlen( &Y ) % biL;
1686 if( k < biL - 1 )
1687 {
1688 k = biL - 1 - k;
1689 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &X, k ) );
1690 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, k ) );
1691 }
1692 else k = 0;
1693
1694 n = X.n - 1;
1695 t = Y.n - 1;
1696 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, biL * ( n - t ) ) );
1697
1698 while( mbedtls_mpi_cmp_mpi( &X, &Y ) >= 0 )
1699 {
1700 Z.p[n - t]++;
1701 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &Y ) );
1702 }
1703 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, biL * ( n - t ) ) );
1704
1705 for( i = n; i > t ; i-- )
1706 {
1707 if( X.p[i] >= Y.p[t] )
1708 Z.p[i - t - 1] = ~0;
1709 else
1710 {
1711 Z.p[i - t - 1] = mbedtls_int_div_int( X.p[i], X.p[i - 1],
1712 Y.p[t], NULL);
1713 }
1714
1715 Z.p[i - t - 1]++;
1716 do
1717 {
1718 Z.p[i - t - 1]--;
1719
1720 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T1, 0 ) );
1721 T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1];
1722 T1.p[1] = Y.p[t];
1723 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1724
1725 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T2, 0 ) );
1726 T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
1727 T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
1728 T2.p[2] = X.p[i];
1729 }
1730 while( mbedtls_mpi_cmp_mpi( &T1, &T2 ) > 0 );
1731
1732 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1733 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
1734 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) );
1735
1736 if( mbedtls_mpi_cmp_int( &X, 0 ) < 0 )
1737 {
1738 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &Y ) );
1739 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
1740 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &X, &X, &T1 ) );
1741 Z.p[i - t - 1]--;
1742 }
1743 }
1744
1745 if( Q != NULL )
1746 {
1747 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( Q, &Z ) );
1748 Q->s = A->s * B->s;
1749 }
1750
1751 if( R != NULL )
1752 {
1753 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &X, k ) );
1754 X.s = A->s;
1755 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, &X ) );
1756
1757 if( mbedtls_mpi_cmp_int( R, 0 ) == 0 )
1758 R->s = 1;
1759 }
1760
1761cleanup:
1762
1763 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
1764 mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
1765
1766 return( ret );
1767}
1768
1769/*
1770 * Division by int: A = Q * b + R
1771 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001772int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R,
1773 const mbedtls_mpi *A,
1774 mbedtls_mpi_sint b )
Jens Wiklander817466c2018-05-22 13:49:31 +02001775{
1776 mbedtls_mpi _B;
1777 mbedtls_mpi_uint p[1];
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001778 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001779
1780 p[0] = ( b < 0 ) ? -b : b;
1781 _B.s = ( b < 0 ) ? -1 : 1;
1782 _B.n = 1;
1783 _B.p = p;
1784
1785 return( mbedtls_mpi_div_mpi( Q, R, A, &_B ) );
1786}
1787
1788/*
1789 * Modulo: R = A mod B
1790 */
1791int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
1792{
1793 int ret;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001794 MPI_VALIDATE_RET( R != NULL );
1795 MPI_VALIDATE_RET( A != NULL );
1796 MPI_VALIDATE_RET( B != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001797
1798 if( mbedtls_mpi_cmp_int( B, 0 ) < 0 )
1799 return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
1800
1801 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( NULL, R, A, B ) );
1802
1803 while( mbedtls_mpi_cmp_int( R, 0 ) < 0 )
1804 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) );
1805
1806 while( mbedtls_mpi_cmp_mpi( R, B ) >= 0 )
1807 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) );
1808
1809cleanup:
1810
1811 return( ret );
1812}
1813
1814/*
1815 * Modulo: r = A mod b
1816 */
1817int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b )
1818{
1819 size_t i;
1820 mbedtls_mpi_uint x, y, z;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001821 MPI_VALIDATE_RET( r != NULL );
1822 MPI_VALIDATE_RET( A != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02001823
1824 if( b == 0 )
1825 return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
1826
1827 if( b < 0 )
1828 return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
1829
1830 /*
1831 * handle trivial cases
1832 */
1833 if( b == 1 )
1834 {
1835 *r = 0;
1836 return( 0 );
1837 }
1838
1839 if( b == 2 )
1840 {
1841 *r = A->p[0] & 1;
1842 return( 0 );
1843 }
1844
1845 /*
1846 * general case
1847 */
1848 for( i = A->n, y = 0; i > 0; i-- )
1849 {
1850 x = A->p[i - 1];
1851 y = ( y << biH ) | ( x >> biH );
1852 z = y / b;
1853 y -= z * b;
1854
1855 x <<= biH;
1856 y = ( y << biH ) | ( x >> biH );
1857 z = y / b;
1858 y -= z * b;
1859 }
1860
1861 /*
1862 * If A is negative, then the current y represents a negative value.
1863 * Flipping it to the positive side.
1864 */
1865 if( A->s < 0 && y != 0 )
1866 y = b - y;
1867
1868 *r = y;
1869
1870 return( 0 );
1871}
1872
1873/*
1874 * Fast Montgomery initialization (thanks to Tom St Denis)
1875 */
Jerome Forissier84f74672020-03-30 17:42:28 +02001876static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
Jens Wiklander817466c2018-05-22 13:49:31 +02001877{
1878 mbedtls_mpi_uint x, m0 = N->p[0];
1879 unsigned int i;
1880
1881 x = m0;
1882 x += ( ( m0 + 2 ) & 4 ) << 1;
1883
1884 for( i = biL; i >= 8; i /= 2 )
1885 x *= ( 2 - ( m0 * x ) );
1886
1887 *mm = ~x + 1;
1888}
1889
1890/*
1891 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1892 */
Jerome Forissier84f74672020-03-30 17:42:28 +02001893static int mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
Jens Wiklander817466c2018-05-22 13:49:31 +02001894 const mbedtls_mpi *T )
1895{
1896 size_t i, n, m;
1897 mbedtls_mpi_uint u0, u1, *d;
1898
1899 if( T->n < N->n + 1 || T->p == NULL )
1900 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
1901
1902 memset( T->p, 0, T->n * ciL );
1903
1904 d = T->p;
1905 n = N->n;
1906 m = ( B->n < n ) ? B->n : n;
1907
1908 for( i = 0; i < n; i++ )
1909 {
1910 /*
1911 * T = (T + u0*B + u1*N) / 2^biL
1912 */
1913 u0 = A->p[i];
1914 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1915
1916 mpi_mul_hlp( m, B->p, d, u0 );
1917 mpi_mul_hlp( n, N->p, d, u1 );
1918
1919 *d++ = u0; d[n + 1] = 0;
1920 }
1921
1922 memcpy( A->p, d, ( n + 1 ) * ciL );
1923
1924 if( mbedtls_mpi_cmp_abs( A, N ) >= 0 )
1925 mpi_sub_hlp( n, N->p, A->p );
1926 else
1927 /* prevent timing attacks */
1928 mpi_sub_hlp( n, A->p, T->p );
1929
1930 return( 0 );
1931}
1932
1933/*
1934 * Montgomery reduction: A = A * R^-1 mod N
1935 */
Jerome Forissier84f74672020-03-30 17:42:28 +02001936static int mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
1937 mbedtls_mpi_uint mm, const mbedtls_mpi *T )
Jens Wiklander817466c2018-05-22 13:49:31 +02001938{
1939 mbedtls_mpi_uint z = 1;
1940 mbedtls_mpi U;
1941
1942 U.n = U.s = (int) z;
1943 U.p = &z;
1944
Jerome Forissier84f74672020-03-30 17:42:28 +02001945 return( mpi_montmul( A, &U, N, mm, T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001946}
1947
1948/*
1949 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1950 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001951int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
1952 const mbedtls_mpi *E, const mbedtls_mpi *N,
1953 mbedtls_mpi *_RR )
Jens Wiklander817466c2018-05-22 13:49:31 +02001954{
1955 int ret;
1956 size_t wbits, wsize, one = 1;
1957 size_t i, j, nblimbs;
1958 size_t bufsize, nbits;
1959 mbedtls_mpi_uint ei, mm, state;
Jerome Forissier84f74672020-03-30 17:42:28 +02001960 mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
Jens Wiklander817466c2018-05-22 13:49:31 +02001961 int neg;
1962
Jens Wiklander3d3b0592019-03-20 15:30:29 +01001963 MPI_VALIDATE_RET( X != NULL );
1964 MPI_VALIDATE_RET( A != NULL );
1965 MPI_VALIDATE_RET( E != NULL );
1966 MPI_VALIDATE_RET( N != NULL );
1967
1968 if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02001969 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
1970
1971 if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
1972 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
1973
1974 /*
1975 * Init temps and window size
1976 */
Jerome Forissier84f74672020-03-30 17:42:28 +02001977 mpi_montg_init( &mm, N );
1978 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T );
1979 mbedtls_mpi_init( &Apos );
1980 memset( W, 0, sizeof( W ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001981
1982 i = mbedtls_mpi_bitlen( E );
1983
1984 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1985 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1986
Jerome Forissier84f74672020-03-30 17:42:28 +02001987#if( MBEDTLS_MPI_WINDOW_SIZE < 6 )
Jens Wiklander817466c2018-05-22 13:49:31 +02001988 if( wsize > MBEDTLS_MPI_WINDOW_SIZE )
1989 wsize = MBEDTLS_MPI_WINDOW_SIZE;
Jerome Forissier84f74672020-03-30 17:42:28 +02001990#endif
Jens Wiklander817466c2018-05-22 13:49:31 +02001991
1992 j = N->n + 1;
1993 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
Jerome Forissier84f74672020-03-30 17:42:28 +02001994 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02001995 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
1996
1997 /*
1998 * Compensate for negative A (and correct at the end)
1999 */
2000 neg = ( A->s == -1 );
2001 if( neg )
2002 {
2003 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Apos, A ) );
2004 Apos.s = 1;
2005 A = &Apos;
2006 }
2007
2008 /*
2009 * If 1st call, pre-compute R^2 mod N
2010 */
2011 if( _RR == NULL || _RR->p == NULL )
2012 {
2013 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &RR, 1 ) );
2014 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &RR, N->n * 2 * biL ) );
2015 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) );
2016
2017 if( _RR != NULL )
2018 memcpy( _RR, &RR, sizeof( mbedtls_mpi ) );
2019 }
2020 else
2021 memcpy( &RR, _RR, sizeof( mbedtls_mpi ) );
2022
2023 /*
2024 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
2025 */
2026 if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 )
2027 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
2028 else
2029 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
2030
Jerome Forissier84f74672020-03-30 17:42:28 +02002031 MBEDTLS_MPI_CHK( mpi_montmul( &W[1], &RR, N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002032
2033 /*
2034 * X = R^2 * R^-1 mod N = R mod N
2035 */
2036 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) );
Jerome Forissier84f74672020-03-30 17:42:28 +02002037 MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002038
2039 if( wsize > 1 )
2040 {
2041 /*
2042 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
2043 */
2044 j = one << ( wsize - 1 );
2045
2046 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) );
2047 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) );
2048
2049 for( i = 0; i < wsize - 1; i++ )
Jerome Forissier84f74672020-03-30 17:42:28 +02002050 MBEDTLS_MPI_CHK( mpi_montmul( &W[j], &W[j], N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002051
2052 /*
2053 * W[i] = W[i - 1] * W[1]
2054 */
2055 for( i = j + 1; i < ( one << wsize ); i++ )
2056 {
2057 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) );
2058 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) );
2059
Jerome Forissier84f74672020-03-30 17:42:28 +02002060 MBEDTLS_MPI_CHK( mpi_montmul( &W[i], &W[1], N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002061 }
2062 }
2063
2064 nblimbs = E->n;
2065 bufsize = 0;
2066 nbits = 0;
2067 wbits = 0;
2068 state = 0;
2069
2070 while( 1 )
2071 {
2072 if( bufsize == 0 )
2073 {
2074 if( nblimbs == 0 )
2075 break;
2076
2077 nblimbs--;
2078
2079 bufsize = sizeof( mbedtls_mpi_uint ) << 3;
2080 }
2081
2082 bufsize--;
2083
2084 ei = (E->p[nblimbs] >> bufsize) & 1;
2085
2086 /*
2087 * skip leading 0s
2088 */
2089 if( ei == 0 && state == 0 )
2090 continue;
2091
2092 if( ei == 0 && state == 1 )
2093 {
2094 /*
2095 * out of window, square X
2096 */
Jerome Forissier84f74672020-03-30 17:42:28 +02002097 MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002098 continue;
2099 }
2100
2101 /*
2102 * add ei to current window
2103 */
2104 state = 2;
2105
2106 nbits++;
2107 wbits |= ( ei << ( wsize - nbits ) );
2108
2109 if( nbits == wsize )
2110 {
2111 /*
2112 * X = X^wsize R^-1 mod N
2113 */
2114 for( i = 0; i < wsize; i++ )
Jerome Forissier84f74672020-03-30 17:42:28 +02002115 MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002116
2117 /*
2118 * X = X * W[wbits] R^-1 mod N
2119 */
Jerome Forissier84f74672020-03-30 17:42:28 +02002120 MBEDTLS_MPI_CHK( mpi_montmul( X, &W[wbits], N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002121
2122 state--;
2123 nbits = 0;
2124 wbits = 0;
2125 }
2126 }
2127
2128 /*
2129 * process the remaining bits
2130 */
2131 for( i = 0; i < nbits; i++ )
2132 {
Jerome Forissier84f74672020-03-30 17:42:28 +02002133 MBEDTLS_MPI_CHK( mpi_montmul( X, X, N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002134
2135 wbits <<= 1;
2136
2137 if( ( wbits & ( one << wsize ) ) != 0 )
Jerome Forissier84f74672020-03-30 17:42:28 +02002138 MBEDTLS_MPI_CHK( mpi_montmul( X, &W[1], N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002139 }
2140
2141 /*
2142 * X = A^E * R * R^-1 mod N = A^E mod N
2143 */
Jerome Forissier84f74672020-03-30 17:42:28 +02002144 MBEDTLS_MPI_CHK( mpi_montred( X, N, mm, &T ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002145
2146 if( neg && E->n != 0 && ( E->p[0] & 1 ) != 0 )
2147 {
2148 X->s = -1;
2149 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) );
2150 }
2151
2152cleanup:
2153
Jerome Forissier84f74672020-03-30 17:42:28 +02002154 for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
2155 mbedtls_mpi_free( &W[i] );
Jens Wiklander817466c2018-05-22 13:49:31 +02002156
Jerome Forissier84f74672020-03-30 17:42:28 +02002157 mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
Jens Wiklander817466c2018-05-22 13:49:31 +02002158
2159 if( _RR == NULL || _RR->p == NULL )
2160 mbedtls_mpi_free( &RR );
2161
2162 return( ret );
2163}
2164
2165/*
2166 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
2167 */
2168int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B )
2169{
2170 int ret;
2171 size_t lz, lzt;
2172 mbedtls_mpi TG, TA, TB;
2173
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002174 MPI_VALIDATE_RET( G != NULL );
2175 MPI_VALIDATE_RET( A != NULL );
2176 MPI_VALIDATE_RET( B != NULL );
2177
Jerome Forissier84f74672020-03-30 17:42:28 +02002178 mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
Jens Wiklander817466c2018-05-22 13:49:31 +02002179
2180 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) );
2181 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
2182
2183 lz = mbedtls_mpi_lsb( &TA );
2184 lzt = mbedtls_mpi_lsb( &TB );
2185
2186 if( lzt < lz )
2187 lz = lzt;
2188
2189 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, lz ) );
2190 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, lz ) );
2191
2192 TA.s = TB.s = 1;
2193
2194 while( mbedtls_mpi_cmp_int( &TA, 0 ) != 0 )
2195 {
2196 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, mbedtls_mpi_lsb( &TA ) ) );
2197 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, mbedtls_mpi_lsb( &TB ) ) );
2198
2199 if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 )
2200 {
2201 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TA, &TA, &TB ) );
2202 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, 1 ) );
2203 }
2204 else
2205 {
2206 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TB, &TB, &TA ) );
2207 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, 1 ) );
2208 }
2209 }
2210
2211 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &TB, lz ) );
2212 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( G, &TB ) );
2213
2214cleanup:
2215
2216 mbedtls_mpi_free( &TG ); mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB );
2217
2218 return( ret );
2219}
2220
2221/*
2222 * Fill X with size bytes of random.
2223 *
2224 * Use a temporary bytes representation to make sure the result is the same
2225 * regardless of the platform endianness (useful when f_rng is actually
2226 * deterministic, eg for tests).
2227 */
2228int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
2229 int (*f_rng)(void *, unsigned char *, size_t),
2230 void *p_rng )
2231{
2232 int ret;
Jerome Forissier84f74672020-03-30 17:42:28 +02002233 size_t const limbs = CHARS_TO_LIMBS( size );
2234 size_t const overhead = ( limbs * ciL ) - size;
2235 unsigned char *Xp;
2236
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002237 MPI_VALIDATE_RET( X != NULL );
2238 MPI_VALIDATE_RET( f_rng != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002239
Jerome Forissier84f74672020-03-30 17:42:28 +02002240 /* Ensure that target MPI has exactly the necessary number of limbs */
2241 if( X->n != limbs )
2242 {
2243 mbedtls_mpi_free( X );
2244 mbedtls_mpi_init( X );
2245 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, limbs ) );
2246 }
2247 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002248
Jerome Forissier84f74672020-03-30 17:42:28 +02002249 Xp = (unsigned char*) X->p;
2250 f_rng( p_rng, Xp + overhead, size );
2251
2252 mpi_bigendian_to_host( X->p, limbs );
Jens Wiklander817466c2018-05-22 13:49:31 +02002253
2254cleanup:
2255 return( ret );
2256}
2257
2258/*
2259 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
2260 */
2261int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N )
2262{
2263 int ret;
2264 mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002265 MPI_VALIDATE_RET( X != NULL );
2266 MPI_VALIDATE_RET( A != NULL );
2267 MPI_VALIDATE_RET( N != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002268
2269 if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 )
2270 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2271
Jerome Forissier84f74672020-03-30 17:42:28 +02002272 mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TU ); mbedtls_mpi_init( &U1 ); mbedtls_mpi_init( &U2 );
2273 mbedtls_mpi_init( &G ); mbedtls_mpi_init( &TB ); mbedtls_mpi_init( &TV );
2274 mbedtls_mpi_init( &V1 ); mbedtls_mpi_init( &V2 );
Jens Wiklander817466c2018-05-22 13:49:31 +02002275
2276 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, A, N ) );
2277
2278 if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
2279 {
2280 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2281 goto cleanup;
2282 }
2283
2284 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &TA, A, N ) );
2285 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TU, &TA ) );
2286 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, N ) );
2287 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TV, N ) );
2288
2289 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U1, 1 ) );
2290 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U2, 0 ) );
2291 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V1, 0 ) );
2292 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V2, 1 ) );
2293
2294 do
2295 {
2296 while( ( TU.p[0] & 1 ) == 0 )
2297 {
2298 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TU, 1 ) );
2299
2300 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
2301 {
2302 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &U1, &U1, &TB ) );
2303 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &TA ) );
2304 }
2305
2306 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U1, 1 ) );
2307 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U2, 1 ) );
2308 }
2309
2310 while( ( TV.p[0] & 1 ) == 0 )
2311 {
2312 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TV, 1 ) );
2313
2314 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
2315 {
2316 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, &TB ) );
2317 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &TA ) );
2318 }
2319
2320 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V1, 1 ) );
2321 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V2, 1 ) );
2322 }
2323
2324 if( mbedtls_mpi_cmp_mpi( &TU, &TV ) >= 0 )
2325 {
2326 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TU, &TU, &TV ) );
2327 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U1, &U1, &V1 ) );
2328 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &V2 ) );
2329 }
2330 else
2331 {
2332 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TV, &TV, &TU ) );
2333 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, &U1 ) );
2334 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &U2 ) );
2335 }
2336 }
2337 while( mbedtls_mpi_cmp_int( &TU, 0 ) != 0 );
2338
2339 while( mbedtls_mpi_cmp_int( &V1, 0 ) < 0 )
2340 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, N ) );
2341
2342 while( mbedtls_mpi_cmp_mpi( &V1, N ) >= 0 )
2343 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, N ) );
2344
2345 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &V1 ) );
2346
2347cleanup:
2348
2349 mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TU ); mbedtls_mpi_free( &U1 ); mbedtls_mpi_free( &U2 );
2350 mbedtls_mpi_free( &G ); mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TV );
2351 mbedtls_mpi_free( &V1 ); mbedtls_mpi_free( &V2 );
2352
2353 return( ret );
2354}
2355
2356#if defined(MBEDTLS_GENPRIME)
2357
2358static const int small_prime[] =
2359{
2360 3, 5, 7, 11, 13, 17, 19, 23,
2361 29, 31, 37, 41, 43, 47, 53, 59,
2362 61, 67, 71, 73, 79, 83, 89, 97,
2363 101, 103, 107, 109, 113, 127, 131, 137,
2364 139, 149, 151, 157, 163, 167, 173, 179,
2365 181, 191, 193, 197, 199, 211, 223, 227,
2366 229, 233, 239, 241, 251, 257, 263, 269,
2367 271, 277, 281, 283, 293, 307, 311, 313,
2368 317, 331, 337, 347, 349, 353, 359, 367,
2369 373, 379, 383, 389, 397, 401, 409, 419,
2370 421, 431, 433, 439, 443, 449, 457, 461,
2371 463, 467, 479, 487, 491, 499, 503, 509,
2372 521, 523, 541, 547, 557, 563, 569, 571,
2373 577, 587, 593, 599, 601, 607, 613, 617,
2374 619, 631, 641, 643, 647, 653, 659, 661,
2375 673, 677, 683, 691, 701, 709, 719, 727,
2376 733, 739, 743, 751, 757, 761, 769, 773,
2377 787, 797, 809, 811, 821, 823, 827, 829,
2378 839, 853, 857, 859, 863, 877, 881, 883,
2379 887, 907, 911, 919, 929, 937, 941, 947,
2380 953, 967, 971, 977, 983, 991, 997, -103
2381};
2382
2383/*
2384 * Small divisors test (X must be positive)
2385 *
2386 * Return values:
2387 * 0: no small factor (possible prime, more tests needed)
2388 * 1: certain prime
2389 * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
2390 * other negative: error
2391 */
2392static int mpi_check_small_factors( const mbedtls_mpi *X )
2393{
2394 int ret = 0;
2395 size_t i;
2396 mbedtls_mpi_uint r;
2397
2398 if( ( X->p[0] & 1 ) == 0 )
2399 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
2400
2401 for( i = 0; small_prime[i] > 0; i++ )
2402 {
2403 if( mbedtls_mpi_cmp_int( X, small_prime[i] ) <= 0 )
2404 return( 1 );
2405
2406 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, small_prime[i] ) );
2407
2408 if( r == 0 )
2409 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
2410 }
2411
2412cleanup:
2413 return( ret );
2414}
2415
2416/*
2417 * Miller-Rabin pseudo-primality test (HAC 4.24)
2418 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002419static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds,
Jens Wiklander817466c2018-05-22 13:49:31 +02002420 int (*f_rng)(void *, unsigned char *, size_t),
2421 void *p_rng )
2422{
2423 int ret, count;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002424 size_t i, j, k, s;
Jens Wiklander817466c2018-05-22 13:49:31 +02002425 mbedtls_mpi W, R, T, A, RR;
2426
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002427 MPI_VALIDATE_RET( X != NULL );
2428 MPI_VALIDATE_RET( f_rng != NULL );
2429
Jerome Forissier84f74672020-03-30 17:42:28 +02002430 mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R );
2431 mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A );
2432 mbedtls_mpi_init( &RR );
Jens Wiklander817466c2018-05-22 13:49:31 +02002433
2434 /*
2435 * W = |X| - 1
2436 * R = W >> lsb( W )
2437 */
2438 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &W, X, 1 ) );
2439 s = mbedtls_mpi_lsb( &W );
2440 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R, &W ) );
2441 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) );
2442
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002443 for( i = 0; i < rounds; i++ )
Jens Wiklander817466c2018-05-22 13:49:31 +02002444 {
2445 /*
2446 * pick a random A, 1 < A < |X| - 1
2447 */
Jens Wiklander817466c2018-05-22 13:49:31 +02002448 count = 0;
2449 do {
2450 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
2451
2452 j = mbedtls_mpi_bitlen( &A );
2453 k = mbedtls_mpi_bitlen( &W );
2454 if (j > k) {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002455 A.p[A.n - 1] &= ( (mbedtls_mpi_uint) 1 << ( k - ( A.n - 1 ) * biL - 1 ) ) - 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02002456 }
2457
Jerome Forissier84f74672020-03-30 17:42:28 +02002458 if (count++ > 30) {
Jens Wiklander336e3292019-01-17 11:14:38 +01002459 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2460 goto cleanup;
Jens Wiklander817466c2018-05-22 13:49:31 +02002461 }
2462
2463 } while ( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 ||
2464 mbedtls_mpi_cmp_int( &A, 1 ) <= 0 );
2465
2466 /*
2467 * A = A^R mod |X|
2468 */
2469 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &A, &A, &R, X, &RR ) );
2470
2471 if( mbedtls_mpi_cmp_mpi( &A, &W ) == 0 ||
2472 mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
2473 continue;
2474
2475 j = 1;
2476 while( j < s && mbedtls_mpi_cmp_mpi( &A, &W ) != 0 )
2477 {
2478 /*
2479 * A = A * A mod |X|
2480 */
2481 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &A, &A ) );
2482 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &A, &T, X ) );
2483
2484 if( mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
2485 break;
2486
2487 j++;
2488 }
2489
2490 /*
2491 * not prime if A != |X| - 1 or A == 1
2492 */
2493 if( mbedtls_mpi_cmp_mpi( &A, &W ) != 0 ||
2494 mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
2495 {
2496 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2497 break;
2498 }
2499 }
2500
2501cleanup:
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002502 mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R );
2503 mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A );
Jens Wiklander817466c2018-05-22 13:49:31 +02002504 mbedtls_mpi_free( &RR );
2505
2506 return( ret );
2507}
2508
2509/*
2510 * Pseudo-primality test: small factors, then Miller-Rabin
2511 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002512int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds,
2513 int (*f_rng)(void *, unsigned char *, size_t),
2514 void *p_rng )
Jens Wiklander817466c2018-05-22 13:49:31 +02002515{
2516 int ret;
2517 mbedtls_mpi XX;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002518 MPI_VALIDATE_RET( X != NULL );
2519 MPI_VALIDATE_RET( f_rng != NULL );
Jens Wiklander817466c2018-05-22 13:49:31 +02002520
2521 XX.s = 1;
2522 XX.n = X->n;
2523 XX.p = X->p;
2524
2525 if( mbedtls_mpi_cmp_int( &XX, 0 ) == 0 ||
2526 mbedtls_mpi_cmp_int( &XX, 1 ) == 0 )
2527 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
2528
2529 if( mbedtls_mpi_cmp_int( &XX, 2 ) == 0 )
2530 return( 0 );
2531
2532 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2533 {
2534 if( ret == 1 )
2535 return( 0 );
2536
2537 return( ret );
2538 }
2539
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002540 return( mpi_miller_rabin( &XX, rounds, f_rng, p_rng ) );
Jens Wiklander817466c2018-05-22 13:49:31 +02002541}
2542
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002543#if !defined(MBEDTLS_DEPRECATED_REMOVED)
2544/*
2545 * Pseudo-primality test, error probability 2^-80
2546 */
2547int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
2548 int (*f_rng)(void *, unsigned char *, size_t),
2549 void *p_rng )
2550{
2551 MPI_VALIDATE_RET( X != NULL );
2552 MPI_VALIDATE_RET( f_rng != NULL );
2553
2554 /*
2555 * In the past our key generation aimed for an error rate of at most
2556 * 2^-80. Since this function is deprecated, aim for the same certainty
2557 * here as well.
2558 */
2559 return( mbedtls_mpi_is_prime_ext( X, 40, f_rng, p_rng ) );
2560}
2561#endif
2562
Jens Wiklander817466c2018-05-22 13:49:31 +02002563/*
2564 * Prime number generation
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002565 *
2566 * To generate an RSA key in a way recommended by FIPS 186-4, both primes must
2567 * be either 1024 bits or 1536 bits long, and flags must contain
2568 * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR.
Jens Wiklander817466c2018-05-22 13:49:31 +02002569 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002570int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags,
Jens Wiklander817466c2018-05-22 13:49:31 +02002571 int (*f_rng)(void *, unsigned char *, size_t),
2572 void *p_rng )
2573{
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002574#ifdef MBEDTLS_HAVE_INT64
2575// ceil(2^63.5)
2576#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL
2577#else
2578// ceil(2^31.5)
2579#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U
2580#endif
2581 int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
Jens Wiklander817466c2018-05-22 13:49:31 +02002582 size_t k, n;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002583 int rounds;
Jens Wiklander817466c2018-05-22 13:49:31 +02002584 mbedtls_mpi_uint r;
2585 mbedtls_mpi Y;
2586
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002587 MPI_VALIDATE_RET( X != NULL );
2588 MPI_VALIDATE_RET( f_rng != NULL );
2589
Jens Wiklander817466c2018-05-22 13:49:31 +02002590 if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS )
2591 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2592
Jerome Forissier84f74672020-03-30 17:42:28 +02002593 mbedtls_mpi_init( &Y );
Jens Wiklander817466c2018-05-22 13:49:31 +02002594
2595 n = BITS_TO_LIMBS( nbits );
2596
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002597 if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR ) == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02002598 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002599 /*
2600 * 2^-80 error probability, number of rounds chosen per HAC, table 4.4
2601 */
2602 rounds = ( ( nbits >= 1300 ) ? 2 : ( nbits >= 850 ) ? 3 :
2603 ( nbits >= 650 ) ? 4 : ( nbits >= 350 ) ? 8 :
2604 ( nbits >= 250 ) ? 12 : ( nbits >= 150 ) ? 18 : 27 );
Jens Wiklander817466c2018-05-22 13:49:31 +02002605 }
2606 else
2607 {
2608 /*
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002609 * 2^-100 error probability, number of rounds computed based on HAC,
2610 * fact 4.48
Jens Wiklander817466c2018-05-22 13:49:31 +02002611 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002612 rounds = ( ( nbits >= 1450 ) ? 4 : ( nbits >= 1150 ) ? 5 :
2613 ( nbits >= 1000 ) ? 6 : ( nbits >= 850 ) ? 7 :
2614 ( nbits >= 750 ) ? 8 : ( nbits >= 500 ) ? 13 :
2615 ( nbits >= 250 ) ? 28 : ( nbits >= 150 ) ? 40 : 51 );
2616 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002617
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002618 while( 1 )
2619 {
2620 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
2621 /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */
2622 if( X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2 ) continue;
Jens Wiklander817466c2018-05-22 13:49:31 +02002623
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002624 k = n * biL;
2625 if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits ) );
2626 X->p[0] |= 1;
Jens Wiklander817466c2018-05-22 13:49:31 +02002627
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002628 if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH ) == 0 )
Jens Wiklander817466c2018-05-22 13:49:31 +02002629 {
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002630 ret = mbedtls_mpi_is_prime_ext( X, rounds, f_rng, p_rng );
Jens Wiklander817466c2018-05-22 13:49:31 +02002631
2632 if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
2633 goto cleanup;
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002634 }
2635 else
2636 {
Jens Wiklander817466c2018-05-22 13:49:31 +02002637 /*
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002638 * An necessary condition for Y and X = 2Y + 1 to be prime
2639 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2640 * Make sure it is satisfied, while keeping X = 3 mod 4
Jens Wiklander817466c2018-05-22 13:49:31 +02002641 */
Jens Wiklander3d3b0592019-03-20 15:30:29 +01002642
2643 X->p[0] |= 2;
2644
2645 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) );
2646 if( r == 0 )
2647 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) );
2648 else if( r == 1 )
2649 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) );
2650
2651 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2652 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) );
2653 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) );
2654
2655 while( 1 )
2656 {
2657 /*
2658 * First, check small factors for X and Y
2659 * before doing Miller-Rabin on any of them
2660 */
2661 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2662 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2663 ( ret = mpi_miller_rabin( X, rounds, f_rng, p_rng ) )
2664 == 0 &&
2665 ( ret = mpi_miller_rabin( &Y, rounds, f_rng, p_rng ) )
2666 == 0 )
2667 goto cleanup;
2668
2669 if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
2670 goto cleanup;
2671
2672 /*
2673 * Next candidates. We want to preserve Y = (X-1) / 2 and
2674 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2675 * so up Y by 6 and X by 12.
2676 */
2677 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 12 ) );
2678 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) );
2679 }
Jens Wiklander817466c2018-05-22 13:49:31 +02002680 }
2681 }
2682
2683cleanup:
2684
2685 mbedtls_mpi_free( &Y );
2686
2687 return( ret );
2688}
2689
2690#endif /* MBEDTLS_GENPRIME */
2691
2692#if defined(MBEDTLS_SELF_TEST)
2693
2694#define GCD_PAIR_COUNT 3
2695
2696static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2697{
2698 { 693, 609, 21 },
2699 { 1764, 868, 28 },
2700 { 768454923, 542167814, 1 }
2701};
2702
2703/*
2704 * Checkup routine
2705 */
2706int mbedtls_mpi_self_test( int verbose )
2707{
2708 int ret, i;
2709 mbedtls_mpi A, E, N, X, Y, U, V;
2710
Jerome Forissier84f74672020-03-30 17:42:28 +02002711 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N ); mbedtls_mpi_init( &X );
2712 mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &U ); mbedtls_mpi_init( &V );
Jens Wiklander817466c2018-05-22 13:49:31 +02002713
2714 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &A, 16,
2715 "EFE021C2645FD1DC586E69184AF4A31E" \
2716 "D5F53E93B5F123FA41680867BA110131" \
2717 "944FE7952E2517337780CB0DB80E61AA" \
2718 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2719
2720 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &E, 16,
2721 "B2E7EFD37075B9F03FF989C7C5051C20" \
2722 "34D2A323810251127E7BF8625A4F49A5" \
2723 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2724 "5B5C25763222FEFCCFC38B832366C29E" ) );
2725
2726 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &N, 16,
2727 "0066A198186C18C10B2F5ED9B522752A" \
2728 "9830B69916E535C8F047518A889A43A5" \
2729 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2730
2731 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &A, &N ) );
2732
2733 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
2734 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2735 "9E857EA95A03512E2BAE7391688D264A" \
2736 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2737 "8001B72E848A38CAE1C65F78E56ABDEF" \
2738 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2739 "ECF677152EF804370C1A305CAF3B5BF1" \
2740 "30879B56C61DE584A0F53A2447A51E" ) );
2741
2742 if( verbose != 0 )
2743 mbedtls_printf( " MPI test #1 (mul_mpi): " );
2744
2745 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
2746 {
2747 if( verbose != 0 )
2748 mbedtls_printf( "failed\n" );
2749
2750 ret = 1;
2751 goto cleanup;
2752 }
2753
2754 if( verbose != 0 )
2755 mbedtls_printf( "passed\n" );
2756
2757 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &X, &Y, &A, &N ) );
2758
2759 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
2760 "256567336059E52CAE22925474705F39A94" ) );
2761
2762 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &V, 16,
2763 "6613F26162223DF488E9CD48CC132C7A" \
2764 "0AC93C701B001B092E4E5B9F73BCD27B" \
2765 "9EE50D0657C77F374E903CDFA4C642" ) );
2766
2767 if( verbose != 0 )
2768 mbedtls_printf( " MPI test #2 (div_mpi): " );
2769
2770 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ||
2771 mbedtls_mpi_cmp_mpi( &Y, &V ) != 0 )
2772 {
2773 if( verbose != 0 )
2774 mbedtls_printf( "failed\n" );
2775
2776 ret = 1;
2777 goto cleanup;
2778 }
2779
2780 if( verbose != 0 )
2781 mbedtls_printf( "passed\n" );
2782
2783 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2784
2785 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
2786 "36E139AEA55215609D2816998ED020BB" \
2787 "BD96C37890F65171D948E9BC7CBAA4D9" \
2788 "325D24D6A3C12710F10A09FA08AB87" ) );
2789
2790 if( verbose != 0 )
2791 mbedtls_printf( " MPI test #3 (exp_mod): " );
2792
2793 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
2794 {
2795 if( verbose != 0 )
2796 mbedtls_printf( "failed\n" );
2797
2798 ret = 1;
2799 goto cleanup;
2800 }
2801
2802 if( verbose != 0 )
2803 mbedtls_printf( "passed\n" );
2804
2805 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &X, &A, &N ) );
2806
2807 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
2808 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2809 "C3DBA76456363A10869622EAC2DD84EC" \
2810 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2811
2812 if( verbose != 0 )
2813 mbedtls_printf( " MPI test #4 (inv_mod): " );
2814
2815 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
2816 {
2817 if( verbose != 0 )
2818 mbedtls_printf( "failed\n" );
2819
2820 ret = 1;
2821 goto cleanup;
2822 }
2823
2824 if( verbose != 0 )
2825 mbedtls_printf( "passed\n" );
2826
2827 if( verbose != 0 )
2828 mbedtls_printf( " MPI test #5 (simple gcd): " );
2829
2830 for( i = 0; i < GCD_PAIR_COUNT; i++ )
2831 {
2832 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &X, gcd_pairs[i][0] ) );
2833 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Y, gcd_pairs[i][1] ) );
2834
2835 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &A, &X, &Y ) );
2836
2837 if( mbedtls_mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2838 {
2839 if( verbose != 0 )
2840 mbedtls_printf( "failed at %d\n", i );
2841
2842 ret = 1;
2843 goto cleanup;
2844 }
2845 }
2846
2847 if( verbose != 0 )
2848 mbedtls_printf( "passed\n" );
2849
2850cleanup:
2851
2852 if( ret != 0 && verbose != 0 )
2853 mbedtls_printf( "Unexpected error, return code = %08X\n", ret );
2854
2855 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N ); mbedtls_mpi_free( &X );
2856 mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &U ); mbedtls_mpi_free( &V );
2857
2858 if( verbose != 0 )
2859 mbedtls_printf( "\n" );
2860
2861 return( ret );
2862}
2863
2864#endif /* MBEDTLS_SELF_TEST */
2865
2866#endif /* MBEDTLS_BIGNUM_C */