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