This Trac instance is not used for development anymore!

We migrated our development workflow to git and Gitea.
To test the future redirection, replace trac by ariadne in the page URL.

source: ps/trunk/build/premake/premake5/contrib/mbedtls/library/bignum.c

Last change on this file was 20366, checked in by Itms, 7 years ago

Alpha 12 version of Premake 5, including prebuilt binary for Windows.
Directly taken from https://premake.github.io/.

Refs #3729.

File size: 56.3 KB
Line 
1/*
2 * Multi-precision integer library
3 *
4 * Copyright (C) 2006-2015, ARM Limited, All Rights Reserved
5 * 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.
18 *
19 * This file is part of mbed TLS (https://tls.mbed.org)
20 */
21
22/*
23 * The following sources were referenced in the design of this Multi-precision
24 * Integer library:
25 *
26 * [1] Handbook of Applied Cryptography - 1997
27 * Menezes, van Oorschot and Vanstone
28 *
29 * [2] Multi-Precision Math
30 * Tom St Denis
31 * https://github.com/libtom/libtommath/blob/develop/tommath.pdf
32 *
33 * [3] GNU Multi-Precision Arithmetic Library
34 * https://gmplib.org/manual/index.html
35 *
36 */
37
38#if !defined(MBEDTLS_CONFIG_FILE)
39#include "mbedtls/config.h"
40#else
41#include MBEDTLS_CONFIG_FILE
42#endif
43
44#if defined(MBEDTLS_BIGNUM_C)
45
46#include "mbedtls/bignum.h"
47#include "mbedtls/bn_mul.h"
48
49#include <string.h>
50
51#if defined(MBEDTLS_PLATFORM_C)
52#include "mbedtls/platform.h"
53#else
54#include <stdio.h>
55#include <stdlib.h>
56#define mbedtls_printf printf
57#define mbedtls_calloc calloc
58#define mbedtls_free free
59#endif
60
61/* Implementation that should never be optimized out by the compiler */
62static void mbedtls_zeroize( void *v, size_t n ) {
63 volatile unsigned char *p = v; while( n-- ) *p++ = 0;
64}
65
66#define ciL (sizeof(mbedtls_mpi_uint)) /* chars in limb */
67#define biL (ciL << 3) /* bits in limb */
68#define biH (ciL << 2) /* half limb size */
69
70#define MPI_SIZE_T_MAX ( (size_t) -1 ) /* SIZE_T_MAX is not standard */
71
72/*
73 * Convert between bits/chars and number of limbs
74 * Divide first in order to avoid potential overflows
75 */
76#define BITS_TO_LIMBS(i) ( (i) / biL + ( (i) % biL != 0 ) )
77#define CHARS_TO_LIMBS(i) ( (i) / ciL + ( (i) % ciL != 0 ) )
78
79/*
80 * Initialize one MPI
81 */
82void mbedtls_mpi_init( mbedtls_mpi *X )
83{
84 if( X == NULL )
85 return;
86
87 X->s = 1;
88 X->n = 0;
89 X->p = NULL;
90}
91
92/*
93 * Unallocate one MPI
94 */
95void mbedtls_mpi_free( mbedtls_mpi *X )
96{
97 if( X == NULL )
98 return;
99
100 if( X->p != NULL )
101 {
102 mbedtls_zeroize( X->p, X->n * ciL );
103 mbedtls_free( X->p );
104 }
105
106 X->s = 1;
107 X->n = 0;
108 X->p = NULL;
109}
110
111/*
112 * Enlarge to the specified number of limbs
113 */
114int mbedtls_mpi_grow( mbedtls_mpi *X, size_t nblimbs )
115{
116 mbedtls_mpi_uint *p;
117
118 if( nblimbs > MBEDTLS_MPI_MAX_LIMBS )
119 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
120
121 if( X->n < nblimbs )
122 {
123 if( ( p = mbedtls_calloc( nblimbs, ciL ) ) == NULL )
124 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
125
126 if( X->p != NULL )
127 {
128 memcpy( p, X->p, X->n * ciL );
129 mbedtls_zeroize( X->p, X->n * ciL );
130 mbedtls_free( X->p );
131 }
132
133 X->n = nblimbs;
134 X->p = p;
135 }
136
137 return( 0 );
138}
139
140/*
141 * Resize down as much as possible,
142 * while keeping at least the specified number of limbs
143 */
144int mbedtls_mpi_shrink( mbedtls_mpi *X, size_t nblimbs )
145{
146 mbedtls_mpi_uint *p;
147 size_t i;
148
149 /* Actually resize up in this case */
150 if( X->n <= nblimbs )
151 return( mbedtls_mpi_grow( X, nblimbs ) );
152
153 for( i = X->n - 1; i > 0; i-- )
154 if( X->p[i] != 0 )
155 break;
156 i++;
157
158 if( i < nblimbs )
159 i = nblimbs;
160
161 if( ( p = mbedtls_calloc( i, ciL ) ) == NULL )
162 return( MBEDTLS_ERR_MPI_ALLOC_FAILED );
163
164 if( X->p != NULL )
165 {
166 memcpy( p, X->p, i * ciL );
167 mbedtls_zeroize( X->p, X->n * ciL );
168 mbedtls_free( X->p );
169 }
170
171 X->n = i;
172 X->p = p;
173
174 return( 0 );
175}
176
177/*
178 * Copy the contents of Y into X
179 */
180int mbedtls_mpi_copy( mbedtls_mpi *X, const mbedtls_mpi *Y )
181{
182 int ret;
183 size_t i;
184
185 if( X == Y )
186 return( 0 );
187
188 if( Y->p == NULL )
189 {
190 mbedtls_mpi_free( X );
191 return( 0 );
192 }
193
194 for( i = Y->n - 1; i > 0; i-- )
195 if( Y->p[i] != 0 )
196 break;
197 i++;
198
199 X->s = Y->s;
200
201 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i ) );
202
203 memset( X->p, 0, X->n * ciL );
204 memcpy( X->p, Y->p, i * ciL );
205
206cleanup:
207
208 return( ret );
209}
210
211/*
212 * Swap the contents of X and Y
213 */
214void mbedtls_mpi_swap( mbedtls_mpi *X, mbedtls_mpi *Y )
215{
216 mbedtls_mpi T;
217
218 memcpy( &T, X, sizeof( mbedtls_mpi ) );
219 memcpy( X, Y, sizeof( mbedtls_mpi ) );
220 memcpy( Y, &T, sizeof( mbedtls_mpi ) );
221}
222
223/*
224 * Conditionally assign X = Y, without leaking information
225 * about whether the assignment was made or not.
226 * (Leaking information about the respective sizes of X and Y is ok however.)
227 */
228int mbedtls_mpi_safe_cond_assign( mbedtls_mpi *X, const mbedtls_mpi *Y, unsigned char assign )
229{
230 int ret = 0;
231 size_t i;
232
233 /* make sure assign is 0 or 1 in a time-constant manner */
234 assign = (assign | (unsigned char)-assign) >> 7;
235
236 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
237
238 X->s = X->s * ( 1 - assign ) + Y->s * assign;
239
240 for( i = 0; i < Y->n; i++ )
241 X->p[i] = X->p[i] * ( 1 - assign ) + Y->p[i] * assign;
242
243 for( ; i < X->n; i++ )
244 X->p[i] *= ( 1 - assign );
245
246cleanup:
247 return( ret );
248}
249
250/*
251 * Conditionally swap X and Y, without leaking information
252 * about whether the swap was made or not.
253 * Here it is not ok to simply swap the pointers, which whould lead to
254 * different memory access patterns when X and Y are used afterwards.
255 */
256int mbedtls_mpi_safe_cond_swap( mbedtls_mpi *X, mbedtls_mpi *Y, unsigned char swap )
257{
258 int ret, s;
259 size_t i;
260 mbedtls_mpi_uint tmp;
261
262 if( X == Y )
263 return( 0 );
264
265 /* make sure swap is 0 or 1 in a time-constant manner */
266 swap = (swap | (unsigned char)-swap) >> 7;
267
268 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, Y->n ) );
269 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( Y, X->n ) );
270
271 s = X->s;
272 X->s = X->s * ( 1 - swap ) + Y->s * swap;
273 Y->s = Y->s * ( 1 - swap ) + s * swap;
274
275
276 for( i = 0; i < X->n; i++ )
277 {
278 tmp = X->p[i];
279 X->p[i] = X->p[i] * ( 1 - swap ) + Y->p[i] * swap;
280 Y->p[i] = Y->p[i] * ( 1 - swap ) + tmp * swap;
281 }
282
283cleanup:
284 return( ret );
285}
286
287/*
288 * Set value from integer
289 */
290int mbedtls_mpi_lset( mbedtls_mpi *X, mbedtls_mpi_sint z )
291{
292 int ret;
293
294 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, 1 ) );
295 memset( X->p, 0, X->n * ciL );
296
297 X->p[0] = ( z < 0 ) ? -z : z;
298 X->s = ( z < 0 ) ? -1 : 1;
299
300cleanup:
301
302 return( ret );
303}
304
305/*
306 * Get a specific bit
307 */
308int mbedtls_mpi_get_bit( const mbedtls_mpi *X, size_t pos )
309{
310 if( X->n * biL <= pos )
311 return( 0 );
312
313 return( ( X->p[pos / biL] >> ( pos % biL ) ) & 0x01 );
314}
315
316/*
317 * Set a bit to a specific value of 0 or 1
318 */
319int mbedtls_mpi_set_bit( mbedtls_mpi *X, size_t pos, unsigned char val )
320{
321 int ret = 0;
322 size_t off = pos / biL;
323 size_t idx = pos % biL;
324
325 if( val != 0 && val != 1 )
326 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
327
328 if( X->n * biL <= pos )
329 {
330 if( val == 0 )
331 return( 0 );
332
333 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, off + 1 ) );
334 }
335
336 X->p[off] &= ~( (mbedtls_mpi_uint) 0x01 << idx );
337 X->p[off] |= (mbedtls_mpi_uint) val << idx;
338
339cleanup:
340
341 return( ret );
342}
343
344/*
345 * Return the number of less significant zero-bits
346 */
347size_t mbedtls_mpi_lsb( const mbedtls_mpi *X )
348{
349 size_t i, j, count = 0;
350
351 for( i = 0; i < X->n; i++ )
352 for( j = 0; j < biL; j++, count++ )
353 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
354 return( count );
355
356 return( 0 );
357}
358
359/*
360 * Count leading zero bits in a given integer
361 */
362static size_t mbedtls_clz( const mbedtls_mpi_uint x )
363{
364 size_t j;
365 mbedtls_mpi_uint mask = (mbedtls_mpi_uint) 1 << (biL - 1);
366
367 for( j = 0; j < biL; j++ )
368 {
369 if( x & mask ) break;
370
371 mask >>= 1;
372 }
373
374 return j;
375}
376
377/*
378 * Return the number of bits
379 */
380size_t mbedtls_mpi_bitlen( const mbedtls_mpi *X )
381{
382 size_t i, j;
383
384 if( X->n == 0 )
385 return( 0 );
386
387 for( i = X->n - 1; i > 0; i-- )
388 if( X->p[i] != 0 )
389 break;
390
391 j = biL - mbedtls_clz( X->p[i] );
392
393 return( ( i * biL ) + j );
394}
395
396/*
397 * Return the total size in bytes
398 */
399size_t mbedtls_mpi_size( const mbedtls_mpi *X )
400{
401 return( ( mbedtls_mpi_bitlen( X ) + 7 ) >> 3 );
402}
403
404/*
405 * Convert an ASCII character to digit value
406 */
407static int mpi_get_digit( mbedtls_mpi_uint *d, int radix, char c )
408{
409 *d = 255;
410
411 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
412 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
413 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
414
415 if( *d >= (mbedtls_mpi_uint) radix )
416 return( MBEDTLS_ERR_MPI_INVALID_CHARACTER );
417
418 return( 0 );
419}
420
421/*
422 * Import from an ASCII string
423 */
424int mbedtls_mpi_read_string( mbedtls_mpi *X, int radix, const char *s )
425{
426 int ret;
427 size_t i, j, slen, n;
428 mbedtls_mpi_uint d;
429 mbedtls_mpi T;
430
431 if( radix < 2 || radix > 16 )
432 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
433
434 mbedtls_mpi_init( &T );
435
436 slen = strlen( s );
437
438 if( radix == 16 )
439 {
440 if( slen > MPI_SIZE_T_MAX >> 2 )
441 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
442
443 n = BITS_TO_LIMBS( slen << 2 );
444
445 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, n ) );
446 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
447
448 for( i = slen, j = 0; i > 0; i--, j++ )
449 {
450 if( i == 1 && s[i - 1] == '-' )
451 {
452 X->s = -1;
453 break;
454 }
455
456 MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i - 1] ) );
457 X->p[j / ( 2 * ciL )] |= d << ( ( j % ( 2 * ciL ) ) << 2 );
458 }
459 }
460 else
461 {
462 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
463
464 for( i = 0; i < slen; i++ )
465 {
466 if( i == 0 && s[i] == '-' )
467 {
468 X->s = -1;
469 continue;
470 }
471
472 MBEDTLS_MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
473 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T, X, radix ) );
474
475 if( X->s == 1 )
476 {
477 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, &T, d ) );
478 }
479 else
480 {
481 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( X, &T, d ) );
482 }
483 }
484 }
485
486cleanup:
487
488 mbedtls_mpi_free( &T );
489
490 return( ret );
491}
492
493/*
494 * Helper to write the digits high-order first
495 */
496static int mpi_write_hlp( mbedtls_mpi *X, int radix, char **p )
497{
498 int ret;
499 mbedtls_mpi_uint r;
500
501 if( radix < 2 || radix > 16 )
502 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
503
504 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, radix ) );
505 MBEDTLS_MPI_CHK( mbedtls_mpi_div_int( X, NULL, X, radix ) );
506
507 if( mbedtls_mpi_cmp_int( X, 0 ) != 0 )
508 MBEDTLS_MPI_CHK( mpi_write_hlp( X, radix, p ) );
509
510 if( r < 10 )
511 *(*p)++ = (char)( r + 0x30 );
512 else
513 *(*p)++ = (char)( r + 0x37 );
514
515cleanup:
516
517 return( ret );
518}
519
520/*
521 * Export into an ASCII string
522 */
523int mbedtls_mpi_write_string( const mbedtls_mpi *X, int radix,
524 char *buf, size_t buflen, size_t *olen )
525{
526 int ret = 0;
527 size_t n;
528 char *p;
529 mbedtls_mpi T;
530
531 if( radix < 2 || radix > 16 )
532 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
533
534 n = mbedtls_mpi_bitlen( X );
535 if( radix >= 4 ) n >>= 1;
536 if( radix >= 16 ) n >>= 1;
537 n += 3;
538
539 if( buflen < n )
540 {
541 *olen = n;
542 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
543 }
544
545 p = buf;
546 mbedtls_mpi_init( &T );
547
548 if( X->s == -1 )
549 *p++ = '-';
550
551 if( radix == 16 )
552 {
553 int c;
554 size_t i, j, k;
555
556 for( i = X->n, k = 0; i > 0; i-- )
557 {
558 for( j = ciL; j > 0; j-- )
559 {
560 c = ( X->p[i - 1] >> ( ( j - 1 ) << 3) ) & 0xFF;
561
562 if( c == 0 && k == 0 && ( i + j ) != 2 )
563 continue;
564
565 *(p++) = "0123456789ABCDEF" [c / 16];
566 *(p++) = "0123456789ABCDEF" [c % 16];
567 k = 1;
568 }
569 }
570 }
571 else
572 {
573 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T, X ) );
574
575 if( T.s == -1 )
576 T.s = 1;
577
578 MBEDTLS_MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
579 }
580
581 *p++ = '\0';
582 *olen = p - buf;
583
584cleanup:
585
586 mbedtls_mpi_free( &T );
587
588 return( ret );
589}
590
591#if defined(MBEDTLS_FS_IO)
592/*
593 * Read X from an opened file
594 */
595int mbedtls_mpi_read_file( mbedtls_mpi *X, int radix, FILE *fin )
596{
597 mbedtls_mpi_uint d;
598 size_t slen;
599 char *p;
600 /*
601 * Buffer should have space for (short) label and decimal formatted MPI,
602 * newline characters and '\0'
603 */
604 char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
605
606 memset( s, 0, sizeof( s ) );
607 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
608 return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
609
610 slen = strlen( s );
611 if( slen == sizeof( s ) - 2 )
612 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
613
614 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
615 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
616
617 p = s + slen;
618 while( --p >= s )
619 if( mpi_get_digit( &d, radix, *p ) != 0 )
620 break;
621
622 return( mbedtls_mpi_read_string( X, radix, p + 1 ) );
623}
624
625/*
626 * Write X into an opened file (or stdout if fout == NULL)
627 */
628int mbedtls_mpi_write_file( const char *p, const mbedtls_mpi *X, int radix, FILE *fout )
629{
630 int ret;
631 size_t n, slen, plen;
632 /*
633 * Buffer should have space for (short) label and decimal formatted MPI,
634 * newline characters and '\0'
635 */
636 char s[ MBEDTLS_MPI_RW_BUFFER_SIZE ];
637
638 memset( s, 0, sizeof( s ) );
639
640 MBEDTLS_MPI_CHK( mbedtls_mpi_write_string( X, radix, s, sizeof( s ) - 2, &n ) );
641
642 if( p == NULL ) p = "";
643
644 plen = strlen( p );
645 slen = strlen( s );
646 s[slen++] = '\r';
647 s[slen++] = '\n';
648
649 if( fout != NULL )
650 {
651 if( fwrite( p, 1, plen, fout ) != plen ||
652 fwrite( s, 1, slen, fout ) != slen )
653 return( MBEDTLS_ERR_MPI_FILE_IO_ERROR );
654 }
655 else
656 mbedtls_printf( "%s%s", p, s );
657
658cleanup:
659
660 return( ret );
661}
662#endif /* MBEDTLS_FS_IO */
663
664/*
665 * Import X from unsigned binary data, big endian
666 */
667int mbedtls_mpi_read_binary( mbedtls_mpi *X, const unsigned char *buf, size_t buflen )
668{
669 int ret;
670 size_t i, j, n;
671
672 for( n = 0; n < buflen; n++ )
673 if( buf[n] != 0 )
674 break;
675
676 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
677 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
678
679 for( i = buflen, j = 0; i > n; i--, j++ )
680 X->p[j / ciL] |= ((mbedtls_mpi_uint) buf[i - 1]) << ((j % ciL) << 3);
681
682cleanup:
683
684 return( ret );
685}
686
687/*
688 * Export X into unsigned binary data, big endian
689 */
690int mbedtls_mpi_write_binary( const mbedtls_mpi *X, unsigned char *buf, size_t buflen )
691{
692 size_t i, j, n;
693
694 n = mbedtls_mpi_size( X );
695
696 if( buflen < n )
697 return( MBEDTLS_ERR_MPI_BUFFER_TOO_SMALL );
698
699 memset( buf, 0, buflen );
700
701 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
702 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
703
704 return( 0 );
705}
706
707/*
708 * Left-shift: X <<= count
709 */
710int mbedtls_mpi_shift_l( mbedtls_mpi *X, size_t count )
711{
712 int ret;
713 size_t i, v0, t1;
714 mbedtls_mpi_uint r0 = 0, r1;
715
716 v0 = count / (biL );
717 t1 = count & (biL - 1);
718
719 i = mbedtls_mpi_bitlen( X ) + count;
720
721 if( X->n * biL < i )
722 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, BITS_TO_LIMBS( i ) ) );
723
724 ret = 0;
725
726 /*
727 * shift by count / limb_size
728 */
729 if( v0 > 0 )
730 {
731 for( i = X->n; i > v0; i-- )
732 X->p[i - 1] = X->p[i - v0 - 1];
733
734 for( ; i > 0; i-- )
735 X->p[i - 1] = 0;
736 }
737
738 /*
739 * shift by count % limb_size
740 */
741 if( t1 > 0 )
742 {
743 for( i = v0; i < X->n; i++ )
744 {
745 r1 = X->p[i] >> (biL - t1);
746 X->p[i] <<= t1;
747 X->p[i] |= r0;
748 r0 = r1;
749 }
750 }
751
752cleanup:
753
754 return( ret );
755}
756
757/*
758 * Right-shift: X >>= count
759 */
760int mbedtls_mpi_shift_r( mbedtls_mpi *X, size_t count )
761{
762 size_t i, v0, v1;
763 mbedtls_mpi_uint r0 = 0, r1;
764
765 v0 = count / biL;
766 v1 = count & (biL - 1);
767
768 if( v0 > X->n || ( v0 == X->n && v1 > 0 ) )
769 return mbedtls_mpi_lset( X, 0 );
770
771 /*
772 * shift by count / limb_size
773 */
774 if( v0 > 0 )
775 {
776 for( i = 0; i < X->n - v0; i++ )
777 X->p[i] = X->p[i + v0];
778
779 for( ; i < X->n; i++ )
780 X->p[i] = 0;
781 }
782
783 /*
784 * shift by count % limb_size
785 */
786 if( v1 > 0 )
787 {
788 for( i = X->n; i > 0; i-- )
789 {
790 r1 = X->p[i - 1] << (biL - v1);
791 X->p[i - 1] >>= v1;
792 X->p[i - 1] |= r0;
793 r0 = r1;
794 }
795 }
796
797 return( 0 );
798}
799
800/*
801 * Compare unsigned values
802 */
803int mbedtls_mpi_cmp_abs( const mbedtls_mpi *X, const mbedtls_mpi *Y )
804{
805 size_t i, j;
806
807 for( i = X->n; i > 0; i-- )
808 if( X->p[i - 1] != 0 )
809 break;
810
811 for( j = Y->n; j > 0; j-- )
812 if( Y->p[j - 1] != 0 )
813 break;
814
815 if( i == 0 && j == 0 )
816 return( 0 );
817
818 if( i > j ) return( 1 );
819 if( j > i ) return( -1 );
820
821 for( ; i > 0; i-- )
822 {
823 if( X->p[i - 1] > Y->p[i - 1] ) return( 1 );
824 if( X->p[i - 1] < Y->p[i - 1] ) return( -1 );
825 }
826
827 return( 0 );
828}
829
830/*
831 * Compare signed values
832 */
833int mbedtls_mpi_cmp_mpi( const mbedtls_mpi *X, const mbedtls_mpi *Y )
834{
835 size_t i, j;
836
837 for( i = X->n; i > 0; i-- )
838 if( X->p[i - 1] != 0 )
839 break;
840
841 for( j = Y->n; j > 0; j-- )
842 if( Y->p[j - 1] != 0 )
843 break;
844
845 if( i == 0 && j == 0 )
846 return( 0 );
847
848 if( i > j ) return( X->s );
849 if( j > i ) return( -Y->s );
850
851 if( X->s > 0 && Y->s < 0 ) return( 1 );
852 if( Y->s > 0 && X->s < 0 ) return( -1 );
853
854 for( ; i > 0; i-- )
855 {
856 if( X->p[i - 1] > Y->p[i - 1] ) return( X->s );
857 if( X->p[i - 1] < Y->p[i - 1] ) return( -X->s );
858 }
859
860 return( 0 );
861}
862
863/*
864 * Compare signed values
865 */
866int mbedtls_mpi_cmp_int( const mbedtls_mpi *X, mbedtls_mpi_sint z )
867{
868 mbedtls_mpi Y;
869 mbedtls_mpi_uint p[1];
870
871 *p = ( z < 0 ) ? -z : z;
872 Y.s = ( z < 0 ) ? -1 : 1;
873 Y.n = 1;
874 Y.p = p;
875
876 return( mbedtls_mpi_cmp_mpi( X, &Y ) );
877}
878
879/*
880 * Unsigned addition: X = |A| + |B| (HAC 14.7)
881 */
882int mbedtls_mpi_add_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
883{
884 int ret;
885 size_t i, j;
886 mbedtls_mpi_uint *o, *p, c;
887
888 if( X == B )
889 {
890 const mbedtls_mpi *T = A; A = X; B = T;
891 }
892
893 if( X != A )
894 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
895
896 /*
897 * X should always be positive as a result of unsigned additions.
898 */
899 X->s = 1;
900
901 for( j = B->n; j > 0; j-- )
902 if( B->p[j - 1] != 0 )
903 break;
904
905 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
906
907 o = B->p; p = X->p; c = 0;
908
909 for( i = 0; i < j; i++, o++, p++ )
910 {
911 *p += c; c = ( *p < c );
912 *p += *o; c += ( *p < *o );
913 }
914
915 while( c != 0 )
916 {
917 if( i >= X->n )
918 {
919 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + 1 ) );
920 p = X->p + i;
921 }
922
923 *p += c; c = ( *p < c ); i++; p++;
924 }
925
926cleanup:
927
928 return( ret );
929}
930
931/*
932 * Helper for mbedtls_mpi subtraction
933 */
934static void mpi_sub_hlp( size_t n, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d )
935{
936 size_t i;
937 mbedtls_mpi_uint c, z;
938
939 for( i = c = 0; i < n; i++, s++, d++ )
940 {
941 z = ( *d < c ); *d -= c;
942 c = ( *d < *s ) + z; *d -= *s;
943 }
944
945 while( c != 0 )
946 {
947 z = ( *d < c ); *d -= c;
948 c = z; i++; d++;
949 }
950}
951
952/*
953 * Unsigned subtraction: X = |A| - |B| (HAC 14.9)
954 */
955int mbedtls_mpi_sub_abs( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
956{
957 mbedtls_mpi TB;
958 int ret;
959 size_t n;
960
961 if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
962 return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
963
964 mbedtls_mpi_init( &TB );
965
966 if( X == B )
967 {
968 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
969 B = &TB;
970 }
971
972 if( X != A )
973 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, A ) );
974
975 /*
976 * X should always be positive as a result of unsigned subtractions.
977 */
978 X->s = 1;
979
980 ret = 0;
981
982 for( n = B->n; n > 0; n-- )
983 if( B->p[n - 1] != 0 )
984 break;
985
986 mpi_sub_hlp( n, B->p, X->p );
987
988cleanup:
989
990 mbedtls_mpi_free( &TB );
991
992 return( ret );
993}
994
995/*
996 * Signed addition: X = A + B
997 */
998int mbedtls_mpi_add_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
999{
1000 int ret, s = A->s;
1001
1002 if( A->s * B->s < 0 )
1003 {
1004 if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
1005 {
1006 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
1007 X->s = s;
1008 }
1009 else
1010 {
1011 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
1012 X->s = -s;
1013 }
1014 }
1015 else
1016 {
1017 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
1018 X->s = s;
1019 }
1020
1021cleanup:
1022
1023 return( ret );
1024}
1025
1026/*
1027 * Signed subtraction: X = A - B
1028 */
1029int mbedtls_mpi_sub_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1030{
1031 int ret, s = A->s;
1032
1033 if( A->s * B->s > 0 )
1034 {
1035 if( mbedtls_mpi_cmp_abs( A, B ) >= 0 )
1036 {
1037 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, A, B ) );
1038 X->s = s;
1039 }
1040 else
1041 {
1042 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( X, B, A ) );
1043 X->s = -s;
1044 }
1045 }
1046 else
1047 {
1048 MBEDTLS_MPI_CHK( mbedtls_mpi_add_abs( X, A, B ) );
1049 X->s = s;
1050 }
1051
1052cleanup:
1053
1054 return( ret );
1055}
1056
1057/*
1058 * Signed addition: X = A + b
1059 */
1060int mbedtls_mpi_add_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
1061{
1062 mbedtls_mpi _B;
1063 mbedtls_mpi_uint p[1];
1064
1065 p[0] = ( b < 0 ) ? -b : b;
1066 _B.s = ( b < 0 ) ? -1 : 1;
1067 _B.n = 1;
1068 _B.p = p;
1069
1070 return( mbedtls_mpi_add_mpi( X, A, &_B ) );
1071}
1072
1073/*
1074 * Signed subtraction: X = A - b
1075 */
1076int mbedtls_mpi_sub_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_sint b )
1077{
1078 mbedtls_mpi _B;
1079 mbedtls_mpi_uint p[1];
1080
1081 p[0] = ( b < 0 ) ? -b : b;
1082 _B.s = ( b < 0 ) ? -1 : 1;
1083 _B.n = 1;
1084 _B.p = p;
1085
1086 return( mbedtls_mpi_sub_mpi( X, A, &_B ) );
1087}
1088
1089/*
1090 * Helper for mbedtls_mpi multiplication
1091 */
1092static
1093#if defined(__APPLE__) && defined(__arm__)
1094/*
1095 * Apple LLVM version 4.2 (clang-425.0.24) (based on LLVM 3.2svn)
1096 * appears to need this to prevent bad ARM code generation at -O3.
1097 */
1098__attribute__ ((noinline))
1099#endif
1100void mpi_mul_hlp( size_t i, mbedtls_mpi_uint *s, mbedtls_mpi_uint *d, mbedtls_mpi_uint b )
1101{
1102 mbedtls_mpi_uint c = 0, t = 0;
1103
1104#if defined(MULADDC_HUIT)
1105 for( ; i >= 8; i -= 8 )
1106 {
1107 MULADDC_INIT
1108 MULADDC_HUIT
1109 MULADDC_STOP
1110 }
1111
1112 for( ; i > 0; i-- )
1113 {
1114 MULADDC_INIT
1115 MULADDC_CORE
1116 MULADDC_STOP
1117 }
1118#else /* MULADDC_HUIT */
1119 for( ; i >= 16; i -= 16 )
1120 {
1121 MULADDC_INIT
1122 MULADDC_CORE MULADDC_CORE
1123 MULADDC_CORE MULADDC_CORE
1124 MULADDC_CORE MULADDC_CORE
1125 MULADDC_CORE MULADDC_CORE
1126
1127 MULADDC_CORE MULADDC_CORE
1128 MULADDC_CORE MULADDC_CORE
1129 MULADDC_CORE MULADDC_CORE
1130 MULADDC_CORE MULADDC_CORE
1131 MULADDC_STOP
1132 }
1133
1134 for( ; i >= 8; i -= 8 )
1135 {
1136 MULADDC_INIT
1137 MULADDC_CORE MULADDC_CORE
1138 MULADDC_CORE MULADDC_CORE
1139
1140 MULADDC_CORE MULADDC_CORE
1141 MULADDC_CORE MULADDC_CORE
1142 MULADDC_STOP
1143 }
1144
1145 for( ; i > 0; i-- )
1146 {
1147 MULADDC_INIT
1148 MULADDC_CORE
1149 MULADDC_STOP
1150 }
1151#endif /* MULADDC_HUIT */
1152
1153 t++;
1154
1155 do {
1156 *d += c; c = ( *d < c ); d++;
1157 }
1158 while( c != 0 );
1159}
1160
1161/*
1162 * Baseline multiplication: X = A * B (HAC 14.12)
1163 */
1164int mbedtls_mpi_mul_mpi( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *B )
1165{
1166 int ret;
1167 size_t i, j;
1168 mbedtls_mpi TA, TB;
1169
1170 mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
1171
1172 if( X == A ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) ); A = &TA; }
1173 if( X == B ) { MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) ); B = &TB; }
1174
1175 for( i = A->n; i > 0; i-- )
1176 if( A->p[i - 1] != 0 )
1177 break;
1178
1179 for( j = B->n; j > 0; j-- )
1180 if( B->p[j - 1] != 0 )
1181 break;
1182
1183 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, i + j ) );
1184 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( X, 0 ) );
1185
1186 for( i++; j > 0; j-- )
1187 mpi_mul_hlp( i - 1, A->p, X->p + j - 1, B->p[j - 1] );
1188
1189 X->s = A->s * B->s;
1190
1191cleanup:
1192
1193 mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TA );
1194
1195 return( ret );
1196}
1197
1198/*
1199 * Baseline multiplication: X = A * b
1200 */
1201int mbedtls_mpi_mul_int( mbedtls_mpi *X, const mbedtls_mpi *A, mbedtls_mpi_uint b )
1202{
1203 mbedtls_mpi _B;
1204 mbedtls_mpi_uint p[1];
1205
1206 _B.s = 1;
1207 _B.n = 1;
1208 _B.p = p;
1209 p[0] = b;
1210
1211 return( mbedtls_mpi_mul_mpi( X, A, &_B ) );
1212}
1213
1214/*
1215 * Unsigned integer divide - double mbedtls_mpi_uint dividend, u1/u0, and
1216 * mbedtls_mpi_uint divisor, d
1217 */
1218static mbedtls_mpi_uint mbedtls_int_div_int( mbedtls_mpi_uint u1,
1219 mbedtls_mpi_uint u0, mbedtls_mpi_uint d, mbedtls_mpi_uint *r )
1220{
1221#if defined(MBEDTLS_HAVE_UDBL)
1222 mbedtls_t_udbl dividend, quotient;
1223#else
1224 const mbedtls_mpi_uint radix = (mbedtls_mpi_uint) 1 << biH;
1225 const mbedtls_mpi_uint uint_halfword_mask = ( (mbedtls_mpi_uint) 1 << biH ) - 1;
1226 mbedtls_mpi_uint d0, d1, q0, q1, rAX, r0, quotient;
1227 mbedtls_mpi_uint u0_msw, u0_lsw;
1228 size_t s;
1229#endif
1230
1231 /*
1232 * Check for overflow
1233 */
1234 if( 0 == d || u1 >= d )
1235 {
1236 if (r != NULL) *r = ~0;
1237
1238 return ( ~0 );
1239 }
1240
1241#if defined(MBEDTLS_HAVE_UDBL)
1242 dividend = (mbedtls_t_udbl) u1 << biL;
1243 dividend |= (mbedtls_t_udbl) u0;
1244 quotient = dividend / d;
1245 if( quotient > ( (mbedtls_t_udbl) 1 << biL ) - 1 )
1246 quotient = ( (mbedtls_t_udbl) 1 << biL ) - 1;
1247
1248 if( r != NULL )
1249 *r = (mbedtls_mpi_uint)( dividend - (quotient * d ) );
1250
1251 return (mbedtls_mpi_uint) quotient;
1252#else
1253
1254 /*
1255 * Algorithm D, Section 4.3.1 - The Art of Computer Programming
1256 * Vol. 2 - Seminumerical Algorithms, Knuth
1257 */
1258
1259 /*
1260 * Normalize the divisor, d, and dividend, u0, u1
1261 */
1262 s = mbedtls_clz( d );
1263 d = d << s;
1264
1265 u1 = u1 << s;
1266 u1 |= ( u0 >> ( biL - s ) ) & ( -(mbedtls_mpi_sint)s >> ( biL - 1 ) );
1267 u0 = u0 << s;
1268
1269 d1 = d >> biH;
1270 d0 = d & uint_halfword_mask;
1271
1272 u0_msw = u0 >> biH;
1273 u0_lsw = u0 & uint_halfword_mask;
1274
1275 /*
1276 * Find the first quotient and remainder
1277 */
1278 q1 = u1 / d1;
1279 r0 = u1 - d1 * q1;
1280
1281 while( q1 >= radix || ( q1 * d0 > radix * r0 + u0_msw ) )
1282 {
1283 q1 -= 1;
1284 r0 += d1;
1285
1286 if ( r0 >= radix ) break;
1287 }
1288
1289 rAX = ( u1 * radix ) + ( u0_msw - q1 * d );
1290 q0 = rAX / d1;
1291 r0 = rAX - q0 * d1;
1292
1293 while( q0 >= radix || ( q0 * d0 > radix * r0 + u0_lsw ) )
1294 {
1295 q0 -= 1;
1296 r0 += d1;
1297
1298 if ( r0 >= radix ) break;
1299 }
1300
1301 if (r != NULL)
1302 *r = ( rAX * radix + u0_lsw - q0 * d ) >> s;
1303
1304 quotient = q1 * radix + q0;
1305
1306 return quotient;
1307#endif
1308}
1309
1310/*
1311 * Division by mbedtls_mpi: A = Q * B + R (HAC 14.20)
1312 */
1313int mbedtls_mpi_div_mpi( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
1314{
1315 int ret;
1316 size_t i, n, t, k;
1317 mbedtls_mpi X, Y, Z, T1, T2;
1318
1319 if( mbedtls_mpi_cmp_int( B, 0 ) == 0 )
1320 return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
1321
1322 mbedtls_mpi_init( &X ); mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &Z );
1323 mbedtls_mpi_init( &T1 ); mbedtls_mpi_init( &T2 );
1324
1325 if( mbedtls_mpi_cmp_abs( A, B ) < 0 )
1326 {
1327 if( Q != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_lset( Q, 0 ) );
1328 if( R != NULL ) MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, A ) );
1329 return( 0 );
1330 }
1331
1332 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &X, A ) );
1333 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, B ) );
1334 X.s = Y.s = 1;
1335
1336 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &Z, A->n + 2 ) );
1337 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Z, 0 ) );
1338 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T1, 2 ) );
1339 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T2, 3 ) );
1340
1341 k = mbedtls_mpi_bitlen( &Y ) % biL;
1342 if( k < biL - 1 )
1343 {
1344 k = biL - 1 - k;
1345 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &X, k ) );
1346 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, k ) );
1347 }
1348 else k = 0;
1349
1350 n = X.n - 1;
1351 t = Y.n - 1;
1352 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &Y, biL * ( n - t ) ) );
1353
1354 while( mbedtls_mpi_cmp_mpi( &X, &Y ) >= 0 )
1355 {
1356 Z.p[n - t]++;
1357 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &Y ) );
1358 }
1359 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, biL * ( n - t ) ) );
1360
1361 for( i = n; i > t ; i-- )
1362 {
1363 if( X.p[i] >= Y.p[t] )
1364 Z.p[i - t - 1] = ~0;
1365 else
1366 {
1367 Z.p[i - t - 1] = mbedtls_int_div_int( X.p[i], X.p[i - 1],
1368 Y.p[t], NULL);
1369 }
1370
1371 Z.p[i - t - 1]++;
1372 do
1373 {
1374 Z.p[i - t - 1]--;
1375
1376 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T1, 0 ) );
1377 T1.p[0] = ( t < 1 ) ? 0 : Y.p[t - 1];
1378 T1.p[1] = Y.p[t];
1379 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1380
1381 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &T2, 0 ) );
1382 T2.p[0] = ( i < 2 ) ? 0 : X.p[i - 2];
1383 T2.p[1] = ( i < 1 ) ? 0 : X.p[i - 1];
1384 T2.p[2] = X.p[i];
1385 }
1386 while( mbedtls_mpi_cmp_mpi( &T1, &T2 ) > 0 );
1387
1388 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1389 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
1390 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &X, &X, &T1 ) );
1391
1392 if( mbedtls_mpi_cmp_int( &X, 0 ) < 0 )
1393 {
1394 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &T1, &Y ) );
1395 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &T1, biL * ( i - t - 1 ) ) );
1396 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &X, &X, &T1 ) );
1397 Z.p[i - t - 1]--;
1398 }
1399 }
1400
1401 if( Q != NULL )
1402 {
1403 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( Q, &Z ) );
1404 Q->s = A->s * B->s;
1405 }
1406
1407 if( R != NULL )
1408 {
1409 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &X, k ) );
1410 X.s = A->s;
1411 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( R, &X ) );
1412
1413 if( mbedtls_mpi_cmp_int( R, 0 ) == 0 )
1414 R->s = 1;
1415 }
1416
1417cleanup:
1418
1419 mbedtls_mpi_free( &X ); mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &Z );
1420 mbedtls_mpi_free( &T1 ); mbedtls_mpi_free( &T2 );
1421
1422 return( ret );
1423}
1424
1425/*
1426 * Division by int: A = Q * b + R
1427 */
1428int mbedtls_mpi_div_int( mbedtls_mpi *Q, mbedtls_mpi *R, const mbedtls_mpi *A, mbedtls_mpi_sint b )
1429{
1430 mbedtls_mpi _B;
1431 mbedtls_mpi_uint p[1];
1432
1433 p[0] = ( b < 0 ) ? -b : b;
1434 _B.s = ( b < 0 ) ? -1 : 1;
1435 _B.n = 1;
1436 _B.p = p;
1437
1438 return( mbedtls_mpi_div_mpi( Q, R, A, &_B ) );
1439}
1440
1441/*
1442 * Modulo: R = A mod B
1443 */
1444int mbedtls_mpi_mod_mpi( mbedtls_mpi *R, const mbedtls_mpi *A, const mbedtls_mpi *B )
1445{
1446 int ret;
1447
1448 if( mbedtls_mpi_cmp_int( B, 0 ) < 0 )
1449 return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
1450
1451 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( NULL, R, A, B ) );
1452
1453 while( mbedtls_mpi_cmp_int( R, 0 ) < 0 )
1454 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( R, R, B ) );
1455
1456 while( mbedtls_mpi_cmp_mpi( R, B ) >= 0 )
1457 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( R, R, B ) );
1458
1459cleanup:
1460
1461 return( ret );
1462}
1463
1464/*
1465 * Modulo: r = A mod b
1466 */
1467int mbedtls_mpi_mod_int( mbedtls_mpi_uint *r, const mbedtls_mpi *A, mbedtls_mpi_sint b )
1468{
1469 size_t i;
1470 mbedtls_mpi_uint x, y, z;
1471
1472 if( b == 0 )
1473 return( MBEDTLS_ERR_MPI_DIVISION_BY_ZERO );
1474
1475 if( b < 0 )
1476 return( MBEDTLS_ERR_MPI_NEGATIVE_VALUE );
1477
1478 /*
1479 * handle trivial cases
1480 */
1481 if( b == 1 )
1482 {
1483 *r = 0;
1484 return( 0 );
1485 }
1486
1487 if( b == 2 )
1488 {
1489 *r = A->p[0] & 1;
1490 return( 0 );
1491 }
1492
1493 /*
1494 * general case
1495 */
1496 for( i = A->n, y = 0; i > 0; i-- )
1497 {
1498 x = A->p[i - 1];
1499 y = ( y << biH ) | ( x >> biH );
1500 z = y / b;
1501 y -= z * b;
1502
1503 x <<= biH;
1504 y = ( y << biH ) | ( x >> biH );
1505 z = y / b;
1506 y -= z * b;
1507 }
1508
1509 /*
1510 * If A is negative, then the current y represents a negative value.
1511 * Flipping it to the positive side.
1512 */
1513 if( A->s < 0 && y != 0 )
1514 y = b - y;
1515
1516 *r = y;
1517
1518 return( 0 );
1519}
1520
1521/*
1522 * Fast Montgomery initialization (thanks to Tom St Denis)
1523 */
1524static void mpi_montg_init( mbedtls_mpi_uint *mm, const mbedtls_mpi *N )
1525{
1526 mbedtls_mpi_uint x, m0 = N->p[0];
1527 unsigned int i;
1528
1529 x = m0;
1530 x += ( ( m0 + 2 ) & 4 ) << 1;
1531
1532 for( i = biL; i >= 8; i /= 2 )
1533 x *= ( 2 - ( m0 * x ) );
1534
1535 *mm = ~x + 1;
1536}
1537
1538/*
1539 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1540 */
1541static void mpi_montmul( mbedtls_mpi *A, const mbedtls_mpi *B, const mbedtls_mpi *N, mbedtls_mpi_uint mm,
1542 const mbedtls_mpi *T )
1543{
1544 size_t i, n, m;
1545 mbedtls_mpi_uint u0, u1, *d;
1546
1547 memset( T->p, 0, T->n * ciL );
1548
1549 d = T->p;
1550 n = N->n;
1551 m = ( B->n < n ) ? B->n : n;
1552
1553 for( i = 0; i < n; i++ )
1554 {
1555 /*
1556 * T = (T + u0*B + u1*N) / 2^biL
1557 */
1558 u0 = A->p[i];
1559 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1560
1561 mpi_mul_hlp( m, B->p, d, u0 );
1562 mpi_mul_hlp( n, N->p, d, u1 );
1563
1564 *d++ = u0; d[n + 1] = 0;
1565 }
1566
1567 memcpy( A->p, d, ( n + 1 ) * ciL );
1568
1569 if( mbedtls_mpi_cmp_abs( A, N ) >= 0 )
1570 mpi_sub_hlp( n, N->p, A->p );
1571 else
1572 /* prevent timing attacks */
1573 mpi_sub_hlp( n, A->p, T->p );
1574}
1575
1576/*
1577 * Montgomery reduction: A = A * R^-1 mod N
1578 */
1579static void mpi_montred( mbedtls_mpi *A, const mbedtls_mpi *N, mbedtls_mpi_uint mm, const mbedtls_mpi *T )
1580{
1581 mbedtls_mpi_uint z = 1;
1582 mbedtls_mpi U;
1583
1584 U.n = U.s = (int) z;
1585 U.p = &z;
1586
1587 mpi_montmul( A, &U, N, mm, T );
1588}
1589
1590/*
1591 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1592 */
1593int mbedtls_mpi_exp_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *E, const mbedtls_mpi *N, mbedtls_mpi *_RR )
1594{
1595 int ret;
1596 size_t wbits, wsize, one = 1;
1597 size_t i, j, nblimbs;
1598 size_t bufsize, nbits;
1599 mbedtls_mpi_uint ei, mm, state;
1600 mbedtls_mpi RR, T, W[ 2 << MBEDTLS_MPI_WINDOW_SIZE ], Apos;
1601 int neg;
1602
1603 if( mbedtls_mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
1604 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
1605
1606 if( mbedtls_mpi_cmp_int( E, 0 ) < 0 )
1607 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
1608
1609 /*
1610 * Init temps and window size
1611 */
1612 mpi_montg_init( &mm, N );
1613 mbedtls_mpi_init( &RR ); mbedtls_mpi_init( &T );
1614 mbedtls_mpi_init( &Apos );
1615 memset( W, 0, sizeof( W ) );
1616
1617 i = mbedtls_mpi_bitlen( E );
1618
1619 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1620 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1621
1622 if( wsize > MBEDTLS_MPI_WINDOW_SIZE )
1623 wsize = MBEDTLS_MPI_WINDOW_SIZE;
1624
1625 j = N->n + 1;
1626 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( X, j ) );
1627 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[1], j ) );
1628 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &T, j * 2 ) );
1629
1630 /*
1631 * Compensate for negative A (and correct at the end)
1632 */
1633 neg = ( A->s == -1 );
1634 if( neg )
1635 {
1636 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Apos, A ) );
1637 Apos.s = 1;
1638 A = &Apos;
1639 }
1640
1641 /*
1642 * If 1st call, pre-compute R^2 mod N
1643 */
1644 if( _RR == NULL || _RR->p == NULL )
1645 {
1646 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &RR, 1 ) );
1647 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &RR, N->n * 2 * biL ) );
1648 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &RR, &RR, N ) );
1649
1650 if( _RR != NULL )
1651 memcpy( _RR, &RR, sizeof( mbedtls_mpi ) );
1652 }
1653 else
1654 memcpy( &RR, _RR, sizeof( mbedtls_mpi ) );
1655
1656 /*
1657 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1658 */
1659 if( mbedtls_mpi_cmp_mpi( A, N ) >= 0 )
1660 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &W[1], A, N ) );
1661 else
1662 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[1], A ) );
1663
1664 mpi_montmul( &W[1], &RR, N, mm, &T );
1665
1666 /*
1667 * X = R^2 * R^-1 mod N = R mod N
1668 */
1669 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &RR ) );
1670 mpi_montred( X, N, mm, &T );
1671
1672 if( wsize > 1 )
1673 {
1674 /*
1675 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1676 */
1677 j = one << ( wsize - 1 );
1678
1679 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[j], N->n + 1 ) );
1680 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[j], &W[1] ) );
1681
1682 for( i = 0; i < wsize - 1; i++ )
1683 mpi_montmul( &W[j], &W[j], N, mm, &T );
1684
1685 /*
1686 * W[i] = W[i - 1] * W[1]
1687 */
1688 for( i = j + 1; i < ( one << wsize ); i++ )
1689 {
1690 MBEDTLS_MPI_CHK( mbedtls_mpi_grow( &W[i], N->n + 1 ) );
1691 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &W[i], &W[i - 1] ) );
1692
1693 mpi_montmul( &W[i], &W[1], N, mm, &T );
1694 }
1695 }
1696
1697 nblimbs = E->n;
1698 bufsize = 0;
1699 nbits = 0;
1700 wbits = 0;
1701 state = 0;
1702
1703 while( 1 )
1704 {
1705 if( bufsize == 0 )
1706 {
1707 if( nblimbs == 0 )
1708 break;
1709
1710 nblimbs--;
1711
1712 bufsize = sizeof( mbedtls_mpi_uint ) << 3;
1713 }
1714
1715 bufsize--;
1716
1717 ei = (E->p[nblimbs] >> bufsize) & 1;
1718
1719 /*
1720 * skip leading 0s
1721 */
1722 if( ei == 0 && state == 0 )
1723 continue;
1724
1725 if( ei == 0 && state == 1 )
1726 {
1727 /*
1728 * out of window, square X
1729 */
1730 mpi_montmul( X, X, N, mm, &T );
1731 continue;
1732 }
1733
1734 /*
1735 * add ei to current window
1736 */
1737 state = 2;
1738
1739 nbits++;
1740 wbits |= ( ei << ( wsize - nbits ) );
1741
1742 if( nbits == wsize )
1743 {
1744 /*
1745 * X = X^wsize R^-1 mod N
1746 */
1747 for( i = 0; i < wsize; i++ )
1748 mpi_montmul( X, X, N, mm, &T );
1749
1750 /*
1751 * X = X * W[wbits] R^-1 mod N
1752 */
1753 mpi_montmul( X, &W[wbits], N, mm, &T );
1754
1755 state--;
1756 nbits = 0;
1757 wbits = 0;
1758 }
1759 }
1760
1761 /*
1762 * process the remaining bits
1763 */
1764 for( i = 0; i < nbits; i++ )
1765 {
1766 mpi_montmul( X, X, N, mm, &T );
1767
1768 wbits <<= 1;
1769
1770 if( ( wbits & ( one << wsize ) ) != 0 )
1771 mpi_montmul( X, &W[1], N, mm, &T );
1772 }
1773
1774 /*
1775 * X = A^E * R * R^-1 mod N = A^E mod N
1776 */
1777 mpi_montred( X, N, mm, &T );
1778
1779 if( neg )
1780 {
1781 X->s = -1;
1782 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( X, N, X ) );
1783 }
1784
1785cleanup:
1786
1787 for( i = ( one << ( wsize - 1 ) ); i < ( one << wsize ); i++ )
1788 mbedtls_mpi_free( &W[i] );
1789
1790 mbedtls_mpi_free( &W[1] ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &Apos );
1791
1792 if( _RR == NULL || _RR->p == NULL )
1793 mbedtls_mpi_free( &RR );
1794
1795 return( ret );
1796}
1797
1798/*
1799 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1800 */
1801int mbedtls_mpi_gcd( mbedtls_mpi *G, const mbedtls_mpi *A, const mbedtls_mpi *B )
1802{
1803 int ret;
1804 size_t lz, lzt;
1805 mbedtls_mpi TG, TA, TB;
1806
1807 mbedtls_mpi_init( &TG ); mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TB );
1808
1809 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TA, A ) );
1810 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, B ) );
1811
1812 lz = mbedtls_mpi_lsb( &TA );
1813 lzt = mbedtls_mpi_lsb( &TB );
1814
1815 if( lzt < lz )
1816 lz = lzt;
1817
1818 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, lz ) );
1819 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, lz ) );
1820
1821 TA.s = TB.s = 1;
1822
1823 while( mbedtls_mpi_cmp_int( &TA, 0 ) != 0 )
1824 {
1825 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, mbedtls_mpi_lsb( &TA ) ) );
1826 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, mbedtls_mpi_lsb( &TB ) ) );
1827
1828 if( mbedtls_mpi_cmp_mpi( &TA, &TB ) >= 0 )
1829 {
1830 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TA, &TA, &TB ) );
1831 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TA, 1 ) );
1832 }
1833 else
1834 {
1835 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_abs( &TB, &TB, &TA ) );
1836 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TB, 1 ) );
1837 }
1838 }
1839
1840 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_l( &TB, lz ) );
1841 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( G, &TB ) );
1842
1843cleanup:
1844
1845 mbedtls_mpi_free( &TG ); mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TB );
1846
1847 return( ret );
1848}
1849
1850/*
1851 * Fill X with size bytes of random.
1852 *
1853 * Use a temporary bytes representation to make sure the result is the same
1854 * regardless of the platform endianness (useful when f_rng is actually
1855 * deterministic, eg for tests).
1856 */
1857int mbedtls_mpi_fill_random( mbedtls_mpi *X, size_t size,
1858 int (*f_rng)(void *, unsigned char *, size_t),
1859 void *p_rng )
1860{
1861 int ret;
1862 unsigned char buf[MBEDTLS_MPI_MAX_SIZE];
1863
1864 if( size > MBEDTLS_MPI_MAX_SIZE )
1865 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
1866
1867 MBEDTLS_MPI_CHK( f_rng( p_rng, buf, size ) );
1868 MBEDTLS_MPI_CHK( mbedtls_mpi_read_binary( X, buf, size ) );
1869
1870cleanup:
1871 return( ret );
1872}
1873
1874/*
1875 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1876 */
1877int mbedtls_mpi_inv_mod( mbedtls_mpi *X, const mbedtls_mpi *A, const mbedtls_mpi *N )
1878{
1879 int ret;
1880 mbedtls_mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1881
1882 if( mbedtls_mpi_cmp_int( N, 0 ) <= 0 )
1883 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
1884
1885 mbedtls_mpi_init( &TA ); mbedtls_mpi_init( &TU ); mbedtls_mpi_init( &U1 ); mbedtls_mpi_init( &U2 );
1886 mbedtls_mpi_init( &G ); mbedtls_mpi_init( &TB ); mbedtls_mpi_init( &TV );
1887 mbedtls_mpi_init( &V1 ); mbedtls_mpi_init( &V2 );
1888
1889 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &G, A, N ) );
1890
1891 if( mbedtls_mpi_cmp_int( &G, 1 ) != 0 )
1892 {
1893 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
1894 goto cleanup;
1895 }
1896
1897 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &TA, A, N ) );
1898 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TU, &TA ) );
1899 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TB, N ) );
1900 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &TV, N ) );
1901
1902 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U1, 1 ) );
1903 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &U2, 0 ) );
1904 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V1, 0 ) );
1905 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &V2, 1 ) );
1906
1907 do
1908 {
1909 while( ( TU.p[0] & 1 ) == 0 )
1910 {
1911 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TU, 1 ) );
1912
1913 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1914 {
1915 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &U1, &U1, &TB ) );
1916 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &TA ) );
1917 }
1918
1919 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U1, 1 ) );
1920 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &U2, 1 ) );
1921 }
1922
1923 while( ( TV.p[0] & 1 ) == 0 )
1924 {
1925 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &TV, 1 ) );
1926
1927 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1928 {
1929 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, &TB ) );
1930 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &TA ) );
1931 }
1932
1933 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V1, 1 ) );
1934 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &V2, 1 ) );
1935 }
1936
1937 if( mbedtls_mpi_cmp_mpi( &TU, &TV ) >= 0 )
1938 {
1939 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TU, &TU, &TV ) );
1940 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U1, &U1, &V1 ) );
1941 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &U2, &U2, &V2 ) );
1942 }
1943 else
1944 {
1945 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &TV, &TV, &TU ) );
1946 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, &U1 ) );
1947 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V2, &V2, &U2 ) );
1948 }
1949 }
1950 while( mbedtls_mpi_cmp_int( &TU, 0 ) != 0 );
1951
1952 while( mbedtls_mpi_cmp_int( &V1, 0 ) < 0 )
1953 MBEDTLS_MPI_CHK( mbedtls_mpi_add_mpi( &V1, &V1, N ) );
1954
1955 while( mbedtls_mpi_cmp_mpi( &V1, N ) >= 0 )
1956 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_mpi( &V1, &V1, N ) );
1957
1958 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( X, &V1 ) );
1959
1960cleanup:
1961
1962 mbedtls_mpi_free( &TA ); mbedtls_mpi_free( &TU ); mbedtls_mpi_free( &U1 ); mbedtls_mpi_free( &U2 );
1963 mbedtls_mpi_free( &G ); mbedtls_mpi_free( &TB ); mbedtls_mpi_free( &TV );
1964 mbedtls_mpi_free( &V1 ); mbedtls_mpi_free( &V2 );
1965
1966 return( ret );
1967}
1968
1969#if defined(MBEDTLS_GENPRIME)
1970
1971static const int small_prime[] =
1972{
1973 3, 5, 7, 11, 13, 17, 19, 23,
1974 29, 31, 37, 41, 43, 47, 53, 59,
1975 61, 67, 71, 73, 79, 83, 89, 97,
1976 101, 103, 107, 109, 113, 127, 131, 137,
1977 139, 149, 151, 157, 163, 167, 173, 179,
1978 181, 191, 193, 197, 199, 211, 223, 227,
1979 229, 233, 239, 241, 251, 257, 263, 269,
1980 271, 277, 281, 283, 293, 307, 311, 313,
1981 317, 331, 337, 347, 349, 353, 359, 367,
1982 373, 379, 383, 389, 397, 401, 409, 419,
1983 421, 431, 433, 439, 443, 449, 457, 461,
1984 463, 467, 479, 487, 491, 499, 503, 509,
1985 521, 523, 541, 547, 557, 563, 569, 571,
1986 577, 587, 593, 599, 601, 607, 613, 617,
1987 619, 631, 641, 643, 647, 653, 659, 661,
1988 673, 677, 683, 691, 701, 709, 719, 727,
1989 733, 739, 743, 751, 757, 761, 769, 773,
1990 787, 797, 809, 811, 821, 823, 827, 829,
1991 839, 853, 857, 859, 863, 877, 881, 883,
1992 887, 907, 911, 919, 929, 937, 941, 947,
1993 953, 967, 971, 977, 983, 991, 997, -103
1994};
1995
1996/*
1997 * Small divisors test (X must be positive)
1998 *
1999 * Return values:
2000 * 0: no small factor (possible prime, more tests needed)
2001 * 1: certain prime
2002 * MBEDTLS_ERR_MPI_NOT_ACCEPTABLE: certain non-prime
2003 * other negative: error
2004 */
2005static int mpi_check_small_factors( const mbedtls_mpi *X )
2006{
2007 int ret = 0;
2008 size_t i;
2009 mbedtls_mpi_uint r;
2010
2011 if( ( X->p[0] & 1 ) == 0 )
2012 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
2013
2014 for( i = 0; small_prime[i] > 0; i++ )
2015 {
2016 if( mbedtls_mpi_cmp_int( X, small_prime[i] ) <= 0 )
2017 return( 1 );
2018
2019 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, small_prime[i] ) );
2020
2021 if( r == 0 )
2022 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
2023 }
2024
2025cleanup:
2026 return( ret );
2027}
2028
2029/*
2030 * Miller-Rabin pseudo-primality test (HAC 4.24)
2031 */
2032static int mpi_miller_rabin( const mbedtls_mpi *X,
2033 int (*f_rng)(void *, unsigned char *, size_t),
2034 void *p_rng )
2035{
2036 int ret, count;
2037 size_t i, j, k, n, s;
2038 mbedtls_mpi W, R, T, A, RR;
2039
2040 mbedtls_mpi_init( &W ); mbedtls_mpi_init( &R ); mbedtls_mpi_init( &T ); mbedtls_mpi_init( &A );
2041 mbedtls_mpi_init( &RR );
2042
2043 /*
2044 * W = |X| - 1
2045 * R = W >> lsb( W )
2046 */
2047 MBEDTLS_MPI_CHK( mbedtls_mpi_sub_int( &W, X, 1 ) );
2048 s = mbedtls_mpi_lsb( &W );
2049 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &R, &W ) );
2050 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &R, s ) );
2051
2052 i = mbedtls_mpi_bitlen( X );
2053 /*
2054 * HAC, table 4.4
2055 */
2056 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
2057 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
2058 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
2059
2060 for( i = 0; i < n; i++ )
2061 {
2062 /*
2063 * pick a random A, 1 < A < |X| - 1
2064 */
2065 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
2066
2067 if( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 )
2068 {
2069 j = mbedtls_mpi_bitlen( &A ) - mbedtls_mpi_bitlen( &W );
2070 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &A, j + 1 ) );
2071 }
2072 A.p[0] |= 3;
2073
2074 count = 0;
2075 do {
2076 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( &A, X->n * ciL, f_rng, p_rng ) );
2077
2078 j = mbedtls_mpi_bitlen( &A );
2079 k = mbedtls_mpi_bitlen( &W );
2080 if (j > k) {
2081 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &A, j - k ) );
2082 }
2083
2084 if (count++ > 30) {
2085 return MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2086 }
2087
2088 } while ( mbedtls_mpi_cmp_mpi( &A, &W ) >= 0 ||
2089 mbedtls_mpi_cmp_int( &A, 1 ) <= 0 );
2090
2091 /*
2092 * A = A^R mod |X|
2093 */
2094 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &A, &A, &R, X, &RR ) );
2095
2096 if( mbedtls_mpi_cmp_mpi( &A, &W ) == 0 ||
2097 mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
2098 continue;
2099
2100 j = 1;
2101 while( j < s && mbedtls_mpi_cmp_mpi( &A, &W ) != 0 )
2102 {
2103 /*
2104 * A = A * A mod |X|
2105 */
2106 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &T, &A, &A ) );
2107 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_mpi( &A, &T, X ) );
2108
2109 if( mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
2110 break;
2111
2112 j++;
2113 }
2114
2115 /*
2116 * not prime if A != |X| - 1 or A == 1
2117 */
2118 if( mbedtls_mpi_cmp_mpi( &A, &W ) != 0 ||
2119 mbedtls_mpi_cmp_int( &A, 1 ) == 0 )
2120 {
2121 ret = MBEDTLS_ERR_MPI_NOT_ACCEPTABLE;
2122 break;
2123 }
2124 }
2125
2126cleanup:
2127 mbedtls_mpi_free( &W ); mbedtls_mpi_free( &R ); mbedtls_mpi_free( &T ); mbedtls_mpi_free( &A );
2128 mbedtls_mpi_free( &RR );
2129
2130 return( ret );
2131}
2132
2133/*
2134 * Pseudo-primality test: small factors, then Miller-Rabin
2135 */
2136int mbedtls_mpi_is_prime( const mbedtls_mpi *X,
2137 int (*f_rng)(void *, unsigned char *, size_t),
2138 void *p_rng )
2139{
2140 int ret;
2141 mbedtls_mpi XX;
2142
2143 XX.s = 1;
2144 XX.n = X->n;
2145 XX.p = X->p;
2146
2147 if( mbedtls_mpi_cmp_int( &XX, 0 ) == 0 ||
2148 mbedtls_mpi_cmp_int( &XX, 1 ) == 0 )
2149 return( MBEDTLS_ERR_MPI_NOT_ACCEPTABLE );
2150
2151 if( mbedtls_mpi_cmp_int( &XX, 2 ) == 0 )
2152 return( 0 );
2153
2154 if( ( ret = mpi_check_small_factors( &XX ) ) != 0 )
2155 {
2156 if( ret == 1 )
2157 return( 0 );
2158
2159 return( ret );
2160 }
2161
2162 return( mpi_miller_rabin( &XX, f_rng, p_rng ) );
2163}
2164
2165/*
2166 * Prime number generation
2167 */
2168int mbedtls_mpi_gen_prime( mbedtls_mpi *X, size_t nbits, int dh_flag,
2169 int (*f_rng)(void *, unsigned char *, size_t),
2170 void *p_rng )
2171{
2172 int ret;
2173 size_t k, n;
2174 mbedtls_mpi_uint r;
2175 mbedtls_mpi Y;
2176
2177 if( nbits < 3 || nbits > MBEDTLS_MPI_MAX_BITS )
2178 return( MBEDTLS_ERR_MPI_BAD_INPUT_DATA );
2179
2180 mbedtls_mpi_init( &Y );
2181
2182 n = BITS_TO_LIMBS( nbits );
2183
2184 MBEDTLS_MPI_CHK( mbedtls_mpi_fill_random( X, n * ciL, f_rng, p_rng ) );
2185
2186 k = mbedtls_mpi_bitlen( X );
2187 if( k > nbits ) MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( X, k - nbits + 1 ) );
2188
2189 mbedtls_mpi_set_bit( X, nbits-1, 1 );
2190
2191 X->p[0] |= 1;
2192
2193 if( dh_flag == 0 )
2194 {
2195 while( ( ret = mbedtls_mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
2196 {
2197 if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
2198 goto cleanup;
2199
2200 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 2 ) );
2201 }
2202 }
2203 else
2204 {
2205 /*
2206 * An necessary condition for Y and X = 2Y + 1 to be prime
2207 * is X = 2 mod 3 (which is equivalent to Y = 2 mod 3).
2208 * Make sure it is satisfied, while keeping X = 3 mod 4
2209 */
2210
2211 X->p[0] |= 2;
2212
2213 MBEDTLS_MPI_CHK( mbedtls_mpi_mod_int( &r, X, 3 ) );
2214 if( r == 0 )
2215 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 8 ) );
2216 else if( r == 1 )
2217 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 4 ) );
2218
2219 /* Set Y = (X-1) / 2, which is X / 2 because X is odd */
2220 MBEDTLS_MPI_CHK( mbedtls_mpi_copy( &Y, X ) );
2221 MBEDTLS_MPI_CHK( mbedtls_mpi_shift_r( &Y, 1 ) );
2222
2223 while( 1 )
2224 {
2225 /*
2226 * First, check small factors for X and Y
2227 * before doing Miller-Rabin on any of them
2228 */
2229 if( ( ret = mpi_check_small_factors( X ) ) == 0 &&
2230 ( ret = mpi_check_small_factors( &Y ) ) == 0 &&
2231 ( ret = mpi_miller_rabin( X, f_rng, p_rng ) ) == 0 &&
2232 ( ret = mpi_miller_rabin( &Y, f_rng, p_rng ) ) == 0 )
2233 {
2234 break;
2235 }
2236
2237 if( ret != MBEDTLS_ERR_MPI_NOT_ACCEPTABLE )
2238 goto cleanup;
2239
2240 /*
2241 * Next candidates. We want to preserve Y = (X-1) / 2 and
2242 * Y = 1 mod 2 and Y = 2 mod 3 (eq X = 3 mod 4 and X = 2 mod 3)
2243 * so up Y by 6 and X by 12.
2244 */
2245 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( X, X, 12 ) );
2246 MBEDTLS_MPI_CHK( mbedtls_mpi_add_int( &Y, &Y, 6 ) );
2247 }
2248 }
2249
2250cleanup:
2251
2252 mbedtls_mpi_free( &Y );
2253
2254 return( ret );
2255}
2256
2257#endif /* MBEDTLS_GENPRIME */
2258
2259#if defined(MBEDTLS_SELF_TEST)
2260
2261#define GCD_PAIR_COUNT 3
2262
2263static const int gcd_pairs[GCD_PAIR_COUNT][3] =
2264{
2265 { 693, 609, 21 },
2266 { 1764, 868, 28 },
2267 { 768454923, 542167814, 1 }
2268};
2269
2270/*
2271 * Checkup routine
2272 */
2273int mbedtls_mpi_self_test( int verbose )
2274{
2275 int ret, i;
2276 mbedtls_mpi A, E, N, X, Y, U, V;
2277
2278 mbedtls_mpi_init( &A ); mbedtls_mpi_init( &E ); mbedtls_mpi_init( &N ); mbedtls_mpi_init( &X );
2279 mbedtls_mpi_init( &Y ); mbedtls_mpi_init( &U ); mbedtls_mpi_init( &V );
2280
2281 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &A, 16,
2282 "EFE021C2645FD1DC586E69184AF4A31E" \
2283 "D5F53E93B5F123FA41680867BA110131" \
2284 "944FE7952E2517337780CB0DB80E61AA" \
2285 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
2286
2287 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &E, 16,
2288 "B2E7EFD37075B9F03FF989C7C5051C20" \
2289 "34D2A323810251127E7BF8625A4F49A5" \
2290 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
2291 "5B5C25763222FEFCCFC38B832366C29E" ) );
2292
2293 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &N, 16,
2294 "0066A198186C18C10B2F5ED9B522752A" \
2295 "9830B69916E535C8F047518A889A43A5" \
2296 "94B6BED27A168D31D4A52F88925AA8F5" ) );
2297
2298 MBEDTLS_MPI_CHK( mbedtls_mpi_mul_mpi( &X, &A, &N ) );
2299
2300 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
2301 "602AB7ECA597A3D6B56FF9829A5E8B85" \
2302 "9E857EA95A03512E2BAE7391688D264A" \
2303 "A5663B0341DB9CCFD2C4C5F421FEC814" \
2304 "8001B72E848A38CAE1C65F78E56ABDEF" \
2305 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
2306 "ECF677152EF804370C1A305CAF3B5BF1" \
2307 "30879B56C61DE584A0F53A2447A51E" ) );
2308
2309 if( verbose != 0 )
2310 mbedtls_printf( " MPI test #1 (mul_mpi): " );
2311
2312 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
2313 {
2314 if( verbose != 0 )
2315 mbedtls_printf( "failed\n" );
2316
2317 ret = 1;
2318 goto cleanup;
2319 }
2320
2321 if( verbose != 0 )
2322 mbedtls_printf( "passed\n" );
2323
2324 MBEDTLS_MPI_CHK( mbedtls_mpi_div_mpi( &X, &Y, &A, &N ) );
2325
2326 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
2327 "256567336059E52CAE22925474705F39A94" ) );
2328
2329 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &V, 16,
2330 "6613F26162223DF488E9CD48CC132C7A" \
2331 "0AC93C701B001B092E4E5B9F73BCD27B" \
2332 "9EE50D0657C77F374E903CDFA4C642" ) );
2333
2334 if( verbose != 0 )
2335 mbedtls_printf( " MPI test #2 (div_mpi): " );
2336
2337 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 ||
2338 mbedtls_mpi_cmp_mpi( &Y, &V ) != 0 )
2339 {
2340 if( verbose != 0 )
2341 mbedtls_printf( "failed\n" );
2342
2343 ret = 1;
2344 goto cleanup;
2345 }
2346
2347 if( verbose != 0 )
2348 mbedtls_printf( "passed\n" );
2349
2350 MBEDTLS_MPI_CHK( mbedtls_mpi_exp_mod( &X, &A, &E, &N, NULL ) );
2351
2352 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
2353 "36E139AEA55215609D2816998ED020BB" \
2354 "BD96C37890F65171D948E9BC7CBAA4D9" \
2355 "325D24D6A3C12710F10A09FA08AB87" ) );
2356
2357 if( verbose != 0 )
2358 mbedtls_printf( " MPI test #3 (exp_mod): " );
2359
2360 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
2361 {
2362 if( verbose != 0 )
2363 mbedtls_printf( "failed\n" );
2364
2365 ret = 1;
2366 goto cleanup;
2367 }
2368
2369 if( verbose != 0 )
2370 mbedtls_printf( "passed\n" );
2371
2372 MBEDTLS_MPI_CHK( mbedtls_mpi_inv_mod( &X, &A, &N ) );
2373
2374 MBEDTLS_MPI_CHK( mbedtls_mpi_read_string( &U, 16,
2375 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
2376 "C3DBA76456363A10869622EAC2DD84EC" \
2377 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
2378
2379 if( verbose != 0 )
2380 mbedtls_printf( " MPI test #4 (inv_mod): " );
2381
2382 if( mbedtls_mpi_cmp_mpi( &X, &U ) != 0 )
2383 {
2384 if( verbose != 0 )
2385 mbedtls_printf( "failed\n" );
2386
2387 ret = 1;
2388 goto cleanup;
2389 }
2390
2391 if( verbose != 0 )
2392 mbedtls_printf( "passed\n" );
2393
2394 if( verbose != 0 )
2395 mbedtls_printf( " MPI test #5 (simple gcd): " );
2396
2397 for( i = 0; i < GCD_PAIR_COUNT; i++ )
2398 {
2399 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &X, gcd_pairs[i][0] ) );
2400 MBEDTLS_MPI_CHK( mbedtls_mpi_lset( &Y, gcd_pairs[i][1] ) );
2401
2402 MBEDTLS_MPI_CHK( mbedtls_mpi_gcd( &A, &X, &Y ) );
2403
2404 if( mbedtls_mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
2405 {
2406 if( verbose != 0 )
2407 mbedtls_printf( "failed at %d\n", i );
2408
2409 ret = 1;
2410 goto cleanup;
2411 }
2412 }
2413
2414 if( verbose != 0 )
2415 mbedtls_printf( "passed\n" );
2416
2417cleanup:
2418
2419 if( ret != 0 && verbose != 0 )
2420 mbedtls_printf( "Unexpected error, return code = %08X\n", ret );
2421
2422 mbedtls_mpi_free( &A ); mbedtls_mpi_free( &E ); mbedtls_mpi_free( &N ); mbedtls_mpi_free( &X );
2423 mbedtls_mpi_free( &Y ); mbedtls_mpi_free( &U ); mbedtls_mpi_free( &V );
2424
2425 if( verbose != 0 )
2426 mbedtls_printf( "\n" );
2427
2428 return( ret );
2429}
2430
2431#endif /* MBEDTLS_SELF_TEST */
2432
2433#endif /* MBEDTLS_BIGNUM_C */
Note: See TracBrowser for help on using the repository browser.