blob: 9c6a91dc7ff4907e01d80f79d94cdb27610787a3 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Multi-precision integer library
3 *
Bence Szépkúti1e148272020-08-07 13:07:28 +02004 * Copyright The Mbed TLS Contributors
Manuel Pégourié-Gonnard37ff1402015-09-04 14:21:07 +02005 * SPDX-License-Identifier: Apache-2.0
6 *
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.
Paul Bakker5121ce52009-01-03 21:22:43 +000018 */
Simon Butcher15b15d12015-11-26 19:35:03 +000019
Paul Bakker5121ce52009-01-03 21:22:43 +000020/*
Simon Butcher15b15d12015-11-26 19:35:03 +000021 * The following sources were referenced in the design of this Multi-precision
22 * Integer library:
Paul Bakker5121ce52009-01-03 21:22:43 +000023 *
Simon Butcher15b15d12015-11-26 19:35:03 +000024 * [1] Handbook of Applied Cryptography - 1997
25 * Menezes, van Oorschot and Vanstone
26 *
27 * [2] Multi-Precision Math
28 * Tom St Denis
29 * https://github.com/libtom/libtommath/blob/develop/tommath.pdf
30 *
31 * [3] GNU Multi-Precision Arithmetic Library
32 * https://gmplib.org/manual/index.html
33 *
Simon Butcherf5ba0452015-12-27 23:01:55 +000034 */
Paul Bakker5121ce52009-01-03 21:22:43 +000035
Gilles Peskinedb09ef62020-06-03 01:43:33 +020036#include "common.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000037
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020038#if defined(MBEDTLS_BIGNUM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000039
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000040#include "mbedtls/bignum.h"
41#include "mbedtls/bn_mul.h"
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050042#include "mbedtls/platform_util.h"
Janos Follath24eed8d2019-11-22 13:21:35 +000043#include "mbedtls/error.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000044
Rich Evans00ab4702015-02-06 13:43:58 +000045#include <string.h>
46
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020047#if defined(MBEDTLS_PLATFORM_C)
Manuel Pégourié-Gonnard7f809972015-03-09 17:05:11 +000048#include "mbedtls/platform.h"
Paul Bakker6e339b52013-07-03 13:37:05 +020049#else
Rich Evans00ab4702015-02-06 13:43:58 +000050#include <stdio.h>
51#include <stdlib.h>
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020052#define mbedtls_printf printf
Manuel Pégourié-Gonnard7551cb92015-05-26 16:04:06 +020053#define mbedtls_calloc calloc
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020054#define mbedtls_free free
Paul Bakker6e339b52013-07-03 13:37:05 +020055#endif
56
Hanno Becker73d7d792018-12-11 10:35:51 +000057#define MPI_VALIDATE_RET( cond ) \
58 MBEDTLS_INTERNAL_VALIDATE_RET( cond, MBEDTLS_ERR_MPI_BAD_INPUT_DATA )
59#define MPI_VALIDATE( cond ) \
60 MBEDTLS_INTERNAL_VALIDATE( cond )
61
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020062#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
Paul Bakker5121ce52009-01-03 21:22:43 +000063#define biL (ciL << 3) /* bits in limb */
64#define biH (ciL << 2) /* half limb size */
65
Manuel Pégourié-Gonnard2d708342015-10-05 15:23:11 +010066#define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
67
Paul Bakker5121ce52009-01-03 21:22:43 +000068/*
69 * Convert between bits/chars and number of limbs
Manuel Pégourié-Gonnard58fb4952015-09-28 13:48:04 +020070 * Divide first in order to avoid potential overflows
Paul Bakker5121ce52009-01-03 21:22:43 +000071 */
Manuel Pégourié-Gonnard58fb4952015-09-28 13:48:04 +020072#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
73#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
Paul Bakker5121ce52009-01-03 21:22:43 +000074
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050075/* Implementation that should never be optimized out by the compiler */
Andres Amaya Garcia6698d2f2018-04-24 08:39:07 -050076static void mbedtls_mpi_zeroize( mbedtls_mpi_uint *v, size_t n )
77{
Andres Amaya Garcia1f6301b2018-04-17 09:51:09 -050078 mbedtls_platform_zeroize( v, ciL * n );
79}
80
Paul Bakker5121ce52009-01-03 21:22:43 +000081/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000082 * Initialize one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000083 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020084void mbedtls_mpi_init( mbedtls_mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000085{
Hanno Becker73d7d792018-12-11 10:35:51 +000086 MPI_VALIDATE( X != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +000087
Paul Bakker6c591fa2011-05-05 11:49:20 +000088 X->s = 1;
89 X->n = 0;
90 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +000091}
92
93/*
Paul Bakker6c591fa2011-05-05 11:49:20 +000094 * Unallocate one MPI
Paul Bakker5121ce52009-01-03 21:22:43 +000095 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +020096void mbedtls_mpi_free( mbedtls_mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +000097{
Paul Bakker6c591fa2011-05-05 11:49:20 +000098 if( X == NULL )
99 return;
Paul Bakker5121ce52009-01-03 21:22:43 +0000100
Paul Bakker6c591fa2011-05-05 11:49:20 +0000101 if( X->p != NULL )
Paul Bakker5121ce52009-01-03 21:22:43 +0000102 {
Alexey Skalozube17a8da2016-01-13 17:19:33 +0200103 mbedtls_mpi_zeroize( X->p, X->n );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200104 mbedtls_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000105 }
106
Paul Bakker6c591fa2011-05-05 11:49:20 +0000107 X->s = 1;
108 X->n = 0;
109 X->p = NULL;
Paul Bakker5121ce52009-01-03 21:22:43 +0000110}
111
112/*
113 * Enlarge to the specified number of limbs
114 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200115int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs )
Paul Bakker5121ce52009-01-03 21:22:43 +0000116{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200117 mbedtls_mpi_uint *p;
Hanno Becker73d7d792018-12-11 10:35:51 +0000118 MPI_VALIDATE_RET( X != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000119
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200120 if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200121 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
Paul Bakkerf9688572011-05-05 10:00:45 +0000122
Paul Bakker5121ce52009-01-03 21:22:43 +0000123 if( X->n < nblimbs )
124 {
Simon Butcher29176892016-05-20 00:19:09 +0100125 if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( nblimbs, ciL ) ) == NULL )
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200126 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
Paul Bakker5121ce52009-01-03 21:22:43 +0000127
Paul Bakker5121ce52009-01-03 21:22:43 +0000128 if( X->p != NULL )
129 {
130 memcpy( p, X->p, X->n * ciL );
Alexey Skalozube17a8da2016-01-13 17:19:33 +0200131 mbedtls_mpi_zeroize( X->p, X->n );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200132 mbedtls_free( X->p );
Paul Bakker5121ce52009-01-03 21:22:43 +0000133 }
134
135 X->n = nblimbs;
136 X->p = p;
137 }
138
139 return( 0 );
140}
141
142/*
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100143 * Resize down as much as possible,
144 * while keeping at least the specified number of limbs
145 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200146int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs )
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100147{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200148 mbedtls_mpi_uint *p;
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100149 size_t i;
Hanno Becker73d7d792018-12-11 10:35:51 +0000150 MPI_VALIDATE_RET( X != NULL );
151
152 if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
153 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100154
Gilles Peskinee2f563e2020-01-20 21:17:43 +0100155 /* Actually resize up if there are currently fewer than nblimbs limbs. */
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100156 if( X->n <= nblimbs )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200157 return( mbedtls_mpi_grow( X, nblimbs ) );
Gilles Peskine322752b2020-01-21 13:59:51 +0100158 /* After this point, then X->n > nblimbs and in particular X->n > 0. */
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100159
160 for( i = X->n - 1; i > 0; i-- )
161 if( X->p[i] != 0 )
162 break;
163 i++;
164
165 if( i < nblimbs )
166 i = nblimbs;
167
Simon Butcher29176892016-05-20 00:19:09 +0100168 if( ( p = (mbedtls_mpi_uint*)mbedtls_calloc( i, ciL ) ) == NULL )
Manuel Pégourié-Gonnard6a8ca332015-05-28 09:33:39 +0200169 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100170
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100171 if( X->p != NULL )
172 {
173 memcpy( p, X->p, i * ciL );
Alexey Skalozube17a8da2016-01-13 17:19:33 +0200174 mbedtls_mpi_zeroize( X->p, X->n );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200175 mbedtls_free( X->p );
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100176 }
177
178 X->n = i;
179 X->p = p;
180
181 return( 0 );
182}
183
Gilles Peskine3130ce22021-06-02 22:17:52 +0200184/* Resize X to have exactly n limbs and set it to 0. */
185static int mbedtls_mpi_resize_clear( mbedtls_mpi *X, size_t limbs )
186{
187 if( limbs == 0 )
188 {
189 mbedtls_mpi_free( X );
190 return( 0 );
191 }
192 else if( X->n == limbs )
193 {
194 memset( X->p, 0, limbs * ciL );
195 X->s = 1;
196 return( 0 );
197 }
198 else
199 {
200 mbedtls_mpi_free( X );
201 return( mbedtls_mpi_grow( X, limbs ) );
202 }
203}
204
Manuel Pégourié-Gonnard58681632013-11-21 10:39:37 +0100205/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000206 * Copy the contents of Y into X
207 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200208int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000209{
Gilles Peskine4e4be7c2018-03-21 16:29:03 +0100210 int ret = 0;
Paul Bakker23986e52011-04-24 08:57:21 +0000211 size_t i;
Hanno Becker73d7d792018-12-11 10:35:51 +0000212 MPI_VALIDATE_RET( X != NULL );
213 MPI_VALIDATE_RET( Y != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000214
215 if( X == Y )
216 return( 0 );
217
Gilles Peskinedb420622020-01-20 21:12:50 +0100218 if( Y->n == 0 )
Manuel Pégourié-Gonnardf4999932013-08-12 17:02:59 +0200219 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200220 mbedtls_mpi_free( X );
Manuel Pégourié-Gonnardf4999932013-08-12 17:02:59 +0200221 return( 0 );
222 }
223
Paul Bakker5121ce52009-01-03 21:22:43 +0000224 for( i = Y->n - 1; i > 0; i-- )
225 if( Y->p[i] != 0 )
226 break;
227 i++;
228
229 X->s = Y->s;
230
Gilles Peskine4e4be7c2018-03-21 16:29:03 +0100231 if( X->n < i )
232 {
233 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) );
234 }
235 else
236 {
237 memset( X->p + i, 0, ( X->n - i ) * ciL );
238 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000239
Paul Bakker5121ce52009-01-03 21:22:43 +0000240 memcpy( X->p, Y->p, i * ciL );
241
242cleanup:
243
244 return( ret );
245}
246
247/*
248 * Swap the contents of X and Y
249 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200250void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +0000251{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200252 mbedtls_mpi T;
Hanno Becker73d7d792018-12-11 10:35:51 +0000253 MPI_VALIDATE( X != NULL );
254 MPI_VALIDATE( Y != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000255
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200256 memcpy( &T, X, sizeof( mbedtls_mpi ) );
257 memcpy( X, Y, sizeof( mbedtls_mpi ) );
258 memcpy( Y, &T, sizeof( mbedtls_mpi ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000259}
260
261/*
Gilles Peskinef04d11e2020-06-04 19:14:58 +0200262 * Conditionally assign dest = src, without leaking information
263 * about whether the assignment was made or not.
264 * dest and src must be arrays of limbs of size n.
265 * assign must be 0 or 1.
266 */
267static void mpi_safe_cond_assign( size_t n,
268 mbedtls_mpi_uint *dest,
269 const mbedtls_mpi_uint *src,
270 unsigned char assign )
271{
272 size_t i;
Manuel Pégourié-Gonnardc3be3992021-05-31 11:48:45 +0200273
274 /* MSVC has a warning about unary minus on unsigned integer types,
275 * but this is well-defined and precisely what we want to do here. */
276#if defined(_MSC_VER)
277#pragma warning( push )
278#pragma warning( disable : 4146 )
279#endif
280
281 /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
282 const mbedtls_mpi_uint mask = -assign;
283
284#if defined(_MSC_VER)
285#pragma warning( pop )
286#endif
287
Gilles Peskinef04d11e2020-06-04 19:14:58 +0200288 for( i = 0; i < n; i++ )
Manuel Pégourié-Gonnardc3be3992021-05-31 11:48:45 +0200289 dest[i] = ( src[i] & mask ) | ( dest[i] & ~mask );
Gilles Peskinef04d11e2020-06-04 19:14:58 +0200290}
291
292/*
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100293 * Conditionally assign X = Y, without leaking information
Manuel Pégourié-Gonnard96c7a922013-11-25 18:28:53 +0100294 * about whether the assignment was made or not.
295 * (Leaking information about the respective sizes of X and Y is ok however.)
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100296 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200297int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign )
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100298{
299 int ret = 0;
300 size_t i;
Manuel Pégourié-Gonnardc3be3992021-05-31 11:48:45 +0200301 unsigned int mask;
302 mbedtls_mpi_uint limb_mask;
Hanno Becker73d7d792018-12-11 10:35:51 +0000303 MPI_VALIDATE_RET( X != NULL );
304 MPI_VALIDATE_RET( Y != NULL );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100305
Manuel Pégourié-Gonnardc3be3992021-05-31 11:48:45 +0200306 /* MSVC has a warning about unary minus on unsigned integer types,
307 * but this is well-defined and precisely what we want to do here. */
308#if defined(_MSC_VER)
309#pragma warning( push )
310#pragma warning( disable : 4146 )
311#endif
312
Pascal Junodb99183d2015-03-11 16:49:45 +0100313 /* make sure assign is 0 or 1 in a time-constant manner */
314 assign = (assign | (unsigned char)-assign) >> 7;
Manuel Pégourié-Gonnardc3be3992021-05-31 11:48:45 +0200315 /* all-bits 1 if assign is 1, all-bits 0 if assign is 0 */
316 mask = -assign;
317 limb_mask = -assign;
318
319#if defined(_MSC_VER)
320#pragma warning( pop )
321#endif
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100322
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200323 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100324
Manuel Pégourié-Gonnardc3be3992021-05-31 11:48:45 +0200325 X->s = ( X->s & ~mask ) | ( Y->s & mask );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100326
Gilles Peskinef04d11e2020-06-04 19:14:58 +0200327 mpi_safe_cond_assign( Y->n, X->p, Y->p, assign );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100328
Gilles Peskinef04d11e2020-06-04 19:14:58 +0200329 for( i = Y->n; i < X->n; i++ )
Manuel Pégourié-Gonnardc3be3992021-05-31 11:48:45 +0200330 X->p[i] &= ~limb_mask;
Manuel Pégourié-Gonnard71c2c212013-11-21 16:56:39 +0100331
332cleanup:
333 return( ret );
334}
335
336/*
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100337 * Conditionally swap X and Y, without leaking information
338 * about whether the swap was made or not.
339 * Here it is not ok to simply swap the pointers, which whould lead to
340 * different memory access patterns when X and Y are used afterwards.
341 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200342int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap )
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100343{
344 int ret, s;
345 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200346 mbedtls_mpi_uint tmp;
Hanno Becker73d7d792018-12-11 10:35:51 +0000347 MPI_VALIDATE_RET( X != NULL );
348 MPI_VALIDATE_RET( Y != NULL );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100349
350 if( X == Y )
351 return( 0 );
352
Pascal Junodb99183d2015-03-11 16:49:45 +0100353 /* make sure swap is 0 or 1 in a time-constant manner */
354 swap = (swap | (unsigned char)-swap) >> 7;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100355
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200356 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
357 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100358
359 s = X->s;
Paul Bakker66d5d072014-06-17 16:39:18 +0200360 X->s = X->s * ( 1 - swap ) + Y->s * swap;
361 Y->s = Y->s * ( 1 - swap ) + s * swap;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100362
363
364 for( i = 0; i < X->n; i++ )
365 {
366 tmp = X->p[i];
Paul Bakker66d5d072014-06-17 16:39:18 +0200367 X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap;
368 Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap;
Manuel Pégourié-Gonnarda60fe892013-12-04 21:41:50 +0100369 }
370
371cleanup:
372 return( ret );
373}
374
375/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000376 * Set value from integer
377 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200378int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +0000379{
Janos Follath24eed8d2019-11-22 13:21:35 +0000380 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker73d7d792018-12-11 10:35:51 +0000381 MPI_VALIDATE_RET( X != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000382
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200383 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000384 memset( X->p, 0, X->n * ciL );
385
386 X->p[0] = ( z < 0 ) ? -z : z;
387 X->s = ( z < 0 ) ? -1 : 1;
388
389cleanup:
390
391 return( ret );
392}
393
394/*
Paul Bakker2f5947e2011-05-18 15:47:11 +0000395 * Get a specific bit
396 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200397int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000398{
Hanno Becker73d7d792018-12-11 10:35:51 +0000399 MPI_VALIDATE_RET( X != NULL );
400
Paul Bakker2f5947e2011-05-18 15:47:11 +0000401 if( X->n * biL <= pos )
402 return( 0 );
403
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200404 return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000405}
406
Gilles Peskine11cdb052018-11-20 16:47:47 +0100407/* Get a specific byte, without range checks. */
408#define GET_BYTE( X, i ) \
409 ( ( ( X )->p[( i ) / ciL] >> ( ( ( i ) % ciL ) * 8 ) ) & 0xff )
410
Paul Bakker2f5947e2011-05-18 15:47:11 +0000411/*
412 * Set a bit to a specific value of 0 or 1
413 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200414int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val )
Paul Bakker2f5947e2011-05-18 15:47:11 +0000415{
416 int ret = 0;
417 size_t off = pos / biL;
418 size_t idx = pos % biL;
Hanno Becker73d7d792018-12-11 10:35:51 +0000419 MPI_VALIDATE_RET( X != NULL );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000420
421 if( val != 0 && val != 1 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200422 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker9af723c2014-05-01 13:03:14 +0200423
Paul Bakker2f5947e2011-05-18 15:47:11 +0000424 if( X->n * biL <= pos )
425 {
426 if( val == 0 )
Paul Bakkerd8bb8262014-06-17 14:06:49 +0200427 return( 0 );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000428
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200429 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, off + 1 ) );
Paul Bakker2f5947e2011-05-18 15:47:11 +0000430 }
431
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200432 X->p[off] &= ~( (mbedtls_mpi_uint) 0x01 << idx );
433 X->p[off] |= (mbedtls_mpi_uint) val << idx;
Paul Bakker2f5947e2011-05-18 15:47:11 +0000434
435cleanup:
Paul Bakker9af723c2014-05-01 13:03:14 +0200436
Paul Bakker2f5947e2011-05-18 15:47:11 +0000437 return( ret );
438}
439
440/*
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200441 * Return the number of less significant zero-bits
Paul Bakker5121ce52009-01-03 21:22:43 +0000442 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200443size_t mbedtls_mpi_lsb( const mbedtls_mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000444{
Paul Bakker23986e52011-04-24 08:57:21 +0000445 size_t i, j, count = 0;
Hanno Beckerf25ee7f2018-12-19 16:51:02 +0000446 MBEDTLS_INTERNAL_VALIDATE_RET( X != NULL, 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000447
448 for( i = 0; i < X->n; i++ )
Paul Bakkerf9688572011-05-05 10:00:45 +0000449 for( j = 0; j < biL; j++, count++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000450 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
451 return( count );
452
453 return( 0 );
454}
455
456/*
Simon Butcher15b15d12015-11-26 19:35:03 +0000457 * Count leading zero bits in a given integer
458 */
459static size_t mbedtls_clz( const mbedtls_mpi_uint x )
460{
461 size_t j;
Manuel Pégourié-Gonnarde3e8edf2015-12-01 09:31:52 +0100462 mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);
Simon Butcher15b15d12015-11-26 19:35:03 +0000463
464 for( j = 0; j < biL; j++ )
465 {
466 if( x & mask ) break;
467
468 mask >>= 1;
469 }
470
471 return j;
472}
473
474/*
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200475 * Return the number of bits
Paul Bakker5121ce52009-01-03 21:22:43 +0000476 */
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200477size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000478{
Paul Bakker23986e52011-04-24 08:57:21 +0000479 size_t i, j;
Paul Bakker5121ce52009-01-03 21:22:43 +0000480
Manuel Pégourié-Gonnard770b5e12015-04-29 17:02:01 +0200481 if( X->n == 0 )
482 return( 0 );
483
Paul Bakker5121ce52009-01-03 21:22:43 +0000484 for( i = X->n - 1; i > 0; i-- )
485 if( X->p[i] != 0 )
486 break;
487
Simon Butcher15b15d12015-11-26 19:35:03 +0000488 j = biL - mbedtls_clz( X->p[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +0000489
Paul Bakker23986e52011-04-24 08:57:21 +0000490 return( ( i * biL ) + j );
Paul Bakker5121ce52009-01-03 21:22:43 +0000491}
492
493/*
494 * Return the total size in bytes
495 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200496size_t mbedtls_mpi_size( const mbedtls_mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +0000497{
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +0200498 return( ( mbedtls_mpi_bitlen( X ) + 7 ) >> 3 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000499}
500
501/*
502 * Convert an ASCII character to digit value
503 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200504static int mpi_get_digit( mbedtls_mpi_uint *d, int radix, char c )
Paul Bakker5121ce52009-01-03 21:22:43 +0000505{
506 *d = 255;
507
508 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
509 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
510 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
511
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200512 if( *d >= (mbedtls_mpi_uint) radix )
513 return( MBEDTLS_ERR_MPI_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000514
515 return( 0 );
516}
517
518/*
519 * Import from an ASCII string
520 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200521int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
Paul Bakker5121ce52009-01-03 21:22:43 +0000522{
Janos Follath24eed8d2019-11-22 13:21:35 +0000523 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000524 size_t i, j, slen, n;
Gilles Peskine80f56732021-04-03 18:26:13 +0200525 int sign = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200526 mbedtls_mpi_uint d;
527 mbedtls_mpi T;
Hanno Becker73d7d792018-12-11 10:35:51 +0000528 MPI_VALIDATE_RET( X != NULL );
529 MPI_VALIDATE_RET( s != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000530
531 if( radix < 2 || radix > 16 )
Hanno Becker54c91dd2018-12-12 13:37:06 +0000532 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000533
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200534 mbedtls_mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000535
Gilles Peskine80f56732021-04-03 18:26:13 +0200536 if( s[0] == '-' )
537 {
538 ++s;
539 sign = -1;
540 }
541
Paul Bakkerff60ee62010-03-16 21:09:09 +0000542 slen = strlen( s );
543
Paul Bakker5121ce52009-01-03 21:22:43 +0000544 if( radix == 16 )
545 {
Manuel Pégourié-Gonnard2d708342015-10-05 15:23:11 +0100546 if( slen > MPI_SIZE_T_MAX >> 2 )
Manuel Pégourié-Gonnard58fb4952015-09-28 13:48:04 +0200547 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
548
Paul Bakkerff60ee62010-03-16 21:09:09 +0000549 n = BITS_TO_LIMBS( slen << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000550
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200551 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) );
552 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000553
Paul Bakker23986e52011-04-24 08:57:21 +0000554 for( i = slen, j = 0; i > 0; i--, j++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000555 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200556 MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
Paul Bakker66d5d072014-06-17 16:39:18 +0200557 X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000558 }
559 }
560 else
561 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200562 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000563
Paul Bakkerff60ee62010-03-16 21:09:09 +0000564 for( i = 0; i < slen; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +0000565 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200566 MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
567 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T, X, radix ) );
Gilles Peskine80f56732021-04-03 18:26:13 +0200568 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000569 }
570 }
571
Gilles Peskine80f56732021-04-03 18:26:13 +0200572 if( sign < 0 && mbedtls_mpi_bitlen( X ) != 0 )
573 X->s = -1;
574
Paul Bakker5121ce52009-01-03 21:22:43 +0000575cleanup:
576
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200577 mbedtls_mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000578
579 return( ret );
580}
581
582/*
Ron Eldora16fa292018-11-20 14:07:01 +0200583 * Helper to write the digits high-order first.
Paul Bakker5121ce52009-01-03 21:22:43 +0000584 */
Ron Eldora16fa292018-11-20 14:07:01 +0200585static int mpi_write_hlp( mbedtls_mpi *X, int radix,
586 char **p, const size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000587{
Janos Follath24eed8d2019-11-22 13:21:35 +0000588 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200589 mbedtls_mpi_uint r;
Ron Eldora16fa292018-11-20 14:07:01 +0200590 size_t length = 0;
591 char *p_end = *p + buflen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000592
Ron Eldora16fa292018-11-20 14:07:01 +0200593 do
594 {
595 if( length >= buflen )
596 {
597 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
598 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000599
Ron Eldora16fa292018-11-20 14:07:01 +0200600 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) );
601 MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) );
602 /*
603 * Write the residue in the current position, as an ASCII character.
604 */
605 if( r < 0xA )
606 *(--p_end) = (char)( '0' + r );
607 else
608 *(--p_end) = (char)( 'A' + ( r - 0xA ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000609
Ron Eldora16fa292018-11-20 14:07:01 +0200610 length++;
611 } while( mbedtls_mpi_cmp_int( X, 0 ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +0000612
Ron Eldora16fa292018-11-20 14:07:01 +0200613 memmove( *p, p_end, length );
614 *p += length;
Paul Bakker5121ce52009-01-03 21:22:43 +0000615
616cleanup:
617
618 return( ret );
619}
620
621/*
622 * Export into an ASCII string
623 */
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100624int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
625 char *buf, size_t buflen, size_t *olen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000626{
Paul Bakker23986e52011-04-24 08:57:21 +0000627 int ret = 0;
628 size_t n;
Paul Bakker5121ce52009-01-03 21:22:43 +0000629 char *p;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200630 mbedtls_mpi T;
Hanno Becker73d7d792018-12-11 10:35:51 +0000631 MPI_VALIDATE_RET( X != NULL );
632 MPI_VALIDATE_RET( olen != NULL );
633 MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000634
635 if( radix < 2 || radix > 16 )
Hanno Becker54c91dd2018-12-12 13:37:06 +0000636 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000637
Hanno Becker23cfea02019-02-04 09:45:07 +0000638 n = mbedtls_mpi_bitlen( X ); /* Number of bits necessary to present `n`. */
639 if( radix >= 4 ) n >>= 1; /* Number of 4-adic digits necessary to present
640 * `n`. If radix > 4, this might be a strict
641 * overapproximation of the number of
642 * radix-adic digits needed to present `n`. */
643 if( radix >= 16 ) n >>= 1; /* Number of hexadecimal digits necessary to
644 * present `n`. */
645
Janos Follath80470622019-03-06 13:43:02 +0000646 n += 1; /* Terminating null byte */
Hanno Becker23cfea02019-02-04 09:45:07 +0000647 n += 1; /* Compensate for the divisions above, which round down `n`
648 * in case it's not even. */
649 n += 1; /* Potential '-'-sign. */
650 n += ( n & 1 ); /* Make n even to have enough space for hexadecimal writing,
651 * which always uses an even number of hex-digits. */
Paul Bakker5121ce52009-01-03 21:22:43 +0000652
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100653 if( buflen < n )
Paul Bakker5121ce52009-01-03 21:22:43 +0000654 {
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100655 *olen = n;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200656 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000657 }
658
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100659 p = buf;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200660 mbedtls_mpi_init( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000661
662 if( X->s == -1 )
Hanno Beckerc983c812019-02-01 16:41:30 +0000663 {
Paul Bakker5121ce52009-01-03 21:22:43 +0000664 *p++ = '-';
Hanno Beckerc983c812019-02-01 16:41:30 +0000665 buflen--;
666 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000667
668 if( radix == 16 )
669 {
Paul Bakker23986e52011-04-24 08:57:21 +0000670 int c;
671 size_t i, j, k;
Paul Bakker5121ce52009-01-03 21:22:43 +0000672
Paul Bakker23986e52011-04-24 08:57:21 +0000673 for( i = X->n, k = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000674 {
Paul Bakker23986e52011-04-24 08:57:21 +0000675 for( j = ciL; j > 0; j-- )
Paul Bakker5121ce52009-01-03 21:22:43 +0000676 {
Paul Bakker23986e52011-04-24 08:57:21 +0000677 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
Paul Bakker5121ce52009-01-03 21:22:43 +0000678
Paul Bakker6c343d72014-07-10 14:36:19 +0200679 if( c == 0 && k == 0 && ( i + j ) != 2 )
Paul Bakker5121ce52009-01-03 21:22:43 +0000680 continue;
681
Paul Bakker98fe5ea2012-10-24 11:17:48 +0000682 *(p++) = "0123456789ABCDEF" [c / 16];
Paul Bakkerd2c167e2012-10-30 07:49:19 +0000683 *(p++) = "0123456789ABCDEF" [c % 16];
Paul Bakker5121ce52009-01-03 21:22:43 +0000684 k = 1;
685 }
686 }
687 }
688 else
689 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200690 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T, X ) );
Paul Bakkerce40a6d2009-06-23 19:46:08 +0000691
692 if( T.s == -1 )
693 T.s = 1;
694
Ron Eldora16fa292018-11-20 14:07:01 +0200695 MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p, buflen ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000696 }
697
698 *p++ = '\0';
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100699 *olen = p - buf;
Paul Bakker5121ce52009-01-03 21:22:43 +0000700
701cleanup:
702
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200703 mbedtls_mpi_free( &T );
Paul Bakker5121ce52009-01-03 21:22:43 +0000704
705 return( ret );
706}
707
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200708#if defined(MBEDTLS_FS_IO)
Paul Bakker5121ce52009-01-03 21:22:43 +0000709/*
710 * Read X from an opened file
711 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200712int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin )
Paul Bakker5121ce52009-01-03 21:22:43 +0000713{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200714 mbedtls_mpi_uint d;
Paul Bakker23986e52011-04-24 08:57:21 +0000715 size_t slen;
Paul Bakker5121ce52009-01-03 21:22:43 +0000716 char *p;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000717 /*
Paul Bakkercb37aa52011-11-30 16:00:20 +0000718 * Buffer should have space for (short) label and decimal formatted MPI,
719 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000720 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200721 char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
Paul Bakker5121ce52009-01-03 21:22:43 +0000722
Hanno Becker73d7d792018-12-11 10:35:51 +0000723 MPI_VALIDATE_RET( X != NULL );
724 MPI_VALIDATE_RET( fin != NULL );
725
726 if( radix < 2 || radix > 16 )
727 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
728
Paul Bakker5121ce52009-01-03 21:22:43 +0000729 memset( s, 0, sizeof( s ) );
730 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200731 return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000732
733 slen = strlen( s );
Paul Bakkercb37aa52011-11-30 16:00:20 +0000734 if( slen == sizeof( s ) - 2 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200735 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakkercb37aa52011-11-30 16:00:20 +0000736
Hanno Beckerb2034b72017-04-26 11:46:46 +0100737 if( slen > 0 && s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
738 if( slen > 0 && s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
Paul Bakker5121ce52009-01-03 21:22:43 +0000739
740 p = s + slen;
Hanno Beckerb2034b72017-04-26 11:46:46 +0100741 while( p-- > s )
Paul Bakker5121ce52009-01-03 21:22:43 +0000742 if( mpi_get_digit( &d, radix, *p ) != 0 )
743 break;
744
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200745 return( mbedtls_mpi_read_string( X, radix, p + 1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000746}
747
748/*
749 * Write X into an opened file (or stdout if fout == NULL)
750 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200751int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout )
Paul Bakker5121ce52009-01-03 21:22:43 +0000752{
Janos Follath24eed8d2019-11-22 13:21:35 +0000753 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +0000754 size_t n, slen, plen;
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000755 /*
Paul Bakker5531c6d2012-09-26 19:20:46 +0000756 * Buffer should have space for (short) label and decimal formatted MPI,
757 * newline characters and '\0'
Paul Bakkerfe3256e2011-11-25 12:11:43 +0000758 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200759 char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
Hanno Becker73d7d792018-12-11 10:35:51 +0000760 MPI_VALIDATE_RET( X != NULL );
761
762 if( radix < 2 || radix > 16 )
763 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000764
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100765 memset( s, 0, sizeof( s ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000766
Manuel Pégourié-Gonnardf79b4252015-06-02 15:41:48 +0100767 MBEDTLS_MPI_CHK( mbedtls_mpi_write_string( X, radix, s, sizeof( s ) - 2, &n ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000768
769 if( p == NULL ) p = "";
770
771 plen = strlen( p );
772 slen = strlen( s );
773 s[slen++] = '\r';
774 s[slen++] = '\n';
775
776 if( fout != NULL )
777 {
778 if( fwrite( p, 1, plen, fout ) != plen ||
779 fwrite( s, 1, slen, fout ) != slen )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200780 return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000781 }
782 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200783 mbedtls_printf( "%s%s", p, s );
Paul Bakker5121ce52009-01-03 21:22:43 +0000784
785cleanup:
786
787 return( ret );
788}
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200789#endif /* MBEDTLS_FS_IO */
Paul Bakker5121ce52009-01-03 21:22:43 +0000790
Hanno Beckerda1655a2017-10-18 14:21:44 +0100791
792/* Convert a big-endian byte array aligned to the size of mbedtls_mpi_uint
793 * into the storage form used by mbedtls_mpi. */
Hanno Beckerf8720072018-11-08 11:53:49 +0000794
795static mbedtls_mpi_uint mpi_uint_bigendian_to_host_c( mbedtls_mpi_uint x )
796{
797 uint8_t i;
Hanno Becker031d6332019-05-01 17:09:11 +0100798 unsigned char *x_ptr;
Hanno Beckerf8720072018-11-08 11:53:49 +0000799 mbedtls_mpi_uint tmp = 0;
Hanno Becker031d6332019-05-01 17:09:11 +0100800
801 for( i = 0, x_ptr = (unsigned char*) &x; i < ciL; i++, x_ptr++ )
802 {
803 tmp <<= CHAR_BIT;
804 tmp |= (mbedtls_mpi_uint) *x_ptr;
805 }
806
Hanno Beckerf8720072018-11-08 11:53:49 +0000807 return( tmp );
808}
809
810static mbedtls_mpi_uint mpi_uint_bigendian_to_host( mbedtls_mpi_uint x )
811{
812#if defined(__BYTE_ORDER__)
813
814/* Nothing to do on bigendian systems. */
815#if ( __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ )
816 return( x );
817#endif /* __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ */
818
819#if ( __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ )
820
821/* For GCC and Clang, have builtins for byte swapping. */
Hanno Becker9f6d16a2019-01-02 17:15:06 +0000822#if defined(__GNUC__) && defined(__GNUC_PREREQ)
823#if __GNUC_PREREQ(4,3)
Hanno Beckerf8720072018-11-08 11:53:49 +0000824#define have_bswap
825#endif
Hanno Becker9f6d16a2019-01-02 17:15:06 +0000826#endif
827
828#if defined(__clang__) && defined(__has_builtin)
829#if __has_builtin(__builtin_bswap32) && \
830 __has_builtin(__builtin_bswap64)
831#define have_bswap
832#endif
833#endif
834
Hanno Beckerf8720072018-11-08 11:53:49 +0000835#if defined(have_bswap)
836 /* The compiler is hopefully able to statically evaluate this! */
837 switch( sizeof(mbedtls_mpi_uint) )
838 {
839 case 4:
840 return( __builtin_bswap32(x) );
841 case 8:
842 return( __builtin_bswap64(x) );
843 }
844#endif
845#endif /* __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__ */
846#endif /* __BYTE_ORDER__ */
847
848 /* Fall back to C-based reordering if we don't know the byte order
849 * or we couldn't use a compiler-specific builtin. */
850 return( mpi_uint_bigendian_to_host_c( x ) );
851}
852
Hanno Becker2be8a552018-10-25 12:40:09 +0100853static void mpi_bigendian_to_host( mbedtls_mpi_uint * const p, size_t limbs )
Hanno Beckerda1655a2017-10-18 14:21:44 +0100854{
Hanno Beckerda1655a2017-10-18 14:21:44 +0100855 mbedtls_mpi_uint *cur_limb_left;
856 mbedtls_mpi_uint *cur_limb_right;
Hanno Becker2be8a552018-10-25 12:40:09 +0100857 if( limbs == 0 )
858 return;
Hanno Beckerda1655a2017-10-18 14:21:44 +0100859
860 /*
861 * Traverse limbs and
862 * - adapt byte-order in each limb
863 * - swap the limbs themselves.
864 * For that, simultaneously traverse the limbs from left to right
865 * and from right to left, as long as the left index is not bigger
866 * than the right index (it's not a problem if limbs is odd and the
867 * indices coincide in the last iteration).
868 */
Hanno Beckerda1655a2017-10-18 14:21:44 +0100869 for( cur_limb_left = p, cur_limb_right = p + ( limbs - 1 );
870 cur_limb_left <= cur_limb_right;
871 cur_limb_left++, cur_limb_right-- )
872 {
Hanno Beckerf8720072018-11-08 11:53:49 +0000873 mbedtls_mpi_uint tmp;
874 /* Note that if cur_limb_left == cur_limb_right,
875 * this code effectively swaps the bytes only once. */
876 tmp = mpi_uint_bigendian_to_host( *cur_limb_left );
877 *cur_limb_left = mpi_uint_bigendian_to_host( *cur_limb_right );
878 *cur_limb_right = tmp;
Hanno Beckerda1655a2017-10-18 14:21:44 +0100879 }
Hanno Beckerda1655a2017-10-18 14:21:44 +0100880}
881
Paul Bakker5121ce52009-01-03 21:22:43 +0000882/*
Janos Follatha778a942019-02-13 10:28:28 +0000883 * Import X from unsigned binary data, little endian
884 */
885int mbedtls_mpi_read_binary_le( mbedtls_mpi *X,
886 const unsigned char *buf, size_t buflen )
887{
Janos Follath24eed8d2019-11-22 13:21:35 +0000888 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Janos Follatha778a942019-02-13 10:28:28 +0000889 size_t i;
890 size_t const limbs = CHARS_TO_LIMBS( buflen );
891
892 /* Ensure that target MPI has exactly the necessary number of limbs */
Gilles Peskine3130ce22021-06-02 22:17:52 +0200893 MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
Janos Follatha778a942019-02-13 10:28:28 +0000894
895 for( i = 0; i < buflen; i++ )
896 X->p[i / ciL] |= ((mbedtls_mpi_uint) buf[i]) << ((i % ciL) << 3);
897
898cleanup:
899
Janos Follath171a7ef2019-02-15 16:17:45 +0000900 /*
901 * This function is also used to import keys. However, wiping the buffers
902 * upon failure is not necessary because failure only can happen before any
903 * input is copied.
904 */
Janos Follatha778a942019-02-13 10:28:28 +0000905 return( ret );
906}
907
908/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000909 * Import X from unsigned binary data, big endian
910 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +0200911int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000912{
Janos Follath24eed8d2019-11-22 13:21:35 +0000913 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Beckerda1655a2017-10-18 14:21:44 +0100914 size_t const limbs = CHARS_TO_LIMBS( buflen );
915 size_t const overhead = ( limbs * ciL ) - buflen;
916 unsigned char *Xp;
Paul Bakker5121ce52009-01-03 21:22:43 +0000917
Hanno Becker8ce11a32018-12-19 16:18:52 +0000918 MPI_VALIDATE_RET( X != NULL );
Hanno Becker73d7d792018-12-11 10:35:51 +0000919 MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
920
Hanno Becker073c1992017-10-17 15:17:27 +0100921 /* Ensure that target MPI has exactly the necessary number of limbs */
Gilles Peskine3130ce22021-06-02 22:17:52 +0200922 MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
Paul Bakker5121ce52009-01-03 21:22:43 +0000923
Gilles Peskine3130ce22021-06-02 22:17:52 +0200924 /* Avoid calling `memcpy` with NULL source or destination argument,
Hanno Becker0e810b92019-01-03 17:13:11 +0000925 * even if buflen is 0. */
Gilles Peskine3130ce22021-06-02 22:17:52 +0200926 if( buflen != 0 )
Hanno Becker0e810b92019-01-03 17:13:11 +0000927 {
928 Xp = (unsigned char*) X->p;
929 memcpy( Xp + overhead, buf, buflen );
Hanno Beckerda1655a2017-10-18 14:21:44 +0100930
Hanno Becker0e810b92019-01-03 17:13:11 +0000931 mpi_bigendian_to_host( X->p, limbs );
932 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000933
934cleanup:
935
Janos Follath171a7ef2019-02-15 16:17:45 +0000936 /*
937 * This function is also used to import keys. However, wiping the buffers
938 * upon failure is not necessary because failure only can happen before any
939 * input is copied.
940 */
Paul Bakker5121ce52009-01-03 21:22:43 +0000941 return( ret );
942}
943
944/*
Janos Follathe344d0f2019-02-19 16:17:40 +0000945 * Export X into unsigned binary data, little endian
946 */
947int mbedtls_mpi_write_binary_le( const mbedtls_mpi *X,
948 unsigned char *buf, size_t buflen )
949{
950 size_t stored_bytes = X->n * ciL;
951 size_t bytes_to_copy;
952 size_t i;
953
954 if( stored_bytes < buflen )
955 {
956 bytes_to_copy = stored_bytes;
957 }
958 else
959 {
960 bytes_to_copy = buflen;
961
962 /* The output buffer is smaller than the allocated size of X.
963 * However X may fit if its leading bytes are zero. */
964 for( i = bytes_to_copy; i < stored_bytes; i++ )
965 {
966 if( GET_BYTE( X, i ) != 0 )
967 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
968 }
969 }
970
971 for( i = 0; i < bytes_to_copy; i++ )
972 buf[i] = GET_BYTE( X, i );
973
974 if( stored_bytes < buflen )
975 {
976 /* Write trailing 0 bytes */
977 memset( buf + stored_bytes, 0, buflen - stored_bytes );
978 }
979
980 return( 0 );
981}
982
983/*
Paul Bakker5121ce52009-01-03 21:22:43 +0000984 * Export X into unsigned binary data, big endian
985 */
Gilles Peskine11cdb052018-11-20 16:47:47 +0100986int mbedtls_mpi_write_binary( const mbedtls_mpi *X,
987 unsigned char *buf, size_t buflen )
Paul Bakker5121ce52009-01-03 21:22:43 +0000988{
Hanno Becker73d7d792018-12-11 10:35:51 +0000989 size_t stored_bytes;
Gilles Peskine11cdb052018-11-20 16:47:47 +0100990 size_t bytes_to_copy;
991 unsigned char *p;
992 size_t i;
Paul Bakker5121ce52009-01-03 21:22:43 +0000993
Hanno Becker73d7d792018-12-11 10:35:51 +0000994 MPI_VALIDATE_RET( X != NULL );
995 MPI_VALIDATE_RET( buflen == 0 || buf != NULL );
996
997 stored_bytes = X->n * ciL;
998
Gilles Peskine11cdb052018-11-20 16:47:47 +0100999 if( stored_bytes < buflen )
1000 {
1001 /* There is enough space in the output buffer. Write initial
1002 * null bytes and record the position at which to start
1003 * writing the significant bytes. In this case, the execution
1004 * trace of this function does not depend on the value of the
1005 * number. */
1006 bytes_to_copy = stored_bytes;
1007 p = buf + buflen - stored_bytes;
1008 memset( buf, 0, buflen - stored_bytes );
1009 }
1010 else
1011 {
1012 /* The output buffer is smaller than the allocated size of X.
1013 * However X may fit if its leading bytes are zero. */
1014 bytes_to_copy = buflen;
1015 p = buf;
1016 for( i = bytes_to_copy; i < stored_bytes; i++ )
1017 {
1018 if( GET_BYTE( X, i ) != 0 )
1019 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
1020 }
1021 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001022
Gilles Peskine11cdb052018-11-20 16:47:47 +01001023 for( i = 0; i < bytes_to_copy; i++ )
1024 p[bytes_to_copy - i - 1] = GET_BYTE( X, i );
Paul Bakker5121ce52009-01-03 21:22:43 +00001025
1026 return( 0 );
1027}
1028
1029/*
1030 * Left-shift: X <<= count
1031 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001032int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +00001033{
Janos Follath24eed8d2019-11-22 13:21:35 +00001034 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +00001035 size_t i, v0, t1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001036 mbedtls_mpi_uint r0 = 0, r1;
Hanno Becker73d7d792018-12-11 10:35:51 +00001037 MPI_VALIDATE_RET( X != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001038
1039 v0 = count / (biL );
1040 t1 = count & (biL - 1);
1041
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001042 i = mbedtls_mpi_bitlen( X ) + count;
Paul Bakker5121ce52009-01-03 21:22:43 +00001043
Paul Bakkerf9688572011-05-05 10:00:45 +00001044 if( X->n * biL < i )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001045 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, BITS_TO_LIMBS( i ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001046
1047 ret = 0;
1048
1049 /*
1050 * shift by count / limb_size
1051 */
1052 if( v0 > 0 )
1053 {
Paul Bakker23986e52011-04-24 08:57:21 +00001054 for( i = X->n; i > v0; i-- )
1055 X->p[i - 1] = X->p[i - v0 - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001056
Paul Bakker23986e52011-04-24 08:57:21 +00001057 for( ; i > 0; i-- )
1058 X->p[i - 1] = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001059 }
1060
1061 /*
1062 * shift by count % limb_size
1063 */
1064 if( t1 > 0 )
1065 {
1066 for( i = v0; i < X->n; i++ )
1067 {
1068 r1 = X->p[i] >> (biL - t1);
1069 X->p[i] <<= t1;
1070 X->p[i] |= r0;
1071 r0 = r1;
1072 }
1073 }
1074
1075cleanup:
1076
1077 return( ret );
1078}
1079
1080/*
1081 * Right-shift: X >>= count
1082 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001083int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count )
Paul Bakker5121ce52009-01-03 21:22:43 +00001084{
Paul Bakker23986e52011-04-24 08:57:21 +00001085 size_t i, v0, v1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001086 mbedtls_mpi_uint r0 = 0, r1;
Hanno Becker73d7d792018-12-11 10:35:51 +00001087 MPI_VALIDATE_RET( X != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001088
1089 v0 = count / biL;
1090 v1 = count & (biL - 1);
1091
Manuel Pégourié-Gonnarde44ec102012-11-17 12:42:51 +01001092 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001093 return mbedtls_mpi_lset( X, 0 );
Manuel Pégourié-Gonnarde44ec102012-11-17 12:42:51 +01001094
Paul Bakker5121ce52009-01-03 21:22:43 +00001095 /*
1096 * shift by count / limb_size
1097 */
1098 if( v0 > 0 )
1099 {
1100 for( i = 0; i < X->n - v0; i++ )
1101 X->p[i] = X->p[i + v0];
1102
1103 for( ; i < X->n; i++ )
1104 X->p[i] = 0;
1105 }
1106
1107 /*
1108 * shift by count % limb_size
1109 */
1110 if( v1 > 0 )
1111 {
Paul Bakker23986e52011-04-24 08:57:21 +00001112 for( i = X->n; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001113 {
Paul Bakker23986e52011-04-24 08:57:21 +00001114 r1 = X->p[i - 1] << (biL - v1);
1115 X->p[i - 1] >>= v1;
1116 X->p[i - 1] |= r0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001117 r0 = r1;
1118 }
1119 }
1120
1121 return( 0 );
1122}
1123
1124/*
1125 * Compare unsigned values
1126 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001127int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +00001128{
Paul Bakker23986e52011-04-24 08:57:21 +00001129 size_t i, j;
Hanno Becker73d7d792018-12-11 10:35:51 +00001130 MPI_VALIDATE_RET( X != NULL );
1131 MPI_VALIDATE_RET( Y != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001132
Paul Bakker23986e52011-04-24 08:57:21 +00001133 for( i = X->n; i > 0; i-- )
1134 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001135 break;
1136
Paul Bakker23986e52011-04-24 08:57:21 +00001137 for( j = Y->n; j > 0; j-- )
1138 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001139 break;
1140
Paul Bakker23986e52011-04-24 08:57:21 +00001141 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001142 return( 0 );
1143
1144 if( i > j ) return( 1 );
1145 if( j > i ) return( -1 );
1146
Paul Bakker23986e52011-04-24 08:57:21 +00001147 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001148 {
Paul Bakker23986e52011-04-24 08:57:21 +00001149 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
1150 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001151 }
1152
1153 return( 0 );
1154}
1155
1156/*
1157 * Compare signed values
1158 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001159int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
Paul Bakker5121ce52009-01-03 21:22:43 +00001160{
Paul Bakker23986e52011-04-24 08:57:21 +00001161 size_t i, j;
Hanno Becker73d7d792018-12-11 10:35:51 +00001162 MPI_VALIDATE_RET( X != NULL );
1163 MPI_VALIDATE_RET( Y != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001164
Paul Bakker23986e52011-04-24 08:57:21 +00001165 for( i = X->n; i > 0; i-- )
1166 if( X->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001167 break;
1168
Paul Bakker23986e52011-04-24 08:57:21 +00001169 for( j = Y->n; j > 0; j-- )
1170 if( Y->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001171 break;
1172
Paul Bakker23986e52011-04-24 08:57:21 +00001173 if( i == 0 && j == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001174 return( 0 );
1175
1176 if( i > j ) return( X->s );
Paul Bakker0c8f73b2012-03-22 14:08:57 +00001177 if( j > i ) return( -Y->s );
Paul Bakker5121ce52009-01-03 21:22:43 +00001178
1179 if( X->s > 0 && Y->s < 0 ) return( 1 );
1180 if( Y->s > 0 && X->s < 0 ) return( -1 );
1181
Paul Bakker23986e52011-04-24 08:57:21 +00001182 for( ; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00001183 {
Paul Bakker23986e52011-04-24 08:57:21 +00001184 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
1185 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
Paul Bakker5121ce52009-01-03 21:22:43 +00001186 }
1187
1188 return( 0 );
1189}
1190
Janos Follath3f6f0e42019-10-14 09:09:32 +01001191/** Decide if an integer is less than the other, without branches.
1192 *
1193 * \param x First integer.
1194 * \param y Second integer.
1195 *
1196 * \return 1 if \p x is less than \p y, 0 otherwise
1197 */
Janos Follath0e5532d2019-10-11 14:21:53 +01001198static unsigned ct_lt_mpi_uint( const mbedtls_mpi_uint x,
1199 const mbedtls_mpi_uint y )
Janos Follathee6abce2019-09-05 14:47:19 +01001200{
1201 mbedtls_mpi_uint ret;
1202 mbedtls_mpi_uint cond;
1203
1204 /*
1205 * Check if the most significant bits (MSB) of the operands are different.
1206 */
1207 cond = ( x ^ y );
1208 /*
1209 * If the MSB are the same then the difference x-y will be negative (and
1210 * have its MSB set to 1 during conversion to unsigned) if and only if x<y.
1211 */
1212 ret = ( x - y ) & ~cond;
1213 /*
1214 * If the MSB are different, then the operand with the MSB of 1 is the
1215 * bigger. (That is if y has MSB of 1, then x<y is true and it is false if
1216 * the MSB of y is 0.)
1217 */
1218 ret |= y & cond;
1219
1220
Janos Follatha0f732b2019-10-14 08:59:14 +01001221 ret = ret >> ( biL - 1 );
Janos Follathee6abce2019-09-05 14:47:19 +01001222
Janos Follath67ce6472019-10-29 15:08:46 +00001223 return (unsigned) ret;
Janos Follathee6abce2019-09-05 14:47:19 +01001224}
1225
1226/*
1227 * Compare signed values in constant time
1228 */
Janos Follath0e5532d2019-10-11 14:21:53 +01001229int mbedtls_mpi_lt_mpi_ct( const mbedtls_mpi *X, const mbedtls_mpi *Y,
1230 unsigned *ret )
Janos Follathee6abce2019-09-05 14:47:19 +01001231{
1232 size_t i;
Janos Follathbb5147f2019-10-28 12:23:18 +00001233 /* The value of any of these variables is either 0 or 1 at all times. */
Janos Follath5e614ce2019-10-28 12:31:34 +00001234 unsigned cond, done, X_is_negative, Y_is_negative;
Janos Follathee6abce2019-09-05 14:47:19 +01001235
1236 MPI_VALIDATE_RET( X != NULL );
1237 MPI_VALIDATE_RET( Y != NULL );
1238 MPI_VALIDATE_RET( ret != NULL );
1239
1240 if( X->n != Y->n )
1241 return MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
1242
1243 /*
Janos Follath73ba9ec2019-10-28 12:12:15 +00001244 * Set sign_N to 1 if N >= 0, 0 if N < 0.
1245 * We know that N->s == 1 if N >= 0 and N->s == -1 if N < 0.
Janos Follathee6abce2019-09-05 14:47:19 +01001246 */
Janos Follath5e614ce2019-10-28 12:31:34 +00001247 X_is_negative = ( X->s & 2 ) >> 1;
1248 Y_is_negative = ( Y->s & 2 ) >> 1;
Janos Follath0e5532d2019-10-11 14:21:53 +01001249
1250 /*
1251 * If the signs are different, then the positive operand is the bigger.
Janos Follath5e614ce2019-10-28 12:31:34 +00001252 * That is if X is negative (X_is_negative == 1), then X < Y is true and it
1253 * is false if X is positive (X_is_negative == 0).
Janos Follath0e5532d2019-10-11 14:21:53 +01001254 */
Janos Follath5e614ce2019-10-28 12:31:34 +00001255 cond = ( X_is_negative ^ Y_is_negative );
1256 *ret = cond & X_is_negative;
Janos Follath0e5532d2019-10-11 14:21:53 +01001257
1258 /*
Janos Follathbb5147f2019-10-28 12:23:18 +00001259 * This is a constant-time function. We might have the result, but we still
Janos Follath0e5532d2019-10-11 14:21:53 +01001260 * need to go through the loop. Record if we have the result already.
1261 */
Janos Follathee6abce2019-09-05 14:47:19 +01001262 done = cond;
1263
1264 for( i = X->n; i > 0; i-- )
1265 {
1266 /*
Janos Follath30702422019-11-05 12:24:52 +00001267 * If Y->p[i - 1] < X->p[i - 1] then X < Y is true if and only if both
1268 * X and Y are negative.
Janos Follath0e5532d2019-10-11 14:21:53 +01001269 *
1270 * Again even if we can make a decision, we just mark the result and
1271 * the fact that we are done and continue looping.
Janos Follathee6abce2019-09-05 14:47:19 +01001272 */
Janos Follath30702422019-11-05 12:24:52 +00001273 cond = ct_lt_mpi_uint( Y->p[i - 1], X->p[i - 1] );
1274 *ret |= cond & ( 1 - done ) & X_is_negative;
Janos Follathc50e6d52019-10-28 12:37:21 +00001275 done |= cond;
Janos Follathee6abce2019-09-05 14:47:19 +01001276
1277 /*
Janos Follath30702422019-11-05 12:24:52 +00001278 * If X->p[i - 1] < Y->p[i - 1] then X < Y is true if and only if both
1279 * X and Y are positive.
Janos Follath0e5532d2019-10-11 14:21:53 +01001280 *
1281 * Again even if we can make a decision, we just mark the result and
1282 * the fact that we are done and continue looping.
Janos Follathee6abce2019-09-05 14:47:19 +01001283 */
Janos Follath30702422019-11-05 12:24:52 +00001284 cond = ct_lt_mpi_uint( X->p[i - 1], Y->p[i - 1] );
1285 *ret |= cond & ( 1 - done ) & ( 1 - X_is_negative );
Janos Follathc50e6d52019-10-28 12:37:21 +00001286 done |= cond;
Janos Follathee6abce2019-09-05 14:47:19 +01001287 }
1288
1289 return( 0 );
1290}
1291
Paul Bakker5121ce52009-01-03 21:22:43 +00001292/*
1293 * Compare signed values
1294 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001295int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z )
Paul Bakker5121ce52009-01-03 21:22:43 +00001296{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001297 mbedtls_mpi Y;
1298 mbedtls_mpi_uint p[1];
Hanno Becker73d7d792018-12-11 10:35:51 +00001299 MPI_VALIDATE_RET( X != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001300
1301 *p = ( z < 0 ) ? -z : z;
1302 Y.s = ( z < 0 ) ? -1 : 1;
1303 Y.n = 1;
1304 Y.p = p;
1305
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001306 return( mbedtls_mpi_cmp_mpi( X, &Y ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001307}
1308
1309/*
1310 * Unsigned addition: X = |A| + |B| (HAC 14.7)
1311 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001312int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001313{
Janos Follath24eed8d2019-11-22 13:21:35 +00001314 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +00001315 size_t i, j;
Janos Follath6c922682015-10-30 17:43:11 +01001316 mbedtls_mpi_uint *o, *p, c, tmp;
Hanno Becker73d7d792018-12-11 10:35:51 +00001317 MPI_VALIDATE_RET( X != NULL );
1318 MPI_VALIDATE_RET( A != NULL );
1319 MPI_VALIDATE_RET( B != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001320
1321 if( X == B )
1322 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001323 const mbedtls_mpi *T = A; A = X; B = T;
Paul Bakker5121ce52009-01-03 21:22:43 +00001324 }
1325
1326 if( X != A )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001327 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
Paul Bakker9af723c2014-05-01 13:03:14 +02001328
Paul Bakkerf7ca7b92009-06-20 10:31:06 +00001329 /*
1330 * X should always be positive as a result of unsigned additions.
1331 */
1332 X->s = 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00001333
Paul Bakker23986e52011-04-24 08:57:21 +00001334 for( j = B->n; j > 0; j-- )
1335 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001336 break;
1337
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001338 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001339
1340 o = B->p; p = X->p; c = 0;
1341
Janos Follath6c922682015-10-30 17:43:11 +01001342 /*
1343 * tmp is used because it might happen that p == o
1344 */
Paul Bakker23986e52011-04-24 08:57:21 +00001345 for( i = 0; i < j; i++, o++, p++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001346 {
Janos Follath6c922682015-10-30 17:43:11 +01001347 tmp= *o;
Paul Bakker5121ce52009-01-03 21:22:43 +00001348 *p += c; c = ( *p < c );
Janos Follath6c922682015-10-30 17:43:11 +01001349 *p += tmp; c += ( *p < tmp );
Paul Bakker5121ce52009-01-03 21:22:43 +00001350 }
1351
1352 while( c != 0 )
1353 {
1354 if( i >= X->n )
1355 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001356 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + 1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001357 p = X->p + i;
1358 }
1359
Paul Bakker2d319fd2012-09-16 21:34:26 +00001360 *p += c; c = ( *p < c ); i++; p++;
Paul Bakker5121ce52009-01-03 21:22:43 +00001361 }
1362
1363cleanup:
1364
1365 return( ret );
1366}
1367
Gilles Peskine09ec10a2020-06-09 10:39:38 +02001368/**
Gilles Peskinec097e9e2020-06-08 21:58:22 +02001369 * Helper for mbedtls_mpi subtraction.
1370 *
Gilles Peskine1acf7cb2020-07-23 01:03:22 +02001371 * Calculate l - r where l and r have the same size.
Gilles Peskinec097e9e2020-06-08 21:58:22 +02001372 * This function operates modulo (2^ciL)^n and returns the carry
Gilles Peskine1acf7cb2020-07-23 01:03:22 +02001373 * (1 if there was a wraparound, i.e. if `l < r`, and 0 otherwise).
Gilles Peskinec097e9e2020-06-08 21:58:22 +02001374 *
Gilles Peskine1acf7cb2020-07-23 01:03:22 +02001375 * d may be aliased to l or r.
Gilles Peskinec097e9e2020-06-08 21:58:22 +02001376 *
Gilles Peskine1acf7cb2020-07-23 01:03:22 +02001377 * \param n Number of limbs of \p d, \p l and \p r.
1378 * \param[out] d The result of the subtraction.
1379 * \param[in] l The left operand.
1380 * \param[in] r The right operand.
1381 *
1382 * \return 1 if `l < r`.
1383 * 0 if `l >= r`.
Paul Bakker5121ce52009-01-03 21:22:43 +00001384 */
Gilles Peskinec097e9e2020-06-08 21:58:22 +02001385static mbedtls_mpi_uint mpi_sub_hlp( size_t n,
1386 mbedtls_mpi_uint *d,
Gilles Peskine1acf7cb2020-07-23 01:03:22 +02001387 const mbedtls_mpi_uint *l,
1388 const mbedtls_mpi_uint *r )
Paul Bakker5121ce52009-01-03 21:22:43 +00001389{
Paul Bakker23986e52011-04-24 08:57:21 +00001390 size_t i;
Gilles Peskine1acf7cb2020-07-23 01:03:22 +02001391 mbedtls_mpi_uint c = 0, t, z;
Paul Bakker5121ce52009-01-03 21:22:43 +00001392
Gilles Peskine1acf7cb2020-07-23 01:03:22 +02001393 for( i = 0; i < n; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00001394 {
Gilles Peskine1acf7cb2020-07-23 01:03:22 +02001395 z = ( l[i] < c ); t = l[i] - c;
1396 c = ( t < r[i] ) + z; d[i] = t - r[i];
Paul Bakker5121ce52009-01-03 21:22:43 +00001397 }
1398
Gilles Peskinec097e9e2020-06-08 21:58:22 +02001399 return( c );
Paul Bakker5121ce52009-01-03 21:22:43 +00001400}
1401
1402/*
Gilles Peskine0e5faf62020-06-08 22:50:35 +02001403 * Unsigned subtraction: X = |A| - |B| (HAC 14.9, 14.10)
Paul Bakker5121ce52009-01-03 21:22:43 +00001404 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001405int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001406{
Janos Follath24eed8d2019-11-22 13:21:35 +00001407 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +00001408 size_t n;
Gilles Peskine0e5faf62020-06-08 22:50:35 +02001409 mbedtls_mpi_uint carry;
Hanno Becker73d7d792018-12-11 10:35:51 +00001410 MPI_VALIDATE_RET( X != NULL );
1411 MPI_VALIDATE_RET( A != NULL );
1412 MPI_VALIDATE_RET( B != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001413
Paul Bakker23986e52011-04-24 08:57:21 +00001414 for( n = B->n; n > 0; n-- )
1415 if( B->p[n - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001416 break;
Gilles Peskinec8a91772021-01-27 22:30:43 +01001417 if( n > A->n )
1418 {
1419 /* B >= (2^ciL)^n > A */
1420 ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
1421 goto cleanup;
1422 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001423
Gilles Peskine1acf7cb2020-07-23 01:03:22 +02001424 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, A->n ) );
1425
1426 /* Set the high limbs of X to match A. Don't touch the lower limbs
1427 * because X might be aliased to B, and we must not overwrite the
1428 * significant digits of B. */
1429 if( A->n > n )
1430 memcpy( X->p + n, A->p + n, ( A->n - n ) * ciL );
1431 if( X->n > A->n )
1432 memset( X->p + A->n, 0, ( X->n - A->n ) * ciL );
1433
1434 carry = mpi_sub_hlp( n, X->p, A->p, B->p );
Gilles Peskine0e5faf62020-06-08 22:50:35 +02001435 if( carry != 0 )
Gilles Peskinec097e9e2020-06-08 21:58:22 +02001436 {
Gilles Peskine0e5faf62020-06-08 22:50:35 +02001437 /* Propagate the carry to the first nonzero limb of X. */
1438 for( ; n < X->n && X->p[n] == 0; n++ )
1439 --X->p[n];
1440 /* If we ran out of space for the carry, it means that the result
1441 * is negative. */
1442 if( n == X->n )
Gilles Peskine89b41302020-07-23 01:16:46 +02001443 {
1444 ret = MBEDTLS_ERR_MPI_NEGATIVE_VALUE;
1445 goto cleanup;
1446 }
Gilles Peskine0e5faf62020-06-08 22:50:35 +02001447 --X->p[n];
Gilles Peskinec097e9e2020-06-08 21:58:22 +02001448 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001449
Gilles Peskine1acf7cb2020-07-23 01:03:22 +02001450 /* X should always be positive as a result of unsigned subtractions. */
1451 X->s = 1;
1452
Paul Bakker5121ce52009-01-03 21:22:43 +00001453cleanup:
Paul Bakker5121ce52009-01-03 21:22:43 +00001454 return( ret );
1455}
1456
1457/*
1458 * Signed addition: X = A + B
1459 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001460int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001461{
Hanno Becker73d7d792018-12-11 10:35:51 +00001462 int ret, s;
1463 MPI_VALIDATE_RET( X != NULL );
1464 MPI_VALIDATE_RET( A != NULL );
1465 MPI_VALIDATE_RET( B != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001466
Hanno Becker73d7d792018-12-11 10:35:51 +00001467 s = A->s;
Paul Bakker5121ce52009-01-03 21:22:43 +00001468 if( A->s * B->s < 0 )
1469 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001470 if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001471 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001472 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001473 X->s = s;
1474 }
1475 else
1476 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001477 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001478 X->s = -s;
1479 }
1480 }
1481 else
1482 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001483 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001484 X->s = s;
1485 }
1486
1487cleanup:
1488
1489 return( ret );
1490}
1491
1492/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001493 * Signed subtraction: X = A - B
Paul Bakker5121ce52009-01-03 21:22:43 +00001494 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001495int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001496{
Hanno Becker73d7d792018-12-11 10:35:51 +00001497 int ret, s;
1498 MPI_VALIDATE_RET( X != NULL );
1499 MPI_VALIDATE_RET( A != NULL );
1500 MPI_VALIDATE_RET( B != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001501
Hanno Becker73d7d792018-12-11 10:35:51 +00001502 s = A->s;
Paul Bakker5121ce52009-01-03 21:22:43 +00001503 if( A->s * B->s > 0 )
1504 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001505 if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001506 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001507 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001508 X->s = s;
1509 }
1510 else
1511 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001512 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001513 X->s = -s;
1514 }
1515 }
1516 else
1517 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001518 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001519 X->s = s;
1520 }
1521
1522cleanup:
1523
1524 return( ret );
1525}
1526
1527/*
1528 * Signed addition: X = A + b
1529 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001530int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001531{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001532 mbedtls_mpi _B;
1533 mbedtls_mpi_uint p[1];
Hanno Becker73d7d792018-12-11 10:35:51 +00001534 MPI_VALIDATE_RET( X != NULL );
1535 MPI_VALIDATE_RET( A != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001536
1537 p[0] = ( b < 0 ) ? -b : b;
1538 _B.s = ( b < 0 ) ? -1 : 1;
1539 _B.n = 1;
1540 _B.p = p;
1541
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001542 return( mbedtls_mpi_add_mpi( X, A, &_B ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001543}
1544
1545/*
Paul Bakker60b1d102013-10-29 10:02:51 +01001546 * Signed subtraction: X = A - b
Paul Bakker5121ce52009-01-03 21:22:43 +00001547 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001548int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001549{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001550 mbedtls_mpi _B;
1551 mbedtls_mpi_uint p[1];
Hanno Becker73d7d792018-12-11 10:35:51 +00001552 MPI_VALIDATE_RET( X != NULL );
1553 MPI_VALIDATE_RET( A != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001554
1555 p[0] = ( b < 0 ) ? -b : b;
1556 _B.s = ( b < 0 ) ? -1 : 1;
1557 _B.n = 1;
1558 _B.p = p;
1559
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001560 return( mbedtls_mpi_sub_mpi( X, A, &_B ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001561}
1562
Gilles Peskinea5d8d892020-07-23 21:27:15 +02001563/** Helper for mbedtls_mpi multiplication.
1564 *
1565 * Add \p b * \p s to \p d.
1566 *
1567 * \param i The number of limbs of \p s.
1568 * \param[in] s A bignum to multiply, of size \p i.
1569 * It may overlap with \p d, but only if
1570 * \p d <= \p s.
1571 * Its leading limb must not be \c 0.
1572 * \param[in,out] d The bignum to add to.
1573 * It must be sufficiently large to store the
1574 * result of the multiplication. This means
1575 * \p i + 1 limbs if \p d[\p i - 1] started as 0 and \p b
1576 * is not known a priori.
1577 * \param b A scalar to multiply.
Paul Bakkerfc4f46f2013-06-24 19:23:56 +02001578 */
1579static
1580#if defined(__APPLE__) && defined(__arm__)
1581/*
1582 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1583 * appears to need this to prevent bad ARM code generation at -O3.
1584 */
1585__attribute__ ((noinline))
1586#endif
Gilles Peskinea5d8d892020-07-23 21:27:15 +02001587void mpi_mul_hlp( size_t i,
1588 const mbedtls_mpi_uint *s,
1589 mbedtls_mpi_uint *d,
1590 mbedtls_mpi_uint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001591{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001592 mbedtls_mpi_uint c = 0, t = 0;
Paul Bakker5121ce52009-01-03 21:22:43 +00001593
1594#if defined(MULADDC_HUIT)
1595 for( ; i >= 8; i -= 8 )
1596 {
1597 MULADDC_INIT
1598 MULADDC_HUIT
1599 MULADDC_STOP
1600 }
1601
1602 for( ; i > 0; i-- )
1603 {
1604 MULADDC_INIT
1605 MULADDC_CORE
1606 MULADDC_STOP
1607 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001608#else /* MULADDC_HUIT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001609 for( ; i >= 16; i -= 16 )
1610 {
1611 MULADDC_INIT
1612 MULADDC_CORE MULADDC_CORE
1613 MULADDC_CORE MULADDC_CORE
1614 MULADDC_CORE MULADDC_CORE
1615 MULADDC_CORE MULADDC_CORE
1616
1617 MULADDC_CORE MULADDC_CORE
1618 MULADDC_CORE MULADDC_CORE
1619 MULADDC_CORE MULADDC_CORE
1620 MULADDC_CORE MULADDC_CORE
1621 MULADDC_STOP
1622 }
1623
1624 for( ; i >= 8; i -= 8 )
1625 {
1626 MULADDC_INIT
1627 MULADDC_CORE MULADDC_CORE
1628 MULADDC_CORE MULADDC_CORE
1629
1630 MULADDC_CORE MULADDC_CORE
1631 MULADDC_CORE MULADDC_CORE
1632 MULADDC_STOP
1633 }
1634
1635 for( ; i > 0; i-- )
1636 {
1637 MULADDC_INIT
1638 MULADDC_CORE
1639 MULADDC_STOP
1640 }
Paul Bakker9af723c2014-05-01 13:03:14 +02001641#endif /* MULADDC_HUIT */
Paul Bakker5121ce52009-01-03 21:22:43 +00001642
1643 t++;
1644
Gilles Peskine8e464c42020-07-24 00:08:38 +02001645 while( c != 0 )
1646 {
Paul Bakker5121ce52009-01-03 21:22:43 +00001647 *d += c; c = ( *d < c ); d++;
1648 }
Paul Bakker5121ce52009-01-03 21:22:43 +00001649}
1650
1651/*
1652 * Baseline multiplication: X = A * B (HAC 14.12)
1653 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001654int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001655{
Janos Follath24eed8d2019-11-22 13:21:35 +00001656 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +00001657 size_t i, j;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001658 mbedtls_mpi TA, TB;
Hanno Becker73d7d792018-12-11 10:35:51 +00001659 MPI_VALIDATE_RET( X != NULL );
1660 MPI_VALIDATE_RET( A != NULL );
1661 MPI_VALIDATE_RET( B != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001662
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001663 mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00001664
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001665 if( X == A ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); A = &TA; }
1666 if( X == B ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); B = &TB; }
Paul Bakker5121ce52009-01-03 21:22:43 +00001667
Paul Bakker23986e52011-04-24 08:57:21 +00001668 for( i = A->n; i > 0; i-- )
1669 if( A->p[i - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001670 break;
1671
Paul Bakker23986e52011-04-24 08:57:21 +00001672 for( j = B->n; j > 0; j-- )
1673 if( B->p[j - 1] != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001674 break;
1675
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001676 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
1677 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001678
Alexey Skalozub8e75e682016-01-13 21:59:27 +02001679 for( ; j > 0; j-- )
1680 mpi_mul_hlp( i, A->p, X->p + j - 1, B->p[j - 1] );
Paul Bakker5121ce52009-01-03 21:22:43 +00001681
1682 X->s = A->s * B->s;
1683
1684cleanup:
1685
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001686 mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001687
1688 return( ret );
1689}
1690
1691/*
1692 * Baseline multiplication: X = A * b
1693 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001694int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001695{
Hanno Becker73d7d792018-12-11 10:35:51 +00001696 MPI_VALIDATE_RET( X != NULL );
1697 MPI_VALIDATE_RET( A != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001698
Gilles Peskine8fd95c62020-07-23 21:58:50 +02001699 /* mpi_mul_hlp can't deal with a leading 0. */
1700 size_t n = A->n;
1701 while( n > 0 && A->p[n - 1] == 0 )
1702 --n;
Paul Bakker5121ce52009-01-03 21:22:43 +00001703
Gilles Peskine8fd95c62020-07-23 21:58:50 +02001704 /* The general method below doesn't work if n==0 or b==0. By chance
1705 * calculating the result is trivial in those cases. */
1706 if( b == 0 || n == 0 )
1707 {
Paul Elliott986b55a2021-04-20 21:46:29 +01001708 return( mbedtls_mpi_lset( X, 0 ) );
Gilles Peskine8fd95c62020-07-23 21:58:50 +02001709 }
1710
Gilles Peskinee1bba7c2021-03-10 23:44:10 +01001711 /* Calculate A*b as A + A*(b-1) to take advantage of mpi_mul_hlp */
Gilles Peskine8fd95c62020-07-23 21:58:50 +02001712 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Gilles Peskinecd0dbf32020-07-24 00:09:04 +02001713 /* In general, A * b requires 1 limb more than b. If
1714 * A->p[n - 1] * b / b == A->p[n - 1], then A * b fits in the same
1715 * number of limbs as A and the call to grow() is not required since
Gilles Peskinee1bba7c2021-03-10 23:44:10 +01001716 * copy() will take care of the growth if needed. However, experimentally,
1717 * making the call to grow() unconditional causes slightly fewer
Gilles Peskinecd0dbf32020-07-24 00:09:04 +02001718 * calls to calloc() in ECP code, presumably because it reuses the
1719 * same mpi for a while and this way the mpi is more likely to directly
1720 * grow to its final size. */
Gilles Peskine8fd95c62020-07-23 21:58:50 +02001721 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n + 1 ) );
1722 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
1723 mpi_mul_hlp( n, A->p, X->p, b - 1 );
1724
1725cleanup:
1726 return( ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00001727}
1728
1729/*
Simon Butcherf5ba0452015-12-27 23:01:55 +00001730 * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and
1731 * mbedtls_mpi_uint divisor, d
Simon Butcher15b15d12015-11-26 19:35:03 +00001732 */
Simon Butcherf5ba0452015-12-27 23:01:55 +00001733static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1,
1734 mbedtls_mpi_uint u0, mbedtls_mpi_uint d, mbedtls_mpi_uint *r )
Simon Butcher15b15d12015-11-26 19:35:03 +00001735{
Manuel Pégourié-Gonnard16308882015-12-01 10:27:00 +01001736#if defined(MBEDTLS_HAVE_UDBL)
1737 mbedtls_t_udbl dividend, quotient;
Simon Butcherf5ba0452015-12-27 23:01:55 +00001738#else
Simon Butcher9803d072016-01-03 00:24:34 +00001739 const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH;
1740 const mbedtls_mpi_uint uint_halfword_mask = ( (mbedtls_mpi_uint) 1 << biH ) - 1;
Simon Butcherf5ba0452015-12-27 23:01:55 +00001741 mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient;
1742 mbedtls_mpi_uint u0_msw, u0_lsw;
Simon Butcher9803d072016-01-03 00:24:34 +00001743 size_t s;
Manuel Pégourié-Gonnard16308882015-12-01 10:27:00 +01001744#endif
1745
Simon Butcher15b15d12015-11-26 19:35:03 +00001746 /*
1747 * Check for overflow
1748 */
Simon Butcherf5ba0452015-12-27 23:01:55 +00001749 if( 0 == d || u1 >= d )
Simon Butcher15b15d12015-11-26 19:35:03 +00001750 {
Simon Butcherf5ba0452015-12-27 23:01:55 +00001751 if (r != NULL) *r = ~0;
Simon Butcher15b15d12015-11-26 19:35:03 +00001752
Simon Butcherf5ba0452015-12-27 23:01:55 +00001753 return ( ~0 );
Simon Butcher15b15d12015-11-26 19:35:03 +00001754 }
1755
1756#if defined(MBEDTLS_HAVE_UDBL)
Simon Butcher15b15d12015-11-26 19:35:03 +00001757 dividend = (mbedtls_t_udbl) u1 << biL;
1758 dividend |= (mbedtls_t_udbl) u0;
1759 quotient = dividend / d;
1760 if( quotient > ( (mbedtls_t_udbl) 1 << biL ) - 1 )
1761 quotient = ( (mbedtls_t_udbl) 1 << biL ) - 1;
1762
1763 if( r != NULL )
Simon Butcher9803d072016-01-03 00:24:34 +00001764 *r = (mbedtls_mpi_uint)( dividend - (quotient * d ) );
Simon Butcher15b15d12015-11-26 19:35:03 +00001765
1766 return (mbedtls_mpi_uint) quotient;
1767#else
Simon Butcher15b15d12015-11-26 19:35:03 +00001768
1769 /*
1770 * Algorithm D, Section 4.3.1 - The Art of Computer Programming
1771 * Vol. 2 - Seminumerical Algorithms, Knuth
1772 */
1773
1774 /*
1775 * Normalize the divisor, d, and dividend, u0, u1
1776 */
1777 s = mbedtls_clz( d );
1778 d = d << s;
1779
1780 u1 = u1 << s;
Simon Butcher9803d072016-01-03 00:24:34 +00001781 u1 |= ( u0 >> ( biL - s ) ) & ( -(mbedtls_mpi_sint)s >> ( biL - 1 ) );
Simon Butcher15b15d12015-11-26 19:35:03 +00001782 u0 = u0 << s;
1783
1784 d1 = d >> biH;
Simon Butcher9803d072016-01-03 00:24:34 +00001785 d0 = d & uint_halfword_mask;
Simon Butcher15b15d12015-11-26 19:35:03 +00001786
1787 u0_msw = u0 >> biH;
Simon Butcher9803d072016-01-03 00:24:34 +00001788 u0_lsw = u0 & uint_halfword_mask;
Simon Butcher15b15d12015-11-26 19:35:03 +00001789
1790 /*
1791 * Find the first quotient and remainder
1792 */
1793 q1 = u1 / d1;
1794 r0 = u1 - d1 * q1;
1795
1796 while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) )
1797 {
1798 q1 -= 1;
1799 r0 += d1;
1800
1801 if ( r0 >= radix ) break;
1802 }
1803
Simon Butcherf5ba0452015-12-27 23:01:55 +00001804 rAX = ( u1 * radix ) + ( u0_msw - q1 * d );
Simon Butcher15b15d12015-11-26 19:35:03 +00001805 q0 = rAX / d1;
1806 r0 = rAX - q0 * d1;
1807
1808 while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) )
1809 {
1810 q0 -= 1;
1811 r0 += d1;
1812
1813 if ( r0 >= radix ) break;
1814 }
1815
1816 if (r != NULL)
Simon Butcherf5ba0452015-12-27 23:01:55 +00001817 *r = ( rAX * radix + u0_lsw - q0 * d ) >> s;
Simon Butcher15b15d12015-11-26 19:35:03 +00001818
1819 quotient = q1 * radix + q0;
1820
1821 return quotient;
1822#endif
1823}
1824
1825/*
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001826 * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20)
Paul Bakker5121ce52009-01-03 21:22:43 +00001827 */
Hanno Becker73d7d792018-12-11 10:35:51 +00001828int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A,
1829 const mbedtls_mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001830{
Janos Follath24eed8d2019-11-22 13:21:35 +00001831 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +00001832 size_t i, n, t, k;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001833 mbedtls_mpi X, Y, Z, T1, T2;
Alexander Kd19a1932019-11-01 18:20:42 +03001834 mbedtls_mpi_uint TP2[3];
Hanno Becker73d7d792018-12-11 10:35:51 +00001835 MPI_VALIDATE_RET( A != NULL );
1836 MPI_VALIDATE_RET( B != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001837
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001838 if( mbedtls_mpi_cmp_int( B, 0 ) == 0 )
1839 return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001840
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001841 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
Alexander K35d6d462019-10-31 14:46:45 +03001842 mbedtls_mpi_init( &T1 );
Alexander Kd19a1932019-11-01 18:20:42 +03001843 /*
1844 * Avoid dynamic memory allocations for constant-size T2.
1845 *
1846 * T2 is used for comparison only and the 3 limbs are assigned explicitly,
1847 * so nobody increase the size of the MPI and we're safe to use an on-stack
1848 * buffer.
1849 */
Alexander K35d6d462019-10-31 14:46:45 +03001850 T2.s = 1;
Alexander Kd19a1932019-11-01 18:20:42 +03001851 T2.n = sizeof( TP2 ) / sizeof( *TP2 );
1852 T2.p = TP2;
Paul Bakker5121ce52009-01-03 21:22:43 +00001853
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001854 if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001855 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001856 if( Q != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_lset( Q, 0 ) );
1857 if( R != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, A ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001858 return( 0 );
1859 }
1860
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001861 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &X, A ) );
1862 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, B ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001863 X.s = Y.s = 1;
1864
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001865 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &Z, A->n + 2 ) );
1866 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Z, 0 ) );
Gilles Peskine2536aa72020-07-24 00:12:59 +02001867 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, A->n + 2 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001868
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02001869 k = mbedtls_mpi_bitlen( &Y ) % biL;
Paul Bakkerf9688572011-05-05 10:00:45 +00001870 if( k < biL - 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001871 {
1872 k = biL - 1 - k;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001873 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &X, k ) );
1874 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, k ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001875 }
1876 else k = 0;
1877
1878 n = X.n - 1;
1879 t = Y.n - 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001880 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, biL * ( n - t ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001881
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001882 while( mbedtls_mpi_cmp_mpi( &X, &Y ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001883 {
1884 Z.p[n - t]++;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001885 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &Y ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001886 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001887 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, biL * ( n - t ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001888
1889 for( i = n; i > t ; i-- )
1890 {
1891 if( X.p[i] >= Y.p[t] )
1892 Z.p[i - t - 1] = ~0;
1893 else
1894 {
Simon Butcher15b15d12015-11-26 19:35:03 +00001895 Z.p[i - t - 1] = mbedtls_int_div_int( X.p[i], X.p[i - 1],
1896 Y.p[t], NULL);
Paul Bakker5121ce52009-01-03 21:22:43 +00001897 }
1898
Alexander K35d6d462019-10-31 14:46:45 +03001899 T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
1900 T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
1901 T2.p[2] = X.p[i];
1902
Paul Bakker5121ce52009-01-03 21:22:43 +00001903 Z.p[i - t - 1]++;
1904 do
1905 {
1906 Z.p[i - t - 1]--;
1907
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001908 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T1, 0 ) );
Paul Bakker66d5d072014-06-17 16:39:18 +02001909 T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00001910 T1.p[1] = Y.p[t];
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001911 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001912 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001913 while( mbedtls_mpi_cmp_mpi( &T1, &T2 ) > 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00001914
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001915 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1916 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
1917 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001918
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001919 if( mbedtls_mpi_cmp_int( &X, 0 ) < 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001920 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001921 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &Y ) );
1922 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
1923 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &X, &X, &T1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001924 Z.p[i - t - 1]--;
1925 }
1926 }
1927
1928 if( Q != NULL )
1929 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001930 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( Q, &Z ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001931 Q->s = A->s * B->s;
1932 }
1933
1934 if( R != NULL )
1935 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001936 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &X, k ) );
Paul Bakkerf02c5642012-11-13 10:25:21 +00001937 X.s = A->s;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001938 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, &X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001939
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001940 if( mbedtls_mpi_cmp_int( R, 0 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00001941 R->s = 1;
1942 }
1943
1944cleanup:
1945
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001946 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
Alexander K35d6d462019-10-31 14:46:45 +03001947 mbedtls_mpi_free( &T1 );
Alexander Kd19a1932019-11-01 18:20:42 +03001948 mbedtls_platform_zeroize( TP2, sizeof( TP2 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001949
1950 return( ret );
1951}
1952
1953/*
1954 * Division by int: A = Q * b + R
Paul Bakker5121ce52009-01-03 21:22:43 +00001955 */
Hanno Becker73d7d792018-12-11 10:35:51 +00001956int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R,
1957 const mbedtls_mpi *A,
1958 mbedtls_mpi_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00001959{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001960 mbedtls_mpi _B;
1961 mbedtls_mpi_uint p[1];
Hanno Becker73d7d792018-12-11 10:35:51 +00001962 MPI_VALIDATE_RET( A != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001963
1964 p[0] = ( b < 0 ) ? -b : b;
1965 _B.s = ( b < 0 ) ? -1 : 1;
1966 _B.n = 1;
1967 _B.p = p;
1968
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001969 return( mbedtls_mpi_div_mpi( Q, R, A, &_B ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001970}
1971
1972/*
1973 * Modulo: R = A mod B
1974 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001975int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00001976{
Janos Follath24eed8d2019-11-22 13:21:35 +00001977 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker73d7d792018-12-11 10:35:51 +00001978 MPI_VALIDATE_RET( R != NULL );
1979 MPI_VALIDATE_RET( A != NULL );
1980 MPI_VALIDATE_RET( B != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00001981
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001982 if( mbedtls_mpi_cmp_int( B, 0 ) < 0 )
1983 return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
Paul Bakkerce40a6d2009-06-23 19:46:08 +00001984
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001985 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( NULL, R, A, B ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001986
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001987 while( mbedtls_mpi_cmp_int( R, 0 ) < 0 )
1988 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001989
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02001990 while( mbedtls_mpi_cmp_mpi( R, B ) >= 0 )
1991 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001992
1993cleanup:
1994
1995 return( ret );
1996}
1997
1998/*
1999 * Modulo: r = A mod b
2000 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002001int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b )
Paul Bakker5121ce52009-01-03 21:22:43 +00002002{
Paul Bakker23986e52011-04-24 08:57:21 +00002003 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002004 mbedtls_mpi_uint x, y, z;
Hanno Becker73d7d792018-12-11 10:35:51 +00002005 MPI_VALIDATE_RET( r != NULL );
2006 MPI_VALIDATE_RET( A != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00002007
2008 if( b == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002009 return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00002010
2011 if( b < 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002012 return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002013
2014 /*
2015 * handle trivial cases
2016 */
2017 if( b == 1 )
2018 {
2019 *r = 0;
2020 return( 0 );
2021 }
2022
2023 if( b == 2 )
2024 {
2025 *r = A->p[0] & 1;
2026 return( 0 );
2027 }
2028
2029 /*
2030 * general case
2031 */
Paul Bakker23986e52011-04-24 08:57:21 +00002032 for( i = A->n, y = 0; i > 0; i-- )
Paul Bakker5121ce52009-01-03 21:22:43 +00002033 {
Paul Bakker23986e52011-04-24 08:57:21 +00002034 x = A->p[i - 1];
Paul Bakker5121ce52009-01-03 21:22:43 +00002035 y = ( y << biH ) | ( x >> biH );
2036 z = y / b;
2037 y -= z * b;
2038
2039 x <<= biH;
2040 y = ( y << biH ) | ( x >> biH );
2041 z = y / b;
2042 y -= z * b;
2043 }
2044
Paul Bakkerce40a6d2009-06-23 19:46:08 +00002045 /*
2046 * If A is negative, then the current y represents a negative value.
2047 * Flipping it to the positive side.
2048 */
2049 if( A->s < 0 && y != 0 )
2050 y = b - y;
2051
Paul Bakker5121ce52009-01-03 21:22:43 +00002052 *r = y;
2053
2054 return( 0 );
2055}
2056
2057/*
2058 * Fast Montgomery initialization (thanks to Tom St Denis)
2059 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002060static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00002061{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002062 mbedtls_mpi_uint x, m0 = N->p[0];
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01002063 unsigned int i;
Paul Bakker5121ce52009-01-03 21:22:43 +00002064
2065 x = m0;
2066 x += ( ( m0 + 2 ) & 4 ) << 1;
Paul Bakker5121ce52009-01-03 21:22:43 +00002067
Manuel Pégourié-Gonnardfdf3f0e2014-03-11 13:47:05 +01002068 for( i = biL; i >= 8; i /= 2 )
2069 x *= ( 2 - ( m0 * x ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002070
2071 *mm = ~x + 1;
2072}
2073
Gilles Peskine2a82f722020-06-04 15:00:49 +02002074/** Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
2075 *
2076 * \param[in,out] A One of the numbers to multiply.
Gilles Peskine221626f2020-06-08 22:37:50 +02002077 * It must have at least as many limbs as N
2078 * (A->n >= N->n), and any limbs beyond n are ignored.
Gilles Peskine2a82f722020-06-04 15:00:49 +02002079 * On successful completion, A contains the result of
2080 * the multiplication A * B * R^-1 mod N where
2081 * R = (2^ciL)^n.
2082 * \param[in] B One of the numbers to multiply.
2083 * It must be nonzero and must not have more limbs than N
2084 * (B->n <= N->n).
2085 * \param[in] N The modulo. N must be odd.
2086 * \param mm The value calculated by `mpi_montg_init(&mm, N)`.
2087 * This is -N^-1 mod 2^ciL.
2088 * \param[in,out] T A bignum for temporary storage.
2089 * It must be at least twice the limb size of N plus 2
2090 * (T->n >= 2 * (N->n + 1)).
2091 * Its initial content is unused and
2092 * its final content is indeterminate.
2093 * Note that unlike the usual convention in the library
2094 * for `const mbedtls_mpi*`, the content of T can change.
Paul Bakker5121ce52009-01-03 21:22:43 +00002095 */
Gilles Peskine4e91d472020-06-04 20:55:15 +02002096static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002097 const mbedtls_mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00002098{
Paul Bakker23986e52011-04-24 08:57:21 +00002099 size_t i, n, m;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002100 mbedtls_mpi_uint u0, u1, *d;
Paul Bakker5121ce52009-01-03 21:22:43 +00002101
2102 memset( T->p, 0, T->n * ciL );
2103
2104 d = T->p;
2105 n = N->n;
2106 m = ( B->n < n ) ? B->n : n;
2107
2108 for( i = 0; i < n; i++ )
2109 {
2110 /*
2111 * T = (T + u0*B + u1*N) / 2^biL
2112 */
2113 u0 = A->p[i];
2114 u1 = ( d[0] + u0 * B->p[0] ) * mm;
2115
2116 mpi_mul_hlp( m, B->p, d, u0 );
2117 mpi_mul_hlp( n, N->p, d, u1 );
2118
2119 *d++ = u0; d[n + 1] = 0;
2120 }
2121
Gilles Peskine221626f2020-06-08 22:37:50 +02002122 /* At this point, d is either the desired result or the desired result
2123 * plus N. We now potentially subtract N, avoiding leaking whether the
2124 * subtraction is performed through side channels. */
Paul Bakker5121ce52009-01-03 21:22:43 +00002125
Gilles Peskine221626f2020-06-08 22:37:50 +02002126 /* Copy the n least significant limbs of d to A, so that
2127 * A = d if d < N (recall that N has n limbs). */
2128 memcpy( A->p, d, n * ciL );
Gilles Peskine09ec10a2020-06-09 10:39:38 +02002129 /* If d >= N then we want to set A to d - N. To prevent timing attacks,
Gilles Peskine221626f2020-06-08 22:37:50 +02002130 * do the calculation without using conditional tests. */
2131 /* Set d to d0 + (2^biL)^n - N where d0 is the current value of d. */
Gilles Peskine132c0972020-06-04 21:05:24 +02002132 d[n] += 1;
Gilles Peskine1acf7cb2020-07-23 01:03:22 +02002133 d[n] -= mpi_sub_hlp( n, d, d, N->p );
Gilles Peskine221626f2020-06-08 22:37:50 +02002134 /* If d0 < N then d < (2^biL)^n
2135 * so d[n] == 0 and we want to keep A as it is.
2136 * If d0 >= N then d >= (2^biL)^n, and d <= (2^biL)^n + N < 2 * (2^biL)^n
2137 * so d[n] == 1 and we want to set A to the result of the subtraction
2138 * which is d - (2^biL)^n, i.e. the n least significant limbs of d.
2139 * This exactly corresponds to a conditional assignment. */
2140 mpi_safe_cond_assign( n, A->p, d, (unsigned char) d[n] );
Paul Bakker5121ce52009-01-03 21:22:43 +00002141}
2142
2143/*
2144 * Montgomery reduction: A = A * R^-1 mod N
Gilles Peskine2a82f722020-06-04 15:00:49 +02002145 *
2146 * See mpi_montmul() regarding constraints and guarantees on the parameters.
Paul Bakker5121ce52009-01-03 21:22:43 +00002147 */
Gilles Peskine4e91d472020-06-04 20:55:15 +02002148static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N,
2149 mbedtls_mpi_uint mm, const mbedtls_mpi *T )
Paul Bakker5121ce52009-01-03 21:22:43 +00002150{
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002151 mbedtls_mpi_uint z = 1;
2152 mbedtls_mpi U;
Paul Bakker5121ce52009-01-03 21:22:43 +00002153
Paul Bakker8ddb6452013-02-27 14:56:33 +01002154 U.n = U.s = (int) z;
Paul Bakker5121ce52009-01-03 21:22:43 +00002155 U.p = &z;
2156
Gilles Peskine4e91d472020-06-04 20:55:15 +02002157 mpi_montmul( A, &U, N, mm, T );
Paul Bakker5121ce52009-01-03 21:22:43 +00002158}
2159
Manuel Pégourié-Gonnardeaafa492021-06-03 10:42:46 +02002160/*
2161 * Constant-flow boolean "equal" comparison:
2162 * return x == y
2163 *
2164 * This function can be used to write constant-time code by replacing branches
2165 * with bit operations - it can be used in conjunction with
2166 * mbedtls_ssl_cf_mask_from_bit().
2167 *
2168 * This function is implemented without using comparison operators, as those
2169 * might be translated to branches by some compilers on some platforms.
2170 */
2171static size_t mbedtls_mpi_cf_bool_eq( size_t x, size_t y )
2172{
2173 /* diff = 0 if x == y, non-zero otherwise */
2174 const size_t diff = x ^ y;
2175
2176 /* MSVC has a warning about unary minus on unsigned integer types,
2177 * but this is well-defined and precisely what we want to do here. */
2178#if defined(_MSC_VER)
2179#pragma warning( push )
2180#pragma warning( disable : 4146 )
2181#endif
2182
2183 /* diff_msb's most significant bit is equal to x != y */
2184 const size_t diff_msb = ( diff | -diff );
2185
2186#if defined(_MSC_VER)
2187#pragma warning( pop )
2188#endif
2189
2190 /* diff1 = (x != y) ? 1 : 0 */
2191 const size_t diff1 = diff_msb >> ( sizeof( diff_msb ) * 8 - 1 );
2192
2193 return( 1 ^ diff1 );
2194}
2195
Manuel Pégourié-Gonnarde10e8db2021-03-09 11:22:20 +01002196/**
2197 * Select an MPI from a table without leaking the index.
2198 *
2199 * This is functionally equivalent to mbedtls_mpi_copy(R, T[idx]) except it
2200 * reads the entire table in order to avoid leaking the value of idx to an
2201 * attacker able to observe memory access patterns.
2202 *
2203 * \param[out] R Where to write the selected MPI.
2204 * \param[in] T The table to read from.
2205 * \param[in] T_size The number of elements in the table.
2206 * \param[in] idx The index of the element to select;
2207 * this must satisfy 0 <= idx < T_size.
2208 *
2209 * \return \c 0 on success, or a negative error code.
2210 */
2211static int mpi_select( mbedtls_mpi *R, const mbedtls_mpi *T, size_t T_size, size_t idx )
2212{
2213 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2214
2215 for( size_t i = 0; i < T_size; i++ )
Manuel Pégourié-Gonnardeaafa492021-06-03 10:42:46 +02002216 {
2217 MBEDTLS_MPI_CHK( mbedtls_mpi_safe_cond_assign( R, &T[i],
2218 mbedtls_mpi_cf_bool_eq( i, idx ) ) );
2219 }
Manuel Pégourié-Gonnarde10e8db2021-03-09 11:22:20 +01002220
2221cleanup:
2222 return( ret );
2223}
2224
Paul Bakker5121ce52009-01-03 21:22:43 +00002225/*
2226 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
2227 */
Hanno Becker73d7d792018-12-11 10:35:51 +00002228int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A,
2229 const mbedtls_mpi *E, const mbedtls_mpi *N,
2230 mbedtls_mpi *_RR )
Paul Bakker5121ce52009-01-03 21:22:43 +00002231{
Janos Follath24eed8d2019-11-22 13:21:35 +00002232 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +00002233 size_t wbits, wsize, one = 1;
2234 size_t i, j, nblimbs;
2235 size_t bufsize, nbits;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002236 mbedtls_mpi_uint ei, mm, state;
Manuel Pégourié-Gonnarde10e8db2021-03-09 11:22:20 +01002237 mbedtls_mpi RR, T, W[ 1 << MBEDTLS_MPI_WINDOW_SIZE ], WW, Apos;
Paul Bakkerf6198c12012-05-16 08:02:29 +00002238 int neg;
Paul Bakker5121ce52009-01-03 21:22:43 +00002239
Hanno Becker73d7d792018-12-11 10:35:51 +00002240 MPI_VALIDATE_RET( X != NULL );
2241 MPI_VALIDATE_RET( A != NULL );
2242 MPI_VALIDATE_RET( E != NULL );
2243 MPI_VALIDATE_RET( N != NULL );
2244
Hanno Becker8d1dd1b2017-09-28 11:02:24 +01002245 if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 || ( N->p[0] & 1 ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002246 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002247
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002248 if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
2249 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
Paul Bakkerf6198c12012-05-16 08:02:29 +00002250
Chris Jones9246d042020-11-25 15:12:39 +00002251 if( mbedtls_mpi_bitlen( E ) > MBEDTLS_MPI_MAX_BITS ||
2252 mbedtls_mpi_bitlen( N ) > MBEDTLS_MPI_MAX_BITS )
2253 return ( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2254
Paul Bakkerf6198c12012-05-16 08:02:29 +00002255 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00002256 * Init temps and window size
2257 */
2258 mpi_montg_init( &mm, N );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002259 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T );
2260 mbedtls_mpi_init( &Apos );
Manuel Pégourié-Gonnarde10e8db2021-03-09 11:22:20 +01002261 mbedtls_mpi_init( &WW );
Paul Bakker5121ce52009-01-03 21:22:43 +00002262 memset( W, 0, sizeof( W ) );
2263
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02002264 i = mbedtls_mpi_bitlen( E );
Paul Bakker5121ce52009-01-03 21:22:43 +00002265
2266 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
2267 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
2268
Peter Kolbuse6bcad32018-12-11 14:01:44 -06002269#if( MBEDTLS_MPI_WINDOW_SIZE < 6 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002270 if( wsize > MBEDTLS_MPI_WINDOW_SIZE )
2271 wsize = MBEDTLS_MPI_WINDOW_SIZE;
Peter Kolbuse6bcad32018-12-11 14:01:44 -06002272#endif
Paul Bakkerb6d5f082011-11-25 11:52:11 +00002273
Paul Bakker5121ce52009-01-03 21:22:43 +00002274 j = N->n + 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002275 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
2276 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) );
2277 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002278
2279 /*
Paul Bakker50546922012-05-19 08:40:49 +00002280 * Compensate for negative A (and correct at the end)
2281 */
2282 neg = ( A->s == -1 );
Paul Bakker50546922012-05-19 08:40:49 +00002283 if( neg )
2284 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002285 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Apos, A ) );
Paul Bakker50546922012-05-19 08:40:49 +00002286 Apos.s = 1;
2287 A = &Apos;
2288 }
2289
2290 /*
Paul Bakker5121ce52009-01-03 21:22:43 +00002291 * If 1st call, pre-compute R^2 mod N
2292 */
2293 if( _RR == NULL || _RR->p == NULL )
2294 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002295 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &RR, 1 ) );
2296 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &RR, N->n * 2 * biL ) );
2297 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002298
2299 if( _RR != NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002300 memcpy( _RR, &RR, sizeof( mbedtls_mpi ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002301 }
2302 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002303 memcpy( &RR, _RR, sizeof( mbedtls_mpi ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002304
2305 /*
2306 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
2307 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002308 if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 )
2309 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
Paul Bakkerc2024f42014-01-23 20:38:35 +01002310 else
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002311 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002312
Gilles Peskine4e91d472020-06-04 20:55:15 +02002313 mpi_montmul( &W[1], &RR, N, mm, &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00002314
2315 /*
2316 * X = R^2 * R^-1 mod N = R mod N
2317 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002318 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) );
Gilles Peskine4e91d472020-06-04 20:55:15 +02002319 mpi_montred( X, N, mm, &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00002320
2321 if( wsize > 1 )
2322 {
2323 /*
2324 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
2325 */
Paul Bakker66d5d072014-06-17 16:39:18 +02002326 j = one << ( wsize - 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002327
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002328 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) );
2329 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002330
2331 for( i = 0; i < wsize - 1; i++ )
Gilles Peskine4e91d472020-06-04 20:55:15 +02002332 mpi_montmul( &W[j], &W[j], N, mm, &T );
Paul Bakker0d7702c2013-10-29 16:18:35 +01002333
Paul Bakker5121ce52009-01-03 21:22:43 +00002334 /*
2335 * W[i] = W[i - 1] * W[1]
2336 */
Paul Bakker66d5d072014-06-17 16:39:18 +02002337 for( i = j + 1; i < ( one << wsize ); i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00002338 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002339 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) );
2340 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002341
Gilles Peskine4e91d472020-06-04 20:55:15 +02002342 mpi_montmul( &W[i], &W[1], N, mm, &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00002343 }
2344 }
2345
2346 nblimbs = E->n;
2347 bufsize = 0;
2348 nbits = 0;
2349 wbits = 0;
2350 state = 0;
2351
2352 while( 1 )
2353 {
2354 if( bufsize == 0 )
2355 {
Paul Bakker0d7702c2013-10-29 16:18:35 +01002356 if( nblimbs == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002357 break;
2358
Paul Bakker0d7702c2013-10-29 16:18:35 +01002359 nblimbs--;
2360
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002361 bufsize = sizeof( mbedtls_mpi_uint ) << 3;
Paul Bakker5121ce52009-01-03 21:22:43 +00002362 }
2363
2364 bufsize--;
2365
2366 ei = (E->p[nblimbs] >> bufsize) & 1;
2367
2368 /*
2369 * skip leading 0s
2370 */
2371 if( ei == 0 && state == 0 )
2372 continue;
2373
2374 if( ei == 0 && state == 1 )
2375 {
2376 /*
2377 * out of window, square X
2378 */
Gilles Peskine4e91d472020-06-04 20:55:15 +02002379 mpi_montmul( X, X, N, mm, &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00002380 continue;
2381 }
2382
2383 /*
2384 * add ei to current window
2385 */
2386 state = 2;
2387
2388 nbits++;
Paul Bakker66d5d072014-06-17 16:39:18 +02002389 wbits |= ( ei << ( wsize - nbits ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002390
2391 if( nbits == wsize )
2392 {
2393 /*
2394 * X = X^wsize R^-1 mod N
2395 */
2396 for( i = 0; i < wsize; i++ )
Gilles Peskine4e91d472020-06-04 20:55:15 +02002397 mpi_montmul( X, X, N, mm, &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00002398
2399 /*
2400 * X = X * W[wbits] R^-1 mod N
2401 */
Manuel Pégourié-Gonnarde10e8db2021-03-09 11:22:20 +01002402 MBEDTLS_MPI_CHK( mpi_select( &WW, W, 1 << wsize, wbits ) );
2403 mpi_montmul( X, &WW, N, mm, &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00002404
2405 state--;
2406 nbits = 0;
2407 wbits = 0;
2408 }
2409 }
2410
2411 /*
2412 * process the remaining bits
2413 */
2414 for( i = 0; i < nbits; i++ )
2415 {
Gilles Peskine4e91d472020-06-04 20:55:15 +02002416 mpi_montmul( X, X, N, mm, &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00002417
2418 wbits <<= 1;
2419
Paul Bakker66d5d072014-06-17 16:39:18 +02002420 if( ( wbits & ( one << wsize ) ) != 0 )
Gilles Peskine4e91d472020-06-04 20:55:15 +02002421 mpi_montmul( X, &W[1], N, mm, &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00002422 }
2423
2424 /*
2425 * X = A^E * R * R^-1 mod N = A^E mod N
2426 */
Gilles Peskine4e91d472020-06-04 20:55:15 +02002427 mpi_montred( X, N, mm, &T );
Paul Bakker5121ce52009-01-03 21:22:43 +00002428
Hanno Beckera4af1c42017-04-18 09:07:45 +01002429 if( neg && E->n != 0 && ( E->p[0] & 1 ) != 0 )
Paul Bakkerf6198c12012-05-16 08:02:29 +00002430 {
2431 X->s = -1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002432 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) );
Paul Bakkerf6198c12012-05-16 08:02:29 +00002433 }
2434
Paul Bakker5121ce52009-01-03 21:22:43 +00002435cleanup:
2436
Paul Bakker66d5d072014-06-17 16:39:18 +02002437 for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002438 mbedtls_mpi_free( &W[i] );
Paul Bakker5121ce52009-01-03 21:22:43 +00002439
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002440 mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
Manuel Pégourié-Gonnarde10e8db2021-03-09 11:22:20 +01002441 mbedtls_mpi_free( &WW );
Paul Bakker6c591fa2011-05-05 11:49:20 +00002442
Paul Bakker75a28602014-03-31 12:08:17 +02002443 if( _RR == NULL || _RR->p == NULL )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002444 mbedtls_mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002445
2446 return( ret );
2447}
2448
Paul Bakker5121ce52009-01-03 21:22:43 +00002449/*
2450 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
2451 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002452int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B )
Paul Bakker5121ce52009-01-03 21:22:43 +00002453{
Janos Follath24eed8d2019-11-22 13:21:35 +00002454 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Paul Bakker23986e52011-04-24 08:57:21 +00002455 size_t lz, lzt;
Alexander Ke8ad49f2019-08-16 16:16:07 +03002456 mbedtls_mpi TA, TB;
Paul Bakker5121ce52009-01-03 21:22:43 +00002457
Hanno Becker73d7d792018-12-11 10:35:51 +00002458 MPI_VALIDATE_RET( G != NULL );
2459 MPI_VALIDATE_RET( A != NULL );
2460 MPI_VALIDATE_RET( B != NULL );
2461
Alexander Ke8ad49f2019-08-16 16:16:07 +03002462 mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00002463
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002464 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) );
2465 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002466
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002467 lz = mbedtls_mpi_lsb( &TA );
2468 lzt = mbedtls_mpi_lsb( &TB );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002469
Paul Bakker66d5d072014-06-17 16:39:18 +02002470 if( lzt < lz )
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002471 lz = lzt;
2472
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002473 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, lz ) );
2474 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, lz ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00002475
Paul Bakker5121ce52009-01-03 21:22:43 +00002476 TA.s = TB.s = 1;
2477
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002478 while( mbedtls_mpi_cmp_int( &TA, 0 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002479 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002480 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, mbedtls_mpi_lsb( &TA ) ) );
2481 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, mbedtls_mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002482
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002483 if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002484 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002485 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TA, &TA, &TB ) );
2486 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, 1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002487 }
2488 else
2489 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002490 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TB, &TB, &TA ) );
2491 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, 1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002492 }
2493 }
2494
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002495 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &TB, lz ) );
2496 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002497
2498cleanup:
2499
Alexander Ke8ad49f2019-08-16 16:16:07 +03002500 mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB );
Paul Bakker5121ce52009-01-03 21:22:43 +00002501
2502 return( ret );
2503}
2504
Gilles Peskine8f454702021-04-01 15:57:18 +02002505/* Fill X with n_bytes random bytes.
2506 * X must already have room for those bytes.
Gilles Peskine23422e42021-06-03 11:51:09 +02002507 * The ordering of the bytes returned from the RNG is suitable for
2508 * deterministic ECDSA (see RFC 6979 §3.3 and mbedtls_mpi_random()).
Gilles Peskinea16001e2021-04-13 21:55:35 +02002509 * The size and sign of X are unchanged.
Gilles Peskine8f454702021-04-01 15:57:18 +02002510 * n_bytes must not be 0.
2511 */
2512static int mpi_fill_random_internal(
2513 mbedtls_mpi *X, size_t n_bytes,
2514 int (*f_rng)(void *, unsigned char *, size_t), void *p_rng )
2515{
2516 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
2517 const size_t limbs = CHARS_TO_LIMBS( n_bytes );
2518 const size_t overhead = ( limbs * ciL ) - n_bytes;
2519
2520 if( X->n < limbs )
2521 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
Gilles Peskine8f454702021-04-01 15:57:18 +02002522
Gilles Peskinea16001e2021-04-13 21:55:35 +02002523 memset( X->p, 0, overhead );
2524 memset( (unsigned char *) X->p + limbs * ciL, 0, ( X->n - limbs ) * ciL );
Gilles Peskine8f454702021-04-01 15:57:18 +02002525 MBEDTLS_MPI_CHK( f_rng( p_rng, (unsigned char *) X->p + overhead, n_bytes ) );
2526 mpi_bigendian_to_host( X->p, limbs );
2527
2528cleanup:
2529 return( ret );
2530}
2531
Paul Bakker33dc46b2014-04-30 16:11:39 +02002532/*
2533 * Fill X with size bytes of random.
2534 *
2535 * Use a temporary bytes representation to make sure the result is the same
Paul Bakkerc37b0ac2014-05-01 14:19:23 +02002536 * regardless of the platform endianness (useful when f_rng is actually
Paul Bakker33dc46b2014-04-30 16:11:39 +02002537 * deterministic, eg for tests).
2538 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002539int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002540 int (*f_rng)(void *, unsigned char *, size_t),
2541 void *p_rng )
Paul Bakker287781a2011-03-26 13:18:49 +00002542{
Janos Follath24eed8d2019-11-22 13:21:35 +00002543 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Hanno Becker6dab6202019-01-02 16:42:29 +00002544 size_t const limbs = CHARS_TO_LIMBS( size );
Hanno Beckerda1655a2017-10-18 14:21:44 +01002545
Hanno Becker8ce11a32018-12-19 16:18:52 +00002546 MPI_VALIDATE_RET( X != NULL );
Hanno Becker73d7d792018-12-11 10:35:51 +00002547 MPI_VALIDATE_RET( f_rng != NULL );
Paul Bakker33dc46b2014-04-30 16:11:39 +02002548
Hanno Beckerda1655a2017-10-18 14:21:44 +01002549 /* Ensure that target MPI has exactly the necessary number of limbs */
Gilles Peskine3130ce22021-06-02 22:17:52 +02002550 MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, limbs ) );
Gilles Peskine8f454702021-04-01 15:57:18 +02002551 if( size == 0 )
2552 return( 0 );
Paul Bakker287781a2011-03-26 13:18:49 +00002553
Gilles Peskine8f454702021-04-01 15:57:18 +02002554 ret = mpi_fill_random_internal( X, size, f_rng, p_rng );
Paul Bakker287781a2011-03-26 13:18:49 +00002555
2556cleanup:
2557 return( ret );
2558}
2559
Gilles Peskine4699fa42021-03-29 22:02:55 +02002560int mbedtls_mpi_random( mbedtls_mpi *X,
2561 mbedtls_mpi_sint min,
2562 const mbedtls_mpi *N,
2563 int (*f_rng)(void *, unsigned char *, size_t),
2564 void *p_rng )
2565{
Gilles Peskine4699fa42021-03-29 22:02:55 +02002566 int ret = MBEDTLS_ERR_MPI_BAD_INPUT_DATA;
Gilles Peskinee39ee8e2021-04-13 21:23:25 +02002567 int count;
Gilles Peskine74f66bb2021-04-13 21:09:10 +02002568 unsigned lt_lower = 1, lt_upper = 0;
Gilles Peskine4699fa42021-03-29 22:02:55 +02002569 size_t n_bits = mbedtls_mpi_bitlen( N );
2570 size_t n_bytes = ( n_bits + 7 ) / 8;
Gilles Peskine74f66bb2021-04-13 21:09:10 +02002571 mbedtls_mpi lower_bound;
Gilles Peskine4699fa42021-03-29 22:02:55 +02002572
Gilles Peskine9312ba52021-03-29 22:14:51 +02002573 if( min < 0 )
2574 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2575 if( mbedtls_mpi_cmp_int( N, min ) <= 0 )
2576 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2577
Gilles Peskinee39ee8e2021-04-13 21:23:25 +02002578 /*
2579 * When min == 0, each try has at worst a probability 1/2 of failing
2580 * (the msb has a probability 1/2 of being 0, and then the result will
2581 * be < N), so after 30 tries failure probability is a most 2**(-30).
2582 *
2583 * When N is just below a power of 2, as is the case when generating
Gilles Peskine3f613632021-04-15 11:45:19 +02002584 * a random scalar on most elliptic curves, 1 try is enough with
Gilles Peskinee39ee8e2021-04-13 21:23:25 +02002585 * overwhelming probability. When N is just above a power of 2,
Gilles Peskine3f613632021-04-15 11:45:19 +02002586 * as when generating a random scalar on secp224k1, each try has
Gilles Peskinee39ee8e2021-04-13 21:23:25 +02002587 * a probability of failing that is almost 1/2.
2588 *
2589 * The probabilities are almost the same if min is nonzero but negligible
2590 * compared to N. This is always the case when N is crypto-sized, but
2591 * it's convenient to support small N for testing purposes. When N
2592 * is small, use a higher repeat count, otherwise the probability of
2593 * failure is macroscopic.
2594 */
Gilles Peskine11779072021-06-02 21:18:59 +02002595 count = ( n_bytes > 4 ? 30 : 250 );
Gilles Peskinee39ee8e2021-04-13 21:23:25 +02002596
Gilles Peskine74f66bb2021-04-13 21:09:10 +02002597 mbedtls_mpi_init( &lower_bound );
2598
Gilles Peskine8f454702021-04-01 15:57:18 +02002599 /* Ensure that target MPI has exactly the same number of limbs
2600 * as the upper bound, even if the upper bound has leading zeros.
2601 * This is necessary for the mbedtls_mpi_lt_mpi_ct() check. */
Gilles Peskine3130ce22021-06-02 22:17:52 +02002602 MBEDTLS_MPI_CHK( mbedtls_mpi_resize_clear( X, N->n ) );
Gilles Peskine74f66bb2021-04-13 21:09:10 +02002603 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &lower_bound, N->n ) );
2604 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &lower_bound, min ) );
Gilles Peskine8f454702021-04-01 15:57:18 +02002605
Gilles Peskine4699fa42021-03-29 22:02:55 +02002606 /*
2607 * Match the procedure given in RFC 6979 §3.3 (deterministic ECDSA)
2608 * when f_rng is a suitably parametrized instance of HMAC_DRBG:
2609 * - use the same byte ordering;
2610 * - keep the leftmost n_bits bits of the generated octet string;
2611 * - try until result is in the desired range.
2612 * This also avoids any bias, which is especially important for ECDSA.
2613 */
2614 do
2615 {
Gilles Peskine8f454702021-04-01 15:57:18 +02002616 MBEDTLS_MPI_CHK( mpi_fill_random_internal( X, n_bytes, f_rng, p_rng ) );
Gilles Peskine4699fa42021-03-29 22:02:55 +02002617 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, 8 * n_bytes - n_bits ) );
2618
Gilles Peskinee39ee8e2021-04-13 21:23:25 +02002619 if( --count == 0 )
Gilles Peskine4699fa42021-03-29 22:02:55 +02002620 {
2621 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2622 goto cleanup;
2623 }
2624
Gilles Peskine74f66bb2021-04-13 21:09:10 +02002625 MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, &lower_bound, &lt_lower ) );
2626 MBEDTLS_MPI_CHK( mbedtls_mpi_lt_mpi_ct( X, N, &lt_upper ) );
Gilles Peskine4699fa42021-03-29 22:02:55 +02002627 }
Gilles Peskine74f66bb2021-04-13 21:09:10 +02002628 while( lt_lower != 0 || lt_upper == 0 );
Gilles Peskine4699fa42021-03-29 22:02:55 +02002629
2630cleanup:
Gilles Peskine74f66bb2021-04-13 21:09:10 +02002631 mbedtls_mpi_free( &lower_bound );
Gilles Peskine4699fa42021-03-29 22:02:55 +02002632 return( ret );
2633}
2634
Paul Bakker5121ce52009-01-03 21:22:43 +00002635/*
2636 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
2637 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002638int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N )
Paul Bakker5121ce52009-01-03 21:22:43 +00002639{
Janos Follath24eed8d2019-11-22 13:21:35 +00002640 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002641 mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
Hanno Becker73d7d792018-12-11 10:35:51 +00002642 MPI_VALIDATE_RET( X != NULL );
2643 MPI_VALIDATE_RET( A != NULL );
2644 MPI_VALIDATE_RET( N != NULL );
Paul Bakker5121ce52009-01-03 21:22:43 +00002645
Hanno Becker4bcb4912017-04-18 15:49:39 +01002646 if( mbedtls_mpi_cmp_int( N, 1 ) <= 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002647 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002648
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002649 mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TU ); mbedtls_mpi_init( &U1 ); mbedtls_mpi_init( &U2 );
2650 mbedtls_mpi_init( &G ); mbedtls_mpi_init( &TB ); mbedtls_mpi_init( &TV );
2651 mbedtls_mpi_init( &V1 ); mbedtls_mpi_init( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002652
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002653 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, A, N ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002654
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002655 if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002656 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002657 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002658 goto cleanup;
2659 }
2660
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002661 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &TA, A, N ) );
2662 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TU, &TA ) );
2663 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, N ) );
2664 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TV, N ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002665
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002666 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U1, 1 ) );
2667 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U2, 0 ) );
2668 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V1, 0 ) );
2669 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V2, 1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002670
2671 do
2672 {
2673 while( ( TU.p[0] & 1 ) == 0 )
2674 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002675 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TU, 1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002676
2677 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
2678 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002679 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &U1, &U1, &TB ) );
2680 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &TA ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002681 }
2682
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002683 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U1, 1 ) );
2684 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U2, 1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002685 }
2686
2687 while( ( TV.p[0] & 1 ) == 0 )
2688 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002689 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TV, 1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002690
2691 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
2692 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002693 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, &TB ) );
2694 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &TA ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002695 }
2696
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002697 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V1, 1 ) );
2698 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V2, 1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002699 }
2700
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002701 if( mbedtls_mpi_cmp_mpi( &TU, &TV ) >= 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002702 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002703 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TU, &TU, &TV ) );
2704 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U1, &U1, &V1 ) );
2705 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &V2 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002706 }
2707 else
2708 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002709 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TV, &TV, &TU ) );
2710 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, &U1 ) );
2711 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &U2 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002712 }
2713 }
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002714 while( mbedtls_mpi_cmp_int( &TU, 0 ) != 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002715
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002716 while( mbedtls_mpi_cmp_int( &V1, 0 ) < 0 )
2717 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, N ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002718
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002719 while( mbedtls_mpi_cmp_mpi( &V1, N ) >= 0 )
2720 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, N ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002721
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002722 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &V1 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002723
2724cleanup:
2725
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002726 mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TU ); mbedtls_mpi_free( &U1 ); mbedtls_mpi_free( &U2 );
2727 mbedtls_mpi_free( &G ); mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TV );
2728 mbedtls_mpi_free( &V1 ); mbedtls_mpi_free( &V2 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002729
2730 return( ret );
2731}
2732
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002733#if defined(MBEDTLS_GENPRIME)
Paul Bakkerd9374b02012-11-02 11:02:58 +00002734
Paul Bakker5121ce52009-01-03 21:22:43 +00002735static const int small_prime[] =
2736{
2737 3, 5, 7, 11, 13, 17, 19, 23,
2738 29, 31, 37, 41, 43, 47, 53, 59,
2739 61, 67, 71, 73, 79, 83, 89, 97,
2740 101, 103, 107, 109, 113, 127, 131, 137,
2741 139, 149, 151, 157, 163, 167, 173, 179,
2742 181, 191, 193, 197, 199, 211, 223, 227,
2743 229, 233, 239, 241, 251, 257, 263, 269,
2744 271, 277, 281, 283, 293, 307, 311, 313,
2745 317, 331, 337, 347, 349, 353, 359, 367,
2746 373, 379, 383, 389, 397, 401, 409, 419,
2747 421, 431, 433, 439, 443, 449, 457, 461,
2748 463, 467, 479, 487, 491, 499, 503, 509,
2749 521, 523, 541, 547, 557, 563, 569, 571,
2750 577, 587, 593, 599, 601, 607, 613, 617,
2751 619, 631, 641, 643, 647, 653, 659, 661,
2752 673, 677, 683, 691, 701, 709, 719, 727,
2753 733, 739, 743, 751, 757, 761, 769, 773,
2754 787, 797, 809, 811, 821, 823, 827, 829,
2755 839, 853, 857, 859, 863, 877, 881, 883,
2756 887, 907, 911, 919, 929, 937, 941, 947,
2757 953, 967, 971, 977, 983, 991, 997, -103
2758};
2759
2760/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002761 * Small divisors test (X must be positive)
2762 *
2763 * Return values:
2764 * 0: no small factor (possible prime, more tests needed)
2765 * 1: certain prime
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002766 * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002767 * other negative: error
Paul Bakker5121ce52009-01-03 21:22:43 +00002768 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002769static int mpi_check_small_factors( const mbedtls_mpi *X )
Paul Bakker5121ce52009-01-03 21:22:43 +00002770{
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002771 int ret = 0;
2772 size_t i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002773 mbedtls_mpi_uint r;
Paul Bakker5121ce52009-01-03 21:22:43 +00002774
Paul Bakker5121ce52009-01-03 21:22:43 +00002775 if( ( X->p[0] & 1 ) == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002776 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002777
2778 for( i = 0; small_prime[i] > 0; i++ )
2779 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002780 if( mbedtls_mpi_cmp_int( X, small_prime[i] ) <= 0 )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002781 return( 1 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002782
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002783 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, small_prime[i] ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002784
2785 if( r == 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002786 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00002787 }
2788
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002789cleanup:
2790 return( ret );
2791}
2792
2793/*
2794 * Miller-Rabin pseudo-primality test (HAC 4.24)
2795 */
Janos Follathda31fa12018-09-03 14:45:23 +01002796static int mpi_miller_rabin( const mbedtls_mpi *X, size_t rounds,
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002797 int (*f_rng)(void *, unsigned char *, size_t),
2798 void *p_rng )
2799{
Pascal Junodb99183d2015-03-11 16:49:45 +01002800 int ret, count;
Janos Follathda31fa12018-09-03 14:45:23 +01002801 size_t i, j, k, s;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002802 mbedtls_mpi W, R, T, A, RR;
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002803
Hanno Becker8ce11a32018-12-19 16:18:52 +00002804 MPI_VALIDATE_RET( X != NULL );
Hanno Becker73d7d792018-12-11 10:35:51 +00002805 MPI_VALIDATE_RET( f_rng != NULL );
2806
2807 mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R );
2808 mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002809 mbedtls_mpi_init( &RR );
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002810
Paul Bakker5121ce52009-01-03 21:22:43 +00002811 /*
2812 * W = |X| - 1
2813 * R = W >> lsb( W )
2814 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002815 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &W, X, 1 ) );
2816 s = mbedtls_mpi_lsb( &W );
2817 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R, &W ) );
2818 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002819
Janos Follathda31fa12018-09-03 14:45:23 +01002820 for( i = 0; i < rounds; i++ )
Paul Bakker5121ce52009-01-03 21:22:43 +00002821 {
2822 /*
2823 * pick a random A, 1 < A < |X| - 1
2824 */
Pascal Junodb99183d2015-03-11 16:49:45 +01002825 count = 0;
2826 do {
Manuel Pégourié-Gonnard53c76c02015-04-17 20:15:36 +02002827 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
Pascal Junodb99183d2015-03-11 16:49:45 +01002828
Manuel Pégourié-Gonnardc0696c22015-06-18 16:47:17 +02002829 j = mbedtls_mpi_bitlen( &A );
2830 k = mbedtls_mpi_bitlen( &W );
Pascal Junodb99183d2015-03-11 16:49:45 +01002831 if (j > k) {
Darryl Greene3f95ed2018-10-02 13:21:35 +01002832 A.p[A.n - 1] &= ( (mbedtls_mpi_uint) 1 << ( k - ( A.n - 1 ) * biL - 1 ) ) - 1;
Pascal Junodb99183d2015-03-11 16:49:45 +01002833 }
2834
2835 if (count++ > 30) {
Jens Wiklanderf08aa3e2019-01-17 13:30:57 +01002836 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2837 goto cleanup;
Pascal Junodb99183d2015-03-11 16:49:45 +01002838 }
2839
Manuel Pégourié-Gonnard53c76c02015-04-17 20:15:36 +02002840 } while ( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 ||
2841 mbedtls_mpi_cmp_int( &A, 1 ) <= 0 );
Paul Bakker5121ce52009-01-03 21:22:43 +00002842
2843 /*
2844 * A = A^R mod |X|
2845 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002846 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &A, &A, &R, X, &RR ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002847
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002848 if( mbedtls_mpi_cmp_mpi( &A, &W ) == 0 ||
2849 mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002850 continue;
2851
2852 j = 1;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002853 while( j < s && mbedtls_mpi_cmp_mpi( &A, &W ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002854 {
2855 /*
2856 * A = A * A mod |X|
2857 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002858 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &A, &A ) );
2859 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &A, &T, X ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00002860
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002861 if( mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002862 break;
2863
2864 j++;
2865 }
2866
2867 /*
2868 * not prime if A != |X| - 1 or A == 1
2869 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002870 if( mbedtls_mpi_cmp_mpi( &A, &W ) != 0 ||
2871 mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002872 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002873 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00002874 break;
2875 }
2876 }
2877
2878cleanup:
Hanno Becker73d7d792018-12-11 10:35:51 +00002879 mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R );
2880 mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A );
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002881 mbedtls_mpi_free( &RR );
Paul Bakker5121ce52009-01-03 21:22:43 +00002882
2883 return( ret );
2884}
2885
2886/*
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002887 * Pseudo-primality test: small factors, then Miller-Rabin
2888 */
Janos Follatha0b67c22018-09-18 14:48:23 +01002889int mbedtls_mpi_is_prime_ext( const mbedtls_mpi *X, int rounds,
2890 int (*f_rng)(void *, unsigned char *, size_t),
2891 void *p_rng )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002892{
Janos Follath24eed8d2019-11-22 13:21:35 +00002893 int ret = MBEDTLS_ERR_ERROR_CORRUPTION_DETECTED;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002894 mbedtls_mpi XX;
Hanno Becker8ce11a32018-12-19 16:18:52 +00002895 MPI_VALIDATE_RET( X != NULL );
Hanno Becker73d7d792018-12-11 10:35:51 +00002896 MPI_VALIDATE_RET( f_rng != NULL );
Manuel Pégourié-Gonnard7f4ed672014-10-14 20:56:02 +02002897
2898 XX.s = 1;
2899 XX.n = X->n;
2900 XX.p = X->p;
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002901
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002902 if( mbedtls_mpi_cmp_int( &XX, 0 ) == 0 ||
2903 mbedtls_mpi_cmp_int( &XX, 1 ) == 0 )
2904 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002905
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002906 if( mbedtls_mpi_cmp_int( &XX, 2 ) == 0 )
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002907 return( 0 );
2908
2909 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2910 {
2911 if( ret == 1 )
2912 return( 0 );
2913
2914 return( ret );
2915 }
2916
Janos Follathda31fa12018-09-03 14:45:23 +01002917 return( mpi_miller_rabin( &XX, rounds, f_rng, p_rng ) );
Janos Follathf301d232018-08-14 13:34:01 +01002918}
2919
Janos Follatha0b67c22018-09-18 14:48:23 +01002920#if !defined(MBEDTLS_DEPRECATED_REMOVED)
Janos Follathf301d232018-08-14 13:34:01 +01002921/*
2922 * Pseudo-primality test, error probability 2^-80
2923 */
2924int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
2925 int (*f_rng)(void *, unsigned char *, size_t),
2926 void *p_rng )
2927{
Hanno Becker8ce11a32018-12-19 16:18:52 +00002928 MPI_VALIDATE_RET( X != NULL );
Hanno Becker73d7d792018-12-11 10:35:51 +00002929 MPI_VALIDATE_RET( f_rng != NULL );
2930
Janos Follatha0b67c22018-09-18 14:48:23 +01002931 /*
2932 * In the past our key generation aimed for an error rate of at most
2933 * 2^-80. Since this function is deprecated, aim for the same certainty
2934 * here as well.
2935 */
Hanno Becker73d7d792018-12-11 10:35:51 +00002936 return( mbedtls_mpi_is_prime_ext( X, 40, f_rng, p_rng ) );
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002937}
Janos Follatha0b67c22018-09-18 14:48:23 +01002938#endif
Manuel Pégourié-Gonnard378fb4b2013-11-22 18:39:18 +01002939
2940/*
Paul Bakker5121ce52009-01-03 21:22:43 +00002941 * Prime number generation
Jethro Beekman66689272018-02-14 19:24:10 -08002942 *
Janos Follathf301d232018-08-14 13:34:01 +01002943 * To generate an RSA key in a way recommended by FIPS 186-4, both primes must
2944 * be either 1024 bits or 1536 bits long, and flags must contain
2945 * MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR.
Paul Bakker5121ce52009-01-03 21:22:43 +00002946 */
Janos Follath7c025a92018-08-14 11:08:41 +01002947int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int flags,
Paul Bakkera3d195c2011-11-27 21:07:34 +00002948 int (*f_rng)(void *, unsigned char *, size_t),
2949 void *p_rng )
Paul Bakker5121ce52009-01-03 21:22:43 +00002950{
Jethro Beekman66689272018-02-14 19:24:10 -08002951#ifdef MBEDTLS_HAVE_INT64
2952// ceil(2^63.5)
2953#define CEIL_MAXUINT_DIV_SQRT2 0xb504f333f9de6485ULL
2954#else
2955// ceil(2^31.5)
2956#define CEIL_MAXUINT_DIV_SQRT2 0xb504f334U
2957#endif
2958 int ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker23986e52011-04-24 08:57:21 +00002959 size_t k, n;
Janos Follathda31fa12018-09-03 14:45:23 +01002960 int rounds;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002961 mbedtls_mpi_uint r;
2962 mbedtls_mpi Y;
Paul Bakker5121ce52009-01-03 21:22:43 +00002963
Hanno Becker8ce11a32018-12-19 16:18:52 +00002964 MPI_VALIDATE_RET( X != NULL );
Hanno Becker73d7d792018-12-11 10:35:51 +00002965 MPI_VALIDATE_RET( f_rng != NULL );
2966
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002967 if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS )
2968 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00002969
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02002970 mbedtls_mpi_init( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00002971
2972 n = BITS_TO_LIMBS( nbits );
2973
Janos Follathda31fa12018-09-03 14:45:23 +01002974 if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_LOW_ERR ) == 0 )
2975 {
2976 /*
2977 * 2^-80 error probability, number of rounds chosen per HAC, table 4.4
2978 */
2979 rounds = ( ( nbits >= 1300 ) ? 2 : ( nbits >= 850 ) ? 3 :
2980 ( nbits >= 650 ) ? 4 : ( nbits >= 350 ) ? 8 :
2981 ( nbits >= 250 ) ? 12 : ( nbits >= 150 ) ? 18 : 27 );
2982 }
2983 else
2984 {
2985 /*
2986 * 2^-100 error probability, number of rounds computed based on HAC,
2987 * fact 4.48
2988 */
2989 rounds = ( ( nbits >= 1450 ) ? 4 : ( nbits >= 1150 ) ? 5 :
2990 ( nbits >= 1000 ) ? 6 : ( nbits >= 850 ) ? 7 :
2991 ( nbits >= 750 ) ? 8 : ( nbits >= 500 ) ? 13 :
2992 ( nbits >= 250 ) ? 28 : ( nbits >= 150 ) ? 40 : 51 );
2993 }
2994
Jethro Beekman66689272018-02-14 19:24:10 -08002995 while( 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00002996 {
Jethro Beekman66689272018-02-14 19:24:10 -08002997 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
2998 /* make sure generated number is at least (nbits-1)+0.5 bits (FIPS 186-4 §B.3.3 steps 4.4, 5.5) */
2999 if( X->p[n-1] < CEIL_MAXUINT_DIV_SQRT2 ) continue;
3000
3001 k = n * biL;
3002 if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits ) );
3003 X->p[0] |= 1;
3004
Janos Follath7c025a92018-08-14 11:08:41 +01003005 if( ( flags & MBEDTLS_MPI_GEN_PRIME_FLAG_DH ) == 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003006 {
Janos Follatha0b67c22018-09-18 14:48:23 +01003007 ret = mbedtls_mpi_is_prime_ext( X, rounds, f_rng, p_rng );
Jethro Beekman66689272018-02-14 19:24:10 -08003008
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003009 if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00003010 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00003011 }
Jethro Beekman66689272018-02-14 19:24:10 -08003012 else
Paul Bakker5121ce52009-01-03 21:22:43 +00003013 {
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01003014 /*
Jethro Beekman66689272018-02-14 19:24:10 -08003015 * An necessary condition for Y and X = 2Y + 1 to be prime
3016 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
3017 * Make sure it is satisfied, while keeping X = 3 mod 4
Manuel Pégourié-Gonnardddf76152013-11-22 19:58:22 +01003018 */
Jethro Beekman66689272018-02-14 19:24:10 -08003019
3020 X->p[0] |= 2;
3021
3022 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) );
3023 if( r == 0 )
3024 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) );
3025 else if( r == 1 )
3026 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) );
3027
3028 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
3029 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) );
3030 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) );
3031
3032 while( 1 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003033 {
Jethro Beekman66689272018-02-14 19:24:10 -08003034 /*
3035 * First, check small factors for X and Y
3036 * before doing Miller-Rabin on any of them
3037 */
3038 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
3039 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
Janos Follathda31fa12018-09-03 14:45:23 +01003040 ( ret = mpi_miller_rabin( X, rounds, f_rng, p_rng ) )
Janos Follathf301d232018-08-14 13:34:01 +01003041 == 0 &&
Janos Follathda31fa12018-09-03 14:45:23 +01003042 ( ret = mpi_miller_rabin( &Y, rounds, f_rng, p_rng ) )
Janos Follathf301d232018-08-14 13:34:01 +01003043 == 0 )
Jethro Beekman66689272018-02-14 19:24:10 -08003044 goto cleanup;
3045
3046 if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
3047 goto cleanup;
3048
3049 /*
3050 * Next candidates. We want to preserve Y = (X-1) / 2 and
3051 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
3052 * so up Y by 6 and X by 12.
3053 */
3054 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 12 ) );
3055 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003056 }
Paul Bakker5121ce52009-01-03 21:22:43 +00003057 }
3058 }
3059
3060cleanup:
3061
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003062 mbedtls_mpi_free( &Y );
Paul Bakker5121ce52009-01-03 21:22:43 +00003063
3064 return( ret );
3065}
3066
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003067#endif /* MBEDTLS_GENPRIME */
Paul Bakker5121ce52009-01-03 21:22:43 +00003068
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003069#if defined(MBEDTLS_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00003070
Paul Bakker23986e52011-04-24 08:57:21 +00003071#define GCD_PAIR_COUNT 3
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00003072
3073static const int gcd_pairs[GCD_PAIR_COUNT][3] =
3074{
3075 { 693, 609, 21 },
3076 { 1764, 868, 28 },
3077 { 768454923, 542167814, 1 }
3078};
3079
Paul Bakker5121ce52009-01-03 21:22:43 +00003080/*
3081 * Checkup routine
3082 */
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003083int mbedtls_mpi_self_test( int verbose )
Paul Bakker5121ce52009-01-03 21:22:43 +00003084{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00003085 int ret, i;
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003086 mbedtls_mpi A, E, N, X, Y, U, V;
Paul Bakker5121ce52009-01-03 21:22:43 +00003087
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003088 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N ); mbedtls_mpi_init( &X );
3089 mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &U ); mbedtls_mpi_init( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00003090
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003091 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &A, 16,
Paul Bakker5121ce52009-01-03 21:22:43 +00003092 "EFE021C2645FD1DC586E69184AF4A31E" \
3093 "D5F53E93B5F123FA41680867BA110131" \
3094 "944FE7952E2517337780CB0DB80E61AA" \
3095 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
3096
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003097 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &E, 16,
Paul Bakker5121ce52009-01-03 21:22:43 +00003098 "B2E7EFD37075B9F03FF989C7C5051C20" \
3099 "34D2A323810251127E7BF8625A4F49A5" \
3100 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
3101 "5B5C25763222FEFCCFC38B832366C29E" ) );
3102
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003103 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &N, 16,
Paul Bakker5121ce52009-01-03 21:22:43 +00003104 "0066A198186C18C10B2F5ED9B522752A" \
3105 "9830B69916E535C8F047518A889A43A5" \
3106 "94B6BED27A168D31D4A52F88925AA8F5" ) );
3107
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003108 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &A, &N ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003109
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003110 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
Paul Bakker5121ce52009-01-03 21:22:43 +00003111 "602AB7ECA597A3D6B56FF9829A5E8B85" \
3112 "9E857EA95A03512E2BAE7391688D264A" \
3113 "A5663B0341DB9CCFD2C4C5F421FEC814" \
3114 "8001B72E848A38CAE1C65F78E56ABDEF" \
3115 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
3116 "ECF677152EF804370C1A305CAF3B5BF1" \
3117 "30879B56C61DE584A0F53A2447A51E" ) );
3118
3119 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003120 mbedtls_printf( " MPI test #1 (mul_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00003121
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003122 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003123 {
3124 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003125 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00003126
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01003127 ret = 1;
3128 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00003129 }
3130
3131 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003132 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00003133
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003134 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &X, &Y, &A, &N ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003135
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003136 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
Paul Bakker5121ce52009-01-03 21:22:43 +00003137 "256567336059E52CAE22925474705F39A94" ) );
3138
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003139 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &V, 16,
Paul Bakker5121ce52009-01-03 21:22:43 +00003140 "6613F26162223DF488E9CD48CC132C7A" \
3141 "0AC93C701B001B092E4E5B9F73BCD27B" \
3142 "9EE50D0657C77F374E903CDFA4C642" ) );
3143
3144 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003145 mbedtls_printf( " MPI test #2 (div_mpi): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00003146
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003147 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ||
3148 mbedtls_mpi_cmp_mpi( &Y, &V ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003149 {
3150 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003151 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00003152
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01003153 ret = 1;
3154 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00003155 }
3156
3157 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003158 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00003159
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003160 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &X, &A, &E, &N, NULL ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003161
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003162 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
Paul Bakker5121ce52009-01-03 21:22:43 +00003163 "36E139AEA55215609D2816998ED020BB" \
3164 "BD96C37890F65171D948E9BC7CBAA4D9" \
3165 "325D24D6A3C12710F10A09FA08AB87" ) );
3166
3167 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003168 mbedtls_printf( " MPI test #3 (exp_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00003169
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003170 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003171 {
3172 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003173 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00003174
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01003175 ret = 1;
3176 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00003177 }
3178
3179 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003180 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00003181
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003182 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &X, &A, &N ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00003183
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003184 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
Paul Bakker5121ce52009-01-03 21:22:43 +00003185 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
3186 "C3DBA76456363A10869622EAC2DD84EC" \
3187 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
3188
3189 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003190 mbedtls_printf( " MPI test #4 (inv_mod): " );
Paul Bakker5121ce52009-01-03 21:22:43 +00003191
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003192 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
Paul Bakker5121ce52009-01-03 21:22:43 +00003193 {
3194 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003195 mbedtls_printf( "failed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00003196
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01003197 ret = 1;
3198 goto cleanup;
Paul Bakker5121ce52009-01-03 21:22:43 +00003199 }
3200
3201 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003202 mbedtls_printf( "passed\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00003203
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00003204 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003205 mbedtls_printf( " MPI test #5 (simple gcd): " );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00003206
Paul Bakker66d5d072014-06-17 16:39:18 +02003207 for( i = 0; i < GCD_PAIR_COUNT; i++ )
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00003208 {
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003209 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &X, gcd_pairs[i][0] ) );
3210 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Y, gcd_pairs[i][1] ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00003211
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003212 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &A, &X, &Y ) );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00003213
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003214 if( mbedtls_mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01003215 {
3216 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003217 mbedtls_printf( "failed at %d\n", i );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00003218
Manuel Pégourié-Gonnard9e987ed2014-01-20 10:03:15 +01003219 ret = 1;
3220 goto cleanup;
3221 }
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00003222 }
3223
3224 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003225 mbedtls_printf( "passed\n" );
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00003226
Paul Bakker5121ce52009-01-03 21:22:43 +00003227cleanup:
3228
3229 if( ret != 0 && verbose != 0 )
Kenneth Soerensen518d4352020-04-01 17:22:45 +02003230 mbedtls_printf( "Unexpected error, return code = %08X\n", (unsigned int) ret );
Paul Bakker5121ce52009-01-03 21:22:43 +00003231
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003232 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N ); mbedtls_mpi_free( &X );
3233 mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &U ); mbedtls_mpi_free( &V );
Paul Bakker5121ce52009-01-03 21:22:43 +00003234
3235 if( verbose != 0 )
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003236 mbedtls_printf( "\n" );
Paul Bakker5121ce52009-01-03 21:22:43 +00003237
3238 return( ret );
3239}
3240
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003241#endif /* MBEDTLS_SELF_TEST */
Paul Bakker5121ce52009-01-03 21:22:43 +00003242
Manuel Pégourié-Gonnard2cf5a7c2015-04-08 12:49:31 +02003243#endif /* MBEDTLS_BIGNUM_C */