]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/bn/bn_lib.c
Support the EBCDIC character set and BS2000/OSD-POSIX (work in progress).
[thirdparty/openssl.git] / crypto / bn / bn_lib.c
CommitLineData
d02b48c6 1/* crypto/bn/bn_lib.c */
58964a49 2/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
d02b48c6
RE
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
e778802f 63const char *BN_version="Big Number" OPENSSL_VERSION_PTEXT;
dfeab068
RE
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 */
7f0dae32
BM
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) */
dfeab068 82
6b691a5c 83void BN_set_params(int mult, int high, int low, int mont)
dfeab068
RE
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
6b691a5c 115int BN_get_params(int which)
dfeab068
RE
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 }
d02b48c6 123
6b691a5c 124BIGNUM *BN_value_one(void)
d02b48c6
RE
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
6b691a5c 132char *BN_options(void)
d02b48c6
RE
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
6b691a5c 151int BN_num_bits_word(BN_ULONG l)
d02b48c6 152 {
e14d4443 153 static const char bits[256]={
d02b48c6
RE
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
dfeab068 172#if defined(SIXTY_FOUR_BIT_LONG)
d02b48c6
RE
173 if (l & 0xffffffff00000000L)
174 {
175 if (l & 0xffff000000000000L)
176 {
177 if (l & 0xff00000000000000L)
178 {
dfeab068 179 return(bits[(int)(l>>56)]+56);
d02b48c6 180 }
dfeab068 181 else return(bits[(int)(l>>48)]+48);
d02b48c6
RE
182 }
183 else
184 {
185 if (l & 0x0000ff0000000000L)
186 {
dfeab068 187 return(bits[(int)(l>>40)]+40);
d02b48c6 188 }
dfeab068 189 else return(bits[(int)(l>>32)]+32);
d02b48c6
RE
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 {
dfeab068 201 return(bits[(int)(l>>56)]+56);
d02b48c6 202 }
dfeab068 203 else return(bits[(int)(l>>48)]+48);
d02b48c6
RE
204 }
205 else
206 {
207 if (l & 0x0000ff0000000000LL)
208 {
dfeab068 209 return(bits[(int)(l>>40)]+40);
d02b48c6 210 }
dfeab068 211 else return(bits[(int)(l>>32)]+32);
d02b48c6
RE
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)
dfeab068
RE
222 return(bits[(int)(l>>24L)]+24);
223 else return(bits[(int)(l>>16L)]+16);
d02b48c6
RE
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)
dfeab068 230 return(bits[(int)(l>>8)]+8);
d02b48c6
RE
231 else
232#endif
dfeab068 233 return(bits[(int)(l )] );
d02b48c6
RE
234 }
235 }
236 }
237
6b691a5c 238int BN_num_bits(BIGNUM *a)
d02b48c6
RE
239 {
240 BN_ULONG l;
241 int i;
242
dfeab068
RE
243 bn_check_top(a);
244
d02b48c6
RE
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 {
58964a49 250#if !defined(NO_STDIO) && !defined(WIN16)
d02b48c6
RE
251 fprintf(stderr,"BAD TOP VALUE\n");
252#endif
253 abort();
254 }
255 return(i+BN_num_bits_word(l));
256 }
257
6b691a5c 258void BN_clear_free(BIGNUM *a)
d02b48c6 259 {
dfeab068
RE
260 int i;
261
d02b48c6
RE
262 if (a == NULL) return;
263 if (a->d != NULL)
264 {
265 memset(a->d,0,a->max*sizeof(a->d[0]));
dfeab068
RE
266 if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
267 Free(a->d);
d02b48c6 268 }
dfeab068 269 i=BN_get_flags(a,BN_FLG_MALLOCED);
d02b48c6 270 memset(a,0,sizeof(BIGNUM));
dfeab068
RE
271 if (i)
272 Free(a);
d02b48c6
RE
273 }
274
6b691a5c 275void BN_free(BIGNUM *a)
d02b48c6
RE
276 {
277 if (a == NULL) return;
dfeab068
RE
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
6b691a5c 285void BN_init(BIGNUM *a)
dfeab068
RE
286 {
287 memset(a,0,sizeof(BIGNUM));
d02b48c6
RE
288 }
289
6b691a5c 290BIGNUM *BN_new(void)
d02b48c6
RE
291 {
292 BIGNUM *ret;
d02b48c6 293
dfeab068
RE
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;
d02b48c6
RE
300 ret->top=0;
301 ret->neg=0;
dfeab068
RE
302 ret->max=0;
303 ret->d=NULL;
d02b48c6 304 return(ret);
d02b48c6
RE
305 }
306
dfeab068 307
6b691a5c 308BN_CTX *BN_CTX_new(void)
d02b48c6
RE
309 {
310 BN_CTX *ret;
d02b48c6
RE
311
312 ret=(BN_CTX *)Malloc(sizeof(BN_CTX));
dfeab068 313 if (ret == NULL)
d02b48c6 314 {
dfeab068
RE
315 BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);
316 return(NULL);
d02b48c6
RE
317 }
318
dfeab068
RE
319 BN_CTX_init(ret);
320 ret->flags=BN_FLG_MALLOCED;
d02b48c6 321 return(ret);
dfeab068
RE
322 }
323
6b691a5c 324void BN_CTX_init(BN_CTX *ctx)
dfeab068
RE
325 {
326 memset(ctx,0,sizeof(BN_CTX));
327 ctx->tos=0;
328 ctx->flags=0;
d02b48c6
RE
329 }
330
6b691a5c 331void BN_CTX_free(BN_CTX *c)
d02b48c6
RE
332 {
333 int i;
334
e03ddfae
BL
335 if(c == NULL)
336 return;
337
d02b48c6 338 for (i=0; i<BN_CTX_NUM; i++)
dfeab068
RE
339 BN_clear_free(&(c->bn[i]));
340 if (c->flags & BN_FLG_MALLOCED)
341 Free(c);
d02b48c6
RE
342 }
343
6b691a5c 344BIGNUM *bn_expand2(BIGNUM *b, int words)
d02b48c6 345 {
e14d4443
UM
346 BN_ULONG *A,*a;
347 const BN_ULONG *B;
348 int i;
dfeab068
RE
349
350 bn_check_top(b);
d02b48c6 351
58964a49 352 if (words > b->max)
d02b48c6 353 {
dfeab068
RE
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)
d02b48c6
RE
362 {
363 BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE);
364 return(NULL);
365 }
dfeab068
RE
366#if 1
367 B=b->d;
953937bd 368 /* Check if the previous number needs to be copied */
dfeab068
RE
369 if (B != NULL)
370 {
e14d4443 371#if 0
953937bd
DSH
372 /* This lot is an unrolled loop to copy b->top
373 * BN_ULONGs from B to A
374 */
e14d4443
UM
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 */
dfeab068
RE
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 }
e14d4443
UM
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
953937bd
DSH
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
e14d4443
UM
466 A= &(b->d[b->top]);
467 for (i=(b->max - b->top)>>3; i>0; i--,A+=8)
953937bd 468 {
e14d4443
UM
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;
953937bd 471 }
e14d4443
UM
472 for (i=(b->max - b->top)&7; i>0; i--,A++)
473 A[0]=0;
dfeab068 474#else
e14d4443
UM
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;
dfeab068
RE
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;} */
dfeab068 483
d02b48c6
RE
484 }
485 return(b);
486 }
487
6b691a5c 488BIGNUM *BN_dup(BIGNUM *a)
d02b48c6
RE
489 {
490 BIGNUM *r;
491
dfeab068
RE
492 bn_check_top(a);
493
d02b48c6
RE
494 r=BN_new();
495 if (r == NULL) return(NULL);
496 return((BIGNUM *)BN_copy(r,a));
497 }
498
6b691a5c 499BIGNUM *BN_copy(BIGNUM *a, BIGNUM *b)
d02b48c6 500 {
58964a49 501 int i;
e14d4443
UM
502 BN_ULONG *A;
503 const BN_ULONG *B;
58964a49 504
dfeab068
RE
505 bn_check_top(b);
506
58964a49
RE
507 if (a == b) return(a);
508 if (bn_wexpand(a,b->top) == NULL) return(NULL);
509
510#if 1
511 A=a->d;
512 B=b->d;
e14d4443 513 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
58964a49 514 {
e14d4443
UM
515 BN_ULONG a0,a1,a2,a3;
516 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
517 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
58964a49 518 }
e14d4443 519 switch (b->top&3)
58964a49 520 {
e14d4443
UM
521 case 3: A[2]=B[2];
522 case 2: A[1]=B[1];
523 case 1: A[0]=B[0];
524 case 0: ; /* ultrix cc workaround, see comments in bn_expand2 */
58964a49
RE
525 }
526#else
d02b48c6 527 memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
58964a49
RE
528#endif
529
d02b48c6
RE
530/* memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
531 a->top=b->top;
dfeab068 532 if ((a->top == 0) && (a->d != NULL))
58964a49 533 a->d[0]=0;
d02b48c6
RE
534 a->neg=b->neg;
535 return(a);
536 }
537
6b691a5c 538void BN_clear(BIGNUM *a)
d02b48c6 539 {
dfeab068
RE
540 if (a->d != NULL)
541 memset(a->d,0,a->max*sizeof(a->d[0]));
d02b48c6
RE
542 a->top=0;
543 a->neg=0;
544 }
545
6b691a5c 546BN_ULONG BN_get_word(BIGNUM *a)
d02b48c6
RE
547 {
548 int i,n;
dfeab068 549 BN_ULONG ret=0;
d02b48c6
RE
550
551 n=BN_num_bytes(a);
dfeab068 552 if (n > sizeof(BN_ULONG))
d02b48c6 553 return(BN_MASK2);
d02b48c6
RE
554 for (i=a->top-1; i>=0; i--)
555 {
556#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
557 ret<<=BN_BITS4; /* stops the compiler complaining */
558 ret<<=BN_BITS4;
e14d4443
UM
559#else
560 ret=0;
d02b48c6
RE
561#endif
562 ret|=a->d[i];
563 }
564 return(ret);
565 }
566
6b691a5c 567int BN_set_word(BIGNUM *a, BN_ULONG w)
d02b48c6
RE
568 {
569 int i,n;
dfeab068 570 if (bn_expand(a,sizeof(BN_ULONG)*8) == NULL) return(0);
d02b48c6 571
dfeab068 572 n=sizeof(BN_ULONG)/BN_BYTES;
d02b48c6
RE
573 a->neg=0;
574 a->top=0;
575 a->d[0]=(BN_ULONG)w&BN_MASK2;
576 if (a->d[0] != 0) a->top=1;
577 for (i=1; i<n; i++)
578 {
579 /* the following is done instead of
580 * w>>=BN_BITS2 so compilers don't complain
581 * on builds where sizeof(long) == BN_TYPES */
582#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
583 w>>=BN_BITS4;
584 w>>=BN_BITS4;
e14d4443
UM
585#else
586 w=0;
d02b48c6
RE
587#endif
588 a->d[i]=(BN_ULONG)w&BN_MASK2;
589 if (a->d[i] != 0) a->top=i+1;
590 }
591 return(1);
592 }
593
594/* ignore negative */
61f5b6f3 595BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
d02b48c6
RE
596 {
597 unsigned int i,m;
598 unsigned int n;
599 BN_ULONG l;
600
601 if (ret == NULL) ret=BN_new();
602 if (ret == NULL) return(NULL);
603 l=0;
604 n=len;
605 if (n == 0)
606 {
607 ret->top=0;
608 return(ret);
609 }
610 if (bn_expand(ret,(int)(n+2)*8) == NULL)
611 return(NULL);
612 i=((n-1)/BN_BYTES)+1;
613 m=((n-1)%(BN_BYTES));
614 ret->top=i;
615 while (n-- > 0)
616 {
617 l=(l<<8L)| *(s++);
618 if (m-- == 0)
619 {
620 ret->d[--i]=l;
621 l=0;
622 m=BN_BYTES-1;
623 }
624 }
625 /* need to call this due to clear byte at top if avoiding
626 * having the top bit set (-ve number) */
627 bn_fix_top(ret);
628 return(ret);
629 }
630
631/* ignore negative */
6b691a5c 632int BN_bn2bin(BIGNUM *a, unsigned char *to)
d02b48c6
RE
633 {
634 int n,i;
635 BN_ULONG l;
636
637 n=i=BN_num_bytes(a);
638 while (i-- > 0)
639 {
640 l=a->d[i/BN_BYTES];
641 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
642 }
643 return(n);
644 }
645
6b691a5c 646int BN_ucmp(BIGNUM *a, BIGNUM *b)
d02b48c6
RE
647 {
648 int i;
649 BN_ULONG t1,t2,*ap,*bp;
650
dfeab068
RE
651 bn_check_top(a);
652 bn_check_top(b);
653
d02b48c6
RE
654 i=a->top-b->top;
655 if (i != 0) return(i);
656 ap=a->d;
657 bp=b->d;
658 for (i=a->top-1; i>=0; i--)
659 {
660 t1= ap[i];
661 t2= bp[i];
662 if (t1 != t2)
663 return(t1 > t2?1:-1);
664 }
665 return(0);
666 }
667
6b691a5c 668int BN_cmp(BIGNUM *a, BIGNUM *b)
d02b48c6
RE
669 {
670 int i;
671 int gt,lt;
672 BN_ULONG t1,t2;
673
674 if ((a == NULL) || (b == NULL))
675 {
676 if (a != NULL)
677 return(-1);
678 else if (b != NULL)
679 return(1);
680 else
681 return(0);
682 }
dfeab068
RE
683
684 bn_check_top(a);
685 bn_check_top(b);
686
d02b48c6
RE
687 if (a->neg != b->neg)
688 {
689 if (a->neg)
690 return(-1);
691 else return(1);
692 }
693 if (a->neg == 0)
694 { gt=1; lt= -1; }
695 else { gt= -1; lt=1; }
696
697 if (a->top > b->top) return(gt);
698 if (a->top < b->top) return(lt);
699 for (i=a->top-1; i>=0; i--)
700 {
701 t1=a->d[i];
702 t2=b->d[i];
703 if (t1 > t2) return(gt);
704 if (t1 < t2) return(lt);
705 }
706 return(0);
707 }
708
6b691a5c 709int BN_set_bit(BIGNUM *a, int n)
d02b48c6 710 {
dfeab068 711 int i,j,k;
d02b48c6
RE
712
713 i=n/BN_BITS2;
714 j=n%BN_BITS2;
58964a49
RE
715 if (a->top <= i)
716 {
dfeab068
RE
717 if (bn_wexpand(a,i+1) == NULL) return(0);
718 for(k=a->top; k<i+1; k++)
719 a->d[k]=0;
58964a49
RE
720 a->top=i+1;
721 }
d02b48c6 722
e14d4443 723 a->d[i]|=(((BN_ULONG)1)<<j);
d02b48c6
RE
724 return(1);
725 }
726
6b691a5c 727int BN_clear_bit(BIGNUM *a, int n)
d02b48c6
RE
728 {
729 int i,j;
730
731 i=n/BN_BITS2;
732 j=n%BN_BITS2;
733 if (a->top <= i) return(0);
734
e14d4443 735 a->d[i]&=(~(((BN_ULONG)1)<<j));
dfeab068 736 bn_fix_top(a);
d02b48c6
RE
737 return(1);
738 }
739
6b691a5c 740int BN_is_bit_set(BIGNUM *a, int n)
d02b48c6
RE
741 {
742 int i,j;
743
744 if (n < 0) return(0);
745 i=n/BN_BITS2;
746 j=n%BN_BITS2;
747 if (a->top <= i) return(0);
748 return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
749 }
750
6b691a5c 751int BN_mask_bits(BIGNUM *a, int n)
d02b48c6
RE
752 {
753 int b,w;
754
755 w=n/BN_BITS2;
756 b=n%BN_BITS2;
757 if (w >= a->top) return(0);
758 if (b == 0)
759 a->top=w;
760 else
761 {
762 a->top=w+1;
763 a->d[w]&= ~(BN_MASK2<<b);
d02b48c6 764 }
dfeab068 765 bn_fix_top(a);
d02b48c6
RE
766 return(1);
767 }
dfeab068 768
6b691a5c 769int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n)
dfeab068
RE
770 {
771 int i;
772 BN_ULONG aa,bb;
773
774 aa=a[n-1];
775 bb=b[n-1];
776 if (aa != bb) return((aa > bb)?1:-1);
777 for (i=n-2; i>=0; i--)
778 {
779 aa=a[i];
780 bb=b[i];
781 if (aa != bb) return((aa > bb)?1:-1);
782 }
783 return(0);
784 }
785