blob: d29a7cc8df299b584aafc53a2d08cfeac0333bd7 [file] [log] [blame]
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +00001/* crypto/bn/bn_lib.c */
Ralf S. Engelschall58964a41998-12-21 10:56:39 +00002/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +00003 * 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
Bodo Möllerbbb8de02000-09-04 15:34:43 +000059#ifndef BN_DEBUG
60# undef NDEBUG /* avoid conflicting definitions */
61# define NDEBUG
62#endif
63
64#include <assert.h>
Bodo Mölleraddb3092000-12-03 09:55:08 +000065#include <limits.h>
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +000066#include <stdio.h>
67#include "cryptlib.h"
68#include "bn_lcl.h"
69
Ben Lauriee7788021999-04-17 21:25:43 +000070const char *BN_version="Big Number" OPENSSL_VERSION_PTEXT;
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +000071
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 */
Ulf Möller775c63f2000-02-26 22:16:47 +000081static 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) */
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +000089
Ulf Möller6b691a51999-04-19 21:31:43 +000090void BN_set_params(int mult, int high, int low, int mont)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +000091 {
92 if (mult >= 0)
93 {
Geoff Thorpe27545972003-10-29 20:24:15 +000094 if (mult > (int)(sizeof(int)*8)-1)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +000095 mult=sizeof(int)*8-1;
96 bn_limit_bits=mult;
97 bn_limit_num=1<<mult;
98 }
99 if (high >= 0)
100 {
Geoff Thorpe27545972003-10-29 20:24:15 +0000101 if (high > (int)(sizeof(int)*8)-1)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000102 high=sizeof(int)*8-1;
103 bn_limit_bits_high=high;
104 bn_limit_num_high=1<<high;
105 }
106 if (low >= 0)
107 {
Geoff Thorpe27545972003-10-29 20:24:15 +0000108 if (low > (int)(sizeof(int)*8)-1)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000109 low=sizeof(int)*8-1;
110 bn_limit_bits_low=low;
111 bn_limit_num_low=1<<low;
112 }
113 if (mont >= 0)
114 {
Geoff Thorpe27545972003-10-29 20:24:15 +0000115 if (mont > (int)(sizeof(int)*8)-1)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000116 mont=sizeof(int)*8-1;
117 bn_limit_bits_mont=mont;
118 bn_limit_num_mont=1<<mont;
119 }
120 }
121
Ulf Möller6b691a51999-04-19 21:31:43 +0000122int BN_get_params(int which)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000123 {
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 }
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000130
Bodo Möller98499132001-03-08 13:58:09 +0000131const BIGNUM *BN_value_one(void)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000132 {
133 static BN_ULONG data_one=1L;
Geoff Thorpe34066d72003-12-01 23:13:17 +0000134 static BIGNUM const_one={&data_one,1,1,0,BN_FLG_STATIC_DATA};
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000135
136 return(&const_one);
137 }
138
Ulf Möller6b691a51999-04-19 21:31:43 +0000139char *BN_options(void)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000140 {
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
Ulf Möller6b691a51999-04-19 21:31:43 +0000158int BN_num_bits_word(BN_ULONG l)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000159 {
Ulf Möllere14d4441999-05-20 01:43:07 +0000160 static const char bits[256]={
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000161 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
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000179#if defined(SIXTY_FOUR_BIT_LONG)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000180 if (l & 0xffffffff00000000L)
181 {
182 if (l & 0xffff000000000000L)
183 {
184 if (l & 0xff00000000000000L)
185 {
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000186 return(bits[(int)(l>>56)]+56);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000187 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000188 else return(bits[(int)(l>>48)]+48);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000189 }
190 else
191 {
192 if (l & 0x0000ff0000000000L)
193 {
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000194 return(bits[(int)(l>>40)]+40);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000195 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000196 else return(bits[(int)(l>>32)]+32);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000197 }
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 {
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000208 return(bits[(int)(l>>56)]+56);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000209 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000210 else return(bits[(int)(l>>48)]+48);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000211 }
212 else
213 {
214 if (l & 0x0000ff0000000000LL)
215 {
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000216 return(bits[(int)(l>>40)]+40);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000217 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000218 else return(bits[(int)(l>>32)]+32);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000219 }
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)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000229 return(bits[(int)(l>>24L)]+24);
230 else return(bits[(int)(l>>16L)]+16);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000231 }
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)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000237 return(bits[(int)(l>>8)]+8);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000238 else
239#endif
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000240 return(bits[(int)(l )] );
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000241 }
242 }
243 }
244
Ben Laurie84c15db1999-06-04 22:23:10 +0000245int BN_num_bits(const BIGNUM *a)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000246 {
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000247 int i = a->top - 1;
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000248 bn_check_top(a);
249
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000250 if (BN_is_zero(a)) return 0;
251 return ((i*BN_BITS2) + BN_num_bits_word(a->d[i]));
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000252 }
253
Ulf Möller6b691a51999-04-19 21:31:43 +0000254void BN_clear_free(BIGNUM *a)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000255 {
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000256 int i;
257
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000258 if (a == NULL) return;
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000259 bn_check_top(a);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000260 if (a->d != NULL)
261 {
Richard Levitte43d60162002-11-29 11:30:45 +0000262 OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0]));
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000263 if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
Richard Levitte26a3a482000-06-01 22:19:21 +0000264 OPENSSL_free(a->d);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000265 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000266 i=BN_get_flags(a,BN_FLG_MALLOCED);
Richard Levitte43d60162002-11-29 11:30:45 +0000267 OPENSSL_cleanse(a,sizeof(BIGNUM));
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000268 if (i)
Richard Levitte26a3a482000-06-01 22:19:21 +0000269 OPENSSL_free(a);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000270 }
271
Ulf Möller6b691a51999-04-19 21:31:43 +0000272void BN_free(BIGNUM *a)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000273 {
274 if (a == NULL) return;
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000275 bn_check_top(a);
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000276 if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
Richard Levitte26a3a482000-06-01 22:19:21 +0000277 OPENSSL_free(a->d);
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000278 if (a->flags & BN_FLG_MALLOCED)
Richard Levitte26a3a482000-06-01 22:19:21 +0000279 OPENSSL_free(a);
Geoff Thorpe2ae1ea32003-12-02 03:16:56 +0000280 else
281 {
282#ifndef OPENSSL_NO_DEPRECATED
283 a->flags|=BN_FLG_FREE;
284#endif
285 a->d = NULL;
286 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000287 }
288
Ulf Möller6b691a51999-04-19 21:31:43 +0000289void BN_init(BIGNUM *a)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000290 {
291 memset(a,0,sizeof(BIGNUM));
Geoff Thorped8707402003-11-04 22:54:49 +0000292 bn_check_top(a);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000293 }
294
Ulf Möller6b691a51999-04-19 21:31:43 +0000295BIGNUM *BN_new(void)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000296 {
297 BIGNUM *ret;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000298
Richard Levitte26a3a482000-06-01 22:19:21 +0000299 if ((ret=(BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000300 {
301 BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
302 return(NULL);
303 }
304 ret->flags=BN_FLG_MALLOCED;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000305 ret->top=0;
306 ret->neg=0;
Dr. Stephen Henson2d978cb2000-08-04 00:01:39 +0000307 ret->dmax=0;
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000308 ret->d=NULL;
Geoff Thorped8707402003-11-04 22:54:49 +0000309 bn_check_top(ret);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000310 return(ret);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000311 }
312
Richard Levitte020fc822000-11-06 21:15:54 +0000313/* This is used both by bn_expand2() and bn_dup_expand() */
314/* The caller MUST check that words > b->dmax before calling this */
Bodo Möllera08bccc2000-11-29 12:32:10 +0000315static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000316 {
Richard Levitte020fc822000-11-06 21:15:54 +0000317 BN_ULONG *A,*a = NULL;
Ulf Möllere14d4441999-05-20 01:43:07 +0000318 const BN_ULONG *B;
319 int i;
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000320
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000321 bn_check_top(b);
322
Bodo Möller152a6892000-12-03 09:39:04 +0000323 if (words > (INT_MAX/(4*BN_BITS2)))
324 {
Bodo Möllere5164b72000-12-04 09:24:54 +0000325 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_BIGNUM_TOO_LONG);
Bodo Möller152a6892000-12-03 09:39:04 +0000326 return NULL;
327 }
Richard Levitte020fc822000-11-06 21:15:54 +0000328 if (BN_get_flags(b,BN_FLG_STATIC_DATA))
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000329 {
Bodo Möllera08bccc2000-11-29 12:32:10 +0000330 BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
Richard Levitte020fc822000-11-06 21:15:54 +0000331 return(NULL);
332 }
333 a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*(words+1));
334 if (A == NULL)
335 {
Bodo Möllera08bccc2000-11-29 12:32:10 +0000336 BNerr(BN_F_BN_EXPAND_INTERNAL,ERR_R_MALLOC_FAILURE);
Richard Levitte020fc822000-11-06 21:15:54 +0000337 return(NULL);
338 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000339#if 1
Richard Levitte020fc822000-11-06 21:15:54 +0000340 B=b->d;
341 /* Check if the previous number needs to be copied */
342 if (B != NULL)
343 {
Richard Levitte020fc822000-11-06 21:15:54 +0000344 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
345 {
346 /*
347 * The fact that the loop is unrolled
348 * 4-wise is a tribute to Intel. It's
349 * the one that doesn't have enough
350 * registers to accomodate more data.
351 * I'd unroll it 8-wise otherwise:-)
352 *
353 * <appro@fy.chalmers.se>
354 */
355 BN_ULONG a0,a1,a2,a3;
356 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
357 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
358 }
359 switch (b->top&3)
360 {
361 case 3: A[2]=B[2];
362 case 2: A[1]=B[1];
363 case 1: A[0]=B[0];
Bodo Möllera08bccc2000-11-29 12:32:10 +0000364 case 0: /* workaround for ultrix cc: without 'case 0', the optimizer does
365 * the switch table by doing a=top&3; a--; goto jump_table[a];
366 * which fails for top== 0 */
367 ;
Richard Levitte020fc822000-11-06 21:15:54 +0000368 }
Richard Levitte020fc822000-11-06 21:15:54 +0000369 }
370
Richard Levitte020fc822000-11-06 21:15:54 +0000371#else
372 memset(A,0,sizeof(BN_ULONG)*(words+1));
373 memcpy(A,b->d,sizeof(b->d[0])*b->top);
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000374#endif
375
Richard Levitte020fc822000-11-06 21:15:54 +0000376 return(a);
377 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000378
Richard Levitte020fc822000-11-06 21:15:54 +0000379/* This is an internal function that can be used instead of bn_expand2()
380 * when there is a need to copy BIGNUMs instead of only expanding the
381 * data part, while still expanding them.
382 * Especially useful when needing to expand BIGNUMs that are declared
383 * 'const' and should therefore not be changed.
384 * The reason to use this instead of a BN_dup() followed by a bn_expand2()
385 * is memory allocation overhead. A BN_dup() followed by a bn_expand2()
386 * will allocate new memory for the BIGNUM data twice, and free it once,
387 * while bn_dup_expand() makes sure allocation is made only once.
388 */
389
390BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
391 {
392 BIGNUM *r = NULL;
393
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000394 bn_check_top(b);
395
Bodo Möller12593e62002-07-25 12:12:39 +0000396 /* This function does not work if
397 * words <= b->dmax && top < words
398 * because BN_dup() does not preserve 'dmax'!
399 * (But bn_dup_expand() is not used anywhere yet.)
400 */
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000401
Richard Levitte020fc822000-11-06 21:15:54 +0000402 if (words > b->dmax)
403 {
Bodo Möllera08bccc2000-11-29 12:32:10 +0000404 BN_ULONG *a = bn_expand_internal(b, words);
Richard Levitte020fc822000-11-06 21:15:54 +0000405
406 if (a)
407 {
408 r = BN_new();
Bodo Möller58f0f522000-11-07 09:35:19 +0000409 if (r)
410 {
411 r->top = b->top;
412 r->dmax = words;
413 r->neg = b->neg;
414 r->d = a;
415 }
416 else
417 {
418 /* r == NULL, BN_new failure */
419 OPENSSL_free(a);
420 }
Richard Levitte020fc822000-11-06 21:15:54 +0000421 }
Bodo Möller58f0f522000-11-07 09:35:19 +0000422 /* If a == NULL, there was an error in allocation in
Bodo Möllera08bccc2000-11-29 12:32:10 +0000423 bn_expand_internal(), and NULL should be returned */
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000424 }
Richard Levitte020fc822000-11-06 21:15:54 +0000425 else
426 {
427 r = BN_dup(b);
428 }
429
Geoff Thorped8707402003-11-04 22:54:49 +0000430 bn_check_top(r);
Richard Levitte020fc822000-11-06 21:15:54 +0000431 return r;
432 }
433
434/* This is an internal function that should not be used in applications.
Bodo Möller12593e62002-07-25 12:12:39 +0000435 * It ensures that 'b' has enough room for a 'words' word number
Bodo Möller33d4e692002-08-02 18:23:55 +0000436 * and initialises any unused part of b->d with leading zeros.
Richard Levitte020fc822000-11-06 21:15:54 +0000437 * It is mostly used by the various BIGNUM routines. If there is an error,
438 * NULL is returned. If not, 'b' is returned. */
439
440BIGNUM *bn_expand2(BIGNUM *b, int words)
441 {
Bodo Möller12593e62002-07-25 12:12:39 +0000442 BN_ULONG *A;
443 int i;
444
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000445 bn_check_top(b);
446
Richard Levitte020fc822000-11-06 21:15:54 +0000447 if (words > b->dmax)
448 {
Bodo Möllera08bccc2000-11-29 12:32:10 +0000449 BN_ULONG *a = bn_expand_internal(b, words);
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000450 if(!a) return NULL;
451 if(b->d) OPENSSL_free(b->d);
452 b->d=a;
453 b->dmax=words;
Richard Levitte020fc822000-11-06 21:15:54 +0000454 }
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000455
Bodo Möller12593e62002-07-25 12:12:39 +0000456 /* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000457 if (b->top < b->dmax)
Bodo Möller12593e62002-07-25 12:12:39 +0000458 {
Bodo Möller33d4e692002-08-02 18:23:55 +0000459 A = &(b->d[b->top]);
Bodo Möller18384772002-08-03 18:27:47 +0000460 for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
Bodo Möller33d4e692002-08-02 18:23:55 +0000461 {
462 A[0]=0; A[1]=0; A[2]=0; A[3]=0;
463 A[4]=0; A[5]=0; A[6]=0; A[7]=0;
464 }
Bodo Möller18384772002-08-03 18:27:47 +0000465 for (i=(b->dmax - b->top)&7; i>0; i--,A++)
Bodo Möller33d4e692002-08-02 18:23:55 +0000466 A[0]=0;
Bodo Möller18384772002-08-03 18:27:47 +0000467 assert(A == &(b->d[b->dmax]));
Bodo Möller12593e62002-07-25 12:12:39 +0000468 }
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000469 bn_check_top(b);
Richard Levitte020fc822000-11-06 21:15:54 +0000470 return b;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000471 }
472
Ben Laurie84c15db1999-06-04 22:23:10 +0000473BIGNUM *BN_dup(const BIGNUM *a)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000474 {
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000475 BIGNUM *t;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000476
Bodo Möller8d85b331999-07-30 19:22:57 +0000477 if (a == NULL) return NULL;
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000478 bn_check_top(a);
479
Bodo Möllere0bf5c12000-11-07 09:39:51 +0000480 t = BN_new();
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000481 if (t == NULL) return NULL;
482 if(!BN_copy(t, a))
483 {
Bodo Möllere0bf5c12000-11-07 09:39:51 +0000484 BN_free(t);
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000485 return NULL;
486 }
487 bn_check_top(t);
488 return t;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000489 }
490
Ben Laurie84c15db1999-06-04 22:23:10 +0000491BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000492 {
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000493 int i;
Ulf Möllere14d4441999-05-20 01:43:07 +0000494 BN_ULONG *A;
495 const BN_ULONG *B;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000496
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000497 bn_check_top(b);
498
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000499 if (a == b) return(a);
500 if (bn_wexpand(a,b->top) == NULL) return(NULL);
501
502#if 1
503 A=a->d;
504 B=b->d;
Ulf Möllere14d4441999-05-20 01:43:07 +0000505 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000506 {
Ulf Möllere14d4441999-05-20 01:43:07 +0000507 BN_ULONG a0,a1,a2,a3;
508 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
509 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000510 }
Ulf Möllere14d4441999-05-20 01:43:07 +0000511 switch (b->top&3)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000512 {
Ulf Möllere14d4441999-05-20 01:43:07 +0000513 case 3: A[2]=B[2];
514 case 2: A[1]=B[1];
515 case 1: A[0]=B[0];
Bodo Möllera08bccc2000-11-29 12:32:10 +0000516 case 0: ; /* ultrix cc workaround, see comments in bn_expand_internal */
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000517 }
518#else
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000519 memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000520#endif
521
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000522 a->top=b->top;
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000523#ifndef BN_STRICT
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000524 if ((a->top == 0) && (a->d != NULL))
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000525 a->d[0]=0;
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000526#endif
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000527 a->neg=b->neg;
Geoff Thorped8707402003-11-04 22:54:49 +0000528 bn_check_top(a);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000529 return(a);
530 }
531
Bodo Möller5c6bf032002-10-28 13:23:24 +0000532BIGNUM *BN_ncopy(BIGNUM *a, const BIGNUM *b, size_t n)
533 {
534 int i, min;
535 BN_ULONG *A;
536 const BN_ULONG *B;
537
538 bn_check_top(b);
Bodo Möller5c6bf032002-10-28 13:23:24 +0000539 if (a == b)
540 return a;
541
542 min = (b->top < (int)n)? b->top: (int)n;
Bodo Möller5c6bf032002-10-28 13:23:24 +0000543 if (!min)
544 {
545 BN_zero(a);
546 return a;
547 }
Bodo Möller5c6bf032002-10-28 13:23:24 +0000548 if (bn_wexpand(a, min) == NULL)
549 return NULL;
550
551 A=a->d;
552 B=b->d;
553 for (i=min>>2; i>0; i--, A+=4, B+=4)
554 {
555 BN_ULONG a0,a1,a2,a3;
556 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
557 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
558 }
559 switch (min&3)
560 {
561 case 3: A[2]=B[2];
562 case 2: A[1]=B[1];
563 case 1: A[0]=B[0];
564 case 0: ;
565 }
566 a->top = min;
Bodo Möller5c6bf032002-10-28 13:23:24 +0000567 a->neg = b->neg;
Geoff Thorped8707402003-11-04 22:54:49 +0000568 bn_correct_top(a);
Bodo Möller5c6bf032002-10-28 13:23:24 +0000569 return(a);
570 }
571
Bodo Möller78a0c1f2000-11-26 16:42:38 +0000572void BN_swap(BIGNUM *a, BIGNUM *b)
573 {
574 int flags_old_a, flags_old_b;
575 BN_ULONG *tmp_d;
576 int tmp_top, tmp_dmax, tmp_neg;
577
Geoff Thorpe657a9192003-11-29 20:34:07 +0000578 bn_check_top(a);
579 bn_check_top(b);
580
Bodo Möller78a0c1f2000-11-26 16:42:38 +0000581 flags_old_a = a->flags;
582 flags_old_b = b->flags;
583
584 tmp_d = a->d;
585 tmp_top = a->top;
586 tmp_dmax = a->dmax;
587 tmp_neg = a->neg;
588
589 a->d = b->d;
590 a->top = b->top;
591 a->dmax = b->dmax;
592 a->neg = b->neg;
593
594 b->d = tmp_d;
595 b->top = tmp_top;
596 b->dmax = tmp_dmax;
597 b->neg = tmp_neg;
598
599 a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
600 b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
Geoff Thorped8707402003-11-04 22:54:49 +0000601 bn_check_top(a);
602 bn_check_top(b);
Bodo Möller78a0c1f2000-11-26 16:42:38 +0000603 }
604
Ulf Möller6b691a51999-04-19 21:31:43 +0000605void BN_clear(BIGNUM *a)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000606 {
Geoff Thorpe657a9192003-11-29 20:34:07 +0000607 bn_check_top(a);
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000608 if (a->d != NULL)
Dr. Stephen Henson2d978cb2000-08-04 00:01:39 +0000609 memset(a->d,0,a->dmax*sizeof(a->d[0]));
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000610 a->top=0;
611 a->neg=0;
612 }
613
Richard Levitte020fc822000-11-06 21:15:54 +0000614BN_ULONG BN_get_word(const BIGNUM *a)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000615 {
616 int i,n;
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000617 BN_ULONG ret=0;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000618
619 n=BN_num_bytes(a);
Geoff Thorpe27545972003-10-29 20:24:15 +0000620 if (n > (int)sizeof(BN_ULONG))
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000621 return(BN_MASK2);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000622 for (i=a->top-1; i>=0; i--)
623 {
624#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
625 ret<<=BN_BITS4; /* stops the compiler complaining */
626 ret<<=BN_BITS4;
Ulf Möllere14d4441999-05-20 01:43:07 +0000627#else
628 ret=0;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000629#endif
630 ret|=a->d[i];
631 }
632 return(ret);
633 }
634
Ulf Möller6b691a51999-04-19 21:31:43 +0000635int BN_set_word(BIGNUM *a, BN_ULONG w)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000636 {
637 int i,n;
Geoff Thorpe657a9192003-11-29 20:34:07 +0000638 bn_check_top(a);
Geoff Thorpe27545972003-10-29 20:24:15 +0000639 if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000640
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000641 n=sizeof(BN_ULONG)/BN_BYTES;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000642 a->neg=0;
643 a->top=0;
644 a->d[0]=(BN_ULONG)w&BN_MASK2;
645 if (a->d[0] != 0) a->top=1;
646 for (i=1; i<n; i++)
647 {
648 /* the following is done instead of
649 * w>>=BN_BITS2 so compilers don't complain
650 * on builds where sizeof(long) == BN_TYPES */
651#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
652 w>>=BN_BITS4;
653 w>>=BN_BITS4;
Ulf Möllere14d4441999-05-20 01:43:07 +0000654#else
655 w=0;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000656#endif
657 a->d[i]=(BN_ULONG)w&BN_MASK2;
658 if (a->d[i] != 0) a->top=i+1;
659 }
Geoff Thorped8707402003-11-04 22:54:49 +0000660 bn_check_top(a);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000661 return(1);
662 }
663
Ben Laurie61f5b6f1999-04-23 15:01:15 +0000664BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000665 {
666 unsigned int i,m;
667 unsigned int n;
668 BN_ULONG l;
669
670 if (ret == NULL) ret=BN_new();
671 if (ret == NULL) return(NULL);
Geoff Thorpe657a9192003-11-29 20:34:07 +0000672 bn_check_top(ret);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000673 l=0;
674 n=len;
675 if (n == 0)
676 {
677 ret->top=0;
678 return(ret);
679 }
680 if (bn_expand(ret,(int)(n+2)*8) == NULL)
681 return(NULL);
682 i=((n-1)/BN_BYTES)+1;
683 m=((n-1)%(BN_BYTES));
Bodo Möller91616722000-11-29 12:53:41 +0000684 ret->top=i;
685 ret->neg=0;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000686 while (n-- > 0)
687 {
688 l=(l<<8L)| *(s++);
689 if (m-- == 0)
690 {
691 ret->d[--i]=l;
692 l=0;
693 m=BN_BYTES-1;
694 }
695 }
696 /* need to call this due to clear byte at top if avoiding
697 * having the top bit set (-ve number) */
Geoff Thorped8707402003-11-04 22:54:49 +0000698 bn_correct_top(ret);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000699 return(ret);
700 }
701
702/* ignore negative */
Dr. Stephen Henson8623f691999-06-20 17:36:11 +0000703int BN_bn2bin(const BIGNUM *a, unsigned char *to)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000704 {
705 int n,i;
706 BN_ULONG l;
707
Geoff Thorpe657a9192003-11-29 20:34:07 +0000708 bn_check_top(a);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000709 n=i=BN_num_bytes(a);
710 while (i-- > 0)
711 {
712 l=a->d[i/BN_BYTES];
713 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
714 }
715 return(n);
716 }
717
Ben Laurie84c15db1999-06-04 22:23:10 +0000718int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000719 {
720 int i;
721 BN_ULONG t1,t2,*ap,*bp;
722
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000723 bn_check_top(a);
724 bn_check_top(b);
725
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000726 i=a->top-b->top;
727 if (i != 0) return(i);
728 ap=a->d;
729 bp=b->d;
730 for (i=a->top-1; i>=0; i--)
731 {
732 t1= ap[i];
733 t2= bp[i];
734 if (t1 != t2)
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000735 return((t1 > t2) ? 1 : -1);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000736 }
737 return(0);
738 }
739
Ben Laurie84c15db1999-06-04 22:23:10 +0000740int BN_cmp(const BIGNUM *a, const BIGNUM *b)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000741 {
742 int i;
743 int gt,lt;
744 BN_ULONG t1,t2;
745
746 if ((a == NULL) || (b == NULL))
747 {
748 if (a != NULL)
749 return(-1);
750 else if (b != NULL)
751 return(1);
752 else
753 return(0);
754 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000755
756 bn_check_top(a);
757 bn_check_top(b);
758
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000759 if (a->neg != b->neg)
760 {
761 if (a->neg)
762 return(-1);
763 else return(1);
764 }
765 if (a->neg == 0)
766 { gt=1; lt= -1; }
767 else { gt= -1; lt=1; }
768
769 if (a->top > b->top) return(gt);
770 if (a->top < b->top) return(lt);
771 for (i=a->top-1; i>=0; i--)
772 {
773 t1=a->d[i];
774 t2=b->d[i];
775 if (t1 > t2) return(gt);
776 if (t1 < t2) return(lt);
777 }
778 return(0);
779 }
780
Ulf Möller6b691a51999-04-19 21:31:43 +0000781int BN_set_bit(BIGNUM *a, int n)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000782 {
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000783 int i,j,k;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000784
Ulf Möller1a017332003-11-15 08:37:50 +0000785 if (n < 0)
786 return 0;
787
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000788 i=n/BN_BITS2;
789 j=n%BN_BITS2;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000790 if (a->top <= i)
791 {
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000792 if (bn_wexpand(a,i+1) == NULL) return(0);
793 for(k=a->top; k<i+1; k++)
794 a->d[k]=0;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000795 a->top=i+1;
796 }
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000797
Ulf Möllere14d4441999-05-20 01:43:07 +0000798 a->d[i]|=(((BN_ULONG)1)<<j);
Geoff Thorped8707402003-11-04 22:54:49 +0000799 bn_check_top(a);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000800 return(1);
801 }
802
Ulf Möller6b691a51999-04-19 21:31:43 +0000803int BN_clear_bit(BIGNUM *a, int n)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000804 {
805 int i,j;
806
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000807 bn_check_top(a);
808 if (n < 0) return 0;
Ulf Möller1a017332003-11-15 08:37:50 +0000809
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000810 i=n/BN_BITS2;
811 j=n%BN_BITS2;
812 if (a->top <= i) return(0);
813
Ulf Möllere14d4441999-05-20 01:43:07 +0000814 a->d[i]&=(~(((BN_ULONG)1)<<j));
Geoff Thorped8707402003-11-04 22:54:49 +0000815 bn_correct_top(a);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000816 return(1);
817 }
818
Ben Laurie84c15db1999-06-04 22:23:10 +0000819int BN_is_bit_set(const BIGNUM *a, int n)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000820 {
821 int i,j;
822
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000823 bn_check_top(a);
824 if (n < 0) return 0;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000825 i=n/BN_BITS2;
826 j=n%BN_BITS2;
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000827 if (a->top <= i) return 0;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000828 return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
829 }
830
Ulf Möller6b691a51999-04-19 21:31:43 +0000831int BN_mask_bits(BIGNUM *a, int n)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000832 {
833 int b,w;
834
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000835 bn_check_top(a);
836 if (n < 0) return 0;
Ulf Möller1a017332003-11-15 08:37:50 +0000837
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000838 w=n/BN_BITS2;
839 b=n%BN_BITS2;
Geoff Thorpe2bfd2c72003-12-02 20:01:30 +0000840 if (w >= a->top) return 0;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000841 if (b == 0)
842 a->top=w;
843 else
844 {
845 a->top=w+1;
846 a->d[w]&= ~(BN_MASK2<<b);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000847 }
Geoff Thorped8707402003-11-04 22:54:49 +0000848 bn_correct_top(a);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000849 return(1);
850 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000851
Richard Levittecbd48ba2000-11-16 22:43:32 +0000852int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000853 {
854 int i;
855 BN_ULONG aa,bb;
856
857 aa=a[n-1];
858 bb=b[n-1];
859 if (aa != bb) return((aa > bb)?1:-1);
860 for (i=n-2; i>=0; i--)
861 {
862 aa=a[i];
863 bb=b[i];
864 if (aa != bb) return((aa > bb)?1:-1);
865 }
866 return(0);
867 }
Ulf Möller52a1bab2000-12-02 07:28:43 +0000868
Richard Levittec21c35e2000-12-02 21:16:13 +0000869/* Here follows a specialised variants of bn_cmp_words(). It has the
870 property of performing the operation on arrays of different sizes.
871 The sizes of those arrays is expressed through cl, which is the
872 common length ( basicall, min(len(a),len(b)) ), and dl, which is the
873 delta between the two lengths, calculated as len(a)-len(b).
874 All lengths are the number of BN_ULONGs... */
875
Ulf Möller52a1bab2000-12-02 07:28:43 +0000876int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
877 int cl, int dl)
878 {
879 int n,i;
880 n = cl-1;
881
882 if (dl < 0)
883 {
Ulf Möllerb26f84c2000-12-02 20:51:47 +0000884 for (i=dl; i<0; i++)
Ulf Möller52a1bab2000-12-02 07:28:43 +0000885 {
Ulf Möllerb26f84c2000-12-02 20:51:47 +0000886 if (b[n-i] != 0)
Ulf Möller52a1bab2000-12-02 07:28:43 +0000887 return -1; /* a < b */
888 }
889 }
890 if (dl > 0)
891 {
892 for (i=dl; i>0; i--)
893 {
894 if (a[n+i] != 0)
895 return 1; /* a > b */
896 }
897 }
898 return bn_cmp_words(a,b,cl);
899 }