Don't allow BIGNUMs to become so large that computations with dmax
[oweals/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 #include <assert.h>
65 #include <stdio.h>
66 #include "cryptlib.h"
67 #include "bn_lcl.h"
68
69 const char *BN_version="Big Number" OPENSSL_VERSION_PTEXT;
70
71 /* For a 32 bit machine
72  * 2 -   4 ==  128
73  * 3 -   8 ==  256
74  * 4 -  16 ==  512
75  * 5 -  32 == 1024
76  * 6 -  64 == 2048
77  * 7 - 128 == 4096
78  * 8 - 256 == 8192
79  */
80 static int bn_limit_bits=0;
81 static int bn_limit_num=8;        /* (1<<bn_limit_bits) */
82 static int bn_limit_bits_low=0;
83 static int bn_limit_num_low=8;    /* (1<<bn_limit_bits_low) */
84 static int bn_limit_bits_high=0;
85 static int bn_limit_num_high=8;   /* (1<<bn_limit_bits_high) */
86 static int bn_limit_bits_mont=0;
87 static int bn_limit_num_mont=8;   /* (1<<bn_limit_bits_mont) */
88
89 void BN_set_params(int mult, int high, int low, int mont)
90         {
91         if (mult >= 0)
92                 {
93                 if (mult > (sizeof(int)*8)-1)
94                         mult=sizeof(int)*8-1;
95                 bn_limit_bits=mult;
96                 bn_limit_num=1<<mult;
97                 }
98         if (high >= 0)
99                 {
100                 if (high > (sizeof(int)*8)-1)
101                         high=sizeof(int)*8-1;
102                 bn_limit_bits_high=high;
103                 bn_limit_num_high=1<<high;
104                 }
105         if (low >= 0)
106                 {
107                 if (low > (sizeof(int)*8)-1)
108                         low=sizeof(int)*8-1;
109                 bn_limit_bits_low=low;
110                 bn_limit_num_low=1<<low;
111                 }
112         if (mont >= 0)
113                 {
114                 if (mont > (sizeof(int)*8)-1)
115                         mont=sizeof(int)*8-1;
116                 bn_limit_bits_mont=mont;
117                 bn_limit_num_mont=1<<mont;
118                 }
119         }
120
121 int BN_get_params(int which)
122         {
123         if      (which == 0) return(bn_limit_bits);
124         else if (which == 1) return(bn_limit_bits_high);
125         else if (which == 2) return(bn_limit_bits_low);
126         else if (which == 3) return(bn_limit_bits_mont);
127         else return(0);
128         }
129
130 BIGNUM *BN_value_one(void)
131         {
132         static BN_ULONG data_one=1L;
133         static BIGNUM const_one={&data_one,1,1,0};
134
135         return(&const_one);
136         }
137
138 char *BN_options(void)
139         {
140         static int init=0;
141         static char data[16];
142
143         if (!init)
144                 {
145                 init++;
146 #ifdef BN_LLONG
147                 sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULLONG)*8,
148                         (int)sizeof(BN_ULONG)*8);
149 #else
150                 sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULONG)*8,
151                         (int)sizeof(BN_ULONG)*8);
152 #endif
153                 }
154         return(data);
155         }
156
157 int BN_num_bits_word(BN_ULONG l)
158         {
159         static const char bits[256]={
160                 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
161                 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
162                 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
163                 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
164                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
165                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
166                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
167                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
168                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
169                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
170                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
171                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
172                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
173                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
174                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
175                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
176                 };
177
178 #if defined(SIXTY_FOUR_BIT_LONG)
179         if (l & 0xffffffff00000000L)
180                 {
181                 if (l & 0xffff000000000000L)
182                         {
183                         if (l & 0xff00000000000000L)
184                                 {
185                                 return(bits[(int)(l>>56)]+56);
186                                 }
187                         else    return(bits[(int)(l>>48)]+48);
188                         }
189                 else
190                         {
191                         if (l & 0x0000ff0000000000L)
192                                 {
193                                 return(bits[(int)(l>>40)]+40);
194                                 }
195                         else    return(bits[(int)(l>>32)]+32);
196                         }
197                 }
198         else
199 #else
200 #ifdef SIXTY_FOUR_BIT
201         if (l & 0xffffffff00000000LL)
202                 {
203                 if (l & 0xffff000000000000LL)
204                         {
205                         if (l & 0xff00000000000000LL)
206                                 {
207                                 return(bits[(int)(l>>56)]+56);
208                                 }
209                         else    return(bits[(int)(l>>48)]+48);
210                         }
211                 else
212                         {
213                         if (l & 0x0000ff0000000000LL)
214                                 {
215                                 return(bits[(int)(l>>40)]+40);
216                                 }
217                         else    return(bits[(int)(l>>32)]+32);
218                         }
219                 }
220         else
221 #endif
222 #endif
223                 {
224 #if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
225                 if (l & 0xffff0000L)
226                         {
227                         if (l & 0xff000000L)
228                                 return(bits[(int)(l>>24L)]+24);
229                         else    return(bits[(int)(l>>16L)]+16);
230                         }
231                 else
232 #endif
233                         {
234 #if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
235                         if (l & 0xff00L)
236                                 return(bits[(int)(l>>8)]+8);
237                         else    
238 #endif
239                                 return(bits[(int)(l   )]  );
240                         }
241                 }
242         }
243
244 int BN_num_bits(const BIGNUM *a)
245         {
246         BN_ULONG l;
247         int i;
248
249         bn_check_top(a);
250
251         if (a->top == 0) return(0);
252         l=a->d[a->top-1];
253         assert(l != 0);
254         i=(a->top-1)*BN_BITS2;
255         return(i+BN_num_bits_word(l));
256         }
257
258 void BN_clear_free(BIGNUM *a)
259         {
260         int i;
261
262         if (a == NULL) return;
263         if (a->d != NULL)
264                 {
265                 memset(a->d,0,a->dmax*sizeof(a->d[0]));
266                 if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
267                         OPENSSL_free(a->d);
268                 }
269         i=BN_get_flags(a,BN_FLG_MALLOCED);
270         memset(a,0,sizeof(BIGNUM));
271         if (i)
272                 OPENSSL_free(a);
273         }
274
275 void BN_free(BIGNUM *a)
276         {
277         if (a == NULL) return;
278         if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
279                 OPENSSL_free(a->d);
280         a->flags|=BN_FLG_FREE; /* REMOVE? */
281         if (a->flags & BN_FLG_MALLOCED)
282                 OPENSSL_free(a);
283         }
284
285 void BN_init(BIGNUM *a)
286         {
287         memset(a,0,sizeof(BIGNUM));
288         }
289
290 BIGNUM *BN_new(void)
291         {
292         BIGNUM *ret;
293
294         if ((ret=(BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL)
295                 {
296                 BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
297                 return(NULL);
298                 }
299         ret->flags=BN_FLG_MALLOCED;
300         ret->top=0;
301         ret->neg=0;
302         ret->dmax=0;
303         ret->d=NULL;
304         return(ret);
305         }
306
307 /* This is an internal function that should not be used in applications.
308  * It ensures that 'b' has enough room for a 'words' word number number.
309  * It is mostly used by the various BIGNUM routines. If there is an error,
310  * NULL is returned. If not, 'b' is returned. */
311
312 BIGNUM *bn_expand2(BIGNUM *b, int words)
313         {
314         BN_ULONG *A,*a;
315         const BN_ULONG *B;
316         int i;
317
318         bn_check_top(b);
319
320         if (words > b->dmax)
321                 {
322                 if (words > (INT_MAX/(4*BN_BITS2)))
323                         {
324                         BNerr(BN_F_BN_EXPAND2,BN_R_TOO_LARGE);
325                         return NULL;
326                         }
327                         
328                 bn_check_top(b);        
329                 if (BN_get_flags(b,BN_FLG_STATIC_DATA))
330                         {
331                         BNerr(BN_F_BN_EXPAND2,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
332                         return(NULL);
333                         }
334                 a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*(words+1));
335                 if (A == NULL)
336                         {
337                         BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE);
338                         return(NULL);
339                         }
340 #if 1
341                 B=b->d;
342                 /* Check if the previous number needs to be copied */
343                 if (B != NULL)
344                         {
345 #if 0
346                         /* This lot is an unrolled loop to copy b->top 
347                          * BN_ULONGs from B to A
348                          */
349 /*
350  * I have nothing against unrolling but it's usually done for
351  * several reasons, namely:
352  * - minimize percentage of decision making code, i.e. branches;
353  * - avoid cache trashing;
354  * - make it possible to schedule loads earlier;
355  * Now let's examine the code below. The cornerstone of C is
356  * "programmer is always right" and that's what we love it for:-)
357  * For this very reason C compilers have to be paranoid when it
358  * comes to data aliasing and assume the worst. Yeah, but what
359  * does it mean in real life? This means that loop body below will
360  * be compiled to sequence of loads immediately followed by stores
361  * as compiler assumes the worst, something in A==B+1 style. As a
362  * result CPU pipeline is going to starve for incoming data. Secondly
363  * if A and B happen to share same cache line such code is going to
364  * cause severe cache trashing. Both factors have severe impact on
365  * performance of modern CPUs and this is the reason why this
366  * particular piece of code is #ifdefed away and replaced by more
367  * "friendly" version found in #else section below. This comment
368  * also applies to BN_copy function.
369  *
370  *                                      <appro@fy.chalmers.se>
371  */
372                         for (i=b->top&(~7); i>0; i-=8)
373                                 {
374                                 A[0]=B[0]; A[1]=B[1]; A[2]=B[2]; A[3]=B[3];
375                                 A[4]=B[4]; A[5]=B[5]; A[6]=B[6]; A[7]=B[7];
376                                 A+=8;
377                                 B+=8;
378                                 }
379                         switch (b->top&7)
380                                 {
381                         case 7:
382                                 A[6]=B[6];
383                         case 6:
384                                 A[5]=B[5];
385                         case 5:
386                                 A[4]=B[4];
387                         case 4:
388                                 A[3]=B[3];
389                         case 3:
390                                 A[2]=B[2];
391                         case 2:
392                                 A[1]=B[1];
393                         case 1:
394                                 A[0]=B[0];
395                         case 0:
396                                 /* I need the 'case 0' entry for utrix cc.
397                                  * If the optimizer is turned on, it does the
398                                  * switch table by doing
399                                  * a=top&7
400                                  * a--;
401                                  * goto jump_table[a];
402                                  * If top is 0, this makes us jump to 0xffffffc 
403                                  * which is rather bad :-(.
404                                  * eric 23-Apr-1998
405                                  */
406                                 ;
407                                 }
408 #else
409                         for (i=b->top>>2; i>0; i--,A+=4,B+=4)
410                                 {
411                                 /*
412                                  * The fact that the loop is unrolled
413                                  * 4-wise is a tribute to Intel. It's
414                                  * the one that doesn't have enough
415                                  * registers to accomodate more data.
416                                  * I'd unroll it 8-wise otherwise:-)
417                                  *
418                                  *              <appro@fy.chalmers.se>
419                                  */
420                                 BN_ULONG a0,a1,a2,a3;
421                                 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
422                                 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
423                                 }
424                         switch (b->top&3)
425                                 {
426                                 case 3: A[2]=B[2];
427                                 case 2: A[1]=B[1];
428                                 case 1: A[0]=B[0];
429                                 case 0: ; /* ultrix cc workaround, see above */
430                                 }
431 #endif
432                         OPENSSL_free(b->d);
433                         }
434
435                 b->d=a;
436                 b->dmax=words;
437
438                 /* Now need to zero any data between b->top and b->max */
439
440                 A= &(b->d[b->top]);
441                 for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
442                         {
443                         A[0]=0; A[1]=0; A[2]=0; A[3]=0;
444                         A[4]=0; A[5]=0; A[6]=0; A[7]=0;
445                         }
446                 for (i=(b->dmax - b->top)&7; i>0; i--,A++)
447                         A[0]=0;
448 #else
449                         memset(A,0,sizeof(BN_ULONG)*(words+1));
450                         memcpy(A,b->d,sizeof(b->d[0])*b->top);
451                         b->d=a;
452                         b->max=words;
453 #endif
454                 
455 /*              memset(&(p[b->max]),0,((words+1)-b->max)*sizeof(BN_ULONG)); */
456 /*      { int i; for (i=b->max; i<words+1; i++) p[i]=i;} */
457
458                 }
459         return(b);
460         }
461
462 BIGNUM *BN_dup(const BIGNUM *a)
463         {
464         BIGNUM *r;
465
466         if (a == NULL) return NULL;
467
468         bn_check_top(a);
469
470         r=BN_new();
471         if (r == NULL) return(NULL);
472         return((BIGNUM *)BN_copy(r,a));
473         }
474
475 BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
476         {
477         int i;
478         BN_ULONG *A;
479         const BN_ULONG *B;
480
481         bn_check_top(b);
482
483         if (a == b) return(a);
484         if (bn_wexpand(a,b->top) == NULL) return(NULL);
485
486 #if 1
487         A=a->d;
488         B=b->d;
489         for (i=b->top>>2; i>0; i--,A+=4,B+=4)
490                 {
491                 BN_ULONG a0,a1,a2,a3;
492                 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
493                 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
494                 }
495         switch (b->top&3)
496                 {
497                 case 3: A[2]=B[2];
498                 case 2: A[1]=B[1];
499                 case 1: A[0]=B[0];
500                 case 0: ; /* ultrix cc workaround, see comments in bn_expand2 */
501                 }
502 #else
503         memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
504 #endif
505
506 /*      memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
507         a->top=b->top;
508         if ((a->top == 0) && (a->d != NULL))
509                 a->d[0]=0;
510         a->neg=b->neg;
511         return(a);
512         }
513
514 void BN_clear(BIGNUM *a)
515         {
516         if (a->d != NULL)
517                 memset(a->d,0,a->dmax*sizeof(a->d[0]));
518         a->top=0;
519         a->neg=0;
520         }
521
522 BN_ULONG BN_get_word(BIGNUM *a)
523         {
524         int i,n;
525         BN_ULONG ret=0;
526
527         n=BN_num_bytes(a);
528         if (n > sizeof(BN_ULONG))
529                 return(BN_MASK2);
530         for (i=a->top-1; i>=0; i--)
531                 {
532 #ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
533                 ret<<=BN_BITS4; /* stops the compiler complaining */
534                 ret<<=BN_BITS4;
535 #else
536                 ret=0;
537 #endif
538                 ret|=a->d[i];
539                 }
540         return(ret);
541         }
542
543 int BN_set_word(BIGNUM *a, BN_ULONG w)
544         {
545         int i,n;
546         if (bn_expand(a,sizeof(BN_ULONG)*8) == NULL) return(0);
547
548         n=sizeof(BN_ULONG)/BN_BYTES;
549         a->neg=0;
550         a->top=0;
551         a->d[0]=(BN_ULONG)w&BN_MASK2;
552         if (a->d[0] != 0) a->top=1;
553         for (i=1; i<n; i++)
554                 {
555                 /* the following is done instead of
556                  * w>>=BN_BITS2 so compilers don't complain
557                  * on builds where sizeof(long) == BN_TYPES */
558 #ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
559                 w>>=BN_BITS4;
560                 w>>=BN_BITS4;
561 #else
562                 w=0;
563 #endif
564                 a->d[i]=(BN_ULONG)w&BN_MASK2;
565                 if (a->d[i] != 0) a->top=i+1;
566                 }
567         return(1);
568         }
569
570 /* ignore negative */
571 BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
572         {
573         unsigned int i,m;
574         unsigned int n;
575         BN_ULONG l;
576
577         if (ret == NULL) ret=BN_new();
578         if (ret == NULL) return(NULL);
579         l=0;
580         n=len;
581         if (n == 0)
582                 {
583                 ret->top=0;
584                 return(ret);
585                 }
586         if (bn_expand(ret,(int)(n+2)*8) == NULL)
587                 return(NULL);
588         i=((n-1)/BN_BYTES)+1;
589         m=((n-1)%(BN_BYTES));
590         ret->top=i;
591         while (n-- > 0)
592                 {
593                 l=(l<<8L)| *(s++);
594                 if (m-- == 0)
595                         {
596                         ret->d[--i]=l;
597                         l=0;
598                         m=BN_BYTES-1;
599                         }
600                 }
601         /* need to call this due to clear byte at top if avoiding
602          * having the top bit set (-ve number) */
603         bn_fix_top(ret);
604         return(ret);
605         }
606
607 /* ignore negative */
608 int BN_bn2bin(const BIGNUM *a, unsigned char *to)
609         {
610         int n,i;
611         BN_ULONG l;
612
613         n=i=BN_num_bytes(a);
614         while (i-- > 0)
615                 {
616                 l=a->d[i/BN_BYTES];
617                 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
618                 }
619         return(n);
620         }
621
622 int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
623         {
624         int i;
625         BN_ULONG t1,t2,*ap,*bp;
626
627         bn_check_top(a);
628         bn_check_top(b);
629
630         i=a->top-b->top;
631         if (i != 0) return(i);
632         ap=a->d;
633         bp=b->d;
634         for (i=a->top-1; i>=0; i--)
635                 {
636                 t1= ap[i];
637                 t2= bp[i];
638                 if (t1 != t2)
639                         return(t1 > t2?1:-1);
640                 }
641         return(0);
642         }
643
644 int BN_cmp(const BIGNUM *a, const BIGNUM *b)
645         {
646         int i;
647         int gt,lt;
648         BN_ULONG t1,t2;
649
650         if ((a == NULL) || (b == NULL))
651                 {
652                 if (a != NULL)
653                         return(-1);
654                 else if (b != NULL)
655                         return(1);
656                 else
657                         return(0);
658                 }
659
660         bn_check_top(a);
661         bn_check_top(b);
662
663         if (a->neg != b->neg)
664                 {
665                 if (a->neg)
666                         return(-1);
667                 else    return(1);
668                 }
669         if (a->neg == 0)
670                 { gt=1; lt= -1; }
671         else    { gt= -1; lt=1; }
672
673         if (a->top > b->top) return(gt);
674         if (a->top < b->top) return(lt);
675         for (i=a->top-1; i>=0; i--)
676                 {
677                 t1=a->d[i];
678                 t2=b->d[i];
679                 if (t1 > t2) return(gt);
680                 if (t1 < t2) return(lt);
681                 }
682         return(0);
683         }
684
685 int BN_set_bit(BIGNUM *a, int n)
686         {
687         int i,j,k;
688
689         i=n/BN_BITS2;
690         j=n%BN_BITS2;
691         if (a->top <= i)
692                 {
693                 if (bn_wexpand(a,i+1) == NULL) return(0);
694                 for(k=a->top; k<i+1; k++)
695                         a->d[k]=0;
696                 a->top=i+1;
697                 }
698
699         a->d[i]|=(((BN_ULONG)1)<<j);
700         return(1);
701         }
702
703 int BN_clear_bit(BIGNUM *a, int n)
704         {
705         int i,j;
706
707         i=n/BN_BITS2;
708         j=n%BN_BITS2;
709         if (a->top <= i) return(0);
710
711         a->d[i]&=(~(((BN_ULONG)1)<<j));
712         bn_fix_top(a);
713         return(1);
714         }
715
716 int BN_is_bit_set(const BIGNUM *a, int n)
717         {
718         int i,j;
719
720         if (n < 0) return(0);
721         i=n/BN_BITS2;
722         j=n%BN_BITS2;
723         if (a->top <= i) return(0);
724         return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
725         }
726
727 int BN_mask_bits(BIGNUM *a, int n)
728         {
729         int b,w;
730
731         w=n/BN_BITS2;
732         b=n%BN_BITS2;
733         if (w >= a->top) return(0);
734         if (b == 0)
735                 a->top=w;
736         else
737                 {
738                 a->top=w+1;
739                 a->d[w]&= ~(BN_MASK2<<b);
740                 }
741         bn_fix_top(a);
742         return(1);
743         }
744
745 int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n)
746         {
747         int i;
748         BN_ULONG aa,bb;
749
750         aa=a[n-1];
751         bb=b[n-1];
752         if (aa != bb) return((aa > bb)?1:-1);
753         for (i=n-2; i>=0; i--)
754                 {
755                 aa=a[i];
756                 bb=b[i];
757                 if (aa != bb) return((aa > bb)?1:-1);
758                 }
759         return(0);
760         }
761