Configire: take multi-block modules into build loop.
[openssl.git] / crypto / bn / bn_lib.c
1 /* crypto/bn/bn_lib.c */
2 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  * 
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  * 
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  * 
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from 
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  * 
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * 
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58
59 #ifndef BN_DEBUG
60 # undef NDEBUG /* avoid conflicting definitions */
61 # define NDEBUG
62 #endif
63
64 #define OPENSSL_FIPSAPI
65
66 #include <assert.h>
67 #include <limits.h>
68 #include <stdio.h>
69 #include "cryptlib.h"
70 #include "bn_lcl.h"
71
72 __fips_constseg
73 const char BN_version[]="Big Number" OPENSSL_VERSION_PTEXT;
74
75 /* This stuff appears to be completely unused, so is deprecated */
76 #ifndef OPENSSL_NO_DEPRECATED
77 /* For a 32 bit machine
78  * 2 -   4 ==  128
79  * 3 -   8 ==  256
80  * 4 -  16 ==  512
81  * 5 -  32 == 1024
82  * 6 -  64 == 2048
83  * 7 - 128 == 4096
84  * 8 - 256 == 8192
85  */
86 static int bn_limit_bits=0;
87 static int bn_limit_num=8;        /* (1<<bn_limit_bits) */
88 static int bn_limit_bits_low=0;
89 static int bn_limit_num_low=8;    /* (1<<bn_limit_bits_low) */
90 static int bn_limit_bits_high=0;
91 static int bn_limit_num_high=8;   /* (1<<bn_limit_bits_high) */
92 static int bn_limit_bits_mont=0;
93 static int bn_limit_num_mont=8;   /* (1<<bn_limit_bits_mont) */
94
95 void BN_set_params(int mult, int high, int low, int mont)
96         {
97         if (mult >= 0)
98                 {
99                 if (mult > (int)(sizeof(int)*8)-1)
100                         mult=sizeof(int)*8-1;
101                 bn_limit_bits=mult;
102                 bn_limit_num=1<<mult;
103                 }
104         if (high >= 0)
105                 {
106                 if (high > (int)(sizeof(int)*8)-1)
107                         high=sizeof(int)*8-1;
108                 bn_limit_bits_high=high;
109                 bn_limit_num_high=1<<high;
110                 }
111         if (low >= 0)
112                 {
113                 if (low > (int)(sizeof(int)*8)-1)
114                         low=sizeof(int)*8-1;
115                 bn_limit_bits_low=low;
116                 bn_limit_num_low=1<<low;
117                 }
118         if (mont >= 0)
119                 {
120                 if (mont > (int)(sizeof(int)*8)-1)
121                         mont=sizeof(int)*8-1;
122                 bn_limit_bits_mont=mont;
123                 bn_limit_num_mont=1<<mont;
124                 }
125         }
126
127 int BN_get_params(int which)
128         {
129         if      (which == 0) return(bn_limit_bits);
130         else if (which == 1) return(bn_limit_bits_high);
131         else if (which == 2) return(bn_limit_bits_low);
132         else if (which == 3) return(bn_limit_bits_mont);
133         else return(0);
134         }
135 #endif
136
137 const BIGNUM *BN_value_one(void)
138         {
139         static const BN_ULONG data_one=1L;
140         static const BIGNUM const_one={(BN_ULONG *)&data_one,1,1,0,BN_FLG_STATIC_DATA};
141
142         return(&const_one);
143         }
144
145 int BN_num_bits_word(BN_ULONG l)
146         {
147         __fips_constseg
148         static const unsigned char bits[256]={
149                 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
150                 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
151                 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
152                 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
153                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
154                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
155                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
156                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
157                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
158                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
159                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
160                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
161                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
162                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
163                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
164                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
165                 };
166
167 #if defined(SIXTY_FOUR_BIT_LONG)
168         if (l & 0xffffffff00000000L)
169                 {
170                 if (l & 0xffff000000000000L)
171                         {
172                         if (l & 0xff00000000000000L)
173                                 {
174                                 return(bits[(int)(l>>56)]+56);
175                                 }
176                         else    return(bits[(int)(l>>48)]+48);
177                         }
178                 else
179                         {
180                         if (l & 0x0000ff0000000000L)
181                                 {
182                                 return(bits[(int)(l>>40)]+40);
183                                 }
184                         else    return(bits[(int)(l>>32)]+32);
185                         }
186                 }
187         else
188 #else
189 #ifdef SIXTY_FOUR_BIT
190         if (l & 0xffffffff00000000LL)
191                 {
192                 if (l & 0xffff000000000000LL)
193                         {
194                         if (l & 0xff00000000000000LL)
195                                 {
196                                 return(bits[(int)(l>>56)]+56);
197                                 }
198                         else    return(bits[(int)(l>>48)]+48);
199                         }
200                 else
201                         {
202                         if (l & 0x0000ff0000000000LL)
203                                 {
204                                 return(bits[(int)(l>>40)]+40);
205                                 }
206                         else    return(bits[(int)(l>>32)]+32);
207                         }
208                 }
209         else
210 #endif
211 #endif
212                 {
213 #if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
214                 if (l & 0xffff0000L)
215                         {
216                         if (l & 0xff000000L)
217                                 return(bits[(int)(l>>24L)]+24);
218                         else    return(bits[(int)(l>>16L)]+16);
219                         }
220                 else
221 #endif
222                         {
223 #if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
224                         if (l & 0xff00L)
225                                 return(bits[(int)(l>>8)]+8);
226                         else    
227 #endif
228                                 return(bits[(int)(l   )]  );
229                         }
230                 }
231         }
232
233 int BN_num_bits(const BIGNUM *a)
234         {
235         int i = a->top - 1;
236         bn_check_top(a);
237
238         if (BN_is_zero(a)) return 0;
239         return ((i*BN_BITS2) + BN_num_bits_word(a->d[i]));
240         }
241
242 void BN_clear_free(BIGNUM *a)
243         {
244         int i;
245
246         if (a == NULL) return;
247         bn_check_top(a);
248         if (a->d != NULL)
249                 {
250                 OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0]));
251                 if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
252                         OPENSSL_free(a->d);
253                 }
254         i=BN_get_flags(a,BN_FLG_MALLOCED);
255         OPENSSL_cleanse(a,sizeof(BIGNUM));
256         if (i)
257                 OPENSSL_free(a);
258         }
259
260 void BN_free(BIGNUM *a)
261         {
262         if (a == NULL) return;
263         bn_check_top(a);
264         if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
265                 OPENSSL_free(a->d);
266         if (a->flags & BN_FLG_MALLOCED)
267                 OPENSSL_free(a);
268         else
269                 {
270 #ifndef OPENSSL_NO_DEPRECATED
271                 a->flags|=BN_FLG_FREE;
272 #endif
273                 a->d = NULL;
274                 }
275         }
276
277 void BN_init(BIGNUM *a)
278         {
279         memset(a,0,sizeof(BIGNUM));
280         bn_check_top(a);
281         }
282
283 BIGNUM *BN_new(void)
284         {
285         BIGNUM *ret;
286
287         if ((ret=(BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL)
288                 {
289                 BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
290                 return(NULL);
291                 }
292         ret->flags=BN_FLG_MALLOCED;
293         ret->top=0;
294         ret->neg=0;
295         ret->dmax=0;
296         ret->d=NULL;
297         bn_check_top(ret);
298         return(ret);
299         }
300
301 /* This is used both by bn_expand2() and bn_dup_expand() */
302 /* The caller MUST check that words > b->dmax before calling this */
303 static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
304         {
305         BN_ULONG *A,*a = NULL;
306         const BN_ULONG *B;
307         int i;
308
309         bn_check_top(b);
310
311         if (words > (INT_MAX/(4*BN_BITS2)))
312                 {
313                 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_BIGNUM_TOO_LONG);
314                 return NULL;
315                 }
316         if (BN_get_flags(b,BN_FLG_STATIC_DATA))
317                 {
318                 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
319                 return(NULL);
320                 }
321         a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*words);
322         if (A == NULL)
323                 {
324                 BNerr(BN_F_BN_EXPAND_INTERNAL,ERR_R_MALLOC_FAILURE);
325                 return(NULL);
326                 }
327 #if 1
328         B=b->d;
329         /* Check if the previous number needs to be copied */
330         if (B != NULL)
331                 {
332                 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
333                         {
334                         /*
335                          * The fact that the loop is unrolled
336                          * 4-wise is a tribute to Intel. It's
337                          * the one that doesn't have enough
338                          * registers to accomodate more data.
339                          * I'd unroll it 8-wise otherwise:-)
340                          *
341                          *              <appro@fy.chalmers.se>
342                          */
343                         BN_ULONG a0,a1,a2,a3;
344                         a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
345                         A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
346                         }
347                 switch (b->top&3)
348                         {
349                 case 3: A[2]=B[2];
350                 case 2: A[1]=B[1];
351                 case 1: A[0]=B[0];
352                 case 0: /* workaround for ultrix cc: without 'case 0', the optimizer does
353                          * the switch table by doing a=top&3; a--; goto jump_table[a];
354                          * which fails for top== 0 */
355                         ;
356                         }
357                 }
358
359 #else
360         memset(A,0,sizeof(BN_ULONG)*words);
361         memcpy(A,b->d,sizeof(b->d[0])*b->top);
362 #endif
363                 
364         return(a);
365         }
366
367 /* This is an internal function that can be used instead of bn_expand2()
368  * when there is a need to copy BIGNUMs instead of only expanding the
369  * data part, while still expanding them.
370  * Especially useful when needing to expand BIGNUMs that are declared
371  * 'const' and should therefore not be changed.
372  * The reason to use this instead of a BN_dup() followed by a bn_expand2()
373  * is memory allocation overhead.  A BN_dup() followed by a bn_expand2()
374  * will allocate new memory for the BIGNUM data twice, and free it once,
375  * while bn_dup_expand() makes sure allocation is made only once.
376  */
377
378 #ifndef OPENSSL_NO_DEPRECATED
379 BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
380         {
381         BIGNUM *r = NULL;
382
383         bn_check_top(b);
384
385         /* This function does not work if
386          *      words <= b->dmax && top < words
387          * because BN_dup() does not preserve 'dmax'!
388          * (But bn_dup_expand() is not used anywhere yet.)
389          */
390
391         if (words > b->dmax)
392                 {
393                 BN_ULONG *a = bn_expand_internal(b, words);
394
395                 if (a)
396                         {
397                         r = BN_new();
398                         if (r)
399                                 {
400                                 r->top = b->top;
401                                 r->dmax = words;
402                                 r->neg = b->neg;
403                                 r->d = a;
404                                 }
405                         else
406                                 {
407                                 /* r == NULL, BN_new failure */
408                                 OPENSSL_free(a);
409                                 }
410                         }
411                 /* If a == NULL, there was an error in allocation in
412                    bn_expand_internal(), and NULL should be returned */
413                 }
414         else
415                 {
416                 r = BN_dup(b);
417                 }
418
419         bn_check_top(r);
420         return r;
421         }
422 #endif
423
424 /* This is an internal function that should not be used in applications.
425  * It ensures that 'b' has enough room for a 'words' word number
426  * and initialises any unused part of b->d with leading zeros.
427  * It is mostly used by the various BIGNUM routines. If there is an error,
428  * NULL is returned. If not, 'b' is returned. */
429
430 BIGNUM *bn_expand2(BIGNUM *b, int words)
431         {
432         bn_check_top(b);
433
434         if (words > b->dmax)
435                 {
436                 BN_ULONG *a = bn_expand_internal(b, words);
437                 if(!a) return NULL;
438                 if(b->d) OPENSSL_free(b->d);
439                 b->d=a;
440                 b->dmax=words;
441                 }
442
443 /* None of this should be necessary because of what b->top means! */
444 #if 0
445         /* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
446         if (b->top < b->dmax)
447                 {
448                 int i;
449                 BN_ULONG *A = &(b->d[b->top]);
450                 for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
451                         {
452                         A[0]=0; A[1]=0; A[2]=0; A[3]=0;
453                         A[4]=0; A[5]=0; A[6]=0; A[7]=0;
454                         }
455                 for (i=(b->dmax - b->top)&7; i>0; i--,A++)
456                         A[0]=0;
457                 assert(A == &(b->d[b->dmax]));
458                 }
459 #endif
460         bn_check_top(b);
461         return b;
462         }
463
464 BIGNUM *BN_dup(const BIGNUM *a)
465         {
466         BIGNUM *t;
467
468         if (a == NULL) return NULL;
469         bn_check_top(a);
470
471         t = BN_new();
472         if (t == NULL) return NULL;
473         if(!BN_copy(t, a))
474                 {
475                 BN_free(t);
476                 return NULL;
477                 }
478         bn_check_top(t);
479         return t;
480         }
481
482 BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
483         {
484         int i;
485         BN_ULONG *A;
486         const BN_ULONG *B;
487
488         bn_check_top(b);
489
490         if (a == b) return(a);
491         if (bn_wexpand(a,b->top) == NULL) return(NULL);
492
493 #if 1
494         A=a->d;
495         B=b->d;
496         for (i=b->top>>2; i>0; i--,A+=4,B+=4)
497                 {
498                 BN_ULONG a0,a1,a2,a3;
499                 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
500                 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
501                 }
502         switch (b->top&3)
503                 {
504                 case 3: A[2]=B[2];
505                 case 2: A[1]=B[1];
506                 case 1: A[0]=B[0];
507                 case 0: ; /* ultrix cc workaround, see comments in bn_expand_internal */
508                 }
509 #else
510         memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
511 #endif
512
513         a->top=b->top;
514         a->neg=b->neg;
515         bn_check_top(a);
516         return(a);
517         }
518
519 void BN_swap(BIGNUM *a, BIGNUM *b)
520         {
521         int flags_old_a, flags_old_b;
522         BN_ULONG *tmp_d;
523         int tmp_top, tmp_dmax, tmp_neg;
524         
525         bn_check_top(a);
526         bn_check_top(b);
527
528         flags_old_a = a->flags;
529         flags_old_b = b->flags;
530
531         tmp_d = a->d;
532         tmp_top = a->top;
533         tmp_dmax = a->dmax;
534         tmp_neg = a->neg;
535         
536         a->d = b->d;
537         a->top = b->top;
538         a->dmax = b->dmax;
539         a->neg = b->neg;
540         
541         b->d = tmp_d;
542         b->top = tmp_top;
543         b->dmax = tmp_dmax;
544         b->neg = tmp_neg;
545         
546         a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
547         b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
548         bn_check_top(a);
549         bn_check_top(b);
550         }
551
552 void BN_clear(BIGNUM *a)
553         {
554         bn_check_top(a);
555         if (a->d != NULL)
556                 memset(a->d,0,a->dmax*sizeof(a->d[0]));
557         a->top=0;
558         a->neg=0;
559         }
560
561 BN_ULONG BN_get_word(const BIGNUM *a)
562         {
563         if (a->top > 1)
564                 return BN_MASK2;
565         else if (a->top == 1)
566                 return a->d[0];
567         /* a->top == 0 */
568         return 0;
569         }
570
571 int BN_set_word(BIGNUM *a, BN_ULONG w)
572         {
573         bn_check_top(a);
574         if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0);
575         a->neg = 0;
576         a->d[0] = w;
577         a->top = (w ? 1 : 0);
578         bn_check_top(a);
579         return(1);
580         }
581
582 BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
583         {
584         unsigned int i,m;
585         unsigned int n;
586         BN_ULONG l;
587         BIGNUM  *bn = NULL;
588
589         if (ret == NULL)
590                 ret = bn = BN_new();
591         if (ret == NULL) return(NULL);
592         bn_check_top(ret);
593         l=0;
594         n=len;
595         if (n == 0)
596                 {
597                 ret->top=0;
598                 return(ret);
599                 }
600         i=((n-1)/BN_BYTES)+1;
601         m=((n-1)%(BN_BYTES));
602         if (bn_wexpand(ret, (int)i) == NULL)
603                 {
604                 if (bn) BN_free(bn);
605                 return NULL;
606                 }
607         ret->top=i;
608         ret->neg=0;
609         while (n--)
610                 {
611                 l=(l<<8L)| *(s++);
612                 if (m-- == 0)
613                         {
614                         ret->d[--i]=l;
615                         l=0;
616                         m=BN_BYTES-1;
617                         }
618                 }
619         /* need to call this due to clear byte at top if avoiding
620          * having the top bit set (-ve number) */
621         bn_correct_top(ret);
622         return(ret);
623         }
624
625 /* ignore negative */
626 int BN_bn2bin(const BIGNUM *a, unsigned char *to)
627         {
628         int n,i;
629         BN_ULONG l;
630
631         bn_check_top(a);
632         n=i=BN_num_bytes(a);
633         while (i--)
634                 {
635                 l=a->d[i/BN_BYTES];
636                 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
637                 }
638         return(n);
639         }
640
641 int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
642         {
643         int i;
644         BN_ULONG t1,t2,*ap,*bp;
645
646         bn_check_top(a);
647         bn_check_top(b);
648
649         i=a->top-b->top;
650         if (i != 0) return(i);
651         ap=a->d;
652         bp=b->d;
653         for (i=a->top-1; i>=0; i--)
654                 {
655                 t1= ap[i];
656                 t2= bp[i];
657                 if (t1 != t2)
658                         return((t1 > t2) ? 1 : -1);
659                 }
660         return(0);
661         }
662
663 int BN_cmp(const BIGNUM *a, const BIGNUM *b)
664         {
665         int i;
666         int gt,lt;
667         BN_ULONG t1,t2;
668
669         if ((a == NULL) || (b == NULL))
670                 {
671                 if (a != NULL)
672                         return(-1);
673                 else if (b != NULL)
674                         return(1);
675                 else
676                         return(0);
677                 }
678
679         bn_check_top(a);
680         bn_check_top(b);
681
682         if (a->neg != b->neg)
683                 {
684                 if (a->neg)
685                         return(-1);
686                 else    return(1);
687                 }
688         if (a->neg == 0)
689                 { gt=1; lt= -1; }
690         else    { gt= -1; lt=1; }
691
692         if (a->top > b->top) return(gt);
693         if (a->top < b->top) return(lt);
694         for (i=a->top-1; i>=0; i--)
695                 {
696                 t1=a->d[i];
697                 t2=b->d[i];
698                 if (t1 > t2) return(gt);
699                 if (t1 < t2) return(lt);
700                 }
701         return(0);
702         }
703
704 int BN_set_bit(BIGNUM *a, int n)
705         {
706         int i,j,k;
707
708         if (n < 0)
709                 return 0;
710
711         i=n/BN_BITS2;
712         j=n%BN_BITS2;
713         if (a->top <= i)
714                 {
715                 if (bn_wexpand(a,i+1) == NULL) return(0);
716                 for(k=a->top; k<i+1; k++)
717                         a->d[k]=0;
718                 a->top=i+1;
719                 }
720
721         a->d[i]|=(((BN_ULONG)1)<<j);
722         bn_check_top(a);
723         return(1);
724         }
725
726 int BN_clear_bit(BIGNUM *a, int n)
727         {
728         int i,j;
729
730         bn_check_top(a);
731         if (n < 0) return 0;
732
733         i=n/BN_BITS2;
734         j=n%BN_BITS2;
735         if (a->top <= i) return(0);
736
737         a->d[i]&=(~(((BN_ULONG)1)<<j));
738         bn_correct_top(a);
739         return(1);
740         }
741
742 int BN_is_bit_set(const BIGNUM *a, int n)
743         {
744         int i,j;
745
746         bn_check_top(a);
747         if (n < 0) return 0;
748         i=n/BN_BITS2;
749         j=n%BN_BITS2;
750         if (a->top <= i) return 0;
751         return (int)(((a->d[i])>>j)&((BN_ULONG)1));
752         }
753
754 int BN_mask_bits(BIGNUM *a, int n)
755         {
756         int b,w;
757
758         bn_check_top(a);
759         if (n < 0) return 0;
760
761         w=n/BN_BITS2;
762         b=n%BN_BITS2;
763         if (w >= a->top) return 0;
764         if (b == 0)
765                 a->top=w;
766         else
767                 {
768                 a->top=w+1;
769                 a->d[w]&= ~(BN_MASK2<<b);
770                 }
771         bn_correct_top(a);
772         return(1);
773         }
774
775 void BN_set_negative(BIGNUM *a, int b)
776         {
777         if (b && !BN_is_zero(a))
778                 a->neg = 1;
779         else
780                 a->neg = 0;
781         }
782
783 int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
784         {
785         int i;
786         BN_ULONG aa,bb;
787
788         aa=a[n-1];
789         bb=b[n-1];
790         if (aa != bb) return((aa > bb)?1:-1);
791         for (i=n-2; i>=0; i--)
792                 {
793                 aa=a[i];
794                 bb=b[i];
795                 if (aa != bb) return((aa > bb)?1:-1);
796                 }
797         return(0);
798         }
799
800 /* Here follows a specialised variants of bn_cmp_words().  It has the
801    property of performing the operation on arrays of different sizes.
802    The sizes of those arrays is expressed through cl, which is the
803    common length ( basicall, min(len(a),len(b)) ), and dl, which is the
804    delta between the two lengths, calculated as len(a)-len(b).
805    All lengths are the number of BN_ULONGs...  */
806
807 int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
808         int cl, int dl)
809         {
810         int n,i;
811         n = cl-1;
812
813         if (dl < 0)
814                 {
815                 for (i=dl; i<0; i++)
816                         {
817                         if (b[n-i] != 0)
818                                 return -1; /* a < b */
819                         }
820                 }
821         if (dl > 0)
822                 {
823                 for (i=dl; i>0; i--)
824                         {
825                         if (a[n+i] != 0)
826                                 return 1; /* a > b */
827                         }
828                 }
829         return bn_cmp_words(a,b,cl);
830         }