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