Import of old SSLeay release: SSLeay 0.8.1b
[openssl.git] / crypto / bn / bn_lib.c
1 /* crypto/bn/bn_lib.c */
2 /* Copyright (C) 1995-1997 Eric Young (eay@cryptsoft.com)
3  * All rights reserved.
4  *
5  * This package is an SSL implementation written
6  * by Eric Young (eay@cryptsoft.com).
7  * The implementation was written so as to conform with Netscapes SSL.
8  * 
9  * This library is free for commercial and non-commercial use as long as
10  * the following conditions are aheared to.  The following conditions
11  * apply to all code found in this distribution, be it the RC4, RSA,
12  * lhash, DES, etc., code; not just the SSL code.  The SSL documentation
13  * included with this distribution is covered by the same copyright terms
14  * except that the holder is Tim Hudson (tjh@cryptsoft.com).
15  * 
16  * Copyright remains Eric Young's, and as such any Copyright notices in
17  * the code are not to be removed.
18  * If this package is used in a product, Eric Young should be given attribution
19  * as the author of the parts of the library used.
20  * This can be in the form of a textual message at program startup or
21  * in documentation (online or textual) provided with the package.
22  * 
23  * Redistribution and use in source and binary forms, with or without
24  * modification, are permitted provided that the following conditions
25  * are met:
26  * 1. Redistributions of source code must retain the copyright
27  *    notice, this list of conditions and the following disclaimer.
28  * 2. Redistributions in binary form must reproduce the above copyright
29  *    notice, this list of conditions and the following disclaimer in the
30  *    documentation and/or other materials provided with the distribution.
31  * 3. All advertising materials mentioning features or use of this software
32  *    must display the following acknowledgement:
33  *    "This product includes cryptographic software written by
34  *     Eric Young (eay@cryptsoft.com)"
35  *    The word 'cryptographic' can be left out if the rouines from the library
36  *    being used are not cryptographic related :-).
37  * 4. If you include any Windows specific code (or a derivative thereof) from 
38  *    the apps directory (application code) you must include an acknowledgement:
39  *    "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
40  * 
41  * THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
42  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
43  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
44  * ARE DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
45  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
46  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
47  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
48  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
49  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
50  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
51  * SUCH DAMAGE.
52  * 
53  * The licence and distribution terms for any publically available version or
54  * derivative of this code cannot be changed.  i.e. this code cannot simply be
55  * copied and put under another distribution licence
56  * [including the GNU Public Licence.]
57  */
58
59 #include <stdio.h>
60 #include "cryptlib.h"
61 #include "bn_lcl.h"
62
63 char *BN_version="Big Number part of SSLeay 0.8.1b 29-Jun-1998";
64
65 BIGNUM *BN_value_one()
66         {
67         static BN_ULONG data_one=1L;
68         static BIGNUM const_one={&data_one,1,1,0};
69
70         return(&const_one);
71         }
72
73 char *BN_options()
74         {
75         static int init=0;
76         static char data[16];
77
78         if (!init)
79                 {
80                 init++;
81 #ifdef BN_LLONG
82                 sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULLONG)*8,
83                         (int)sizeof(BN_ULONG)*8);
84 #else
85                 sprintf(data,"bn(%d,%d)",(int)sizeof(BN_ULONG)*8,
86                         (int)sizeof(BN_ULONG)*8);
87 #endif
88                 }
89         return(data);
90         }
91
92 int BN_num_bits_word(l)
93 BN_ULONG l;
94         {
95         static char bits[256]={
96                 0,1,2,2,3,3,3,3,4,4,4,4,4,4,4,4,
97                 5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,5,
98                 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
99                 6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,6,
100                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
101                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
102                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
103                 7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,7,
104                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
105                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
106                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
107                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
108                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
109                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
110                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
111                 8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,8,
112                 };
113
114 #ifdef SIXTY_FOUR_BIT_LONG
115         if (l & 0xffffffff00000000L)
116                 {
117                 if (l & 0xffff000000000000L)
118                         {
119                         if (l & 0xff00000000000000L)
120                                 {
121                                 return(bits[l>>56]+56);
122                                 }
123                         else    return(bits[l>>48]+48);
124                         }
125                 else
126                         {
127                         if (l & 0x0000ff0000000000L)
128                                 {
129                                 return(bits[l>>40]+40);
130                                 }
131                         else    return(bits[l>>32]+32);
132                         }
133                 }
134         else
135 #else
136 #ifdef SIXTY_FOUR_BIT
137         if (l & 0xffffffff00000000LL)
138                 {
139                 if (l & 0xffff000000000000LL)
140                         {
141                         if (l & 0xff00000000000000LL)
142                                 {
143                                 return(bits[l>>56]+56);
144                                 }
145                         else    return(bits[l>>48]+48);
146                         }
147                 else
148                         {
149                         if (l & 0x0000ff0000000000LL)
150                                 {
151                                 return(bits[l>>40]+40);
152                                 }
153                         else    return(bits[l>>32]+32);
154                         }
155                 }
156         else
157 #endif
158 #endif
159                 {
160 #if defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
161                 if (l & 0xffff0000L)
162                         {
163                         if (l & 0xff000000L)
164                                 return(bits[l>>24L]+24);
165                         else    return(bits[l>>16L]+16);
166                         }
167                 else
168 #endif
169                         {
170 #if defined(SIXTEEN_BIT) || defined(THIRTY_TWO_BIT) || defined(SIXTY_FOUR_BIT) || defined(SIXTY_FOUR_BIT_LONG)
171                         if (l & 0xff00L)
172                                 return(bits[l>>8]+8);
173                         else    
174 #endif
175                                 return(bits[l   ]  );
176                         }
177                 }
178         }
179
180 int BN_num_bits(a)
181 BIGNUM *a;
182         {
183         BN_ULONG l;
184         int i;
185
186         if (a->top == 0) return(0);
187         l=a->d[a->top-1];
188         i=(a->top-1)*BN_BITS2;
189         if (l == 0)
190                 {
191 #ifndef WIN16
192                 fprintf(stderr,"BAD TOP VALUE\n");
193 #endif
194                 abort();
195                 }
196         return(i+BN_num_bits_word(l));
197         }
198
199 void BN_clear_free(a)
200 BIGNUM *a;
201         {
202         if (a == NULL) return;
203         if (a->d != NULL)
204                 {
205                 memset(a->d,0,a->max*sizeof(a->d[0]));
206                 Free(a->d);
207                 }
208         memset(a,0,sizeof(BIGNUM));
209         Free(a);
210         }
211
212 void BN_free(a)
213 BIGNUM *a;
214         {
215         if (a == NULL) return;
216         if (a->d != NULL) Free(a->d);
217         Free(a);
218         }
219
220 BIGNUM *BN_new()
221         {
222         BIGNUM *ret;
223         BN_ULONG *p;
224
225         ret=(BIGNUM *)Malloc(sizeof(BIGNUM));
226         if (ret == NULL) goto err;
227         ret->top=0;
228         ret->neg=0;
229         ret->max=(BN_DEFAULT_BITS/BN_BITS2);
230         p=(BN_ULONG *)Malloc(sizeof(BN_ULONG)*(ret->max+1));
231         if (p == NULL) goto err;
232         ret->d=p;
233
234         memset(p,0,(ret->max+1)*sizeof(p[0]));
235         return(ret);
236 err:
237         BNerr(BN_F_BN_NEW,ERR_R_MALLOC_FAILURE);
238         return(NULL);
239         }
240
241 BN_CTX *BN_CTX_new()
242         {
243         BN_CTX *ret;
244         BIGNUM *n;
245         int i,j;
246
247         ret=(BN_CTX *)Malloc(sizeof(BN_CTX));
248         if (ret == NULL) goto err2;
249
250         for (i=0; i<BN_CTX_NUM; i++)
251                 {
252                 n=BN_new();
253                 if (n == NULL) goto err;
254                 ret->bn[i]=n;
255                 }
256
257         /* There is actually an extra one, this is for debugging my
258          * stuff */
259         ret->bn[BN_CTX_NUM]=NULL;
260
261         ret->tos=0;
262         return(ret);
263 err:
264         for (j=0; j<i; j++)
265                 BN_free(ret->bn[j]);
266         Free(ret);
267 err2:
268         BNerr(BN_F_BN_CTX_NEW,ERR_R_MALLOC_FAILURE);
269         return(NULL);
270         }
271
272 void BN_CTX_free(c)
273 BN_CTX *c;
274         {
275         int i;
276
277         for (i=0; i<BN_CTX_NUM; i++)
278                 BN_clear_free(c->bn[i]);
279         Free(c);
280         }
281
282 BIGNUM *bn_expand2(b, bits)
283 BIGNUM *b;
284 int bits;
285         {
286         BN_ULONG *p;
287         register int n;
288
289         while (bits > b->max*BN_BITS2)
290                 {
291                 n=((bits+BN_BITS2-1)/BN_BITS2)*2;
292                 p=b->d=(BN_ULONG *)Realloc(b->d,sizeof(BN_ULONG)*(n+1));
293                 if (p == NULL)
294                         {
295                         BNerr(BN_F_BN_EXPAND2,ERR_R_MALLOC_FAILURE);
296                         return(NULL);
297                         }
298                 memset(&(p[b->max]),0,((n+1)-b->max)*sizeof(BN_ULONG));
299                 b->max=n;
300                 }
301         return(b);
302         }
303
304 BIGNUM *BN_dup(a)
305 BIGNUM *a;
306         {
307         BIGNUM *r;
308
309         r=BN_new();
310         if (r == NULL) return(NULL);
311         return((BIGNUM *)BN_copy(r,a));
312         }
313
314 BIGNUM *BN_copy(a, b)
315 BIGNUM *a;
316 BIGNUM *b;
317         {
318         if (bn_expand(a,b->top*BN_BITS2) == NULL) return(NULL);
319         memcpy(a->d,b->d,sizeof(b->d[0])*b->top);
320 /*      memset(&(a->d[b->top]),0,sizeof(a->d[0])*(a->max-b->top));*/
321         a->top=b->top;
322         a->neg=b->neg;
323         return(a);
324         }
325
326 void BN_clear(a)
327 BIGNUM *a;
328         {
329         memset(a->d,0,a->max*sizeof(a->d[0]));
330         a->top=0;
331         a->neg=0;
332         }
333
334 unsigned long BN_get_word(a)
335 BIGNUM *a;
336         {
337         int i,n;
338         unsigned long ret=0;
339
340         n=BN_num_bytes(a);
341         if (n > sizeof(unsigned long))
342 #ifdef SIXTY_FOUR_BIT_LONG
343                 return(BN_MASK2);
344 #else
345                 return(0xFFFFFFFFL);
346 #endif
347         for (i=a->top-1; i>=0; i--)
348                 {
349 #ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
350                 ret<<=BN_BITS4; /* stops the compiler complaining */
351                 ret<<=BN_BITS4;
352 #endif
353                 ret|=a->d[i];
354                 }
355         return(ret);
356         }
357
358 int BN_set_word(a,w)
359 BIGNUM *a;
360 unsigned long w;
361         {
362         int i,n;
363         if (bn_expand(a,sizeof(unsigned long)*8) == NULL) return(0);
364
365         n=sizeof(unsigned long)/BN_BYTES;
366         a->neg=0;
367         a->top=0;
368         a->d[0]=(BN_ULONG)w&BN_MASK2;
369         if (a->d[0] != 0) a->top=1;
370         for (i=1; i<n; i++)
371                 {
372                 /* the following is done instead of
373                  * w>>=BN_BITS2 so compilers don't complain
374                  * on builds where sizeof(long) == BN_TYPES */
375 #ifndef SIXTY_FOUR_BIT /* the data item > unsigned long */
376                 w>>=BN_BITS4;
377                 w>>=BN_BITS4;
378 #endif
379                 a->d[i]=(BN_ULONG)w&BN_MASK2;
380                 if (a->d[i] != 0) a->top=i+1;
381                 }
382         return(1);
383         }
384
385 /* ignore negative */
386 BIGNUM *BN_bin2bn(s, len, ret)
387 unsigned char *s;
388 int len;
389 BIGNUM *ret;
390         {
391         unsigned int i,m;
392         unsigned int n;
393         BN_ULONG l;
394
395         if (ret == NULL) ret=BN_new();
396         if (ret == NULL) return(NULL);
397         l=0;
398         n=len;
399         if (n == 0)
400                 {
401                 ret->top=0;
402                 return(ret);
403                 }
404         if (bn_expand(ret,(int)(n+2)*8) == NULL)
405                 return(NULL);
406         i=((n-1)/BN_BYTES)+1;
407         m=((n-1)%(BN_BYTES));
408         ret->top=i;
409         while (n-- > 0)
410                 {
411                 l=(l<<8L)| *(s++);
412                 if (m-- == 0)
413                         {
414                         ret->d[--i]=l;
415                         l=0;
416                         m=BN_BYTES-1;
417                         }
418                 }
419         /* need to call this due to clear byte at top if avoiding
420          * having the top bit set (-ve number) */
421         bn_fix_top(ret);
422         return(ret);
423         }
424
425 /* ignore negative */
426 int BN_bn2bin(a, to)
427 BIGNUM *a;
428 unsigned char *to;
429         {
430         int n,i;
431         BN_ULONG l;
432
433         n=i=BN_num_bytes(a);
434         while (i-- > 0)
435                 {
436                 l=a->d[i/BN_BYTES];
437                 *(to++)=(unsigned char)(l>>(8*(i%BN_BYTES)))&0xff;
438                 }
439         return(n);
440         }
441
442 int BN_ucmp(a, b)
443 BIGNUM *a;
444 BIGNUM *b;
445         {
446         int i;
447         BN_ULONG t1,t2,*ap,*bp;
448
449         i=a->top-b->top;
450         if (i != 0) return(i);
451         ap=a->d;
452         bp=b->d;
453         for (i=a->top-1; i>=0; i--)
454                 {
455                 t1= ap[i];
456                 t2= bp[i];
457                 if (t1 != t2)
458                         return(t1 > t2?1:-1);
459                 }
460         return(0);
461         }
462
463 int BN_cmp(a, b)
464 BIGNUM *a;
465 BIGNUM *b;
466         {
467         int i;
468         int gt,lt;
469         BN_ULONG t1,t2;
470
471         if ((a == NULL) || (b == NULL))
472                 {
473                 if (a != NULL)
474                         return(-1);
475                 else if (b != NULL)
476                         return(1);
477                 else
478                         return(0);
479                 }
480         if (a->neg != b->neg)
481                 {
482                 if (a->neg)
483                         return(-1);
484                 else    return(1);
485                 }
486         if (a->neg == 0)
487                 { gt=1; lt= -1; }
488         else    { gt= -1; lt=1; }
489
490         if (a->top > b->top) return(gt);
491         if (a->top < b->top) return(lt);
492         for (i=a->top-1; i>=0; i--)
493                 {
494                 t1=a->d[i];
495                 t2=b->d[i];
496                 if (t1 > t2) return(gt);
497                 if (t1 < t2) return(lt);
498                 }
499         return(0);
500         }
501
502 int BN_set_bit(a, n)
503 BIGNUM *a;
504 int n;
505         {
506         int i,j;
507
508         i=n/BN_BITS2;
509         j=n%BN_BITS2;
510         if (a->top <= i) return(0);
511
512         a->d[i]|=(1L<<j);
513         return(1);
514         }
515
516 int BN_clear_bit(a, n)
517 BIGNUM *a;
518 int n;
519         {
520         int i,j;
521
522         i=n/BN_BITS2;
523         j=n%BN_BITS2;
524         if (a->top <= i) return(0);
525
526         a->d[i]&=(~(1L<<j));
527         return(1);
528         }
529
530 int BN_is_bit_set(a, n)
531 BIGNUM *a;
532 int n;
533         {
534         int i,j;
535
536         if (n < 0) return(0);
537         i=n/BN_BITS2;
538         j=n%BN_BITS2;
539         if (a->top <= i) return(0);
540         return((a->d[i]&(((BN_ULONG)1)<<j))?1:0);
541         }
542
543 int BN_mask_bits(a,n)
544 BIGNUM *a;
545 int n;
546         {
547         int b,w;
548
549         w=n/BN_BITS2;
550         b=n%BN_BITS2;
551         if (w >= a->top) return(0);
552         if (b == 0)
553                 a->top=w;
554         else
555                 {
556                 a->top=w+1;
557                 a->d[w]&= ~(BN_MASK2<<b);
558                 while ((w >= 0) && (a->d[w] == 0))
559                         {
560                         a->top--;
561                         w--;
562                         }
563                 }
564         return(1);
565         }