Fix warnings in expspeed.c (but the segmentation fault remains)
[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 used both by bn_expand2() and bn_dup_expand() */
308 /* The caller MUST check that words > b->dmax before calling this */
309 static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
310         {
311         BN_ULONG *A,*a = NULL;
312         const BN_ULONG *B;
313         int i;
314
315         bn_check_top(b);        
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+1));
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         /* Now need to zero any data between b->top and b->max */
360         /* XXX Why? */
361
362         A= &(a[b->top]);
363         for (i=(words - b->top)>>3; i>0; i--,A+=8)
364                 {
365                 A[0]=0; A[1]=0; A[2]=0; A[3]=0;
366                 A[4]=0; A[5]=0; A[6]=0; A[7]=0;
367                 }
368         for (i=(words - b->top)&7; i>0; i--,A++)
369                 A[0]=0;
370 #else
371         memset(A,0,sizeof(BN_ULONG)*(words+1));
372         memcpy(A,b->d,sizeof(b->d[0])*b->top);
373 #endif
374                 
375         return(a);
376         }
377
378 /* This is an internal function that can be used instead of bn_expand2()
379  * when there is a need to copy BIGNUMs instead of only expanding the
380  * data part, while still expanding them.
381  * Especially useful when needing to expand BIGNUMs that are declared
382  * 'const' and should therefore not be changed.
383  * The reason to use this instead of a BN_dup() followed by a bn_expand2()
384  * is memory allocation overhead.  A BN_dup() followed by a bn_expand2()
385  * will allocate new memory for the BIGNUM data twice, and free it once,
386  * while bn_dup_expand() makes sure allocation is made only once.
387  */
388
389 BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
390         {
391         BIGNUM *r = NULL;
392
393         if (words > b->dmax)
394                 {
395                 BN_ULONG *a = bn_expand_internal(b, words);
396
397                 if (a)
398                         {
399                         r = BN_new();
400                         if (r)
401                                 {
402                                 r->top = b->top;
403                                 r->dmax = words;
404                                 r->neg = b->neg;
405                                 r->d = a;
406                                 }
407                         else
408                                 {
409                                 /* r == NULL, BN_new failure */
410                                 OPENSSL_free(a);
411                                 }
412                         }
413                 /* If a == NULL, there was an error in allocation in
414                    bn_expand_internal(), and NULL should be returned */
415                 }
416         else
417                 {
418                 r = BN_dup(b);
419                 }
420
421         return r;
422         }
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 number.
426  * It is mostly used by the various BIGNUM routines. If there is an error,
427  * NULL is returned. If not, 'b' is returned. */
428
429 BIGNUM *bn_expand2(BIGNUM *b, int words)
430         {
431         if (words > b->dmax)
432                 {
433                 BN_ULONG *a = bn_expand_internal(b, words);
434
435                 if (a)
436                         {
437                         if (b->d)
438                                 OPENSSL_free(b->d);
439                         b->d=a;
440                         b->dmax=words;
441                         }
442                 else
443                         b = NULL;
444                 }
445         return b;
446         }
447
448 BIGNUM *BN_dup(const BIGNUM *a)
449         {
450         BIGNUM *r, *t;
451
452         if (a == NULL) return NULL;
453
454         bn_check_top(a);
455
456         t = BN_new();
457         if (t == NULL) return(NULL);
458         r = BN_copy(t, a);
459         /* now  r == t || r == NULL */
460         if (r == NULL)
461                 BN_free(t);
462         return r;
463         }
464
465 BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
466         {
467         int i;
468         BN_ULONG *A;
469         const BN_ULONG *B;
470
471         bn_check_top(b);
472
473         if (a == b) return(a);
474         if (bn_wexpand(a,b->top) == NULL) return(NULL);
475
476 #if 1
477         A=a->d;
478         B=b->d;
479         for (i=b->top>>2; i>0; i--,A+=4,B+=4)
480                 {
481                 BN_ULONG a0,a1,a2,a3;
482                 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
483                 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
484                 }
485         switch (b->top&3)
486                 {
487                 case 3: A[2]=B[2];
488                 case 2: A[1]=B[1];
489                 case 1: A[0]=B[0];
490                 case 0: ; /* ultrix cc workaround, see comments in bn_expand_internal */
491                 }
492 #else
493         memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
494 #endif
495
496 /*      memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
497         a->top=b->top;
498         if ((a->top == 0) && (a->d != NULL))
499                 a->d[0]=0;
500         a->neg=b->neg;
501         return(a);
502         }
503
504 void BN_swap(BIGNUM *a, BIGNUM *b)
505         {
506         int flags_old_a, flags_old_b;
507         BN_ULONG *tmp_d;
508         int tmp_top, tmp_dmax, tmp_neg;
509         
510         flags_old_a = a->flags;
511         flags_old_b = b->flags;
512
513         tmp_d = a->d;
514         tmp_top = a->top;
515         tmp_dmax = a->dmax;
516         tmp_neg = a->neg;
517         
518         a->d = b->d;
519         a->top = b->top;
520         a->dmax = b->dmax;
521         a->neg = b->neg;
522         
523         b->d = tmp_d;
524         b->top = tmp_top;
525         b->dmax = tmp_dmax;
526         b->neg = tmp_neg;
527         
528         a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
529         b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
530         }
531
532
533 void BN_clear(BIGNUM *a)
534         {
535         if (a->d != NULL)
536                 memset(a->d,0,a->dmax*sizeof(a->d[0]));
537         a->top=0;
538         a->neg=0;
539         }
540
541 BN_ULONG BN_get_word(const BIGNUM *a)
542         {
543         int i,n;
544         BN_ULONG ret=0;
545
546         n=BN_num_bytes(a);
547         if (n > sizeof(BN_ULONG))
548                 return(BN_MASK2);
549         for (i=a->top-1; i>=0; i--)
550                 {
551 #ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
552                 ret<<=BN_BITS4; /* stops the compiler complaining */
553                 ret<<=BN_BITS4;
554 #else
555                 ret=0;
556 #endif
557                 ret|=a->d[i];
558                 }
559         return(ret);
560         }
561
562 int BN_set_word(BIGNUM *a, BN_ULONG w)
563         {
564         int i,n;
565         if (bn_expand(a,sizeof(BN_ULONG)*8) == NULL) return(0);
566
567         n=sizeof(BN_ULONG)/BN_BYTES;
568         a->neg=0;
569         a->top=0;
570         a->d[0]=(BN_ULONG)w&BN_MASK2;
571         if (a->d[0] != 0) a->top=1;
572         for (i=1; i<n; i++)
573                 {
574                 /* the following is done instead of
575                  * w>>=BN_BITS2 so compilers don't complain
576                  * on builds where sizeof(long) == BN_TYPES */
577 #ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
578                 w>>=BN_BITS4;
579                 w>>=BN_BITS4;
580 #else
581                 w=0;
582 #endif
583                 a->d[i]=(BN_ULONG)w&BN_MASK2;
584                 if (a->d[i] != 0) a->top=i+1;
585                 }
586         return(1);
587         }
588
589 BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
590         {
591         unsigned int i,m;
592         unsigned int n;
593         BN_ULONG l;
594
595         if (ret == NULL) ret=BN_new();
596         if (ret == NULL) return(NULL);
597         l=0;
598         n=len;
599         if (n == 0)
600                 {
601                 ret->top=0;
602                 return(ret);
603                 }
604         if (bn_expand(ret,(int)(n+2)*8) == NULL)
605                 return(NULL);
606         i=((n-1)/BN_BYTES)+1;
607         m=((n-1)%(BN_BYTES));
608         ret->top=i;
609         ret->neg=0;
610         while (n-- > 0)
611                 {
612                 l=(l<<8L)| *(s++);
613                 if (m-- == 0)
614                         {
615                         ret->d[--i]=l;
616                         l=0;
617                         m=BN_BYTES-1;
618                         }
619                 }
620         /* need to call this due to clear byte at top if avoiding
621          * having the top bit set (-ve number) */
622         bn_fix_top(ret);
623         return(ret);
624         }
625
626 /* ignore negative */
627 int BN_bn2bin(const BIGNUM *a, unsigned char *to)
628         {
629         int n,i;
630         BN_ULONG l;
631
632         n=i=BN_num_bytes(a);
633         while (i-- > 0)
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         i=n/BN_BITS2;
709         j=n%BN_BITS2;
710         if (a->top <= i)
711                 {
712                 if (bn_wexpand(a,i+1) == NULL) return(0);
713                 for(k=a->top; k<i+1; k++)
714                         a->d[k]=0;
715                 a->top=i+1;
716                 }
717
718         a->d[i]|=(((BN_ULONG)1)<<j);
719         return(1);
720         }
721
722 int BN_clear_bit(BIGNUM *a, int n)
723         {
724         int i,j;
725
726         i=n/BN_BITS2;
727         j=n%BN_BITS2;
728         if (a->top <= i) return(0);
729
730         a->d[i]&=(~(((BN_ULONG)1)<<j));
731         bn_fix_top(a);
732         return(1);
733         }
734
735 int BN_is_bit_set(const BIGNUM *a, int n)
736         {
737         int i,j;
738
739         if (n < 0) return(0);
740         i=n/BN_BITS2;
741         j=n%BN_BITS2;
742         if (a->top <= i) return(0);
743         return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
744         }
745
746 int BN_mask_bits(BIGNUM *a, int n)
747         {
748         int b,w;
749
750         w=n/BN_BITS2;
751         b=n%BN_BITS2;
752         if (w >= a->top) return(0);
753         if (b == 0)
754                 a->top=w;
755         else
756                 {
757                 a->top=w+1;
758                 a->d[w]&= ~(BN_MASK2<<b);
759                 }
760         bn_fix_top(a);
761         return(1);
762         }
763
764 int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
765         {
766         int i;
767         BN_ULONG aa,bb;
768
769         aa=a[n-1];
770         bb=b[n-1];
771         if (aa != bb) return((aa > bb)?1:-1);
772         for (i=n-2; i>=0; i--)
773                 {
774                 aa=a[i];
775                 bb=b[i];
776                 if (aa != bb) return((aa > bb)?1:-1);
777                 }
778         return(0);
779         }