blob: 89a3267b4af10485ef95b9ffe5e33a169e352feb [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>
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +000065#include <stdio.h>
66#include "cryptlib.h"
67#include "bn_lcl.h"
68
Ben Lauriee7788021999-04-17 21:25:43 +000069const char *BN_version="Big Number" OPENSSL_VERSION_PTEXT;
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +000070
71/* For a 32 bit machine
72 * 2 - 4 == 128
73 * 3 - 8 == 256
74 * 4 - 16 == 512
75 * 5 - 32 == 1024
76 * 6 - 64 == 2048
77 * 7 - 128 == 4096
78 * 8 - 256 == 8192
79 */
Ulf Möller775c63f2000-02-26 22:16:47 +000080static int bn_limit_bits=0;
81static int bn_limit_num=8; /* (1<<bn_limit_bits) */
82static int bn_limit_bits_low=0;
83static int bn_limit_num_low=8; /* (1<<bn_limit_bits_low) */
84static int bn_limit_bits_high=0;
85static int bn_limit_num_high=8; /* (1<<bn_limit_bits_high) */
86static int bn_limit_bits_mont=0;
87static int bn_limit_num_mont=8; /* (1<<bn_limit_bits_mont) */
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +000088
Ulf Möller6b691a51999-04-19 21:31:43 +000089void BN_set_params(int mult, int high, int low, int mont)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +000090 {
91 if (mult >= 0)
92 {
93 if (mult > (sizeof(int)*8)-1)
94 mult=sizeof(int)*8-1;
95 bn_limit_bits=mult;
96 bn_limit_num=1<<mult;
97 }
98 if (high >= 0)
99 {
100 if (high > (sizeof(int)*8)-1)
101 high=sizeof(int)*8-1;
102 bn_limit_bits_high=high;
103 bn_limit_num_high=1<<high;
104 }
105 if (low >= 0)
106 {
107 if (low > (sizeof(int)*8)-1)
108 low=sizeof(int)*8-1;
109 bn_limit_bits_low=low;
110 bn_limit_num_low=1<<low;
111 }
112 if (mont >= 0)
113 {
114 if (mont > (sizeof(int)*8)-1)
115 mont=sizeof(int)*8-1;
116 bn_limit_bits_mont=mont;
117 bn_limit_num_mont=1<<mont;
118 }
119 }
120
Ulf Möller6b691a51999-04-19 21:31:43 +0000121int BN_get_params(int which)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000122 {
123 if (which == 0) return(bn_limit_bits);
124 else if (which == 1) return(bn_limit_bits_high);
125 else if (which == 2) return(bn_limit_bits_low);
126 else if (which == 3) return(bn_limit_bits_mont);
127 else return(0);
128 }
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000129
Ulf Möller6b691a51999-04-19 21:31:43 +0000130BIGNUM *BN_value_one(void)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000131 {
132 static BN_ULONG data_one=1L;
133 static BIGNUM const_one={&data_one,1,1,0};
134
135 return(&const_one);
136 }
137
Ulf Möller6b691a51999-04-19 21:31:43 +0000138char *BN_options(void)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000139 {
140 static int init=0;
141 static char data[16];
142
143 if (!init)
144 {
145 init++;
146#ifdef BN_LLONG
147 sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULLONG)*8,
148 (int)sizeof(BN_ULONG)*8);
149#else
150 sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULONG)*8,
151 (int)sizeof(BN_ULONG)*8);
152#endif
153 }
154 return(data);
155 }
156
Ulf Möller6b691a51999-04-19 21:31:43 +0000157int BN_num_bits_word(BN_ULONG l)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000158 {
Ulf Möllere14d4441999-05-20 01:43:07 +0000159 static const char bits[256]={
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000160 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
161 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
162 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
163 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
164 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
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 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 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 };
177
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000178#if defined(SIXTY_FOUR_BIT_LONG)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000179 if (l & 0xffffffff00000000L)
180 {
181 if (l & 0xffff000000000000L)
182 {
183 if (l & 0xff00000000000000L)
184 {
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000185 return(bits[(int)(l>>56)]+56);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000186 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000187 else return(bits[(int)(l>>48)]+48);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000188 }
189 else
190 {
191 if (l & 0x0000ff0000000000L)
192 {
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000193 return(bits[(int)(l>>40)]+40);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000194 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000195 else return(bits[(int)(l>>32)]+32);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000196 }
197 }
198 else
199#else
200#ifdef SIXTY_FOUR_BIT
201 if (l & 0xffffffff00000000LL)
202 {
203 if (l & 0xffff000000000000LL)
204 {
205 if (l & 0xff00000000000000LL)
206 {
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000207 return(bits[(int)(l>>56)]+56);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000208 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000209 else return(bits[(int)(l>>48)]+48);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000210 }
211 else
212 {
213 if (l & 0x0000ff0000000000LL)
214 {
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000215 return(bits[(int)(l>>40)]+40);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000216 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000217 else return(bits[(int)(l>>32)]+32);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000218 }
219 }
220 else
221#endif
222#endif
223 {
224#if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
225 if (l & 0xffff0000L)
226 {
227 if (l & 0xff000000L)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000228 return(bits[(int)(l>>24L)]+24);
229 else return(bits[(int)(l>>16L)]+16);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000230 }
231 else
232#endif
233 {
234#if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
235 if (l & 0xff00L)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000236 return(bits[(int)(l>>8)]+8);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000237 else
238#endif
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000239 return(bits[(int)(l )] );
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000240 }
241 }
242 }
243
Ben Laurie84c15db1999-06-04 22:23:10 +0000244int BN_num_bits(const BIGNUM *a)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000245 {
246 BN_ULONG l;
247 int i;
248
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000249 bn_check_top(a);
250
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000251 if (a->top == 0) return(0);
252 l=a->d[a->top-1];
Bodo Möllerbbb8de02000-09-04 15:34:43 +0000253 assert(l != 0);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000254 i=(a->top-1)*BN_BITS2;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000255 return(i+BN_num_bits_word(l));
256 }
257
Ulf Möller6b691a51999-04-19 21:31:43 +0000258void BN_clear_free(BIGNUM *a)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000259 {
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000260 int i;
261
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000262 if (a == NULL) return;
263 if (a->d != NULL)
264 {
Dr. Stephen Henson2d978cb2000-08-04 00:01:39 +0000265 memset(a->d,0,a->dmax*sizeof(a->d[0]));
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000266 if (!(BN_get_flags(a,BN_FLG_STATIC_DATA)))
Richard Levitte26a3a482000-06-01 22:19:21 +0000267 OPENSSL_free(a->d);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000268 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000269 i=BN_get_flags(a,BN_FLG_MALLOCED);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000270 memset(a,0,sizeof(BIGNUM));
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000271 if (i)
Richard Levitte26a3a482000-06-01 22:19:21 +0000272 OPENSSL_free(a);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000273 }
274
Ulf Möller6b691a51999-04-19 21:31:43 +0000275void BN_free(BIGNUM *a)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000276 {
277 if (a == NULL) return;
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000278 if ((a->d != NULL) && !(BN_get_flags(a,BN_FLG_STATIC_DATA)))
Richard Levitte26a3a482000-06-01 22:19:21 +0000279 OPENSSL_free(a->d);
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000280 a->flags|=BN_FLG_FREE; /* REMOVE? */
281 if (a->flags & BN_FLG_MALLOCED)
Richard Levitte26a3a482000-06-01 22:19:21 +0000282 OPENSSL_free(a);
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000283 }
284
Ulf Möller6b691a51999-04-19 21:31:43 +0000285void BN_init(BIGNUM *a)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000286 {
287 memset(a,0,sizeof(BIGNUM));
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000288 }
289
Ulf Möller6b691a51999-04-19 21:31:43 +0000290BIGNUM *BN_new(void)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000291 {
292 BIGNUM *ret;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000293
Richard Levitte26a3a482000-06-01 22:19:21 +0000294 if ((ret=(BIGNUM *)OPENSSL_malloc(sizeof(BIGNUM))) == NULL)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000295 {
296 BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
297 return(NULL);
298 }
299 ret->flags=BN_FLG_MALLOCED;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000300 ret->top=0;
301 ret->neg=0;
Dr. Stephen Henson2d978cb2000-08-04 00:01:39 +0000302 ret->dmax=0;
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000303 ret->d=NULL;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000304 return(ret);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000305 }
306
Richard Levitte020fc822000-11-06 21:15:54 +0000307/* This is used both by bn_expand2() and bn_dup_expand() */
308/* The caller MUST check that words > b->dmax before calling this */
309static BN_ULONG *internal_bn_expand(const BIGNUM *b, int words)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000310 {
Richard Levitte020fc822000-11-06 21:15:54 +0000311 BN_ULONG *A,*a = NULL;
Ulf Möllere14d4441999-05-20 01:43:07 +0000312 const BN_ULONG *B;
313 int i;
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000314
Richard Levitte020fc822000-11-06 21:15:54 +0000315 bn_check_top(b);
316 if (BN_get_flags(b,BN_FLG_STATIC_DATA))
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000317 {
Richard Levitte020fc822000-11-06 21:15:54 +0000318 BNerr(BN_F_BN_EXPAND2,BN_R_EXPAND_ON_STATIC_BIGNUM_DATA);
319 return(NULL);
320 }
321 a=A=(BN_ULONG *)OPENSSL_malloc(sizeof(BN_ULONG)*(words+1));
322 if (A == NULL)
323 {
324 BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE);
325 return(NULL);
326 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000327#if 1
Richard Levitte020fc822000-11-06 21:15:54 +0000328 B=b->d;
329 /* Check if the previous number needs to be copied */
330 if (B != NULL)
331 {
Ulf Möllere14d4441999-05-20 01:43:07 +0000332#if 0
Richard Levitte020fc822000-11-06 21:15:54 +0000333 /* This lot is an unrolled loop to copy b->top
334 * BN_ULONGs from B to A
335 */
Ulf Möllere14d4441999-05-20 01:43:07 +0000336/*
337 * I have nothing against unrolling but it's usually done for
338 * several reasons, namely:
339 * - minimize percentage of decision making code, i.e. branches;
340 * - avoid cache trashing;
341 * - make it possible to schedule loads earlier;
342 * Now let's examine the code below. The cornerstone of C is
343 * "programmer is always right" and that's what we love it for:-)
344 * For this very reason C compilers have to be paranoid when it
345 * comes to data aliasing and assume the worst. Yeah, but what
346 * does it mean in real life? This means that loop body below will
347 * be compiled to sequence of loads immediately followed by stores
348 * as compiler assumes the worst, something in A==B+1 style. As a
349 * result CPU pipeline is going to starve for incoming data. Secondly
350 * if A and B happen to share same cache line such code is going to
351 * cause severe cache trashing. Both factors have severe impact on
352 * performance of modern CPUs and this is the reason why this
Ulf Möller657e60f2000-02-03 23:23:24 +0000353 * particular piece of code is #ifdefed away and replaced by more
Ulf Möllere14d4441999-05-20 01:43:07 +0000354 * "friendly" version found in #else section below. This comment
355 * also applies to BN_copy function.
356 *
357 * <appro@fy.chalmers.se>
358 */
Richard Levitte020fc822000-11-06 21:15:54 +0000359 for (i=b->top&(~7); i>0; i-=8)
Dr. Stephen Henson953937b1999-04-15 23:07:00 +0000360 {
Richard Levitte020fc822000-11-06 21:15:54 +0000361 A[0]=B[0]; A[1]=B[1]; A[2]=B[2]; A[3]=B[3];
362 A[4]=B[4]; A[5]=B[5]; A[6]=B[6]; A[7]=B[7];
363 A+=8;
364 B+=8;
Dr. Stephen Henson953937b1999-04-15 23:07:00 +0000365 }
Richard Levitte020fc822000-11-06 21:15:54 +0000366 switch (b->top&7)
367 {
368 case 7:
369 A[6]=B[6];
370 case 6:
371 A[5]=B[5];
372 case 5:
373 A[4]=B[4];
374 case 4:
375 A[3]=B[3];
376 case 3:
377 A[2]=B[2];
378 case 2:
379 A[1]=B[1];
380 case 1:
381 A[0]=B[0];
382 case 0:
383 /* I need the 'case 0' entry for utrix cc.
384 * If the optimizer is turned on, it does the
385 * switch table by doing
386 * a=top&7
387 * a--;
388 * goto jump_table[a];
389 * If top is 0, this makes us jump to 0xffffffc
390 * which is rather bad :-(.
391 * eric 23-Apr-1998
392 */
393 ;
394 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000395#else
Richard Levitte020fc822000-11-06 21:15:54 +0000396 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
397 {
398 /*
399 * The fact that the loop is unrolled
400 * 4-wise is a tribute to Intel. It's
401 * the one that doesn't have enough
402 * registers to accomodate more data.
403 * I'd unroll it 8-wise otherwise:-)
404 *
405 * <appro@fy.chalmers.se>
406 */
407 BN_ULONG a0,a1,a2,a3;
408 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
409 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
410 }
411 switch (b->top&3)
412 {
413 case 3: A[2]=B[2];
414 case 2: A[1]=B[1];
415 case 1: A[0]=B[0];
416 case 0: ; /* ultrix cc workaround, see above */
417 }
418#endif
419 }
420
421 /* Now need to zero any data between b->top and b->max */
422
423 A= &(a[b->top]);
424 for (i=(words - b->top)>>3; i>0; i--,A+=8)
425 {
426 A[0]=0; A[1]=0; A[2]=0; A[3]=0;
427 A[4]=0; A[5]=0; A[6]=0; A[7]=0;
428 }
429 for (i=(words - b->top)&7; i>0; i--,A++)
430 A[0]=0;
431#else
432 memset(A,0,sizeof(BN_ULONG)*(words+1));
433 memcpy(A,b->d,sizeof(b->d[0])*b->top);
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000434#endif
435
Richard Levitte020fc822000-11-06 21:15:54 +0000436 return(a);
437 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000438
Richard Levitte020fc822000-11-06 21:15:54 +0000439/* This is an internal function that can be used instead of bn_expand2()
440 * when there is a need to copy BIGNUMs instead of only expanding the
441 * data part, while still expanding them.
442 * Especially useful when needing to expand BIGNUMs that are declared
443 * 'const' and should therefore not be changed.
444 * The reason to use this instead of a BN_dup() followed by a bn_expand2()
445 * is memory allocation overhead. A BN_dup() followed by a bn_expand2()
446 * will allocate new memory for the BIGNUM data twice, and free it once,
447 * while bn_dup_expand() makes sure allocation is made only once.
448 */
449
450BIGNUM *bn_dup_expand(const BIGNUM *b, int words)
451 {
452 BIGNUM *r = NULL;
453
454 if (words > b->dmax)
455 {
456 BN_ULONG *a = internal_bn_expand(b, words);
457
458 if (a)
459 {
460 r = BN_new();
Bodo Möller58f0f522000-11-07 09:35:19 +0000461 if (r)
462 {
463 r->top = b->top;
464 r->dmax = words;
465 r->neg = b->neg;
466 r->d = a;
467 }
468 else
469 {
470 /* r == NULL, BN_new failure */
471 OPENSSL_free(a);
472 }
Richard Levitte020fc822000-11-06 21:15:54 +0000473 }
Bodo Möller58f0f522000-11-07 09:35:19 +0000474 /* If a == NULL, there was an error in allocation in
Richard Levitte020fc822000-11-06 21:15:54 +0000475 internal_bn_expand(), and NULL should be returned */
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000476 }
Richard Levitte020fc822000-11-06 21:15:54 +0000477 else
478 {
479 r = BN_dup(b);
480 }
481
482 return r;
483 }
484
485/* This is an internal function that should not be used in applications.
486 * It ensures that 'b' has enough room for a 'words' word number number.
487 * It is mostly used by the various BIGNUM routines. If there is an error,
488 * NULL is returned. If not, 'b' is returned. */
489
490BIGNUM *bn_expand2(BIGNUM *b, int words)
491 {
492 if (words > b->dmax)
493 {
494 BN_ULONG *a = internal_bn_expand(b, words);
495
496 if (a)
497 {
498 OPENSSL_free(b->d);
499 b->d=a;
500 b->dmax=words;
501 }
502 else
503 b = NULL;
504 }
505 return b;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000506 }
507
Ben Laurie84c15db1999-06-04 22:23:10 +0000508BIGNUM *BN_dup(const BIGNUM *a)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000509 {
510 BIGNUM *r;
511
Bodo Möller8d85b331999-07-30 19:22:57 +0000512 if (a == NULL) return NULL;
513
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000514 bn_check_top(a);
515
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000516 r=BN_new();
517 if (r == NULL) return(NULL);
518 return((BIGNUM *)BN_copy(r,a));
519 }
520
Ben Laurie84c15db1999-06-04 22:23:10 +0000521BIGNUM *BN_copy(BIGNUM *a, const BIGNUM *b)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000522 {
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000523 int i;
Ulf Möllere14d4441999-05-20 01:43:07 +0000524 BN_ULONG *A;
525 const BN_ULONG *B;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000526
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000527 bn_check_top(b);
528
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000529 if (a == b) return(a);
530 if (bn_wexpand(a,b->top) == NULL) return(NULL);
531
532#if 1
533 A=a->d;
534 B=b->d;
Ulf Möllere14d4441999-05-20 01:43:07 +0000535 for (i=b->top>>2; i>0; i--,A+=4,B+=4)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000536 {
Ulf Möllere14d4441999-05-20 01:43:07 +0000537 BN_ULONG a0,a1,a2,a3;
538 a0=B[0]; a1=B[1]; a2=B[2]; a3=B[3];
539 A[0]=a0; A[1]=a1; A[2]=a2; A[3]=a3;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000540 }
Ulf Möllere14d4441999-05-20 01:43:07 +0000541 switch (b->top&3)
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000542 {
Ulf Möllere14d4441999-05-20 01:43:07 +0000543 case 3: A[2]=B[2];
544 case 2: A[1]=B[1];
545 case 1: A[0]=B[0];
546 case 0: ; /* ultrix cc workaround, see comments in bn_expand2 */
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000547 }
548#else
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000549 memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000550#endif
551
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000552/* memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
553 a->top=b->top;
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000554 if ((a->top == 0) && (a->d != NULL))
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000555 a->d[0]=0;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000556 a->neg=b->neg;
557 return(a);
558 }
559
Ulf Möller6b691a51999-04-19 21:31:43 +0000560void BN_clear(BIGNUM *a)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000561 {
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000562 if (a->d != NULL)
Dr. Stephen Henson2d978cb2000-08-04 00:01:39 +0000563 memset(a->d,0,a->dmax*sizeof(a->d[0]));
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000564 a->top=0;
565 a->neg=0;
566 }
567
Richard Levitte020fc822000-11-06 21:15:54 +0000568BN_ULONG BN_get_word(const BIGNUM *a)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000569 {
570 int i,n;
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000571 BN_ULONG ret=0;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000572
573 n=BN_num_bytes(a);
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000574 if (n > sizeof(BN_ULONG))
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000575 return(BN_MASK2);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000576 for (i=a->top-1; i>=0; i--)
577 {
578#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
579 ret<<=BN_BITS4; /* stops the compiler complaining */
580 ret<<=BN_BITS4;
Ulf Möllere14d4441999-05-20 01:43:07 +0000581#else
582 ret=0;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000583#endif
584 ret|=a->d[i];
585 }
586 return(ret);
587 }
588
Ulf Möller6b691a51999-04-19 21:31:43 +0000589int BN_set_word(BIGNUM *a, BN_ULONG w)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000590 {
591 int i,n;
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000592 if (bn_expand(a,sizeof(BN_ULONG)*8) == NULL) return(0);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000593
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000594 n=sizeof(BN_ULONG)/BN_BYTES;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000595 a->neg=0;
596 a->top=0;
597 a->d[0]=(BN_ULONG)w&BN_MASK2;
598 if (a->d[0] != 0) a->top=1;
599 for (i=1; i<n; i++)
600 {
601 /* the following is done instead of
602 * w>>=BN_BITS2 so compilers don't complain
603 * on builds where sizeof(long) == BN_TYPES */
604#ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
605 w>>=BN_BITS4;
606 w>>=BN_BITS4;
Ulf Möllere14d4441999-05-20 01:43:07 +0000607#else
608 w=0;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000609#endif
610 a->d[i]=(BN_ULONG)w&BN_MASK2;
611 if (a->d[i] != 0) a->top=i+1;
612 }
613 return(1);
614 }
615
616/* ignore negative */
Ben Laurie61f5b6f1999-04-23 15:01:15 +0000617BIGNUM *BN_bin2bn(const unsigned char *s, int len, BIGNUM *ret)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000618 {
619 unsigned int i,m;
620 unsigned int n;
621 BN_ULONG l;
622
623 if (ret == NULL) ret=BN_new();
624 if (ret == NULL) return(NULL);
625 l=0;
626 n=len;
627 if (n == 0)
628 {
629 ret->top=0;
630 return(ret);
631 }
632 if (bn_expand(ret,(int)(n+2)*8) == NULL)
633 return(NULL);
634 i=((n-1)/BN_BYTES)+1;
635 m=((n-1)%(BN_BYTES));
636 ret->top=i;
637 while (n-- > 0)
638 {
639 l=(l<<8L)| *(s++);
640 if (m-- == 0)
641 {
642 ret->d[--i]=l;
643 l=0;
644 m=BN_BYTES-1;
645 }
646 }
647 /* need to call this due to clear byte at top if avoiding
648 * having the top bit set (-ve number) */
649 bn_fix_top(ret);
650 return(ret);
651 }
652
653/* ignore negative */
Dr. Stephen Henson8623f691999-06-20 17:36:11 +0000654int BN_bn2bin(const BIGNUM *a, unsigned char *to)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000655 {
656 int n,i;
657 BN_ULONG l;
658
659 n=i=BN_num_bytes(a);
660 while (i-- > 0)
661 {
662 l=a->d[i/BN_BYTES];
663 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
664 }
665 return(n);
666 }
667
Ben Laurie84c15db1999-06-04 22:23:10 +0000668int BN_ucmp(const BIGNUM *a, const BIGNUM *b)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000669 {
670 int i;
671 BN_ULONG t1,t2,*ap,*bp;
672
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000673 bn_check_top(a);
674 bn_check_top(b);
675
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000676 i=a->top-b->top;
677 if (i != 0) return(i);
678 ap=a->d;
679 bp=b->d;
680 for (i=a->top-1; i>=0; i--)
681 {
682 t1= ap[i];
683 t2= bp[i];
684 if (t1 != t2)
685 return(t1 > t2?1:-1);
686 }
687 return(0);
688 }
689
Ben Laurie84c15db1999-06-04 22:23:10 +0000690int BN_cmp(const BIGNUM *a, const BIGNUM *b)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000691 {
692 int i;
693 int gt,lt;
694 BN_ULONG t1,t2;
695
696 if ((a == NULL) || (b == NULL))
697 {
698 if (a != NULL)
699 return(-1);
700 else if (b != NULL)
701 return(1);
702 else
703 return(0);
704 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000705
706 bn_check_top(a);
707 bn_check_top(b);
708
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000709 if (a->neg != b->neg)
710 {
711 if (a->neg)
712 return(-1);
713 else return(1);
714 }
715 if (a->neg == 0)
716 { gt=1; lt= -1; }
717 else { gt= -1; lt=1; }
718
719 if (a->top > b->top) return(gt);
720 if (a->top < b->top) return(lt);
721 for (i=a->top-1; i>=0; i--)
722 {
723 t1=a->d[i];
724 t2=b->d[i];
725 if (t1 > t2) return(gt);
726 if (t1 < t2) return(lt);
727 }
728 return(0);
729 }
730
Ulf Möller6b691a51999-04-19 21:31:43 +0000731int BN_set_bit(BIGNUM *a, int n)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000732 {
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000733 int i,j,k;
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000734
735 i=n/BN_BITS2;
736 j=n%BN_BITS2;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000737 if (a->top <= i)
738 {
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000739 if (bn_wexpand(a,i+1) == NULL) return(0);
740 for(k=a->top; k<i+1; k++)
741 a->d[k]=0;
Ralf S. Engelschall58964a41998-12-21 10:56:39 +0000742 a->top=i+1;
743 }
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000744
Ulf Möllere14d4441999-05-20 01:43:07 +0000745 a->d[i]|=(((BN_ULONG)1)<<j);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000746 return(1);
747 }
748
Ulf Möller6b691a51999-04-19 21:31:43 +0000749int BN_clear_bit(BIGNUM *a, int n)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000750 {
751 int i,j;
752
753 i=n/BN_BITS2;
754 j=n%BN_BITS2;
755 if (a->top <= i) return(0);
756
Ulf Möllere14d4441999-05-20 01:43:07 +0000757 a->d[i]&=(~(((BN_ULONG)1)<<j));
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000758 bn_fix_top(a);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000759 return(1);
760 }
761
Ben Laurie84c15db1999-06-04 22:23:10 +0000762int BN_is_bit_set(const BIGNUM *a, int n)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000763 {
764 int i,j;
765
766 if (n < 0) return(0);
767 i=n/BN_BITS2;
768 j=n%BN_BITS2;
769 if (a->top <= i) return(0);
770 return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
771 }
772
Ulf Möller6b691a51999-04-19 21:31:43 +0000773int BN_mask_bits(BIGNUM *a, int n)
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000774 {
775 int b,w;
776
777 w=n/BN_BITS2;
778 b=n%BN_BITS2;
779 if (w >= a->top) return(0);
780 if (b == 0)
781 a->top=w;
782 else
783 {
784 a->top=w+1;
785 a->d[w]&= ~(BN_MASK2<<b);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000786 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000787 bn_fix_top(a);
Ralf S. Engelschalld02b48c1998-12-21 10:52:47 +0000788 return(1);
789 }
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000790
Ulf Möller6b691a51999-04-19 21:31:43 +0000791int bn_cmp_words(BN_ULONG *a, BN_ULONG *b, int n)
Ralf S. Engelschalldfeab061998-12-21 11:00:56 +0000792 {
793 int i;
794 BN_ULONG aa,bb;
795
796 aa=a[n-1];
797 bb=b[n-1];
798 if (aa != bb) return((aa > bb)?1:-1);
799 for (i=n-2; i>=0; i--)
800 {
801 aa=a[i];
802 bb=b[i];
803 if (aa != bb) return((aa > bb)?1:-1);
804 }
805 return(0);
806 }
807