Work with -pedantic!
[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 int bn_limit_bits=0;
75 int bn_limit_num=8;        /* (1<<bn_limit_bits) */
76 int bn_limit_bits_low=0;
77 int bn_limit_num_low=8;    /* (1<<bn_limit_bits_low) */
78 int bn_limit_bits_high=0;
79 int bn_limit_num_high=8;   /* (1<<bn_limit_bits_high) */
80 int bn_limit_bits_mont=0;
81 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 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(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,*B,*a;
347         int i,j;
348
349         bn_check_top(b);
350
351         if (words > b->max)
352                 {
353                 bn_check_top(b);        
354                 if (BN_get_flags(b,BN_FLG_STATIC_DATA))
355                         {
356                         BNerr(BN_F_BN_EXPAND2,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
357                         return(NULL);
358                         }
359                 a=A=(BN_ULONG *)Malloc(sizeof(BN_ULONG)*(words+1));
360                 if (A == NULL)
361                         {
362                         BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE);
363                         return(NULL);
364                         }
365 memset(A,0x5c,sizeof(BN_ULONG)*(words+1));
366 #if 1
367                 B=b->d;
368                 /* Check if the previous number needs to be copied */
369                 if (B != NULL)
370                         {
371                         /* This lot is an unrolled loop to copy b->top 
372                          * BN_ULONGs from B to A
373                          */
374                         for (i=b->top&(~7); i>0; i-=8)
375                                 {
376                                 A[0]=B[0]; A[1]=B[1]; A[2]=B[2]; A[3]=B[3];
377                                 A[4]=B[4]; A[5]=B[5]; A[6]=B[6]; A[7]=B[7];
378                                 A+=8;
379                                 B+=8;
380                                 }
381                         switch (b->top&7)
382                                 {
383                         case 7:
384                                 A[6]=B[6];
385                         case 6:
386                                 A[5]=B[5];
387                         case 5:
388                                 A[4]=B[4];
389                         case 4:
390                                 A[3]=B[3];
391                         case 3:
392                                 A[2]=B[2];
393                         case 2:
394                                 A[1]=B[1];
395                         case 1:
396                                 A[0]=B[0];
397                         case 0:
398                                 /* I need the 'case 0' entry for utrix cc.
399                                  * If the optimiser is turned on, it does the
400                                  * switch table by doing
401                                  * a=top&7
402                                  * a--;
403                                  * goto jump_table[a];
404                                  * If top is 0, this makes us jump to 0xffffffc 
405                                  * which is rather bad :-(.
406                                  * eric 23-Apr-1998
407                                  */
408                                 ;
409                                 }
410                         Free(b->d);
411                         }
412
413                 b->d=a;
414                 b->max=words;
415
416                 /* Now need to zero any data between b->top and b->max */
417
418                 B= &(b->d[b->top]);
419                 j=(b->max - b->top) & ~7;
420                 for (i=0; i<j; i+=8)
421                         {
422                         B[0]=0; B[1]=0; B[2]=0; B[3]=0;
423                         B[4]=0; B[5]=0; B[6]=0; B[7]=0;
424                         B+=8;
425                         }
426                 j=(b->max - b->top) & 7;
427                 for (i=0; i<j; i++)
428                         {
429                         B[0]=0;
430                         B++;
431                         }
432 #else
433                         memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
434 #endif
435                 
436 /*              memset(&(p[b->max]),0,((words+1)-b->max)*sizeof(BN_ULONG)); */
437 /*      { int i; for (i=b->max; i<words+1; i++) p[i]=i;} */
438
439                 }
440         return(b);
441         }
442
443 BIGNUM *BN_dup(BIGNUM *a)
444         {
445         BIGNUM *r;
446
447         bn_check_top(a);
448
449         r=BN_new();
450         if (r == NULL) return(NULL);
451         return((BIGNUM *)BN_copy(r,a));
452         }
453
454 BIGNUM *BN_copy(BIGNUM *a, BIGNUM *b)
455         {
456         int i;
457         BN_ULONG *A,*B;
458
459         bn_check_top(b);
460
461         if (a == b) return(a);
462         if (bn_wexpand(a,b->top) == NULL) return(NULL);
463
464 #if 1
465         A=a->d;
466         B=b->d;
467         for (i=b->top&(~7); i>0; i-=8)
468                 {
469                 A[0]=B[0];
470                 A[1]=B[1];
471                 A[2]=B[2];
472                 A[3]=B[3];
473                 A[4]=B[4];
474                 A[5]=B[5];
475                 A[6]=B[6];
476                 A[7]=B[7];
477                 A+=8;
478                 B+=8;
479                 }
480         switch (b->top&7)
481                 {
482         case 7:
483                 A[6]=B[6];
484         case 6:
485                 A[5]=B[5];
486         case 5:
487                 A[4]=B[4];
488         case 4:
489                 A[3]=B[3];
490         case 3:
491                 A[2]=B[2];
492         case 2:
493                 A[1]=B[1];
494         case 1:
495                 A[0]=B[0];
496         case 0:
497                 /* I need the 'case 0' entry for utrix cc.
498                  * If the optimiser is turned on, it does the
499                  * switch table by doing
500                  * a=top&7
501                  * a--;
502                  * goto jump_table[a];
503                  * If top is 0, this makes us jump to 0xffffffc which is
504                  * rather bad :-(.
505                  * eric 23-Apr-1998
506                  */
507                 ;
508                 }
509 #else
510         memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
511 #endif
512
513 /*      memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
514         a->top=b->top;
515         if ((a->top == 0) && (a->d != NULL))
516                 a->d[0]=0;
517         a->neg=b->neg;
518         return(a);
519         }
520
521 void BN_clear(BIGNUM *a)
522         {
523         if (a->d != NULL)
524                 memset(a->d,0,a->max*sizeof(a->d[0]));
525         a->top=0;
526         a->neg=0;
527         }
528
529 BN_ULONG BN_get_word(BIGNUM *a)
530         {
531         int i,n;
532         BN_ULONG ret=0;
533
534         n=BN_num_bytes(a);
535         if (n > sizeof(BN_ULONG))
536                 return(BN_MASK2);
537         for (i=a->top-1; i>=0; i--)
538                 {
539 #ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
540                 ret<<=BN_BITS4; /* stops the compiler complaining */
541                 ret<<=BN_BITS4;
542 #endif
543                 ret|=a->d[i];
544                 }
545         return(ret);
546         }
547
548 int BN_set_word(BIGNUM *a, BN_ULONG w)
549         {
550         int i,n;
551         if (bn_expand(a,sizeof(BN_ULONG)*8) == NULL) return(0);
552
553         n=sizeof(BN_ULONG)/BN_BYTES;
554         a->neg=0;
555         a->top=0;
556         a->d[0]=(BN_ULONG)w&BN_MASK2;
557         if (a->d[0] != 0) a->top=1;
558         for (i=1; i<n; i++)
559                 {
560                 /* the following is done instead of
561                  * w>>=BN_BITS2 so compilers don't complain
562                  * on builds where sizeof(long) == BN_TYPES */
563 #ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
564                 w>>=BN_BITS4;
565                 w>>=BN_BITS4;
566 #endif
567                 a->d[i]=(BN_ULONG)w&BN_MASK2;
568                 if (a->d[i] != 0) a->top=i+1;
569                 }
570         return(1);
571         }
572
573 /* ignore negative */
574 BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
575         {
576         unsigned int i,m;
577         unsigned int n;
578         BN_ULONG l;
579
580         if (ret == NULL) ret=BN_new();
581         if (ret == NULL) return(NULL);
582         l=0;
583         n=len;
584         if (n == 0)
585                 {
586                 ret->top=0;
587                 return(ret);
588                 }
589         if (bn_expand(ret,(int)(n+2)*8) == NULL)
590                 return(NULL);
591         i=((n-1)/BN_BYTES)+1;
592         m=((n-1)%(BN_BYTES));
593         ret->top=i;
594         while (n-- > 0)
595                 {
596                 l=(l<<8L)| *(s++);
597                 if (m-- == 0)
598                         {
599                         ret->d[--i]=l;
600                         l=0;
601                         m=BN_BYTES-1;
602                         }
603                 }
604         /* need to call this due to clear byte at top if avoiding
605          * having the top bit set (-ve number) */
606         bn_fix_top(ret);
607         return(ret);
608         }
609
610 /* ignore negative */
611 int BN_bn2bin(BIGNUM *a, unsigned char *to)
612         {
613         int n,i;
614         BN_ULONG l;
615
616         n=i=BN_num_bytes(a);
617         while (i-- > 0)
618                 {
619                 l=a->d[i/BN_BYTES];
620                 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
621                 }
622         return(n);
623         }
624
625 int BN_ucmp(BIGNUM *a, BIGNUM *b)
626         {
627         int i;
628         BN_ULONG t1,t2,*ap,*bp;
629
630         bn_check_top(a);
631         bn_check_top(b);
632
633         i=a->top-b->top;
634         if (i != 0) return(i);
635         ap=a->d;
636         bp=b->d;
637         for (i=a->top-1; i>=0; i--)
638                 {
639                 t1= ap[i];
640                 t2= bp[i];
641                 if (t1 != t2)
642                         return(t1 > t2?1:-1);
643                 }
644         return(0);
645         }
646
647 int BN_cmp(BIGNUM *a, BIGNUM *b)
648         {
649         int i;
650         int gt,lt;
651         BN_ULONG t1,t2;
652
653         if ((a == NULL) || (b == NULL))
654                 {
655                 if (a != NULL)
656                         return(-1);
657                 else if (b != NULL)
658                         return(1);
659                 else
660                         return(0);
661                 }
662
663         bn_check_top(a);
664         bn_check_top(b);
665
666         if (a->neg != b->neg)
667                 {
668                 if (a->neg)
669                         return(-1);
670                 else    return(1);
671                 }
672         if (a->neg == 0)
673                 { gt=1; lt= -1; }
674         else    { gt= -1; lt=1; }
675
676         if (a->top > b->top) return(gt);
677         if (a->top < b->top) return(lt);
678         for (i=a->top-1; i>=0; i--)
679                 {
680                 t1=a->d[i];
681                 t2=b->d[i];
682                 if (t1 > t2) return(gt);
683                 if (t1 < t2) return(lt);
684                 }
685         return(0);
686         }
687
688 int BN_set_bit(BIGNUM *a, int n)
689         {
690         int i,j,k;
691
692         i=n/BN_BITS2;
693         j=n%BN_BITS2;
694         if (a->top <= i)
695                 {
696                 if (bn_wexpand(a,i+1) == NULL) return(0);
697                 for(k=a->top; k<i+1; k++)
698                         a->d[k]=0;
699                 a->top=i+1;
700                 }
701
702         a->d[i]|=(1L<<j);
703         return(1);
704         }
705
706 int BN_clear_bit(BIGNUM *a, int n)
707         {
708         int i,j;
709
710         i=n/BN_BITS2;
711         j=n%BN_BITS2;
712         if (a->top <= i) return(0);
713
714         a->d[i]&=(~(1L<<j));
715         bn_fix_top(a);
716         return(1);
717         }
718
719 int BN_is_bit_set(BIGNUM *a, int n)
720         {
721         int i,j;
722
723         if (n < 0) return(0);
724         i=n/BN_BITS2;
725         j=n%BN_BITS2;
726         if (a->top <= i) return(0);
727         return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
728         }
729
730 int BN_mask_bits(BIGNUM *a, int n)
731         {
732         int b,w;
733
734         w=n/BN_BITS2;
735         b=n%BN_BITS2;
736         if (w >= a->top) return(0);
737         if (b == 0)
738                 a->top=w;
739         else
740                 {
741                 a->top=w+1;
742                 a->d[w]&= ~(BN_MASK2<<b);
743                 }
744         bn_fix_top(a);
745         return(1);
746         }
747
748 int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n)
749         {
750         int i;
751         BN_ULONG aa,bb;
752
753         aa=a[n-1];
754         bb=b[n-1];
755         if (aa != bb) return((aa > bb)?1:-1);
756         for (i=n-2; i>=0; i--)
757                 {
758                 aa=a[i];
759                 bb=b[i];
760                 if (aa != bb) return((aa > bb)?1:-1);
761                 }
762         return(0);
763         }
764