- for (i = 1; i < k; i++) {
- mp *d = mp_mul(x, n, v[i].m);
- x = n;
- n = d;
+ for (i = 1; i < k; i++)
+ n = mp_mul(n, n, v[i].m);
+ }
+
+ /* --- A quick hack if %$k = 2$% --- */
+
+ if (k == 2) {
+
+ /* --- The %$n / n_i$% values are trivial in this case --- */
+
+ if (!v[0].n)
+ v[0].n = MP_COPY(v[1].m);
+ if (!v[1].n)
+ v[1].n = MP_COPY(v[0].m);
+
+ /* --- Now sort out the inverses --- *
+ *
+ * @mp_gcd@ will ensure that the first argument is negative.
+ */
+
+ if (!v[0].ni && !v[1].ni) {
+ mp_gcd(0, &v[0].ni, &v[1].ni, v[0].n, v[1].n);
+ v[0].ni = mp_add(v[0].ni, v[0].ni, v[1].n);
+ } else {
+ int i, j;
+ mp *x;
+
+ if (!v[0].ni)
+ i = 0, j = 1;
+ else
+ i = 1, j = 0;
+
+ x = mp_mul(MP_NEW, v[j].n, v[j].ni);
+ x = mp_sub(x, x, MP_ONE);
+ mp_div(&x, 0, x, v[i].n);
+ v[i].ni = x;