blob: 1685d308a958843907cfdc932128f258c4c9e405 [file] [log] [blame]
Paul Bakker5121ce52009-01-03 21:22:43 +00001/*
2 * Multi-precision integer library
3 *
Paul Bakkere0ccd0a2009-01-04 16:27:10 +00004 * Based on XySSL: Copyright (C) 2006-2008 Christophe Devine
5 *
Paul Bakker785a9ee2009-01-25 14:15:10 +00006 * Copyright (C) 2009 Paul Bakker <polarssl_maintainer at polarssl dot org>
Paul Bakker5121ce52009-01-03 21:22:43 +00007 *
8 * This program is free software; you can redistribute it and/or modify
9 * it under the terms of the GNU General Public License as published by
10 * the Free Software Foundation; either version 2 of the License, or
11 * (at your option) any later version.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License along
19 * with this program; if not, write to the Free Software Foundation, Inc.,
20 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
22/*
23 * This MPI implementation is based on:
24 *
25 * http://www.cacr.math.uwaterloo.ca/hac/about/chap14.pdf
26 * http://www.stillhq.com/extracted/gnupg-api/mpi/
27 * http://math.libtomcrypt.com/files/tommath.pdf
28 */
29
Paul Bakker40e46942009-01-03 21:51:57 +000030#include "polarssl/config.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000031
Paul Bakker40e46942009-01-03 21:51:57 +000032#if defined(POLARSSL_BIGNUM_C)
Paul Bakker5121ce52009-01-03 21:22:43 +000033
Paul Bakker40e46942009-01-03 21:51:57 +000034#include "polarssl/bignum.h"
35#include "polarssl/bn_mul.h"
Paul Bakker5121ce52009-01-03 21:22:43 +000036
37#include <string.h>
38#include <stdlib.h>
39#include <stdarg.h>
40
41#define ciL ((int) sizeof(t_int)) /* chars in limb */
42#define biL (ciL << 3) /* bits in limb */
43#define biH (ciL << 2) /* half limb size */
44
45/*
46 * Convert between bits/chars and number of limbs
47 */
48#define BITS_TO_LIMBS(i) (((i) + biL - 1) / biL)
49#define CHARS_TO_LIMBS(i) (((i) + ciL - 1) / ciL)
50
51/*
52 * Initialize one or more mpi
53 */
54void mpi_init( mpi *X, ... )
55{
56 va_list args;
57
58 va_start( args, X );
59
60 while( X != NULL )
61 {
62 X->s = 1;
63 X->n = 0;
64 X->p = NULL;
65
66 X = va_arg( args, mpi* );
67 }
68
69 va_end( args );
70}
71
72/*
73 * Unallocate one or more mpi
74 */
75void mpi_free( mpi *X, ... )
76{
77 va_list args;
78
79 va_start( args, X );
80
81 while( X != NULL )
82 {
83 if( X->p != NULL )
84 {
85 memset( X->p, 0, X->n * ciL );
86 free( X->p );
87 }
88
89 X->s = 1;
90 X->n = 0;
91 X->p = NULL;
92
93 X = va_arg( args, mpi* );
94 }
95
96 va_end( args );
97}
98
99/*
100 * Enlarge to the specified number of limbs
101 */
102int mpi_grow( mpi *X, int nblimbs )
103{
104 t_int *p;
105
106 if( X->n < nblimbs )
107 {
108 if( ( p = (t_int *) malloc( nblimbs * ciL ) ) == NULL )
109 return( 1 );
110
111 memset( p, 0, nblimbs * ciL );
112
113 if( X->p != NULL )
114 {
115 memcpy( p, X->p, X->n * ciL );
116 memset( X->p, 0, X->n * ciL );
117 free( X->p );
118 }
119
120 X->n = nblimbs;
121 X->p = p;
122 }
123
124 return( 0 );
125}
126
127/*
128 * Copy the contents of Y into X
129 */
130int mpi_copy( mpi *X, mpi *Y )
131{
132 int ret, i;
133
134 if( X == Y )
135 return( 0 );
136
137 for( i = Y->n - 1; i > 0; i-- )
138 if( Y->p[i] != 0 )
139 break;
140 i++;
141
142 X->s = Y->s;
143
144 MPI_CHK( mpi_grow( X, i ) );
145
146 memset( X->p, 0, X->n * ciL );
147 memcpy( X->p, Y->p, i * ciL );
148
149cleanup:
150
151 return( ret );
152}
153
154/*
155 * Swap the contents of X and Y
156 */
157void mpi_swap( mpi *X, mpi *Y )
158{
159 mpi T;
160
161 memcpy( &T, X, sizeof( mpi ) );
162 memcpy( X, Y, sizeof( mpi ) );
163 memcpy( Y, &T, sizeof( mpi ) );
164}
165
166/*
167 * Set value from integer
168 */
169int mpi_lset( mpi *X, int z )
170{
171 int ret;
172
173 MPI_CHK( mpi_grow( X, 1 ) );
174 memset( X->p, 0, X->n * ciL );
175
176 X->p[0] = ( z < 0 ) ? -z : z;
177 X->s = ( z < 0 ) ? -1 : 1;
178
179cleanup:
180
181 return( ret );
182}
183
184/*
185 * Return the number of least significant bits
186 */
187int mpi_lsb( mpi *X )
188{
189 int i, j, count = 0;
190
191 for( i = 0; i < X->n; i++ )
192 for( j = 0; j < (int) biL; j++, count++ )
193 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
194 return( count );
195
196 return( 0 );
197}
198
199/*
200 * Return the number of most significant bits
201 */
202int mpi_msb( mpi *X )
203{
204 int i, j;
205
206 for( i = X->n - 1; i > 0; i-- )
207 if( X->p[i] != 0 )
208 break;
209
210 for( j = biL - 1; j >= 0; j-- )
211 if( ( ( X->p[i] >> j ) & 1 ) != 0 )
212 break;
213
214 return( ( i * biL ) + j + 1 );
215}
216
217/*
218 * Return the total size in bytes
219 */
220int mpi_size( mpi *X )
221{
222 return( ( mpi_msb( X ) + 7 ) >> 3 );
223}
224
225/*
226 * Convert an ASCII character to digit value
227 */
228static int mpi_get_digit( t_int *d, int radix, char c )
229{
230 *d = 255;
231
232 if( c >= 0x30 && c <= 0x39 ) *d = c - 0x30;
233 if( c >= 0x41 && c <= 0x46 ) *d = c - 0x37;
234 if( c >= 0x61 && c <= 0x66 ) *d = c - 0x57;
235
236 if( *d >= (t_int) radix )
Paul Bakker40e46942009-01-03 21:51:57 +0000237 return( POLARSSL_ERR_MPI_INVALID_CHARACTER );
Paul Bakker5121ce52009-01-03 21:22:43 +0000238
239 return( 0 );
240}
241
242/*
243 * Import from an ASCII string
244 */
245int mpi_read_string( mpi *X, int radix, char *s )
246{
247 int ret, i, j, n;
248 t_int d;
249 mpi T;
250
251 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000252 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000253
254 mpi_init( &T, NULL );
255
256 if( radix == 16 )
257 {
258 n = BITS_TO_LIMBS( strlen( s ) << 2 );
259
260 MPI_CHK( mpi_grow( X, n ) );
261 MPI_CHK( mpi_lset( X, 0 ) );
262
263 for( i = strlen( s ) - 1, j = 0; i >= 0; i--, j++ )
264 {
265 if( i == 0 && s[i] == '-' )
266 {
267 X->s = -1;
268 break;
269 }
270
271 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
272 X->p[j / (2 * ciL)] |= d << ( (j % (2 * ciL)) << 2 );
273 }
274 }
275 else
276 {
277 MPI_CHK( mpi_lset( X, 0 ) );
278
279 for( i = 0; i < (int) strlen( s ); i++ )
280 {
281 if( i == 0 && s[i] == '-' )
282 {
283 X->s = -1;
284 continue;
285 }
286
287 MPI_CHK( mpi_get_digit( &d, radix, s[i] ) );
288 MPI_CHK( mpi_mul_int( &T, X, radix ) );
289 MPI_CHK( mpi_add_int( X, &T, d ) );
290 }
291 }
292
293cleanup:
294
295 mpi_free( &T, NULL );
296
297 return( ret );
298}
299
300/*
301 * Helper to write the digits high-order first
302 */
303static int mpi_write_hlp( mpi *X, int radix, char **p )
304{
305 int ret;
306 t_int r;
307
308 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000309 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000310
311 MPI_CHK( mpi_mod_int( &r, X, radix ) );
312 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
313
314 if( mpi_cmp_int( X, 0 ) != 0 )
315 MPI_CHK( mpi_write_hlp( X, radix, p ) );
316
317 if( r < 10 )
318 *(*p)++ = (char)( r + 0x30 );
319 else
320 *(*p)++ = (char)( r + 0x37 );
321
322cleanup:
323
324 return( ret );
325}
326
327/*
328 * Export into an ASCII string
329 */
330int mpi_write_string( mpi *X, int radix, char *s, int *slen )
331{
332 int ret = 0, n;
333 char *p;
334 mpi T;
335
336 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000337 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000338
339 n = mpi_msb( X );
340 if( radix >= 4 ) n >>= 1;
341 if( radix >= 16 ) n >>= 1;
342 n += 3;
343
344 if( *slen < n )
345 {
346 *slen = n;
Paul Bakker40e46942009-01-03 21:51:57 +0000347 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000348 }
349
350 p = s;
351 mpi_init( &T, NULL );
352
353 if( X->s == -1 )
354 *p++ = '-';
355
356 if( radix == 16 )
357 {
358 int c, i, j, k;
359
360 for( i = X->n - 1, k = 0; i >= 0; i-- )
361 {
362 for( j = ciL - 1; j >= 0; j-- )
363 {
364 c = ( X->p[i] >> (j << 3) ) & 0xFF;
365
366 if( c == 0 && k == 0 && (i + j) != 0 )
367 continue;
368
369 p += sprintf( p, "%02X", c );
370 k = 1;
371 }
372 }
373 }
374 else
375 {
376 MPI_CHK( mpi_copy( &T, X ) );
377 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
378 }
379
380 *p++ = '\0';
381 *slen = p - s;
382
383cleanup:
384
385 mpi_free( &T, NULL );
386
387 return( ret );
388}
389
390/*
391 * Read X from an opened file
392 */
393int mpi_read_file( mpi *X, int radix, FILE *fin )
394{
395 t_int d;
396 int slen;
397 char *p;
398 char s[1024];
399
400 memset( s, 0, sizeof( s ) );
401 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000402 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000403
404 slen = strlen( s );
405 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
406 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
407
408 p = s + slen;
409 while( --p >= s )
410 if( mpi_get_digit( &d, radix, *p ) != 0 )
411 break;
412
413 return( mpi_read_string( X, radix, p + 1 ) );
414}
415
416/*
417 * Write X into an opened file (or stdout if fout == NULL)
418 */
419int mpi_write_file( char *p, mpi *X, int radix, FILE *fout )
420{
421 int n, ret;
422 size_t slen;
423 size_t plen;
424 char s[1024];
425
426 n = sizeof( s );
427 memset( s, 0, n );
428 n -= 2;
429
430 MPI_CHK( mpi_write_string( X, radix, s, (int *) &n ) );
431
432 if( p == NULL ) p = "";
433
434 plen = strlen( p );
435 slen = strlen( s );
436 s[slen++] = '\r';
437 s[slen++] = '\n';
438
439 if( fout != NULL )
440 {
441 if( fwrite( p, 1, plen, fout ) != plen ||
442 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000443 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000444 }
445 else
446 printf( "%s%s", p, s );
447
448cleanup:
449
450 return( ret );
451}
452
453/*
454 * Import X from unsigned binary data, big endian
455 */
456int mpi_read_binary( mpi *X, unsigned char *buf, int buflen )
457{
458 int ret, i, j, n;
459
460 for( n = 0; n < buflen; n++ )
461 if( buf[n] != 0 )
462 break;
463
464 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
465 MPI_CHK( mpi_lset( X, 0 ) );
466
467 for( i = buflen - 1, j = 0; i >= n; i--, j++ )
468 X->p[j / ciL] |= ((t_int) buf[i]) << ((j % ciL) << 3);
469
470cleanup:
471
472 return( ret );
473}
474
475/*
476 * Export X into unsigned binary data, big endian
477 */
478int mpi_write_binary( mpi *X, unsigned char *buf, int buflen )
479{
480 int i, j, n;
481
482 n = mpi_size( X );
483
484 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000485 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000486
487 memset( buf, 0, buflen );
488
489 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
490 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
491
492 return( 0 );
493}
494
495/*
496 * Left-shift: X <<= count
497 */
498int mpi_shift_l( mpi *X, int count )
499{
500 int ret, i, v0, t1;
501 t_int r0 = 0, r1;
502
503 v0 = count / (biL );
504 t1 = count & (biL - 1);
505
506 i = mpi_msb( X ) + count;
507
508 if( X->n * (int) biL < i )
509 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
510
511 ret = 0;
512
513 /*
514 * shift by count / limb_size
515 */
516 if( v0 > 0 )
517 {
518 for( i = X->n - 1; i >= v0; i-- )
519 X->p[i] = X->p[i - v0];
520
521 for( ; i >= 0; i-- )
522 X->p[i] = 0;
523 }
524
525 /*
526 * shift by count % limb_size
527 */
528 if( t1 > 0 )
529 {
530 for( i = v0; i < X->n; i++ )
531 {
532 r1 = X->p[i] >> (biL - t1);
533 X->p[i] <<= t1;
534 X->p[i] |= r0;
535 r0 = r1;
536 }
537 }
538
539cleanup:
540
541 return( ret );
542}
543
544/*
545 * Right-shift: X >>= count
546 */
547int mpi_shift_r( mpi *X, int count )
548{
549 int i, v0, v1;
550 t_int r0 = 0, r1;
551
552 v0 = count / biL;
553 v1 = count & (biL - 1);
554
555 /*
556 * shift by count / limb_size
557 */
558 if( v0 > 0 )
559 {
560 for( i = 0; i < X->n - v0; i++ )
561 X->p[i] = X->p[i + v0];
562
563 for( ; i < X->n; i++ )
564 X->p[i] = 0;
565 }
566
567 /*
568 * shift by count % limb_size
569 */
570 if( v1 > 0 )
571 {
572 for( i = X->n - 1; i >= 0; i-- )
573 {
574 r1 = X->p[i] << (biL - v1);
575 X->p[i] >>= v1;
576 X->p[i] |= r0;
577 r0 = r1;
578 }
579 }
580
581 return( 0 );
582}
583
584/*
585 * Compare unsigned values
586 */
587int mpi_cmp_abs( mpi *X, mpi *Y )
588{
589 int i, j;
590
591 for( i = X->n - 1; i >= 0; i-- )
592 if( X->p[i] != 0 )
593 break;
594
595 for( j = Y->n - 1; j >= 0; j-- )
596 if( Y->p[j] != 0 )
597 break;
598
599 if( i < 0 && j < 0 )
600 return( 0 );
601
602 if( i > j ) return( 1 );
603 if( j > i ) return( -1 );
604
605 for( ; i >= 0; i-- )
606 {
607 if( X->p[i] > Y->p[i] ) return( 1 );
608 if( X->p[i] < Y->p[i] ) return( -1 );
609 }
610
611 return( 0 );
612}
613
614/*
615 * Compare signed values
616 */
617int mpi_cmp_mpi( mpi *X, mpi *Y )
618{
619 int i, j;
620
621 for( i = X->n - 1; i >= 0; i-- )
622 if( X->p[i] != 0 )
623 break;
624
625 for( j = Y->n - 1; j >= 0; j-- )
626 if( Y->p[j] != 0 )
627 break;
628
629 if( i < 0 && j < 0 )
630 return( 0 );
631
632 if( i > j ) return( X->s );
633 if( j > i ) return( -X->s );
634
635 if( X->s > 0 && Y->s < 0 ) return( 1 );
636 if( Y->s > 0 && X->s < 0 ) return( -1 );
637
638 for( ; i >= 0; i-- )
639 {
640 if( X->p[i] > Y->p[i] ) return( X->s );
641 if( X->p[i] < Y->p[i] ) return( -X->s );
642 }
643
644 return( 0 );
645}
646
647/*
648 * Compare signed values
649 */
650int mpi_cmp_int( mpi *X, int z )
651{
652 mpi Y;
653 t_int p[1];
654
655 *p = ( z < 0 ) ? -z : z;
656 Y.s = ( z < 0 ) ? -1 : 1;
657 Y.n = 1;
658 Y.p = p;
659
660 return( mpi_cmp_mpi( X, &Y ) );
661}
662
663/*
664 * Unsigned addition: X = |A| + |B| (HAC 14.7)
665 */
666int mpi_add_abs( mpi *X, mpi *A, mpi *B )
667{
668 int ret, i, j;
669 t_int *o, *p, c;
670
671 if( X == B )
672 {
673 mpi *T = A; A = X; B = T;
674 }
675
676 if( X != A )
677 MPI_CHK( mpi_copy( X, A ) );
678
679 for( j = B->n - 1; j >= 0; j-- )
680 if( B->p[j] != 0 )
681 break;
682
683 MPI_CHK( mpi_grow( X, j + 1 ) );
684
685 o = B->p; p = X->p; c = 0;
686
687 for( i = 0; i <= j; i++, o++, p++ )
688 {
689 *p += c; c = ( *p < c );
690 *p += *o; c += ( *p < *o );
691 }
692
693 while( c != 0 )
694 {
695 if( i >= X->n )
696 {
697 MPI_CHK( mpi_grow( X, i + 1 ) );
698 p = X->p + i;
699 }
700
701 *p += c; c = ( *p < c ); i++;
702 }
703
704cleanup:
705
706 return( ret );
707}
708
709/*
710 * Helper for mpi substraction
711 */
712static void mpi_sub_hlp( int n, t_int *s, t_int *d )
713{
714 int i;
715 t_int c, z;
716
717 for( i = c = 0; i < n; i++, s++, d++ )
718 {
719 z = ( *d < c ); *d -= c;
720 c = ( *d < *s ) + z; *d -= *s;
721 }
722
723 while( c != 0 )
724 {
725 z = ( *d < c ); *d -= c;
726 c = z; i++; d++;
727 }
728}
729
730/*
731 * Unsigned substraction: X = |A| - |B| (HAC 14.9)
732 */
733int mpi_sub_abs( mpi *X, mpi *A, mpi *B )
734{
735 mpi TB;
736 int ret, n;
737
738 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000739 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000740
741 mpi_init( &TB, NULL );
742
743 if( X == B )
744 {
745 MPI_CHK( mpi_copy( &TB, B ) );
746 B = &TB;
747 }
748
749 if( X != A )
750 MPI_CHK( mpi_copy( X, A ) );
751
752 ret = 0;
753
754 for( n = B->n - 1; n >= 0; n-- )
755 if( B->p[n] != 0 )
756 break;
757
758 mpi_sub_hlp( n + 1, B->p, X->p );
759
760cleanup:
761
762 mpi_free( &TB, NULL );
763
764 return( ret );
765}
766
767/*
768 * Signed addition: X = A + B
769 */
770int mpi_add_mpi( mpi *X, mpi *A, mpi *B )
771{
772 int ret, s = A->s;
773
774 if( A->s * B->s < 0 )
775 {
776 if( mpi_cmp_abs( A, B ) >= 0 )
777 {
778 MPI_CHK( mpi_sub_abs( X, A, B ) );
779 X->s = s;
780 }
781 else
782 {
783 MPI_CHK( mpi_sub_abs( X, B, A ) );
784 X->s = -s;
785 }
786 }
787 else
788 {
789 MPI_CHK( mpi_add_abs( X, A, B ) );
790 X->s = s;
791 }
792
793cleanup:
794
795 return( ret );
796}
797
798/*
799 * Signed substraction: X = A - B
800 */
801int mpi_sub_mpi( mpi *X, mpi *A, mpi *B )
802{
803 int ret, s = A->s;
804
805 if( A->s * B->s > 0 )
806 {
807 if( mpi_cmp_abs( A, B ) >= 0 )
808 {
809 MPI_CHK( mpi_sub_abs( X, A, B ) );
810 X->s = s;
811 }
812 else
813 {
814 MPI_CHK( mpi_sub_abs( X, B, A ) );
815 X->s = -s;
816 }
817 }
818 else
819 {
820 MPI_CHK( mpi_add_abs( X, A, B ) );
821 X->s = s;
822 }
823
824cleanup:
825
826 return( ret );
827}
828
829/*
830 * Signed addition: X = A + b
831 */
832int mpi_add_int( mpi *X, mpi *A, int b )
833{
834 mpi _B;
835 t_int p[1];
836
837 p[0] = ( b < 0 ) ? -b : b;
838 _B.s = ( b < 0 ) ? -1 : 1;
839 _B.n = 1;
840 _B.p = p;
841
842 return( mpi_add_mpi( X, A, &_B ) );
843}
844
845/*
846 * Signed substraction: X = A - b
847 */
848int mpi_sub_int( mpi *X, mpi *A, int b )
849{
850 mpi _B;
851 t_int p[1];
852
853 p[0] = ( b < 0 ) ? -b : b;
854 _B.s = ( b < 0 ) ? -1 : 1;
855 _B.n = 1;
856 _B.p = p;
857
858 return( mpi_sub_mpi( X, A, &_B ) );
859}
860
861/*
862 * Helper for mpi multiplication
863 */
864static void mpi_mul_hlp( int i, t_int *s, t_int *d, t_int b )
865{
866 t_int c = 0, t = 0;
867
868#if defined(MULADDC_HUIT)
869 for( ; i >= 8; i -= 8 )
870 {
871 MULADDC_INIT
872 MULADDC_HUIT
873 MULADDC_STOP
874 }
875
876 for( ; i > 0; i-- )
877 {
878 MULADDC_INIT
879 MULADDC_CORE
880 MULADDC_STOP
881 }
882#else
883 for( ; i >= 16; i -= 16 )
884 {
885 MULADDC_INIT
886 MULADDC_CORE MULADDC_CORE
887 MULADDC_CORE MULADDC_CORE
888 MULADDC_CORE MULADDC_CORE
889 MULADDC_CORE MULADDC_CORE
890
891 MULADDC_CORE MULADDC_CORE
892 MULADDC_CORE MULADDC_CORE
893 MULADDC_CORE MULADDC_CORE
894 MULADDC_CORE MULADDC_CORE
895 MULADDC_STOP
896 }
897
898 for( ; i >= 8; i -= 8 )
899 {
900 MULADDC_INIT
901 MULADDC_CORE MULADDC_CORE
902 MULADDC_CORE MULADDC_CORE
903
904 MULADDC_CORE MULADDC_CORE
905 MULADDC_CORE MULADDC_CORE
906 MULADDC_STOP
907 }
908
909 for( ; i > 0; i-- )
910 {
911 MULADDC_INIT
912 MULADDC_CORE
913 MULADDC_STOP
914 }
915#endif
916
917 t++;
918
919 do {
920 *d += c; c = ( *d < c ); d++;
921 }
922 while( c != 0 );
923}
924
925/*
926 * Baseline multiplication: X = A * B (HAC 14.12)
927 */
928int mpi_mul_mpi( mpi *X, mpi *A, mpi *B )
929{
930 int ret, i, j;
931 mpi TA, TB;
932
933 mpi_init( &TA, &TB, NULL );
934
935 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
936 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
937
938 for( i = A->n - 1; i >= 0; i-- )
939 if( A->p[i] != 0 )
940 break;
941
942 for( j = B->n - 1; j >= 0; j-- )
943 if( B->p[j] != 0 )
944 break;
945
946 MPI_CHK( mpi_grow( X, i + j + 2 ) );
947 MPI_CHK( mpi_lset( X, 0 ) );
948
949 for( i++; j >= 0; j-- )
950 mpi_mul_hlp( i, A->p, X->p + j, B->p[j] );
951
952 X->s = A->s * B->s;
953
954cleanup:
955
956 mpi_free( &TB, &TA, NULL );
957
958 return( ret );
959}
960
961/*
962 * Baseline multiplication: X = A * b
963 */
964int mpi_mul_int( mpi *X, mpi *A, t_int b )
965{
966 mpi _B;
967 t_int p[1];
968
969 _B.s = 1;
970 _B.n = 1;
971 _B.p = p;
972 p[0] = b;
973
974 return( mpi_mul_mpi( X, A, &_B ) );
975}
976
977/*
978 * Division by mpi: A = Q * B + R (HAC 14.20)
979 */
980int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B )
981{
982 int ret, i, n, t, k;
983 mpi X, Y, Z, T1, T2;
984
985 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000986 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +0000987
988 mpi_init( &X, &Y, &Z, &T1, &T2, NULL );
989
990 if( mpi_cmp_abs( A, B ) < 0 )
991 {
992 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
993 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
994 return( 0 );
995 }
996
997 MPI_CHK( mpi_copy( &X, A ) );
998 MPI_CHK( mpi_copy( &Y, B ) );
999 X.s = Y.s = 1;
1000
1001 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1002 MPI_CHK( mpi_lset( &Z, 0 ) );
1003 MPI_CHK( mpi_grow( &T1, 2 ) );
1004 MPI_CHK( mpi_grow( &T2, 3 ) );
1005
1006 k = mpi_msb( &Y ) % biL;
1007 if( k < (int) biL - 1 )
1008 {
1009 k = biL - 1 - k;
1010 MPI_CHK( mpi_shift_l( &X, k ) );
1011 MPI_CHK( mpi_shift_l( &Y, k ) );
1012 }
1013 else k = 0;
1014
1015 n = X.n - 1;
1016 t = Y.n - 1;
1017 mpi_shift_l( &Y, biL * (n - t) );
1018
1019 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1020 {
1021 Z.p[n - t]++;
1022 mpi_sub_mpi( &X, &X, &Y );
1023 }
1024 mpi_shift_r( &Y, biL * (n - t) );
1025
1026 for( i = n; i > t ; i-- )
1027 {
1028 if( X.p[i] >= Y.p[t] )
1029 Z.p[i - t - 1] = ~0;
1030 else
1031 {
Paul Bakker40e46942009-01-03 21:51:57 +00001032#if defined(POLARSSL_HAVE_LONGLONG)
Paul Bakker5121ce52009-01-03 21:22:43 +00001033 t_dbl r;
1034
1035 r = (t_dbl) X.p[i] << biL;
1036 r |= (t_dbl) X.p[i - 1];
1037 r /= Y.p[t];
1038 if( r > ((t_dbl) 1 << biL) - 1)
1039 r = ((t_dbl) 1 << biL) - 1;
1040
1041 Z.p[i - t - 1] = (t_int) r;
1042#else
1043 /*
1044 * __udiv_qrnnd_c, from gmp/longlong.h
1045 */
1046 t_int q0, q1, r0, r1;
1047 t_int d0, d1, d, m;
1048
1049 d = Y.p[t];
1050 d0 = ( d << biH ) >> biH;
1051 d1 = ( d >> biH );
1052
1053 q1 = X.p[i] / d1;
1054 r1 = X.p[i] - d1 * q1;
1055 r1 <<= biH;
1056 r1 |= ( X.p[i - 1] >> biH );
1057
1058 m = q1 * d0;
1059 if( r1 < m )
1060 {
1061 q1--, r1 += d;
1062 while( r1 >= d && r1 < m )
1063 q1--, r1 += d;
1064 }
1065 r1 -= m;
1066
1067 q0 = r1 / d1;
1068 r0 = r1 - d1 * q0;
1069 r0 <<= biH;
1070 r0 |= ( X.p[i - 1] << biH ) >> biH;
1071
1072 m = q0 * d0;
1073 if( r0 < m )
1074 {
1075 q0--, r0 += d;
1076 while( r0 >= d && r0 < m )
1077 q0--, r0 += d;
1078 }
1079 r0 -= m;
1080
1081 Z.p[i - t - 1] = ( q1 << biH ) | q0;
1082#endif
1083 }
1084
1085 Z.p[i - t - 1]++;
1086 do
1087 {
1088 Z.p[i - t - 1]--;
1089
1090 MPI_CHK( mpi_lset( &T1, 0 ) );
1091 T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
1092 T1.p[1] = Y.p[t];
1093 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1094
1095 MPI_CHK( mpi_lset( &T2, 0 ) );
1096 T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
1097 T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
1098 T2.p[2] = X.p[i];
1099 }
1100 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1101
1102 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1103 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1104 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1105
1106 if( mpi_cmp_int( &X, 0 ) < 0 )
1107 {
1108 MPI_CHK( mpi_copy( &T1, &Y ) );
1109 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1110 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1111 Z.p[i - t - 1]--;
1112 }
1113 }
1114
1115 if( Q != NULL )
1116 {
1117 mpi_copy( Q, &Z );
1118 Q->s = A->s * B->s;
1119 }
1120
1121 if( R != NULL )
1122 {
1123 mpi_shift_r( &X, k );
1124 mpi_copy( R, &X );
1125
1126 R->s = A->s;
1127 if( mpi_cmp_int( R, 0 ) == 0 )
1128 R->s = 1;
1129 }
1130
1131cleanup:
1132
1133 mpi_free( &X, &Y, &Z, &T1, &T2, NULL );
1134
1135 return( ret );
1136}
1137
1138/*
1139 * Division by int: A = Q * b + R
1140 *
1141 * Returns 0 if successful
1142 * 1 if memory allocation failed
Paul Bakker40e46942009-01-03 21:51:57 +00001143 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
Paul Bakker5121ce52009-01-03 21:22:43 +00001144 */
1145int mpi_div_int( mpi *Q, mpi *R, mpi *A, int b )
1146{
1147 mpi _B;
1148 t_int p[1];
1149
1150 p[0] = ( b < 0 ) ? -b : b;
1151 _B.s = ( b < 0 ) ? -1 : 1;
1152 _B.n = 1;
1153 _B.p = p;
1154
1155 return( mpi_div_mpi( Q, R, A, &_B ) );
1156}
1157
1158/*
1159 * Modulo: R = A mod B
1160 */
1161int mpi_mod_mpi( mpi *R, mpi *A, mpi *B )
1162{
1163 int ret;
1164
1165 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1166
1167 while( mpi_cmp_int( R, 0 ) < 0 )
1168 MPI_CHK( mpi_add_mpi( R, R, B ) );
1169
1170 while( mpi_cmp_mpi( R, B ) >= 0 )
1171 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1172
1173cleanup:
1174
1175 return( ret );
1176}
1177
1178/*
1179 * Modulo: r = A mod b
1180 */
1181int mpi_mod_int( t_int *r, mpi *A, int b )
1182{
1183 int i;
1184 t_int x, y, z;
1185
1186 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001187 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001188
1189 if( b < 0 )
1190 b = -b;
1191
1192 /*
1193 * handle trivial cases
1194 */
1195 if( b == 1 )
1196 {
1197 *r = 0;
1198 return( 0 );
1199 }
1200
1201 if( b == 2 )
1202 {
1203 *r = A->p[0] & 1;
1204 return( 0 );
1205 }
1206
1207 /*
1208 * general case
1209 */
1210 for( i = A->n - 1, y = 0; i >= 0; i-- )
1211 {
1212 x = A->p[i];
1213 y = ( y << biH ) | ( x >> biH );
1214 z = y / b;
1215 y -= z * b;
1216
1217 x <<= biH;
1218 y = ( y << biH ) | ( x >> biH );
1219 z = y / b;
1220 y -= z * b;
1221 }
1222
1223 *r = y;
1224
1225 return( 0 );
1226}
1227
1228/*
1229 * Fast Montgomery initialization (thanks to Tom St Denis)
1230 */
1231static void mpi_montg_init( t_int *mm, mpi *N )
1232{
1233 t_int x, m0 = N->p[0];
1234
1235 x = m0;
1236 x += ( ( m0 + 2 ) & 4 ) << 1;
1237 x *= ( 2 - ( m0 * x ) );
1238
1239 if( biL >= 16 ) x *= ( 2 - ( m0 * x ) );
1240 if( biL >= 32 ) x *= ( 2 - ( m0 * x ) );
1241 if( biL >= 64 ) x *= ( 2 - ( m0 * x ) );
1242
1243 *mm = ~x + 1;
1244}
1245
1246/*
1247 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1248 */
1249static void mpi_montmul( mpi *A, mpi *B, mpi *N, t_int mm, mpi *T )
1250{
1251 int i, n, m;
1252 t_int u0, u1, *d;
1253
1254 memset( T->p, 0, T->n * ciL );
1255
1256 d = T->p;
1257 n = N->n;
1258 m = ( B->n < n ) ? B->n : n;
1259
1260 for( i = 0; i < n; i++ )
1261 {
1262 /*
1263 * T = (T + u0*B + u1*N) / 2^biL
1264 */
1265 u0 = A->p[i];
1266 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1267
1268 mpi_mul_hlp( m, B->p, d, u0 );
1269 mpi_mul_hlp( n, N->p, d, u1 );
1270
1271 *d++ = u0; d[n + 1] = 0;
1272 }
1273
1274 memcpy( A->p, d, (n + 1) * ciL );
1275
1276 if( mpi_cmp_abs( A, N ) >= 0 )
1277 mpi_sub_hlp( n, N->p, A->p );
1278 else
1279 /* prevent timing attacks */
1280 mpi_sub_hlp( n, A->p, T->p );
1281}
1282
1283/*
1284 * Montgomery reduction: A = A * R^-1 mod N
1285 */
1286static void mpi_montred( mpi *A, mpi *N, t_int mm, mpi *T )
1287{
1288 t_int z = 1;
1289 mpi U;
1290
1291 U.n = U.s = z;
1292 U.p = &z;
1293
1294 mpi_montmul( A, &U, N, mm, T );
1295}
1296
1297/*
1298 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1299 */
1300int mpi_exp_mod( mpi *X, mpi *A, mpi *E, mpi *N, mpi *_RR )
1301{
1302 int ret, i, j, wsize, wbits;
1303 int bufsize, nblimbs, nbits;
1304 t_int ei, mm, state;
1305 mpi RR, T, W[64];
1306
1307 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001308 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001309
1310 /*
1311 * Init temps and window size
1312 */
1313 mpi_montg_init( &mm, N );
1314 mpi_init( &RR, &T, NULL );
1315 memset( W, 0, sizeof( W ) );
1316
1317 i = mpi_msb( E );
1318
1319 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1320 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1321
1322 j = N->n + 1;
1323 MPI_CHK( mpi_grow( X, j ) );
1324 MPI_CHK( mpi_grow( &W[1], j ) );
1325 MPI_CHK( mpi_grow( &T, j * 2 ) );
1326
1327 /*
1328 * If 1st call, pre-compute R^2 mod N
1329 */
1330 if( _RR == NULL || _RR->p == NULL )
1331 {
1332 MPI_CHK( mpi_lset( &RR, 1 ) );
1333 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1334 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1335
1336 if( _RR != NULL )
1337 memcpy( _RR, &RR, sizeof( mpi ) );
1338 }
1339 else
1340 memcpy( &RR, _RR, sizeof( mpi ) );
1341
1342 /*
1343 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1344 */
1345 if( mpi_cmp_mpi( A, N ) >= 0 )
1346 mpi_mod_mpi( &W[1], A, N );
1347 else mpi_copy( &W[1], A );
1348
1349 mpi_montmul( &W[1], &RR, N, mm, &T );
1350
1351 /*
1352 * X = R^2 * R^-1 mod N = R mod N
1353 */
1354 MPI_CHK( mpi_copy( X, &RR ) );
1355 mpi_montred( X, N, mm, &T );
1356
1357 if( wsize > 1 )
1358 {
1359 /*
1360 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1361 */
1362 j = 1 << (wsize - 1);
1363
1364 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1365 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1366
1367 for( i = 0; i < wsize - 1; i++ )
1368 mpi_montmul( &W[j], &W[j], N, mm, &T );
1369
1370 /*
1371 * W[i] = W[i - 1] * W[1]
1372 */
1373 for( i = j + 1; i < (1 << wsize); i++ )
1374 {
1375 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1376 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1377
1378 mpi_montmul( &W[i], &W[1], N, mm, &T );
1379 }
1380 }
1381
1382 nblimbs = E->n;
1383 bufsize = 0;
1384 nbits = 0;
1385 wbits = 0;
1386 state = 0;
1387
1388 while( 1 )
1389 {
1390 if( bufsize == 0 )
1391 {
1392 if( nblimbs-- == 0 )
1393 break;
1394
1395 bufsize = sizeof( t_int ) << 3;
1396 }
1397
1398 bufsize--;
1399
1400 ei = (E->p[nblimbs] >> bufsize) & 1;
1401
1402 /*
1403 * skip leading 0s
1404 */
1405 if( ei == 0 && state == 0 )
1406 continue;
1407
1408 if( ei == 0 && state == 1 )
1409 {
1410 /*
1411 * out of window, square X
1412 */
1413 mpi_montmul( X, X, N, mm, &T );
1414 continue;
1415 }
1416
1417 /*
1418 * add ei to current window
1419 */
1420 state = 2;
1421
1422 nbits++;
1423 wbits |= (ei << (wsize - nbits));
1424
1425 if( nbits == wsize )
1426 {
1427 /*
1428 * X = X^wsize R^-1 mod N
1429 */
1430 for( i = 0; i < wsize; i++ )
1431 mpi_montmul( X, X, N, mm, &T );
1432
1433 /*
1434 * X = X * W[wbits] R^-1 mod N
1435 */
1436 mpi_montmul( X, &W[wbits], N, mm, &T );
1437
1438 state--;
1439 nbits = 0;
1440 wbits = 0;
1441 }
1442 }
1443
1444 /*
1445 * process the remaining bits
1446 */
1447 for( i = 0; i < nbits; i++ )
1448 {
1449 mpi_montmul( X, X, N, mm, &T );
1450
1451 wbits <<= 1;
1452
1453 if( (wbits & (1 << wsize)) != 0 )
1454 mpi_montmul( X, &W[1], N, mm, &T );
1455 }
1456
1457 /*
1458 * X = A^E * R * R^-1 mod N = A^E mod N
1459 */
1460 mpi_montred( X, N, mm, &T );
1461
1462cleanup:
1463
1464 for( i = (1 << (wsize - 1)); i < (1 << wsize); i++ )
1465 mpi_free( &W[i], NULL );
1466
1467 if( _RR != NULL )
1468 mpi_free( &W[1], &T, NULL );
1469 else mpi_free( &W[1], &T, &RR, NULL );
1470
1471 return( ret );
1472}
1473
Paul Bakker40e46942009-01-03 21:51:57 +00001474#if defined(POLARSSL_GENPRIME)
Paul Bakker5121ce52009-01-03 21:22:43 +00001475
1476/*
1477 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1478 */
1479int mpi_gcd( mpi *G, mpi *A, mpi *B )
1480{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001481 int ret, lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001482 mpi TG, TA, TB;
1483
1484 mpi_init( &TG, &TA, &TB, NULL );
1485
Paul Bakker5121ce52009-01-03 21:22:43 +00001486 MPI_CHK( mpi_copy( &TA, A ) );
1487 MPI_CHK( mpi_copy( &TB, B ) );
1488
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001489 lz = mpi_lsb( &TA );
1490 lzt = mpi_lsb( &TB );
1491
1492 if ( lzt < lz )
1493 lz = lzt;
1494
1495 MPI_CHK( mpi_shift_r( &TA, lz ) );
1496 MPI_CHK( mpi_shift_r( &TB, lz ) );
1497
Paul Bakker5121ce52009-01-03 21:22:43 +00001498 TA.s = TB.s = 1;
1499
1500 while( mpi_cmp_int( &TA, 0 ) != 0 )
1501 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001502 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1503 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001504
1505 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1506 {
1507 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1508 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1509 }
1510 else
1511 {
1512 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1513 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1514 }
1515 }
1516
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001517 MPI_CHK( mpi_shift_l( &TB, lz ) );
1518 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001519
1520cleanup:
1521
1522 mpi_free( &TB, &TA, &TG, NULL );
1523
1524 return( ret );
1525}
1526
1527/*
1528 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1529 */
1530int mpi_inv_mod( mpi *X, mpi *A, mpi *N )
1531{
1532 int ret;
1533 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1534
1535 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001536 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001537
1538 mpi_init( &TA, &TU, &U1, &U2, &G,
1539 &TB, &TV, &V1, &V2, NULL );
1540
1541 MPI_CHK( mpi_gcd( &G, A, N ) );
1542
1543 if( mpi_cmp_int( &G, 1 ) != 0 )
1544 {
Paul Bakker40e46942009-01-03 21:51:57 +00001545 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001546 goto cleanup;
1547 }
1548
1549 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1550 MPI_CHK( mpi_copy( &TU, &TA ) );
1551 MPI_CHK( mpi_copy( &TB, N ) );
1552 MPI_CHK( mpi_copy( &TV, N ) );
1553
1554 MPI_CHK( mpi_lset( &U1, 1 ) );
1555 MPI_CHK( mpi_lset( &U2, 0 ) );
1556 MPI_CHK( mpi_lset( &V1, 0 ) );
1557 MPI_CHK( mpi_lset( &V2, 1 ) );
1558
1559 do
1560 {
1561 while( ( TU.p[0] & 1 ) == 0 )
1562 {
1563 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1564
1565 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1566 {
1567 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1568 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1569 }
1570
1571 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1572 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1573 }
1574
1575 while( ( TV.p[0] & 1 ) == 0 )
1576 {
1577 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1578
1579 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1580 {
1581 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1582 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1583 }
1584
1585 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1586 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1587 }
1588
1589 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1590 {
1591 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1592 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1593 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1594 }
1595 else
1596 {
1597 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1598 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1599 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1600 }
1601 }
1602 while( mpi_cmp_int( &TU, 0 ) != 0 );
1603
1604 while( mpi_cmp_int( &V1, 0 ) < 0 )
1605 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1606
1607 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1608 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1609
1610 MPI_CHK( mpi_copy( X, &V1 ) );
1611
1612cleanup:
1613
1614 mpi_free( &V2, &V1, &TV, &TB, &G,
1615 &U2, &U1, &TU, &TA, NULL );
1616
1617 return( ret );
1618}
1619
1620static const int small_prime[] =
1621{
1622 3, 5, 7, 11, 13, 17, 19, 23,
1623 29, 31, 37, 41, 43, 47, 53, 59,
1624 61, 67, 71, 73, 79, 83, 89, 97,
1625 101, 103, 107, 109, 113, 127, 131, 137,
1626 139, 149, 151, 157, 163, 167, 173, 179,
1627 181, 191, 193, 197, 199, 211, 223, 227,
1628 229, 233, 239, 241, 251, 257, 263, 269,
1629 271, 277, 281, 283, 293, 307, 311, 313,
1630 317, 331, 337, 347, 349, 353, 359, 367,
1631 373, 379, 383, 389, 397, 401, 409, 419,
1632 421, 431, 433, 439, 443, 449, 457, 461,
1633 463, 467, 479, 487, 491, 499, 503, 509,
1634 521, 523, 541, 547, 557, 563, 569, 571,
1635 577, 587, 593, 599, 601, 607, 613, 617,
1636 619, 631, 641, 643, 647, 653, 659, 661,
1637 673, 677, 683, 691, 701, 709, 719, 727,
1638 733, 739, 743, 751, 757, 761, 769, 773,
1639 787, 797, 809, 811, 821, 823, 827, 829,
1640 839, 853, 857, 859, 863, 877, 881, 883,
1641 887, 907, 911, 919, 929, 937, 941, 947,
1642 953, 967, 971, 977, 983, 991, 997, -103
1643};
1644
1645/*
1646 * Miller-Rabin primality test (HAC 4.24)
1647 */
1648int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng )
1649{
1650 int ret, i, j, n, s, xs;
1651 mpi W, R, T, A, RR;
1652 unsigned char *p;
1653
1654 if( mpi_cmp_int( X, 0 ) == 0 )
1655 return( 0 );
1656
1657 mpi_init( &W, &R, &T, &A, &RR, NULL );
1658
1659 xs = X->s; X->s = 1;
1660
1661 /*
1662 * test trivial factors first
1663 */
1664 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001665 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001666
1667 for( i = 0; small_prime[i] > 0; i++ )
1668 {
1669 t_int r;
1670
1671 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
1672 return( 0 );
1673
1674 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1675
1676 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001677 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001678 }
1679
1680 /*
1681 * W = |X| - 1
1682 * R = W >> lsb( W )
1683 */
1684 s = mpi_lsb( &W );
1685 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
1686 MPI_CHK( mpi_copy( &R, &W ) );
1687 MPI_CHK( mpi_shift_r( &R, s ) );
1688
1689 i = mpi_msb( X );
1690 /*
1691 * HAC, table 4.4
1692 */
1693 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1694 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1695 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1696
1697 for( i = 0; i < n; i++ )
1698 {
1699 /*
1700 * pick a random A, 1 < A < |X| - 1
1701 */
1702 MPI_CHK( mpi_grow( &A, X->n ) );
1703
1704 p = (unsigned char *) A.p;
1705 for( j = 0; j < A.n * ciL; j++ )
1706 *p++ = (unsigned char) f_rng( p_rng );
1707
1708 j = mpi_msb( &A ) - mpi_msb( &W );
1709 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
1710 A.p[0] |= 3;
1711
1712 /*
1713 * A = A^R mod |X|
1714 */
1715 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
1716
1717 if( mpi_cmp_mpi( &A, &W ) == 0 ||
1718 mpi_cmp_int( &A, 1 ) == 0 )
1719 continue;
1720
1721 j = 1;
1722 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
1723 {
1724 /*
1725 * A = A * A mod |X|
1726 */
1727 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
1728 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
1729
1730 if( mpi_cmp_int( &A, 1 ) == 0 )
1731 break;
1732
1733 j++;
1734 }
1735
1736 /*
1737 * not prime if A != |X| - 1 or A == 1
1738 */
1739 if( mpi_cmp_mpi( &A, &W ) != 0 ||
1740 mpi_cmp_int( &A, 1 ) == 0 )
1741 {
Paul Bakker40e46942009-01-03 21:51:57 +00001742 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001743 break;
1744 }
1745 }
1746
1747cleanup:
1748
1749 X->s = xs;
1750
1751 mpi_free( &RR, &A, &T, &R, &W, NULL );
1752
1753 return( ret );
1754}
1755
1756/*
1757 * Prime number generation
1758 */
1759int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
1760 int (*f_rng)(void *), void *p_rng )
1761{
1762 int ret, k, n;
1763 unsigned char *p;
1764 mpi Y;
1765
1766 if( nbits < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +00001767 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001768
1769 mpi_init( &Y, NULL );
1770
1771 n = BITS_TO_LIMBS( nbits );
1772
1773 MPI_CHK( mpi_grow( X, n ) );
1774 MPI_CHK( mpi_lset( X, 0 ) );
1775
1776 p = (unsigned char *) X->p;
1777 for( k = 0; k < X->n * ciL; k++ )
1778 *p++ = (unsigned char) f_rng( p_rng );
1779
1780 k = mpi_msb( X );
1781 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
1782 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
1783
1784 X->p[0] |= 3;
1785
1786 if( dh_flag == 0 )
1787 {
1788 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
1789 {
Paul Bakker40e46942009-01-03 21:51:57 +00001790 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001791 goto cleanup;
1792
1793 MPI_CHK( mpi_add_int( X, X, 2 ) );
1794 }
1795 }
1796 else
1797 {
1798 MPI_CHK( mpi_sub_int( &Y, X, 1 ) );
1799 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1800
1801 while( 1 )
1802 {
1803 if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 )
1804 {
1805 if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 )
1806 break;
1807
Paul Bakker40e46942009-01-03 21:51:57 +00001808 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001809 goto cleanup;
1810 }
1811
Paul Bakker40e46942009-01-03 21:51:57 +00001812 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001813 goto cleanup;
1814
1815 MPI_CHK( mpi_add_int( &Y, X, 1 ) );
1816 MPI_CHK( mpi_add_int( X, X, 2 ) );
1817 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1818 }
1819 }
1820
1821cleanup:
1822
1823 mpi_free( &Y, NULL );
1824
1825 return( ret );
1826}
1827
1828#endif
1829
Paul Bakker40e46942009-01-03 21:51:57 +00001830#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001831
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001832#define GCD_PAIR_COUNT 3
1833
1834static const int gcd_pairs[GCD_PAIR_COUNT][3] =
1835{
1836 { 693, 609, 21 },
1837 { 1764, 868, 28 },
1838 { 768454923, 542167814, 1 }
1839};
1840
Paul Bakker5121ce52009-01-03 21:22:43 +00001841/*
1842 * Checkup routine
1843 */
1844int mpi_self_test( int verbose )
1845{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001846 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001847 mpi A, E, N, X, Y, U, V;
1848
1849 mpi_init( &A, &E, &N, &X, &Y, &U, &V, NULL );
1850
1851 MPI_CHK( mpi_read_string( &A, 16,
1852 "EFE021C2645FD1DC586E69184AF4A31E" \
1853 "D5F53E93B5F123FA41680867BA110131" \
1854 "944FE7952E2517337780CB0DB80E61AA" \
1855 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
1856
1857 MPI_CHK( mpi_read_string( &E, 16,
1858 "B2E7EFD37075B9F03FF989C7C5051C20" \
1859 "34D2A323810251127E7BF8625A4F49A5" \
1860 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
1861 "5B5C25763222FEFCCFC38B832366C29E" ) );
1862
1863 MPI_CHK( mpi_read_string( &N, 16,
1864 "0066A198186C18C10B2F5ED9B522752A" \
1865 "9830B69916E535C8F047518A889A43A5" \
1866 "94B6BED27A168D31D4A52F88925AA8F5" ) );
1867
1868 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
1869
1870 MPI_CHK( mpi_read_string( &U, 16,
1871 "602AB7ECA597A3D6B56FF9829A5E8B85" \
1872 "9E857EA95A03512E2BAE7391688D264A" \
1873 "A5663B0341DB9CCFD2C4C5F421FEC814" \
1874 "8001B72E848A38CAE1C65F78E56ABDEF" \
1875 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
1876 "ECF677152EF804370C1A305CAF3B5BF1" \
1877 "30879B56C61DE584A0F53A2447A51E" ) );
1878
1879 if( verbose != 0 )
1880 printf( " MPI test #1 (mul_mpi): " );
1881
1882 if( mpi_cmp_mpi( &X, &U ) != 0 )
1883 {
1884 if( verbose != 0 )
1885 printf( "failed\n" );
1886
1887 return( 1 );
1888 }
1889
1890 if( verbose != 0 )
1891 printf( "passed\n" );
1892
1893 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
1894
1895 MPI_CHK( mpi_read_string( &U, 16,
1896 "256567336059E52CAE22925474705F39A94" ) );
1897
1898 MPI_CHK( mpi_read_string( &V, 16,
1899 "6613F26162223DF488E9CD48CC132C7A" \
1900 "0AC93C701B001B092E4E5B9F73BCD27B" \
1901 "9EE50D0657C77F374E903CDFA4C642" ) );
1902
1903 if( verbose != 0 )
1904 printf( " MPI test #2 (div_mpi): " );
1905
1906 if( mpi_cmp_mpi( &X, &U ) != 0 ||
1907 mpi_cmp_mpi( &Y, &V ) != 0 )
1908 {
1909 if( verbose != 0 )
1910 printf( "failed\n" );
1911
1912 return( 1 );
1913 }
1914
1915 if( verbose != 0 )
1916 printf( "passed\n" );
1917
1918 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
1919
1920 MPI_CHK( mpi_read_string( &U, 16,
1921 "36E139AEA55215609D2816998ED020BB" \
1922 "BD96C37890F65171D948E9BC7CBAA4D9" \
1923 "325D24D6A3C12710F10A09FA08AB87" ) );
1924
1925 if( verbose != 0 )
1926 printf( " MPI test #3 (exp_mod): " );
1927
1928 if( mpi_cmp_mpi( &X, &U ) != 0 )
1929 {
1930 if( verbose != 0 )
1931 printf( "failed\n" );
1932
1933 return( 1 );
1934 }
1935
1936 if( verbose != 0 )
1937 printf( "passed\n" );
1938
1939 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
1940
1941 MPI_CHK( mpi_read_string( &U, 16,
1942 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
1943 "C3DBA76456363A10869622EAC2DD84EC" \
1944 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
1945
1946 if( verbose != 0 )
1947 printf( " MPI test #4 (inv_mod): " );
1948
1949 if( mpi_cmp_mpi( &X, &U ) != 0 )
1950 {
1951 if( verbose != 0 )
1952 printf( "failed\n" );
1953
1954 return( 1 );
1955 }
1956
1957 if( verbose != 0 )
1958 printf( "passed\n" );
1959
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001960 if( verbose != 0 )
1961 printf( " MPI test #5 (simple gcd): " );
1962
1963 for ( i = 0; i < GCD_PAIR_COUNT; i++)
1964 {
1965 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
1966 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
1967
1968 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
1969
1970 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
1971 {
1972 if( verbose != 0 )
1973 printf( "failed at %d\n", i );
1974
1975 return( 1 );
1976 }
1977 }
1978
1979 if( verbose != 0 )
1980 printf( "passed\n" );
1981
Paul Bakker5121ce52009-01-03 21:22:43 +00001982cleanup:
1983
1984 if( ret != 0 && verbose != 0 )
1985 printf( "Unexpected error, return code = %08X\n", ret );
1986
1987 mpi_free( &V, &U, &Y, &X, &N, &E, &A, NULL );
1988
1989 if( verbose != 0 )
1990 printf( "\n" );
1991
1992 return( ret );
1993}
1994
1995#endif
1996
1997#endif