LogDlg: When filtering only for paths log entries might contain invalid data
[TortoiseGit.git] / src / TortoisePlink / SSHBN.C
blob6240a0691d30bb387d188692fef8e768cf36c4aa
1 /*\r
2  * Bignum routines for RSA and DH and stuff.\r
3  */\r
4 \r
5 #include <stdio.h>\r
6 #include <assert.h>\r
7 #include <stdlib.h>\r
8 #include <string.h>\r
9 #include <limits.h>\r
11 #include "misc.h"\r
13 #include "sshbn.h"\r
15 #define BIGNUM_INTERNAL\r
16 typedef BignumInt *Bignum;\r
18 #include "ssh.h"\r
20 BignumInt bnZero[1] = { 0 };\r
21 BignumInt bnOne[2] = { 1, 1 };\r
23 /*\r
24  * The Bignum format is an array of `BignumInt'. The first\r
25  * element of the array counts the remaining elements. The\r
26  * remaining elements express the actual number, base 2^BIGNUM_INT_BITS, _least_\r
27  * significant digit first. (So it's trivial to extract the bit\r
28  * with value 2^n for any n.)\r
29  *\r
30  * All Bignums in this module are positive. Negative numbers must\r
31  * be dealt with outside it.\r
32  *\r
33  * INVARIANT: the most significant word of any Bignum must be\r
34  * nonzero.\r
35  */\r
37 Bignum Zero = bnZero, One = bnOne;\r
39 static Bignum newbn(int length)\r
40 {\r
41     Bignum b;\r
43     assert(length >= 0 && length < INT_MAX / BIGNUM_INT_BITS);\r
45     b = snewn(length + 1, BignumInt);\r
46     if (!b)\r
47         abort();                       /* FIXME */\r
48     memset(b, 0, (length + 1) * sizeof(*b));\r
49     b[0] = length;\r
50     return b;\r
51 }\r
53 void bn_restore_invariant(Bignum b)\r
54 {\r
55     while (b[0] > 1 && b[b[0]] == 0)\r
56         b[0]--;\r
57 }\r
59 Bignum copybn(Bignum orig)\r
60 {\r
61     Bignum b = snewn(orig[0] + 1, BignumInt);\r
62     if (!b)\r
63         abort();                       /* FIXME */\r
64     memcpy(b, orig, (orig[0] + 1) * sizeof(*b));\r
65     return b;\r
66 }\r
68 void freebn(Bignum b)\r
69 {\r
70     /*\r
71      * Burn the evidence, just in case.\r
72      */\r
73     smemclr(b, sizeof(b[0]) * (b[0] + 1));\r
74     sfree(b);\r
75 }\r
77 Bignum bn_power_2(int n)\r
78 {\r
79     Bignum ret;\r
81     assert(n >= 0);\r
83     ret = newbn(n / BIGNUM_INT_BITS + 1);\r
84     bignum_set_bit(ret, n, 1);\r
85     return ret;\r
86 }\r
88 /*\r
89  * Internal addition. Sets c = a - b, where 'a', 'b' and 'c' are all\r
90  * big-endian arrays of 'len' BignumInts. Returns a BignumInt carried\r
91  * off the top.\r
92  */\r
93 static BignumInt internal_add(const BignumInt *a, const BignumInt *b,\r
94                               BignumInt *c, int len)\r
95 {\r
96     int i;\r
97     BignumDblInt carry = 0;\r
99     for (i = len-1; i >= 0; i--) {\r
100         carry += (BignumDblInt)a[i] + b[i];\r
101         c[i] = (BignumInt)carry;\r
102         carry >>= BIGNUM_INT_BITS;\r
103     }\r
105     return (BignumInt)carry;\r
108 /*\r
109  * Internal subtraction. Sets c = a - b, where 'a', 'b' and 'c' are\r
110  * all big-endian arrays of 'len' BignumInts. Any borrow from the top\r
111  * is ignored.\r
112  */\r
113 static void internal_sub(const BignumInt *a, const BignumInt *b,\r
114                          BignumInt *c, int len)\r
116     int i;\r
117     BignumDblInt carry = 1;\r
119     for (i = len-1; i >= 0; i--) {\r
120         carry += (BignumDblInt)a[i] + (b[i] ^ BIGNUM_INT_MASK);\r
121         c[i] = (BignumInt)carry;\r
122         carry >>= BIGNUM_INT_BITS;\r
123     }\r
126 /*\r
127  * Compute c = a * b.\r
128  * Input is in the first len words of a and b.\r
129  * Result is returned in the first 2*len words of c.\r
130  *\r
131  * 'scratch' must point to an array of BignumInt of size at least\r
132  * mul_compute_scratch(len). (This covers the needs of internal_mul\r
133  * and all its recursive calls to itself.)\r
134  */\r
135 #define KARATSUBA_THRESHOLD 50\r
136 static int mul_compute_scratch(int len)\r
138     int ret = 0;\r
139     while (len > KARATSUBA_THRESHOLD) {\r
140         int toplen = len/2, botlen = len - toplen; /* botlen is the bigger */\r
141         int midlen = botlen + 1;\r
142         ret += 4*midlen;\r
143         len = midlen;\r
144     }\r
145     return ret;\r
147 static void internal_mul(const BignumInt *a, const BignumInt *b,\r
148                          BignumInt *c, int len, BignumInt *scratch)\r
150     if (len > KARATSUBA_THRESHOLD) {\r
151         int i;\r
153         /*\r
154          * Karatsuba divide-and-conquer algorithm. Cut each input in\r
155          * half, so that it's expressed as two big 'digits' in a giant\r
156          * base D:\r
157          *\r
158          *   a = a_1 D + a_0\r
159          *   b = b_1 D + b_0\r
160          *\r
161          * Then the product is of course\r
162          *\r
163          *  ab = a_1 b_1 D^2 + (a_1 b_0 + a_0 b_1) D + a_0 b_0\r
164          *\r
165          * and we compute the three coefficients by recursively\r
166          * calling ourself to do half-length multiplications.\r
167          *\r
168          * The clever bit that makes this worth doing is that we only\r
169          * need _one_ half-length multiplication for the central\r
170          * coefficient rather than the two that it obviouly looks\r
171          * like, because we can use a single multiplication to compute\r
172          *\r
173          *   (a_1 + a_0) (b_1 + b_0) = a_1 b_1 + a_1 b_0 + a_0 b_1 + a_0 b_0\r
174          *\r
175          * and then we subtract the other two coefficients (a_1 b_1\r
176          * and a_0 b_0) which we were computing anyway.\r
177          *\r
178          * Hence we get to multiply two numbers of length N in about\r
179          * three times as much work as it takes to multiply numbers of\r
180          * length N/2, which is obviously better than the four times\r
181          * as much work it would take if we just did a long\r
182          * conventional multiply.\r
183          */\r
185         int toplen = len/2, botlen = len - toplen; /* botlen is the bigger */\r
186         int midlen = botlen + 1;\r
187         BignumDblInt carry;\r
188 #ifdef KARA_DEBUG\r
189         int i;\r
190 #endif\r
192         /*\r
193          * The coefficients a_1 b_1 and a_0 b_0 just avoid overlapping\r
194          * in the output array, so we can compute them immediately in\r
195          * place.\r
196          */\r
198 #ifdef KARA_DEBUG\r
199         printf("a1,a0 = 0x");\r
200         for (i = 0; i < len; i++) {\r
201             if (i == toplen) printf(", 0x");\r
202             printf("%0*x", BIGNUM_INT_BITS/4, a[i]);\r
203         }\r
204         printf("\n");\r
205         printf("b1,b0 = 0x");\r
206         for (i = 0; i < len; i++) {\r
207             if (i == toplen) printf(", 0x");\r
208             printf("%0*x", BIGNUM_INT_BITS/4, b[i]);\r
209         }\r
210         printf("\n");\r
211 #endif\r
213         /* a_1 b_1 */\r
214         internal_mul(a, b, c, toplen, scratch);\r
215 #ifdef KARA_DEBUG\r
216         printf("a1b1 = 0x");\r
217         for (i = 0; i < 2*toplen; i++) {\r
218             printf("%0*x", BIGNUM_INT_BITS/4, c[i]);\r
219         }\r
220         printf("\n");\r
221 #endif\r
223         /* a_0 b_0 */\r
224         internal_mul(a + toplen, b + toplen, c + 2*toplen, botlen, scratch);\r
225 #ifdef KARA_DEBUG\r
226         printf("a0b0 = 0x");\r
227         for (i = 0; i < 2*botlen; i++) {\r
228             printf("%0*x", BIGNUM_INT_BITS/4, c[2*toplen+i]);\r
229         }\r
230         printf("\n");\r
231 #endif\r
233         /* Zero padding. midlen exceeds toplen by at most 2, so just\r
234          * zero the first two words of each input and the rest will be\r
235          * copied over. */\r
236         scratch[0] = scratch[1] = scratch[midlen] = scratch[midlen+1] = 0;\r
238         for (i = 0; i < toplen; i++) {\r
239             scratch[midlen - toplen + i] = a[i]; /* a_1 */\r
240             scratch[2*midlen - toplen + i] = b[i]; /* b_1 */\r
241         }\r
243         /* compute a_1 + a_0 */\r
244         scratch[0] = internal_add(scratch+1, a+toplen, scratch+1, botlen);\r
245 #ifdef KARA_DEBUG\r
246         printf("a1plusa0 = 0x");\r
247         for (i = 0; i < midlen; i++) {\r
248             printf("%0*x", BIGNUM_INT_BITS/4, scratch[i]);\r
249         }\r
250         printf("\n");\r
251 #endif\r
252         /* compute b_1 + b_0 */\r
253         scratch[midlen] = internal_add(scratch+midlen+1, b+toplen,\r
254                                        scratch+midlen+1, botlen);\r
255 #ifdef KARA_DEBUG\r
256         printf("b1plusb0 = 0x");\r
257         for (i = 0; i < midlen; i++) {\r
258             printf("%0*x", BIGNUM_INT_BITS/4, scratch[midlen+i]);\r
259         }\r
260         printf("\n");\r
261 #endif\r
263         /*\r
264          * Now we can do the third multiplication.\r
265          */\r
266         internal_mul(scratch, scratch + midlen, scratch + 2*midlen, midlen,\r
267                      scratch + 4*midlen);\r
268 #ifdef KARA_DEBUG\r
269         printf("a1plusa0timesb1plusb0 = 0x");\r
270         for (i = 0; i < 2*midlen; i++) {\r
271             printf("%0*x", BIGNUM_INT_BITS/4, scratch[2*midlen+i]);\r
272         }\r
273         printf("\n");\r
274 #endif\r
276         /*\r
277          * Now we can reuse the first half of 'scratch' to compute the\r
278          * sum of the outer two coefficients, to subtract from that\r
279          * product to obtain the middle one.\r
280          */\r
281         scratch[0] = scratch[1] = scratch[2] = scratch[3] = 0;\r
282         for (i = 0; i < 2*toplen; i++)\r
283             scratch[2*midlen - 2*toplen + i] = c[i];\r
284         scratch[1] = internal_add(scratch+2, c + 2*toplen,\r
285                                   scratch+2, 2*botlen);\r
286 #ifdef KARA_DEBUG\r
287         printf("a1b1plusa0b0 = 0x");\r
288         for (i = 0; i < 2*midlen; i++) {\r
289             printf("%0*x", BIGNUM_INT_BITS/4, scratch[i]);\r
290         }\r
291         printf("\n");\r
292 #endif\r
294         internal_sub(scratch + 2*midlen, scratch,\r
295                      scratch + 2*midlen, 2*midlen);\r
296 #ifdef KARA_DEBUG\r
297         printf("a1b0plusa0b1 = 0x");\r
298         for (i = 0; i < 2*midlen; i++) {\r
299             printf("%0*x", BIGNUM_INT_BITS/4, scratch[2*midlen+i]);\r
300         }\r
301         printf("\n");\r
302 #endif\r
304         /*\r
305          * And now all we need to do is to add that middle coefficient\r
306          * back into the output. We may have to propagate a carry\r
307          * further up the output, but we can be sure it won't\r
308          * propagate right the way off the top.\r
309          */\r
310         carry = internal_add(c + 2*len - botlen - 2*midlen,\r
311                              scratch + 2*midlen,\r
312                              c + 2*len - botlen - 2*midlen, 2*midlen);\r
313         i = 2*len - botlen - 2*midlen - 1;\r
314         while (carry) {\r
315             assert(i >= 0);\r
316             carry += c[i];\r
317             c[i] = (BignumInt)carry;\r
318             carry >>= BIGNUM_INT_BITS;\r
319             i--;\r
320         }\r
321 #ifdef KARA_DEBUG\r
322         printf("ab = 0x");\r
323         for (i = 0; i < 2*len; i++) {\r
324             printf("%0*x", BIGNUM_INT_BITS/4, c[i]);\r
325         }\r
326         printf("\n");\r
327 #endif\r
329     } else {\r
330         int i;\r
331         BignumInt carry;\r
332         BignumDblInt t;\r
333         const BignumInt *ap, *bp;\r
334         BignumInt *cp, *cps;\r
336         /*\r
337          * Multiply in the ordinary O(N^2) way.\r
338          */\r
340         for (i = 0; i < 2 * len; i++)\r
341             c[i] = 0;\r
343         for (cps = c + 2*len, ap = a + len; ap-- > a; cps--) {\r
344             carry = 0;\r
345             for (cp = cps, bp = b + len; cp--, bp-- > b ;) {\r
346                 t = (MUL_WORD(*ap, *bp) + carry) + *cp;\r
347                 *cp = (BignumInt) t;\r
348                 carry = (BignumInt)(t >> BIGNUM_INT_BITS);\r
349             }\r
350             *cp = carry;\r
351         }\r
352     }\r
355 /*\r
356  * Variant form of internal_mul used for the initial step of\r
357  * Montgomery reduction. Only bothers outputting 'len' words\r
358  * (everything above that is thrown away).\r
359  */\r
360 static void internal_mul_low(const BignumInt *a, const BignumInt *b,\r
361                              BignumInt *c, int len, BignumInt *scratch)\r
363     if (len > KARATSUBA_THRESHOLD) {\r
364         int i;\r
366         /*\r
367          * Karatsuba-aware version of internal_mul_low. As before, we\r
368          * express each input value as a shifted combination of two\r
369          * halves:\r
370          *\r
371          *   a = a_1 D + a_0\r
372          *   b = b_1 D + b_0\r
373          *\r
374          * Then the full product is, as before,\r
375          *\r
376          *  ab = a_1 b_1 D^2 + (a_1 b_0 + a_0 b_1) D + a_0 b_0\r
377          *\r
378          * Provided we choose D on the large side (so that a_0 and b_0\r
379          * are _at least_ as long as a_1 and b_1), we don't need the\r
380          * topmost term at all, and we only need half of the middle\r
381          * term. So there's no point in doing the proper Karatsuba\r
382          * optimisation which computes the middle term using the top\r
383          * one, because we'd take as long computing the top one as\r
384          * just computing the middle one directly.\r
385          *\r
386          * So instead, we do a much more obvious thing: we call the\r
387          * fully optimised internal_mul to compute a_0 b_0, and we\r
388          * recursively call ourself to compute the _bottom halves_ of\r
389          * a_1 b_0 and a_0 b_1, each of which we add into the result\r
390          * in the obvious way.\r
391          *\r
392          * In other words, there's no actual Karatsuba _optimisation_\r
393          * in this function; the only benefit in doing it this way is\r
394          * that we call internal_mul proper for a large part of the\r
395          * work, and _that_ can optimise its operation.\r
396          */\r
398         int toplen = len/2, botlen = len - toplen; /* botlen is the bigger */\r
400         /*\r
401          * Scratch space for the various bits and pieces we're going\r
402          * to be adding together: we need botlen*2 words for a_0 b_0\r
403          * (though we may end up throwing away its topmost word), and\r
404          * toplen words for each of a_1 b_0 and a_0 b_1. That adds up\r
405          * to exactly 2*len.\r
406          */\r
408         /* a_0 b_0 */\r
409         internal_mul(a + toplen, b + toplen, scratch + 2*toplen, botlen,\r
410                      scratch + 2*len);\r
412         /* a_1 b_0 */\r
413         internal_mul_low(a, b + len - toplen, scratch + toplen, toplen,\r
414                          scratch + 2*len);\r
416         /* a_0 b_1 */\r
417         internal_mul_low(a + len - toplen, b, scratch, toplen,\r
418                          scratch + 2*len);\r
420         /* Copy the bottom half of the big coefficient into place */\r
421         for (i = 0; i < botlen; i++)\r
422             c[toplen + i] = scratch[2*toplen + botlen + i];\r
424         /* Add the two small coefficients, throwing away the returned carry */\r
425         internal_add(scratch, scratch + toplen, scratch, toplen);\r
427         /* And add that to the large coefficient, leaving the result in c. */\r
428         internal_add(scratch, scratch + 2*toplen + botlen - toplen,\r
429                      c, toplen);\r
431     } else {\r
432         int i;\r
433         BignumInt carry;\r
434         BignumDblInt t;\r
435         const BignumInt *ap, *bp;\r
436         BignumInt *cp, *cps;\r
438         /*\r
439          * Multiply in the ordinary O(N^2) way.\r
440          */\r
442         for (i = 0; i < len; i++)\r
443             c[i] = 0;\r
445         for (cps = c + len, ap = a + len; ap-- > a; cps--) {\r
446             carry = 0;\r
447             for (cp = cps, bp = b + len; bp--, cp-- > c ;) {\r
448                 t = (MUL_WORD(*ap, *bp) + carry) + *cp;\r
449                 *cp = (BignumInt) t;\r
450                 carry = (BignumInt)(t >> BIGNUM_INT_BITS);\r
451             }\r
452         }\r
453     }\r
456 /*\r
457  * Montgomery reduction. Expects x to be a big-endian array of 2*len\r
458  * BignumInts whose value satisfies 0 <= x < rn (where r = 2^(len *\r
459  * BIGNUM_INT_BITS) is the Montgomery base). Returns in the same array\r
460  * a value x' which is congruent to xr^{-1} mod n, and satisfies 0 <=\r
461  * x' < n.\r
462  *\r
463  * 'n' and 'mninv' should be big-endian arrays of 'len' BignumInts\r
464  * each, containing respectively n and the multiplicative inverse of\r
465  * -n mod r.\r
466  *\r
467  * 'tmp' is an array of BignumInt used as scratch space, of length at\r
468  * least 3*len + mul_compute_scratch(len).\r
469  */\r
470 static void monty_reduce(BignumInt *x, const BignumInt *n,\r
471                          const BignumInt *mninv, BignumInt *tmp, int len)\r
473     int i;\r
474     BignumInt carry;\r
476     /*\r
477      * Multiply x by (-n)^{-1} mod r. This gives us a value m such\r
478      * that mn is congruent to -x mod r. Hence, mn+x is an exact\r
479      * multiple of r, and is also (obviously) congruent to x mod n.\r
480      */\r
481     internal_mul_low(x + len, mninv, tmp, len, tmp + 3*len);\r
483     /*\r
484      * Compute t = (mn+x)/r in ordinary, non-modular, integer\r
485      * arithmetic. By construction this is exact, and is congruent mod\r
486      * n to x * r^{-1}, i.e. the answer we want.\r
487      *\r
488      * The following multiply leaves that answer in the _most_\r
489      * significant half of the 'x' array, so then we must shift it\r
490      * down.\r
491      */\r
492     internal_mul(tmp, n, tmp+len, len, tmp + 3*len);\r
493     carry = internal_add(x, tmp+len, x, 2*len);\r
494     for (i = 0; i < len; i++)\r
495         x[len + i] = x[i], x[i] = 0;\r
497     /*\r
498      * Reduce t mod n. This doesn't require a full-on division by n,\r
499      * but merely a test and single optional subtraction, since we can\r
500      * show that 0 <= t < 2n.\r
501      *\r
502      * Proof:\r
503      *  + we computed m mod r, so 0 <= m < r.\r
504      *  + so 0 <= mn < rn, obviously\r
505      *  + hence we only need 0 <= x < rn to guarantee that 0 <= mn+x < 2rn\r
506      *  + yielding 0 <= (mn+x)/r < 2n as required.\r
507      */\r
508     if (!carry) {\r
509         for (i = 0; i < len; i++)\r
510             if (x[len + i] != n[i])\r
511                 break;\r
512     }\r
513     if (carry || i >= len || x[len + i] > n[i])\r
514         internal_sub(x+len, n, x+len, len);\r
517 static void internal_add_shifted(BignumInt *number,\r
518                                  BignumInt n, int shift)\r
520     int word = 1 + (shift / BIGNUM_INT_BITS);\r
521     int bshift = shift % BIGNUM_INT_BITS;\r
522     BignumDblInt addend;\r
524     addend = (BignumDblInt)n << bshift;\r
526     while (addend) {\r
527         assert(word <= number[0]);\r
528         addend += number[word];\r
529         number[word] = (BignumInt) addend & BIGNUM_INT_MASK;\r
530         addend >>= BIGNUM_INT_BITS;\r
531         word++;\r
532     }\r
535 /*\r
536  * Compute a = a % m.\r
537  * Input in first alen words of a and first mlen words of m.\r
538  * Output in first alen words of a\r
539  * (of which first alen-mlen words will be zero).\r
540  * The MSW of m MUST have its high bit set.\r
541  * Quotient is accumulated in the `quotient' array, which is a Bignum\r
542  * rather than the internal bigendian format. Quotient parts are shifted\r
543  * left by `qshift' before adding into quot.\r
544  */\r
545 static void internal_mod(BignumInt *a, int alen,\r
546                          BignumInt *m, int mlen,\r
547                          BignumInt *quot, int qshift)\r
549     BignumInt m0, m1, h;\r
550     int i, k;\r
552     m0 = m[0];\r
553     assert(m0 >> (BIGNUM_INT_BITS-1) == 1);\r
554     if (mlen > 1)\r
555         m1 = m[1];\r
556     else\r
557         m1 = 0;\r
559     for (i = 0; i <= alen - mlen; i++) {\r
560         BignumDblInt t;\r
561         BignumInt q, r, c, ai1;\r
563         if (i == 0) {\r
564             h = 0;\r
565         } else {\r
566             h = a[i - 1];\r
567             a[i - 1] = 0;\r
568         }\r
570         if (i == alen - 1)\r
571             ai1 = 0;\r
572         else\r
573             ai1 = a[i + 1];\r
575         /* Find q = h:a[i] / m0 */\r
576         if (h >= m0) {\r
577             /*\r
578              * Special case.\r
579              * \r
580              * To illustrate it, suppose a BignumInt is 8 bits, and\r
581              * we are dividing (say) A1:23:45:67 by A1:B2:C3. Then\r
582              * our initial division will be 0xA123 / 0xA1, which\r
583              * will give a quotient of 0x100 and a divide overflow.\r
584              * However, the invariants in this division algorithm\r
585              * are not violated, since the full number A1:23:... is\r
586              * _less_ than the quotient prefix A1:B2:... and so the\r
587              * following correction loop would have sorted it out.\r
588              * \r
589              * In this situation we set q to be the largest\r
590              * quotient we _can_ stomach (0xFF, of course).\r
591              */\r
592             q = BIGNUM_INT_MASK;\r
593         } else {\r
594             /* Macro doesn't want an array subscript expression passed\r
595              * into it (see definition), so use a temporary. */\r
596             BignumInt tmplo = a[i];\r
597             DIVMOD_WORD(q, r, h, tmplo, m0);\r
599             /* Refine our estimate of q by looking at\r
600              h:a[i]:a[i+1] / m0:m1 */\r
601             t = MUL_WORD(m1, q);\r
602             if (t > ((BignumDblInt) r << BIGNUM_INT_BITS) + ai1) {\r
603                 q--;\r
604                 t -= m1;\r
605                 r = (r + m0) & BIGNUM_INT_MASK;     /* overflow? */\r
606                 if (r >= (BignumDblInt) m0 &&\r
607                     t > ((BignumDblInt) r << BIGNUM_INT_BITS) + ai1) q--;\r
608             }\r
609         }\r
611         /* Subtract q * m from a[i...] */\r
612         c = 0;\r
613         for (k = mlen - 1; k >= 0; k--) {\r
614             t = MUL_WORD(q, m[k]);\r
615             t += c;\r
616             c = (BignumInt)(t >> BIGNUM_INT_BITS);\r
617             if ((BignumInt) t > a[i + k])\r
618                 c++;\r
619             a[i + k] -= (BignumInt) t;\r
620         }\r
622         /* Add back m in case of borrow */\r
623         if (c != h) {\r
624             t = 0;\r
625             for (k = mlen - 1; k >= 0; k--) {\r
626                 t += m[k];\r
627                 t += a[i + k];\r
628                 a[i + k] = (BignumInt) t;\r
629                 t = t >> BIGNUM_INT_BITS;\r
630             }\r
631             q--;\r
632         }\r
633         if (quot)\r
634             internal_add_shifted(quot, q, qshift + BIGNUM_INT_BITS * (alen - mlen - i));\r
635     }\r
638 /*\r
639  * Compute (base ^ exp) % mod, the pedestrian way.\r
640  */\r
641 Bignum modpow_simple(Bignum base_in, Bignum exp, Bignum mod)\r
643     BignumInt *a, *b, *n, *m, *scratch;\r
644     int mshift;\r
645     int mlen, scratchlen, i, j;\r
646     Bignum base, result;\r
648     /*\r
649      * The most significant word of mod needs to be non-zero. It\r
650      * should already be, but let's make sure.\r
651      */\r
652     assert(mod[mod[0]] != 0);\r
654     /*\r
655      * Make sure the base is smaller than the modulus, by reducing\r
656      * it modulo the modulus if not.\r
657      */\r
658     base = bigmod(base_in, mod);\r
660     /* Allocate m of size mlen, copy mod to m */\r
661     /* We use big endian internally */\r
662     mlen = mod[0];\r
663     m = snewn(mlen, BignumInt);\r
664     for (j = 0; j < mlen; j++)\r
665         m[j] = mod[mod[0] - j];\r
667     /* Shift m left to make msb bit set */\r
668     for (mshift = 0; mshift < BIGNUM_INT_BITS-1; mshift++)\r
669         if ((m[0] << mshift) & BIGNUM_TOP_BIT)\r
670             break;\r
671     if (mshift) {\r
672         for (i = 0; i < mlen - 1; i++)\r
673             m[i] = (m[i] << mshift) | (m[i + 1] >> (BIGNUM_INT_BITS - mshift));\r
674         m[mlen - 1] = m[mlen - 1] << mshift;\r
675     }\r
677     /* Allocate n of size mlen, copy base to n */\r
678     n = snewn(mlen, BignumInt);\r
679     i = mlen - base[0];\r
680     for (j = 0; j < i; j++)\r
681         n[j] = 0;\r
682     for (j = 0; j < (int)base[0]; j++)\r
683         n[i + j] = base[base[0] - j];\r
685     /* Allocate a and b of size 2*mlen. Set a = 1 */\r
686     a = snewn(2 * mlen, BignumInt);\r
687     b = snewn(2 * mlen, BignumInt);\r
688     for (i = 0; i < 2 * mlen; i++)\r
689         a[i] = 0;\r
690     a[2 * mlen - 1] = 1;\r
692     /* Scratch space for multiplies */\r
693     scratchlen = mul_compute_scratch(mlen);\r
694     scratch = snewn(scratchlen, BignumInt);\r
696     /* Skip leading zero bits of exp. */\r
697     i = 0;\r
698     j = BIGNUM_INT_BITS-1;\r
699     while (i < (int)exp[0] && (exp[exp[0] - i] & ((BignumInt)1 << j)) == 0) {\r
700         j--;\r
701         if (j < 0) {\r
702             i++;\r
703             j = BIGNUM_INT_BITS-1;\r
704         }\r
705     }\r
707     /* Main computation */\r
708     while (i < (int)exp[0]) {\r
709         while (j >= 0) {\r
710             internal_mul(a + mlen, a + mlen, b, mlen, scratch);\r
711             internal_mod(b, mlen * 2, m, mlen, NULL, 0);\r
712             if ((exp[exp[0] - i] & ((BignumInt)1 << j)) != 0) {\r
713                 internal_mul(b + mlen, n, a, mlen, scratch);\r
714                 internal_mod(a, mlen * 2, m, mlen, NULL, 0);\r
715             } else {\r
716                 BignumInt *t;\r
717                 t = a;\r
718                 a = b;\r
719                 b = t;\r
720             }\r
721             j--;\r
722         }\r
723         i++;\r
724         j = BIGNUM_INT_BITS-1;\r
725     }\r
727     /* Fixup result in case the modulus was shifted */\r
728     if (mshift) {\r
729         for (i = mlen - 1; i < 2 * mlen - 1; i++)\r
730             a[i] = (a[i] << mshift) | (a[i + 1] >> (BIGNUM_INT_BITS - mshift));\r
731         a[2 * mlen - 1] = a[2 * mlen - 1] << mshift;\r
732         internal_mod(a, mlen * 2, m, mlen, NULL, 0);\r
733         for (i = 2 * mlen - 1; i >= mlen; i--)\r
734             a[i] = (a[i] >> mshift) | (a[i - 1] << (BIGNUM_INT_BITS - mshift));\r
735     }\r
737     /* Copy result to buffer */\r
738     result = newbn(mod[0]);\r
739     for (i = 0; i < mlen; i++)\r
740         result[result[0] - i] = a[i + mlen];\r
741     while (result[0] > 1 && result[result[0]] == 0)\r
742         result[0]--;\r
744     /* Free temporary arrays */\r
745     smemclr(a, 2 * mlen * sizeof(*a));\r
746     sfree(a);\r
747     smemclr(scratch, scratchlen * sizeof(*scratch));\r
748     sfree(scratch);\r
749     smemclr(b, 2 * mlen * sizeof(*b));\r
750     sfree(b);\r
751     smemclr(m, mlen * sizeof(*m));\r
752     sfree(m);\r
753     smemclr(n, mlen * sizeof(*n));\r
754     sfree(n);\r
756     freebn(base);\r
758     return result;\r
761 /*\r
762  * Compute (base ^ exp) % mod. Uses the Montgomery multiplication\r
763  * technique where possible, falling back to modpow_simple otherwise.\r
764  */\r
765 Bignum modpow(Bignum base_in, Bignum exp, Bignum mod)\r
767     BignumInt *a, *b, *x, *n, *mninv, *scratch;\r
768     int len, scratchlen, i, j;\r
769     Bignum base, base2, r, rn, inv, result;\r
771     /*\r
772      * The most significant word of mod needs to be non-zero. It\r
773      * should already be, but let's make sure.\r
774      */\r
775     assert(mod[mod[0]] != 0);\r
777     /*\r
778      * mod had better be odd, or we can't do Montgomery multiplication\r
779      * using a power of two at all.\r
780      */\r
781     if (!(mod[1] & 1))\r
782         return modpow_simple(base_in, exp, mod);\r
784     /*\r
785      * Make sure the base is smaller than the modulus, by reducing\r
786      * it modulo the modulus if not.\r
787      */\r
788     base = bigmod(base_in, mod);\r
790     /*\r
791      * Compute the inverse of n mod r, for monty_reduce. (In fact we\r
792      * want the inverse of _minus_ n mod r, but we'll sort that out\r
793      * below.)\r
794      */\r
795     len = mod[0];\r
796     r = bn_power_2(BIGNUM_INT_BITS * len);\r
797     inv = modinv(mod, r);\r
798     assert(inv); /* cannot fail, since mod is odd and r is a power of 2 */\r
800     /*\r
801      * Multiply the base by r mod n, to get it into Montgomery\r
802      * representation.\r
803      */\r
804     base2 = modmul(base, r, mod);\r
805     freebn(base);\r
806     base = base2;\r
808     rn = bigmod(r, mod);               /* r mod n, i.e. Montgomerified 1 */\r
810     freebn(r);                         /* won't need this any more */\r
812     /*\r
813      * Set up internal arrays of the right lengths, in big-endian\r
814      * format, containing the base, the modulus, and the modulus's\r
815      * inverse.\r
816      */\r
817     n = snewn(len, BignumInt);\r
818     for (j = 0; j < len; j++)\r
819         n[len - 1 - j] = mod[j + 1];\r
821     mninv = snewn(len, BignumInt);\r
822     for (j = 0; j < len; j++)\r
823         mninv[len - 1 - j] = (j < (int)inv[0] ? inv[j + 1] : 0);\r
824     freebn(inv);         /* we don't need this copy of it any more */\r
825     /* Now negate mninv mod r, so it's the inverse of -n rather than +n. */\r
826     x = snewn(len, BignumInt);\r
827     for (j = 0; j < len; j++)\r
828         x[j] = 0;\r
829     internal_sub(x, mninv, mninv, len);\r
831     /* x = snewn(len, BignumInt); */ /* already done above */\r
832     for (j = 0; j < len; j++)\r
833         x[len - 1 - j] = (j < (int)base[0] ? base[j + 1] : 0);\r
834     freebn(base);        /* we don't need this copy of it any more */\r
836     a = snewn(2*len, BignumInt);\r
837     b = snewn(2*len, BignumInt);\r
838     for (j = 0; j < len; j++)\r
839         a[2*len - 1 - j] = (j < (int)rn[0] ? rn[j + 1] : 0);\r
840     freebn(rn);\r
842     /* Scratch space for multiplies */\r
843     scratchlen = 3*len + mul_compute_scratch(len);\r
844     scratch = snewn(scratchlen, BignumInt);\r
846     /* Skip leading zero bits of exp. */\r
847     i = 0;\r
848     j = BIGNUM_INT_BITS-1;\r
849     while (i < (int)exp[0] && (exp[exp[0] - i] & ((BignumInt)1 << j)) == 0) {\r
850         j--;\r
851         if (j < 0) {\r
852             i++;\r
853             j = BIGNUM_INT_BITS-1;\r
854         }\r
855     }\r
857     /* Main computation */\r
858     while (i < (int)exp[0]) {\r
859         while (j >= 0) {\r
860             internal_mul(a + len, a + len, b, len, scratch);\r
861             monty_reduce(b, n, mninv, scratch, len);\r
862             if ((exp[exp[0] - i] & ((BignumInt)1 << j)) != 0) {\r
863                 internal_mul(b + len, x, a, len,  scratch);\r
864                 monty_reduce(a, n, mninv, scratch, len);\r
865             } else {\r
866                 BignumInt *t;\r
867                 t = a;\r
868                 a = b;\r
869                 b = t;\r
870             }\r
871             j--;\r
872         }\r
873         i++;\r
874         j = BIGNUM_INT_BITS-1;\r
875     }\r
877     /*\r
878      * Final monty_reduce to get back from the adjusted Montgomery\r
879      * representation.\r
880      */\r
881     monty_reduce(a, n, mninv, scratch, len);\r
883     /* Copy result to buffer */\r
884     result = newbn(mod[0]);\r
885     for (i = 0; i < len; i++)\r
886         result[result[0] - i] = a[i + len];\r
887     while (result[0] > 1 && result[result[0]] == 0)\r
888         result[0]--;\r
890     /* Free temporary arrays */\r
891     smemclr(scratch, scratchlen * sizeof(*scratch));\r
892     sfree(scratch);\r
893     smemclr(a, 2 * len * sizeof(*a));\r
894     sfree(a);\r
895     smemclr(b, 2 * len * sizeof(*b));\r
896     sfree(b);\r
897     smemclr(mninv, len * sizeof(*mninv));\r
898     sfree(mninv);\r
899     smemclr(n, len * sizeof(*n));\r
900     sfree(n);\r
901     smemclr(x, len * sizeof(*x));\r
902     sfree(x);\r
904     return result;\r
907 /*\r
908  * Compute (p * q) % mod.\r
909  * The most significant word of mod MUST be non-zero.\r
910  * We assume that the result array is the same size as the mod array.\r
911  */\r
912 Bignum modmul(Bignum p, Bignum q, Bignum mod)\r
914     BignumInt *a, *n, *m, *o, *scratch;\r
915     int mshift, scratchlen;\r
916     int pqlen, mlen, rlen, i, j;\r
917     Bignum result;\r
919     /*\r
920      * The most significant word of mod needs to be non-zero. It\r
921      * should already be, but let's make sure.\r
922      */\r
923     assert(mod[mod[0]] != 0);\r
925     /* Allocate m of size mlen, copy mod to m */\r
926     /* We use big endian internally */\r
927     mlen = mod[0];\r
928     m = snewn(mlen, BignumInt);\r
929     for (j = 0; j < mlen; j++)\r
930         m[j] = mod[mod[0] - j];\r
932     /* Shift m left to make msb bit set */\r
933     for (mshift = 0; mshift < BIGNUM_INT_BITS-1; mshift++)\r
934         if ((m[0] << mshift) & BIGNUM_TOP_BIT)\r
935             break;\r
936     if (mshift) {\r
937         for (i = 0; i < mlen - 1; i++)\r
938             m[i] = (m[i] << mshift) | (m[i + 1] >> (BIGNUM_INT_BITS - mshift));\r
939         m[mlen - 1] = m[mlen - 1] << mshift;\r
940     }\r
942     pqlen = (p[0] > q[0] ? p[0] : q[0]);\r
944     /*\r
945      * Make sure that we're allowing enough space. The shifting below\r
946      * will underflow the vectors we allocate if pqlen is too small.\r
947      */\r
948     if (2*pqlen <= mlen)\r
949         pqlen = mlen/2 + 1;\r
951     /* Allocate n of size pqlen, copy p to n */\r
952     n = snewn(pqlen, BignumInt);\r
953     i = pqlen - p[0];\r
954     for (j = 0; j < i; j++)\r
955         n[j] = 0;\r
956     for (j = 0; j < (int)p[0]; j++)\r
957         n[i + j] = p[p[0] - j];\r
959     /* Allocate o of size pqlen, copy q to o */\r
960     o = snewn(pqlen, BignumInt);\r
961     i = pqlen - q[0];\r
962     for (j = 0; j < i; j++)\r
963         o[j] = 0;\r
964     for (j = 0; j < (int)q[0]; j++)\r
965         o[i + j] = q[q[0] - j];\r
967     /* Allocate a of size 2*pqlen for result */\r
968     a = snewn(2 * pqlen, BignumInt);\r
970     /* Scratch space for multiplies */\r
971     scratchlen = mul_compute_scratch(pqlen);\r
972     scratch = snewn(scratchlen, BignumInt);\r
974     /* Main computation */\r
975     internal_mul(n, o, a, pqlen, scratch);\r
976     internal_mod(a, pqlen * 2, m, mlen, NULL, 0);\r
978     /* Fixup result in case the modulus was shifted */\r
979     if (mshift) {\r
980         for (i = 2 * pqlen - mlen - 1; i < 2 * pqlen - 1; i++)\r
981             a[i] = (a[i] << mshift) | (a[i + 1] >> (BIGNUM_INT_BITS - mshift));\r
982         a[2 * pqlen - 1] = a[2 * pqlen - 1] << mshift;\r
983         internal_mod(a, pqlen * 2, m, mlen, NULL, 0);\r
984         for (i = 2 * pqlen - 1; i >= 2 * pqlen - mlen; i--)\r
985             a[i] = (a[i] >> mshift) | (a[i - 1] << (BIGNUM_INT_BITS - mshift));\r
986     }\r
988     /* Copy result to buffer */\r
989     rlen = (mlen < pqlen * 2 ? mlen : pqlen * 2);\r
990     result = newbn(rlen);\r
991     for (i = 0; i < rlen; i++)\r
992         result[result[0] - i] = a[i + 2 * pqlen - rlen];\r
993     while (result[0] > 1 && result[result[0]] == 0)\r
994         result[0]--;\r
996     /* Free temporary arrays */\r
997     smemclr(scratch, scratchlen * sizeof(*scratch));\r
998     sfree(scratch);\r
999     smemclr(a, 2 * pqlen * sizeof(*a));\r
1000     sfree(a);\r
1001     smemclr(m, mlen * sizeof(*m));\r
1002     sfree(m);\r
1003     smemclr(n, pqlen * sizeof(*n));\r
1004     sfree(n);\r
1005     smemclr(o, pqlen * sizeof(*o));\r
1006     sfree(o);\r
1008     return result;\r
1011 /*\r
1012  * Compute p % mod.\r
1013  * The most significant word of mod MUST be non-zero.\r
1014  * We assume that the result array is the same size as the mod array.\r
1015  * We optionally write out a quotient if `quotient' is non-NULL.\r
1016  * We can avoid writing out the result if `result' is NULL.\r
1017  */\r
1018 static void bigdivmod(Bignum p, Bignum mod, Bignum result, Bignum quotient)\r
1020     BignumInt *n, *m;\r
1021     int mshift;\r
1022     int plen, mlen, i, j;\r
1024     /*\r
1025      * The most significant word of mod needs to be non-zero. It\r
1026      * should already be, but let's make sure.\r
1027      */\r
1028     assert(mod[mod[0]] != 0);\r
1030     /* Allocate m of size mlen, copy mod to m */\r
1031     /* We use big endian internally */\r
1032     mlen = mod[0];\r
1033     m = snewn(mlen, BignumInt);\r
1034     for (j = 0; j < mlen; j++)\r
1035         m[j] = mod[mod[0] - j];\r
1037     /* Shift m left to make msb bit set */\r
1038     for (mshift = 0; mshift < BIGNUM_INT_BITS-1; mshift++)\r
1039         if ((m[0] << mshift) & BIGNUM_TOP_BIT)\r
1040             break;\r
1041     if (mshift) {\r
1042         for (i = 0; i < mlen - 1; i++)\r
1043             m[i] = (m[i] << mshift) | (m[i + 1] >> (BIGNUM_INT_BITS - mshift));\r
1044         m[mlen - 1] = m[mlen - 1] << mshift;\r
1045     }\r
1047     plen = p[0];\r
1048     /* Ensure plen > mlen */\r
1049     if (plen <= mlen)\r
1050         plen = mlen + 1;\r
1052     /* Allocate n of size plen, copy p to n */\r
1053     n = snewn(plen, BignumInt);\r
1054     for (j = 0; j < plen; j++)\r
1055         n[j] = 0;\r
1056     for (j = 1; j <= (int)p[0]; j++)\r
1057         n[plen - j] = p[j];\r
1059     /* Main computation */\r
1060     internal_mod(n, plen, m, mlen, quotient, mshift);\r
1062     /* Fixup result in case the modulus was shifted */\r
1063     if (mshift) {\r
1064         for (i = plen - mlen - 1; i < plen - 1; i++)\r
1065             n[i] = (n[i] << mshift) | (n[i + 1] >> (BIGNUM_INT_BITS - mshift));\r
1066         n[plen - 1] = n[plen - 1] << mshift;\r
1067         internal_mod(n, plen, m, mlen, quotient, 0);\r
1068         for (i = plen - 1; i >= plen - mlen; i--)\r
1069             n[i] = (n[i] >> mshift) | (n[i - 1] << (BIGNUM_INT_BITS - mshift));\r
1070     }\r
1072     /* Copy result to buffer */\r
1073     if (result) {\r
1074         for (i = 1; i <= (int)result[0]; i++) {\r
1075             int j = plen - i;\r
1076             result[i] = j >= 0 ? n[j] : 0;\r
1077         }\r
1078     }\r
1080     /* Free temporary arrays */\r
1081     smemclr(m, mlen * sizeof(*m));\r
1082     sfree(m);\r
1083     smemclr(n, plen * sizeof(*n));\r
1084     sfree(n);\r
1087 /*\r
1088  * Decrement a number.\r
1089  */\r
1090 void decbn(Bignum bn)\r
1092     int i = 1;\r
1093     while (i < (int)bn[0] && bn[i] == 0)\r
1094         bn[i++] = BIGNUM_INT_MASK;\r
1095     bn[i]--;\r
1098 Bignum bignum_from_bytes(const unsigned char *data, int nbytes)\r
1100     Bignum result;\r
1101     int w, i;\r
1103     assert(nbytes >= 0 && nbytes < INT_MAX/8);\r
1105     w = (nbytes + BIGNUM_INT_BYTES - 1) / BIGNUM_INT_BYTES; /* bytes->words */\r
1107     result = newbn(w);\r
1108     for (i = 1; i <= w; i++)\r
1109         result[i] = 0;\r
1110     for (i = nbytes; i--;) {\r
1111         unsigned char byte = *data++;\r
1112         result[1 + i / BIGNUM_INT_BYTES] |=\r
1113             (BignumInt)byte << (8*i % BIGNUM_INT_BITS);\r
1114     }\r
1116     while (result[0] > 1 && result[result[0]] == 0)\r
1117         result[0]--;\r
1118     return result;\r
1121 /*\r
1122  * Read an SSH-1-format bignum from a data buffer. Return the number\r
1123  * of bytes consumed, or -1 if there wasn't enough data.\r
1124  */\r
1125 int ssh1_read_bignum(const unsigned char *data, int len, Bignum * result)\r
1127     const unsigned char *p = data;\r
1128     int i;\r
1129     int w, b;\r
1131     if (len < 2)\r
1132         return -1;\r
1134     w = 0;\r
1135     for (i = 0; i < 2; i++)\r
1136         w = (w << 8) + *p++;\r
1137     b = (w + 7) / 8;                   /* bits -> bytes */\r
1139     if (len < b+2)\r
1140         return -1;\r
1142     if (!result)                       /* just return length */\r
1143         return b + 2;\r
1145     *result = bignum_from_bytes(p, b);\r
1147     return p + b - data;\r
1150 /*\r
1151  * Return the bit count of a bignum, for SSH-1 encoding.\r
1152  */\r
1153 int bignum_bitcount(Bignum bn)\r
1155     int bitcount = bn[0] * BIGNUM_INT_BITS - 1;\r
1156     while (bitcount >= 0\r
1157            && (bn[bitcount / BIGNUM_INT_BITS + 1] >> (bitcount % BIGNUM_INT_BITS)) == 0) bitcount--;\r
1158     return bitcount + 1;\r
1161 /*\r
1162  * Return the byte length of a bignum when SSH-1 encoded.\r
1163  */\r
1164 int ssh1_bignum_length(Bignum bn)\r
1166     return 2 + (bignum_bitcount(bn) + 7) / 8;\r
1169 /*\r
1170  * Return the byte length of a bignum when SSH-2 encoded.\r
1171  */\r
1172 int ssh2_bignum_length(Bignum bn)\r
1174     return 4 + (bignum_bitcount(bn) + 8) / 8;\r
1177 /*\r
1178  * Return a byte from a bignum; 0 is least significant, etc.\r
1179  */\r
1180 int bignum_byte(Bignum bn, int i)\r
1182     if (i < 0 || i >= (int)(BIGNUM_INT_BYTES * bn[0]))\r
1183         return 0;                      /* beyond the end */\r
1184     else\r
1185         return (bn[i / BIGNUM_INT_BYTES + 1] >>\r
1186                 ((i % BIGNUM_INT_BYTES)*8)) & 0xFF;\r
1189 /*\r
1190  * Return a bit from a bignum; 0 is least significant, etc.\r
1191  */\r
1192 int bignum_bit(Bignum bn, int i)\r
1194     if (i < 0 || i >= (int)(BIGNUM_INT_BITS * bn[0]))\r
1195         return 0;                      /* beyond the end */\r
1196     else\r
1197         return (bn[i / BIGNUM_INT_BITS + 1] >> (i % BIGNUM_INT_BITS)) & 1;\r
1200 /*\r
1201  * Set a bit in a bignum; 0 is least significant, etc.\r
1202  */\r
1203 void bignum_set_bit(Bignum bn, int bitnum, int value)\r
1205     if (bitnum < 0 || bitnum >= (int)(BIGNUM_INT_BITS * bn[0]))\r
1206         abort();                       /* beyond the end */\r
1207     else {\r
1208         int v = bitnum / BIGNUM_INT_BITS + 1;\r
1209         BignumInt mask = (BignumInt)1 << (bitnum % BIGNUM_INT_BITS);\r
1210         if (value)\r
1211             bn[v] |= mask;\r
1212         else\r
1213             bn[v] &= ~mask;\r
1214     }\r
1217 /*\r
1218  * Write a SSH-1-format bignum into a buffer. It is assumed the\r
1219  * buffer is big enough. Returns the number of bytes used.\r
1220  */\r
1221 int ssh1_write_bignum(void *data, Bignum bn)\r
1223     unsigned char *p = data;\r
1224     int len = ssh1_bignum_length(bn);\r
1225     int i;\r
1226     int bitc = bignum_bitcount(bn);\r
1228     *p++ = (bitc >> 8) & 0xFF;\r
1229     *p++ = (bitc) & 0xFF;\r
1230     for (i = len - 2; i--;)\r
1231         *p++ = bignum_byte(bn, i);\r
1232     return len;\r
1235 /*\r
1236  * Compare two bignums. Returns like strcmp.\r
1237  */\r
1238 int bignum_cmp(Bignum a, Bignum b)\r
1240     int amax = a[0], bmax = b[0];\r
1241     int i;\r
1243     /* Annoyingly we have two representations of zero */\r
1244     if (amax == 1 && a[amax] == 0)\r
1245         amax = 0;\r
1246     if (bmax == 1 && b[bmax] == 0)\r
1247         bmax = 0;\r
1249     assert(amax == 0 || a[amax] != 0);\r
1250     assert(bmax == 0 || b[bmax] != 0);\r
1252     i = (amax > bmax ? amax : bmax);\r
1253     while (i) {\r
1254         BignumInt aval = (i > amax ? 0 : a[i]);\r
1255         BignumInt bval = (i > bmax ? 0 : b[i]);\r
1256         if (aval < bval)\r
1257             return -1;\r
1258         if (aval > bval)\r
1259             return +1;\r
1260         i--;\r
1261     }\r
1262     return 0;\r
1265 /*\r
1266  * Right-shift one bignum to form another.\r
1267  */\r
1268 Bignum bignum_rshift(Bignum a, int shift)\r
1270     Bignum ret;\r
1271     int i, shiftw, shiftb, shiftbb, bits;\r
1272     BignumInt ai, ai1;\r
1274     assert(shift >= 0);\r
1276     bits = bignum_bitcount(a) - shift;\r
1277     ret = newbn((bits + BIGNUM_INT_BITS - 1) / BIGNUM_INT_BITS);\r
1279     if (ret) {\r
1280         shiftw = shift / BIGNUM_INT_BITS;\r
1281         shiftb = shift % BIGNUM_INT_BITS;\r
1282         shiftbb = BIGNUM_INT_BITS - shiftb;\r
1284         ai1 = a[shiftw + 1];\r
1285         for (i = 1; i <= (int)ret[0]; i++) {\r
1286             ai = ai1;\r
1287             ai1 = (i + shiftw + 1 <= (int)a[0] ? a[i + shiftw + 1] : 0);\r
1288             ret[i] = ((ai >> shiftb) | (ai1 << shiftbb)) & BIGNUM_INT_MASK;\r
1289         }\r
1290     }\r
1292     return ret;\r
1295 /*\r
1296  * Non-modular multiplication and addition.\r
1297  */\r
1298 Bignum bigmuladd(Bignum a, Bignum b, Bignum addend)\r
1300     int alen = a[0], blen = b[0];\r
1301     int mlen = (alen > blen ? alen : blen);\r
1302     int rlen, i, maxspot;\r
1303     int wslen;\r
1304     BignumInt *workspace;\r
1305     Bignum ret;\r
1307     /* mlen space for a, mlen space for b, 2*mlen for result,\r
1308      * plus scratch space for multiplication */\r
1309     wslen = mlen * 4 + mul_compute_scratch(mlen);\r
1310     workspace = snewn(wslen, BignumInt);\r
1311     for (i = 0; i < mlen; i++) {\r
1312         workspace[0 * mlen + i] = (mlen - i <= (int)a[0] ? a[mlen - i] : 0);\r
1313         workspace[1 * mlen + i] = (mlen - i <= (int)b[0] ? b[mlen - i] : 0);\r
1314     }\r
1316     internal_mul(workspace + 0 * mlen, workspace + 1 * mlen,\r
1317                  workspace + 2 * mlen, mlen, workspace + 4 * mlen);\r
1319     /* now just copy the result back */\r
1320     rlen = alen + blen + 1;\r
1321     if (addend && rlen <= (int)addend[0])\r
1322         rlen = addend[0] + 1;\r
1323     ret = newbn(rlen);\r
1324     maxspot = 0;\r
1325     for (i = 1; i <= (int)ret[0]; i++) {\r
1326         ret[i] = (i <= 2 * mlen ? workspace[4 * mlen - i] : 0);\r
1327         if (ret[i] != 0)\r
1328             maxspot = i;\r
1329     }\r
1330     ret[0] = maxspot;\r
1332     /* now add in the addend, if any */\r
1333     if (addend) {\r
1334         BignumDblInt carry = 0;\r
1335         for (i = 1; i <= rlen; i++) {\r
1336             carry += (i <= (int)ret[0] ? ret[i] : 0);\r
1337             carry += (i <= (int)addend[0] ? addend[i] : 0);\r
1338             ret[i] = (BignumInt) carry & BIGNUM_INT_MASK;\r
1339             carry >>= BIGNUM_INT_BITS;\r
1340             if (ret[i] != 0 && i > maxspot)\r
1341                 maxspot = i;\r
1342         }\r
1343     }\r
1344     ret[0] = maxspot;\r
1346     smemclr(workspace, wslen * sizeof(*workspace));\r
1347     sfree(workspace);\r
1348     return ret;\r
1351 /*\r
1352  * Non-modular multiplication.\r
1353  */\r
1354 Bignum bigmul(Bignum a, Bignum b)\r
1356     return bigmuladd(a, b, NULL);\r
1359 /*\r
1360  * Simple addition.\r
1361  */\r
1362 Bignum bigadd(Bignum a, Bignum b)\r
1364     int alen = a[0], blen = b[0];\r
1365     int rlen = (alen > blen ? alen : blen) + 1;\r
1366     int i, maxspot;\r
1367     Bignum ret;\r
1368     BignumDblInt carry;\r
1370     ret = newbn(rlen);\r
1372     carry = 0;\r
1373     maxspot = 0;\r
1374     for (i = 1; i <= rlen; i++) {\r
1375         carry += (i <= (int)a[0] ? a[i] : 0);\r
1376         carry += (i <= (int)b[0] ? b[i] : 0);\r
1377         ret[i] = (BignumInt) carry & BIGNUM_INT_MASK;\r
1378         carry >>= BIGNUM_INT_BITS;\r
1379         if (ret[i] != 0 && i > maxspot)\r
1380             maxspot = i;\r
1381     }\r
1382     ret[0] = maxspot;\r
1384     return ret;\r
1387 /*\r
1388  * Subtraction. Returns a-b, or NULL if the result would come out\r
1389  * negative (recall that this entire bignum module only handles\r
1390  * positive numbers).\r
1391  */\r
1392 Bignum bigsub(Bignum a, Bignum b)\r
1394     int alen = a[0], blen = b[0];\r
1395     int rlen = (alen > blen ? alen : blen);\r
1396     int i, maxspot;\r
1397     Bignum ret;\r
1398     BignumDblInt carry;\r
1400     ret = newbn(rlen);\r
1402     carry = 1;\r
1403     maxspot = 0;\r
1404     for (i = 1; i <= rlen; i++) {\r
1405         carry += (i <= (int)a[0] ? a[i] : 0);\r
1406         carry += (i <= (int)b[0] ? b[i] ^ BIGNUM_INT_MASK : BIGNUM_INT_MASK);\r
1407         ret[i] = (BignumInt) carry & BIGNUM_INT_MASK;\r
1408         carry >>= BIGNUM_INT_BITS;\r
1409         if (ret[i] != 0 && i > maxspot)\r
1410             maxspot = i;\r
1411     }\r
1412     ret[0] = maxspot;\r
1414     if (!carry) {\r
1415         freebn(ret);\r
1416         return NULL;\r
1417     }\r
1419     return ret;\r
1422 /*\r
1423  * Create a bignum which is the bitmask covering another one. That\r
1424  * is, the smallest integer which is >= N and is also one less than\r
1425  * a power of two.\r
1426  */\r
1427 Bignum bignum_bitmask(Bignum n)\r
1429     Bignum ret = copybn(n);\r
1430     int i;\r
1431     BignumInt j;\r
1433     i = ret[0];\r
1434     while (n[i] == 0 && i > 0)\r
1435         i--;\r
1436     if (i <= 0)\r
1437         return ret;                    /* input was zero */\r
1438     j = 1;\r
1439     while (j < n[i])\r
1440         j = 2 * j + 1;\r
1441     ret[i] = j;\r
1442     while (--i > 0)\r
1443         ret[i] = BIGNUM_INT_MASK;\r
1444     return ret;\r
1447 /*\r
1448  * Convert a (max 32-bit) long into a bignum.\r
1449  */\r
1450 Bignum bignum_from_long(unsigned long nn)\r
1452     Bignum ret;\r
1453     BignumDblInt n = nn;\r
1455     ret = newbn(3);\r
1456     ret[1] = (BignumInt)(n & BIGNUM_INT_MASK);\r
1457     ret[2] = (BignumInt)((n >> BIGNUM_INT_BITS) & BIGNUM_INT_MASK);\r
1458     ret[3] = 0;\r
1459     ret[0] = (ret[2]  ? 2 : 1);\r
1460     return ret;\r
1463 /*\r
1464  * Add a long to a bignum.\r
1465  */\r
1466 Bignum bignum_add_long(Bignum number, unsigned long addendx)\r
1468     Bignum ret = newbn(number[0] + 1);\r
1469     int i, maxspot = 0;\r
1470     BignumDblInt carry = 0, addend = addendx;\r
1472     for (i = 1; i <= (int)ret[0]; i++) {\r
1473         carry += addend & BIGNUM_INT_MASK;\r
1474         carry += (i <= (int)number[0] ? number[i] : 0);\r
1475         addend >>= BIGNUM_INT_BITS;\r
1476         ret[i] = (BignumInt) carry & BIGNUM_INT_MASK;\r
1477         carry >>= BIGNUM_INT_BITS;\r
1478         if (ret[i] != 0)\r
1479             maxspot = i;\r
1480     }\r
1481     ret[0] = maxspot;\r
1482     return ret;\r
1485 /*\r
1486  * Compute the residue of a bignum, modulo a (max 16-bit) short.\r
1487  */\r
1488 unsigned short bignum_mod_short(Bignum number, unsigned short modulus)\r
1490     BignumDblInt mod, r;\r
1491     int i;\r
1493     r = 0;\r
1494     mod = modulus;\r
1495     for (i = number[0]; i > 0; i--)\r
1496         r = (r * (BIGNUM_TOP_BIT % mod) * 2 + number[i] % mod) % mod;\r
1497     return (unsigned short) r;\r
1500 #ifdef DEBUG\r
1501 void diagbn(char *prefix, Bignum md)\r
1503     int i, nibbles, morenibbles;\r
1504     static const char hex[] = "0123456789ABCDEF";\r
1506     debug(("%s0x", prefix ? prefix : ""));\r
1508     nibbles = (3 + bignum_bitcount(md)) / 4;\r
1509     if (nibbles < 1)\r
1510         nibbles = 1;\r
1511     morenibbles = 4 * md[0] - nibbles;\r
1512     for (i = 0; i < morenibbles; i++)\r
1513         debug(("-"));\r
1514     for (i = nibbles; i--;)\r
1515         debug(("%c",\r
1516                hex[(bignum_byte(md, i / 2) >> (4 * (i % 2))) & 0xF]));\r
1518     if (prefix)\r
1519         debug(("\n"));\r
1521 #endif\r
1523 /*\r
1524  * Simple division.\r
1525  */\r
1526 Bignum bigdiv(Bignum a, Bignum b)\r
1528     Bignum q = newbn(a[0]);\r
1529     bigdivmod(a, b, NULL, q);\r
1530     while (q[0] > 1 && q[q[0]] == 0)\r
1531         q[0]--;\r
1532     return q;\r
1535 /*\r
1536  * Simple remainder.\r
1537  */\r
1538 Bignum bigmod(Bignum a, Bignum b)\r
1540     Bignum r = newbn(b[0]);\r
1541     bigdivmod(a, b, r, NULL);\r
1542     while (r[0] > 1 && r[r[0]] == 0)\r
1543         r[0]--;\r
1544     return r;\r
1547 /*\r
1548  * Greatest common divisor.\r
1549  */\r
1550 Bignum biggcd(Bignum av, Bignum bv)\r
1552     Bignum a = copybn(av);\r
1553     Bignum b = copybn(bv);\r
1555     while (bignum_cmp(b, Zero) != 0) {\r
1556         Bignum t = newbn(b[0]);\r
1557         bigdivmod(a, b, t, NULL);\r
1558         while (t[0] > 1 && t[t[0]] == 0)\r
1559             t[0]--;\r
1560         freebn(a);\r
1561         a = b;\r
1562         b = t;\r
1563     }\r
1565     freebn(b);\r
1566     return a;\r
1569 /*\r
1570  * Modular inverse, using Euclid's extended algorithm.\r
1571  */\r
1572 Bignum modinv(Bignum number, Bignum modulus)\r
1574     Bignum a = copybn(modulus);\r
1575     Bignum b = copybn(number);\r
1576     Bignum xp = copybn(Zero);\r
1577     Bignum x = copybn(One);\r
1578     int sign = +1;\r
1580     assert(number[number[0]] != 0);\r
1581     assert(modulus[modulus[0]] != 0);\r
1583     while (bignum_cmp(b, One) != 0) {\r
1584         Bignum t, q;\r
1586         if (bignum_cmp(b, Zero) == 0) {\r
1587             /*\r
1588              * Found a common factor between the inputs, so we cannot\r
1589              * return a modular inverse at all.\r
1590              */\r
1591             freebn(b);\r
1592             freebn(a);\r
1593             freebn(xp);\r
1594             freebn(x);\r
1595             return NULL;\r
1596         }\r
1598         t = newbn(b[0]);\r
1599         q = newbn(a[0]);\r
1600         bigdivmod(a, b, t, q);\r
1601         while (t[0] > 1 && t[t[0]] == 0)\r
1602             t[0]--;\r
1603         while (q[0] > 1 && q[q[0]] == 0)\r
1604             q[0]--;\r
1605         freebn(a);\r
1606         a = b;\r
1607         b = t;\r
1608         t = xp;\r
1609         xp = x;\r
1610         x = bigmuladd(q, xp, t);\r
1611         sign = -sign;\r
1612         freebn(t);\r
1613         freebn(q);\r
1614     }\r
1616     freebn(b);\r
1617     freebn(a);\r
1618     freebn(xp);\r
1620     /* now we know that sign * x == 1, and that x < modulus */\r
1621     if (sign < 0) {\r
1622         /* set a new x to be modulus - x */\r
1623         Bignum newx = newbn(modulus[0]);\r
1624         BignumInt carry = 0;\r
1625         int maxspot = 1;\r
1626         int i;\r
1628         for (i = 1; i <= (int)newx[0]; i++) {\r
1629             BignumInt aword = (i <= (int)modulus[0] ? modulus[i] : 0);\r
1630             BignumInt bword = (i <= (int)x[0] ? x[i] : 0);\r
1631             newx[i] = aword - bword - carry;\r
1632             bword = ~bword;\r
1633             carry = carry ? (newx[i] >= bword) : (newx[i] > bword);\r
1634             if (newx[i] != 0)\r
1635                 maxspot = i;\r
1636         }\r
1637         newx[0] = maxspot;\r
1638         freebn(x);\r
1639         x = newx;\r
1640     }\r
1642     /* and return. */\r
1643     return x;\r
1646 /*\r
1647  * Render a bignum into decimal. Return a malloced string holding\r
1648  * the decimal representation.\r
1649  */\r
1650 char *bignum_decimal(Bignum x)\r
1652     int ndigits, ndigit;\r
1653     int i, iszero;\r
1654     BignumDblInt carry;\r
1655     char *ret;\r
1656     BignumInt *workspace;\r
1658     /*\r
1659      * First, estimate the number of digits. Since log(10)/log(2)\r
1660      * is just greater than 93/28 (the joys of continued fraction\r
1661      * approximations...) we know that for every 93 bits, we need\r
1662      * at most 28 digits. This will tell us how much to malloc.\r
1663      *\r
1664      * Formally: if x has i bits, that means x is strictly less\r
1665      * than 2^i. Since 2 is less than 10^(28/93), this is less than\r
1666      * 10^(28i/93). We need an integer power of ten, so we must\r
1667      * round up (rounding down might make it less than x again).\r
1668      * Therefore if we multiply the bit count by 28/93, rounding\r
1669      * up, we will have enough digits.\r
1670      *\r
1671      * i=0 (i.e., x=0) is an irritating special case.\r
1672      */\r
1673     i = bignum_bitcount(x);\r
1674     if (!i)\r
1675         ndigits = 1;                   /* x = 0 */\r
1676     else\r
1677         ndigits = (28 * i + 92) / 93;  /* multiply by 28/93 and round up */\r
1678     ndigits++;                         /* allow for trailing \0 */\r
1679     ret = snewn(ndigits, char);\r
1681     /*\r
1682      * Now allocate some workspace to hold the binary form as we\r
1683      * repeatedly divide it by ten. Initialise this to the\r
1684      * big-endian form of the number.\r
1685      */\r
1686     workspace = snewn(x[0], BignumInt);\r
1687     for (i = 0; i < (int)x[0]; i++)\r
1688         workspace[i] = x[x[0] - i];\r
1690     /*\r
1691      * Next, write the decimal number starting with the last digit.\r
1692      * We use ordinary short division, dividing 10 into the\r
1693      * workspace.\r
1694      */\r
1695     ndigit = ndigits - 1;\r
1696     ret[ndigit] = '\0';\r
1697     do {\r
1698         iszero = 1;\r
1699         carry = 0;\r
1700         for (i = 0; i < (int)x[0]; i++) {\r
1701             carry = (carry << BIGNUM_INT_BITS) + workspace[i];\r
1702             workspace[i] = (BignumInt) (carry / 10);\r
1703             if (workspace[i])\r
1704                 iszero = 0;\r
1705             carry %= 10;\r
1706         }\r
1707         ret[--ndigit] = (char) (carry + '0');\r
1708     } while (!iszero);\r
1710     /*\r
1711      * There's a chance we've fallen short of the start of the\r
1712      * string. Correct if so.\r
1713      */\r
1714     if (ndigit > 0)\r
1715         memmove(ret, ret + ndigit, ndigits - ndigit);\r
1717     /*\r
1718      * Done.\r
1719      */\r
1720     smemclr(workspace, x[0] * sizeof(*workspace));\r
1721     sfree(workspace);\r
1722     return ret;\r
1725 #ifdef TESTBN\r
1727 #include <stdio.h>\r
1728 #include <stdlib.h>\r
1729 #include <ctype.h>\r
1731 /*\r
1732  * gcc -Wall -g -O0 -DTESTBN -o testbn sshbn.c misc.c conf.c tree234.c unix/uxmisc.c -I. -I unix -I charset\r
1733  *\r
1734  * Then feed to this program's standard input the output of\r
1735  * testdata/bignum.py .\r
1736  */\r
1738 void modalfatalbox(char *p, ...)\r
1740     va_list ap;\r
1741     fprintf(stderr, "FATAL ERROR: ");\r
1742     va_start(ap, p);\r
1743     vfprintf(stderr, p, ap);\r
1744     va_end(ap);\r
1745     fputc('\n', stderr);\r
1746     exit(1);\r
1749 int random_byte(void)\r
1751     modalfatalbox("random_byte called in testbn");\r
1752     return 0;\r
1755 #define fromxdigit(c) ( (c)>'9' ? ((c)&0xDF) - 'A' + 10 : (c) - '0' )\r
1757 int main(int argc, char **argv)\r
1759     char *buf;\r
1760     int line = 0;\r
1761     int passes = 0, fails = 0;\r
1763     while ((buf = fgetline(stdin)) != NULL) {\r
1764         int maxlen = strlen(buf);\r
1765         unsigned char *data = snewn(maxlen, unsigned char);\r
1766         unsigned char *ptrs[5], *q;\r
1767         int ptrnum;\r
1768         char *bufp = buf;\r
1770         line++;\r
1772         q = data;\r
1773         ptrnum = 0;\r
1775         while (*bufp && !isspace((unsigned char)*bufp))\r
1776             bufp++;\r
1777         if (bufp)\r
1778             *bufp++ = '\0';\r
1780         while (*bufp) {\r
1781             char *start, *end;\r
1782             int i;\r
1784             while (*bufp && !isxdigit((unsigned char)*bufp))\r
1785                 bufp++;\r
1786             start = bufp;\r
1788             if (!*bufp)\r
1789                 break;\r
1791             while (*bufp && isxdigit((unsigned char)*bufp))\r
1792                 bufp++;\r
1793             end = bufp;\r
1795             if (ptrnum >= lenof(ptrs))\r
1796                 break;\r
1797             ptrs[ptrnum++] = q;\r
1798             \r
1799             for (i = -((end - start) & 1); i < end-start; i += 2) {\r
1800                 unsigned char val = (i < 0 ? 0 : fromxdigit(start[i]));\r
1801                 val = val * 16 + fromxdigit(start[i+1]);\r
1802                 *q++ = val;\r
1803             }\r
1805             ptrs[ptrnum] = q;\r
1806         }\r
1808         if (!strcmp(buf, "mul")) {\r
1809             Bignum a, b, c, p;\r
1811             if (ptrnum != 3) {\r
1812                 printf("%d: mul with %d parameters, expected 3\n", line, ptrnum);\r
1813                 exit(1);\r
1814             }\r
1815             a = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]);\r
1816             b = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]);\r
1817             c = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]);\r
1818             p = bigmul(a, b);\r
1820             if (bignum_cmp(c, p) == 0) {\r
1821                 passes++;\r
1822             } else {\r
1823                 char *as = bignum_decimal(a);\r
1824                 char *bs = bignum_decimal(b);\r
1825                 char *cs = bignum_decimal(c);\r
1826                 char *ps = bignum_decimal(p);\r
1827                 \r
1828                 printf("%d: fail: %s * %s gave %s expected %s\n",\r
1829                        line, as, bs, ps, cs);\r
1830                 fails++;\r
1832                 sfree(as);\r
1833                 sfree(bs);\r
1834                 sfree(cs);\r
1835                 sfree(ps);\r
1836             }\r
1837             freebn(a);\r
1838             freebn(b);\r
1839             freebn(c);\r
1840             freebn(p);\r
1841         } else if (!strcmp(buf, "modmul")) {\r
1842             Bignum a, b, m, c, p;\r
1844             if (ptrnum != 4) {\r
1845                 printf("%d: modmul with %d parameters, expected 4\n",\r
1846                        line, ptrnum);\r
1847                 exit(1);\r
1848             }\r
1849             a = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]);\r
1850             b = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]);\r
1851             m = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]);\r
1852             c = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]);\r
1853             p = modmul(a, b, m);\r
1855             if (bignum_cmp(c, p) == 0) {\r
1856                 passes++;\r
1857             } else {\r
1858                 char *as = bignum_decimal(a);\r
1859                 char *bs = bignum_decimal(b);\r
1860                 char *ms = bignum_decimal(m);\r
1861                 char *cs = bignum_decimal(c);\r
1862                 char *ps = bignum_decimal(p);\r
1863                 \r
1864                 printf("%d: fail: %s * %s mod %s gave %s expected %s\n",\r
1865                        line, as, bs, ms, ps, cs);\r
1866                 fails++;\r
1868                 sfree(as);\r
1869                 sfree(bs);\r
1870                 sfree(ms);\r
1871                 sfree(cs);\r
1872                 sfree(ps);\r
1873             }\r
1874             freebn(a);\r
1875             freebn(b);\r
1876             freebn(m);\r
1877             freebn(c);\r
1878             freebn(p);\r
1879         } else if (!strcmp(buf, "pow")) {\r
1880             Bignum base, expt, modulus, expected, answer;\r
1882             if (ptrnum != 4) {\r
1883                 printf("%d: mul with %d parameters, expected 4\n", line, ptrnum);\r
1884                 exit(1);\r
1885             }\r
1887             base = bignum_from_bytes(ptrs[0], ptrs[1]-ptrs[0]);\r
1888             expt = bignum_from_bytes(ptrs[1], ptrs[2]-ptrs[1]);\r
1889             modulus = bignum_from_bytes(ptrs[2], ptrs[3]-ptrs[2]);\r
1890             expected = bignum_from_bytes(ptrs[3], ptrs[4]-ptrs[3]);\r
1891             answer = modpow(base, expt, modulus);\r
1893             if (bignum_cmp(expected, answer) == 0) {\r
1894                 passes++;\r
1895             } else {\r
1896                 char *as = bignum_decimal(base);\r
1897                 char *bs = bignum_decimal(expt);\r
1898                 char *cs = bignum_decimal(modulus);\r
1899                 char *ds = bignum_decimal(answer);\r
1900                 char *ps = bignum_decimal(expected);\r
1901                 \r
1902                 printf("%d: fail: %s ^ %s mod %s gave %s expected %s\n",\r
1903                        line, as, bs, cs, ds, ps);\r
1904                 fails++;\r
1906                 sfree(as);\r
1907                 sfree(bs);\r
1908                 sfree(cs);\r
1909                 sfree(ds);\r
1910                 sfree(ps);\r
1911             }\r
1912             freebn(base);\r
1913             freebn(expt);\r
1914             freebn(modulus);\r
1915             freebn(expected);\r
1916             freebn(answer);\r
1917         } else {\r
1918             printf("%d: unrecognised test keyword: '%s'\n", line, buf);\r
1919             exit(1);\r
1920         }\r
1922         sfree(buf);\r
1923         sfree(data);\r
1924     }\r
1926     printf("passed %d failed %d total %d\n", passes, fails, passes+fails);\r
1927     return fails != 0;\r
1930 #endif\r