]> git.ipfire.org Git - thirdparty/openssl.git/blame - crypto/bn/bn_lib.c
optical changes
[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
bbb8de09
BM
59#ifndef BN_DEBUG
60# undef NDEBUG /* avoid conflicting definitions */
61# define NDEBUG
62#endif
63
64#include <assert.h>
addb309a 65#include <limits.h>
d02b48c6
RE
66#include <stdio.h>
67#include "cryptlib.h"
68#include "bn_lcl.h"
69
e778802f 70const char *BN_version="Big Number" OPENSSL_VERSION_PTEXT;
dfeab068
RE
71
72/* For a 32 bit machine
73 * 2 - 4 == 128
74 * 3 - 8 == 256
75 * 4 - 16 == 512
76 * 5 - 32 == 1024
77 * 6 - 64 == 2048
78 * 7 - 128 == 4096
79 * 8 - 256 == 8192
80 */
775c63fc
UM
81static int bn_limit_bits=0;
82static int bn_limit_num=8; /* (1<<bn_limit_bits) */
83static int bn_limit_bits_low=0;
84static int bn_limit_num_low=8; /* (1<<bn_limit_bits_low) */
85static int bn_limit_bits_high=0;
86static int bn_limit_num_high=8; /* (1<<bn_limit_bits_high) */
87static int bn_limit_bits_mont=0;
88static int bn_limit_num_mont=8; /* (1<<bn_limit_bits_mont) */
dfeab068 89
6b691a5c 90void BN_set_params(int mult, int high, int low, int mont)
dfeab068
RE
91 {
92 if (mult >= 0)
93 {
94 if (mult > (sizeof(int)*8)-1)
95 mult=sizeof(int)*8-1;
96 bn_limit_bits=mult;
97 bn_limit_num=1<<mult;
98 }
99 if (high >= 0)
100 {
101 if (high > (sizeof(int)*8)-1)
102 high=sizeof(int)*8-1;
103 bn_limit_bits_high=high;
104 bn_limit_num_high=1<<high;
105 }
106 if (low >= 0)
107 {
108 if (low > (sizeof(int)*8)-1)
109 low=sizeof(int)*8-1;
110 bn_limit_bits_low=low;
111 bn_limit_num_low=1<<low;
112 }
113 if (mont >= 0)
114 {
115 if (mont > (sizeof(int)*8)-1)
116 mont=sizeof(int)*8-1;
117 bn_limit_bits_mont=mont;
118 bn_limit_num_mont=1<<mont;
119 }
120 }
121
6b691a5c 122int BN_get_params(int which)
dfeab068
RE
123 {
124 if (which == 0) return(bn_limit_bits);
125 else if (which == 1) return(bn_limit_bits_high);
126 else if (which == 2) return(bn_limit_bits_low);
127 else if (which == 3) return(bn_limit_bits_mont);
128 else return(0);
129 }
d02b48c6 130
98499135 131const BIGNUM *BN_value_one(void)
d02b48c6
RE
132 {
133 static BN_ULONG data_one=1L;
134 static BIGNUM const_one={&data_one,1,1,0};
135
136 return(&const_one);
137 }
138
6b691a5c 139char *BN_options(void)
d02b48c6
RE
140 {
141 static int init=0;
142 static char data[16];
143
144 if (!init)
145 {
146 init++;
147#ifdef BN_LLONG
148 sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULLONG)*8,
149 (int)sizeof(BN_ULONG)*8);
150#else
151 sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULONG)*8,
152 (int)sizeof(BN_ULONG)*8);
153#endif
154 }
155 return(data);
156 }
157
6b691a5c 158int BN_num_bits_word(BN_ULONG l)
d02b48c6 159 {
e14d4443 160 static const char bits[256]={
d02b48c6
RE
161 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
162 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
163 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
164 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
165 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
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 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
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 };
178
dfeab068 179#if defined(SIXTY_FOUR_BIT_LONG)
d02b48c6
RE
180 if (l & 0xffffffff00000000L)
181 {
182 if (l & 0xffff000000000000L)
183 {
184 if (l & 0xff00000000000000L)
185 {
dfeab068 186 return(bits[(int)(l>>56)]+56);
d02b48c6 187 }
dfeab068 188 else return(bits[(int)(l>>48)]+48);
d02b48c6
RE
189 }
190 else
191 {
192 if (l & 0x0000ff0000000000L)
193 {
dfeab068 194 return(bits[(int)(l>>40)]+40);
d02b48c6 195 }
dfeab068 196 else return(bits[(int)(l>>32)]+32);
d02b48c6
RE
197 }
198 }
199 else
200#else
201#ifdef SIXTY_FOUR_BIT
202 if (l & 0xffffffff00000000LL)
203 {
204 if (l & 0xffff000000000000LL)
205 {
206 if (l & 0xff00000000000000LL)
207 {
dfeab068 208 return(bits[(int)(l>>56)]+56);
d02b48c6 209 }
dfeab068 210 else return(bits[(int)(l>>48)]+48);
d02b48c6
RE
211 }
212 else
213 {
214 if (l & 0x0000ff0000000000LL)
215 {
dfeab068 216 return(bits[(int)(l>>40)]+40);
d02b48c6 217 }
dfeab068 218 else return(bits[(int)(l>>32)]+32);
d02b48c6
RE
219 }
220 }
221 else
222#endif
223#endif
224 {
225#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
226 if (l & 0xffff0000L)
227 {
228 if (l & 0xff000000L)
dfeab068
RE
229 return(bits[(int)(l>>24L)]+24);
230 else return(bits[(int)(l>>16L)]+16);
d02b48c6
RE
231 }
232 else
233#endif
234 {
235#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
236 if (l & 0xff00L)
dfeab068 237 return(bits[(int)(l>>8)]+8);
d02b48c6
RE
238 else
239#endif
dfeab068 240 return(bits[(int)(l )] );
d02b48c6
RE
241 }
242 }
243 }
244
84c15db5 245int BN_num_bits(const BIGNUM *a)
d02b48c6
RE
246 {
247 BN_ULONG l;
248 int i;
249
dfeab068
RE
250 bn_check_top(a);
251
d02b48c6
RE
252 if (a->top == 0) return(0);
253 l=a->d[a->top-1];
bbb8de09 254 assert(l != 0);
d02b48c6 255 i=(a->top-1)*BN_BITS2;
d02b48c6
RE
256 return(i+BN_num_bits_word(l));
257 }
258
6b691a5c 259void BN_clear_free(BIGNUM *a)
d02b48c6 260 {
dfeab068
RE
261 int i;
262
d02b48c6
RE
263 if (a == NULL) return;
264 if (a->d != NULL)
265 {
2d978cbd 266 memset(a->d,0,a->dmax*sizeof(a->d[0]));
dfeab068 267 if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
26a3a48d 268 OPENSSL_free(a->d);
d02b48c6 269 }
dfeab068 270 i=BN_get_flags(a,BN_FLG_MALLOCED);
d02b48c6 271 memset(a,0,sizeof(BIGNUM));
dfeab068 272 if (i)
26a3a48d 273 OPENSSL_free(a);
d02b48c6
RE
274 }
275
6b691a5c 276void BN_free(BIGNUM *a)
d02b48c6
RE
277 {
278 if (a == NULL) return;
dfeab068 279 if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
26a3a48d 280 OPENSSL_free(a->d);
dfeab068
RE
281 a->flags|=BN_FLG_FREE; /* REMOVE? */
282 if (a->flags & BN_FLG_MALLOCED)
26a3a48d 283 OPENSSL_free(a);
dfeab068
RE
284 }
285
6b691a5c 286void BN_init(BIGNUM *a)
dfeab068
RE
287 {
288 memset(a,0,sizeof(BIGNUM));
d02b48c6
RE
289 }
290
6b691a5c 291BIGNUM *BN_new(void)
d02b48c6
RE
292 {
293 BIGNUM *ret;
d02b48c6 294
26a3a48d 295 if ((ret=(BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL)
dfeab068
RE
296 {
297 BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
298 return(NULL);
299 }
300 ret->flags=BN_FLG_MALLOCED;
d02b48c6
RE
301 ret->top=0;
302 ret->neg=0;
2d978cbd 303 ret->dmax=0;
dfeab068 304 ret->d=NULL;
d02b48c6 305 return(ret);
d02b48c6
RE
306 }
307
020fc820
RL
308/* This is used both by bn_expand2() and bn_dup_expand() */
309/* The caller MUST check that words > b->dmax before calling this */
a08bcccc 310static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
d02b48c6 311 {
020fc820 312 BN_ULONG *A,*a = NULL;
e14d4443
UM
313 const BN_ULONG *B;
314 int i;
dfeab068 315
152a689c
BM
316 if (words > (INT_MAX/(4*BN_BITS2)))
317 {
e5164b70 318 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_BIGNUM_TOO_LONG);
152a689c
BM
319 return NULL;
320 }
321
020fc820
RL
322 bn_check_top(b);
323 if (BN_get_flags(b,BN_FLG_STATIC_DATA))
d02b48c6 324 {
a08bcccc 325 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
020fc820
RL
326 return(NULL);
327 }
328 a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*(words+1));
329 if (A == NULL)
330 {
a08bcccc 331 BNerr(BN_F_BN_EXPAND_INTERNAL,ERR_R_MALLOC_FAILURE);
020fc820
RL
332 return(NULL);
333 }
dfeab068 334#if 1
020fc820
RL
335 B=b->d;
336 /* Check if the previous number needs to be copied */
337 if (B != NULL)
338 {
020fc820
RL
339 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
340 {
341 /*
342 * The fact that the loop is unrolled
343 * 4-wise is a tribute to Intel. It's
344 * the one that doesn't have enough
345 * registers to accomodate more data.
346 * I'd unroll it 8-wise otherwise:-)
347 *
348 * <appro@fy.chalmers.se>
349 */
350 BN_ULONG a0,a1,a2,a3;
351 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
352 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
953937bd 353 }
020fc820 354 switch (b->top&3)
953937bd 355 {
020fc820
RL
356 case 3: A[2]=B[2];
357 case 2: A[1]=B[1];
358 case 1: A[0]=B[0];
a08bcccc
BM
359 case 0: /* workaround for ultrix cc: without 'case 0', the optimizer does
360 * the switch table by doing a=top&3; a--; goto jump_table[a];
361 * which fails for top== 0 */
362 ;
953937bd 363 }
020fc820
RL
364 }
365
dfeab068 366#else
020fc820
RL
367 memset(A,0,sizeof(BN_ULONG)*(words+1));
368 memcpy(A,b->d,sizeof(b->d[0])*b->top);
dfeab068
RE
369#endif
370
020fc820
RL
371 return(a);
372 }
dfeab068 373
020fc820
RL
374/* This is an internal function that can be used instead of bn_expand2()
375 * when there is a need to copy BIGNUMs instead of only expanding the
376 * data part, while still expanding them.
377 * Especially useful when needing to expand BIGNUMs that are declared
378 * 'const' and should therefore not be changed.
379 * The reason to use this instead of a BN_dup() followed by a bn_expand2()
380 * is memory allocation overhead. A BN_dup() followed by a bn_expand2()
381 * will allocate new memory for the BIGNUM data twice, and free it once,
382 * while bn_dup_expand() makes sure allocation is made only once.
383 */
384
385BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
386 {
387 BIGNUM *r = NULL;
388
12593e6f
BM
389 /* This function does not work if
390 * words <= b->dmax && top < words
391 * because BN_dup() does not preserve 'dmax'!
392 * (But bn_dup_expand() is not used anywhere yet.)
393 */
394
020fc820
RL
395 if (words > b->dmax)
396 {
a08bcccc 397 BN_ULONG *a = bn_expand_internal(b, words);
020fc820
RL
398
399 if (a)
400 {
401 r = BN_new();
58f0f52e
BM
402 if (r)
403 {
404 r->top = b->top;
405 r->dmax = words;
406 r->neg = b->neg;
407 r->d = a;
408 }
409 else
410 {
411 /* r == NULL, BN_new failure */
412 OPENSSL_free(a);
413 }
020fc820 414 }
58f0f52e 415 /* If a == NULL, there was an error in allocation in
a08bcccc 416 bn_expand_internal(), and NULL should be returned */
020fc820
RL
417 }
418 else
419 {
420 r = BN_dup(b);
421 }
422
423 return r;
424 }
425
426/* This is an internal function that should not be used in applications.
12593e6f
BM
427 * It ensures that 'b' has enough room for a 'words' word number
428 * and initialises the unused part of b->d with leading zeros.
020fc820
RL
429 * It is mostly used by the various BIGNUM routines. If there is an error,
430 * NULL is returned. If not, 'b' is returned. */
431
432BIGNUM *bn_expand2(BIGNUM *b, int words)
433 {
12593e6f
BM
434 BN_ULONG *A;
435 int i;
436
020fc820
RL
437 if (words > b->dmax)
438 {
a08bcccc 439 BN_ULONG *a = bn_expand_internal(b, words);
020fc820
RL
440
441 if (a)
442 {
a08bcccc
BM
443 if (b->d)
444 OPENSSL_free(b->d);
020fc820
RL
445 b->d=a;
446 b->dmax=words;
447 }
448 else
449 b = NULL;
d02b48c6 450 }
12593e6f
BM
451
452 /* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
453 A = &(b->d[b->top]);
454 for (i=(words - b->top)>>3; i>0; i--,A+=8)
455 {
456 A[0]=0; A[1]=0; A[2]=0; A[3]=0;
457 A[4]=0; A[5]=0; A[6]=0; A[7]=0;
458 }
459 for (i=(words - b->top)&7; i>0; i--,A++)
460 A[0]=0;
461
020fc820 462 return b;
d02b48c6
RE
463 }
464
84c15db5 465BIGNUM *BN_dup(const BIGNUM *a)
d02b48c6 466 {
e0bf5c11 467 BIGNUM *r, *t;
d02b48c6 468
8d85b33e
BM
469 if (a == NULL) return NULL;
470
dfeab068
RE
471 bn_check_top(a);
472
e0bf5c11
BM
473 t = BN_new();
474 if (t == NULL) return(NULL);
475 r = BN_copy(t, a);
476 /* now r == t || r == NULL */
477 if (r == NULL)
478 BN_free(t);
479 return r;
d02b48c6
RE
480 }
481
84c15db5 482BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
d02b48c6 483 {
58964a49 484 int i;
e14d4443
UM
485 BN_ULONG *A;
486 const BN_ULONG *B;
58964a49 487
dfeab068
RE
488 bn_check_top(b);
489
58964a49
RE
490 if (a == b) return(a);
491 if (bn_wexpand(a,b->top) == NULL) return(NULL);
492
493#if 1
494 A=a->d;
495 B=b->d;
e14d4443 496 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
58964a49 497 {
e14d4443
UM
498 BN_ULONG a0,a1,a2,a3;
499 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
500 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
58964a49 501 }
e14d4443 502 switch (b->top&3)
58964a49 503 {
e14d4443
UM
504 case 3: A[2]=B[2];
505 case 2: A[1]=B[1];
506 case 1: A[0]=B[0];
a08bcccc 507 case 0: ; /* ultrix cc workaround, see comments in bn_expand_internal */
58964a49
RE
508 }
509#else
d02b48c6 510 memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
58964a49
RE
511#endif
512
d02b48c6
RE
513/* memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
514 a->top=b->top;
dfeab068 515 if ((a->top == 0) && (a->d != NULL))
58964a49 516 a->d[0]=0;
d02b48c6
RE
517 a->neg=b->neg;
518 return(a);
519 }
520
78a0c1f1
BM
521void BN_swap(BIGNUM *a, BIGNUM *b)
522 {
523 int flags_old_a, flags_old_b;
524 BN_ULONG *tmp_d;
525 int tmp_top, tmp_dmax, tmp_neg;
526
527 flags_old_a = a->flags;
528 flags_old_b = b->flags;
529
530 tmp_d = a->d;
531 tmp_top = a->top;
532 tmp_dmax = a->dmax;
533 tmp_neg = a->neg;
534
535 a->d = b->d;
536 a->top = b->top;
537 a->dmax = b->dmax;
538 a->neg = b->neg;
539
540 b->d = tmp_d;
541 b->top = tmp_top;
542 b->dmax = tmp_dmax;
543 b->neg = tmp_neg;
544
545 a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
546 b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
547 }
548
549
6b691a5c 550void BN_clear(BIGNUM *a)
d02b48c6 551 {
dfeab068 552 if (a->d != NULL)
2d978cbd 553 memset(a->d,0,a->dmax*sizeof(a->d[0]));
d02b48c6
RE
554 a->top=0;
555 a->neg=0;
556 }
557
020fc820 558BN_ULONG BN_get_word(const BIGNUM *a)
d02b48c6
RE
559 {
560 int i,n;
dfeab068 561 BN_ULONG ret=0;
d02b48c6
RE
562
563 n=BN_num_bytes(a);
dfeab068 564 if (n > sizeof(BN_ULONG))
d02b48c6 565 return(BN_MASK2);
d02b48c6
RE
566 for (i=a->top-1; i>=0; i--)
567 {
568#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
569 ret<<=BN_BITS4; /* stops the compiler complaining */
570 ret<<=BN_BITS4;
e14d4443
UM
571#else
572 ret=0;
d02b48c6
RE
573#endif
574 ret|=a->d[i];
575 }
576 return(ret);
577 }
578
6b691a5c 579int BN_set_word(BIGNUM *a, BN_ULONG w)
d02b48c6
RE
580 {
581 int i,n;
dfeab068 582 if (bn_expand(a,sizeof(BN_ULONG)*8) == NULL) return(0);
d02b48c6 583
dfeab068 584 n=sizeof(BN_ULONG)/BN_BYTES;
d02b48c6
RE
585 a->neg=0;
586 a->top=0;
587 a->d[0]=(BN_ULONG)w&BN_MASK2;
588 if (a->d[0] != 0) a->top=1;
589 for (i=1; i<n; i++)
590 {
591 /* the following is done instead of
592 * w>>=BN_BITS2 so compilers don't complain
593 * on builds where sizeof(long) == BN_TYPES */
594#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
595 w>>=BN_BITS4;
596 w>>=BN_BITS4;
e14d4443
UM
597#else
598 w=0;
d02b48c6
RE
599#endif
600 a->d[i]=(BN_ULONG)w&BN_MASK2;
601 if (a->d[i] != 0) a->top=i+1;
602 }
603 return(1);
604 }
605
61f5b6f3 606BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
d02b48c6
RE
607 {
608 unsigned int i,m;
609 unsigned int n;
610 BN_ULONG l;
611
612 if (ret == NULL) ret=BN_new();
613 if (ret == NULL) return(NULL);
614 l=0;
615 n=len;
616 if (n == 0)
617 {
618 ret->top=0;
619 return(ret);
620 }
621 if (bn_expand(ret,(int)(n+2)*8) == NULL)
622 return(NULL);
623 i=((n-1)/BN_BYTES)+1;
624 m=((n-1)%(BN_BYTES));
91616729
BM
625 ret->top=i;
626 ret->neg=0;
d02b48c6
RE
627 while (n-- > 0)
628 {
629 l=(l<<8L)| *(s++);
630 if (m-- == 0)
631 {
632 ret->d[--i]=l;
633 l=0;
634 m=BN_BYTES-1;
635 }
636 }
637 /* need to call this due to clear byte at top if avoiding
638 * having the top bit set (-ve number) */
639 bn_fix_top(ret);
640 return(ret);
641 }
642
643/* ignore negative */
8623f693 644int BN_bn2bin(const BIGNUM *a, unsigned char *to)
d02b48c6
RE
645 {
646 int n,i;
647 BN_ULONG l;
648
649 n=i=BN_num_bytes(a);
650 while (i-- > 0)
651 {
652 l=a->d[i/BN_BYTES];
653 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
654 }
655 return(n);
656 }
657
84c15db5 658int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
d02b48c6
RE
659 {
660 int i;
661 BN_ULONG t1,t2,*ap,*bp;
662
dfeab068
RE
663 bn_check_top(a);
664 bn_check_top(b);
665
d02b48c6
RE
666 i=a->top-b->top;
667 if (i != 0) return(i);
668 ap=a->d;
669 bp=b->d;
670 for (i=a->top-1; i>=0; i--)
671 {
672 t1= ap[i];
673 t2= bp[i];
674 if (t1 != t2)
675 return(t1 > t2?1:-1);
676 }
677 return(0);
678 }
679
84c15db5 680int BN_cmp(const BIGNUM *a, const BIGNUM *b)
d02b48c6
RE
681 {
682 int i;
683 int gt,lt;
684 BN_ULONG t1,t2;
685
686 if ((a == NULL) || (b == NULL))
687 {
688 if (a != NULL)
689 return(-1);
690 else if (b != NULL)
691 return(1);
692 else
693 return(0);
694 }
dfeab068
RE
695
696 bn_check_top(a);
697 bn_check_top(b);
698
d02b48c6
RE
699 if (a->neg != b->neg)
700 {
701 if (a->neg)
702 return(-1);
703 else return(1);
704 }
705 if (a->neg == 0)
706 { gt=1; lt= -1; }
707 else { gt= -1; lt=1; }
708
709 if (a->top > b->top) return(gt);
710 if (a->top < b->top) return(lt);
711 for (i=a->top-1; i>=0; i--)
712 {
713 t1=a->d[i];
714 t2=b->d[i];
715 if (t1 > t2) return(gt);
716 if (t1 < t2) return(lt);
717 }
718 return(0);
719 }
720
6b691a5c 721int BN_set_bit(BIGNUM *a, int n)
d02b48c6 722 {
dfeab068 723 int i,j,k;
d02b48c6
RE
724
725 i=n/BN_BITS2;
726 j=n%BN_BITS2;
58964a49
RE
727 if (a->top <= i)
728 {
dfeab068
RE
729 if (bn_wexpand(a,i+1) == NULL) return(0);
730 for(k=a->top; k<i+1; k++)
731 a->d[k]=0;
58964a49
RE
732 a->top=i+1;
733 }
d02b48c6 734
e14d4443 735 a->d[i]|=(((BN_ULONG)1)<<j);
d02b48c6
RE
736 return(1);
737 }
738
6b691a5c 739int BN_clear_bit(BIGNUM *a, int n)
d02b48c6
RE
740 {
741 int i,j;
742
743 i=n/BN_BITS2;
744 j=n%BN_BITS2;
745 if (a->top <= i) return(0);
746
e14d4443 747 a->d[i]&=(~(((BN_ULONG)1)<<j));
dfeab068 748 bn_fix_top(a);
d02b48c6
RE
749 return(1);
750 }
751
84c15db5 752int BN_is_bit_set(const BIGNUM *a, int n)
d02b48c6
RE
753 {
754 int i,j;
755
756 if (n < 0) return(0);
757 i=n/BN_BITS2;
758 j=n%BN_BITS2;
759 if (a->top <= i) return(0);
760 return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
761 }
762
6b691a5c 763int BN_mask_bits(BIGNUM *a, int n)
d02b48c6
RE
764 {
765 int b,w;
766
767 w=n/BN_BITS2;
768 b=n%BN_BITS2;
769 if (w >= a->top) return(0);
770 if (b == 0)
771 a->top=w;
772 else
773 {
774 a->top=w+1;
775 a->d[w]&= ~(BN_MASK2<<b);
d02b48c6 776 }
dfeab068 777 bn_fix_top(a);
d02b48c6
RE
778 return(1);
779 }
dfeab068 780
cbd48ba6 781int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
dfeab068
RE
782 {
783 int i;
784 BN_ULONG aa,bb;
785
786 aa=a[n-1];
787 bb=b[n-1];
788 if (aa != bb) return((aa > bb)?1:-1);
789 for (i=n-2; i>=0; i--)
790 {
791 aa=a[i];
792 bb=b[i];
793 if (aa != bb) return((aa > bb)?1:-1);
794 }
795 return(0);
796 }
52a1bab2 797
c21c35e6
RL
798/* Here follows a specialised variants of bn_cmp_words(). It has the
799 property of performing the operation on arrays of different sizes.
800 The sizes of those arrays is expressed through cl, which is the
801 common length ( basicall, min(len(a),len(b)) ), and dl, which is the
802 delta between the two lengths, calculated as len(a)-len(b).
803 All lengths are the number of BN_ULONGs... */
804
52a1bab2
UM
805int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
806 int cl, int dl)
807 {
808 int n,i;
809 n = cl-1;
810
811 if (dl < 0)
812 {
b26f84cb 813 for (i=dl; i<0; i++)
52a1bab2 814 {
b26f84cb 815 if (b[n-i] != 0)
52a1bab2
UM
816 return -1; /* a < b */
817 }
818 }
819 if (dl > 0)
820 {
821 for (i=dl; i>0; i--)
822 {
823 if (a[n+i] != 0)
824 return 1; /* a > b */
825 }
826 }
827 return bn_cmp_words(a,b,cl);
828 }