source: trunk/library/bignum.c @ 1280

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

What are you looking for?