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