blob: 5c1de684cc3c2bd92e339056828c6f1fad4847c2 [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 ) );
Paul Bakker05feca62009-06-20 08:22:43 +0000289
290 if( X->s == 1 )
291 {
292 MPI_CHK( mpi_add_int( X, &T, d ) );
293 }
294 else
295 {
296 MPI_CHK( mpi_sub_int( X, &T, d ) );
297 }
Paul Bakker5121ce52009-01-03 21:22:43 +0000298 }
299 }
300
301cleanup:
302
303 mpi_free( &T, NULL );
304
305 return( ret );
306}
307
308/*
309 * Helper to write the digits high-order first
310 */
311static int mpi_write_hlp( mpi *X, int radix, char **p )
312{
313 int ret;
314 t_int r;
315
316 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000317 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000318
319 MPI_CHK( mpi_mod_int( &r, X, radix ) );
320 MPI_CHK( mpi_div_int( X, NULL, X, radix ) );
321
322 if( mpi_cmp_int( X, 0 ) != 0 )
323 MPI_CHK( mpi_write_hlp( X, radix, p ) );
324
325 if( r < 10 )
326 *(*p)++ = (char)( r + 0x30 );
327 else
328 *(*p)++ = (char)( r + 0x37 );
329
330cleanup:
331
332 return( ret );
333}
334
335/*
336 * Export into an ASCII string
337 */
338int mpi_write_string( mpi *X, int radix, char *s, int *slen )
339{
340 int ret = 0, n;
341 char *p;
342 mpi T;
343
344 if( radix < 2 || radix > 16 )
Paul Bakker40e46942009-01-03 21:51:57 +0000345 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +0000346
347 n = mpi_msb( X );
348 if( radix >= 4 ) n >>= 1;
349 if( radix >= 16 ) n >>= 1;
350 n += 3;
351
352 if( *slen < n )
353 {
354 *slen = n;
Paul Bakker40e46942009-01-03 21:51:57 +0000355 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000356 }
357
358 p = s;
359 mpi_init( &T, NULL );
360
361 if( X->s == -1 )
362 *p++ = '-';
363
364 if( radix == 16 )
365 {
366 int c, i, j, k;
367
368 for( i = X->n - 1, k = 0; i >= 0; i-- )
369 {
370 for( j = ciL - 1; j >= 0; j-- )
371 {
372 c = ( X->p[i] >> (j << 3) ) & 0xFF;
373
374 if( c == 0 && k == 0 && (i + j) != 0 )
375 continue;
376
377 p += sprintf( p, "%02X", c );
378 k = 1;
379 }
380 }
381 }
382 else
383 {
384 MPI_CHK( mpi_copy( &T, X ) );
385 MPI_CHK( mpi_write_hlp( &T, radix, &p ) );
386 }
387
388 *p++ = '\0';
389 *slen = p - s;
390
391cleanup:
392
393 mpi_free( &T, NULL );
394
395 return( ret );
396}
397
398/*
399 * Read X from an opened file
400 */
401int mpi_read_file( mpi *X, int radix, FILE *fin )
402{
403 t_int d;
404 int slen;
405 char *p;
406 char s[1024];
407
408 memset( s, 0, sizeof( s ) );
409 if( fgets( s, sizeof( s ) - 1, fin ) == NULL )
Paul Bakker40e46942009-01-03 21:51:57 +0000410 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000411
412 slen = strlen( s );
413 if( s[slen - 1] == '\n' ) { slen--; s[slen] = '\0'; }
414 if( s[slen - 1] == '\r' ) { slen--; s[slen] = '\0'; }
415
416 p = s + slen;
417 while( --p >= s )
418 if( mpi_get_digit( &d, radix, *p ) != 0 )
419 break;
420
421 return( mpi_read_string( X, radix, p + 1 ) );
422}
423
424/*
425 * Write X into an opened file (or stdout if fout == NULL)
426 */
427int mpi_write_file( char *p, mpi *X, int radix, FILE *fout )
428{
429 int n, ret;
430 size_t slen;
431 size_t plen;
432 char s[1024];
433
434 n = sizeof( s );
435 memset( s, 0, n );
436 n -= 2;
437
438 MPI_CHK( mpi_write_string( X, radix, s, (int *) &n ) );
439
440 if( p == NULL ) p = "";
441
442 plen = strlen( p );
443 slen = strlen( s );
444 s[slen++] = '\r';
445 s[slen++] = '\n';
446
447 if( fout != NULL )
448 {
449 if( fwrite( p, 1, plen, fout ) != plen ||
450 fwrite( s, 1, slen, fout ) != slen )
Paul Bakker40e46942009-01-03 21:51:57 +0000451 return( POLARSSL_ERR_MPI_FILE_IO_ERROR );
Paul Bakker5121ce52009-01-03 21:22:43 +0000452 }
453 else
454 printf( "%s%s", p, s );
455
456cleanup:
457
458 return( ret );
459}
460
461/*
462 * Import X from unsigned binary data, big endian
463 */
464int mpi_read_binary( mpi *X, unsigned char *buf, int buflen )
465{
466 int ret, i, j, n;
467
468 for( n = 0; n < buflen; n++ )
469 if( buf[n] != 0 )
470 break;
471
472 MPI_CHK( mpi_grow( X, CHARS_TO_LIMBS( buflen - n ) ) );
473 MPI_CHK( mpi_lset( X, 0 ) );
474
475 for( i = buflen - 1, j = 0; i >= n; i--, j++ )
476 X->p[j / ciL] |= ((t_int) buf[i]) << ((j % ciL) << 3);
477
478cleanup:
479
480 return( ret );
481}
482
483/*
484 * Export X into unsigned binary data, big endian
485 */
486int mpi_write_binary( mpi *X, unsigned char *buf, int buflen )
487{
488 int i, j, n;
489
490 n = mpi_size( X );
491
492 if( buflen < n )
Paul Bakker40e46942009-01-03 21:51:57 +0000493 return( POLARSSL_ERR_MPI_BUFFER_TOO_SMALL );
Paul Bakker5121ce52009-01-03 21:22:43 +0000494
495 memset( buf, 0, buflen );
496
497 for( i = buflen - 1, j = 0; n > 0; i--, j++, n-- )
498 buf[i] = (unsigned char)( X->p[j / ciL] >> ((j % ciL) << 3) );
499
500 return( 0 );
501}
502
503/*
504 * Left-shift: X <<= count
505 */
506int mpi_shift_l( mpi *X, int count )
507{
508 int ret, i, v0, t1;
509 t_int r0 = 0, r1;
510
511 v0 = count / (biL );
512 t1 = count & (biL - 1);
513
514 i = mpi_msb( X ) + count;
515
516 if( X->n * (int) biL < i )
517 MPI_CHK( mpi_grow( X, BITS_TO_LIMBS( i ) ) );
518
519 ret = 0;
520
521 /*
522 * shift by count / limb_size
523 */
524 if( v0 > 0 )
525 {
526 for( i = X->n - 1; i >= v0; i-- )
527 X->p[i] = X->p[i - v0];
528
529 for( ; i >= 0; i-- )
530 X->p[i] = 0;
531 }
532
533 /*
534 * shift by count % limb_size
535 */
536 if( t1 > 0 )
537 {
538 for( i = v0; i < X->n; i++ )
539 {
540 r1 = X->p[i] >> (biL - t1);
541 X->p[i] <<= t1;
542 X->p[i] |= r0;
543 r0 = r1;
544 }
545 }
546
547cleanup:
548
549 return( ret );
550}
551
552/*
553 * Right-shift: X >>= count
554 */
555int mpi_shift_r( mpi *X, int count )
556{
557 int i, v0, v1;
558 t_int r0 = 0, r1;
559
560 v0 = count / biL;
561 v1 = count & (biL - 1);
562
563 /*
564 * shift by count / limb_size
565 */
566 if( v0 > 0 )
567 {
568 for( i = 0; i < X->n - v0; i++ )
569 X->p[i] = X->p[i + v0];
570
571 for( ; i < X->n; i++ )
572 X->p[i] = 0;
573 }
574
575 /*
576 * shift by count % limb_size
577 */
578 if( v1 > 0 )
579 {
580 for( i = X->n - 1; i >= 0; i-- )
581 {
582 r1 = X->p[i] << (biL - v1);
583 X->p[i] >>= v1;
584 X->p[i] |= r0;
585 r0 = r1;
586 }
587 }
588
589 return( 0 );
590}
591
592/*
593 * Compare unsigned values
594 */
595int mpi_cmp_abs( mpi *X, mpi *Y )
596{
597 int i, j;
598
599 for( i = X->n - 1; i >= 0; i-- )
600 if( X->p[i] != 0 )
601 break;
602
603 for( j = Y->n - 1; j >= 0; j-- )
604 if( Y->p[j] != 0 )
605 break;
606
607 if( i < 0 && j < 0 )
608 return( 0 );
609
610 if( i > j ) return( 1 );
611 if( j > i ) return( -1 );
612
613 for( ; i >= 0; i-- )
614 {
615 if( X->p[i] > Y->p[i] ) return( 1 );
616 if( X->p[i] < Y->p[i] ) return( -1 );
617 }
618
619 return( 0 );
620}
621
622/*
623 * Compare signed values
624 */
625int mpi_cmp_mpi( mpi *X, mpi *Y )
626{
627 int i, j;
628
629 for( i = X->n - 1; i >= 0; i-- )
630 if( X->p[i] != 0 )
631 break;
632
633 for( j = Y->n - 1; j >= 0; j-- )
634 if( Y->p[j] != 0 )
635 break;
636
637 if( i < 0 && j < 0 )
638 return( 0 );
639
640 if( i > j ) return( X->s );
641 if( j > i ) return( -X->s );
642
643 if( X->s > 0 && Y->s < 0 ) return( 1 );
644 if( Y->s > 0 && X->s < 0 ) return( -1 );
645
646 for( ; i >= 0; i-- )
647 {
648 if( X->p[i] > Y->p[i] ) return( X->s );
649 if( X->p[i] < Y->p[i] ) return( -X->s );
650 }
651
652 return( 0 );
653}
654
655/*
656 * Compare signed values
657 */
658int mpi_cmp_int( mpi *X, int z )
659{
660 mpi Y;
661 t_int p[1];
662
663 *p = ( z < 0 ) ? -z : z;
664 Y.s = ( z < 0 ) ? -1 : 1;
665 Y.n = 1;
666 Y.p = p;
667
668 return( mpi_cmp_mpi( X, &Y ) );
669}
670
671/*
672 * Unsigned addition: X = |A| + |B| (HAC 14.7)
673 */
674int mpi_add_abs( mpi *X, mpi *A, mpi *B )
675{
676 int ret, i, j;
677 t_int *o, *p, c;
678
679 if( X == B )
680 {
681 mpi *T = A; A = X; B = T;
682 }
683
684 if( X != A )
685 MPI_CHK( mpi_copy( X, A ) );
686
687 for( j = B->n - 1; j >= 0; j-- )
688 if( B->p[j] != 0 )
689 break;
690
691 MPI_CHK( mpi_grow( X, j + 1 ) );
692
693 o = B->p; p = X->p; c = 0;
694
695 for( i = 0; i <= j; i++, o++, p++ )
696 {
697 *p += c; c = ( *p < c );
698 *p += *o; c += ( *p < *o );
699 }
700
701 while( c != 0 )
702 {
703 if( i >= X->n )
704 {
705 MPI_CHK( mpi_grow( X, i + 1 ) );
706 p = X->p + i;
707 }
708
709 *p += c; c = ( *p < c ); i++;
710 }
711
712cleanup:
713
714 return( ret );
715}
716
717/*
718 * Helper for mpi substraction
719 */
720static void mpi_sub_hlp( int n, t_int *s, t_int *d )
721{
722 int i;
723 t_int c, z;
724
725 for( i = c = 0; i < n; i++, s++, d++ )
726 {
727 z = ( *d < c ); *d -= c;
728 c = ( *d < *s ) + z; *d -= *s;
729 }
730
731 while( c != 0 )
732 {
733 z = ( *d < c ); *d -= c;
734 c = z; i++; d++;
735 }
736}
737
738/*
739 * Unsigned substraction: X = |A| - |B| (HAC 14.9)
740 */
741int mpi_sub_abs( mpi *X, mpi *A, mpi *B )
742{
743 mpi TB;
744 int ret, n;
745
746 if( mpi_cmp_abs( A, B ) < 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000747 return( POLARSSL_ERR_MPI_NEGATIVE_VALUE );
Paul Bakker5121ce52009-01-03 21:22:43 +0000748
749 mpi_init( &TB, NULL );
750
751 if( X == B )
752 {
753 MPI_CHK( mpi_copy( &TB, B ) );
754 B = &TB;
755 }
756
757 if( X != A )
758 MPI_CHK( mpi_copy( X, A ) );
759
760 ret = 0;
761
762 for( n = B->n - 1; n >= 0; n-- )
763 if( B->p[n] != 0 )
764 break;
765
766 mpi_sub_hlp( n + 1, B->p, X->p );
767
768cleanup:
769
770 mpi_free( &TB, NULL );
771
772 return( ret );
773}
774
775/*
776 * Signed addition: X = A + B
777 */
778int mpi_add_mpi( mpi *X, mpi *A, mpi *B )
779{
780 int ret, s = A->s;
781
782 if( A->s * B->s < 0 )
783 {
784 if( mpi_cmp_abs( A, B ) >= 0 )
785 {
786 MPI_CHK( mpi_sub_abs( X, A, B ) );
787 X->s = s;
788 }
789 else
790 {
791 MPI_CHK( mpi_sub_abs( X, B, A ) );
792 X->s = -s;
793 }
794 }
795 else
796 {
797 MPI_CHK( mpi_add_abs( X, A, B ) );
798 X->s = s;
799 }
800
801cleanup:
802
803 return( ret );
804}
805
806/*
807 * Signed substraction: X = A - B
808 */
809int mpi_sub_mpi( mpi *X, mpi *A, mpi *B )
810{
811 int ret, s = A->s;
812
813 if( A->s * B->s > 0 )
814 {
815 if( mpi_cmp_abs( A, B ) >= 0 )
816 {
817 MPI_CHK( mpi_sub_abs( X, A, B ) );
818 X->s = s;
819 }
820 else
821 {
822 MPI_CHK( mpi_sub_abs( X, B, A ) );
823 X->s = -s;
824 }
825 }
826 else
827 {
828 MPI_CHK( mpi_add_abs( X, A, B ) );
829 X->s = s;
830 }
831
832cleanup:
833
834 return( ret );
835}
836
837/*
838 * Signed addition: X = A + b
839 */
840int mpi_add_int( mpi *X, mpi *A, int b )
841{
842 mpi _B;
843 t_int p[1];
844
845 p[0] = ( b < 0 ) ? -b : b;
846 _B.s = ( b < 0 ) ? -1 : 1;
847 _B.n = 1;
848 _B.p = p;
849
850 return( mpi_add_mpi( X, A, &_B ) );
851}
852
853/*
854 * Signed substraction: X = A - b
855 */
856int mpi_sub_int( mpi *X, mpi *A, int b )
857{
858 mpi _B;
859 t_int p[1];
860
861 p[0] = ( b < 0 ) ? -b : b;
862 _B.s = ( b < 0 ) ? -1 : 1;
863 _B.n = 1;
864 _B.p = p;
865
866 return( mpi_sub_mpi( X, A, &_B ) );
867}
868
869/*
870 * Helper for mpi multiplication
871 */
872static void mpi_mul_hlp( int i, t_int *s, t_int *d, t_int b )
873{
874 t_int c = 0, t = 0;
875
876#if defined(MULADDC_HUIT)
877 for( ; i >= 8; i -= 8 )
878 {
879 MULADDC_INIT
880 MULADDC_HUIT
881 MULADDC_STOP
882 }
883
884 for( ; i > 0; i-- )
885 {
886 MULADDC_INIT
887 MULADDC_CORE
888 MULADDC_STOP
889 }
890#else
891 for( ; i >= 16; i -= 16 )
892 {
893 MULADDC_INIT
894 MULADDC_CORE MULADDC_CORE
895 MULADDC_CORE MULADDC_CORE
896 MULADDC_CORE MULADDC_CORE
897 MULADDC_CORE MULADDC_CORE
898
899 MULADDC_CORE MULADDC_CORE
900 MULADDC_CORE MULADDC_CORE
901 MULADDC_CORE MULADDC_CORE
902 MULADDC_CORE MULADDC_CORE
903 MULADDC_STOP
904 }
905
906 for( ; i >= 8; i -= 8 )
907 {
908 MULADDC_INIT
909 MULADDC_CORE MULADDC_CORE
910 MULADDC_CORE MULADDC_CORE
911
912 MULADDC_CORE MULADDC_CORE
913 MULADDC_CORE MULADDC_CORE
914 MULADDC_STOP
915 }
916
917 for( ; i > 0; i-- )
918 {
919 MULADDC_INIT
920 MULADDC_CORE
921 MULADDC_STOP
922 }
923#endif
924
925 t++;
926
927 do {
928 *d += c; c = ( *d < c ); d++;
929 }
930 while( c != 0 );
931}
932
933/*
934 * Baseline multiplication: X = A * B (HAC 14.12)
935 */
936int mpi_mul_mpi( mpi *X, mpi *A, mpi *B )
937{
938 int ret, i, j;
939 mpi TA, TB;
940
941 mpi_init( &TA, &TB, NULL );
942
943 if( X == A ) { MPI_CHK( mpi_copy( &TA, A ) ); A = &TA; }
944 if( X == B ) { MPI_CHK( mpi_copy( &TB, B ) ); B = &TB; }
945
946 for( i = A->n - 1; i >= 0; i-- )
947 if( A->p[i] != 0 )
948 break;
949
950 for( j = B->n - 1; j >= 0; j-- )
951 if( B->p[j] != 0 )
952 break;
953
954 MPI_CHK( mpi_grow( X, i + j + 2 ) );
955 MPI_CHK( mpi_lset( X, 0 ) );
956
957 for( i++; j >= 0; j-- )
958 mpi_mul_hlp( i, A->p, X->p + j, B->p[j] );
959
960 X->s = A->s * B->s;
961
962cleanup:
963
964 mpi_free( &TB, &TA, NULL );
965
966 return( ret );
967}
968
969/*
970 * Baseline multiplication: X = A * b
971 */
972int mpi_mul_int( mpi *X, mpi *A, t_int b )
973{
974 mpi _B;
975 t_int p[1];
976
977 _B.s = 1;
978 _B.n = 1;
979 _B.p = p;
980 p[0] = b;
981
982 return( mpi_mul_mpi( X, A, &_B ) );
983}
984
985/*
986 * Division by mpi: A = Q * B + R (HAC 14.20)
987 */
988int mpi_div_mpi( mpi *Q, mpi *R, mpi *A, mpi *B )
989{
990 int ret, i, n, t, k;
991 mpi X, Y, Z, T1, T2;
992
993 if( mpi_cmp_int( B, 0 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +0000994 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +0000995
996 mpi_init( &X, &Y, &Z, &T1, &T2, NULL );
997
998 if( mpi_cmp_abs( A, B ) < 0 )
999 {
1000 if( Q != NULL ) MPI_CHK( mpi_lset( Q, 0 ) );
1001 if( R != NULL ) MPI_CHK( mpi_copy( R, A ) );
1002 return( 0 );
1003 }
1004
1005 MPI_CHK( mpi_copy( &X, A ) );
1006 MPI_CHK( mpi_copy( &Y, B ) );
1007 X.s = Y.s = 1;
1008
1009 MPI_CHK( mpi_grow( &Z, A->n + 2 ) );
1010 MPI_CHK( mpi_lset( &Z, 0 ) );
1011 MPI_CHK( mpi_grow( &T1, 2 ) );
1012 MPI_CHK( mpi_grow( &T2, 3 ) );
1013
1014 k = mpi_msb( &Y ) % biL;
1015 if( k < (int) biL - 1 )
1016 {
1017 k = biL - 1 - k;
1018 MPI_CHK( mpi_shift_l( &X, k ) );
1019 MPI_CHK( mpi_shift_l( &Y, k ) );
1020 }
1021 else k = 0;
1022
1023 n = X.n - 1;
1024 t = Y.n - 1;
1025 mpi_shift_l( &Y, biL * (n - t) );
1026
1027 while( mpi_cmp_mpi( &X, &Y ) >= 0 )
1028 {
1029 Z.p[n - t]++;
1030 mpi_sub_mpi( &X, &X, &Y );
1031 }
1032 mpi_shift_r( &Y, biL * (n - t) );
1033
1034 for( i = n; i > t ; i-- )
1035 {
1036 if( X.p[i] >= Y.p[t] )
1037 Z.p[i - t - 1] = ~0;
1038 else
1039 {
Paul Bakker40e46942009-01-03 21:51:57 +00001040#if defined(POLARSSL_HAVE_LONGLONG)
Paul Bakker5121ce52009-01-03 21:22:43 +00001041 t_dbl r;
1042
1043 r = (t_dbl) X.p[i] << biL;
1044 r |= (t_dbl) X.p[i - 1];
1045 r /= Y.p[t];
1046 if( r > ((t_dbl) 1 << biL) - 1)
1047 r = ((t_dbl) 1 << biL) - 1;
1048
1049 Z.p[i - t - 1] = (t_int) r;
1050#else
1051 /*
1052 * __udiv_qrnnd_c, from gmp/longlong.h
1053 */
1054 t_int q0, q1, r0, r1;
1055 t_int d0, d1, d, m;
1056
1057 d = Y.p[t];
1058 d0 = ( d << biH ) >> biH;
1059 d1 = ( d >> biH );
1060
1061 q1 = X.p[i] / d1;
1062 r1 = X.p[i] - d1 * q1;
1063 r1 <<= biH;
1064 r1 |= ( X.p[i - 1] >> biH );
1065
1066 m = q1 * d0;
1067 if( r1 < m )
1068 {
1069 q1--, r1 += d;
1070 while( r1 >= d && r1 < m )
1071 q1--, r1 += d;
1072 }
1073 r1 -= m;
1074
1075 q0 = r1 / d1;
1076 r0 = r1 - d1 * q0;
1077 r0 <<= biH;
1078 r0 |= ( X.p[i - 1] << biH ) >> biH;
1079
1080 m = q0 * d0;
1081 if( r0 < m )
1082 {
1083 q0--, r0 += d;
1084 while( r0 >= d && r0 < m )
1085 q0--, r0 += d;
1086 }
1087 r0 -= m;
1088
1089 Z.p[i - t - 1] = ( q1 << biH ) | q0;
1090#endif
1091 }
1092
1093 Z.p[i - t - 1]++;
1094 do
1095 {
1096 Z.p[i - t - 1]--;
1097
1098 MPI_CHK( mpi_lset( &T1, 0 ) );
1099 T1.p[0] = (t < 1) ? 0 : Y.p[t - 1];
1100 T1.p[1] = Y.p[t];
1101 MPI_CHK( mpi_mul_int( &T1, &T1, Z.p[i - t - 1] ) );
1102
1103 MPI_CHK( mpi_lset( &T2, 0 ) );
1104 T2.p[0] = (i < 2) ? 0 : X.p[i - 2];
1105 T2.p[1] = (i < 1) ? 0 : X.p[i - 1];
1106 T2.p[2] = X.p[i];
1107 }
1108 while( mpi_cmp_mpi( &T1, &T2 ) > 0 );
1109
1110 MPI_CHK( mpi_mul_int( &T1, &Y, Z.p[i - t - 1] ) );
1111 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1112 MPI_CHK( mpi_sub_mpi( &X, &X, &T1 ) );
1113
1114 if( mpi_cmp_int( &X, 0 ) < 0 )
1115 {
1116 MPI_CHK( mpi_copy( &T1, &Y ) );
1117 MPI_CHK( mpi_shift_l( &T1, biL * (i - t - 1) ) );
1118 MPI_CHK( mpi_add_mpi( &X, &X, &T1 ) );
1119 Z.p[i - t - 1]--;
1120 }
1121 }
1122
1123 if( Q != NULL )
1124 {
1125 mpi_copy( Q, &Z );
1126 Q->s = A->s * B->s;
1127 }
1128
1129 if( R != NULL )
1130 {
1131 mpi_shift_r( &X, k );
1132 mpi_copy( R, &X );
1133
1134 R->s = A->s;
1135 if( mpi_cmp_int( R, 0 ) == 0 )
1136 R->s = 1;
1137 }
1138
1139cleanup:
1140
1141 mpi_free( &X, &Y, &Z, &T1, &T2, NULL );
1142
1143 return( ret );
1144}
1145
1146/*
1147 * Division by int: A = Q * b + R
1148 *
1149 * Returns 0 if successful
1150 * 1 if memory allocation failed
Paul Bakker40e46942009-01-03 21:51:57 +00001151 * POLARSSL_ERR_MPI_DIVISION_BY_ZERO if b == 0
Paul Bakker5121ce52009-01-03 21:22:43 +00001152 */
1153int mpi_div_int( mpi *Q, mpi *R, mpi *A, int b )
1154{
1155 mpi _B;
1156 t_int p[1];
1157
1158 p[0] = ( b < 0 ) ? -b : b;
1159 _B.s = ( b < 0 ) ? -1 : 1;
1160 _B.n = 1;
1161 _B.p = p;
1162
1163 return( mpi_div_mpi( Q, R, A, &_B ) );
1164}
1165
1166/*
1167 * Modulo: R = A mod B
1168 */
1169int mpi_mod_mpi( mpi *R, mpi *A, mpi *B )
1170{
1171 int ret;
1172
1173 MPI_CHK( mpi_div_mpi( NULL, R, A, B ) );
1174
1175 while( mpi_cmp_int( R, 0 ) < 0 )
1176 MPI_CHK( mpi_add_mpi( R, R, B ) );
1177
1178 while( mpi_cmp_mpi( R, B ) >= 0 )
1179 MPI_CHK( mpi_sub_mpi( R, R, B ) );
1180
1181cleanup:
1182
1183 return( ret );
1184}
1185
1186/*
1187 * Modulo: r = A mod b
1188 */
1189int mpi_mod_int( t_int *r, mpi *A, int b )
1190{
1191 int i;
1192 t_int x, y, z;
1193
1194 if( b == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001195 return( POLARSSL_ERR_MPI_DIVISION_BY_ZERO );
Paul Bakker5121ce52009-01-03 21:22:43 +00001196
1197 if( b < 0 )
1198 b = -b;
1199
1200 /*
1201 * handle trivial cases
1202 */
1203 if( b == 1 )
1204 {
1205 *r = 0;
1206 return( 0 );
1207 }
1208
1209 if( b == 2 )
1210 {
1211 *r = A->p[0] & 1;
1212 return( 0 );
1213 }
1214
1215 /*
1216 * general case
1217 */
1218 for( i = A->n - 1, y = 0; i >= 0; i-- )
1219 {
1220 x = A->p[i];
1221 y = ( y << biH ) | ( x >> biH );
1222 z = y / b;
1223 y -= z * b;
1224
1225 x <<= biH;
1226 y = ( y << biH ) | ( x >> biH );
1227 z = y / b;
1228 y -= z * b;
1229 }
1230
1231 *r = y;
1232
1233 return( 0 );
1234}
1235
1236/*
1237 * Fast Montgomery initialization (thanks to Tom St Denis)
1238 */
1239static void mpi_montg_init( t_int *mm, mpi *N )
1240{
1241 t_int x, m0 = N->p[0];
1242
1243 x = m0;
1244 x += ( ( m0 + 2 ) & 4 ) << 1;
1245 x *= ( 2 - ( m0 * x ) );
1246
1247 if( biL >= 16 ) x *= ( 2 - ( m0 * x ) );
1248 if( biL >= 32 ) x *= ( 2 - ( m0 * x ) );
1249 if( biL >= 64 ) x *= ( 2 - ( m0 * x ) );
1250
1251 *mm = ~x + 1;
1252}
1253
1254/*
1255 * Montgomery multiplication: A = A * B * R^-1 mod N (HAC 14.36)
1256 */
1257static void mpi_montmul( mpi *A, mpi *B, mpi *N, t_int mm, mpi *T )
1258{
1259 int i, n, m;
1260 t_int u0, u1, *d;
1261
1262 memset( T->p, 0, T->n * ciL );
1263
1264 d = T->p;
1265 n = N->n;
1266 m = ( B->n < n ) ? B->n : n;
1267
1268 for( i = 0; i < n; i++ )
1269 {
1270 /*
1271 * T = (T + u0*B + u1*N) / 2^biL
1272 */
1273 u0 = A->p[i];
1274 u1 = ( d[0] + u0 * B->p[0] ) * mm;
1275
1276 mpi_mul_hlp( m, B->p, d, u0 );
1277 mpi_mul_hlp( n, N->p, d, u1 );
1278
1279 *d++ = u0; d[n + 1] = 0;
1280 }
1281
1282 memcpy( A->p, d, (n + 1) * ciL );
1283
1284 if( mpi_cmp_abs( A, N ) >= 0 )
1285 mpi_sub_hlp( n, N->p, A->p );
1286 else
1287 /* prevent timing attacks */
1288 mpi_sub_hlp( n, A->p, T->p );
1289}
1290
1291/*
1292 * Montgomery reduction: A = A * R^-1 mod N
1293 */
1294static void mpi_montred( mpi *A, mpi *N, t_int mm, mpi *T )
1295{
1296 t_int z = 1;
1297 mpi U;
1298
1299 U.n = U.s = z;
1300 U.p = &z;
1301
1302 mpi_montmul( A, &U, N, mm, T );
1303}
1304
1305/*
1306 * Sliding-window exponentiation: X = A^E mod N (HAC 14.85)
1307 */
1308int mpi_exp_mod( mpi *X, mpi *A, mpi *E, mpi *N, mpi *_RR )
1309{
1310 int ret, i, j, wsize, wbits;
1311 int bufsize, nblimbs, nbits;
1312 t_int ei, mm, state;
1313 mpi RR, T, W[64];
1314
1315 if( mpi_cmp_int( N, 0 ) < 0 || ( N->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001316 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001317
1318 /*
1319 * Init temps and window size
1320 */
1321 mpi_montg_init( &mm, N );
1322 mpi_init( &RR, &T, NULL );
1323 memset( W, 0, sizeof( W ) );
1324
1325 i = mpi_msb( E );
1326
1327 wsize = ( i > 671 ) ? 6 : ( i > 239 ) ? 5 :
1328 ( i > 79 ) ? 4 : ( i > 23 ) ? 3 : 1;
1329
1330 j = N->n + 1;
1331 MPI_CHK( mpi_grow( X, j ) );
1332 MPI_CHK( mpi_grow( &W[1], j ) );
1333 MPI_CHK( mpi_grow( &T, j * 2 ) );
1334
1335 /*
1336 * If 1st call, pre-compute R^2 mod N
1337 */
1338 if( _RR == NULL || _RR->p == NULL )
1339 {
1340 MPI_CHK( mpi_lset( &RR, 1 ) );
1341 MPI_CHK( mpi_shift_l( &RR, N->n * 2 * biL ) );
1342 MPI_CHK( mpi_mod_mpi( &RR, &RR, N ) );
1343
1344 if( _RR != NULL )
1345 memcpy( _RR, &RR, sizeof( mpi ) );
1346 }
1347 else
1348 memcpy( &RR, _RR, sizeof( mpi ) );
1349
1350 /*
1351 * W[1] = A * R^2 * R^-1 mod N = A * R mod N
1352 */
1353 if( mpi_cmp_mpi( A, N ) >= 0 )
1354 mpi_mod_mpi( &W[1], A, N );
1355 else mpi_copy( &W[1], A );
1356
1357 mpi_montmul( &W[1], &RR, N, mm, &T );
1358
1359 /*
1360 * X = R^2 * R^-1 mod N = R mod N
1361 */
1362 MPI_CHK( mpi_copy( X, &RR ) );
1363 mpi_montred( X, N, mm, &T );
1364
1365 if( wsize > 1 )
1366 {
1367 /*
1368 * W[1 << (wsize - 1)] = W[1] ^ (wsize - 1)
1369 */
1370 j = 1 << (wsize - 1);
1371
1372 MPI_CHK( mpi_grow( &W[j], N->n + 1 ) );
1373 MPI_CHK( mpi_copy( &W[j], &W[1] ) );
1374
1375 for( i = 0; i < wsize - 1; i++ )
1376 mpi_montmul( &W[j], &W[j], N, mm, &T );
1377
1378 /*
1379 * W[i] = W[i - 1] * W[1]
1380 */
1381 for( i = j + 1; i < (1 << wsize); i++ )
1382 {
1383 MPI_CHK( mpi_grow( &W[i], N->n + 1 ) );
1384 MPI_CHK( mpi_copy( &W[i], &W[i - 1] ) );
1385
1386 mpi_montmul( &W[i], &W[1], N, mm, &T );
1387 }
1388 }
1389
1390 nblimbs = E->n;
1391 bufsize = 0;
1392 nbits = 0;
1393 wbits = 0;
1394 state = 0;
1395
1396 while( 1 )
1397 {
1398 if( bufsize == 0 )
1399 {
1400 if( nblimbs-- == 0 )
1401 break;
1402
1403 bufsize = sizeof( t_int ) << 3;
1404 }
1405
1406 bufsize--;
1407
1408 ei = (E->p[nblimbs] >> bufsize) & 1;
1409
1410 /*
1411 * skip leading 0s
1412 */
1413 if( ei == 0 && state == 0 )
1414 continue;
1415
1416 if( ei == 0 && state == 1 )
1417 {
1418 /*
1419 * out of window, square X
1420 */
1421 mpi_montmul( X, X, N, mm, &T );
1422 continue;
1423 }
1424
1425 /*
1426 * add ei to current window
1427 */
1428 state = 2;
1429
1430 nbits++;
1431 wbits |= (ei << (wsize - nbits));
1432
1433 if( nbits == wsize )
1434 {
1435 /*
1436 * X = X^wsize R^-1 mod N
1437 */
1438 for( i = 0; i < wsize; i++ )
1439 mpi_montmul( X, X, N, mm, &T );
1440
1441 /*
1442 * X = X * W[wbits] R^-1 mod N
1443 */
1444 mpi_montmul( X, &W[wbits], N, mm, &T );
1445
1446 state--;
1447 nbits = 0;
1448 wbits = 0;
1449 }
1450 }
1451
1452 /*
1453 * process the remaining bits
1454 */
1455 for( i = 0; i < nbits; i++ )
1456 {
1457 mpi_montmul( X, X, N, mm, &T );
1458
1459 wbits <<= 1;
1460
1461 if( (wbits & (1 << wsize)) != 0 )
1462 mpi_montmul( X, &W[1], N, mm, &T );
1463 }
1464
1465 /*
1466 * X = A^E * R * R^-1 mod N = A^E mod N
1467 */
1468 mpi_montred( X, N, mm, &T );
1469
1470cleanup:
1471
1472 for( i = (1 << (wsize - 1)); i < (1 << wsize); i++ )
1473 mpi_free( &W[i], NULL );
1474
1475 if( _RR != NULL )
1476 mpi_free( &W[1], &T, NULL );
1477 else mpi_free( &W[1], &T, &RR, NULL );
1478
1479 return( ret );
1480}
1481
Paul Bakker5121ce52009-01-03 21:22:43 +00001482/*
1483 * Greatest common divisor: G = gcd(A, B) (HAC 14.54)
1484 */
1485int mpi_gcd( mpi *G, mpi *A, mpi *B )
1486{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001487 int ret, lz, lzt;
Paul Bakker5121ce52009-01-03 21:22:43 +00001488 mpi TG, TA, TB;
1489
1490 mpi_init( &TG, &TA, &TB, NULL );
1491
Paul Bakker5121ce52009-01-03 21:22:43 +00001492 MPI_CHK( mpi_copy( &TA, A ) );
1493 MPI_CHK( mpi_copy( &TB, B ) );
1494
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001495 lz = mpi_lsb( &TA );
1496 lzt = mpi_lsb( &TB );
1497
1498 if ( lzt < lz )
1499 lz = lzt;
1500
1501 MPI_CHK( mpi_shift_r( &TA, lz ) );
1502 MPI_CHK( mpi_shift_r( &TB, lz ) );
1503
Paul Bakker5121ce52009-01-03 21:22:43 +00001504 TA.s = TB.s = 1;
1505
1506 while( mpi_cmp_int( &TA, 0 ) != 0 )
1507 {
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001508 MPI_CHK( mpi_shift_r( &TA, mpi_lsb( &TA ) ) );
1509 MPI_CHK( mpi_shift_r( &TB, mpi_lsb( &TB ) ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001510
1511 if( mpi_cmp_mpi( &TA, &TB ) >= 0 )
1512 {
1513 MPI_CHK( mpi_sub_abs( &TA, &TA, &TB ) );
1514 MPI_CHK( mpi_shift_r( &TA, 1 ) );
1515 }
1516 else
1517 {
1518 MPI_CHK( mpi_sub_abs( &TB, &TB, &TA ) );
1519 MPI_CHK( mpi_shift_r( &TB, 1 ) );
1520 }
1521 }
1522
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001523 MPI_CHK( mpi_shift_l( &TB, lz ) );
1524 MPI_CHK( mpi_copy( G, &TB ) );
Paul Bakker5121ce52009-01-03 21:22:43 +00001525
1526cleanup:
1527
1528 mpi_free( &TB, &TA, &TG, NULL );
1529
1530 return( ret );
1531}
1532
Paul Bakker70b3eed2009-03-14 18:01:25 +00001533#if defined(POLARSSL_GENPRIME)
1534
Paul Bakker5121ce52009-01-03 21:22:43 +00001535/*
1536 * Modular inverse: X = A^-1 mod N (HAC 14.61 / 14.64)
1537 */
1538int mpi_inv_mod( mpi *X, mpi *A, mpi *N )
1539{
1540 int ret;
1541 mpi G, TA, TU, U1, U2, TB, TV, V1, V2;
1542
1543 if( mpi_cmp_int( N, 0 ) <= 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001544 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001545
1546 mpi_init( &TA, &TU, &U1, &U2, &G,
1547 &TB, &TV, &V1, &V2, NULL );
1548
1549 MPI_CHK( mpi_gcd( &G, A, N ) );
1550
1551 if( mpi_cmp_int( &G, 1 ) != 0 )
1552 {
Paul Bakker40e46942009-01-03 21:51:57 +00001553 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001554 goto cleanup;
1555 }
1556
1557 MPI_CHK( mpi_mod_mpi( &TA, A, N ) );
1558 MPI_CHK( mpi_copy( &TU, &TA ) );
1559 MPI_CHK( mpi_copy( &TB, N ) );
1560 MPI_CHK( mpi_copy( &TV, N ) );
1561
1562 MPI_CHK( mpi_lset( &U1, 1 ) );
1563 MPI_CHK( mpi_lset( &U2, 0 ) );
1564 MPI_CHK( mpi_lset( &V1, 0 ) );
1565 MPI_CHK( mpi_lset( &V2, 1 ) );
1566
1567 do
1568 {
1569 while( ( TU.p[0] & 1 ) == 0 )
1570 {
1571 MPI_CHK( mpi_shift_r( &TU, 1 ) );
1572
1573 if( ( U1.p[0] & 1 ) != 0 || ( U2.p[0] & 1 ) != 0 )
1574 {
1575 MPI_CHK( mpi_add_mpi( &U1, &U1, &TB ) );
1576 MPI_CHK( mpi_sub_mpi( &U2, &U2, &TA ) );
1577 }
1578
1579 MPI_CHK( mpi_shift_r( &U1, 1 ) );
1580 MPI_CHK( mpi_shift_r( &U2, 1 ) );
1581 }
1582
1583 while( ( TV.p[0] & 1 ) == 0 )
1584 {
1585 MPI_CHK( mpi_shift_r( &TV, 1 ) );
1586
1587 if( ( V1.p[0] & 1 ) != 0 || ( V2.p[0] & 1 ) != 0 )
1588 {
1589 MPI_CHK( mpi_add_mpi( &V1, &V1, &TB ) );
1590 MPI_CHK( mpi_sub_mpi( &V2, &V2, &TA ) );
1591 }
1592
1593 MPI_CHK( mpi_shift_r( &V1, 1 ) );
1594 MPI_CHK( mpi_shift_r( &V2, 1 ) );
1595 }
1596
1597 if( mpi_cmp_mpi( &TU, &TV ) >= 0 )
1598 {
1599 MPI_CHK( mpi_sub_mpi( &TU, &TU, &TV ) );
1600 MPI_CHK( mpi_sub_mpi( &U1, &U1, &V1 ) );
1601 MPI_CHK( mpi_sub_mpi( &U2, &U2, &V2 ) );
1602 }
1603 else
1604 {
1605 MPI_CHK( mpi_sub_mpi( &TV, &TV, &TU ) );
1606 MPI_CHK( mpi_sub_mpi( &V1, &V1, &U1 ) );
1607 MPI_CHK( mpi_sub_mpi( &V2, &V2, &U2 ) );
1608 }
1609 }
1610 while( mpi_cmp_int( &TU, 0 ) != 0 );
1611
1612 while( mpi_cmp_int( &V1, 0 ) < 0 )
1613 MPI_CHK( mpi_add_mpi( &V1, &V1, N ) );
1614
1615 while( mpi_cmp_mpi( &V1, N ) >= 0 )
1616 MPI_CHK( mpi_sub_mpi( &V1, &V1, N ) );
1617
1618 MPI_CHK( mpi_copy( X, &V1 ) );
1619
1620cleanup:
1621
1622 mpi_free( &V2, &V1, &TV, &TB, &G,
1623 &U2, &U1, &TU, &TA, NULL );
1624
1625 return( ret );
1626}
1627
1628static const int small_prime[] =
1629{
1630 3, 5, 7, 11, 13, 17, 19, 23,
1631 29, 31, 37, 41, 43, 47, 53, 59,
1632 61, 67, 71, 73, 79, 83, 89, 97,
1633 101, 103, 107, 109, 113, 127, 131, 137,
1634 139, 149, 151, 157, 163, 167, 173, 179,
1635 181, 191, 193, 197, 199, 211, 223, 227,
1636 229, 233, 239, 241, 251, 257, 263, 269,
1637 271, 277, 281, 283, 293, 307, 311, 313,
1638 317, 331, 337, 347, 349, 353, 359, 367,
1639 373, 379, 383, 389, 397, 401, 409, 419,
1640 421, 431, 433, 439, 443, 449, 457, 461,
1641 463, 467, 479, 487, 491, 499, 503, 509,
1642 521, 523, 541, 547, 557, 563, 569, 571,
1643 577, 587, 593, 599, 601, 607, 613, 617,
1644 619, 631, 641, 643, 647, 653, 659, 661,
1645 673, 677, 683, 691, 701, 709, 719, 727,
1646 733, 739, 743, 751, 757, 761, 769, 773,
1647 787, 797, 809, 811, 821, 823, 827, 829,
1648 839, 853, 857, 859, 863, 877, 881, 883,
1649 887, 907, 911, 919, 929, 937, 941, 947,
1650 953, 967, 971, 977, 983, 991, 997, -103
1651};
1652
1653/*
1654 * Miller-Rabin primality test (HAC 4.24)
1655 */
1656int mpi_is_prime( mpi *X, int (*f_rng)(void *), void *p_rng )
1657{
1658 int ret, i, j, n, s, xs;
1659 mpi W, R, T, A, RR;
1660 unsigned char *p;
1661
1662 if( mpi_cmp_int( X, 0 ) == 0 )
1663 return( 0 );
1664
1665 mpi_init( &W, &R, &T, &A, &RR, NULL );
1666
1667 xs = X->s; X->s = 1;
1668
1669 /*
1670 * test trivial factors first
1671 */
1672 if( ( X->p[0] & 1 ) == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001673 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001674
1675 for( i = 0; small_prime[i] > 0; i++ )
1676 {
1677 t_int r;
1678
1679 if( mpi_cmp_int( X, small_prime[i] ) <= 0 )
1680 return( 0 );
1681
1682 MPI_CHK( mpi_mod_int( &r, X, small_prime[i] ) );
1683
1684 if( r == 0 )
Paul Bakker40e46942009-01-03 21:51:57 +00001685 return( POLARSSL_ERR_MPI_NOT_ACCEPTABLE );
Paul Bakker5121ce52009-01-03 21:22:43 +00001686 }
1687
1688 /*
1689 * W = |X| - 1
1690 * R = W >> lsb( W )
1691 */
1692 s = mpi_lsb( &W );
1693 MPI_CHK( mpi_sub_int( &W, X, 1 ) );
1694 MPI_CHK( mpi_copy( &R, &W ) );
1695 MPI_CHK( mpi_shift_r( &R, s ) );
1696
1697 i = mpi_msb( X );
1698 /*
1699 * HAC, table 4.4
1700 */
1701 n = ( ( i >= 1300 ) ? 2 : ( i >= 850 ) ? 3 :
1702 ( i >= 650 ) ? 4 : ( i >= 350 ) ? 8 :
1703 ( i >= 250 ) ? 12 : ( i >= 150 ) ? 18 : 27 );
1704
1705 for( i = 0; i < n; i++ )
1706 {
1707 /*
1708 * pick a random A, 1 < A < |X| - 1
1709 */
1710 MPI_CHK( mpi_grow( &A, X->n ) );
1711
1712 p = (unsigned char *) A.p;
1713 for( j = 0; j < A.n * ciL; j++ )
1714 *p++ = (unsigned char) f_rng( p_rng );
1715
1716 j = mpi_msb( &A ) - mpi_msb( &W );
1717 MPI_CHK( mpi_shift_r( &A, j + 1 ) );
1718 A.p[0] |= 3;
1719
1720 /*
1721 * A = A^R mod |X|
1722 */
1723 MPI_CHK( mpi_exp_mod( &A, &A, &R, X, &RR ) );
1724
1725 if( mpi_cmp_mpi( &A, &W ) == 0 ||
1726 mpi_cmp_int( &A, 1 ) == 0 )
1727 continue;
1728
1729 j = 1;
1730 while( j < s && mpi_cmp_mpi( &A, &W ) != 0 )
1731 {
1732 /*
1733 * A = A * A mod |X|
1734 */
1735 MPI_CHK( mpi_mul_mpi( &T, &A, &A ) );
1736 MPI_CHK( mpi_mod_mpi( &A, &T, X ) );
1737
1738 if( mpi_cmp_int( &A, 1 ) == 0 )
1739 break;
1740
1741 j++;
1742 }
1743
1744 /*
1745 * not prime if A != |X| - 1 or A == 1
1746 */
1747 if( mpi_cmp_mpi( &A, &W ) != 0 ||
1748 mpi_cmp_int( &A, 1 ) == 0 )
1749 {
Paul Bakker40e46942009-01-03 21:51:57 +00001750 ret = POLARSSL_ERR_MPI_NOT_ACCEPTABLE;
Paul Bakker5121ce52009-01-03 21:22:43 +00001751 break;
1752 }
1753 }
1754
1755cleanup:
1756
1757 X->s = xs;
1758
1759 mpi_free( &RR, &A, &T, &R, &W, NULL );
1760
1761 return( ret );
1762}
1763
1764/*
1765 * Prime number generation
1766 */
1767int mpi_gen_prime( mpi *X, int nbits, int dh_flag,
1768 int (*f_rng)(void *), void *p_rng )
1769{
1770 int ret, k, n;
1771 unsigned char *p;
1772 mpi Y;
1773
1774 if( nbits < 3 )
Paul Bakker40e46942009-01-03 21:51:57 +00001775 return( POLARSSL_ERR_MPI_BAD_INPUT_DATA );
Paul Bakker5121ce52009-01-03 21:22:43 +00001776
1777 mpi_init( &Y, NULL );
1778
1779 n = BITS_TO_LIMBS( nbits );
1780
1781 MPI_CHK( mpi_grow( X, n ) );
1782 MPI_CHK( mpi_lset( X, 0 ) );
1783
1784 p = (unsigned char *) X->p;
1785 for( k = 0; k < X->n * ciL; k++ )
1786 *p++ = (unsigned char) f_rng( p_rng );
1787
1788 k = mpi_msb( X );
1789 if( k < nbits ) MPI_CHK( mpi_shift_l( X, nbits - k ) );
1790 if( k > nbits ) MPI_CHK( mpi_shift_r( X, k - nbits ) );
1791
1792 X->p[0] |= 3;
1793
1794 if( dh_flag == 0 )
1795 {
1796 while( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) != 0 )
1797 {
Paul Bakker40e46942009-01-03 21:51:57 +00001798 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001799 goto cleanup;
1800
1801 MPI_CHK( mpi_add_int( X, X, 2 ) );
1802 }
1803 }
1804 else
1805 {
1806 MPI_CHK( mpi_sub_int( &Y, X, 1 ) );
1807 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1808
1809 while( 1 )
1810 {
1811 if( ( ret = mpi_is_prime( X, f_rng, p_rng ) ) == 0 )
1812 {
1813 if( ( ret = mpi_is_prime( &Y, f_rng, p_rng ) ) == 0 )
1814 break;
1815
Paul Bakker40e46942009-01-03 21:51:57 +00001816 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001817 goto cleanup;
1818 }
1819
Paul Bakker40e46942009-01-03 21:51:57 +00001820 if( ret != POLARSSL_ERR_MPI_NOT_ACCEPTABLE )
Paul Bakker5121ce52009-01-03 21:22:43 +00001821 goto cleanup;
1822
1823 MPI_CHK( mpi_add_int( &Y, X, 1 ) );
1824 MPI_CHK( mpi_add_int( X, X, 2 ) );
1825 MPI_CHK( mpi_shift_r( &Y, 1 ) );
1826 }
1827 }
1828
1829cleanup:
1830
1831 mpi_free( &Y, NULL );
1832
1833 return( ret );
1834}
1835
1836#endif
1837
Paul Bakker40e46942009-01-03 21:51:57 +00001838#if defined(POLARSSL_SELF_TEST)
Paul Bakker5121ce52009-01-03 21:22:43 +00001839
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001840#define GCD_PAIR_COUNT 3
1841
1842static const int gcd_pairs[GCD_PAIR_COUNT][3] =
1843{
1844 { 693, 609, 21 },
1845 { 1764, 868, 28 },
1846 { 768454923, 542167814, 1 }
1847};
1848
Paul Bakker5121ce52009-01-03 21:22:43 +00001849/*
1850 * Checkup routine
1851 */
1852int mpi_self_test( int verbose )
1853{
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001854 int ret, i;
Paul Bakker5121ce52009-01-03 21:22:43 +00001855 mpi A, E, N, X, Y, U, V;
1856
1857 mpi_init( &A, &E, &N, &X, &Y, &U, &V, NULL );
1858
1859 MPI_CHK( mpi_read_string( &A, 16,
1860 "EFE021C2645FD1DC586E69184AF4A31E" \
1861 "D5F53E93B5F123FA41680867BA110131" \
1862 "944FE7952E2517337780CB0DB80E61AA" \
1863 "E7C8DDC6C5C6AADEB34EB38A2F40D5E6" ) );
1864
1865 MPI_CHK( mpi_read_string( &E, 16,
1866 "B2E7EFD37075B9F03FF989C7C5051C20" \
1867 "34D2A323810251127E7BF8625A4F49A5" \
1868 "F3E27F4DA8BD59C47D6DAABA4C8127BD" \
1869 "5B5C25763222FEFCCFC38B832366C29E" ) );
1870
1871 MPI_CHK( mpi_read_string( &N, 16,
1872 "0066A198186C18C10B2F5ED9B522752A" \
1873 "9830B69916E535C8F047518A889A43A5" \
1874 "94B6BED27A168D31D4A52F88925AA8F5" ) );
1875
1876 MPI_CHK( mpi_mul_mpi( &X, &A, &N ) );
1877
1878 MPI_CHK( mpi_read_string( &U, 16,
1879 "602AB7ECA597A3D6B56FF9829A5E8B85" \
1880 "9E857EA95A03512E2BAE7391688D264A" \
1881 "A5663B0341DB9CCFD2C4C5F421FEC814" \
1882 "8001B72E848A38CAE1C65F78E56ABDEF" \
1883 "E12D3C039B8A02D6BE593F0BBBDA56F1" \
1884 "ECF677152EF804370C1A305CAF3B5BF1" \
1885 "30879B56C61DE584A0F53A2447A51E" ) );
1886
1887 if( verbose != 0 )
1888 printf( " MPI test #1 (mul_mpi): " );
1889
1890 if( mpi_cmp_mpi( &X, &U ) != 0 )
1891 {
1892 if( verbose != 0 )
1893 printf( "failed\n" );
1894
1895 return( 1 );
1896 }
1897
1898 if( verbose != 0 )
1899 printf( "passed\n" );
1900
1901 MPI_CHK( mpi_div_mpi( &X, &Y, &A, &N ) );
1902
1903 MPI_CHK( mpi_read_string( &U, 16,
1904 "256567336059E52CAE22925474705F39A94" ) );
1905
1906 MPI_CHK( mpi_read_string( &V, 16,
1907 "6613F26162223DF488E9CD48CC132C7A" \
1908 "0AC93C701B001B092E4E5B9F73BCD27B" \
1909 "9EE50D0657C77F374E903CDFA4C642" ) );
1910
1911 if( verbose != 0 )
1912 printf( " MPI test #2 (div_mpi): " );
1913
1914 if( mpi_cmp_mpi( &X, &U ) != 0 ||
1915 mpi_cmp_mpi( &Y, &V ) != 0 )
1916 {
1917 if( verbose != 0 )
1918 printf( "failed\n" );
1919
1920 return( 1 );
1921 }
1922
1923 if( verbose != 0 )
1924 printf( "passed\n" );
1925
1926 MPI_CHK( mpi_exp_mod( &X, &A, &E, &N, NULL ) );
1927
1928 MPI_CHK( mpi_read_string( &U, 16,
1929 "36E139AEA55215609D2816998ED020BB" \
1930 "BD96C37890F65171D948E9BC7CBAA4D9" \
1931 "325D24D6A3C12710F10A09FA08AB87" ) );
1932
1933 if( verbose != 0 )
1934 printf( " MPI test #3 (exp_mod): " );
1935
1936 if( mpi_cmp_mpi( &X, &U ) != 0 )
1937 {
1938 if( verbose != 0 )
1939 printf( "failed\n" );
1940
1941 return( 1 );
1942 }
1943
1944 if( verbose != 0 )
1945 printf( "passed\n" );
1946
1947 MPI_CHK( mpi_inv_mod( &X, &A, &N ) );
1948
1949 MPI_CHK( mpi_read_string( &U, 16,
1950 "003A0AAEDD7E784FC07D8F9EC6E3BFD5" \
1951 "C3DBA76456363A10869622EAC2DD84EC" \
1952 "C5B8A74DAC4D09E03B5E0BE779F2DF61" ) );
1953
1954 if( verbose != 0 )
1955 printf( " MPI test #4 (inv_mod): " );
1956
1957 if( mpi_cmp_mpi( &X, &U ) != 0 )
1958 {
1959 if( verbose != 0 )
1960 printf( "failed\n" );
1961
1962 return( 1 );
1963 }
1964
1965 if( verbose != 0 )
1966 printf( "passed\n" );
1967
Paul Bakker4e0d7ca2009-01-29 22:24:33 +00001968 if( verbose != 0 )
1969 printf( " MPI test #5 (simple gcd): " );
1970
1971 for ( i = 0; i < GCD_PAIR_COUNT; i++)
1972 {
1973 MPI_CHK( mpi_lset( &X, gcd_pairs[i][0] ) );
1974 MPI_CHK( mpi_lset( &Y, gcd_pairs[i][1] ) );
1975
1976 MPI_CHK( mpi_gcd( &A, &X, &Y ) );
1977
1978 if( mpi_cmp_int( &A, gcd_pairs[i][2] ) != 0 )
1979 {
1980 if( verbose != 0 )
1981 printf( "failed at %d\n", i );
1982
1983 return( 1 );
1984 }
1985 }
1986
1987 if( verbose != 0 )
1988 printf( "passed\n" );
1989
Paul Bakker5121ce52009-01-03 21:22:43 +00001990cleanup:
1991
1992 if( ret != 0 && verbose != 0 )
1993 printf( "Unexpected error, return code = %08X\n", ret );
1994
1995 mpi_free( &V, &U, &Y, &X, &N, &E, &A, NULL );
1996
1997 if( verbose != 0 )
1998 printf( "\n" );
1999
2000 return( ret );
2001}
2002
2003#endif
2004
2005#endif