blob: b0a3b85add4d2b181b6ef2d13c0f70ede632d351 [file] [log] [blame]
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -05001/*
2 * bn32.c - the high-level bignum interface
3 *
4 * Like lbn32.c, this reserves the string "32" for textual replacement.
5 * The string must not appear anywhere unless it is intended to be replaced
6 * to generate other bignum interface functions.
7 *
8 * Copyright (c) 1995 Colin Plumb. All rights reserved.
9 * For licensing and other legal details, see the file legal.c.
10 */
11
12#ifndef HAVE_CONFIG_H
13#define HAVE_CONFIG_H 0
14#endif
15#if HAVE_CONFIG_H
Alexandre Lisionddd731e2014-01-31 11:50:08 -050016#include "bnconfig.h"
Alexandre Lision7fd5d3d2013-12-04 13:06:40 -050017#endif
18
19/*
20 * Some compilers complain about #if FOO if FOO isn't defined,
21 * so do the ANSI-mandated thing explicitly...
22 */
23#ifndef NO_ASSERT_H
24#define NO_ASSERT_H 0
25#endif
26#ifndef NO_STRING_H
27#define NO_STRING_H 0
28#endif
29#ifndef HAVE_STRINGS_H
30#define HAVE_STRINGS_H 0
31#endif
32#ifndef NEED_MEMORY_H
33#define NEED_MEMORY_H 0
34#endif
35
36#if !NO_ASSERT_H
37#include <assert.h>
38#else
39#define assert(x) (void)0
40#endif
41
42#if !NO_STRING_H
43#include <string.h> /* for memmove() in bnMakeOdd */
44#elif HAVE_STRINGS_H
45#include <strings.h>
46#endif
47#if NEED_MEMORY_H
48#include <memory.h>
49#endif
50
51/*
52 * This was useful during debugging, so it's left in here.
53 * You can ignore it. DBMALLOC is generally undefined.
54 */
55#ifndef DBMALLOC
56#define DBMALLOC 0
57#endif
58#if DBMALLOC
59#include "../dbmalloc/malloc.h"
60#define MALLOCDB malloc_chain_check(1)
61#else
62#define MALLOCDB (void)0
63#endif
64
65#include "lbn.h"
66#include "lbn32.h"
67#include "lbnmem.h"
68#include "bn32.h"
69#include "bn.h"
70
71/* Work-arounds for some particularly broken systems */
72#include "kludge.h" /* For memmove() */
73
74/* Functions */
75void
76bnInit_32(void)
77{
78 bnEnd = bnEnd_32;
79 bnPrealloc = bnPrealloc_32;
80 bnCopy = bnCopy_32;
81 bnNorm = bnNorm_32;
82 bnExtractBigBytes = bnExtractBigBytes_32;
83 bnInsertBigBytes = bnInsertBigBytes_32;
84 bnExtractLittleBytes = bnExtractLittleBytes_32;
85 bnInsertLittleBytes = bnInsertLittleBytes_32;
86 bnLSWord = bnLSWord_32;
87 bnReadBit = bnReadBit_32;
88 bnBits = bnBits_32;
89 bnAdd = bnAdd_32;
90 bnSub = bnSub_32;
91 bnCmpQ = bnCmpQ_32;
92 bnSetQ = bnSetQ_32;
93 bnAddQ = bnAddQ_32;
94 bnSubQ = bnSubQ_32;
95 bnCmp = bnCmp_32;
96 bnSquare = bnSquare_32;
97 bnMul = bnMul_32;
98 bnMulQ = bnMulQ_32;
99 bnDivMod = bnDivMod_32;
100 bnMod = bnMod_32;
101 bnModQ = bnModQ_32;
102 bnExpMod = bnExpMod_32;
103 bnDoubleExpMod = bnDoubleExpMod_32;
104 bnTwoExpMod = bnTwoExpMod_32;
105 bnGcd = bnGcd_32;
106 bnInv = bnInv_32;
107 bnLShift = bnLShift_32;
108 bnRShift = bnRShift_32;
109 bnMakeOdd = bnMakeOdd_32;
110 bnBasePrecompBegin = bnBasePrecompBegin_32;
111 bnBasePrecompEnd = bnBasePrecompEnd_32;
112 bnBasePrecompExpMod = bnBasePrecompExpMod_32;
113 bnDoubleBasePrecompExpMod = bnDoubleBasePrecompExpMod_32;
114}
115
116void
117bnEnd_32(struct BigNum *bn)
118{
119 if (bn->ptr) {
120 LBNFREE((BNWORD32 *)bn->ptr, bn->allocated);
121 bn->ptr = 0;
122 }
123 bn->size = 0;
124 bn->allocated = 0;
125
126 MALLOCDB;
127}
128
129/* Internal function. It operates in words. */
130static int
131bnResize_32(struct BigNum *bn, unsigned len)
132{
133 void *p;
134
135 /* Round size up: most mallocs impose 8-byte granularity anyway */
136 len = (len + (8/sizeof(BNWORD32) - 1)) & ~(8/sizeof(BNWORD32) - 1);
137 p = LBNREALLOC((BNWORD32 *)bn->ptr, bn->allocated, len);
138 if (!p)
139 return -1;
140 bn->ptr = p;
141 bn->allocated = len;
142
143 MALLOCDB;
144
145 return 0;
146}
147
148#define bnSizeCheck(bn, size) \
149 if (bn->allocated < size && bnResize_32(bn, size) < 0) \
150 return -1
151
152/* Preallocate enough space in bn to hold "bits" bits. */
153int
154bnPrealloc_32(struct BigNum *bn, unsigned bits)
155{
156 bits = (bits + 32-1)/32;
157 bnSizeCheck(bn, bits);
158 MALLOCDB;
159 return 0;
160}
161
162int
163bnCopy_32(struct BigNum *dest, struct BigNum const *src)
164{
165 bnSizeCheck(dest, src->size);
166 dest->size = src->size;
167 lbnCopy_32((BNWORD32 *)dest->ptr, (BNWORD32 *)src->ptr, src->size);
168 MALLOCDB;
169 return 0;
170}
171
172/* Is this ever needed? Normalize the bn by deleting high-order 0 words */
173void
174bnNorm_32(struct BigNum *bn)
175{
176 bn->size = lbnNorm_32((BNWORD32 *)bn->ptr, bn->size);
177}
178
179/*
180 * Convert a bignum to big-endian bytes. Returns, in big-endian form, a
181 * substring of the bignum starting from lsbyte and "len" bytes long.
182 * Unused high-order (leading) bytes are filled with 0.
183 */
184void
185bnExtractBigBytes_32(struct BigNum const *bn, unsigned char *dest,
186 unsigned lsbyte, unsigned len)
187{
188 unsigned s = bn->size * (32 / 8);
189
190 /* Fill unused leading bytes with 0 */
191 while (s < lsbyte + len) {
192 *dest++ = 0;
193 len--;
194 }
195
196 if (len)
197 lbnExtractBigBytes_32((BNWORD32 *)bn->ptr, dest, lsbyte, len);
198 MALLOCDB;
199}
200
201/* The inverse of the above. */
202int
203bnInsertBigBytes_32(struct BigNum *bn, unsigned char const *src,
204 unsigned lsbyte, unsigned len)
205{
206 unsigned s = bn->size;
207 unsigned words = (len+lsbyte+sizeof(BNWORD32)-1) / sizeof(BNWORD32);
208
209 /* Pad with zeros as required */
210 bnSizeCheck(bn, words);
211
212 if (s < words) {
213 lbnZero_32((BNWORD32 *)bn->ptr BIGLITTLE(-s,+s), words-s);
214 s = words;
215 }
216
217 lbnInsertBigBytes_32((BNWORD32 *)bn->ptr, src, lsbyte, len);
218
219 bn->size = lbnNorm_32((BNWORD32 *)bn->ptr, s);
220
221 MALLOCDB;
222 return 0;
223}
224
225
226/*
227 * Convert a bignum to little-endian bytes. Returns, in little-endian form, a
228 * substring of the bignum starting from lsbyte and "len" bytes long.
229 * Unused high-order (trailing) bytes are filled with 0.
230 */
231void
232bnExtractLittleBytes_32(struct BigNum const *bn, unsigned char *dest,
233 unsigned lsbyte, unsigned len)
234{
235 unsigned s = bn->size * (32 / 8);
236
237 /* Fill unused leading bytes with 0 */
238 while (s < lsbyte + len)
239 dest[--len] = 0;
240
241 if (len)
242 lbnExtractLittleBytes_32((BNWORD32 *)bn->ptr, dest,
243 lsbyte, len);
244 MALLOCDB;
245}
246
247/* The inverse of the above */
248int
249bnInsertLittleBytes_32(struct BigNum *bn, unsigned char const *src,
250 unsigned lsbyte, unsigned len)
251{
252 unsigned s = bn->size;
253 unsigned words = (len+lsbyte+sizeof(BNWORD32)-1) / sizeof(BNWORD32);
254
255 /* Pad with zeros as required */
256 bnSizeCheck(bn, words);
257
258 if (s < words) {
259 lbnZero_32((BNWORD32 *)bn->ptr BIGLITTLE(-s,+s), words-s);
260 s = words;
261 }
262
263 lbnInsertLittleBytes_32((BNWORD32 *)bn->ptr, src, lsbyte, len);
264
265 bn->size = lbnNorm_32((BNWORD32 *)bn->ptr, s);
266
267 MALLOCDB;
268 return 0;
269}
270
271/* Return the least-significant word of the input. */
272unsigned
273bnLSWord_32(struct BigNum const *bn)
274{
275 return bn->size ? (unsigned)((BNWORD32 *)bn->ptr)[BIGLITTLE(-1,0)]: 0;
276}
277
278/* Return a selected bit of the data */
279int
280bnReadBit_32(struct BigNum const *bn, unsigned bit)
281{
282 BNWORD32 word;
283 if (bit/32 >= bn->size)
284 return 0;
285 word = ((BNWORD32 *)bn->ptr)[BIGLITTLE(-1-bit/32,bit/32)];
286 return (int)(word >> (bit % 32) & 1);
287}
288
289/* Count the number of significant bits. */
290unsigned
291bnBits_32(struct BigNum const *bn)
292{
293 return lbnBits_32((BNWORD32 *)bn->ptr, bn->size);
294}
295
296/* dest += src */
297int
298bnAdd_32(struct BigNum *dest, struct BigNum const *src)
299{
300 unsigned s = src->size, d = dest->size;
301 BNWORD32 t;
302
303 if (!s)
304 return 0;
305
306 bnSizeCheck(dest, s);
307
308 if (d < s) {
309 lbnZero_32((BNWORD32 *)dest->ptr BIGLITTLE(-d,+d), s-d);
310 dest->size = d = s;
311 MALLOCDB;
312 }
313 t = lbnAddN_32((BNWORD32 *)dest->ptr, (BNWORD32 *)src->ptr, s);
314 MALLOCDB;
315 if (t) {
316 if (d > s) {
317 t = lbnAdd1_32((BNWORD32 *)dest->ptr BIGLITTLE(-s,+s),
318 d-s, t);
319 MALLOCDB;
320 }
321 if (t) {
322 bnSizeCheck(dest, d+1);
323 ((BNWORD32 *)dest->ptr)[BIGLITTLE(-1-d,d)] = t;
324 dest->size = d+1;
325 }
326 }
327 return 0;
328}
329
330/*
331 * dest -= src.
332 * If dest goes negative, this produces the absolute value of
333 * the difference (the negative of the true value) and returns 1.
334 * Otherwise, it returls 0.
335 */
336int
337bnSub_32(struct BigNum *dest, struct BigNum const *src)
338{
339 unsigned s = src->size, d = dest->size;
340 BNWORD32 t;
341
342 if (d < s && d < (s = lbnNorm_32((BNWORD32 *)src->ptr, s))) {
343 bnSizeCheck(dest, s);
344 lbnZero_32((BNWORD32 *)dest->ptr BIGLITTLE(-d,+d), s-d);
345 dest->size = d = s;
346 MALLOCDB;
347 }
348 if (!s)
349 return 0;
350 t = lbnSubN_32((BNWORD32 *)dest->ptr, (BNWORD32 *)src->ptr, s);
351 MALLOCDB;
352 if (t) {
353 if (d > s) {
354 t = lbnSub1_32((BNWORD32 *)dest->ptr BIGLITTLE(-s,+s),
355 d-s, t);
356 MALLOCDB;
357 }
358 if (t) {
359 lbnNeg_32((BNWORD32 *)dest->ptr, d);
360 dest->size = lbnNorm_32((BNWORD32 *)dest->ptr,
361 dest->size);
362 MALLOCDB;
363 return 1;
364 }
365 }
366 dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, dest->size);
367 return 0;
368}
369
370/*
371 * Compare the BigNum to the given value, which must be < 65536.
372 * Returns -1. 0 or 1 if a<b, a == b or a>b.
373 * a <=> b --> bnCmpQ(a,b) <=> 0
374 */
375int
376bnCmpQ_32(struct BigNum const *a, unsigned b)
377{
378 unsigned t;
379 BNWORD32 v;
380
381 t = lbnNorm_32((BNWORD32 *)a->ptr, a->size);
382 /* If a is more than one word long or zero, it's easy... */
383 if (t != 1)
384 return (t > 1) ? 1 : (b ? -1 : 0);
385 v = (unsigned)((BNWORD32 *)a->ptr)[BIGLITTLE(-1,0)];
386 return (v > b) ? 1 : ((v < b) ? -1 : 0);
387}
388
389/* Set dest to a small value */
390int
391bnSetQ_32(struct BigNum *dest, unsigned src)
392{
393 if (src) {
394 bnSizeCheck(dest, 1);
395
396 ((BNWORD32 *)dest->ptr)[BIGLITTLE(-1,0)] = (BNWORD32)src;
397 dest->size = 1;
398 } else {
399 dest->size = 0;
400 }
401 return 0;
402}
403
404/* dest += src */
405int
406bnAddQ_32(struct BigNum *dest, unsigned src)
407{
408 BNWORD32 t;
409
410 if (!dest->size)
411 return bnSetQ(dest, src);
412
413 t = lbnAdd1_32((BNWORD32 *)dest->ptr, dest->size, (BNWORD32)src);
414 MALLOCDB;
415 if (t) {
416 src = dest->size;
417 bnSizeCheck(dest, src+1);
418 ((BNWORD32 *)dest->ptr)[BIGLITTLE(-1-src,src)] = t;
419 dest->size = src+1;
420 }
421 return 0;
422}
423
424/*
425 * Return value as for bnSub: 1 if subtract underflowed, in which
426 * case the return is the negative of the computed value.
427 */
428int
429bnSubQ_32(struct BigNum *dest, unsigned src)
430{
431 BNWORD32 t;
432
433 if (!dest->size)
434 return bnSetQ(dest, src) < 0 ? -1 : (src != 0);
435
436 t = lbnSub1_32((BNWORD32 *)dest->ptr, dest->size, src);
437 MALLOCDB;
438 if (t) {
439 /* Underflow. <= 1 word, so do it simply. */
440 lbnNeg_32((BNWORD32 *)dest->ptr, 1);
441 dest->size = 1;
442 return 1;
443 }
444/* Try to normalize? Needing this is going to be pretty damn rare. */
445/* dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, dest->size); */
446 return 0;
447}
448
449/*
450 * Compare two BigNums. Returns -1. 0 or 1 if a<b, a == b or a>b.
451 * a <=> b --> bnCmp(a,b) <=> 0
452 */
453int
454bnCmp_32(struct BigNum const *a, struct BigNum const *b)
455{
456 unsigned s, t;
457
458 s = lbnNorm_32((BNWORD32 *)a->ptr, a->size);
459 t = lbnNorm_32((BNWORD32 *)b->ptr, b->size);
460
461 if (s != t)
462 return s > t ? 1 : -1;
463 return lbnCmp_32((BNWORD32 *)a->ptr, (BNWORD32 *)b->ptr, s);
464}
465
466/* dest = src*src. This is more efficient than bnMul. */
467int
468bnSquare_32(struct BigNum *dest, struct BigNum const *src)
469{
470 unsigned s;
471 BNWORD32 *srcbuf;
472
473 s = lbnNorm_32((BNWORD32 *)src->ptr, src->size);
474 if (!s) {
475 dest->size = 0;
476 return 0;
477 }
478 bnSizeCheck(dest, 2*s);
479
480 if (src == dest) {
481 LBNALLOC(srcbuf, BNWORD32, s);
482 if (!srcbuf)
483 return -1;
484 lbnCopy_32(srcbuf, (BNWORD32 *)src->ptr, s);
485 lbnSquare_32((BNWORD32 *)dest->ptr, (BNWORD32 *)srcbuf, s);
486 LBNFREE(srcbuf, s);
487 } else {
488 lbnSquare_32((BNWORD32 *)dest->ptr, (BNWORD32 *)src->ptr, s);
489 }
490
491 dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, 2*s);
492 MALLOCDB;
493 return 0;
494}
495
496/* dest = a * b. Any overlap between operands is allowed. */
497int
498bnMul_32(struct BigNum *dest, struct BigNum const *a, struct BigNum const *b)
499{
500 unsigned s, t;
501 BNWORD32 *srcbuf;
502
503 s = lbnNorm_32((BNWORD32 *)a->ptr, a->size);
504 t = lbnNorm_32((BNWORD32 *)b->ptr, b->size);
505
506 if (!s || !t) {
507 dest->size = 0;
508 return 0;
509 }
510
511 if (a == b)
512 return bnSquare_32(dest, a);
513
514 bnSizeCheck(dest, s+t);
515
516 if (dest == a) {
517 LBNALLOC(srcbuf, BNWORD32, s);
518 if (!srcbuf)
519 return -1;
520 lbnCopy_32(srcbuf, (BNWORD32 *)a->ptr, s);
521 lbnMul_32((BNWORD32 *)dest->ptr, srcbuf, s,
522 (BNWORD32 *)b->ptr, t);
523 LBNFREE(srcbuf, s);
524 } else if (dest == b) {
525 LBNALLOC(srcbuf, BNWORD32, t);
526 if (!srcbuf)
527 return -1;
528 lbnCopy_32(srcbuf, (BNWORD32 *)b->ptr, t);
529 lbnMul_32((BNWORD32 *)dest->ptr, (BNWORD32 *)a->ptr, s,
530 srcbuf, t);
531 LBNFREE(srcbuf, t);
532 } else {
533 lbnMul_32((BNWORD32 *)dest->ptr, (BNWORD32 *)a->ptr, s,
534 (BNWORD32 *)b->ptr, t);
535 }
536 dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, s+t);
537 MALLOCDB;
538 return 0;
539}
540
541/* dest = a * b */
542int
543bnMulQ_32(struct BigNum *dest, struct BigNum const *a, unsigned b)
544{
545 unsigned s;
546
547 s = lbnNorm_32((BNWORD32 *)a->ptr, a->size);
548 if (!s || !b) {
549 dest->size = 0;
550 return 0;
551 }
552 if (b == 1)
553 return bnCopy_32(dest, a);
554 bnSizeCheck(dest, s+1);
555 lbnMulN1_32((BNWORD32 *)dest->ptr, (BNWORD32 *)a->ptr, s, b);
556 dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, s+1);
557 MALLOCDB;
558 return 0;
559}
560
561/* q = n/d, r = n % d */
562int
563bnDivMod_32(struct BigNum *q, struct BigNum *r, struct BigNum const *n,
564 struct BigNum const *d)
565{
566 unsigned dsize, nsize;
567 BNWORD32 qhigh;
568
569 dsize = lbnNorm_32((BNWORD32 *)d->ptr, d->size);
570 nsize = lbnNorm_32((BNWORD32 *)n->ptr, n->size);
571
572 if (nsize < dsize) {
573 q->size = 0; /* No quotient */
574 r->size = nsize;
575 return 0; /* Success */
576 }
577
578 bnSizeCheck(q, nsize-dsize);
579
580 if (r != n) { /* You are allowed to reduce in place */
581 bnSizeCheck(r, nsize);
582 lbnCopy_32((BNWORD32 *)r->ptr, (BNWORD32 *)n->ptr, nsize);
583 }
584
585 qhigh = lbnDiv_32((BNWORD32 *)q->ptr, (BNWORD32 *)r->ptr, nsize,
586 (BNWORD32 *)d->ptr, dsize);
587 nsize -= dsize;
588 if (qhigh) {
589 bnSizeCheck(q, nsize+1);
590 *((BNWORD32 *)q->ptr BIGLITTLE(-nsize-1,+nsize)) = qhigh;
591 q->size = nsize+1;
592 } else {
593 q->size = lbnNorm_32((BNWORD32 *)q->ptr, nsize);
594 }
595 r->size = lbnNorm_32((BNWORD32 *)r->ptr, dsize);
596 MALLOCDB;
597 return 0;
598}
599
600/* det = src % d */
601int
602bnMod_32(struct BigNum *dest, struct BigNum const *src, struct BigNum const *d)
603{
604 unsigned dsize, nsize;
605
606 nsize = lbnNorm_32((BNWORD32 *)src->ptr, src->size);
607 dsize = lbnNorm_32((BNWORD32 *)d->ptr, d->size);
608
609
610 if (dest != src) {
611 bnSizeCheck(dest, nsize);
612 lbnCopy_32((BNWORD32 *)dest->ptr, (BNWORD32 *)src->ptr, nsize);
613 }
614
615 if (nsize < dsize) {
616 dest->size = nsize; /* No quotient */
617 return 0;
618 }
619
620 (void)lbnDiv_32((BNWORD32 *)dest->ptr BIGLITTLE(-dsize,+dsize),
621 (BNWORD32 *)dest->ptr, nsize,
622 (BNWORD32 *)d->ptr, dsize);
623 dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, dsize);
624 MALLOCDB;
625 return 0;
626}
627
628/* return src % d. */
629unsigned
630bnModQ_32(struct BigNum const *src, unsigned d)
631{
632 unsigned s;
633
634 s = lbnNorm_32((BNWORD32 *)src->ptr, src->size);
635 if (!s)
636 return 0;
637
638 if (d & (d-1)) /* Not a power of 2 */
639 d = lbnModQ_32((BNWORD32 *)src->ptr, s, d);
640 else
641 d = (unsigned)((BNWORD32 *)src->ptr)[BIGLITTLE(-1,0)] & (d-1);
642 return d;
643}
644
645/* dest = n^exp (mod mod) */
646int
647bnExpMod_32(struct BigNum *dest, struct BigNum const *n,
648 struct BigNum const *exp, struct BigNum const *mod)
649{
650 unsigned nsize, esize, msize;
651
652 nsize = lbnNorm_32((BNWORD32 *)n->ptr, n->size);
653 esize = lbnNorm_32((BNWORD32 *)exp->ptr, exp->size);
654 msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
655
656 if (!msize || (((BNWORD32 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
657 return -1; /* Illegal modulus! */
658
659 bnSizeCheck(dest, msize);
660
661 /* Special-case base of 2 */
662 if (nsize == 1 && ((BNWORD32 *)n->ptr)[BIGLITTLE(-1,0)] == 2) {
663 if (lbnTwoExpMod_32((BNWORD32 *)dest->ptr,
664 (BNWORD32 *)exp->ptr, esize,
665 (BNWORD32 *)mod->ptr, msize) < 0)
666 return -1;
667 } else {
668 if (lbnExpMod_32((BNWORD32 *)dest->ptr,
669 (BNWORD32 *)n->ptr, nsize,
670 (BNWORD32 *)exp->ptr, esize,
671 (BNWORD32 *)mod->ptr, msize) < 0)
672 return -1;
673 }
674
675 dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, msize);
676 MALLOCDB;
677 return 0;
678}
679
680/*
681 * dest = n1^e1 * n2^e2 (mod mod). This is more efficient than two
682 * separate modular exponentiations, and in fact asymptotically approaches
683 * the cost of one.
684 */
685int
686bnDoubleExpMod_32(struct BigNum *dest,
687 struct BigNum const *n1, struct BigNum const *e1,
688 struct BigNum const *n2, struct BigNum const *e2,
689 struct BigNum const *mod)
690{
691 unsigned n1size, e1size, n2size, e2size, msize;
692
693 n1size = lbnNorm_32((BNWORD32 *)n1->ptr, n1->size);
694 e1size = lbnNorm_32((BNWORD32 *)e1->ptr, e1->size);
695 n2size = lbnNorm_32((BNWORD32 *)n2->ptr, n2->size);
696 e2size = lbnNorm_32((BNWORD32 *)e2->ptr, e2->size);
697 msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
698
699 if (!msize || (((BNWORD32 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
700 return -1; /* Illegal modulus! */
701
702 bnSizeCheck(dest, msize);
703
704 if (lbnDoubleExpMod_32((BNWORD32 *)dest->ptr,
705 (BNWORD32 *)n1->ptr, n1size, (BNWORD32 *)e1->ptr, e1size,
706 (BNWORD32 *)n2->ptr, n2size, (BNWORD32 *)e2->ptr, e2size,
707 (BNWORD32 *)mod->ptr, msize) < 0)
708 return -1;
709
710 dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, msize);
711 MALLOCDB;
712 return 0;
713}
714
715/* n = 2^exp (mod mod) */
716int
717bnTwoExpMod_32(struct BigNum *n, struct BigNum const *exp,
718 struct BigNum const *mod)
719{
720 unsigned esize, msize;
721
722 esize = lbnNorm_32((BNWORD32 *)exp->ptr, exp->size);
723 msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
724
725 if (!msize || (((BNWORD32 *)mod->ptr)[BIGLITTLE(-1,0)] & 1) == 0)
726 return -1; /* Illegal modulus! */
727
728 bnSizeCheck(n, msize);
729
730 if (lbnTwoExpMod_32((BNWORD32 *)n->ptr, (BNWORD32 *)exp->ptr, esize,
731 (BNWORD32 *)mod->ptr, msize) < 0)
732 return -1;
733
734 n->size = lbnNorm_32((BNWORD32 *)n->ptr, msize);
735 MALLOCDB;
736 return 0;
737}
738
739/* dest = gcd(a, b) */
740int
741bnGcd_32(struct BigNum *dest, struct BigNum const *a, struct BigNum const *b)
742{
743 BNWORD32 *tmp;
744 unsigned asize, bsize;
745 int i;
746
747 /* Kind of silly, but we might as well permit it... */
748 if (a == b)
749 return dest == a ? 0 : bnCopy(dest, a);
750
751 /* Ensure a is not the same as "dest" */
752 if (a == dest) {
753 a = b;
754 b = dest;
755 }
756
757 asize = lbnNorm_32((BNWORD32 *)a->ptr, a->size);
758 bsize = lbnNorm_32((BNWORD32 *)b->ptr, b->size);
759
760 bnSizeCheck(dest, bsize+1);
761
762 /* Copy a to tmp */
763 LBNALLOC(tmp, BNWORD32, asize+1);
764 if (!tmp)
765 return -1;
766 lbnCopy_32(tmp, (BNWORD32 *)a->ptr, asize);
767
768 /* Copy b to dest, if necessary */
769 if (dest != b)
770 lbnCopy_32((BNWORD32 *)dest->ptr,
771 (BNWORD32 *)b->ptr, bsize);
772 if (bsize > asize || (bsize == asize &&
773 lbnCmp_32((BNWORD32 *)b->ptr, (BNWORD32 *)a->ptr, asize) > 0))
774 {
775 i = lbnGcd_32((BNWORD32 *)dest->ptr, bsize, tmp, asize,
776 &dest->size);
777 if (i > 0) /* Result in tmp, not dest */
778 lbnCopy_32((BNWORD32 *)dest->ptr, tmp, dest->size);
779 } else {
780 i = lbnGcd_32(tmp, asize, (BNWORD32 *)dest->ptr, bsize,
781 &dest->size);
782 if (i == 0) /* Result in tmp, not dest */
783 lbnCopy_32((BNWORD32 *)dest->ptr, tmp, dest->size);
784 }
785 LBNFREE(tmp, asize+1);
786 MALLOCDB;
787 return (i < 0) ? i : 0;
788}
789
790/*
791 * dest = 1/src (mod mod). Returns >0 if gcd(src, mod) != 1 (in which case
792 * the inverse does not exist).
793 */
794int
795bnInv_32(struct BigNum *dest, struct BigNum const *src,
796 struct BigNum const *mod)
797{
798 unsigned s, m;
799 int i;
800
801 s = lbnNorm_32((BNWORD32 *)src->ptr, src->size);
802 m = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
803
804 /* lbnInv_32 requires that the input be less than the modulus */
805 if (m < s ||
806 (m==s && lbnCmp_32((BNWORD32 *)src->ptr, (BNWORD32 *)mod->ptr, s)))
807 {
808 bnSizeCheck(dest, s + (m==s));
809 if (dest != src)
810 lbnCopy_32((BNWORD32 *)dest->ptr,
811 (BNWORD32 *)src->ptr, s);
812 /* Pre-reduce modulo the modulus */
813 (void)lbnDiv_32((BNWORD32 *)dest->ptr BIGLITTLE(-m,+m),
814 (BNWORD32 *)dest->ptr, s,
815 (BNWORD32 *)mod->ptr, m);
816 s = lbnNorm_32((BNWORD32 *)dest->ptr, m);
817 MALLOCDB;
818 } else {
819 bnSizeCheck(dest, m+1);
820 if (dest != src)
821 lbnCopy_32((BNWORD32 *)dest->ptr,
822 (BNWORD32 *)src->ptr, s);
823 }
824
825 i = lbnInv_32((BNWORD32 *)dest->ptr, s, (BNWORD32 *)mod->ptr, m);
826 if (i == 0)
827 dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, m);
828
829 MALLOCDB;
830 return i;
831}
832
833/*
834 * Shift a bignum left the appropriate number of bits,
835 * multiplying by 2^amt.
836 */
837int
838bnLShift_32(struct BigNum *dest, unsigned amt)
839{
840 unsigned s = dest->size;
841 BNWORD32 carry;
842
843 if (amt % 32) {
844 carry = lbnLshift_32((BNWORD32 *)dest->ptr, s, amt % 32);
845 if (carry) {
846 s++;
847 bnSizeCheck(dest, s);
848 ((BNWORD32 *)dest->ptr)[BIGLITTLE(-s,s-1)] = carry;
849 }
850 }
851
852 amt /= 32;
853 if (amt) {
854 bnSizeCheck(dest, s+amt);
855 memmove((BNWORD32 *)dest->ptr BIGLITTLE(-s-amt, +amt),
856 (BNWORD32 *)dest->ptr BIG(-s),
857 s * sizeof(BNWORD32));
858 lbnZero_32((BNWORD32 *)dest->ptr, amt);
859 s += amt;
860 }
861 dest->size = s;
862 MALLOCDB;
863 return 0;
864}
865
866/*
867 * Shift a bignum right the appropriate number of bits,
868 * dividing by 2^amt.
869 */
870void
871bnRShift_32(struct BigNum *dest, unsigned amt)
872{
873 unsigned s = dest->size;
874
875 if (amt >= 32) {
876 memmove(
877 (BNWORD32 *)dest->ptr BIG(-s+amt/32),
878 (BNWORD32 *)dest->ptr BIGLITTLE(-s, +amt/32),
879 (s-amt/32) * sizeof(BNWORD32));
880 s -= amt/32;
881 amt %= 32;
882 }
883
884 if (amt)
885 (void)lbnRshift_32((BNWORD32 *)dest->ptr, s, amt);
886
887 dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, s);
888 MALLOCDB;
889}
890
891/*
892 * Shift a bignum right until it is odd, and return the number of
893 * bits shifted. n = d * 2^s. Replaces n with d and returns s.
894 * Returns 0 when given 0. (Another valid answer is infinity.)
895 */
896unsigned
897bnMakeOdd_32(struct BigNum *n)
898{
899 unsigned size;
900 unsigned s; /* shift amount */
901 BNWORD32 *p;
902 BNWORD32 t;
903
904 p = (BNWORD32 *)n->ptr;
905 size = lbnNorm_32(p, n->size);
906 if (!size)
907 return 0;
908
909 t = BIGLITTLE(p[-1],p[0]);
910 s = 0;
911
912 /* See how many words we have to shift */
913 if (!t) {
914 /* Shift by words */
915 do {
916 s++;
917 BIGLITTLE(--p,p++);
918 } while ((t = BIGLITTLE(p[-1],p[0])) == 0);
919 size -= s;
920 s *= 32;
921 memmove((BNWORD32 *)n->ptr BIG(-size), p BIG(-size),
922 size * sizeof(BNWORD32));
923 p = (BNWORD32 *)n->ptr;
924 MALLOCDB;
925 }
926
927 assert(t);
928
929 if (!(t & 1)) {
930 /* Now count the bits */
931 do {
932 t >>= 1;
933 s++;
934 } while ((t & 1) == 0);
935
936 /* Shift the bits */
937 lbnRshift_32(p, size, s & (32-1));
938 /* Renormalize */
939 if (BIGLITTLE(*(p-size),*(p+(size-1))) == 0)
940 --size;
941 }
942 n->size = size;
943
944 MALLOCDB;
945 return s;
946}
947
948/*
949 * Do base- and modulus-dependent precomputation for rapid computation of
950 * base^exp (mod mod) with various exponents.
951 *
952 * See lbn32.c for the details on how the algorithm works. Basically,
953 * it involves precomputing a table of powers of base, base^(order^k),
954 * for a suitable range 0 <= k < n detemined by the maximum exponent size
955 * desired. To do eht exponentiation, the exponent is expressed in base
956 * "order" (sorry for the confusing terminology) and the precomputed powers
957 * are combined.
958 *
959 * This implementation allows only power-of-2 values for "order". Using
960 * other numbers can be more efficient, but it's more work and for the
961 * popular exponent size of 320 bits, an order of 8 is optimal, so it
962 * hasn't seemed worth it to implement.
963 *
964 * Here's a table of the optimal power-of-2 order for various exponent
965 * sizes and the associated (average) cost for an exponentiation.
966 * Note that *higher* orders are more memory-efficient; the number
967 * of precomputed values required is ceil(ebits/order). (Ignore the
968 * underscores in the middle of numbers; they're harmless.)
969 *
970 * At 2 bits, order 2 uses 0.000000 multiplies
971 * At 4 bits, order 2 uses 1.000000 multiplies
972 * At 8 bits, order 2 uses 3.000000 multiplies
973 * At 1_6 bits, order 2 uses 7.000000 multiplies
974 * At 3_2 bits, order 2 uses 15.000000 multiplies
975 * At 34 bits, 15.750000 (order 4) < 1_6.000000 (order 2)
976 * At 6_4 bits, order 4 uses 27.000000 multiplies
977 * At 99 bits, 39.875000 (order 8) < 40.250000 (order 4)
978 * At 128 bits, order 8 uses 48.500000 multiplies
979 * At 256 bits, order 8 uses 85.875000 multiplies
980 * At 280 bits, 92.625000 (order 1_6) < 92.875000 (order 8)
981 * At 512 bits, order 1_6 uses 147.000000 multiplies
982 * At 785 bits, 211.093750 (order 3_2) < 211.250000 (order 1_6)
983 * At 1024 bits, order 3_2 uses 257.562500 multiplies
984 * At 2048 bits, order 3_2 uses 456.093750 multiplies
985 * At 2148 bits, 475.406250 (order 6_4) < 475.468750 (order 3_2)
986 * At 4096 bits, order 6_4 uses 795.281250 multiplies
987 * At 5726 bits, 1062.609375 (order 128) < 1062.843750 (order 6_4)
988 * At 8192 bits, order 128 uses 1412.609375 multiplies
989 * At 14848 bits, 2355.750000 (order 256) < 2355.929688 (order 128)
990 * At 37593 bits, 5187.841797 (order 512) < 5188.144531 (order 256)
991 */
992int
993bnBasePrecompBegin_32(struct BnBasePrecomp *pre, struct BigNum const *base,
994 struct BigNum const *mod, unsigned maxebits)
995{
996 int i;
997 BNWORD32 **array; /* Array of precomputed powers of base */
998 unsigned n; /* Number of entries in array (needed) */
999 unsigned m; /* Number of entries in array (non-NULL) */
1000 unsigned arraysize; /* Number of entries in array (allocated) */
1001 unsigned bits; /* log2(order) */
1002 unsigned msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
1003 static unsigned const bnBasePrecompThreshTable[] = {
1004 33, 98, 279, 784, 2147, 5725, 14847, 37592, (unsigned)-1
1005 };
1006
1007 /* Clear pre in case of failure */
1008 pre->array = 0;
1009 pre->msize = 0;
1010 pre->bits = 0;
1011 pre->maxebits = 0;
1012 pre->arraysize = 0;
1013 pre->entries = 0;
1014
1015 /* Find the correct bit-window size */
1016 bits = 0;
1017 do
1018 bits++;
1019 while (maxebits > bnBasePrecompThreshTable[bits]);
1020
1021 /* Now the number of precomputed values we need */
1022 n = (maxebits+bits-1)/bits;
1023 assert(n*bits >= maxebits);
1024
1025 arraysize = n+1; /* Add one trailing NULL for safety */
1026 array = lbnMemAlloc(arraysize * sizeof(*array));
1027 if (!array)
1028 return -1; /* Out of memory */
1029
1030 /* Now allocate the entries (precomputed powers of base) */
1031 for (m = 0; m < n; m++) {
1032 BNWORD32 *entry;
1033
1034 LBNALLOC(entry, BNWORD32, msize);
1035 if (!entry)
1036 break;
1037 array[m] = entry;
1038 }
1039
1040 /* "m" is the number of successfully allocated entries */
1041 if (m < n) {
1042 /* Ran out of memory; see if we can use a smaller array */
1043 BNWORD32 **newarray;
1044
1045 if (m < 2) {
1046 n = 0; /* Forget it */
1047 } else {
1048 /* How few bits can we use with what's allocated? */
1049 bits = (maxebits + m - 1) / m;
1050retry:
1051 n = (maxebits + bits - 1) / bits;
1052 if (! (n >> bits) )
1053 n = 0; /* Not enough to amount to anything */
1054 }
1055 /* Free excess allocated array entries */
1056 while (m > n) {
1057 BNWORD32 *entry = array[--m];
1058 LBNFREE(entry, msize);
1059 }
1060 if (!n) {
1061 /* Give it up */
1062 lbnMemFree(array, arraysize * sizeof(*array));
1063 return -1;
1064 }
1065 /*
1066 * Try to shrink the pointer array. This might fail, but
1067 * it's not critical. lbnMemRealloc isn't guarnateed to
1068 * exist, so we may have to allocate, copy, and free.
1069 */
1070#ifdef lbnMemRealloc
1071 newarray = lbnMemRealloc(array, arraysize * sizeof(*array),
1072 (n+1) * sizeof(*array));
1073 if (newarray) {
1074 array = newarray;
1075 arraysize = n+1;
1076 }
1077#else
1078 newarray = lbnMemAlloc((n+1) * sizeof(*array));
1079 if (newarray) {
1080 memcpy(newarray, array, n * sizeof(*array));
1081 lbnMemFree(array, arraysize * sizeof(*array));
1082 array = newarray;
1083 arraysize = n+1;
1084 }
1085#endif
1086 }
1087
1088 /* Pad with null pointers */
1089 while (m < arraysize)
1090 array[m++] = 0;
1091
1092 /* Okay, we have our array, now initialize it */
1093 i = lbnBasePrecompBegin_32(array, n, bits,
1094 (BNWORD32 *)base->ptr, base->size,
1095 (BNWORD32 *)mod->ptr, msize);
1096 if (i < 0) {
1097 /* Ack, still out of memory */
1098 bits++;
1099 m = n;
1100 goto retry;
1101 }
1102 /* Finally, totoal success */
1103 pre->array = array;
1104 pre->bits = bits;
1105 pre->msize = msize;
1106 pre->maxebits = n * bits;
1107 pre->arraysize = arraysize;
1108 pre->entries = n;
1109 return 0;
1110}
1111
1112/* Free everything preallocated */
1113void
1114bnBasePrecompEnd_32(struct BnBasePrecomp *pre)
1115{
1116 BNWORD32 **array = pre->array;
1117
1118 if (array) {
1119 unsigned entries = pre->entries;
1120 unsigned msize = pre->msize;
1121 unsigned m;
1122
1123 for (m = 0; m < entries; m++) {
1124 BNWORD32 *entry = array[m];
1125 if (entry)
1126 LBNFREE(entry, msize);
1127 }
1128 lbnMemFree(array, pre->arraysize * sizeof(array));
1129 }
1130 pre->array = 0;
1131 pre->bits = 0;
1132 pre->msize = 0;
1133 pre->maxebits = 0;
1134 pre->arraysize = 0;
1135 pre->entries = 0;
1136}
1137
1138int
1139bnBasePrecompExpMod_32(struct BigNum *dest, struct BnBasePrecomp const *pre,
1140 struct BigNum const *exp, struct BigNum const *mod)
1141{
1142 unsigned msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
1143 unsigned esize = lbnNorm_32((BNWORD32 *)exp->ptr, exp->size);
1144 BNWORD32 const * const *array = pre->array;
1145 int i;
1146
1147 assert(msize == pre->msize);
1148 assert(((BNWORD32 *)mod->ptr)[BIGLITTLE(-1,0)] & 1);
1149 assert(lbnBits_32((BNWORD32 *)exp->ptr, esize) <= pre->maxebits);
1150
1151 bnSizeCheck(dest, msize);
1152
1153 i = lbnBasePrecompExp_32(dest->ptr, array, pre->bits,
1154 exp->ptr, esize, mod->ptr, msize);
1155 if (i == 0)
1156 dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, msize);
1157 return i;
1158}
1159
1160int
1161bnDoubleBasePrecompExpMod_32(struct BigNum *dest,
1162 struct BnBasePrecomp const *pre1, struct BigNum const *exp1,
1163 struct BnBasePrecomp const *pre2, struct BigNum const *exp2,
1164 struct BigNum const *mod)
1165{
1166 unsigned msize = lbnNorm_32((BNWORD32 *)mod->ptr, mod->size);
1167 unsigned e1size = lbnNorm_32((BNWORD32 *)exp1->ptr, exp1->size);
1168 unsigned e2size = lbnNorm_32((BNWORD32 *)exp1->ptr, exp2->size);
1169 BNWORD32 const * const *array1 = pre1->array;
1170 BNWORD32 const * const *array2 = pre2->array;
1171 int i;
1172
1173 assert(msize == pre1->msize);
1174 assert(msize == pre2->msize);
1175 assert(((BNWORD32 *)mod->ptr)[BIGLITTLE(-1,0)] & 1);
1176 assert(lbnBits_32((BNWORD32 *)exp1->ptr, e1size) <= pre1->maxebits);
1177 assert(lbnBits_32((BNWORD32 *)exp2->ptr, e2size) <= pre2->maxebits);
1178 assert(pre1->bits == pre2->bits);
1179
1180 bnSizeCheck(dest, msize);
1181
1182 i = lbnDoubleBasePrecompExp_32(dest->ptr, pre1->bits, array1,
1183 exp1->ptr, e1size, array2, exp2->ptr, e2size,
1184 mod->ptr, msize);
1185 if (i == 0)
1186 dest->size = lbnNorm_32((BNWORD32 *)dest->ptr, msize);
1187 return i;
1188}