Under VMS, ftruncate should be available
[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         if (a == NULL) return NULL;
493
494         bn_check_top(a);
495
496         r=BN_new();
497         if (r == NULL) return(NULL);
498         return((BIGNUM *)BN_copy(r,a));
499         }
500
501 BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
502         {
503         int i;
504         BN_ULONG *A;
505         const BN_ULONG *B;
506
507         bn_check_top(b);
508
509         if (a == b) return(a);
510         if (bn_wexpand(a,b->top) == NULL) return(NULL);
511
512 #if 1
513         A=a->d;
514         B=b->d;
515         for (i=b->top>>2; i>0; i--,A+=4,B+=4)
516                 {
517                 BN_ULONG a0,a1,a2,a3;
518                 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
519                 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
520                 }
521         switch (b->top&3)
522                 {
523                 case 3: A[2]=B[2];
524                 case 2: A[1]=B[1];
525                 case 1: A[0]=B[0];
526                 case 0: ; /* ultrix cc workaround, see comments in bn_expand2 */
527                 }
528 #else
529         memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
530 #endif
531
532 /*      memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
533         a->top=b->top;
534         if ((a->top == 0) && (a->d != NULL))
535                 a->d[0]=0;
536         a->neg=b->neg;
537         return(a);
538         }
539
540 void BN_clear(BIGNUM *a)
541         {
542         if (a->d != NULL)
543                 memset(a->d,0,a->max*sizeof(a->d[0]));
544         a->top=0;
545         a->neg=0;
546         }
547
548 BN_ULONG BN_get_word(BIGNUM *a)
549         {
550         int i,n;
551         BN_ULONG ret=0;
552
553         n=BN_num_bytes(a);
554         if (n > sizeof(BN_ULONG))
555                 return(BN_MASK2);
556         for (i=a->top-1; i>=0; i--)
557                 {
558 #ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
559                 ret<<=BN_BITS4; /* stops the compiler complaining */
560                 ret<<=BN_BITS4;
561 #else
562                 ret=0;
563 #endif
564                 ret|=a->d[i];
565                 }
566         return(ret);
567         }
568
569 int BN_set_word(BIGNUM *a, BN_ULONG w)
570         {
571         int i,n;
572         if (bn_expand(a,sizeof(BN_ULONG)*8) == NULL) return(0);
573
574         n=sizeof(BN_ULONG)/BN_BYTES;
575         a->neg=0;
576         a->top=0;
577         a->d[0]=(BN_ULONG)w&BN_MASK2;
578         if (a->d[0] != 0) a->top=1;
579         for (i=1; i<n; i++)
580                 {
581                 /* the following is done instead of
582                  * w>>=BN_BITS2 so compilers don't complain
583                  * on builds where sizeof(long) == BN_TYPES */
584 #ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
585                 w>>=BN_BITS4;
586                 w>>=BN_BITS4;
587 #else
588                 w=0;
589 #endif
590                 a->d[i]=(BN_ULONG)w&BN_MASK2;
591                 if (a->d[i] != 0) a->top=i+1;
592                 }
593         return(1);
594         }
595
596 /* ignore negative */
597 BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
598         {
599         unsigned int i,m;
600         unsigned int n;
601         BN_ULONG l;
602
603         if (ret == NULL) ret=BN_new();
604         if (ret == NULL) return(NULL);
605         l=0;
606         n=len;
607         if (n == 0)
608                 {
609                 ret->top=0;
610                 return(ret);
611                 }
612         if (bn_expand(ret,(int)(n+2)*8) == NULL)
613                 return(NULL);
614         i=((n-1)/BN_BYTES)+1;
615         m=((n-1)%(BN_BYTES));
616         ret->top=i;
617         while (n-- > 0)
618                 {
619                 l=(l<<8L)| *(s++);
620                 if (m-- == 0)
621                         {
622                         ret->d[--i]=l;
623                         l=0;
624                         m=BN_BYTES-1;
625                         }
626                 }
627         /* need to call this due to clear byte at top if avoiding
628          * having the top bit set (-ve number) */
629         bn_fix_top(ret);
630         return(ret);
631         }
632
633 /* ignore negative */
634 int BN_bn2bin(const BIGNUM *a, unsigned char *to)
635         {
636         int n,i;
637         BN_ULONG l;
638
639         n=i=BN_num_bytes(a);
640         while (i-- > 0)
641                 {
642                 l=a->d[i/BN_BYTES];
643                 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
644                 }
645         return(n);
646         }
647
648 int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
649         {
650         int i;
651         BN_ULONG t1,t2,*ap,*bp;
652
653         bn_check_top(a);
654         bn_check_top(b);
655
656         i=a->top-b->top;
657         if (i != 0) return(i);
658         ap=a->d;
659         bp=b->d;
660         for (i=a->top-1; i>=0; i--)
661                 {
662                 t1= ap[i];
663                 t2= bp[i];
664                 if (t1 != t2)
665                         return(t1 > t2?1:-1);
666                 }
667         return(0);
668         }
669
670 int BN_cmp(const BIGNUM *a, const BIGNUM *b)
671         {
672         int i;
673         int gt,lt;
674         BN_ULONG t1,t2;
675
676         if ((a == NULL) || (b == NULL))
677                 {
678                 if (a != NULL)
679                         return(-1);
680                 else if (b != NULL)
681                         return(1);
682                 else
683                         return(0);
684                 }
685
686         bn_check_top(a);
687         bn_check_top(b);
688
689         if (a->neg != b->neg)
690                 {
691                 if (a->neg)
692                         return(-1);
693                 else    return(1);
694                 }
695         if (a->neg == 0)
696                 { gt=1; lt= -1; }
697         else    { gt= -1; lt=1; }
698
699         if (a->top > b->top) return(gt);
700         if (a->top < b->top) return(lt);
701         for (i=a->top-1; i>=0; i--)
702                 {
703                 t1=a->d[i];
704                 t2=b->d[i];
705                 if (t1 > t2) return(gt);
706                 if (t1 < t2) return(lt);
707                 }
708         return(0);
709         }
710
711 int BN_set_bit(BIGNUM *a, int n)
712         {
713         int i,j,k;
714
715         i=n/BN_BITS2;
716         j=n%BN_BITS2;
717         if (a->top <= i)
718                 {
719                 if (bn_wexpand(a,i+1) == NULL) return(0);
720                 for(k=a->top; k<i+1; k++)
721                         a->d[k]=0;
722                 a->top=i+1;
723                 }
724
725         a->d[i]|=(((BN_ULONG)1)<<j);
726         return(1);
727         }
728
729 int BN_clear_bit(BIGNUM *a, int n)
730         {
731         int i,j;
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_fix_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         if (n < 0) return(0);
747         i=n/BN_BITS2;
748         j=n%BN_BITS2;
749         if (a->top <= i) return(0);
750         return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
751         }
752
753 int BN_mask_bits(BIGNUM *a, int n)
754         {
755         int b,w;
756
757         w=n/BN_BITS2;
758         b=n%BN_BITS2;
759         if (w >= a->top) return(0);
760         if (b == 0)
761                 a->top=w;
762         else
763                 {
764                 a->top=w+1;
765                 a->d[w]&= ~(BN_MASK2<<b);
766                 }
767         bn_fix_top(a);
768         return(1);
769         }
770
771 int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n)
772         {
773         int i;
774         BN_ULONG aa,bb;
775
776         aa=a[n-1];
777         bb=b[n-1];
778         if (aa != bb) return((aa > bb)?1:-1);
779         for (i=n-2; i>=0; i--)
780                 {
781                 aa=a[i];
782                 bb=b[i];
783                 if (aa != bb) return((aa > bb)?1:-1);
784                 }
785         return(0);
786         }
787