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