]> git.saurik.com Git - apple/security.git/blob - OSX/libsecurity_apple_csp/open_ssl/bn/bn_lib.c
Security-59754.41.1.tar.gz
[apple/security.git] / OSX / libsecurity_apple_csp / open_ssl / bn / bn_lib.c
1 /*
2 * Copyright (c) 2000-2001,2011,2014 Apple Inc. All Rights Reserved.
3 *
4 * The contents of this file constitute Original Code as defined in and are
5 * subject to the Apple Public Source License Version 1.2 (the 'License').
6 * You may not use this file except in compliance with the License. Please obtain
7 * a copy of the License at http://www.apple.com/publicsource and read it before
8 * using this file.
9 *
10 * This Original Code and all software distributed under the License are
11 * distributed on an 'AS IS' basis, WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESS
12 * OR IMPLIED, AND APPLE HEREBY DISCLAIMS ALL SUCH WARRANTIES, INCLUDING WITHOUT
13 * LIMITATION, ANY WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
14 * PURPOSE, QUIET ENJOYMENT OR NON-INFRINGEMENT. Please see the License for the
15 * specific language governing rights and limitations under the License.
16 */
17
18
19 /* crypto/bn/bn_lib.c */
20 /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
21 * All rights reserved.
22 *
23 * This package is an SSL implementation written
24 * by Eric Young (eay@cryptsoft.com).
25 * The implementation was written so as to conform with Netscapes SSL.
26 *
27 * This library is free for commercial and non-commercial use as long as
28 * the following conditions are aheared to. The following conditions
29 * apply to all code found in this distribution, be it the RC4, RSA,
30 * lhash, DES, etc., code; not just the SSL code. The SSL documentation
31 * included with this distribution is covered by the same copyright terms
32 * except that the holder is Tim Hudson (tjh@cryptsoft.com).
33 *
34 * Copyright remains Eric Young's, and as such any Copyright notices in
35 * the code are not to be removed.
36 * If this package is used in a product, Eric Young should be given attribution
37 * as the author of the parts of the library used.
38 * This can be in the form of a textual message at program startup or
39 * in documentation (online or textual) provided with the package.
40 *
41 * Redistribution and use in source and binary forms, with or without
42 * modification, are permitted provided that the following conditions
43 * are met:
44 * 1. Redistributions of source code must retain the copyright
45 * notice, this list of conditions and the following disclaimer.
46 * 2. Redistributions in binary form must reproduce the above copyright
47 * notice, this list of conditions and the following disclaimer in the
48 * documentation and/or other materials provided with the distribution.
49 * 3. All advertising materials mentioning features or use of this software
50 * must display the following acknowledgement:
51 * "This product includes cryptographic software written by
52 * Eric Young (eay@cryptsoft.com)"
53 * The word 'cryptographic' can be left out if the rouines from the library
54 * being used are not cryptographic related :-).
55 * 4. If you include any Windows specific code (or a derivative thereof) from
56 * the apps directory (application code) you must include an acknowledgement:
57 * "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
58 *
59 * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
60 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
61 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
62 * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
63 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
64 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
65 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
66 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
67 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
68 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
69 * SUCH DAMAGE.
70 *
71 * The licence and distribution terms for any publically available version or
72 * derivative of this code cannot be changed. i.e. this code cannot simply be
73 * copied and put under another distribution licence
74 * [including the GNU Public Licence.]
75 */
76
77 #include <stdio.h>
78 #include "cryptlib.h"
79 #include "bn_lcl.h"
80
81 const char *BN_version="Big Number" OPENSSL_VERSION_PTEXT;
82
83 #if BN_PARAMS_ENABLE
84
85 /* For a 32 bit machine
86 * 2 - 4 == 128
87 * 3 - 8 == 256
88 * 4 - 16 == 512
89 * 5 - 32 == 1024
90 * 6 - 64 == 2048
91 * 7 - 128 == 4096
92 * 8 - 256 == 8192
93 */
94 static int bn_limit_bits=0;
95 static int bn_limit_num=8; /* (1<<bn_limit_bits) */
96 static int bn_limit_bits_low=0;
97 static int bn_limit_num_low=8; /* (1<<bn_limit_bits_low) */
98 static int bn_limit_bits_high=0;
99 static int bn_limit_num_high=8; /* (1<<bn_limit_bits_high) */
100 static int bn_limit_bits_mont=0;
101 static int bn_limit_num_mont=8; /* (1<<bn_limit_bits_mont) */
102
103 void BN_set_params(int mult, int high, int low, int mont)
104 {
105 if (mult >= 0)
106 {
107 if (mult > (sizeof(int)*8)-1)
108 mult=sizeof(int)*8-1;
109 bn_limit_bits=mult;
110 bn_limit_num=1<<mult;
111 }
112 if (high >= 0)
113 {
114 if (high > (sizeof(int)*8)-1)
115 high=sizeof(int)*8-1;
116 bn_limit_bits_high=high;
117 bn_limit_num_high=1<<high;
118 }
119 if (low >= 0)
120 {
121 if (low > (sizeof(int)*8)-1)
122 low=sizeof(int)*8-1;
123 bn_limit_bits_low=low;
124 bn_limit_num_low=1<<low;
125 }
126 if (mont >= 0)
127 {
128 if (mont > (sizeof(int)*8)-1)
129 mont=sizeof(int)*8-1;
130 bn_limit_bits_mont=mont;
131 bn_limit_num_mont=1<<mont;
132 }
133 }
134
135 int BN_get_params(int which)
136 {
137 if (which == 0) return(bn_limit_bits);
138 else if (which == 1) return(bn_limit_bits_high);
139 else if (which == 2) return(bn_limit_bits_low);
140 else if (which == 3) return(bn_limit_bits_mont);
141 else return(0);
142 }
143 #endif /* BN_PARAMS_ENABLE */
144
145 BIGNUM *BN_value_one(void)
146 {
147 static BN_ULONG data_one=1L;
148 static BIGNUM const_one={&data_one,1,1,0};
149
150 return(&const_one);
151 }
152
153 char *BN_options(void)
154 {
155 static int init=0;
156 static char data[16];
157
158 if (!init)
159 {
160 init++;
161 #ifdef BN_LLONG
162 sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULLONG)*8,
163 (int)sizeof(BN_ULONG)*8);
164 #else
165 sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULONG)*8,
166 (int)sizeof(BN_ULONG)*8);
167 #endif
168 }
169 return(data);
170 }
171
172 int BN_num_bits_word(BN_ULONG l)
173 {
174 static const char bits[256]={
175 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
176 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
177 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
178 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
179 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
180 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
181 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
182 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
183 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
184 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
185 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
186 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
187 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
188 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
189 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
190 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
191 };
192
193 #if defined(SIXTY_FOUR_BIT_LONG)
194 if (l & 0xffffffff00000000L)
195 {
196 if (l & 0xffff000000000000L)
197 {
198 if (l & 0xff00000000000000L)
199 {
200 return(bits[(int)(l>>56)]+56);
201 }
202 else return(bits[(int)(l>>48)]+48);
203 }
204 else
205 {
206 if (l & 0x0000ff0000000000L)
207 {
208 return(bits[(int)(l>>40)]+40);
209 }
210 else return(bits[(int)(l>>32)]+32);
211 }
212 }
213 else
214 #else
215 #ifdef SIXTY_FOUR_BIT
216 if (l & 0xffffffff00000000LL)
217 {
218 if (l & 0xffff000000000000LL)
219 {
220 if (l & 0xff00000000000000LL)
221 {
222 return(bits[(int)(l>>56)]+56);
223 }
224 else return(bits[(int)(l>>48)]+48);
225 }
226 else
227 {
228 if (l & 0x0000ff0000000000LL)
229 {
230 return(bits[(int)(l>>40)]+40);
231 }
232 else return(bits[(int)(l>>32)]+32);
233 }
234 }
235 else
236 #endif
237 #endif
238 {
239 #if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
240 if (l & 0xffff0000L)
241 {
242 if (l & 0xff000000L)
243 return(bits[(int)(l>>24L)]+24);
244 else return(bits[(int)(l>>16L)]+16);
245 }
246 else
247 #endif
248 {
249 #if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
250 if (l & 0xff00L)
251 return(bits[(int)(l>>8)]+8);
252 else
253 #endif
254 return(bits[(int)(l )] );
255 }
256 }
257 }
258
259 int BN_num_bits(const BIGNUM *a)
260 {
261 BN_ULONG l;
262 int i;
263
264 bn_check_top(a);
265
266 if (a->top == 0) return(0);
267 l=a->d[a->top-1];
268 i=(a->top-1)*BN_BITS2;
269 if (l == 0)
270 {
271 #if !defined(NO_STDIO) && !defined(WIN16)
272 fprintf(stderr,"BAD TOP VALUE\n");
273 #endif
274 abort();
275 }
276 return(i+BN_num_bits_word(l));
277 }
278
279 void BN_clear_free(BIGNUM *a)
280 {
281 int i;
282
283 if (a == NULL) return;
284 if (a->d != NULL)
285 {
286 memset(a->d,0,a->max*sizeof(a->d[0]));
287 if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
288 Free(a->d);
289 }
290 i=BN_get_flags(a,BN_FLG_MALLOCED);
291 memset(a,0,sizeof(BIGNUM));
292 if (i)
293 Free(a);
294 }
295
296 void BN_free(BIGNUM *a)
297 {
298 if (a == NULL) return;
299 if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
300 Free(a->d);
301 a->flags|=BN_FLG_FREE; /* REMOVE? */
302 if (a->flags & BN_FLG_MALLOCED)
303 Free(a);
304 }
305
306 void BN_init(BIGNUM *a)
307 {
308 memset(a,0,sizeof(BIGNUM));
309 }
310
311 BIGNUM *BN_new(void)
312 {
313 BIGNUM *ret;
314
315 if ((ret=(BIGNUM *)Malloc(sizeof(BIGNUM))) == NULL)
316 {
317 BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
318 return(NULL);
319 }
320 ret->flags=BN_FLG_MALLOCED;
321 ret->top=0;
322 ret->neg=0;
323 ret->max=0;
324 ret->d=NULL;
325 return(ret);
326 }
327
328 /* This is an internal function that should not be used in applications.
329 * It ensures that 'b' has enough room for a 'words' word number number.
330 * It is mostly used by the various BIGNUM routines. If there is an error,
331 * NULL is returned. If not, 'b' is returned. */
332
333 BIGNUM *bn_expand2(BIGNUM *b, int words)
334 {
335 BN_ULONG *A,*a;
336 const BN_ULONG *B;
337 int i;
338
339 bn_check_top(b);
340
341 if (words > b->max)
342 {
343 bn_check_top(b);
344 if (BN_get_flags(b,BN_FLG_STATIC_DATA))
345 {
346 BNerr(BN_F_BN_EXPAND2,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
347 return(NULL);
348 }
349 a=A=(BN_ULONG *)Malloc(sizeof(BN_ULONG)*(words+1));
350 if (A == NULL)
351 {
352 BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE);
353 return(NULL);
354 }
355 #if 1
356 B=b->d;
357 /* Check if the previous number needs to be copied */
358 if (B != NULL)
359 {
360 #if 0
361 /* This lot is an unrolled loop to copy b->top
362 * BN_ULONGs from B to A
363 */
364 /*
365 * I have nothing against unrolling but it's usually done for
366 * several reasons, namely:
367 * - minimize percentage of decision making code, i.e. branches;
368 * - avoid cache trashing;
369 * - make it possible to schedule loads earlier;
370 * Now let's examine the code below. The cornerstone of C is
371 * "programmer is always right" and that's what we love it for:-)
372 * For this very reason C compilers have to be paranoid when it
373 * comes to data aliasing and assume the worst. Yeah, but what
374 * does it mean in real life? This means that loop body below will
375 * be compiled to sequence of loads immediately followed by stores
376 * as compiler assumes the worst, something in A==B+1 style. As a
377 * result CPU pipeline is going to starve for incoming data. Secondly
378 * if A and B happen to share same cache line such code is going to
379 * cause severe cache trashing. Both factors have severe impact on
380 * performance of modern CPUs and this is the reason why this
381 * particular piece of code is #ifdefed away and replaced by more
382 * "friendly" version found in #else section below. This comment
383 * also applies to BN_copy function.
384 *
385 * <appro@fy.chalmers.se>
386 */
387 for (i=b->top&(~7); i>0; i-=8)
388 {
389 A[0]=B[0]; A[1]=B[1]; A[2]=B[2]; A[3]=B[3];
390 A[4]=B[4]; A[5]=B[5]; A[6]=B[6]; A[7]=B[7];
391 A+=8;
392 B+=8;
393 }
394 switch (b->top&7)
395 {
396 case 7:
397 A[6]=B[6];
398 case 6:
399 A[5]=B[5];
400 case 5:
401 A[4]=B[4];
402 case 4:
403 A[3]=B[3];
404 case 3:
405 A[2]=B[2];
406 case 2:
407 A[1]=B[1];
408 case 1:
409 A[0]=B[0];
410 case 0:
411 /* I need the 'case 0' entry for utrix cc.
412 * If the optimizer is turned on, it does the
413 * switch table by doing
414 * a=top&7
415 * a--;
416 * goto jump_table[a];
417 * If top is 0, this makes us jump to 0xffffffc
418 * which is rather bad :-(.
419 * eric 23-Apr-1998
420 */
421 ;
422 }
423 #else
424 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
425 {
426 /*
427 * The fact that the loop is unrolled
428 * 4-wise is a tribute to Intel. It's
429 * the one that doesn't have enough
430 * registers to accomodate more data.
431 * I'd unroll it 8-wise otherwise:-)
432 *
433 * <appro@fy.chalmers.se>
434 */
435 BN_ULONG a0,a1,a2,a3;
436 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
437 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
438 }
439 switch (b->top&3)
440 {
441 case 3: A[2]=B[2];
442 case 2: A[1]=B[1];
443 case 1: A[0]=B[0];
444 case 0: ; /* ultrix cc workaround, see above */
445 }
446 #endif
447 Free(b->d);
448 }
449
450 b->d=a;
451 b->max=words;
452
453 /* Now need to zero any data between b->top and b->max */
454
455 A= &(b->d[b->top]);
456 for (i=(b->max - b->top)>>3; i>0; i--,A+=8)
457 {
458 A[0]=0; A[1]=0; A[2]=0; A[3]=0;
459 A[4]=0; A[5]=0; A[6]=0; A[7]=0;
460 }
461 for (i=(b->max - b->top)&7; i>0; i--,A++)
462 A[0]=0;
463 #else
464 memset(A,0,sizeof(BN_ULONG)*(words+1));
465 memcpy(A,b->d,sizeof(b->d[0])*b->top);
466 b->d=a;
467 b->max=words;
468 #endif
469
470 /* memset(&(p[b->max]),0,((words+1)-b->max)*sizeof(BN_ULONG)); */
471 /* { int i; for (i=b->max; i<words+1; i++) p[i]=i;} */
472
473 }
474 return(b);
475 }
476
477 BIGNUM *BN_dup(const BIGNUM *a)
478 {
479 BIGNUM *r;
480
481 if (a == NULL) return NULL;
482
483 bn_check_top(a);
484
485 r=BN_new();
486 if (r == NULL) return(NULL);
487 return((BIGNUM *)BN_copy(r,a));
488 }
489
490 BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
491 {
492 int i;
493 BN_ULONG *A;
494 const BN_ULONG *B;
495
496 bn_check_top(b);
497
498 if (a == b) return(a);
499 if (bn_wexpand(a,b->top) == NULL) return(NULL);
500
501 #if 1
502 A=a->d;
503 B=b->d;
504 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
505 {
506 BN_ULONG a0,a1,a2,a3;
507 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
508 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
509 }
510 switch (b->top&3)
511 {
512 case 3: A[2]=B[2];
513 case 2: A[1]=B[1];
514 case 1: A[0]=B[0];
515 case 0: ; /* ultrix cc workaround, see comments in bn_expand2 */
516 }
517 #else
518 memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
519 #endif
520
521 /* memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
522 a->top=b->top;
523 if ((a->top == 0) && (a->d != NULL))
524 a->d[0]=0;
525 a->neg=b->neg;
526 return(a);
527 }
528
529 void BN_clear(BIGNUM *a)
530 {
531 if (a->d != NULL)
532 memset(a->d,0,a->max*sizeof(a->d[0]));
533 a->top=0;
534 a->neg=0;
535 }
536
537 BN_ULONG BN_get_word(BIGNUM *a)
538 {
539 int i;
540 unsigned n;
541 BN_ULONG ret=0;
542
543 n=BN_num_bytes(a);
544 if (n > sizeof(BN_ULONG))
545 return(BN_MASK2);
546 for (i=a->top-1; i>=0; i--)
547 {
548 #ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
549 ret<<=BN_BITS4; /* stops the compiler complaining */
550 ret<<=BN_BITS4;
551 #else
552 ret=0;
553 #endif
554 ret|=a->d[i];
555 }
556 return(ret);
557 }
558
559 int BN_set_word(BIGNUM *a, BN_ULONG w)
560 {
561 int i,n;
562
563 if (bn_expand(a,(int)(sizeof(BN_ULONG)*8)) == NULL) return(0);
564
565 n=sizeof(BN_ULONG)/BN_BYTES;
566 a->neg=0;
567 a->top=0;
568 a->d[0]=(BN_ULONG)w&BN_MASK2;
569 if (a->d[0] != 0) a->top=1;
570 for (i=1; i<n; i++)
571 {
572 /* the following is done instead of
573 * w>>=BN_BITS2 so compilers don't complain
574 * on builds where sizeof(long) == BN_TYPES */
575 #ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
576 w>>=BN_BITS4;
577 w>>=BN_BITS4;
578 #else
579 w=0;
580 #endif
581 a->d[i]=(BN_ULONG)w&BN_MASK2;
582 if (a->d[i] != 0) a->top=i+1;
583 }
584 return(1);
585 }
586
587 /* ignore negative */
588 BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
589 {
590 unsigned int i,m;
591 unsigned int n;
592 BN_ULONG l;
593
594 if (ret == NULL) ret=BN_new();
595 if (ret == NULL) return(NULL);
596 l=0;
597 n=len;
598 if (n == 0)
599 {
600 ret->top=0;
601 return(ret);
602 }
603 if (bn_expand(ret,(int)(n+2)*8) == NULL)
604 return(NULL);
605 i=((n-1)/BN_BYTES)+1;
606 m=((n-1)%(BN_BYTES));
607 ret->top=i;
608 while (n-- > 0)
609 {
610 l=(l<<8L)| *(s++);
611 if (m-- == 0)
612 {
613 ret->d[--i]=l;
614 l=0;
615 m=BN_BYTES-1;
616 }
617 }
618 /* need to call this due to clear byte at top if avoiding
619 * having the top bit set (-ve number) */
620 bn_fix_top(ret);
621 return(ret);
622 }
623
624 /* ignore negative */
625 int BN_bn2bin(const BIGNUM *a, unsigned char *to)
626 {
627 int n,i;
628 BN_ULONG l;
629
630 n=i=BN_num_bytes(a);
631 while (i-- > 0)
632 {
633 l=a->d[i/BN_BYTES];
634 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
635 }
636 return(n);
637 }
638
639 int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
640 {
641 int i;
642 BN_ULONG t1,t2,*ap,*bp;
643
644 bn_check_top(a);
645 bn_check_top(b);
646
647 i=a->top-b->top;
648 if (i != 0) return(i);
649 ap=a->d;
650 bp=b->d;
651 for (i=a->top-1; i>=0; i--)
652 {
653 t1= ap[i];
654 t2= bp[i];
655 if (t1 != t2)
656 return(t1 > t2?1:-1);
657 }
658 return(0);
659 }
660
661 int BN_cmp(const BIGNUM *a, const BIGNUM *b)
662 {
663 int i;
664 int gt,lt;
665 BN_ULONG t1,t2;
666
667 if ((a == NULL) || (b == NULL))
668 {
669 if (a != NULL)
670 return(-1);
671 else if (b != NULL)
672 return(1);
673 else
674 return(0);
675 }
676
677 bn_check_top(a);
678 bn_check_top(b);
679
680 if (a->neg != b->neg)
681 {
682 if (a->neg)
683 return(-1);
684 else return(1);
685 }
686 if (a->neg == 0)
687 { gt=1; lt= -1; }
688 else { gt= -1; lt=1; }
689
690 if (a->top > b->top) return(gt);
691 if (a->top < b->top) return(lt);
692 for (i=a->top-1; i>=0; i--)
693 {
694 t1=a->d[i];
695 t2=b->d[i];
696 if (t1 > t2) return(gt);
697 if (t1 < t2) return(lt);
698 }
699 return(0);
700 }
701
702 int BN_set_bit(BIGNUM *a, int n)
703 {
704 int i,j,k;
705
706 i=n/BN_BITS2;
707 j=n%BN_BITS2;
708 if (a->top <= i)
709 {
710 if (bn_wexpand(a,i+1) == NULL) return(0);
711 for(k=a->top; k<i+1; k++)
712 a->d[k]=0;
713 a->top=i+1;
714 }
715
716 a->d[i]|=(((BN_ULONG)1)<<j);
717 return(1);
718 }
719
720 int BN_clear_bit(BIGNUM *a, int n)
721 {
722 int i,j;
723
724 i=n/BN_BITS2;
725 j=n%BN_BITS2;
726 if (a->top <= i) return(0);
727
728 a->d[i]&=(~(((BN_ULONG)1)<<j));
729 bn_fix_top(a);
730 return(1);
731 }
732
733 int BN_is_bit_set(const BIGNUM *a, int n)
734 {
735 int i,j;
736
737 if (n < 0) return(0);
738 i=n/BN_BITS2;
739 j=n%BN_BITS2;
740 if (a->top <= i) return(0);
741 return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
742 }
743
744 int BN_mask_bits(BIGNUM *a, int n)
745 {
746 int b,w;
747
748 w=n/BN_BITS2;
749 b=n%BN_BITS2;
750 if (w >= a->top) return(0);
751 if (b == 0)
752 a->top=w;
753 else
754 {
755 a->top=w+1;
756 a->d[w]&= ~(BN_MASK2<<b);
757 }
758 bn_fix_top(a);
759 return(1);
760 }
761
762 int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n)
763 {
764 int i;
765 BN_ULONG aa,bb;
766
767 aa=a[n-1];
768 bb=b[n-1];
769 if (aa != bb) return((aa > bb)?1:-1);
770 for (i=n-2; i>=0; i--)
771 {
772 aa=a[i];
773 bb=b[i];
774 if (aa != bb) return((aa > bb)?1:-1);
775 }
776 return(0);
777 }
778