Import OpenSSL 0.9.8l
[dragonfly.git] / crypto / openssl / 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 <limits.h>
66 #include <stdio.h>
67 #include "cryptlib.h"
68 #include "bn_lcl.h"
69
70 const char BN_version[]="Big Number" OPENSSL_VERSION_PTEXT;
71
72 /* This stuff appears to be completely unused, so is deprecated */
73 #ifndef OPENSSL_NO_DEPRECATED
74 /* For a 32 bit machine
75  * 2 -   4 ==  128
76  * 3 -   8 ==  256
77  * 4 -  16 ==  512
78  * 5 -  32 == 1024
79  * 6 -  64 == 2048
80  * 7 - 128 == 4096
81  * 8 - 256 == 8192
82  */
83 static int bn_limit_bits=0;
84 static int bn_limit_num=8;        /* (1<<bn_limit_bits) */
85 static int bn_limit_bits_low=0;
86 static int bn_limit_num_low=8;    /* (1<<bn_limit_bits_low) */
87 static int bn_limit_bits_high=0;
88 static int bn_limit_num_high=8;   /* (1<<bn_limit_bits_high) */
89 static int bn_limit_bits_mont=0;
90 static int bn_limit_num_mont=8;   /* (1<<bn_limit_bits_mont) */
91
92 void BN_set_params(int mult, int high, int low, int mont)
93         {
94         if (mult >= 0)
95                 {
96                 if (mult > (int)(sizeof(int)*8)-1)
97                         mult=sizeof(int)*8-1;
98                 bn_limit_bits=mult;
99                 bn_limit_num=1<<mult;
100                 }
101         if (high >= 0)
102                 {
103                 if (high > (int)(sizeof(int)*8)-1)
104                         high=sizeof(int)*8-1;
105                 bn_limit_bits_high=high;
106                 bn_limit_num_high=1<<high;
107                 }
108         if (low >= 0)
109                 {
110                 if (low > (int)(sizeof(int)*8)-1)
111                         low=sizeof(int)*8-1;
112                 bn_limit_bits_low=low;
113                 bn_limit_num_low=1<<low;
114                 }
115         if (mont >= 0)
116                 {
117                 if (mont > (int)(sizeof(int)*8)-1)
118                         mont=sizeof(int)*8-1;
119                 bn_limit_bits_mont=mont;
120                 bn_limit_num_mont=1<<mont;
121                 }
122         }
123
124 int BN_get_params(int which)
125         {
126         if      (which == 0) return(bn_limit_bits);
127         else if (which == 1) return(bn_limit_bits_high);
128         else if (which == 2) return(bn_limit_bits_low);
129         else if (which == 3) return(bn_limit_bits_mont);
130         else return(0);
131         }
132 #endif
133
134 const BIGNUM *BN_value_one(void)
135         {
136         static BN_ULONG data_one=1L;
137         static BIGNUM const_one={&data_one,1,1,0,BN_FLG_STATIC_DATA};
138
139         return(&const_one);
140         }
141
142 int BN_num_bits_word(BN_ULONG l)
143         {
144         static const char bits[256]={
145                 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
146                 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
147                 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
148                 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
149                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
150                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
151                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
152                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
153                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
154                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
155                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
156                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
157                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
158                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
159                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
160                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
161                 };
162
163 #if defined(SIXTY_FOUR_BIT_LONG)
164         if (l & 0xffffffff00000000L)
165                 {
166                 if (l & 0xffff000000000000L)
167                         {
168                         if (l & 0xff00000000000000L)
169                                 {
170                                 return(bits[(int)(l>>56)]+56);
171                                 }
172                         else    return(bits[(int)(l>>48)]+48);
173                         }
174                 else
175                         {
176                         if (l & 0x0000ff0000000000L)
177                                 {
178                                 return(bits[(int)(l>>40)]+40);
179                                 }
180                         else    return(bits[(int)(l>>32)]+32);
181                         }
182                 }
183         else
184 #else
185 #ifdef SIXTY_FOUR_BIT
186         if (l & 0xffffffff00000000LL)
187                 {
188                 if (l & 0xffff000000000000LL)
189                         {
190                         if (l & 0xff00000000000000LL)
191                                 {
192                                 return(bits[(int)(l>>56)]+56);
193                                 }
194                         else    return(bits[(int)(l>>48)]+48);
195                         }
196                 else
197                         {
198                         if (l & 0x0000ff0000000000LL)
199                                 {
200                                 return(bits[(int)(l>>40)]+40);
201                                 }
202                         else    return(bits[(int)(l>>32)]+32);
203                         }
204                 }
205         else
206 #endif
207 #endif
208                 {
209 #if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
210                 if (l & 0xffff0000L)
211                         {
212                         if (l & 0xff000000L)
213                                 return(bits[(int)(l>>24L)]+24);
214                         else    return(bits[(int)(l>>16L)]+16);
215                         }
216                 else
217 #endif
218                         {
219 #if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
220                         if (l & 0xff00L)
221                                 return(bits[(int)(l>>8)]+8);
222                         else    
223 #endif
224                                 return(bits[(int)(l   )]  );
225                         }
226                 }
227         }
228
229 int BN_num_bits(const BIGNUM *a)
230         {
231         int i = a->top - 1;
232         bn_check_top(a);
233
234         if (BN_is_zero(a)) return 0;
235         return ((i*BN_BITS2) + BN_num_bits_word(a->d[i]));
236         }
237
238 void BN_clear_free(BIGNUM *a)
239         {
240         int i;
241
242         if (a == NULL) return;
243         bn_check_top(a);
244         if (a->d != NULL)
245                 {
246                 OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0]));
247                 if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
248                         OPENSSL_free(a->d);
249                 }
250         i=BN_get_flags(a,BN_FLG_MALLOCED);
251         OPENSSL_cleanse(a,sizeof(BIGNUM));
252         if (i)
253                 OPENSSL_free(a);
254         }
255
256 void BN_free(BIGNUM *a)
257         {
258         if (a == NULL) return;
259         bn_check_top(a);
260         if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
261                 OPENSSL_free(a->d);
262         if (a->flags & BN_FLG_MALLOCED)
263                 OPENSSL_free(a);
264         else
265                 {
266 #ifndef OPENSSL_NO_DEPRECATED
267                 a->flags|=BN_FLG_FREE;
268 #endif
269                 a->d = NULL;
270                 }
271         }
272
273 void BN_init(BIGNUM *a)
274         {
275         memset(a,0,sizeof(BIGNUM));
276         bn_check_top(a);
277         }
278
279 BIGNUM *BN_new(void)
280         {
281         BIGNUM *ret;
282
283         if ((ret=(BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL)
284                 {
285                 BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
286                 return(NULL);
287                 }
288         ret->flags=BN_FLG_MALLOCED;
289         ret->top=0;
290         ret->neg=0;
291         ret->dmax=0;
292         ret->d=NULL;
293         bn_check_top(ret);
294         return(ret);
295         }
296
297 /* This is used both by bn_expand2() and bn_dup_expand() */
298 /* The caller MUST check that words > b->dmax before calling this */
299 static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
300         {
301         BN_ULONG *A,*a = NULL;
302         const BN_ULONG *B;
303         int i;
304
305         bn_check_top(b);
306
307         if (words > (INT_MAX/(4*BN_BITS2)))
308                 {
309                 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_BIGNUM_TOO_LONG);
310                 return NULL;
311                 }
312         if (BN_get_flags(b,BN_FLG_STATIC_DATA))
313                 {
314                 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
315                 return(NULL);
316                 }
317         a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*words);
318         if (A == NULL)
319                 {
320                 BNerr(BN_F_BN_EXPAND_INTERNAL,ERR_R_MALLOC_FAILURE);
321                 return(NULL);
322                 }
323 #if 1
324         B=b->d;
325         /* Check if the previous number needs to be copied */
326         if (B != NULL)
327                 {
328                 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
329                         {
330                         /*
331                          * The fact that the loop is unrolled
332                          * 4-wise is a tribute to Intel. It's
333                          * the one that doesn't have enough
334                          * registers to accomodate more data.
335                          * I'd unroll it 8-wise otherwise:-)
336                          *
337                          *              <appro@fy.chalmers.se>
338                          */
339                         BN_ULONG a0,a1,a2,a3;
340                         a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
341                         A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
342                         }
343                 switch (b->top&3)
344                         {
345                 case 3: A[2]=B[2];
346                 case 2: A[1]=B[1];
347                 case 1: A[0]=B[0];
348                 case 0: /* workaround for ultrix cc: without 'case 0', the optimizer does
349                          * the switch table by doing a=top&3; a--; goto jump_table[a];
350                          * which fails for top== 0 */
351                         ;
352                         }
353                 }
354
355 #else
356         memset(A,0,sizeof(BN_ULONG)*words);
357         memcpy(A,b->d,sizeof(b->d[0])*b->top);
358 #endif
359                 
360         return(a);
361         }
362
363 /* This is an internal function that can be used instead of bn_expand2()
364  * when there is a need to copy BIGNUMs instead of only expanding the
365  * data part, while still expanding them.
366  * Especially useful when needing to expand BIGNUMs that are declared
367  * 'const' and should therefore not be changed.
368  * The reason to use this instead of a BN_dup() followed by a bn_expand2()
369  * is memory allocation overhead.  A BN_dup() followed by a bn_expand2()
370  * will allocate new memory for the BIGNUM data twice, and free it once,
371  * while bn_dup_expand() makes sure allocation is made only once.
372  */
373
374 #ifndef OPENSSL_NO_DEPRECATED
375 BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
376         {
377         BIGNUM *r = NULL;
378
379         bn_check_top(b);
380
381         /* This function does not work if
382          *      words <= b->dmax && top < words
383          * because BN_dup() does not preserve 'dmax'!
384          * (But bn_dup_expand() is not used anywhere yet.)
385          */
386
387         if (words > b->dmax)
388                 {
389                 BN_ULONG *a = bn_expand_internal(b, words);
390
391                 if (a)
392                         {
393                         r = BN_new();
394                         if (r)
395                                 {
396                                 r->top = b->top;
397                                 r->dmax = words;
398                                 r->neg = b->neg;
399                                 r->d = a;
400                                 }
401                         else
402                                 {
403                                 /* r == NULL, BN_new failure */
404                                 OPENSSL_free(a);
405                                 }
406                         }
407                 /* If a == NULL, there was an error in allocation in
408                    bn_expand_internal(), and NULL should be returned */
409                 }
410         else
411                 {
412                 r = BN_dup(b);
413                 }
414
415         bn_check_top(r);
416         return r;
417         }
418 #endif
419
420 /* This is an internal function that should not be used in applications.
421  * It ensures that 'b' has enough room for a 'words' word number
422  * and initialises any unused part of b->d with leading zeros.
423  * It is mostly used by the various BIGNUM routines. If there is an error,
424  * NULL is returned. If not, 'b' is returned. */
425
426 BIGNUM *bn_expand2(BIGNUM *b, int words)
427         {
428         bn_check_top(b);
429
430         if (words > b->dmax)
431                 {
432                 BN_ULONG *a = bn_expand_internal(b, words);
433                 if(!a) return NULL;
434                 if(b->d) OPENSSL_free(b->d);
435                 b->d=a;
436                 b->dmax=words;
437                 }
438
439 /* None of this should be necessary because of what b->top means! */
440 #if 0
441         /* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
442         if (b->top < b->dmax)
443                 {
444                 int i;
445                 BN_ULONG *A = &(b->d[b->top]);
446                 for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
447                         {
448                         A[0]=0; A[1]=0; A[2]=0; A[3]=0;
449                         A[4]=0; A[5]=0; A[6]=0; A[7]=0;
450                         }
451                 for (i=(b->dmax - b->top)&7; i>0; i--,A++)
452                         A[0]=0;
453                 assert(A == &(b->d[b->dmax]));
454                 }
455 #endif
456         bn_check_top(b);
457         return b;
458         }
459
460 BIGNUM *BN_dup(const BIGNUM *a)
461         {
462         BIGNUM *t;
463
464         if (a == NULL) return NULL;
465         bn_check_top(a);
466
467         t = BN_new();
468         if (t == NULL) return NULL;
469         if(!BN_copy(t, a))
470                 {
471                 BN_free(t);
472                 return NULL;
473                 }
474         bn_check_top(t);
475         return t;
476         }
477
478 BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
479         {
480         int i;
481         BN_ULONG *A;
482         const BN_ULONG *B;
483
484         bn_check_top(b);
485
486         if (a == b) return(a);
487         if (bn_wexpand(a,b->top) == NULL) return(NULL);
488
489 #if 1
490         A=a->d;
491         B=b->d;
492         for (i=b->top>>2; i>0; i--,A+=4,B+=4)
493                 {
494                 BN_ULONG a0,a1,a2,a3;
495                 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
496                 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
497                 }
498         switch (b->top&3)
499                 {
500                 case 3: A[2]=B[2];
501                 case 2: A[1]=B[1];
502                 case 1: A[0]=B[0];
503                 case 0: ; /* ultrix cc workaround, see comments in bn_expand_internal */
504                 }
505 #else
506         memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
507 #endif
508
509         a->top=b->top;
510         a->neg=b->neg;
511         bn_check_top(a);
512         return(a);
513         }
514
515 void BN_swap(BIGNUM *a, BIGNUM *b)
516         {
517         int flags_old_a, flags_old_b;
518         BN_ULONG *tmp_d;
519         int tmp_top, tmp_dmax, tmp_neg;
520         
521         bn_check_top(a);
522         bn_check_top(b);
523
524         flags_old_a = a->flags;
525         flags_old_b = b->flags;
526
527         tmp_d = a->d;
528         tmp_top = a->top;
529         tmp_dmax = a->dmax;
530         tmp_neg = a->neg;
531         
532         a->d = b->d;
533         a->top = b->top;
534         a->dmax = b->dmax;
535         a->neg = b->neg;
536         
537         b->d = tmp_d;
538         b->top = tmp_top;
539         b->dmax = tmp_dmax;
540         b->neg = tmp_neg;
541         
542         a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
543         b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
544         bn_check_top(a);
545         bn_check_top(b);
546         }
547
548 void BN_clear(BIGNUM *a)
549         {
550         bn_check_top(a);
551         if (a->d != NULL)
552                 memset(a->d,0,a->dmax*sizeof(a->d[0]));
553         a->top=0;
554         a->neg=0;
555         }
556
557 BN_ULONG BN_get_word(const BIGNUM *a)
558         {
559         if (a->top > 1)
560                 return BN_MASK2;
561         else if (a->top == 1)
562                 return a->d[0];
563         /* a->top == 0 */
564         return 0;
565         }
566
567 int BN_set_word(BIGNUM *a, BN_ULONG w)
568         {
569         bn_check_top(a);
570         if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0);
571         a->neg = 0;
572         a->d[0] = w;
573         a->top = (w ? 1 : 0);
574         bn_check_top(a);
575         return(1);
576         }
577
578 BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
579         {
580         unsigned int i,m;
581         unsigned int n;
582         BN_ULONG l;
583         BIGNUM  *bn = NULL;
584
585         if (ret == NULL)
586                 ret = bn = BN_new();
587         if (ret == NULL) return(NULL);
588         bn_check_top(ret);
589         l=0;
590         n=len;
591         if (n == 0)
592                 {
593                 ret->top=0;
594                 return(ret);
595                 }
596         i=((n-1)/BN_BYTES)+1;
597         m=((n-1)%(BN_BYTES));
598         if (bn_wexpand(ret, (int)i) == NULL)
599                 {
600                 if (bn) BN_free(bn);
601                 return NULL;
602                 }
603         ret->top=i;
604         ret->neg=0;
605         while (n--)
606                 {
607                 l=(l<<8L)| *(s++);
608                 if (m-- == 0)
609                         {
610                         ret->d[--i]=l;
611                         l=0;
612                         m=BN_BYTES-1;
613                         }
614                 }
615         /* need to call this due to clear byte at top if avoiding
616          * having the top bit set (-ve number) */
617         bn_correct_top(ret);
618         return(ret);
619         }
620
621 /* ignore negative */
622 int BN_bn2bin(const BIGNUM *a, unsigned char *to)
623         {
624         int n,i;
625         BN_ULONG l;
626
627         bn_check_top(a);
628         n=i=BN_num_bytes(a);
629         while (i--)
630                 {
631                 l=a->d[i/BN_BYTES];
632                 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
633                 }
634         return(n);
635         }
636
637 int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
638         {
639         int i;
640         BN_ULONG t1,t2,*ap,*bp;
641
642         bn_check_top(a);
643         bn_check_top(b);
644
645         i=a->top-b->top;
646         if (i != 0) return(i);
647         ap=a->d;
648         bp=b->d;
649         for (i=a->top-1; i>=0; i--)
650                 {
651                 t1= ap[i];
652                 t2= bp[i];
653                 if (t1 != t2)
654                         return((t1 > t2) ? 1 : -1);
655                 }
656         return(0);
657         }
658
659 int BN_cmp(const BIGNUM *a, const BIGNUM *b)
660         {
661         int i;
662         int gt,lt;
663         BN_ULONG t1,t2;
664
665         if ((a == NULL) || (b == NULL))
666                 {
667                 if (a != NULL)
668                         return(-1);
669                 else if (b != NULL)
670                         return(1);
671                 else
672                         return(0);
673                 }
674
675         bn_check_top(a);
676         bn_check_top(b);
677
678         if (a->neg != b->neg)
679                 {
680                 if (a->neg)
681                         return(-1);
682                 else    return(1);
683                 }
684         if (a->neg == 0)
685                 { gt=1; lt= -1; }
686         else    { gt= -1; lt=1; }
687
688         if (a->top > b->top) return(gt);
689         if (a->top < b->top) return(lt);
690         for (i=a->top-1; i>=0; i--)
691                 {
692                 t1=a->d[i];
693                 t2=b->d[i];
694                 if (t1 > t2) return(gt);
695                 if (t1 < t2) return(lt);
696                 }
697         return(0);
698         }
699
700 int BN_set_bit(BIGNUM *a, int n)
701         {
702         int i,j,k;
703
704         if (n < 0)
705                 return 0;
706
707         i=n/BN_BITS2;
708         j=n%BN_BITS2;
709         if (a->top <= i)
710                 {
711                 if (bn_wexpand(a,i+1) == NULL) return(0);
712                 for(k=a->top; k<i+1; k++)
713                         a->d[k]=0;
714                 a->top=i+1;
715                 }
716
717         a->d[i]|=(((BN_ULONG)1)<<j);
718         bn_check_top(a);
719         return(1);
720         }
721
722 int BN_clear_bit(BIGNUM *a, int n)
723         {
724         int i,j;
725
726         bn_check_top(a);
727         if (n < 0) return 0;
728
729         i=n/BN_BITS2;
730         j=n%BN_BITS2;
731         if (a->top <= i) return(0);
732
733         a->d[i]&=(~(((BN_ULONG)1)<<j));
734         bn_correct_top(a);
735         return(1);
736         }
737
738 int BN_is_bit_set(const BIGNUM *a, int n)
739         {
740         int i,j;
741
742         bn_check_top(a);
743         if (n < 0) return 0;
744         i=n/BN_BITS2;
745         j=n%BN_BITS2;
746         if (a->top <= i) return 0;
747         return(((a->d[i])>>j)&((BN_ULONG)1));
748         }
749
750 int BN_mask_bits(BIGNUM *a, int n)
751         {
752         int b,w;
753
754         bn_check_top(a);
755         if (n < 0) return 0;
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_correct_top(a);
768         return(1);
769         }
770
771 void BN_set_negative(BIGNUM *a, int b)
772         {
773         if (b && !BN_is_zero(a))
774                 a->neg = 1;
775         else
776                 a->neg = 0;
777         }
778
779 int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
780         {
781         int i;
782         BN_ULONG aa,bb;
783
784         aa=a[n-1];
785         bb=b[n-1];
786         if (aa != bb) return((aa > bb)?1:-1);
787         for (i=n-2; i>=0; i--)
788                 {
789                 aa=a[i];
790                 bb=b[i];
791                 if (aa != bb) return((aa > bb)?1:-1);
792                 }
793         return(0);
794         }
795
796 /* Here follows a specialised variants of bn_cmp_words().  It has the
797    property of performing the operation on arrays of different sizes.
798    The sizes of those arrays is expressed through cl, which is the
799    common length ( basicall, min(len(a),len(b)) ), and dl, which is the
800    delta between the two lengths, calculated as len(a)-len(b).
801    All lengths are the number of BN_ULONGs...  */
802
803 int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
804         int cl, int dl)
805         {
806         int n,i;
807         n = cl-1;
808
809         if (dl < 0)
810                 {
811                 for (i=dl; i<0; i++)
812                         {
813                         if (b[n-i] != 0)
814                                 return -1; /* a < b */
815                         }
816                 }
817         if (dl > 0)
818                 {
819                 for (i=dl; i>0; i--)
820                         {
821                         if (a[n+i] != 0)
822                                 return 1; /* a > b */
823                         }
824                 }
825         return bn_cmp_words(a,b,cl);
826         }