ispell (and minor modifications)
[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 /* This is an internal function that should not be used in applications.
345  * It ensures that 'b' has enough room for a 'bits' bit number.  It is
346  * mostly used by the various BIGNUM routines.  If there is an error,
347  * NULL is returned. if not, 'b' is returned.
348  */
349 BIGNUM *bn_expand2(BIGNUM *b, int words)
350         {
351         BN_ULONG *A,*a;
352         const BN_ULONG *B;
353         int i;
354
355         bn_check_top(b);
356
357         if (words > b->max)
358                 {
359                 bn_check_top(b);        
360                 if (BN_get_flags(b,BN_FLG_STATIC_DATA))
361                         {
362                         BNerr(BN_F_BN_EXPAND2,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
363                         return(NULL);
364                         }
365                 a=A=(BN_ULONG *)Malloc(sizeof(BN_ULONG)*(words+1));
366                 if (A == NULL)
367                         {
368                         BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE);
369                         return(NULL);
370                         }
371 #if 1
372                 B=b->d;
373                 /* Check if the previous number needs to be copied */
374                 if (B != NULL)
375                         {
376 #if 0
377                         /* This lot is an unrolled loop to copy b->top 
378                          * BN_ULONGs from B to A
379                          */
380 /*
381  * I have nothing against unrolling but it's usually done for
382  * several reasons, namely:
383  * - minimize percentage of decision making code, i.e. branches;
384  * - avoid cache trashing;
385  * - make it possible to schedule loads earlier;
386  * Now let's examine the code below. The cornerstone of C is
387  * "programmer is always right" and that's what we love it for:-)
388  * For this very reason C compilers have to be paranoid when it
389  * comes to data aliasing and assume the worst. Yeah, but what
390  * does it mean in real life? This means that loop body below will
391  * be compiled to sequence of loads immediately followed by stores
392  * as compiler assumes the worst, something in A==B+1 style. As a
393  * result CPU pipeline is going to starve for incoming data. Secondly
394  * if A and B happen to share same cache line such code is going to
395  * cause severe cache trashing. Both factors have severe impact on
396  * performance of modern CPUs and this is the reason why this
397  * particular piece of code is #ifdefed away and replaced by more
398  * "friendly" version found in #else section below. This comment
399  * also applies to BN_copy function.
400  *
401  *                                      <appro@fy.chalmers.se>
402  */
403                         for (i=b->top&(~7); i>0; i-=8)
404                                 {
405                                 A[0]=B[0]; A[1]=B[1]; A[2]=B[2]; A[3]=B[3];
406                                 A[4]=B[4]; A[5]=B[5]; A[6]=B[6]; A[7]=B[7];
407                                 A+=8;
408                                 B+=8;
409                                 }
410                         switch (b->top&7)
411                                 {
412                         case 7:
413                                 A[6]=B[6];
414                         case 6:
415                                 A[5]=B[5];
416                         case 5:
417                                 A[4]=B[4];
418                         case 4:
419                                 A[3]=B[3];
420                         case 3:
421                                 A[2]=B[2];
422                         case 2:
423                                 A[1]=B[1];
424                         case 1:
425                                 A[0]=B[0];
426                         case 0:
427                                 /* I need the 'case 0' entry for utrix cc.
428                                  * If the optimizer is turned on, it does the
429                                  * switch table by doing
430                                  * a=top&7
431                                  * a--;
432                                  * goto jump_table[a];
433                                  * If top is 0, this makes us jump to 0xffffffc 
434                                  * which is rather bad :-(.
435                                  * eric 23-Apr-1998
436                                  */
437                                 ;
438                                 }
439 #else
440                         for (i=b->top>>2; i>0; i--,A+=4,B+=4)
441                                 {
442                                 /*
443                                  * The fact that the loop is unrolled
444                                  * 4-wise is a tribute to Intel. It's
445                                  * the one that doesn't have enough
446                                  * registers to accomodate more data.
447                                  * I'd unroll it 8-wise otherwise:-)
448                                  *
449                                  *              <appro@fy.chalmers.se>
450                                  */
451                                 BN_ULONG a0,a1,a2,a3;
452                                 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
453                                 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
454                                 }
455                         switch (b->top&3)
456                                 {
457                                 case 3: A[2]=B[2];
458                                 case 2: A[1]=B[1];
459                                 case 1: A[0]=B[0];
460                                 case 0: ; /* ultrix cc workaround, see above */
461                                 }
462 #endif
463                         Free(b->d);
464                         }
465
466                 b->d=a;
467                 b->max=words;
468
469                 /* Now need to zero any data between b->top and b->max */
470
471                 A= &(b->d[b->top]);
472                 for (i=(b->max - b->top)>>3; i>0; i--,A+=8)
473                         {
474                         A[0]=0; A[1]=0; A[2]=0; A[3]=0;
475                         A[4]=0; A[5]=0; A[6]=0; A[7]=0;
476                         }
477                 for (i=(b->max - b->top)&7; i>0; i--,A++)
478                         A[0]=0;
479 #else
480                         memset(A,0,sizeof(BN_ULONG)*(words+1));
481                         memcpy(A,b->d,sizeof(b->d[0])*b->top);
482                         b->d=a;
483                         b->max=words;
484 #endif
485                 
486 /*              memset(&(p[b->max]),0,((words+1)-b->max)*sizeof(BN_ULONG)); */
487 /*      { int i; for (i=b->max; i<words+1; i++) p[i]=i;} */
488
489                 }
490         return(b);
491         }
492
493 BIGNUM *BN_dup(const BIGNUM *a)
494         {
495         BIGNUM *r;
496
497         if (a == NULL) return NULL;
498
499         bn_check_top(a);
500
501         r=BN_new();
502         if (r == NULL) return(NULL);
503         return((BIGNUM *)BN_copy(r,a));
504         }
505
506 BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
507         {
508         int i;
509         BN_ULONG *A;
510         const BN_ULONG *B;
511
512         bn_check_top(b);
513
514         if (a == b) return(a);
515         if (bn_wexpand(a,b->top) == NULL) return(NULL);
516
517 #if 1
518         A=a->d;
519         B=b->d;
520         for (i=b->top>>2; i>0; i--,A+=4,B+=4)
521                 {
522                 BN_ULONG a0,a1,a2,a3;
523                 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
524                 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
525                 }
526         switch (b->top&3)
527                 {
528                 case 3: A[2]=B[2];
529                 case 2: A[1]=B[1];
530                 case 1: A[0]=B[0];
531                 case 0: ; /* ultrix cc workaround, see comments in bn_expand2 */
532                 }
533 #else
534         memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
535 #endif
536
537 /*      memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
538         a->top=b->top;
539         if ((a->top == 0) && (a->d != NULL))
540                 a->d[0]=0;
541         a->neg=b->neg;
542         return(a);
543         }
544
545 void BN_clear(BIGNUM *a)
546         {
547         if (a->d != NULL)
548                 memset(a->d,0,a->max*sizeof(a->d[0]));
549         a->top=0;
550         a->neg=0;
551         }
552
553 BN_ULONG BN_get_word(BIGNUM *a)
554         {
555         int i,n;
556         BN_ULONG ret=0;
557
558         n=BN_num_bytes(a);
559         if (n > sizeof(BN_ULONG))
560                 return(BN_MASK2);
561         for (i=a->top-1; i>=0; i--)
562                 {
563 #ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
564                 ret<<=BN_BITS4; /* stops the compiler complaining */
565                 ret<<=BN_BITS4;
566 #else
567                 ret=0;
568 #endif
569                 ret|=a->d[i];
570                 }
571         return(ret);
572         }
573
574 int BN_set_word(BIGNUM *a, BN_ULONG w)
575         {
576         int i,n;
577         if (bn_expand(a,sizeof(BN_ULONG)*8) == NULL) return(0);
578
579         n=sizeof(BN_ULONG)/BN_BYTES;
580         a->neg=0;
581         a->top=0;
582         a->d[0]=(BN_ULONG)w&BN_MASK2;
583         if (a->d[0] != 0) a->top=1;
584         for (i=1; i<n; i++)
585                 {
586                 /* the following is done instead of
587                  * w>>=BN_BITS2 so compilers don't complain
588                  * on builds where sizeof(long) == BN_TYPES */
589 #ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
590                 w>>=BN_BITS4;
591                 w>>=BN_BITS4;
592 #else
593                 w=0;
594 #endif
595                 a->d[i]=(BN_ULONG)w&BN_MASK2;
596                 if (a->d[i] != 0) a->top=i+1;
597                 }
598         return(1);
599         }
600
601 /* ignore negative */
602 BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
603         {
604         unsigned int i,m;
605         unsigned int n;
606         BN_ULONG l;
607
608         if (ret == NULL) ret=BN_new();
609         if (ret == NULL) return(NULL);
610         l=0;
611         n=len;
612         if (n == 0)
613                 {
614                 ret->top=0;
615                 return(ret);
616                 }
617         if (bn_expand(ret,(int)(n+2)*8) == NULL)
618                 return(NULL);
619         i=((n-1)/BN_BYTES)+1;
620         m=((n-1)%(BN_BYTES));
621         ret->top=i;
622         while (n-- > 0)
623                 {
624                 l=(l<<8L)| *(s++);
625                 if (m-- == 0)
626                         {
627                         ret->d[--i]=l;
628                         l=0;
629                         m=BN_BYTES-1;
630                         }
631                 }
632         /* need to call this due to clear byte at top if avoiding
633          * having the top bit set (-ve number) */
634         bn_fix_top(ret);
635         return(ret);
636         }
637
638 /* ignore negative */
639 int BN_bn2bin(const BIGNUM *a, unsigned char *to)
640         {
641         int n,i;
642         BN_ULONG l;
643
644         n=i=BN_num_bytes(a);
645         while (i-- > 0)
646                 {
647                 l=a->d[i/BN_BYTES];
648                 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
649                 }
650         return(n);
651         }
652
653 int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
654         {
655         int i;
656         BN_ULONG t1,t2,*ap,*bp;
657
658         bn_check_top(a);
659         bn_check_top(b);
660
661         i=a->top-b->top;
662         if (i != 0) return(i);
663         ap=a->d;
664         bp=b->d;
665         for (i=a->top-1; i>=0; i--)
666                 {
667                 t1= ap[i];
668                 t2= bp[i];
669                 if (t1 != t2)
670                         return(t1 > t2?1:-1);
671                 }
672         return(0);
673         }
674
675 int BN_cmp(const BIGNUM *a, const BIGNUM *b)
676         {
677         int i;
678         int gt,lt;
679         BN_ULONG t1,t2;
680
681         if ((a == NULL) || (b == NULL))
682                 {
683                 if (a != NULL)
684                         return(-1);
685                 else if (b != NULL)
686                         return(1);
687                 else
688                         return(0);
689                 }
690
691         bn_check_top(a);
692         bn_check_top(b);
693
694         if (a->neg != b->neg)
695                 {
696                 if (a->neg)
697                         return(-1);
698                 else    return(1);
699                 }
700         if (a->neg == 0)
701                 { gt=1; lt= -1; }
702         else    { gt= -1; lt=1; }
703
704         if (a->top > b->top) return(gt);
705         if (a->top < b->top) return(lt);
706         for (i=a->top-1; i>=0; i--)
707                 {
708                 t1=a->d[i];
709                 t2=b->d[i];
710                 if (t1 > t2) return(gt);
711                 if (t1 < t2) return(lt);
712                 }
713         return(0);
714         }
715
716 int BN_set_bit(BIGNUM *a, int n)
717         {
718         int i,j,k;
719
720         i=n/BN_BITS2;
721         j=n%BN_BITS2;
722         if (a->top <= i)
723                 {
724                 if (bn_wexpand(a,i+1) == NULL) return(0);
725                 for(k=a->top; k<i+1; k++)
726                         a->d[k]=0;
727                 a->top=i+1;
728                 }
729
730         a->d[i]|=(((BN_ULONG)1)<<j);
731         return(1);
732         }
733
734 int BN_clear_bit(BIGNUM *a, int n)
735         {
736         int i,j;
737
738         i=n/BN_BITS2;
739         j=n%BN_BITS2;
740         if (a->top <= i) return(0);
741
742         a->d[i]&=(~(((BN_ULONG)1)<<j));
743         bn_fix_top(a);
744         return(1);
745         }
746
747 int BN_is_bit_set(const BIGNUM *a, int n)
748         {
749         int i,j;
750
751         if (n < 0) return(0);
752         i=n/BN_BITS2;
753         j=n%BN_BITS2;
754         if (a->top <= i) return(0);
755         return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
756         }
757
758 int BN_mask_bits(BIGNUM *a, int n)
759         {
760         int b,w;
761
762         w=n/BN_BITS2;
763         b=n%BN_BITS2;
764         if (w >= a->top) return(0);
765         if (b == 0)
766                 a->top=w;
767         else
768                 {
769                 a->top=w+1;
770                 a->d[w]&= ~(BN_MASK2<<b);
771                 }
772         bn_fix_top(a);
773         return(1);
774         }
775
776 int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n)
777         {
778         int i;
779         BN_ULONG aa,bb;
780
781         aa=a[n-1];
782         bb=b[n-1];
783         if (aa != bb) return((aa > bb)?1:-1);
784         for (i=n-2; i>=0; i--)
785                 {
786                 aa=a[i];
787                 bb=b[i];
788                 if (aa != bb) return((aa > bb)?1:-1);
789                 }
790         return(0);
791         }
792