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