source: trunk/cscrypt/bn_lib.c@ 1

Last change on this file since 1 was 1, checked in by root, 15 years ago

initial import

File size: 16.5 KB
Line 
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 <string.h>
65#include <assert.h>
66#include <limits.h>
67#include <stdio.h>
68#include "bn_lcl.h"
69#include "openssl_mods.h"
70
71const char *BN_version="Big Number 42";
72
73/* For a 32 bit machine
74 * 2 - 4 == 128
75 * 3 - 8 == 256
76 * 4 - 16 == 512
77 * 5 - 32 == 1024
78 * 6 - 64 == 2048
79 * 7 - 128 == 4096
80 * 8 - 256 == 8192
81 */
82static int bn_limit_bits=0;
83static int bn_limit_num=8; /* (1<<bn_limit_bits) */
84static int bn_limit_bits_low=0;
85static int bn_limit_num_low=8; /* (1<<bn_limit_bits_low) */
86static int bn_limit_bits_high=0;
87static int bn_limit_num_high=8; /* (1<<bn_limit_bits_high) */
88static int bn_limit_bits_mont=0;
89static int bn_limit_num_mont=8; /* (1<<bn_limit_bits_mont) */
90
91void BN_set_params(int mult, int high, int low, int mont)
92 {
93 if (mult >= 0)
94 {
95 if (mult > (sizeof(int)*8)-1)
96 mult=sizeof(int)*8-1;
97 bn_limit_bits=mult;
98 bn_limit_num=1<<mult;
99 }
100 if (high >= 0)
101 {
102 if (high > (sizeof(int)*8)-1)
103 high=sizeof(int)*8-1;
104 bn_limit_bits_high=high;
105 bn_limit_num_high=1<<high;
106 }
107 if (low >= 0)
108 {
109 if (low > (sizeof(int)*8)-1)
110 low=sizeof(int)*8-1;
111 bn_limit_bits_low=low;
112 bn_limit_num_low=1<<low;
113 }
114 if (mont >= 0)
115 {
116 if (mont > (sizeof(int)*8)-1)
117 mont=sizeof(int)*8-1;
118 bn_limit_bits_mont=mont;
119 bn_limit_num_mont=1<<mont;
120 }
121 }
122
123int BN_get_params(int which)
124 {
125 if (which == 0) return(bn_limit_bits);
126 else if (which == 1) return(bn_limit_bits_high);
127 else if (which == 2) return(bn_limit_bits_low);
128 else if (which == 3) return(bn_limit_bits_mont);
129 else return(0);
130 }
131
132BIGNUM *BN_value_one(void)
133 {
134 static BN_ULONG data_one=1L;
135 static BIGNUM const_one={&data_one,1,1,0};
136
137 return(&const_one);
138 }
139
140char *BN_options(void)
141 {
142 static int init=0;
143 static char data[16];
144
145 if (!init)
146 {
147 init++;
148#ifdef BN_LLONG
149 sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULLONG)*8,
150 (int)sizeof(BN_ULONG)*8);
151#else
152 sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULONG)*8,
153 (int)sizeof(BN_ULONG)*8);
154#endif
155 }
156 return(data);
157 }
158
159int BN_num_bits_word(BN_ULONG l)
160 {
161 static const char bits[256]={
162 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
163 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
164 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
165 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
166 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
167 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
168 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
169 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
170 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
171 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
172 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
173 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
174 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
175 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
176 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
177 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
178 };
179
180#if defined(SIXTY_FOUR_BIT_LONG)
181 if (l & 0xffffffff00000000L)
182 {
183 if (l & 0xffff000000000000L)
184 {
185 if (l & 0xff00000000000000L)
186 {
187 return(bits[(int)(l>>56)]+56);
188 }
189 else return(bits[(int)(l>>48)]+48);
190 }
191 else
192 {
193 if (l & 0x0000ff0000000000L)
194 {
195 return(bits[(int)(l>>40)]+40);
196 }
197 else return(bits[(int)(l>>32)]+32);
198 }
199 }
200 else
201#else
202#ifdef SIXTY_FOUR_BIT
203 if (l & 0xffffffff00000000LL)
204 {
205 if (l & 0xffff000000000000LL)
206 {
207 if (l & 0xff00000000000000LL)
208 {
209 return(bits[(int)(l>>56)]+56);
210 }
211 else return(bits[(int)(l>>48)]+48);
212 }
213 else
214 {
215 if (l & 0x0000ff0000000000LL)
216 {
217 return(bits[(int)(l>>40)]+40);
218 }
219 else return(bits[(int)(l>>32)]+32);
220 }
221 }
222 else
223#endif
224#endif
225 {
226#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
227 if (l & 0xffff0000L)
228 {
229 if (l & 0xff000000L)
230 return(bits[(int)(l>>24L)]+24);
231 else return(bits[(int)(l>>16L)]+16);
232 }
233 else
234#endif
235 {
236#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
237 if (l & 0xff00L)
238 return(bits[(int)(l>>8)]+8);
239 else
240#endif
241 return(bits[(int)(l )] );
242 }
243 }
244 }
245
246int BN_num_bits(const BIGNUM *a)
247 {
248 BN_ULONG l;
249 int i;
250
251 bn_check_top(a);
252
253 if (a->top == 0) return(0);
254 l=a->d[a->top-1];
255 assert(l != 0);
256 i=(a->top-1)*BN_BITS2;
257 return(i+BN_num_bits_word(l));
258 }
259
260void BN_clear_free(BIGNUM *a)
261 {
262 int i;
263
264 if (a == NULL) return;
265 if (a->d != NULL)
266 {
267 memset(a->d,0,a->dmax*sizeof(a->d[0]));
268 if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
269 OPENSSL_free(a->d);
270 }
271 i=BN_get_flags(a,BN_FLG_MALLOCED);
272 memset(a,0,sizeof(BIGNUM));
273 if (i)
274 OPENSSL_free(a);
275 }
276
277void BN_free(BIGNUM *a)
278 {
279 if (a == NULL) return;
280 if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
281 OPENSSL_free(a->d);
282 a->flags|=BN_FLG_FREE; /* REMOVE? */
283 if (a->flags & BN_FLG_MALLOCED)
284 OPENSSL_free(a);
285 }
286
287void BN_init(BIGNUM *a)
288 {
289 memset(a,0,sizeof(BIGNUM));
290 }
291
292BIGNUM *BN_new(void)
293 {
294 BIGNUM *ret;
295
296 if ((ret=(BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL)
297 {
298 return(NULL);
299 }
300 ret->flags=BN_FLG_MALLOCED;
301 ret->top=0;
302 ret->neg=0;
303 ret->dmax=0;
304 ret->d=NULL;
305 return(ret);
306 }
307
308/* This is an internal function that should not be used in applications.
309 * It ensures that 'b' has enough room for a 'words' word number number.
310 * It is mostly used by the various BIGNUM routines. If there is an error,
311 * NULL is returned. If not, 'b' is returned. */
312
313BIGNUM *bn_expand2(BIGNUM *b, int words)
314 {
315 BN_ULONG *A,*a;
316 const BN_ULONG *B;
317 int i;
318
319 bn_check_top(b);
320
321 if (words > b->dmax)
322 {
323 if (words > (INT_MAX/(4*BN_BITS2)))
324 {
325 return NULL;
326 }
327
328 bn_check_top(b);
329 if (BN_get_flags(b,BN_FLG_STATIC_DATA))
330 {
331 return(NULL);
332 }
333 a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*(words+1));
334 if (A == NULL)
335 {
336 return(NULL);
337 }
338#if 1
339 B=b->d;
340 /* Check if the previous number needs to be copied */
341 if (B != NULL)
342 {
343#if 0
344 /* This lot is an unrolled loop to copy b->top
345 * BN_ULONGs from B to A
346 */
347/*
348 * I have nothing against unrolling but it's usually done for
349 * several reasons, namely:
350 * - minimize percentage of decision making code, i.e. branches;
351 * - avoid cache trashing;
352 * - make it possible to schedule loads earlier;
353 * Now let's examine the code below. The cornerstone of C is
354 * "programmer is always right" and that's what we love it for:-)
355 * For this very reason C compilers have to be paranoid when it
356 * comes to data aliasing and assume the worst. Yeah, but what
357 * does it mean in real life? This means that loop body below will
358 * be compiled to sequence of loads immediately followed by stores
359 * as compiler assumes the worst, something in A==B+1 style. As a
360 * result CPU pipeline is going to starve for incoming data. Secondly
361 * if A and B happen to share same cache line such code is going to
362 * cause severe cache trashing. Both factors have severe impact on
363 * performance of modern CPUs and this is the reason why this
364 * particular piece of code is #ifdefed away and replaced by more
365 * "friendly" version found in #else section below. This comment
366 * also applies to BN_copy function.
367 *
368 * <appro@fy.chalmers.se>
369 */
370 for (i=b->top&(~7); i>0; i-=8)
371 {
372 A[0]=B[0]; A[1]=B[1]; A[2]=B[2]; A[3]=B[3];
373 A[4]=B[4]; A[5]=B[5]; A[6]=B[6]; A[7]=B[7];
374 A+=8;
375 B+=8;
376 }
377 switch (b->top&7)
378 {
379 case 7:
380 A[6]=B[6];
381 case 6:
382 A[5]=B[5];
383 case 5:
384 A[4]=B[4];
385 case 4:
386 A[3]=B[3];
387 case 3:
388 A[2]=B[2];
389 case 2:
390 A[1]=B[1];
391 case 1:
392 A[0]=B[0];
393 case 0:
394 /* I need the 'case 0' entry for utrix cc.
395 * If the optimizer is turned on, it does the
396 * switch table by doing
397 * a=top&7
398 * a--;
399 * goto jump_table[a];
400 * If top is 0, this makes us jump to 0xffffffc
401 * which is rather bad :-(.
402 * eric 23-Apr-1998
403 */
404 ;
405 }
406#else
407 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
408 {
409 /*
410 * The fact that the loop is unrolled
411 * 4-wise is a tribute to Intel. It's
412 * the one that doesn't have enough
413 * registers to accomodate more data.
414 * I'd unroll it 8-wise otherwise:-)
415 *
416 * <appro@fy.chalmers.se>
417 */
418 BN_ULONG a0,a1,a2,a3;
419 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
420 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
421 }
422 switch (b->top&3)
423 {
424 case 3: A[2]=B[2];
425 case 2: A[1]=B[1];
426 case 1: A[0]=B[0];
427 case 0: ; /* ultrix cc workaround, see above */
428 }
429#endif
430 OPENSSL_free(b->d);
431 }
432
433 b->d=a;
434 b->dmax=words;
435
436 /* Now need to zero any data between b->top and b->max */
437
438 A= &(b->d[b->top]);
439 for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
440 {
441 A[0]=0; A[1]=0; A[2]=0; A[3]=0;
442 A[4]=0; A[5]=0; A[6]=0; A[7]=0;
443 }
444 for (i=(b->dmax - b->top)&7; i>0; i--,A++)
445 A[0]=0;
446#else
447 memset(A,0,sizeof(BN_ULONG)*(words+1));
448 memcpy(A,b->d,sizeof(b->d[0])*b->top);
449 b->d=a;
450 b->max=words;
451#endif
452
453/* memset(&(p[b->max]),0,((words+1)-b->max)*sizeof(BN_ULONG)); */
454/* { int i; for (i=b->max; i<words+1; i++) p[i]=i;} */
455
456 }
457 return(b);
458 }
459
460BIGNUM *BN_dup(const BIGNUM *a)
461 {
462 BIGNUM *r;
463
464 if (a == NULL) return NULL;
465
466 bn_check_top(a);
467
468 r=BN_new();
469 if (r == NULL) return(NULL);
470 return((BIGNUM *)BN_copy(r,a));
471 }
472
473BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
474 {
475 int i;
476 BN_ULONG *A;
477 const BN_ULONG *B;
478
479 bn_check_top(b);
480
481 if (a == b) return(a);
482 if (bn_wexpand(a,b->top) == NULL) return(NULL);
483
484#if 1
485 A=a->d;
486 B=b->d;
487 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
488 {
489 BN_ULONG a0,a1,a2,a3;
490 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
491 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
492 }
493 switch (b->top&3)
494 {
495 case 3: A[2]=B[2];
496 case 2: A[1]=B[1];
497 case 1: A[0]=B[0];
498 case 0: ; /* ultrix cc workaround, see comments in bn_expand2 */
499 }
500#else
501 memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
502#endif
503
504/* memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
505 a->top=b->top;
506 if ((a->top == 0) && (a->d != NULL))
507 a->d[0]=0;
508 a->neg=b->neg;
509 return(a);
510 }
511
512void BN_clear(BIGNUM *a)
513 {
514 if (a->d != NULL)
515 memset(a->d,0,a->dmax*sizeof(a->d[0]));
516 a->top=0;
517 a->neg=0;
518 }
519
520BN_ULONG BN_get_word(BIGNUM *a)
521 {
522 int i,n;
523 BN_ULONG ret=0;
524
525 n=BN_num_bytes(a);
526 if (n > sizeof(BN_ULONG))
527 return(BN_MASK2);
528 for (i=a->top-1; i>=0; i--)
529 {
530#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
531 ret<<=BN_BITS4; /* stops the compiler complaining */
532 ret<<=BN_BITS4;
533#else
534 ret=0;
535#endif
536 ret|=a->d[i];
537 }
538 return(ret);
539 }
540
541int BN_set_word(BIGNUM *a, BN_ULONG w)
542 {
543 int i,n;
544 if (bn_expand(a,sizeof(BN_ULONG)*8) == NULL) return(0);
545
546 n=sizeof(BN_ULONG)/BN_BYTES;
547 a->neg=0;
548 a->top=0;
549 a->d[0]=(BN_ULONG)w&BN_MASK2;
550 if (a->d[0] != 0) a->top=1;
551 for (i=1; i<n; i++)
552 {
553 /* the following is done instead of
554 * w>>=BN_BITS2 so compilers don't complain
555 * on builds where sizeof(long) == BN_TYPES */
556#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
557 w>>=BN_BITS4;
558 w>>=BN_BITS4;
559#else
560 w=0;
561#endif
562 a->d[i]=(BN_ULONG)w&BN_MASK2;
563 if (a->d[i] != 0) a->top=i+1;
564 }
565 return(1);
566 }
567
568/* ignore negative */
569BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
570 {
571 unsigned int i,m;
572 unsigned int n;
573 BN_ULONG l;
574
575 if (ret == NULL) ret=BN_new();
576 if (ret == NULL) return(NULL);
577 l=0;
578 n=len;
579 if (n == 0)
580 {
581 ret->top=0;
582 return(ret);
583 }
584 if (bn_expand(ret,(int)(n+2)*8) == NULL)
585 return(NULL);
586 i=((n-1)/BN_BYTES)+1;
587 m=((n-1)%(BN_BYTES));
588 ret->top=i;
589 while (n-- > 0)
590 {
591 l=(l<<8L)| *(s++);
592 if (m-- == 0)
593 {
594 ret->d[--i]=l;
595 l=0;
596 m=BN_BYTES-1;
597 }
598 }
599 /* need to call this due to clear byte at top if avoiding
600 * having the top bit set (-ve number) */
601 bn_fix_top(ret);
602 return(ret);
603 }
604
605/* ignore negative */
606int BN_bn2bin(const BIGNUM *a, unsigned char *to)
607 {
608 int n,i;
609 BN_ULONG l;
610
611 n=i=BN_num_bytes(a);
612 while (i-- > 0)
613 {
614 l=a->d[i/BN_BYTES];
615 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
616 }
617 return(n);
618 }
619
620int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
621 {
622 int i;
623 BN_ULONG t1,t2,*ap,*bp;
624
625 bn_check_top(a);
626 bn_check_top(b);
627
628 i=a->top-b->top;
629 if (i != 0) return(i);
630 ap=a->d;
631 bp=b->d;
632 for (i=a->top-1; i>=0; i--)
633 {
634 t1= ap[i];
635 t2= bp[i];
636 if (t1 != t2)
637 return(t1 > t2?1:-1);
638 }
639 return(0);
640 }
641
642int BN_cmp(const BIGNUM *a, const BIGNUM *b)
643 {
644 int i;
645 int gt,lt;
646 BN_ULONG t1,t2;
647
648 if ((a == NULL) || (b == NULL))
649 {
650 if (a != NULL)
651 return(-1);
652 else if (b != NULL)
653 return(1);
654 else
655 return(0);
656 }
657
658 bn_check_top(a);
659 bn_check_top(b);
660
661 if (a->neg != b->neg)
662 {
663 if (a->neg)
664 return(-1);
665 else return(1);
666 }
667 if (a->neg == 0)
668 { gt=1; lt= -1; }
669 else { gt= -1; lt=1; }
670
671 if (a->top > b->top) return(gt);
672 if (a->top < b->top) return(lt);
673 for (i=a->top-1; i>=0; i--)
674 {
675 t1=a->d[i];
676 t2=b->d[i];
677 if (t1 > t2) return(gt);
678 if (t1 < t2) return(lt);
679 }
680 return(0);
681 }
682
683int BN_set_bit(BIGNUM *a, int n)
684 {
685 int i,j,k;
686
687 i=n/BN_BITS2;
688 j=n%BN_BITS2;
689 if (a->top <= i)
690 {
691 if (bn_wexpand(a,i+1) == NULL) return(0);
692 for(k=a->top; k<i+1; k++)
693 a->d[k]=0;
694 a->top=i+1;
695 }
696
697 a->d[i]|=(((BN_ULONG)1)<<j);
698 return(1);
699 }
700
701int BN_clear_bit(BIGNUM *a, int n)
702 {
703 int i,j;
704
705 i=n/BN_BITS2;
706 j=n%BN_BITS2;
707 if (a->top <= i) return(0);
708
709 a->d[i]&=(~(((BN_ULONG)1)<<j));
710 bn_fix_top(a);
711 return(1);
712 }
713
714int BN_is_bit_set(const BIGNUM *a, int n)
715 {
716 int i,j;
717
718 if (n < 0) return(0);
719 i=n/BN_BITS2;
720 j=n%BN_BITS2;
721 if (a->top <= i) return(0);
722 return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
723 }
724
725int BN_mask_bits(BIGNUM *a, int n)
726 {
727 int b,w;
728
729 w=n/BN_BITS2;
730 b=n%BN_BITS2;
731 if (w >= a->top) return(0);
732 if (b == 0)
733 a->top=w;
734 else
735 {
736 a->top=w+1;
737 a->d[w]&= ~(BN_MASK2<<b);
738 }
739 bn_fix_top(a);
740 return(1);
741 }
742
743int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n)
744 {
745 int i;
746 BN_ULONG aa,bb;
747
748 aa=a[n-1];
749 bb=b[n-1];
750 if (aa != bb) return((aa > bb)?1:-1);
751 for (i=n-2; i>=0; i--)
752 {
753 aa=a[i];
754 bb=b[i];
755 if (aa != bb) return((aa > bb)?1:-1);
756 }
757 return(0);
758 }
759
Note: See TracBrowser for help on using the repository browser.