]> asedeno.scripts.mit.edu Git - PuTTY.git/blob - sshbn.c
bignum_mod_short shouldn't be depending on a fixed place value in
[PuTTY.git] / sshbn.c
1 /*
2  * Bignum routines for RSA and DH and stuff.
3  */
4
5 #include <stdio.h>
6 #include <stdlib.h>
7 #include <string.h>
8
9 #include "misc.h"
10
11 #if defined __GNUC__ && defined __i386__
12 typedef unsigned long BignumInt;
13 typedef unsigned long long BignumDblInt;
14 #define BIGNUM_INT_MASK  0xFFFFFFFFUL
15 #define BIGNUM_TOP_BIT   0x80000000UL
16 #define BIGNUM_INT_BITS  32
17 #define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2)
18 #define DIVMOD_WORD(q, r, hi, lo, w) \
19     __asm__("div %2" : \
20             "=d" (r), "=a" (q) : \
21             "r" (w), "d" (hi), "a" (lo))
22 #else
23 typedef unsigned short BignumInt;
24 typedef unsigned long BignumDblInt;
25 #define BIGNUM_INT_MASK  0xFFFFU
26 #define BIGNUM_TOP_BIT   0x8000U
27 #define BIGNUM_INT_BITS  16
28 #define MUL_WORD(w1, w2) ((BignumDblInt)w1 * w2)
29 #define DIVMOD_WORD(q, r, hi, lo, w) do { \
30     BignumDblInt n = (((BignumDblInt)hi) << BIGNUM_INT_BITS) | lo; \
31     q = n / w; \
32     r = n % w; \
33 } while (0)
34 #endif
35
36 #define BIGNUM_INT_BYTES (BIGNUM_INT_BITS / 8)
37
38 #define BIGNUM_INTERNAL
39 typedef BignumInt *Bignum;
40
41 #include "ssh.h"
42
43 BignumInt bnZero[1] = { 0 };
44 BignumInt bnOne[2] = { 1, 1 };
45
46 /*
47  * The Bignum format is an array of `BignumInt'. The first
48  * element of the array counts the remaining elements. The
49  * remaining elements express the actual number, base 2^BIGNUM_INT_BITS, _least_
50  * significant digit first. (So it's trivial to extract the bit
51  * with value 2^n for any n.)
52  *
53  * All Bignums in this module are positive. Negative numbers must
54  * be dealt with outside it.
55  *
56  * INVARIANT: the most significant word of any Bignum must be
57  * nonzero.
58  */
59
60 Bignum Zero = bnZero, One = bnOne;
61
62 static Bignum newbn(int length)
63 {
64     Bignum b = snewn(length + 1, BignumInt);
65     if (!b)
66         abort();                       /* FIXME */
67     memset(b, 0, (length + 1) * sizeof(*b));
68     b[0] = length;
69     return b;
70 }
71
72 void bn_restore_invariant(Bignum b)
73 {
74     while (b[0] > 1 && b[b[0]] == 0)
75         b[0]--;
76 }
77
78 Bignum copybn(Bignum orig)
79 {
80     Bignum b = snewn(orig[0] + 1, BignumInt);
81     if (!b)
82         abort();                       /* FIXME */
83     memcpy(b, orig, (orig[0] + 1) * sizeof(*b));
84     return b;
85 }
86
87 void freebn(Bignum b)
88 {
89     /*
90      * Burn the evidence, just in case.
91      */
92     memset(b, 0, sizeof(b[0]) * (b[0] + 1));
93     sfree(b);
94 }
95
96 Bignum bn_power_2(int n)
97 {
98     Bignum ret = newbn(n / BIGNUM_INT_BITS + 1);
99     bignum_set_bit(ret, n, 1);
100     return ret;
101 }
102
103 /*
104  * Compute c = a * b.
105  * Input is in the first len words of a and b.
106  * Result is returned in the first 2*len words of c.
107  */
108 static void internal_mul(BignumInt *a, BignumInt *b,
109                          BignumInt *c, int len)
110 {
111     int i, j;
112     BignumDblInt t;
113
114     for (j = 0; j < 2 * len; j++)
115         c[j] = 0;
116
117     for (i = len - 1; i >= 0; i--) {
118         t = 0;
119         for (j = len - 1; j >= 0; j--) {
120             t += MUL_WORD(a[i], (BignumDblInt) b[j]);
121             t += (BignumDblInt) c[i + j + 1];
122             c[i + j + 1] = (BignumInt) t;
123             t = t >> BIGNUM_INT_BITS;
124         }
125         c[i] = (BignumInt) t;
126     }
127 }
128
129 static void internal_add_shifted(BignumInt *number,
130                                  unsigned n, int shift)
131 {
132     int word = 1 + (shift / BIGNUM_INT_BITS);
133     int bshift = shift % BIGNUM_INT_BITS;
134     BignumDblInt addend;
135
136     addend = n << bshift;
137
138     while (addend) {
139         addend += number[word];
140         number[word] = (BignumInt) addend & BIGNUM_INT_MASK;
141         addend >>= BIGNUM_INT_BITS;
142         word++;
143     }
144 }
145
146 /*
147  * Compute a = a % m.
148  * Input in first alen words of a and first mlen words of m.
149  * Output in first alen words of a
150  * (of which first alen-mlen words will be zero).
151  * The MSW of m MUST have its high bit set.
152  * Quotient is accumulated in the `quotient' array, which is a Bignum
153  * rather than the internal bigendian format. Quotient parts are shifted
154  * left by `qshift' before adding into quot.
155  */
156 static void internal_mod(BignumInt *a, int alen,
157                          BignumInt *m, int mlen,
158                          BignumInt *quot, int qshift)
159 {
160     BignumInt m0, m1;
161     unsigned int h;
162     int i, k;
163
164     m0 = m[0];
165     if (mlen > 1)
166         m1 = m[1];
167     else
168         m1 = 0;
169
170     for (i = 0; i <= alen - mlen; i++) {
171         BignumDblInt t;
172         unsigned int q, r, c, ai1;
173
174         if (i == 0) {
175             h = 0;
176         } else {
177             h = a[i - 1];
178             a[i - 1] = 0;
179         }
180
181         if (i == alen - 1)
182             ai1 = 0;
183         else
184             ai1 = a[i + 1];
185
186         /* Find q = h:a[i] / m0 */
187         DIVMOD_WORD(q, r, h, a[i], m0);
188
189         /* Refine our estimate of q by looking at
190            h:a[i]:a[i+1] / m0:m1 */
191         t = MUL_WORD(m1, q);
192         if (t > ((BignumDblInt) r << BIGNUM_INT_BITS) + ai1) {
193             q--;
194             t -= m1;
195             r = (r + m0) & BIGNUM_INT_MASK;     /* overflow? */
196             if (r >= (BignumDblInt) m0 &&
197                 t > ((BignumDblInt) r << BIGNUM_INT_BITS) + ai1) q--;
198         }
199
200         /* Subtract q * m from a[i...] */
201         c = 0;
202         for (k = mlen - 1; k >= 0; k--) {
203             t = MUL_WORD(q, m[k]);
204             t += c;
205             c = t >> BIGNUM_INT_BITS;
206             if ((BignumInt) t > a[i + k])
207                 c++;
208             a[i + k] -= (BignumInt) t;
209         }
210
211         /* Add back m in case of borrow */
212         if (c != h) {
213             t = 0;
214             for (k = mlen - 1; k >= 0; k--) {
215                 t += m[k];
216                 t += a[i + k];
217                 a[i + k] = (BignumInt) t;
218                 t = t >> BIGNUM_INT_BITS;
219             }
220             q--;
221         }
222         if (quot)
223             internal_add_shifted(quot, q, qshift + BIGNUM_INT_BITS * (alen - mlen - i));
224     }
225 }
226
227 /*
228  * Compute (base ^ exp) % mod.
229  * The base MUST be smaller than the modulus.
230  * The most significant word of mod MUST be non-zero.
231  * We assume that the result array is the same size as the mod array.
232  */
233 Bignum modpow(Bignum base, Bignum exp, Bignum mod)
234 {
235     BignumInt *a, *b, *n, *m;
236     int mshift;
237     int mlen, i, j;
238     Bignum result;
239
240     /* Allocate m of size mlen, copy mod to m */
241     /* We use big endian internally */
242     mlen = mod[0];
243     m = snewn(mlen, BignumInt);
244     for (j = 0; j < mlen; j++)
245         m[j] = mod[mod[0] - j];
246
247     /* Shift m left to make msb bit set */
248     for (mshift = 0; mshift < BIGNUM_INT_BITS-1; mshift++)
249         if ((m[0] << mshift) & BIGNUM_TOP_BIT)
250             break;
251     if (mshift) {
252         for (i = 0; i < mlen - 1; i++)
253             m[i] = (m[i] << mshift) | (m[i + 1] >> (BIGNUM_INT_BITS - mshift));
254         m[mlen - 1] = m[mlen - 1] << mshift;
255     }
256
257     /* Allocate n of size mlen, copy base to n */
258     n = snewn(mlen, BignumInt);
259     i = mlen - base[0];
260     for (j = 0; j < i; j++)
261         n[j] = 0;
262     for (j = 0; j < base[0]; j++)
263         n[i + j] = base[base[0] - j];
264
265     /* Allocate a and b of size 2*mlen. Set a = 1 */
266     a = snewn(2 * mlen, BignumInt);
267     b = snewn(2 * mlen, BignumInt);
268     for (i = 0; i < 2 * mlen; i++)
269         a[i] = 0;
270     a[2 * mlen - 1] = 1;
271
272     /* Skip leading zero bits of exp. */
273     i = 0;
274     j = BIGNUM_INT_BITS-1;
275     while (i < exp[0] && (exp[exp[0] - i] & (1 << j)) == 0) {
276         j--;
277         if (j < 0) {
278             i++;
279             j = BIGNUM_INT_BITS-1;
280         }
281     }
282
283     /* Main computation */
284     while (i < exp[0]) {
285         while (j >= 0) {
286             internal_mul(a + mlen, a + mlen, b, mlen);
287             internal_mod(b, mlen * 2, m, mlen, NULL, 0);
288             if ((exp[exp[0] - i] & (1 << j)) != 0) {
289                 internal_mul(b + mlen, n, a, mlen);
290                 internal_mod(a, mlen * 2, m, mlen, NULL, 0);
291             } else {
292                 BignumInt *t;
293                 t = a;
294                 a = b;
295                 b = t;
296             }
297             j--;
298         }
299         i++;
300         j = BIGNUM_INT_BITS-1;
301     }
302
303     /* Fixup result in case the modulus was shifted */
304     if (mshift) {
305         for (i = mlen - 1; i < 2 * mlen - 1; i++)
306             a[i] = (a[i] << mshift) | (a[i + 1] >> (BIGNUM_INT_BITS - mshift));
307         a[2 * mlen - 1] = a[2 * mlen - 1] << mshift;
308         internal_mod(a, mlen * 2, m, mlen, NULL, 0);
309         for (i = 2 * mlen - 1; i >= mlen; i--)
310             a[i] = (a[i] >> mshift) | (a[i - 1] << (BIGNUM_INT_BITS - mshift));
311     }
312
313     /* Copy result to buffer */
314     result = newbn(mod[0]);
315     for (i = 0; i < mlen; i++)
316         result[result[0] - i] = a[i + mlen];
317     while (result[0] > 1 && result[result[0]] == 0)
318         result[0]--;
319
320     /* Free temporary arrays */
321     for (i = 0; i < 2 * mlen; i++)
322         a[i] = 0;
323     sfree(a);
324     for (i = 0; i < 2 * mlen; i++)
325         b[i] = 0;
326     sfree(b);
327     for (i = 0; i < mlen; i++)
328         m[i] = 0;
329     sfree(m);
330     for (i = 0; i < mlen; i++)
331         n[i] = 0;
332     sfree(n);
333
334     return result;
335 }
336
337 /*
338  * Compute (p * q) % mod.
339  * The most significant word of mod MUST be non-zero.
340  * We assume that the result array is the same size as the mod array.
341  */
342 Bignum modmul(Bignum p, Bignum q, Bignum mod)
343 {
344     BignumInt *a, *n, *m, *o;
345     int mshift;
346     int pqlen, mlen, rlen, i, j;
347     Bignum result;
348
349     /* Allocate m of size mlen, copy mod to m */
350     /* We use big endian internally */
351     mlen = mod[0];
352     m = snewn(mlen, BignumInt);
353     for (j = 0; j < mlen; j++)
354         m[j] = mod[mod[0] - j];
355
356     /* Shift m left to make msb bit set */
357     for (mshift = 0; mshift < BIGNUM_INT_BITS-1; mshift++)
358         if ((m[0] << mshift) & BIGNUM_TOP_BIT)
359             break;
360     if (mshift) {
361         for (i = 0; i < mlen - 1; i++)
362             m[i] = (m[i] << mshift) | (m[i + 1] >> (BIGNUM_INT_BITS - mshift));
363         m[mlen - 1] = m[mlen - 1] << mshift;
364     }
365
366     pqlen = (p[0] > q[0] ? p[0] : q[0]);
367
368     /* Allocate n of size pqlen, copy p to n */
369     n = snewn(pqlen, BignumInt);
370     i = pqlen - p[0];
371     for (j = 0; j < i; j++)
372         n[j] = 0;
373     for (j = 0; j < p[0]; j++)
374         n[i + j] = p[p[0] - j];
375
376     /* Allocate o of size pqlen, copy q to o */
377     o = snewn(pqlen, BignumInt);
378     i = pqlen - q[0];
379     for (j = 0; j < i; j++)
380         o[j] = 0;
381     for (j = 0; j < q[0]; j++)
382         o[i + j] = q[q[0] - j];
383
384     /* Allocate a of size 2*pqlen for result */
385     a = snewn(2 * pqlen, BignumInt);
386
387     /* Main computation */
388     internal_mul(n, o, a, pqlen);
389     internal_mod(a, pqlen * 2, m, mlen, NULL, 0);
390
391     /* Fixup result in case the modulus was shifted */
392     if (mshift) {
393         for (i = 2 * pqlen - mlen - 1; i < 2 * pqlen - 1; i++)
394             a[i] = (a[i] << mshift) | (a[i + 1] >> (BIGNUM_INT_BITS - mshift));
395         a[2 * pqlen - 1] = a[2 * pqlen - 1] << mshift;
396         internal_mod(a, pqlen * 2, m, mlen, NULL, 0);
397         for (i = 2 * pqlen - 1; i >= 2 * pqlen - mlen; i--)
398             a[i] = (a[i] >> mshift) | (a[i - 1] << (BIGNUM_INT_BITS - mshift));
399     }
400
401     /* Copy result to buffer */
402     rlen = (mlen < pqlen * 2 ? mlen : pqlen * 2);
403     result = newbn(rlen);
404     for (i = 0; i < rlen; i++)
405         result[result[0] - i] = a[i + 2 * pqlen - rlen];
406     while (result[0] > 1 && result[result[0]] == 0)
407         result[0]--;
408
409     /* Free temporary arrays */
410     for (i = 0; i < 2 * pqlen; i++)
411         a[i] = 0;
412     sfree(a);
413     for (i = 0; i < mlen; i++)
414         m[i] = 0;
415     sfree(m);
416     for (i = 0; i < pqlen; i++)
417         n[i] = 0;
418     sfree(n);
419     for (i = 0; i < pqlen; i++)
420         o[i] = 0;
421     sfree(o);
422
423     return result;
424 }
425
426 /*
427  * Compute p % mod.
428  * The most significant word of mod MUST be non-zero.
429  * We assume that the result array is the same size as the mod array.
430  * We optionally write out a quotient if `quotient' is non-NULL.
431  * We can avoid writing out the result if `result' is NULL.
432  */
433 static void bigdivmod(Bignum p, Bignum mod, Bignum result, Bignum quotient)
434 {
435     BignumInt *n, *m;
436     int mshift;
437     int plen, mlen, i, j;
438
439     /* Allocate m of size mlen, copy mod to m */
440     /* We use big endian internally */
441     mlen = mod[0];
442     m = snewn(mlen, BignumInt);
443     for (j = 0; j < mlen; j++)
444         m[j] = mod[mod[0] - j];
445
446     /* Shift m left to make msb bit set */
447     for (mshift = 0; mshift < BIGNUM_INT_BITS-1; mshift++)
448         if ((m[0] << mshift) & BIGNUM_TOP_BIT)
449             break;
450     if (mshift) {
451         for (i = 0; i < mlen - 1; i++)
452             m[i] = (m[i] << mshift) | (m[i + 1] >> (BIGNUM_INT_BITS - mshift));
453         m[mlen - 1] = m[mlen - 1] << mshift;
454     }
455
456     plen = p[0];
457     /* Ensure plen > mlen */
458     if (plen <= mlen)
459         plen = mlen + 1;
460
461     /* Allocate n of size plen, copy p to n */
462     n = snewn(plen, BignumInt);
463     for (j = 0; j < plen; j++)
464         n[j] = 0;
465     for (j = 1; j <= p[0]; j++)
466         n[plen - j] = p[j];
467
468     /* Main computation */
469     internal_mod(n, plen, m, mlen, quotient, mshift);
470
471     /* Fixup result in case the modulus was shifted */
472     if (mshift) {
473         for (i = plen - mlen - 1; i < plen - 1; i++)
474             n[i] = (n[i] << mshift) | (n[i + 1] >> (BIGNUM_INT_BITS - mshift));
475         n[plen - 1] = n[plen - 1] << mshift;
476         internal_mod(n, plen, m, mlen, quotient, 0);
477         for (i = plen - 1; i >= plen - mlen; i--)
478             n[i] = (n[i] >> mshift) | (n[i - 1] << (BIGNUM_INT_BITS - mshift));
479     }
480
481     /* Copy result to buffer */
482     if (result) {
483         for (i = 1; i <= result[0]; i++) {
484             int j = plen - i;
485             result[i] = j >= 0 ? n[j] : 0;
486         }
487     }
488
489     /* Free temporary arrays */
490     for (i = 0; i < mlen; i++)
491         m[i] = 0;
492     sfree(m);
493     for (i = 0; i < plen; i++)
494         n[i] = 0;
495     sfree(n);
496 }
497
498 /*
499  * Decrement a number.
500  */
501 void decbn(Bignum bn)
502 {
503     int i = 1;
504     while (i < bn[0] && bn[i] == 0)
505         bn[i++] = BIGNUM_INT_MASK;
506     bn[i]--;
507 }
508
509 Bignum bignum_from_bytes(const unsigned char *data, int nbytes)
510 {
511     Bignum result;
512     int w, i;
513
514     w = (nbytes + BIGNUM_INT_BYTES - 1) / BIGNUM_INT_BYTES; /* bytes->words */
515
516     result = newbn(w);
517     for (i = 1; i <= w; i++)
518         result[i] = 0;
519     for (i = nbytes; i--;) {
520         unsigned char byte = *data++;
521         result[1 + i / BIGNUM_INT_BYTES] |= byte << (8*i % BIGNUM_INT_BITS);
522     }
523
524     while (result[0] > 1 && result[result[0]] == 0)
525         result[0]--;
526     return result;
527 }
528
529 /*
530  * Read an ssh1-format bignum from a data buffer. Return the number
531  * of bytes consumed.
532  */
533 int ssh1_read_bignum(const unsigned char *data, Bignum * result)
534 {
535     const unsigned char *p = data;
536     int i;
537     int w, b;
538
539     w = 0;
540     for (i = 0; i < 2; i++)
541         w = (w << 8) + *p++;
542     b = (w + 7) / 8;                   /* bits -> bytes */
543
544     if (!result)                       /* just return length */
545         return b + 2;
546
547     *result = bignum_from_bytes(p, b);
548
549     return p + b - data;
550 }
551
552 /*
553  * Return the bit count of a bignum, for ssh1 encoding.
554  */
555 int bignum_bitcount(Bignum bn)
556 {
557     int bitcount = bn[0] * BIGNUM_INT_BITS - 1;
558     while (bitcount >= 0
559            && (bn[bitcount / BIGNUM_INT_BITS + 1] >> (bitcount % BIGNUM_INT_BITS)) == 0) bitcount--;
560     return bitcount + 1;
561 }
562
563 /*
564  * Return the byte length of a bignum when ssh1 encoded.
565  */
566 int ssh1_bignum_length(Bignum bn)
567 {
568     return 2 + (bignum_bitcount(bn) + 7) / 8;
569 }
570
571 /*
572  * Return the byte length of a bignum when ssh2 encoded.
573  */
574 int ssh2_bignum_length(Bignum bn)
575 {
576     return 4 + (bignum_bitcount(bn) + 8) / 8;
577 }
578
579 /*
580  * Return a byte from a bignum; 0 is least significant, etc.
581  */
582 int bignum_byte(Bignum bn, int i)
583 {
584     if (i >= BIGNUM_INT_BYTES * bn[0])
585         return 0;                      /* beyond the end */
586     else
587         return (bn[i / BIGNUM_INT_BYTES + 1] >>
588                 ((i % BIGNUM_INT_BYTES)*8)) & 0xFF;
589 }
590
591 /*
592  * Return a bit from a bignum; 0 is least significant, etc.
593  */
594 int bignum_bit(Bignum bn, int i)
595 {
596     if (i >= BIGNUM_INT_BITS * bn[0])
597         return 0;                      /* beyond the end */
598     else
599         return (bn[i / BIGNUM_INT_BITS + 1] >> (i % BIGNUM_INT_BITS)) & 1;
600 }
601
602 /*
603  * Set a bit in a bignum; 0 is least significant, etc.
604  */
605 void bignum_set_bit(Bignum bn, int bitnum, int value)
606 {
607     if (bitnum >= BIGNUM_INT_BITS * bn[0])
608         abort();                       /* beyond the end */
609     else {
610         int v = bitnum / BIGNUM_INT_BITS + 1;
611         int mask = 1 << (bitnum % BIGNUM_INT_BITS);
612         if (value)
613             bn[v] |= mask;
614         else
615             bn[v] &= ~mask;
616     }
617 }
618
619 /*
620  * Write a ssh1-format bignum into a buffer. It is assumed the
621  * buffer is big enough. Returns the number of bytes used.
622  */
623 int ssh1_write_bignum(void *data, Bignum bn)
624 {
625     unsigned char *p = data;
626     int len = ssh1_bignum_length(bn);
627     int i;
628     int bitc = bignum_bitcount(bn);
629
630     *p++ = (bitc >> 8) & 0xFF;
631     *p++ = (bitc) & 0xFF;
632     for (i = len - 2; i--;)
633         *p++ = bignum_byte(bn, i);
634     return len;
635 }
636
637 /*
638  * Compare two bignums. Returns like strcmp.
639  */
640 int bignum_cmp(Bignum a, Bignum b)
641 {
642     int amax = a[0], bmax = b[0];
643     int i = (amax > bmax ? amax : bmax);
644     while (i) {
645         BignumInt aval = (i > amax ? 0 : a[i]);
646         BignumInt bval = (i > bmax ? 0 : b[i]);
647         if (aval < bval)
648             return -1;
649         if (aval > bval)
650             return +1;
651         i--;
652     }
653     return 0;
654 }
655
656 /*
657  * Right-shift one bignum to form another.
658  */
659 Bignum bignum_rshift(Bignum a, int shift)
660 {
661     Bignum ret;
662     int i, shiftw, shiftb, shiftbb, bits;
663     BignumInt ai, ai1;
664
665     bits = bignum_bitcount(a) - shift;
666     ret = newbn((bits + BIGNUM_INT_BITS - 1) / BIGNUM_INT_BITS);
667
668     if (ret) {
669         shiftw = shift / BIGNUM_INT_BITS;
670         shiftb = shift % BIGNUM_INT_BITS;
671         shiftbb = BIGNUM_INT_BITS - shiftb;
672
673         ai1 = a[shiftw + 1];
674         for (i = 1; i <= ret[0]; i++) {
675             ai = ai1;
676             ai1 = (i + shiftw + 1 <= a[0] ? a[i + shiftw + 1] : 0);
677             ret[i] = ((ai >> shiftb) | (ai1 << shiftbb)) & BIGNUM_INT_MASK;
678         }
679     }
680
681     return ret;
682 }
683
684 /*
685  * Non-modular multiplication and addition.
686  */
687 Bignum bigmuladd(Bignum a, Bignum b, Bignum addend)
688 {
689     int alen = a[0], blen = b[0];
690     int mlen = (alen > blen ? alen : blen);
691     int rlen, i, maxspot;
692     BignumInt *workspace;
693     Bignum ret;
694
695     /* mlen space for a, mlen space for b, 2*mlen for result */
696     workspace = snewn(mlen * 4, BignumInt);
697     for (i = 0; i < mlen; i++) {
698         workspace[0 * mlen + i] = (mlen - i <= a[0] ? a[mlen - i] : 0);
699         workspace[1 * mlen + i] = (mlen - i <= b[0] ? b[mlen - i] : 0);
700     }
701
702     internal_mul(workspace + 0 * mlen, workspace + 1 * mlen,
703                  workspace + 2 * mlen, mlen);
704
705     /* now just copy the result back */
706     rlen = alen + blen + 1;
707     if (addend && rlen <= addend[0])
708         rlen = addend[0] + 1;
709     ret = newbn(rlen);
710     maxspot = 0;
711     for (i = 1; i <= ret[0]; i++) {
712         ret[i] = (i <= 2 * mlen ? workspace[4 * mlen - i] : 0);
713         if (ret[i] != 0)
714             maxspot = i;
715     }
716     ret[0] = maxspot;
717
718     /* now add in the addend, if any */
719     if (addend) {
720         BignumDblInt carry = 0;
721         for (i = 1; i <= rlen; i++) {
722             carry += (i <= ret[0] ? ret[i] : 0);
723             carry += (i <= addend[0] ? addend[i] : 0);
724             ret[i] = (BignumInt) carry & BIGNUM_INT_MASK;
725             carry >>= BIGNUM_INT_BITS;
726             if (ret[i] != 0 && i > maxspot)
727                 maxspot = i;
728         }
729     }
730     ret[0] = maxspot;
731
732     return ret;
733 }
734
735 /*
736  * Non-modular multiplication.
737  */
738 Bignum bigmul(Bignum a, Bignum b)
739 {
740     return bigmuladd(a, b, NULL);
741 }
742
743 /*
744  * Create a bignum which is the bitmask covering another one. That
745  * is, the smallest integer which is >= N and is also one less than
746  * a power of two.
747  */
748 Bignum bignum_bitmask(Bignum n)
749 {
750     Bignum ret = copybn(n);
751     int i;
752     BignumInt j;
753
754     i = ret[0];
755     while (n[i] == 0 && i > 0)
756         i--;
757     if (i <= 0)
758         return ret;                    /* input was zero */
759     j = 1;
760     while (j < n[i])
761         j = 2 * j + 1;
762     ret[i] = j;
763     while (--i > 0)
764         ret[i] = BIGNUM_INT_MASK;
765     return ret;
766 }
767
768 /*
769  * Convert a (max 32-bit) long into a bignum.
770  */
771 Bignum bignum_from_long(unsigned long nn)
772 {
773     Bignum ret;
774     BignumDblInt n = nn;
775
776     ret = newbn(3);
777     ret[1] = (BignumInt)(n & BIGNUM_INT_MASK);
778     ret[2] = (BignumInt)((n >> BIGNUM_INT_BITS) & BIGNUM_INT_MASK);
779     ret[3] = 0;
780     ret[0] = (ret[2]  ? 2 : 1);
781     return ret;
782 }
783
784 /*
785  * Add a long to a bignum.
786  */
787 Bignum bignum_add_long(Bignum number, unsigned long addendx)
788 {
789     Bignum ret = newbn(number[0] + 1);
790     int i, maxspot = 0;
791     BignumDblInt carry = 0, addend = addendx;
792
793     for (i = 1; i <= ret[0]; i++) {
794         carry += addend & BIGNUM_INT_MASK;
795         carry += (i <= number[0] ? number[i] : 0);
796         addend >>= BIGNUM_INT_BITS;
797         ret[i] = (BignumInt) carry & BIGNUM_INT_MASK;
798         carry >>= BIGNUM_INT_BITS;
799         if (ret[i] != 0)
800             maxspot = i;
801     }
802     ret[0] = maxspot;
803     return ret;
804 }
805
806 /*
807  * Compute the residue of a bignum, modulo a (max 16-bit) short.
808  */
809 unsigned short bignum_mod_short(Bignum number, unsigned short modulus)
810 {
811     BignumDblInt mod, r;
812     int i;
813
814     r = 0;
815     mod = modulus;
816     for (i = number[0]; i > 0; i--)
817         r = (r * (BIGNUM_TOP_BIT % mod) * 2 + number[i] % mod) % mod;
818     return (unsigned short) r;
819 }
820
821 #ifdef DEBUG
822 void diagbn(char *prefix, Bignum md)
823 {
824     int i, nibbles, morenibbles;
825     static const char hex[] = "0123456789ABCDEF";
826
827     debug(("%s0x", prefix ? prefix : ""));
828
829     nibbles = (3 + bignum_bitcount(md)) / 4;
830     if (nibbles < 1)
831         nibbles = 1;
832     morenibbles = 4 * md[0] - nibbles;
833     for (i = 0; i < morenibbles; i++)
834         debug(("-"));
835     for (i = nibbles; i--;)
836         debug(("%c",
837                hex[(bignum_byte(md, i / 2) >> (4 * (i % 2))) & 0xF]));
838
839     if (prefix)
840         debug(("\n"));
841 }
842 #endif
843
844 /*
845  * Simple division.
846  */
847 Bignum bigdiv(Bignum a, Bignum b)
848 {
849     Bignum q = newbn(a[0]);
850     bigdivmod(a, b, NULL, q);
851     return q;
852 }
853
854 /*
855  * Simple remainder.
856  */
857 Bignum bigmod(Bignum a, Bignum b)
858 {
859     Bignum r = newbn(b[0]);
860     bigdivmod(a, b, r, NULL);
861     return r;
862 }
863
864 /*
865  * Greatest common divisor.
866  */
867 Bignum biggcd(Bignum av, Bignum bv)
868 {
869     Bignum a = copybn(av);
870     Bignum b = copybn(bv);
871
872     while (bignum_cmp(b, Zero) != 0) {
873         Bignum t = newbn(b[0]);
874         bigdivmod(a, b, t, NULL);
875         while (t[0] > 1 && t[t[0]] == 0)
876             t[0]--;
877         freebn(a);
878         a = b;
879         b = t;
880     }
881
882     freebn(b);
883     return a;
884 }
885
886 /*
887  * Modular inverse, using Euclid's extended algorithm.
888  */
889 Bignum modinv(Bignum number, Bignum modulus)
890 {
891     Bignum a = copybn(modulus);
892     Bignum b = copybn(number);
893     Bignum xp = copybn(Zero);
894     Bignum x = copybn(One);
895     int sign = +1;
896
897     while (bignum_cmp(b, One) != 0) {
898         Bignum t = newbn(b[0]);
899         Bignum q = newbn(a[0]);
900         bigdivmod(a, b, t, q);
901         while (t[0] > 1 && t[t[0]] == 0)
902             t[0]--;
903         freebn(a);
904         a = b;
905         b = t;
906         t = xp;
907         xp = x;
908         x = bigmuladd(q, xp, t);
909         sign = -sign;
910         freebn(t);
911     }
912
913     freebn(b);
914     freebn(a);
915     freebn(xp);
916
917     /* now we know that sign * x == 1, and that x < modulus */
918     if (sign < 0) {
919         /* set a new x to be modulus - x */
920         Bignum newx = newbn(modulus[0]);
921         BignumInt carry = 0;
922         int maxspot = 1;
923         int i;
924
925         for (i = 1; i <= newx[0]; i++) {
926             BignumInt aword = (i <= modulus[0] ? modulus[i] : 0);
927             BignumInt bword = (i <= x[0] ? x[i] : 0);
928             newx[i] = aword - bword - carry;
929             bword = ~bword;
930             carry = carry ? (newx[i] >= bword) : (newx[i] > bword);
931             if (newx[i] != 0)
932                 maxspot = i;
933         }
934         newx[0] = maxspot;
935         freebn(x);
936         x = newx;
937     }
938
939     /* and return. */
940     return x;
941 }
942
943 /*
944  * Render a bignum into decimal. Return a malloced string holding
945  * the decimal representation.
946  */
947 char *bignum_decimal(Bignum x)
948 {
949     int ndigits, ndigit;
950     int i, iszero;
951     BignumDblInt carry;
952     char *ret;
953     BignumInt *workspace;
954
955     /*
956      * First, estimate the number of digits. Since log(10)/log(2)
957      * is just greater than 93/28 (the joys of continued fraction
958      * approximations...) we know that for every 93 bits, we need
959      * at most 28 digits. This will tell us how much to malloc.
960      *
961      * Formally: if x has i bits, that means x is strictly less
962      * than 2^i. Since 2 is less than 10^(28/93), this is less than
963      * 10^(28i/93). We need an integer power of ten, so we must
964      * round up (rounding down might make it less than x again).
965      * Therefore if we multiply the bit count by 28/93, rounding
966      * up, we will have enough digits.
967      */
968     i = bignum_bitcount(x);
969     ndigits = (28 * i + 92) / 93;      /* multiply by 28/93 and round up */
970     ndigits++;                         /* allow for trailing \0 */
971     ret = snewn(ndigits, char);
972
973     /*
974      * Now allocate some workspace to hold the binary form as we
975      * repeatedly divide it by ten. Initialise this to the
976      * big-endian form of the number.
977      */
978     workspace = snewn(x[0], BignumInt);
979     for (i = 0; i < x[0]; i++)
980         workspace[i] = x[x[0] - i];
981
982     /*
983      * Next, write the decimal number starting with the last digit.
984      * We use ordinary short division, dividing 10 into the
985      * workspace.
986      */
987     ndigit = ndigits - 1;
988     ret[ndigit] = '\0';
989     do {
990         iszero = 1;
991         carry = 0;
992         for (i = 0; i < x[0]; i++) {
993             carry = (carry << BIGNUM_INT_BITS) + workspace[i];
994             workspace[i] = (BignumInt) (carry / 10);
995             if (workspace[i])
996                 iszero = 0;
997             carry %= 10;
998         }
999         ret[--ndigit] = (char) (carry + '0');
1000     } while (!iszero);
1001
1002     /*
1003      * There's a chance we've fallen short of the start of the
1004      * string. Correct if so.
1005      */
1006     if (ndigit > 0)
1007         memmove(ret, ret + ndigit, ndigits - ndigit);
1008
1009     /*
1010      * Done.
1011      */
1012     return ret;
1013 }