sl@0
|
1 |
/* crypto/bn/bn_lib.c */
|
sl@0
|
2 |
/* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
|
sl@0
|
3 |
* All rights reserved.
|
sl@0
|
4 |
*
|
sl@0
|
5 |
* This package is an SSL implementation written
|
sl@0
|
6 |
* by Eric Young (eay@cryptsoft.com).
|
sl@0
|
7 |
* The implementation was written so as to conform with Netscapes SSL.
|
sl@0
|
8 |
*
|
sl@0
|
9 |
* This library is free for commercial and non-commercial use as long as
|
sl@0
|
10 |
* the following conditions are aheared to. The following conditions
|
sl@0
|
11 |
* apply to all code found in this distribution, be it the RC4, RSA,
|
sl@0
|
12 |
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
sl@0
|
13 |
* included with this distribution is covered by the same copyright terms
|
sl@0
|
14 |
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
sl@0
|
15 |
*
|
sl@0
|
16 |
* Copyright remains Eric Young's, and as such any Copyright notices in
|
sl@0
|
17 |
* the code are not to be removed.
|
sl@0
|
18 |
* If this package is used in a product, Eric Young should be given attribution
|
sl@0
|
19 |
* as the author of the parts of the library used.
|
sl@0
|
20 |
* This can be in the form of a textual message at program startup or
|
sl@0
|
21 |
* in documentation (online or textual) provided with the package.
|
sl@0
|
22 |
*
|
sl@0
|
23 |
* Redistribution and use in source and binary forms, with or without
|
sl@0
|
24 |
* modification, are permitted provided that the following conditions
|
sl@0
|
25 |
* are met:
|
sl@0
|
26 |
* 1. Redistributions of source code must retain the copyright
|
sl@0
|
27 |
* notice, this list of conditions and the following disclaimer.
|
sl@0
|
28 |
* 2. Redistributions in binary form must reproduce the above copyright
|
sl@0
|
29 |
* notice, this list of conditions and the following disclaimer in the
|
sl@0
|
30 |
* documentation and/or other materials provided with the distribution.
|
sl@0
|
31 |
* 3. All advertising materials mentioning features or use of this software
|
sl@0
|
32 |
* must display the following acknowledgement:
|
sl@0
|
33 |
* "This product includes cryptographic software written by
|
sl@0
|
34 |
* Eric Young (eay@cryptsoft.com)"
|
sl@0
|
35 |
* The word 'cryptographic' can be left out if the rouines from the library
|
sl@0
|
36 |
* being used are not cryptographic related :-).
|
sl@0
|
37 |
* 4. If you include any Windows specific code (or a derivative thereof) from
|
sl@0
|
38 |
* the apps directory (application code) you must include an acknowledgement:
|
sl@0
|
39 |
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
sl@0
|
40 |
*
|
sl@0
|
41 |
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
sl@0
|
42 |
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
sl@0
|
43 |
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
sl@0
|
44 |
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
|
sl@0
|
45 |
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
|
sl@0
|
46 |
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
|
sl@0
|
47 |
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
|
sl@0
|
48 |
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
|
sl@0
|
49 |
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
|
sl@0
|
50 |
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
|
sl@0
|
51 |
* SUCH DAMAGE.
|
sl@0
|
52 |
*
|
sl@0
|
53 |
* The licence and distribution terms for any publically available version or
|
sl@0
|
54 |
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
sl@0
|
55 |
* copied and put under another distribution licence
|
sl@0
|
56 |
* [including the GNU Public Licence.]
|
sl@0
|
57 |
*/
|
sl@0
|
58 |
/*
|
sl@0
|
59 |
© Portions copyright (c) 2006 Nokia Corporation. All rights reserved.
|
sl@0
|
60 |
*/
|
sl@0
|
61 |
|
sl@0
|
62 |
|
sl@0
|
63 |
#ifndef BN_DEBUG
|
sl@0
|
64 |
# undef NDEBUG /* avoid conflicting definitions */
|
sl@0
|
65 |
# define NDEBUG
|
sl@0
|
66 |
#endif
|
sl@0
|
67 |
|
sl@0
|
68 |
#include <assert.h>
|
sl@0
|
69 |
#include <limits.h>
|
sl@0
|
70 |
#include <stdio.h>
|
sl@0
|
71 |
#include "cryptlib.h"
|
sl@0
|
72 |
#include "bn_lcl.h"
|
sl@0
|
73 |
#if (defined(SYMBIAN) && (defined(__WINSCW__) || defined(__WINS__)))
|
sl@0
|
74 |
#include "libcrypto_wsd_macros.h"
|
sl@0
|
75 |
#include "libcrypto_wsd.h"
|
sl@0
|
76 |
#endif
|
sl@0
|
77 |
|
sl@0
|
78 |
const char BN_version[]="Big Number" OPENSSL_VERSION_PTEXT;
|
sl@0
|
79 |
|
sl@0
|
80 |
/* This stuff appears to be completely unused, so is deprecated */
|
sl@0
|
81 |
#ifndef OPENSSL_NO_DEPRECATED
|
sl@0
|
82 |
/* For a 32 bit machine
|
sl@0
|
83 |
* 2 - 4 == 128
|
sl@0
|
84 |
* 3 - 8 == 256
|
sl@0
|
85 |
* 4 - 16 == 512
|
sl@0
|
86 |
* 5 - 32 == 1024
|
sl@0
|
87 |
* 6 - 64 == 2048
|
sl@0
|
88 |
* 7 - 128 == 4096
|
sl@0
|
89 |
* 8 - 256 == 8192
|
sl@0
|
90 |
*/
|
sl@0
|
91 |
|
sl@0
|
92 |
static int bn_limit_bits=0;
|
sl@0
|
93 |
static int bn_limit_num=8; /* (1<<bn_limit_bits) */
|
sl@0
|
94 |
static int bn_limit_bits_low=0;
|
sl@0
|
95 |
static int bn_limit_num_low=8; /* (1<<bn_limit_bits_low) */
|
sl@0
|
96 |
static int bn_limit_bits_high=0;
|
sl@0
|
97 |
static int bn_limit_num_high=8; /* (1<<bn_limit_bits_high) */
|
sl@0
|
98 |
static int bn_limit_bits_mont=0;
|
sl@0
|
99 |
static int bn_limit_num_mont=8; /* (1<<bn_limit_bits_mont) */
|
sl@0
|
100 |
EXPORT_C void BN_set_params(int mult, int high, int low, int mont)
|
sl@0
|
101 |
{
|
sl@0
|
102 |
if (mult >= 0)
|
sl@0
|
103 |
{
|
sl@0
|
104 |
if (mult > (int)(sizeof(int)*8)-1)
|
sl@0
|
105 |
mult=sizeof(int)*8-1;
|
sl@0
|
106 |
bn_limit_bits=mult;
|
sl@0
|
107 |
bn_limit_num=1<<mult;
|
sl@0
|
108 |
}
|
sl@0
|
109 |
if (high >= 0)
|
sl@0
|
110 |
{
|
sl@0
|
111 |
if (high > (int)(sizeof(int)*8)-1)
|
sl@0
|
112 |
high=sizeof(int)*8-1;
|
sl@0
|
113 |
bn_limit_bits_high=high;
|
sl@0
|
114 |
bn_limit_num_high=1<<high;
|
sl@0
|
115 |
}
|
sl@0
|
116 |
if (low >= 0)
|
sl@0
|
117 |
{
|
sl@0
|
118 |
if (low > (int)(sizeof(int)*8)-1)
|
sl@0
|
119 |
low=sizeof(int)*8-1;
|
sl@0
|
120 |
bn_limit_bits_low=low;
|
sl@0
|
121 |
bn_limit_num_low=1<<low;
|
sl@0
|
122 |
}
|
sl@0
|
123 |
if (mont >= 0)
|
sl@0
|
124 |
{
|
sl@0
|
125 |
if (mont > (int)(sizeof(int)*8)-1)
|
sl@0
|
126 |
mont=sizeof(int)*8-1;
|
sl@0
|
127 |
bn_limit_bits_mont=mont;
|
sl@0
|
128 |
bn_limit_num_mont=1<<mont;
|
sl@0
|
129 |
}
|
sl@0
|
130 |
}
|
sl@0
|
131 |
|
sl@0
|
132 |
EXPORT_C int BN_get_params(int which)
|
sl@0
|
133 |
{
|
sl@0
|
134 |
if (which == 0) return(bn_limit_bits);
|
sl@0
|
135 |
else if (which == 1) return(bn_limit_bits_high);
|
sl@0
|
136 |
else if (which == 2) return(bn_limit_bits_low);
|
sl@0
|
137 |
else if (which == 3) return(bn_limit_bits_mont);
|
sl@0
|
138 |
else return(0);
|
sl@0
|
139 |
}
|
sl@0
|
140 |
#endif
|
sl@0
|
141 |
|
sl@0
|
142 |
#ifdef EMULATOR
|
sl@0
|
143 |
GET_STATIC_VAR_FROM_TLS(data_one,bn_lib,BN_ULONG)
|
sl@0
|
144 |
#define data_one (*GET_WSD_VAR_NAME(data_one,bn_lib, s)())
|
sl@0
|
145 |
GET_STATIC_VAR_FROM_TLS(const_one,bn_lib,BIGNUM)
|
sl@0
|
146 |
#define const_one (*GET_WSD_VAR_NAME(const_one,bn_lib, s)())
|
sl@0
|
147 |
|
sl@0
|
148 |
#endif
|
sl@0
|
149 |
EXPORT_C const BIGNUM *BN_value_one(void)
|
sl@0
|
150 |
{
|
sl@0
|
151 |
#ifndef EMULATOR
|
sl@0
|
152 |
static BN_ULONG data_one=1L;
|
sl@0
|
153 |
|
sl@0
|
154 |
static BIGNUM const_one={&data_one,1,1,0,BN_FLG_STATIC_DATA};
|
sl@0
|
155 |
#endif
|
sl@0
|
156 |
|
sl@0
|
157 |
return(&const_one);
|
sl@0
|
158 |
}
|
sl@0
|
159 |
|
sl@0
|
160 |
#ifdef EMULATOR
|
sl@0
|
161 |
GET_STATIC_ARRAY_FROM_TLS(data,bn_lib,char)
|
sl@0
|
162 |
#define data (GET_WSD_VAR_NAME(data,bn_lib, s)())
|
sl@0
|
163 |
GET_STATIC_VAR_FROM_TLS(init,bn_lib,int)
|
sl@0
|
164 |
#define init (*GET_WSD_VAR_NAME(init,bn_lib, s)())
|
sl@0
|
165 |
#endif
|
sl@0
|
166 |
|
sl@0
|
167 |
|
sl@0
|
168 |
EXPORT_C char *BN_options(void)
|
sl@0
|
169 |
{
|
sl@0
|
170 |
#ifndef EMULATOR
|
sl@0
|
171 |
static int init=0;
|
sl@0
|
172 |
static char data[16];
|
sl@0
|
173 |
#endif
|
sl@0
|
174 |
|
sl@0
|
175 |
if (!init)
|
sl@0
|
176 |
{
|
sl@0
|
177 |
init++;
|
sl@0
|
178 |
#ifdef BN_LLONG
|
sl@0
|
179 |
BIO_snprintf(data,sizeof data,"bn(%d,%d)",
|
sl@0
|
180 |
(int)sizeof(BN_ULLONG)*8,(int)sizeof(BN_ULONG)*8);
|
sl@0
|
181 |
#else
|
sl@0
|
182 |
BIO_snprintf(data,sizeof data,"bn(%d,%d)",
|
sl@0
|
183 |
(int)sizeof(BN_ULONG)*8,(int)sizeof(BN_ULONG)*8);
|
sl@0
|
184 |
#endif
|
sl@0
|
185 |
}
|
sl@0
|
186 |
return((char*)data);
|
sl@0
|
187 |
}
|
sl@0
|
188 |
|
sl@0
|
189 |
EXPORT_C int BN_num_bits_word(BN_ULONG l)
|
sl@0
|
190 |
{
|
sl@0
|
191 |
static const char bits[256]={
|
sl@0
|
192 |
0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
|
sl@0
|
193 |
5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
|
sl@0
|
194 |
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
sl@0
|
195 |
6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
|
sl@0
|
196 |
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
sl@0
|
197 |
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
sl@0
|
198 |
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
sl@0
|
199 |
7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
|
sl@0
|
200 |
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
sl@0
|
201 |
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
sl@0
|
202 |
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
sl@0
|
203 |
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
sl@0
|
204 |
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
sl@0
|
205 |
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
sl@0
|
206 |
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
sl@0
|
207 |
8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
|
sl@0
|
208 |
};
|
sl@0
|
209 |
|
sl@0
|
210 |
#if defined(SIXTY_FOUR_BIT_LONG)
|
sl@0
|
211 |
if (l & 0xffffffff00000000L)
|
sl@0
|
212 |
{
|
sl@0
|
213 |
if (l & 0xffff000000000000L)
|
sl@0
|
214 |
{
|
sl@0
|
215 |
if (l & 0xff00000000000000L)
|
sl@0
|
216 |
{
|
sl@0
|
217 |
return(bits[(int)(l>>56)]+56);
|
sl@0
|
218 |
}
|
sl@0
|
219 |
else return(bits[(int)(l>>48)]+48);
|
sl@0
|
220 |
}
|
sl@0
|
221 |
else
|
sl@0
|
222 |
{
|
sl@0
|
223 |
if (l & 0x0000ff0000000000L)
|
sl@0
|
224 |
{
|
sl@0
|
225 |
return(bits[(int)(l>>40)]+40);
|
sl@0
|
226 |
}
|
sl@0
|
227 |
else return(bits[(int)(l>>32)]+32);
|
sl@0
|
228 |
}
|
sl@0
|
229 |
}
|
sl@0
|
230 |
else
|
sl@0
|
231 |
#else
|
sl@0
|
232 |
#ifdef SIXTY_FOUR_BIT
|
sl@0
|
233 |
if (l & 0xffffffff00000000LL)
|
sl@0
|
234 |
{
|
sl@0
|
235 |
if (l & 0xffff000000000000LL)
|
sl@0
|
236 |
{
|
sl@0
|
237 |
if (l & 0xff00000000000000LL)
|
sl@0
|
238 |
{
|
sl@0
|
239 |
return(bits[(int)(l>>56)]+56);
|
sl@0
|
240 |
}
|
sl@0
|
241 |
else return(bits[(int)(l>>48)]+48);
|
sl@0
|
242 |
}
|
sl@0
|
243 |
else
|
sl@0
|
244 |
{
|
sl@0
|
245 |
if (l & 0x0000ff0000000000LL)
|
sl@0
|
246 |
{
|
sl@0
|
247 |
return(bits[(int)(l>>40)]+40);
|
sl@0
|
248 |
}
|
sl@0
|
249 |
else return(bits[(int)(l>>32)]+32);
|
sl@0
|
250 |
}
|
sl@0
|
251 |
}
|
sl@0
|
252 |
else
|
sl@0
|
253 |
#endif
|
sl@0
|
254 |
#endif
|
sl@0
|
255 |
{
|
sl@0
|
256 |
#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
|
sl@0
|
257 |
if (l & 0xffff0000L)
|
sl@0
|
258 |
{
|
sl@0
|
259 |
if (l & 0xff000000L)
|
sl@0
|
260 |
return(bits[(int)(l>>24L)]+24);
|
sl@0
|
261 |
else return(bits[(int)(l>>16L)]+16);
|
sl@0
|
262 |
}
|
sl@0
|
263 |
else
|
sl@0
|
264 |
#endif
|
sl@0
|
265 |
{
|
sl@0
|
266 |
#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
|
sl@0
|
267 |
if (l & 0xff00L)
|
sl@0
|
268 |
return(bits[(int)(l>>8)]+8);
|
sl@0
|
269 |
else
|
sl@0
|
270 |
#endif
|
sl@0
|
271 |
return(bits[(int)(l )] );
|
sl@0
|
272 |
}
|
sl@0
|
273 |
}
|
sl@0
|
274 |
}
|
sl@0
|
275 |
|
sl@0
|
276 |
EXPORT_C int BN_num_bits(const BIGNUM *a)
|
sl@0
|
277 |
{
|
sl@0
|
278 |
int i = a->top - 1;
|
sl@0
|
279 |
bn_check_top(a);
|
sl@0
|
280 |
|
sl@0
|
281 |
if (BN_is_zero(a)) return 0;
|
sl@0
|
282 |
return ((i*BN_BITS2) + BN_num_bits_word(a->d[i]));
|
sl@0
|
283 |
}
|
sl@0
|
284 |
|
sl@0
|
285 |
EXPORT_C void BN_clear_free(BIGNUM *a)
|
sl@0
|
286 |
{
|
sl@0
|
287 |
int i;
|
sl@0
|
288 |
|
sl@0
|
289 |
if (a == NULL) return;
|
sl@0
|
290 |
bn_check_top(a);
|
sl@0
|
291 |
if (a->d != NULL)
|
sl@0
|
292 |
{
|
sl@0
|
293 |
OPENSSL_cleanse(a->d,a->dmax*sizeof(a->d[0]));
|
sl@0
|
294 |
if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
|
sl@0
|
295 |
OPENSSL_free(a->d);
|
sl@0
|
296 |
}
|
sl@0
|
297 |
i=BN_get_flags(a,BN_FLG_MALLOCED);
|
sl@0
|
298 |
OPENSSL_cleanse(a,sizeof(BIGNUM));
|
sl@0
|
299 |
if (i)
|
sl@0
|
300 |
OPENSSL_free(a);
|
sl@0
|
301 |
}
|
sl@0
|
302 |
|
sl@0
|
303 |
EXPORT_C void BN_free(BIGNUM *a)
|
sl@0
|
304 |
{
|
sl@0
|
305 |
if (a == NULL) return;
|
sl@0
|
306 |
bn_check_top(a);
|
sl@0
|
307 |
if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
|
sl@0
|
308 |
OPENSSL_free(a->d);
|
sl@0
|
309 |
if (a->flags & BN_FLG_MALLOCED)
|
sl@0
|
310 |
OPENSSL_free(a);
|
sl@0
|
311 |
else
|
sl@0
|
312 |
{
|
sl@0
|
313 |
#ifndef OPENSSL_NO_DEPRECATED
|
sl@0
|
314 |
a->flags|=BN_FLG_FREE;
|
sl@0
|
315 |
#endif
|
sl@0
|
316 |
a->d = NULL;
|
sl@0
|
317 |
}
|
sl@0
|
318 |
}
|
sl@0
|
319 |
|
sl@0
|
320 |
EXPORT_C void BN_init(BIGNUM *a)
|
sl@0
|
321 |
{
|
sl@0
|
322 |
memset(a,0,sizeof(BIGNUM));
|
sl@0
|
323 |
bn_check_top(a);
|
sl@0
|
324 |
}
|
sl@0
|
325 |
|
sl@0
|
326 |
EXPORT_C BIGNUM *BN_new(void)
|
sl@0
|
327 |
{
|
sl@0
|
328 |
BIGNUM *ret;
|
sl@0
|
329 |
|
sl@0
|
330 |
if ((ret=(BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL)
|
sl@0
|
331 |
{
|
sl@0
|
332 |
BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
|
sl@0
|
333 |
return(NULL);
|
sl@0
|
334 |
}
|
sl@0
|
335 |
ret->flags=BN_FLG_MALLOCED;
|
sl@0
|
336 |
ret->top=0;
|
sl@0
|
337 |
ret->neg=0;
|
sl@0
|
338 |
ret->dmax=0;
|
sl@0
|
339 |
ret->d=NULL;
|
sl@0
|
340 |
bn_check_top(ret);
|
sl@0
|
341 |
return(ret);
|
sl@0
|
342 |
}
|
sl@0
|
343 |
|
sl@0
|
344 |
/* This is used both by bn_expand2() and bn_dup_expand() */
|
sl@0
|
345 |
/* The caller MUST check that words > b->dmax before calling this */
|
sl@0
|
346 |
static BN_ULONG *bn_expand_internal(const BIGNUM *b, int words)
|
sl@0
|
347 |
{
|
sl@0
|
348 |
BN_ULONG *A,*a = NULL;
|
sl@0
|
349 |
const BN_ULONG *B;
|
sl@0
|
350 |
int i;
|
sl@0
|
351 |
|
sl@0
|
352 |
bn_check_top(b);
|
sl@0
|
353 |
|
sl@0
|
354 |
if (words > (INT_MAX/(4*BN_BITS2)))
|
sl@0
|
355 |
{
|
sl@0
|
356 |
BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_BIGNUM_TOO_LONG);
|
sl@0
|
357 |
return NULL;
|
sl@0
|
358 |
}
|
sl@0
|
359 |
if (BN_get_flags(b,BN_FLG_STATIC_DATA))
|
sl@0
|
360 |
{
|
sl@0
|
361 |
BNerr(BN_F_BN_EXPAND_INTERNAL,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
|
sl@0
|
362 |
return(NULL);
|
sl@0
|
363 |
}
|
sl@0
|
364 |
a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*words);
|
sl@0
|
365 |
if (A == NULL)
|
sl@0
|
366 |
{
|
sl@0
|
367 |
BNerr(BN_F_BN_EXPAND_INTERNAL,ERR_R_MALLOC_FAILURE);
|
sl@0
|
368 |
return(NULL);
|
sl@0
|
369 |
}
|
sl@0
|
370 |
#if 1
|
sl@0
|
371 |
B=b->d;
|
sl@0
|
372 |
/* Check if the previous number needs to be copied */
|
sl@0
|
373 |
if (B != NULL)
|
sl@0
|
374 |
{
|
sl@0
|
375 |
for (i=b->top>>2; i>0; i--,A+=4,B+=4)
|
sl@0
|
376 |
{
|
sl@0
|
377 |
/*
|
sl@0
|
378 |
* The fact that the loop is unrolled
|
sl@0
|
379 |
* 4-wise is a tribute to Intel. It's
|
sl@0
|
380 |
* the one that doesn't have enough
|
sl@0
|
381 |
* registers to accomodate more data.
|
sl@0
|
382 |
* I'd unroll it 8-wise otherwise:-)
|
sl@0
|
383 |
*
|
sl@0
|
384 |
* <appro@fy.chalmers.se>
|
sl@0
|
385 |
*/
|
sl@0
|
386 |
BN_ULONG a0,a1,a2,a3;
|
sl@0
|
387 |
a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
|
sl@0
|
388 |
A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
|
sl@0
|
389 |
}
|
sl@0
|
390 |
switch (b->top&3)
|
sl@0
|
391 |
{
|
sl@0
|
392 |
case 3: A[2]=B[2];
|
sl@0
|
393 |
case 2: A[1]=B[1];
|
sl@0
|
394 |
case 1: A[0]=B[0];
|
sl@0
|
395 |
case 0: /* workaround for ultrix cc: without 'case 0', the optimizer does
|
sl@0
|
396 |
* the switch table by doing a=top&3; a--; goto jump_table[a];
|
sl@0
|
397 |
* which fails for top== 0 */
|
sl@0
|
398 |
;
|
sl@0
|
399 |
}
|
sl@0
|
400 |
}
|
sl@0
|
401 |
|
sl@0
|
402 |
#else
|
sl@0
|
403 |
memset(A,0,sizeof(BN_ULONG)*words);
|
sl@0
|
404 |
memcpy(A,b->d,sizeof(b->d[0])*b->top);
|
sl@0
|
405 |
#endif
|
sl@0
|
406 |
|
sl@0
|
407 |
return(a);
|
sl@0
|
408 |
}
|
sl@0
|
409 |
|
sl@0
|
410 |
/* This is an internal function that can be used instead of bn_expand2()
|
sl@0
|
411 |
* when there is a need to copy BIGNUMs instead of only expanding the
|
sl@0
|
412 |
* data part, while still expanding them.
|
sl@0
|
413 |
* Especially useful when needing to expand BIGNUMs that are declared
|
sl@0
|
414 |
* 'const' and should therefore not be changed.
|
sl@0
|
415 |
* The reason to use this instead of a BN_dup() followed by a bn_expand2()
|
sl@0
|
416 |
* is memory allocation overhead. A BN_dup() followed by a bn_expand2()
|
sl@0
|
417 |
* will allocate new memory for the BIGNUM data twice, and free it once,
|
sl@0
|
418 |
* while bn_dup_expand() makes sure allocation is made only once.
|
sl@0
|
419 |
*/
|
sl@0
|
420 |
|
sl@0
|
421 |
#ifndef OPENSSL_NO_DEPRECATED
|
sl@0
|
422 |
EXPORT_C BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
|
sl@0
|
423 |
{
|
sl@0
|
424 |
BIGNUM *r = NULL;
|
sl@0
|
425 |
|
sl@0
|
426 |
bn_check_top(b);
|
sl@0
|
427 |
|
sl@0
|
428 |
/* This function does not work if
|
sl@0
|
429 |
* words <= b->dmax && top < words
|
sl@0
|
430 |
* because BN_dup() does not preserve 'dmax'!
|
sl@0
|
431 |
* (But bn_dup_expand() is not used anywhere yet.)
|
sl@0
|
432 |
*/
|
sl@0
|
433 |
|
sl@0
|
434 |
if (words > b->dmax)
|
sl@0
|
435 |
{
|
sl@0
|
436 |
BN_ULONG *a = bn_expand_internal(b, words);
|
sl@0
|
437 |
|
sl@0
|
438 |
if (a)
|
sl@0
|
439 |
{
|
sl@0
|
440 |
r = BN_new();
|
sl@0
|
441 |
if (r)
|
sl@0
|
442 |
{
|
sl@0
|
443 |
r->top = b->top;
|
sl@0
|
444 |
r->dmax = words;
|
sl@0
|
445 |
r->neg = b->neg;
|
sl@0
|
446 |
r->d = a;
|
sl@0
|
447 |
}
|
sl@0
|
448 |
else
|
sl@0
|
449 |
{
|
sl@0
|
450 |
/* r == NULL, BN_new failure */
|
sl@0
|
451 |
OPENSSL_free(a);
|
sl@0
|
452 |
}
|
sl@0
|
453 |
}
|
sl@0
|
454 |
/* If a == NULL, there was an error in allocation in
|
sl@0
|
455 |
bn_expand_internal(), and NULL should be returned */
|
sl@0
|
456 |
}
|
sl@0
|
457 |
else
|
sl@0
|
458 |
{
|
sl@0
|
459 |
r = BN_dup(b);
|
sl@0
|
460 |
}
|
sl@0
|
461 |
|
sl@0
|
462 |
bn_check_top(r);
|
sl@0
|
463 |
return r;
|
sl@0
|
464 |
}
|
sl@0
|
465 |
#endif
|
sl@0
|
466 |
|
sl@0
|
467 |
/* This is an internal function that should not be used in applications.
|
sl@0
|
468 |
* It ensures that 'b' has enough room for a 'words' word number
|
sl@0
|
469 |
* and initialises any unused part of b->d with leading zeros.
|
sl@0
|
470 |
* It is mostly used by the various BIGNUM routines. If there is an error,
|
sl@0
|
471 |
* NULL is returned. If not, 'b' is returned. */
|
sl@0
|
472 |
|
sl@0
|
473 |
EXPORT_C BIGNUM *bn_expand2(BIGNUM *b, int words)
|
sl@0
|
474 |
{
|
sl@0
|
475 |
bn_check_top(b);
|
sl@0
|
476 |
|
sl@0
|
477 |
if (words > b->dmax)
|
sl@0
|
478 |
{
|
sl@0
|
479 |
BN_ULONG *a = bn_expand_internal(b, words);
|
sl@0
|
480 |
if(!a) return NULL;
|
sl@0
|
481 |
if(b->d) OPENSSL_free(b->d);
|
sl@0
|
482 |
b->d=a;
|
sl@0
|
483 |
b->dmax=words;
|
sl@0
|
484 |
}
|
sl@0
|
485 |
|
sl@0
|
486 |
/* None of this should be necessary because of what b->top means! */
|
sl@0
|
487 |
#if 0
|
sl@0
|
488 |
/* NB: bn_wexpand() calls this only if the BIGNUM really has to grow */
|
sl@0
|
489 |
if (b->top < b->dmax)
|
sl@0
|
490 |
{
|
sl@0
|
491 |
int i;
|
sl@0
|
492 |
BN_ULONG *A = &(b->d[b->top]);
|
sl@0
|
493 |
for (i=(b->dmax - b->top)>>3; i>0; i--,A+=8)
|
sl@0
|
494 |
{
|
sl@0
|
495 |
A[0]=0; A[1]=0; A[2]=0; A[3]=0;
|
sl@0
|
496 |
A[4]=0; A[5]=0; A[6]=0; A[7]=0;
|
sl@0
|
497 |
}
|
sl@0
|
498 |
for (i=(b->dmax - b->top)&7; i>0; i--,A++)
|
sl@0
|
499 |
A[0]=0;
|
sl@0
|
500 |
assert(A == &(b->d[b->dmax]));
|
sl@0
|
501 |
}
|
sl@0
|
502 |
#endif
|
sl@0
|
503 |
bn_check_top(b);
|
sl@0
|
504 |
return b;
|
sl@0
|
505 |
}
|
sl@0
|
506 |
|
sl@0
|
507 |
EXPORT_C BIGNUM *BN_dup(const BIGNUM *a)
|
sl@0
|
508 |
{
|
sl@0
|
509 |
BIGNUM *t;
|
sl@0
|
510 |
|
sl@0
|
511 |
if (a == NULL) return NULL;
|
sl@0
|
512 |
bn_check_top(a);
|
sl@0
|
513 |
|
sl@0
|
514 |
t = BN_new();
|
sl@0
|
515 |
if (t == NULL) return NULL;
|
sl@0
|
516 |
if(!BN_copy(t, a))
|
sl@0
|
517 |
{
|
sl@0
|
518 |
BN_free(t);
|
sl@0
|
519 |
return NULL;
|
sl@0
|
520 |
}
|
sl@0
|
521 |
bn_check_top(t);
|
sl@0
|
522 |
return t;
|
sl@0
|
523 |
}
|
sl@0
|
524 |
|
sl@0
|
525 |
EXPORT_C BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
|
sl@0
|
526 |
{
|
sl@0
|
527 |
int i;
|
sl@0
|
528 |
BN_ULONG *A;
|
sl@0
|
529 |
const BN_ULONG *B;
|
sl@0
|
530 |
|
sl@0
|
531 |
bn_check_top(b);
|
sl@0
|
532 |
|
sl@0
|
533 |
if (a == b) return(a);
|
sl@0
|
534 |
if (bn_wexpand(a,b->top) == NULL) return(NULL);
|
sl@0
|
535 |
|
sl@0
|
536 |
#if 1
|
sl@0
|
537 |
A=a->d;
|
sl@0
|
538 |
B=b->d;
|
sl@0
|
539 |
for (i=b->top>>2; i>0; i--,A+=4,B+=4)
|
sl@0
|
540 |
{
|
sl@0
|
541 |
BN_ULONG a0,a1,a2,a3;
|
sl@0
|
542 |
a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
|
sl@0
|
543 |
A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
|
sl@0
|
544 |
}
|
sl@0
|
545 |
switch (b->top&3)
|
sl@0
|
546 |
{
|
sl@0
|
547 |
case 3: A[2]=B[2];
|
sl@0
|
548 |
case 2: A[1]=B[1];
|
sl@0
|
549 |
case 1: A[0]=B[0];
|
sl@0
|
550 |
case 0: ; /* ultrix cc workaround, see comments in bn_expand_internal */
|
sl@0
|
551 |
}
|
sl@0
|
552 |
#else
|
sl@0
|
553 |
memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
|
sl@0
|
554 |
#endif
|
sl@0
|
555 |
|
sl@0
|
556 |
a->top=b->top;
|
sl@0
|
557 |
a->neg=b->neg;
|
sl@0
|
558 |
bn_check_top(a);
|
sl@0
|
559 |
return(a);
|
sl@0
|
560 |
}
|
sl@0
|
561 |
|
sl@0
|
562 |
EXPORT_C void BN_swap(BIGNUM *a, BIGNUM *b)
|
sl@0
|
563 |
{
|
sl@0
|
564 |
int flags_old_a, flags_old_b;
|
sl@0
|
565 |
BN_ULONG *tmp_d;
|
sl@0
|
566 |
int tmp_top, tmp_dmax, tmp_neg;
|
sl@0
|
567 |
|
sl@0
|
568 |
bn_check_top(a);
|
sl@0
|
569 |
bn_check_top(b);
|
sl@0
|
570 |
|
sl@0
|
571 |
flags_old_a = a->flags;
|
sl@0
|
572 |
flags_old_b = b->flags;
|
sl@0
|
573 |
|
sl@0
|
574 |
tmp_d = a->d;
|
sl@0
|
575 |
tmp_top = a->top;
|
sl@0
|
576 |
tmp_dmax = a->dmax;
|
sl@0
|
577 |
tmp_neg = a->neg;
|
sl@0
|
578 |
|
sl@0
|
579 |
a->d = b->d;
|
sl@0
|
580 |
a->top = b->top;
|
sl@0
|
581 |
a->dmax = b->dmax;
|
sl@0
|
582 |
a->neg = b->neg;
|
sl@0
|
583 |
|
sl@0
|
584 |
b->d = tmp_d;
|
sl@0
|
585 |
b->top = tmp_top;
|
sl@0
|
586 |
b->dmax = tmp_dmax;
|
sl@0
|
587 |
b->neg = tmp_neg;
|
sl@0
|
588 |
|
sl@0
|
589 |
a->flags = (flags_old_a & BN_FLG_MALLOCED) | (flags_old_b & BN_FLG_STATIC_DATA);
|
sl@0
|
590 |
b->flags = (flags_old_b & BN_FLG_MALLOCED) | (flags_old_a & BN_FLG_STATIC_DATA);
|
sl@0
|
591 |
bn_check_top(a);
|
sl@0
|
592 |
bn_check_top(b);
|
sl@0
|
593 |
}
|
sl@0
|
594 |
|
sl@0
|
595 |
EXPORT_C void BN_clear(BIGNUM *a)
|
sl@0
|
596 |
{
|
sl@0
|
597 |
bn_check_top(a);
|
sl@0
|
598 |
if (a->d != NULL)
|
sl@0
|
599 |
memset(a->d,0,a->dmax*sizeof(a->d[0]));
|
sl@0
|
600 |
a->top=0;
|
sl@0
|
601 |
a->neg=0;
|
sl@0
|
602 |
}
|
sl@0
|
603 |
|
sl@0
|
604 |
EXPORT_C BN_ULONG BN_get_word(const BIGNUM *a)
|
sl@0
|
605 |
{
|
sl@0
|
606 |
if (a->top > 1)
|
sl@0
|
607 |
return BN_MASK2;
|
sl@0
|
608 |
else if (a->top == 1)
|
sl@0
|
609 |
return a->d[0];
|
sl@0
|
610 |
/* a->top == 0 */
|
sl@0
|
611 |
return 0;
|
sl@0
|
612 |
}
|
sl@0
|
613 |
|
sl@0
|
614 |
EXPORT_C int BN_set_word(BIGNUM *a, BN_ULONG w)
|
sl@0
|
615 |
{
|
sl@0
|
616 |
bn_check_top(a);
|
sl@0
|
617 |
if (bn_expand(a,(int)sizeof(BN_ULONG)*8) == NULL) return(0);
|
sl@0
|
618 |
a->neg = 0;
|
sl@0
|
619 |
a->d[0] = w;
|
sl@0
|
620 |
a->top = (w ? 1 : 0);
|
sl@0
|
621 |
bn_check_top(a);
|
sl@0
|
622 |
return(1);
|
sl@0
|
623 |
}
|
sl@0
|
624 |
|
sl@0
|
625 |
EXPORT_C BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
|
sl@0
|
626 |
{
|
sl@0
|
627 |
unsigned int i,m;
|
sl@0
|
628 |
unsigned int n;
|
sl@0
|
629 |
BN_ULONG l;
|
sl@0
|
630 |
BIGNUM *bn = NULL;
|
sl@0
|
631 |
|
sl@0
|
632 |
if (ret == NULL)
|
sl@0
|
633 |
ret = bn = BN_new();
|
sl@0
|
634 |
if (ret == NULL) return(NULL);
|
sl@0
|
635 |
bn_check_top(ret);
|
sl@0
|
636 |
l=0;
|
sl@0
|
637 |
n=len;
|
sl@0
|
638 |
if (n == 0)
|
sl@0
|
639 |
{
|
sl@0
|
640 |
ret->top=0;
|
sl@0
|
641 |
return(ret);
|
sl@0
|
642 |
}
|
sl@0
|
643 |
i=((n-1)/BN_BYTES)+1;
|
sl@0
|
644 |
m=((n-1)%(BN_BYTES));
|
sl@0
|
645 |
if (bn_wexpand(ret, (int)i) == NULL)
|
sl@0
|
646 |
{
|
sl@0
|
647 |
if (bn) BN_free(bn);
|
sl@0
|
648 |
return NULL;
|
sl@0
|
649 |
}
|
sl@0
|
650 |
ret->top=i;
|
sl@0
|
651 |
ret->neg=0;
|
sl@0
|
652 |
while (n--)
|
sl@0
|
653 |
{
|
sl@0
|
654 |
l=(l<<8L)| *(s++);
|
sl@0
|
655 |
if (m-- == 0)
|
sl@0
|
656 |
{
|
sl@0
|
657 |
ret->d[--i]=l;
|
sl@0
|
658 |
l=0;
|
sl@0
|
659 |
m=BN_BYTES-1;
|
sl@0
|
660 |
}
|
sl@0
|
661 |
}
|
sl@0
|
662 |
/* need to call this due to clear byte at top if avoiding
|
sl@0
|
663 |
* having the top bit set (-ve number) */
|
sl@0
|
664 |
bn_correct_top(ret);
|
sl@0
|
665 |
return(ret);
|
sl@0
|
666 |
}
|
sl@0
|
667 |
|
sl@0
|
668 |
/* ignore negative */
|
sl@0
|
669 |
EXPORT_C int BN_bn2bin(const BIGNUM *a, unsigned char *to)
|
sl@0
|
670 |
{
|
sl@0
|
671 |
int n,i;
|
sl@0
|
672 |
BN_ULONG l;
|
sl@0
|
673 |
|
sl@0
|
674 |
bn_check_top(a);
|
sl@0
|
675 |
n=i=BN_num_bytes(a);
|
sl@0
|
676 |
while (i--)
|
sl@0
|
677 |
{
|
sl@0
|
678 |
l=a->d[i/BN_BYTES];
|
sl@0
|
679 |
*(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
|
sl@0
|
680 |
}
|
sl@0
|
681 |
return(n);
|
sl@0
|
682 |
}
|
sl@0
|
683 |
|
sl@0
|
684 |
EXPORT_C int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
|
sl@0
|
685 |
{
|
sl@0
|
686 |
int i;
|
sl@0
|
687 |
BN_ULONG t1,t2,*ap,*bp;
|
sl@0
|
688 |
|
sl@0
|
689 |
bn_check_top(a);
|
sl@0
|
690 |
bn_check_top(b);
|
sl@0
|
691 |
|
sl@0
|
692 |
i=a->top-b->top;
|
sl@0
|
693 |
if (i != 0) return(i);
|
sl@0
|
694 |
ap=a->d;
|
sl@0
|
695 |
bp=b->d;
|
sl@0
|
696 |
for (i=a->top-1; i>=0; i--)
|
sl@0
|
697 |
{
|
sl@0
|
698 |
t1= ap[i];
|
sl@0
|
699 |
t2= bp[i];
|
sl@0
|
700 |
if (t1 != t2)
|
sl@0
|
701 |
return((t1 > t2) ? 1 : -1);
|
sl@0
|
702 |
}
|
sl@0
|
703 |
return(0);
|
sl@0
|
704 |
}
|
sl@0
|
705 |
|
sl@0
|
706 |
EXPORT_C int BN_cmp(const BIGNUM *a, const BIGNUM *b)
|
sl@0
|
707 |
{
|
sl@0
|
708 |
int i;
|
sl@0
|
709 |
int gt,lt;
|
sl@0
|
710 |
BN_ULONG t1,t2;
|
sl@0
|
711 |
|
sl@0
|
712 |
if ((a == NULL) || (b == NULL))
|
sl@0
|
713 |
{
|
sl@0
|
714 |
if (a != NULL)
|
sl@0
|
715 |
return(-1);
|
sl@0
|
716 |
else if (b != NULL)
|
sl@0
|
717 |
return(1);
|
sl@0
|
718 |
else
|
sl@0
|
719 |
return(0);
|
sl@0
|
720 |
}
|
sl@0
|
721 |
|
sl@0
|
722 |
bn_check_top(a);
|
sl@0
|
723 |
bn_check_top(b);
|
sl@0
|
724 |
|
sl@0
|
725 |
if (a->neg != b->neg)
|
sl@0
|
726 |
{
|
sl@0
|
727 |
if (a->neg)
|
sl@0
|
728 |
return(-1);
|
sl@0
|
729 |
else return(1);
|
sl@0
|
730 |
}
|
sl@0
|
731 |
if (a->neg == 0)
|
sl@0
|
732 |
{ gt=1; lt= -1; }
|
sl@0
|
733 |
else { gt= -1; lt=1; }
|
sl@0
|
734 |
|
sl@0
|
735 |
if (a->top > b->top) return(gt);
|
sl@0
|
736 |
if (a->top < b->top) return(lt);
|
sl@0
|
737 |
for (i=a->top-1; i>=0; i--)
|
sl@0
|
738 |
{
|
sl@0
|
739 |
t1=a->d[i];
|
sl@0
|
740 |
t2=b->d[i];
|
sl@0
|
741 |
if (t1 > t2) return(gt);
|
sl@0
|
742 |
if (t1 < t2) return(lt);
|
sl@0
|
743 |
}
|
sl@0
|
744 |
return(0);
|
sl@0
|
745 |
}
|
sl@0
|
746 |
|
sl@0
|
747 |
EXPORT_C int BN_set_bit(BIGNUM *a, int n)
|
sl@0
|
748 |
{
|
sl@0
|
749 |
int i,j,k;
|
sl@0
|
750 |
|
sl@0
|
751 |
if (n < 0)
|
sl@0
|
752 |
return 0;
|
sl@0
|
753 |
|
sl@0
|
754 |
i=n/BN_BITS2;
|
sl@0
|
755 |
j=n%BN_BITS2;
|
sl@0
|
756 |
if (a->top <= i)
|
sl@0
|
757 |
{
|
sl@0
|
758 |
if (bn_wexpand(a,i+1) == NULL) return(0);
|
sl@0
|
759 |
for(k=a->top; k<i+1; k++)
|
sl@0
|
760 |
a->d[k]=0;
|
sl@0
|
761 |
a->top=i+1;
|
sl@0
|
762 |
}
|
sl@0
|
763 |
|
sl@0
|
764 |
a->d[i]|=(((BN_ULONG)1)<<j);
|
sl@0
|
765 |
bn_check_top(a);
|
sl@0
|
766 |
return(1);
|
sl@0
|
767 |
}
|
sl@0
|
768 |
|
sl@0
|
769 |
EXPORT_C int BN_clear_bit(BIGNUM *a, int n)
|
sl@0
|
770 |
{
|
sl@0
|
771 |
int i,j;
|
sl@0
|
772 |
|
sl@0
|
773 |
bn_check_top(a);
|
sl@0
|
774 |
if (n < 0) return 0;
|
sl@0
|
775 |
|
sl@0
|
776 |
i=n/BN_BITS2;
|
sl@0
|
777 |
j=n%BN_BITS2;
|
sl@0
|
778 |
if (a->top <= i) return(0);
|
sl@0
|
779 |
|
sl@0
|
780 |
a->d[i]&=(~(((BN_ULONG)1)<<j));
|
sl@0
|
781 |
bn_correct_top(a);
|
sl@0
|
782 |
return(1);
|
sl@0
|
783 |
}
|
sl@0
|
784 |
|
sl@0
|
785 |
EXPORT_C int BN_is_bit_set(const BIGNUM *a, int n)
|
sl@0
|
786 |
{
|
sl@0
|
787 |
int i,j;
|
sl@0
|
788 |
|
sl@0
|
789 |
bn_check_top(a);
|
sl@0
|
790 |
if (n < 0) return 0;
|
sl@0
|
791 |
i=n/BN_BITS2;
|
sl@0
|
792 |
j=n%BN_BITS2;
|
sl@0
|
793 |
if (a->top <= i) return 0;
|
sl@0
|
794 |
return(((a->d[i])>>j)&((BN_ULONG)1));
|
sl@0
|
795 |
}
|
sl@0
|
796 |
|
sl@0
|
797 |
EXPORT_C int BN_mask_bits(BIGNUM *a, int n)
|
sl@0
|
798 |
{
|
sl@0
|
799 |
int b,w;
|
sl@0
|
800 |
|
sl@0
|
801 |
bn_check_top(a);
|
sl@0
|
802 |
if (n < 0) return 0;
|
sl@0
|
803 |
|
sl@0
|
804 |
w=n/BN_BITS2;
|
sl@0
|
805 |
b=n%BN_BITS2;
|
sl@0
|
806 |
if (w >= a->top) return 0;
|
sl@0
|
807 |
if (b == 0)
|
sl@0
|
808 |
a->top=w;
|
sl@0
|
809 |
else
|
sl@0
|
810 |
{
|
sl@0
|
811 |
a->top=w+1;
|
sl@0
|
812 |
a->d[w]&= ~(BN_MASK2<<b);
|
sl@0
|
813 |
}
|
sl@0
|
814 |
bn_correct_top(a);
|
sl@0
|
815 |
return(1);
|
sl@0
|
816 |
}
|
sl@0
|
817 |
|
sl@0
|
818 |
EXPORT_C void BN_set_negative(BIGNUM *a, int b)
|
sl@0
|
819 |
{
|
sl@0
|
820 |
if (b && !BN_is_zero(a))
|
sl@0
|
821 |
a->neg = 1;
|
sl@0
|
822 |
else
|
sl@0
|
823 |
a->neg = 0;
|
sl@0
|
824 |
}
|
sl@0
|
825 |
|
sl@0
|
826 |
EXPORT_C int bn_cmp_words(const BN_ULONG *a, const BN_ULONG *b, int n)
|
sl@0
|
827 |
{
|
sl@0
|
828 |
int i;
|
sl@0
|
829 |
BN_ULONG aa,bb;
|
sl@0
|
830 |
|
sl@0
|
831 |
aa=a[n-1];
|
sl@0
|
832 |
bb=b[n-1];
|
sl@0
|
833 |
if (aa != bb) return((aa > bb)?1:-1);
|
sl@0
|
834 |
for (i=n-2; i>=0; i--)
|
sl@0
|
835 |
{
|
sl@0
|
836 |
aa=a[i];
|
sl@0
|
837 |
bb=b[i];
|
sl@0
|
838 |
if (aa != bb) return((aa > bb)?1:-1);
|
sl@0
|
839 |
}
|
sl@0
|
840 |
return(0);
|
sl@0
|
841 |
}
|
sl@0
|
842 |
|
sl@0
|
843 |
/* Here follows a specialised variants of bn_cmp_words(). It has the
|
sl@0
|
844 |
property of performing the operation on arrays of different sizes.
|
sl@0
|
845 |
The sizes of those arrays is expressed through cl, which is the
|
sl@0
|
846 |
common length ( basicall, min(len(a),len(b)) ), and dl, which is the
|
sl@0
|
847 |
delta between the two lengths, calculated as len(a)-len(b).
|
sl@0
|
848 |
All lengths are the number of BN_ULONGs... */
|
sl@0
|
849 |
|
sl@0
|
850 |
EXPORT_C int bn_cmp_part_words(const BN_ULONG *a, const BN_ULONG *b,
|
sl@0
|
851 |
int cl, int dl)
|
sl@0
|
852 |
{
|
sl@0
|
853 |
int n,i;
|
sl@0
|
854 |
n = cl-1;
|
sl@0
|
855 |
|
sl@0
|
856 |
if (dl < 0)
|
sl@0
|
857 |
{
|
sl@0
|
858 |
for (i=dl; i<0; i++)
|
sl@0
|
859 |
{
|
sl@0
|
860 |
if (b[n-i] != 0)
|
sl@0
|
861 |
return -1; /* a < b */
|
sl@0
|
862 |
}
|
sl@0
|
863 |
}
|
sl@0
|
864 |
if (dl > 0)
|
sl@0
|
865 |
{
|
sl@0
|
866 |
for (i=dl; i>0; i--)
|
sl@0
|
867 |
{
|
sl@0
|
868 |
if (a[n+i] != 0)
|
sl@0
|
869 |
return 1; /* a > b */
|
sl@0
|
870 |
}
|
sl@0
|
871 |
}
|
sl@0
|
872 |
return bn_cmp_words(a,b,cl);
|
sl@0
|
873 |
}
|