]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - sshccp.c
first pass
[PuTTY.git] / sshccp.c
index df973e63d788abe6af3326edd04ba0c74f0c7d50..d0a617752322d6556f058fdfdd404fb058b7915e 100644 (file)
--- a/sshccp.c
+++ b/sshccp.c
@@ -198,7 +198,8 @@ static void bigval_import_le(bigval *r, const void *vdata, int len)
     int i;
     bigval_clear(r);
     for (i = 0; i < len; i++)
-        r->w[i / BIGNUM_INT_BYTES] |= data[i] << (8 * (i % BIGNUM_INT_BYTES));
+        r->w[i / BIGNUM_INT_BYTES] |=
+            (BignumInt)data[i] << (8 * (i % BIGNUM_INT_BYTES));
 }
 
 static void bigval_export_le(const bigval *r, void *vdata, int len)
@@ -210,700 +211,527 @@ static void bigval_export_le(const bigval *r, void *vdata, int len)
 }
 
 /*
- * Addition of bigvals, not mod p.
+ * Core functions to do arithmetic mod p = 2^130-5. The whole
+ * collection of these, up to and including the surrounding #if, are
+ * generated automatically for various sizes of BignumInt by
+ * contrib/make1305.py.
  */
+
+#if BIGNUM_INT_BITS == 16
+
 static void bigval_add(bigval *r, const bigval *a, const bigval *b)
 {
-#if BIGNUM_INT_BITS == 32
-    /* ./contrib/make1305.py add 32 */
-    BignumDblInt acclo;
-    acclo = 0;
-    acclo += a->w[0];
-    acclo += b->w[0];
-    r->w[0] = acclo;
-    acclo >>= 32;
-    acclo += a->w[1];
-    acclo += b->w[1];
-    r->w[1] = acclo;
-    acclo >>= 32;
-    acclo += a->w[2];
-    acclo += b->w[2];
-    r->w[2] = acclo;
-    acclo >>= 32;
-    acclo += a->w[3];
-    acclo += b->w[3];
-    r->w[3] = acclo;
-    acclo >>= 32;
-    acclo += a->w[4];
-    acclo += b->w[4];
-    r->w[4] = acclo;
-    acclo >>= 32;
-#elif BIGNUM_INT_BITS == 16
-    /* ./contrib/make1305.py add 16 */
-    BignumDblInt acclo;
-    acclo = 0;
-    acclo += a->w[0];
-    acclo += b->w[0];
-    r->w[0] = acclo;
-    acclo >>= 16;
-    acclo += a->w[1];
-    acclo += b->w[1];
-    r->w[1] = acclo;
-    acclo >>= 16;
-    acclo += a->w[2];
-    acclo += b->w[2];
-    r->w[2] = acclo;
-    acclo >>= 16;
-    acclo += a->w[3];
-    acclo += b->w[3];
-    r->w[3] = acclo;
-    acclo >>= 16;
-    acclo += a->w[4];
-    acclo += b->w[4];
-    r->w[4] = acclo;
-    acclo >>= 16;
-    acclo += a->w[5];
-    acclo += b->w[5];
-    r->w[5] = acclo;
-    acclo >>= 16;
-    acclo += a->w[6];
-    acclo += b->w[6];
-    r->w[6] = acclo;
-    acclo >>= 16;
-    acclo += a->w[7];
-    acclo += b->w[7];
-    r->w[7] = acclo;
-    acclo >>= 16;
-    acclo += a->w[8];
-    acclo += b->w[8];
-    r->w[8] = acclo;
-    acclo >>= 16;
-#else
-#error Run contrib/make1305.py again with a different bit count
-#endif
+    BignumInt v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14;
+    BignumInt v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26;
+    BignumCarry carry;
+
+    v0 = a->w[0];
+    v1 = a->w[1];
+    v2 = a->w[2];
+    v3 = a->w[3];
+    v4 = a->w[4];
+    v5 = a->w[5];
+    v6 = a->w[6];
+    v7 = a->w[7];
+    v8 = a->w[8];
+    v9 = b->w[0];
+    v10 = b->w[1];
+    v11 = b->w[2];
+    v12 = b->w[3];
+    v13 = b->w[4];
+    v14 = b->w[5];
+    v15 = b->w[6];
+    v16 = b->w[7];
+    v17 = b->w[8];
+    BignumADC(v18, carry, v0, v9, 0);
+    BignumADC(v19, carry, v1, v10, carry);
+    BignumADC(v20, carry, v2, v11, carry);
+    BignumADC(v21, carry, v3, v12, carry);
+    BignumADC(v22, carry, v4, v13, carry);
+    BignumADC(v23, carry, v5, v14, carry);
+    BignumADC(v24, carry, v6, v15, carry);
+    BignumADC(v25, carry, v7, v16, carry);
+    v26 = v8 + v17 + carry;
+    r->w[0] = v18;
+    r->w[1] = v19;
+    r->w[2] = v20;
+    r->w[3] = v21;
+    r->w[4] = v22;
+    r->w[5] = v23;
+    r->w[6] = v24;
+    r->w[7] = v25;
+    r->w[8] = v26;
 }
 
-/*
- * Multiplication of bigvals mod p. Uses r as temporary storage, so
- * don't pass r aliasing a or b.
- */
 static void bigval_mul_mod_p(bigval *r, const bigval *a, const bigval *b)
 {
-#if BIGNUM_INT_BITS == 32
-    /* ./contrib/make1305.py mul 32 */
-    BignumDblInt tmp;
-    BignumDblInt acclo;
-    BignumDblInt acchi;
-    BignumDblInt acc2lo;
-    acclo = 0;
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[0]) * (b->w[0]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    r->w[0] = acclo;
-    acclo = acchi + (acclo >> 32);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[0]) * (b->w[1]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[1]) * (b->w[0]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    r->w[1] = acclo;
-    acclo = acchi + (acclo >> 32);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[0]) * (b->w[2]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[1]) * (b->w[1]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[2]) * (b->w[0]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    r->w[2] = acclo;
-    acclo = acchi + (acclo >> 32);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[0]) * (b->w[3]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[1]) * (b->w[2]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[2]) * (b->w[1]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[3]) * (b->w[0]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    r->w[3] = acclo;
-    acclo = acchi + (acclo >> 32);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[0]) * (b->w[4]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[1]) * (b->w[3]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[2]) * (b->w[2]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[3]) * (b->w[1]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[4]) * (b->w[0]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    r->w[4] = acclo & (((BignumInt)1 << 2)-1);
-    acc2lo = 0;
-    acc2lo += ((acclo >> 2) & (((BignumInt)1 << 30)-1)) * ((BignumDblInt)5 << 0);
-    acclo = acchi + (acclo >> 32);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[1]) * (b->w[4]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[2]) * (b->w[3]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[3]) * (b->w[2]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[4]) * (b->w[1]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    acc2lo += (acclo & (((BignumInt)1 << 2)-1)) * ((BignumDblInt)5 << 30);
-    acc2lo += r->w[0];
-    r->w[0] = acc2lo;
-    acc2lo >>= 32;
-    acc2lo += ((acclo >> 2) & (((BignumInt)1 << 30)-1)) * ((BignumDblInt)5 << 0);
-    acclo = acchi + (acclo >> 32);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[2]) * (b->w[4]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[3]) * (b->w[3]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[4]) * (b->w[2]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    acc2lo += (acclo & (((BignumInt)1 << 2)-1)) * ((BignumDblInt)5 << 30);
-    acc2lo += r->w[1];
-    r->w[1] = acc2lo;
-    acc2lo >>= 32;
-    acc2lo += ((acclo >> 2) & (((BignumInt)1 << 30)-1)) * ((BignumDblInt)5 << 0);
-    acclo = acchi + (acclo >> 32);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[3]) * (b->w[4]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    tmp = (BignumDblInt)(a->w[4]) * (b->w[3]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    acc2lo += (acclo & (((BignumInt)1 << 2)-1)) * ((BignumDblInt)5 << 30);
-    acc2lo += r->w[2];
-    r->w[2] = acc2lo;
-    acc2lo >>= 32;
-    acc2lo += ((acclo >> 2) & (((BignumInt)1 << 30)-1)) * ((BignumDblInt)5 << 0);
-    acclo = acchi + (acclo >> 32);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[4]) * (b->w[4]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 32;
-    acc2lo += (acclo & (((BignumInt)1 << 2)-1)) * ((BignumDblInt)5 << 30);
-    acc2lo += r->w[3];
-    r->w[3] = acc2lo;
-    acc2lo >>= 32;
-    acc2lo += ((acclo >> 2) & (((BignumInt)1 << 2)-1)) * ((BignumDblInt)5 << 0);
-    acc2lo += r->w[4];
-    r->w[4] = acc2lo;
-    acc2lo = 0;
-    acc2lo += ((acclo >> 4) & (((BignumInt)1 << 28)-1)) * ((BignumDblInt)25 << 0);
-    acclo = acchi + (acclo >> 32);
-    acchi = 0;
-    acc2lo += (acclo & (((BignumInt)1 << 4)-1)) * ((BignumDblInt)25 << 28);
-    acc2lo += r->w[0];
-    r->w[0] = acc2lo;
-    acc2lo >>= 32;
-    acc2lo += ((acclo >> 4) & (((BignumInt)1 << 28)-1)) * ((BignumDblInt)25 << 0);
-    acclo = acchi + (acclo >> 32);
-    acchi = 0;
-    acc2lo += r->w[1];
-    r->w[1] = acc2lo;
-    acc2lo >>= 32;
-    acc2lo += r->w[2];
-    r->w[2] = acc2lo;
-    acc2lo >>= 32;
-    acc2lo += r->w[3];
-    r->w[3] = acc2lo;
-    acc2lo >>= 32;
-    acc2lo += r->w[4];
-    r->w[4] = acc2lo;
-    acc2lo >>= 32;
-#elif BIGNUM_INT_BITS == 16
-    /* ./contrib/make1305.py mul 16 */
-    BignumDblInt tmp;
-    BignumDblInt acclo;
-    BignumDblInt acchi;
-    BignumDblInt acc2lo;
-    acclo = 0;
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[0]) * (b->w[0]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    r->w[0] = acclo;
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[0]) * (b->w[1]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[1]) * (b->w[0]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    r->w[1] = acclo;
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[0]) * (b->w[2]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[1]) * (b->w[1]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[2]) * (b->w[0]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    r->w[2] = acclo;
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[0]) * (b->w[3]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[1]) * (b->w[2]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[2]) * (b->w[1]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[3]) * (b->w[0]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    r->w[3] = acclo;
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[0]) * (b->w[4]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[1]) * (b->w[3]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[2]) * (b->w[2]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[3]) * (b->w[1]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[4]) * (b->w[0]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    r->w[4] = acclo;
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[0]) * (b->w[5]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[1]) * (b->w[4]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[2]) * (b->w[3]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[3]) * (b->w[2]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[4]) * (b->w[1]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[5]) * (b->w[0]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    r->w[5] = acclo;
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[0]) * (b->w[6]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[1]) * (b->w[5]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[2]) * (b->w[4]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[3]) * (b->w[3]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[4]) * (b->w[2]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[5]) * (b->w[1]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[6]) * (b->w[0]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    r->w[6] = acclo;
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[0]) * (b->w[7]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[1]) * (b->w[6]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[2]) * (b->w[5]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[3]) * (b->w[4]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[4]) * (b->w[3]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[5]) * (b->w[2]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[6]) * (b->w[1]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[7]) * (b->w[0]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    r->w[7] = acclo;
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[0]) * (b->w[8]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[1]) * (b->w[7]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[2]) * (b->w[6]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[3]) * (b->w[5]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[4]) * (b->w[4]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[5]) * (b->w[3]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[6]) * (b->w[2]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[7]) * (b->w[1]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[8]) * (b->w[0]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    r->w[8] = acclo & (((BignumInt)1 << 2)-1);
-    acc2lo = 0;
-    acc2lo += ((acclo >> 2) & (((BignumInt)1 << 14)-1)) * ((BignumDblInt)5 << 0);
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[1]) * (b->w[8]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[2]) * (b->w[7]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[3]) * (b->w[6]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[4]) * (b->w[5]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[5]) * (b->w[4]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[6]) * (b->w[3]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[7]) * (b->w[2]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[8]) * (b->w[1]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    acc2lo += (acclo & (((BignumInt)1 << 2)-1)) * ((BignumDblInt)5 << 14);
-    acc2lo += r->w[0];
-    r->w[0] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += ((acclo >> 2) & (((BignumInt)1 << 14)-1)) * ((BignumDblInt)5 << 0);
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[2]) * (b->w[8]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[3]) * (b->w[7]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[4]) * (b->w[6]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[5]) * (b->w[5]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[6]) * (b->w[4]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[7]) * (b->w[3]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[8]) * (b->w[2]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    acc2lo += (acclo & (((BignumInt)1 << 2)-1)) * ((BignumDblInt)5 << 14);
-    acc2lo += r->w[1];
-    r->w[1] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += ((acclo >> 2) & (((BignumInt)1 << 14)-1)) * ((BignumDblInt)5 << 0);
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[3]) * (b->w[8]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[4]) * (b->w[7]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[5]) * (b->w[6]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[6]) * (b->w[5]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[7]) * (b->w[4]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[8]) * (b->w[3]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    acc2lo += (acclo & (((BignumInt)1 << 2)-1)) * ((BignumDblInt)5 << 14);
-    acc2lo += r->w[2];
-    r->w[2] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += ((acclo >> 2) & (((BignumInt)1 << 14)-1)) * ((BignumDblInt)5 << 0);
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[4]) * (b->w[8]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[5]) * (b->w[7]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[6]) * (b->w[6]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[7]) * (b->w[5]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[8]) * (b->w[4]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    acc2lo += (acclo & (((BignumInt)1 << 2)-1)) * ((BignumDblInt)5 << 14);
-    acc2lo += r->w[3];
-    r->w[3] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += ((acclo >> 2) & (((BignumInt)1 << 14)-1)) * ((BignumDblInt)5 << 0);
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[5]) * (b->w[8]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[6]) * (b->w[7]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[7]) * (b->w[6]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[8]) * (b->w[5]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    acc2lo += (acclo & (((BignumInt)1 << 2)-1)) * ((BignumDblInt)5 << 14);
-    acc2lo += r->w[4];
-    r->w[4] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += ((acclo >> 2) & (((BignumInt)1 << 14)-1)) * ((BignumDblInt)5 << 0);
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[6]) * (b->w[8]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[7]) * (b->w[7]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[8]) * (b->w[6]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    acc2lo += (acclo & (((BignumInt)1 << 2)-1)) * ((BignumDblInt)5 << 14);
-    acc2lo += r->w[5];
-    r->w[5] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += ((acclo >> 2) & (((BignumInt)1 << 14)-1)) * ((BignumDblInt)5 << 0);
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[7]) * (b->w[8]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    tmp = (BignumDblInt)(a->w[8]) * (b->w[7]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    acc2lo += (acclo & (((BignumInt)1 << 2)-1)) * ((BignumDblInt)5 << 14);
-    acc2lo += r->w[6];
-    r->w[6] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += ((acclo >> 2) & (((BignumInt)1 << 14)-1)) * ((BignumDblInt)5 << 0);
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    tmp = (BignumDblInt)(a->w[8]) * (b->w[8]);
-    acclo += tmp & BIGNUM_INT_MASK;
-    acchi += tmp >> 16;
-    acc2lo += (acclo & (((BignumInt)1 << 2)-1)) * ((BignumDblInt)5 << 14);
-    acc2lo += r->w[7];
-    r->w[7] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += ((acclo >> 2) & (((BignumInt)1 << 2)-1)) * ((BignumDblInt)5 << 0);
-    acc2lo += r->w[8];
-    r->w[8] = acc2lo;
-    acc2lo = 0;
-    acc2lo += ((acclo >> 4) & (((BignumInt)1 << 12)-1)) * ((BignumDblInt)25 << 0);
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    acc2lo += (acclo & (((BignumInt)1 << 4)-1)) * ((BignumDblInt)25 << 12);
-    acc2lo += r->w[0];
-    r->w[0] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += ((acclo >> 4) & (((BignumInt)1 << 12)-1)) * ((BignumDblInt)25 << 0);
-    acclo = acchi + (acclo >> 16);
-    acchi = 0;
-    acc2lo += r->w[1];
-    r->w[1] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += r->w[2];
-    r->w[2] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += r->w[3];
-    r->w[3] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += r->w[4];
-    r->w[4] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += r->w[5];
-    r->w[5] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += r->w[6];
-    r->w[6] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += r->w[7];
-    r->w[7] = acc2lo;
-    acc2lo >>= 16;
-    acc2lo += r->w[8];
-    r->w[8] = acc2lo;
-    acc2lo >>= 16;
-#else
-#error Run contrib/make1305.py again with a different bit count
-#endif
+    BignumInt v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14;
+    BignumInt v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27;
+    BignumInt v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40;
+    BignumInt v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53;
+    BignumInt v54, v55, v56, v57, v58, v59, v60, v61, v62, v63, v64, v65, v66;
+    BignumInt v67, v68, v69, v70, v71, v72, v73, v74, v75, v76, v77, v78, v79;
+    BignumInt v80, v81, v82, v83, v84, v85, v86, v87, v88, v89, v90, v91, v92;
+    BignumInt v93, v94, v95, v96, v97, v98, v99, v100, v101, v102, v103, v104;
+    BignumInt v105, v106, v107, v108, v109, v110, v111, v112, v113, v114;
+    BignumInt v115, v116, v117, v118, v119, v120, v121, v122, v123, v124;
+    BignumInt v125, v126, v127, v128, v129, v130, v131, v132, v133, v134;
+    BignumInt v135, v136, v137, v138, v139, v140, v141, v142, v143, v144;
+    BignumInt v145, v146, v147, v148, v149, v150, v151, v152, v153, v154;
+    BignumInt v155, v156, v157, v158, v159, v160, v161, v162, v163, v164;
+    BignumInt v165, v166, v167, v168, v169, v170, v171, v172, v173, v174;
+    BignumInt v175, v176, v177, v178, v180, v181, v182, v183, v184, v185;
+    BignumInt v186, v187, v188, v189, v190, v191, v192, v193, v194, v195;
+    BignumInt v196, v197, v198, v199, v200, v201, v202, v203, v204, v205;
+    BignumInt v206, v207, v208, v210, v212, v213, v214, v215, v216, v217;
+    BignumInt v218, v219, v220, v221, v222, v223, v224, v225, v226, v227;
+    BignumInt v228, v229;
+    BignumCarry carry;
+
+    v0 = a->w[0];
+    v1 = a->w[1];
+    v2 = a->w[2];
+    v3 = a->w[3];
+    v4 = a->w[4];
+    v5 = a->w[5];
+    v6 = a->w[6];
+    v7 = a->w[7];
+    v8 = a->w[8];
+    v9 = b->w[0];
+    v10 = b->w[1];
+    v11 = b->w[2];
+    v12 = b->w[3];
+    v13 = b->w[4];
+    v14 = b->w[5];
+    v15 = b->w[6];
+    v16 = b->w[7];
+    v17 = b->w[8];
+    BignumMUL(v19, v18, v0, v9);
+    BignumMULADD(v21, v20, v0, v10, v19);
+    BignumMULADD(v23, v22, v0, v11, v21);
+    BignumMULADD(v25, v24, v0, v12, v23);
+    BignumMULADD(v27, v26, v0, v13, v25);
+    BignumMULADD(v29, v28, v0, v14, v27);
+    BignumMULADD(v31, v30, v0, v15, v29);
+    BignumMULADD(v33, v32, v0, v16, v31);
+    BignumMULADD(v35, v34, v0, v17, v33);
+    BignumMULADD(v37, v36, v1, v9, v20);
+    BignumMULADD2(v39, v38, v1, v10, v22, v37);
+    BignumMULADD2(v41, v40, v1, v11, v24, v39);
+    BignumMULADD2(v43, v42, v1, v12, v26, v41);
+    BignumMULADD2(v45, v44, v1, v13, v28, v43);
+    BignumMULADD2(v47, v46, v1, v14, v30, v45);
+    BignumMULADD2(v49, v48, v1, v15, v32, v47);
+    BignumMULADD2(v51, v50, v1, v16, v34, v49);
+    BignumMULADD2(v53, v52, v1, v17, v35, v51);
+    BignumMULADD(v55, v54, v2, v9, v38);
+    BignumMULADD2(v57, v56, v2, v10, v40, v55);
+    BignumMULADD2(v59, v58, v2, v11, v42, v57);
+    BignumMULADD2(v61, v60, v2, v12, v44, v59);
+    BignumMULADD2(v63, v62, v2, v13, v46, v61);
+    BignumMULADD2(v65, v64, v2, v14, v48, v63);
+    BignumMULADD2(v67, v66, v2, v15, v50, v65);
+    BignumMULADD2(v69, v68, v2, v16, v52, v67);
+    BignumMULADD2(v71, v70, v2, v17, v53, v69);
+    BignumMULADD(v73, v72, v3, v9, v56);
+    BignumMULADD2(v75, v74, v3, v10, v58, v73);
+    BignumMULADD2(v77, v76, v3, v11, v60, v75);
+    BignumMULADD2(v79, v78, v3, v12, v62, v77);
+    BignumMULADD2(v81, v80, v3, v13, v64, v79);
+    BignumMULADD2(v83, v82, v3, v14, v66, v81);
+    BignumMULADD2(v85, v84, v3, v15, v68, v83);
+    BignumMULADD2(v87, v86, v3, v16, v70, v85);
+    BignumMULADD2(v89, v88, v3, v17, v71, v87);
+    BignumMULADD(v91, v90, v4, v9, v74);
+    BignumMULADD2(v93, v92, v4, v10, v76, v91);
+    BignumMULADD2(v95, v94, v4, v11, v78, v93);
+    BignumMULADD2(v97, v96, v4, v12, v80, v95);
+    BignumMULADD2(v99, v98, v4, v13, v82, v97);
+    BignumMULADD2(v101, v100, v4, v14, v84, v99);
+    BignumMULADD2(v103, v102, v4, v15, v86, v101);
+    BignumMULADD2(v105, v104, v4, v16, v88, v103);
+    BignumMULADD2(v107, v106, v4, v17, v89, v105);
+    BignumMULADD(v109, v108, v5, v9, v92);
+    BignumMULADD2(v111, v110, v5, v10, v94, v109);
+    BignumMULADD2(v113, v112, v5, v11, v96, v111);
+    BignumMULADD2(v115, v114, v5, v12, v98, v113);
+    BignumMULADD2(v117, v116, v5, v13, v100, v115);
+    BignumMULADD2(v119, v118, v5, v14, v102, v117);
+    BignumMULADD2(v121, v120, v5, v15, v104, v119);
+    BignumMULADD2(v123, v122, v5, v16, v106, v121);
+    BignumMULADD2(v125, v124, v5, v17, v107, v123);
+    BignumMULADD(v127, v126, v6, v9, v110);
+    BignumMULADD2(v129, v128, v6, v10, v112, v127);
+    BignumMULADD2(v131, v130, v6, v11, v114, v129);
+    BignumMULADD2(v133, v132, v6, v12, v116, v131);
+    BignumMULADD2(v135, v134, v6, v13, v118, v133);
+    BignumMULADD2(v137, v136, v6, v14, v120, v135);
+    BignumMULADD2(v139, v138, v6, v15, v122, v137);
+    BignumMULADD2(v141, v140, v6, v16, v124, v139);
+    BignumMULADD2(v143, v142, v6, v17, v125, v141);
+    BignumMULADD(v145, v144, v7, v9, v128);
+    BignumMULADD2(v147, v146, v7, v10, v130, v145);
+    BignumMULADD2(v149, v148, v7, v11, v132, v147);
+    BignumMULADD2(v151, v150, v7, v12, v134, v149);
+    BignumMULADD2(v153, v152, v7, v13, v136, v151);
+    BignumMULADD2(v155, v154, v7, v14, v138, v153);
+    BignumMULADD2(v157, v156, v7, v15, v140, v155);
+    BignumMULADD2(v159, v158, v7, v16, v142, v157);
+    BignumMULADD2(v161, v160, v7, v17, v143, v159);
+    BignumMULADD(v163, v162, v8, v9, v146);
+    BignumMULADD2(v165, v164, v8, v10, v148, v163);
+    BignumMULADD2(v167, v166, v8, v11, v150, v165);
+    BignumMULADD2(v169, v168, v8, v12, v152, v167);
+    BignumMULADD2(v171, v170, v8, v13, v154, v169);
+    BignumMULADD2(v173, v172, v8, v14, v156, v171);
+    BignumMULADD2(v175, v174, v8, v15, v158, v173);
+    BignumMULADD2(v177, v176, v8, v16, v160, v175);
+    v178 = v8 * v17 + v161 + v177;
+    v180 = (v162) & ((((BignumInt)1) << 2)-1);
+    v181 = ((v162) >> 2) | ((v164) << 14);
+    v182 = ((v164) >> 2) | ((v166) << 14);
+    v183 = ((v166) >> 2) | ((v168) << 14);
+    v184 = ((v168) >> 2) | ((v170) << 14);
+    v185 = ((v170) >> 2) | ((v172) << 14);
+    v186 = ((v172) >> 2) | ((v174) << 14);
+    v187 = ((v174) >> 2) | ((v176) << 14);
+    v188 = ((v176) >> 2) | ((v178) << 14);
+    v189 = (v178) >> 2;
+    v190 = (v189) & ((((BignumInt)1) << 2)-1);
+    v191 = (v178) >> 4;
+    BignumMUL(v193, v192, 5, v181);
+    BignumMULADD(v195, v194, 5, v182, v193);
+    BignumMULADD(v197, v196, 5, v183, v195);
+    BignumMULADD(v199, v198, 5, v184, v197);
+    BignumMULADD(v201, v200, 5, v185, v199);
+    BignumMULADD(v203, v202, 5, v186, v201);
+    BignumMULADD(v205, v204, 5, v187, v203);
+    BignumMULADD(v207, v206, 5, v188, v205);
+    v208 = 5 * v190 + v207;
+    v210 = 25 * v191;
+    BignumADC(v212, carry, v18, v192, 0);
+    BignumADC(v213, carry, v36, v194, carry);
+    BignumADC(v214, carry, v54, v196, carry);
+    BignumADC(v215, carry, v72, v198, carry);
+    BignumADC(v216, carry, v90, v200, carry);
+    BignumADC(v217, carry, v108, v202, carry);
+    BignumADC(v218, carry, v126, v204, carry);
+    BignumADC(v219, carry, v144, v206, carry);
+    v220 = v180 + v208 + carry;
+    BignumADC(v221, carry, v212, v210, 0);
+    BignumADC(v222, carry, v213, 0, carry);
+    BignumADC(v223, carry, v214, 0, carry);
+    BignumADC(v224, carry, v215, 0, carry);
+    BignumADC(v225, carry, v216, 0, carry);
+    BignumADC(v226, carry, v217, 0, carry);
+    BignumADC(v227, carry, v218, 0, carry);
+    BignumADC(v228, carry, v219, 0, carry);
+    v229 = v220 + 0 + carry;
+    r->w[0] = v221;
+    r->w[1] = v222;
+    r->w[2] = v223;
+    r->w[3] = v224;
+    r->w[4] = v225;
+    r->w[5] = v226;
+    r->w[6] = v227;
+    r->w[7] = v228;
+    r->w[8] = v229;
 }
 
 static void bigval_final_reduce(bigval *n)
 {
-#if BIGNUM_INT_BITS == 32
-    /* ./contrib/make1305.py final_reduce 32 */
-    BignumDblInt acclo;
-    acclo = 0;
-    acclo += 5 * ((n->w[4] >> 2) + 1);
-    acclo += n->w[0];
-    acclo >>= 32;
-    acclo += n->w[1];
-    acclo >>= 32;
-    acclo += n->w[2];
-    acclo >>= 32;
-    acclo += n->w[3];
-    acclo >>= 32;
-    acclo += n->w[4];
-    acclo = 5 * (acclo >> 2);
-    acclo += n->w[0];
-    n->w[0] = acclo;
-    acclo >>= 32;
-    acclo += n->w[1];
-    n->w[1] = acclo;
-    acclo >>= 32;
-    acclo += n->w[2];
-    n->w[2] = acclo;
-    acclo >>= 32;
-    acclo += n->w[3];
-    n->w[3] = acclo;
-    acclo >>= 32;
-    acclo += n->w[4];
-    n->w[4] = acclo;
-    acclo >>= 32;
-    n->w[4] &= (1 << 2) - 1;
-#elif BIGNUM_INT_BITS == 16
-    /* ./contrib/make1305.py final_reduce 16 */
-    BignumDblInt acclo;
-    acclo = 0;
-    acclo += 5 * ((n->w[8] >> 2) + 1);
-    acclo += n->w[0];
-    acclo >>= 16;
-    acclo += n->w[1];
-    acclo >>= 16;
-    acclo += n->w[2];
-    acclo >>= 16;
-    acclo += n->w[3];
-    acclo >>= 16;
-    acclo += n->w[4];
-    acclo >>= 16;
-    acclo += n->w[5];
-    acclo >>= 16;
-    acclo += n->w[6];
-    acclo >>= 16;
-    acclo += n->w[7];
-    acclo >>= 16;
-    acclo += n->w[8];
-    acclo = 5 * (acclo >> 2);
-    acclo += n->w[0];
-    n->w[0] = acclo;
-    acclo >>= 16;
-    acclo += n->w[1];
-    n->w[1] = acclo;
-    acclo >>= 16;
-    acclo += n->w[2];
-    n->w[2] = acclo;
-    acclo >>= 16;
-    acclo += n->w[3];
-    n->w[3] = acclo;
-    acclo >>= 16;
-    acclo += n->w[4];
-    n->w[4] = acclo;
-    acclo >>= 16;
-    acclo += n->w[5];
-    n->w[5] = acclo;
-    acclo >>= 16;
-    acclo += n->w[6];
-    n->w[6] = acclo;
-    acclo >>= 16;
-    acclo += n->w[7];
-    n->w[7] = acclo;
-    acclo >>= 16;
-    acclo += n->w[8];
-    n->w[8] = acclo;
-    acclo >>= 16;
-    n->w[8] &= (1 << 2) - 1;
+    BignumInt v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v12, v13, v14, v15;
+    BignumInt v16, v17, v18, v19, v20, v21, v22, v24, v25, v26, v27, v28, v29;
+    BignumInt v30, v31, v32, v33;
+    BignumCarry carry;
+
+    v0 = n->w[0];
+    v1 = n->w[1];
+    v2 = n->w[2];
+    v3 = n->w[3];
+    v4 = n->w[4];
+    v5 = n->w[5];
+    v6 = n->w[6];
+    v7 = n->w[7];
+    v8 = n->w[8];
+    v9 = (v8) >> 2;
+    v10 = 5 * v9;
+    BignumADC(v12, carry, v0, v10, 0);
+    (void)v12;
+    BignumADC(v13, carry, v1, 0, carry);
+    (void)v13;
+    BignumADC(v14, carry, v2, 0, carry);
+    (void)v14;
+    BignumADC(v15, carry, v3, 0, carry);
+    (void)v15;
+    BignumADC(v16, carry, v4, 0, carry);
+    (void)v16;
+    BignumADC(v17, carry, v5, 0, carry);
+    (void)v17;
+    BignumADC(v18, carry, v6, 0, carry);
+    (void)v18;
+    BignumADC(v19, carry, v7, 0, carry);
+    (void)v19;
+    v20 = v8 + 0 + carry;
+    v21 = (v20) >> 2;
+    v22 = 5 * v21;
+    BignumADC(v24, carry, v0, v22, 0);
+    BignumADC(v25, carry, v1, 0, carry);
+    BignumADC(v26, carry, v2, 0, carry);
+    BignumADC(v27, carry, v3, 0, carry);
+    BignumADC(v28, carry, v4, 0, carry);
+    BignumADC(v29, carry, v5, 0, carry);
+    BignumADC(v30, carry, v6, 0, carry);
+    BignumADC(v31, carry, v7, 0, carry);
+    v32 = v8 + 0 + carry;
+    v33 = (v32) & ((((BignumInt)1) << 2)-1);
+    n->w[0] = v24;
+    n->w[1] = v25;
+    n->w[2] = v26;
+    n->w[3] = v27;
+    n->w[4] = v28;
+    n->w[5] = v29;
+    n->w[6] = v30;
+    n->w[7] = v31;
+    n->w[8] = v33;
+}
+
+#elif BIGNUM_INT_BITS == 32
+
+static void bigval_add(bigval *r, const bigval *a, const bigval *b)
+{
+    BignumInt v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14;
+    BignumCarry carry;
+
+    v0 = a->w[0];
+    v1 = a->w[1];
+    v2 = a->w[2];
+    v3 = a->w[3];
+    v4 = a->w[4];
+    v5 = b->w[0];
+    v6 = b->w[1];
+    v7 = b->w[2];
+    v8 = b->w[3];
+    v9 = b->w[4];
+    BignumADC(v10, carry, v0, v5, 0);
+    BignumADC(v11, carry, v1, v6, carry);
+    BignumADC(v12, carry, v2, v7, carry);
+    BignumADC(v13, carry, v3, v8, carry);
+    v14 = v4 + v9 + carry;
+    r->w[0] = v10;
+    r->w[1] = v11;
+    r->w[2] = v12;
+    r->w[3] = v13;
+    r->w[4] = v14;
+}
+
+static void bigval_mul_mod_p(bigval *r, const bigval *a, const bigval *b)
+{
+    BignumInt v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14;
+    BignumInt v15, v16, v17, v18, v19, v20, v21, v22, v23, v24, v25, v26, v27;
+    BignumInt v28, v29, v30, v31, v32, v33, v34, v35, v36, v37, v38, v39, v40;
+    BignumInt v41, v42, v43, v44, v45, v46, v47, v48, v49, v50, v51, v52, v53;
+    BignumInt v54, v55, v56, v57, v58, v60, v61, v62, v63, v64, v65, v66, v67;
+    BignumInt v68, v69, v70, v71, v72, v73, v74, v75, v76, v78, v80, v81, v82;
+    BignumInt v83, v84, v85, v86, v87, v88, v89;
+    BignumCarry carry;
+
+    v0 = a->w[0];
+    v1 = a->w[1];
+    v2 = a->w[2];
+    v3 = a->w[3];
+    v4 = a->w[4];
+    v5 = b->w[0];
+    v6 = b->w[1];
+    v7 = b->w[2];
+    v8 = b->w[3];
+    v9 = b->w[4];
+    BignumMUL(v11, v10, v0, v5);
+    BignumMULADD(v13, v12, v0, v6, v11);
+    BignumMULADD(v15, v14, v0, v7, v13);
+    BignumMULADD(v17, v16, v0, v8, v15);
+    BignumMULADD(v19, v18, v0, v9, v17);
+    BignumMULADD(v21, v20, v1, v5, v12);
+    BignumMULADD2(v23, v22, v1, v6, v14, v21);
+    BignumMULADD2(v25, v24, v1, v7, v16, v23);
+    BignumMULADD2(v27, v26, v1, v8, v18, v25);
+    BignumMULADD2(v29, v28, v1, v9, v19, v27);
+    BignumMULADD(v31, v30, v2, v5, v22);
+    BignumMULADD2(v33, v32, v2, v6, v24, v31);
+    BignumMULADD2(v35, v34, v2, v7, v26, v33);
+    BignumMULADD2(v37, v36, v2, v8, v28, v35);
+    BignumMULADD2(v39, v38, v2, v9, v29, v37);
+    BignumMULADD(v41, v40, v3, v5, v32);
+    BignumMULADD2(v43, v42, v3, v6, v34, v41);
+    BignumMULADD2(v45, v44, v3, v7, v36, v43);
+    BignumMULADD2(v47, v46, v3, v8, v38, v45);
+    BignumMULADD2(v49, v48, v3, v9, v39, v47);
+    BignumMULADD(v51, v50, v4, v5, v42);
+    BignumMULADD2(v53, v52, v4, v6, v44, v51);
+    BignumMULADD2(v55, v54, v4, v7, v46, v53);
+    BignumMULADD2(v57, v56, v4, v8, v48, v55);
+    v58 = v4 * v9 + v49 + v57;
+    v60 = (v50) & ((((BignumInt)1) << 2)-1);
+    v61 = ((v50) >> 2) | ((v52) << 30);
+    v62 = ((v52) >> 2) | ((v54) << 30);
+    v63 = ((v54) >> 2) | ((v56) << 30);
+    v64 = ((v56) >> 2) | ((v58) << 30);
+    v65 = (v58) >> 2;
+    v66 = (v65) & ((((BignumInt)1) << 2)-1);
+    v67 = (v58) >> 4;
+    BignumMUL(v69, v68, 5, v61);
+    BignumMULADD(v71, v70, 5, v62, v69);
+    BignumMULADD(v73, v72, 5, v63, v71);
+    BignumMULADD(v75, v74, 5, v64, v73);
+    v76 = 5 * v66 + v75;
+    v78 = 25 * v67;
+    BignumADC(v80, carry, v10, v68, 0);
+    BignumADC(v81, carry, v20, v70, carry);
+    BignumADC(v82, carry, v30, v72, carry);
+    BignumADC(v83, carry, v40, v74, carry);
+    v84 = v60 + v76 + carry;
+    BignumADC(v85, carry, v80, v78, 0);
+    BignumADC(v86, carry, v81, 0, carry);
+    BignumADC(v87, carry, v82, 0, carry);
+    BignumADC(v88, carry, v83, 0, carry);
+    v89 = v84 + 0 + carry;
+    r->w[0] = v85;
+    r->w[1] = v86;
+    r->w[2] = v87;
+    r->w[3] = v88;
+    r->w[4] = v89;
+}
+
+static void bigval_final_reduce(bigval *n)
+{
+    BignumInt v0, v1, v2, v3, v4, v5, v6, v8, v9, v10, v11, v12, v13, v14;
+    BignumInt v16, v17, v18, v19, v20, v21;
+    BignumCarry carry;
+
+    v0 = n->w[0];
+    v1 = n->w[1];
+    v2 = n->w[2];
+    v3 = n->w[3];
+    v4 = n->w[4];
+    v5 = (v4) >> 2;
+    v6 = 5 * v5;
+    BignumADC(v8, carry, v0, v6, 0);
+    (void)v8;
+    BignumADC(v9, carry, v1, 0, carry);
+    (void)v9;
+    BignumADC(v10, carry, v2, 0, carry);
+    (void)v10;
+    BignumADC(v11, carry, v3, 0, carry);
+    (void)v11;
+    v12 = v4 + 0 + carry;
+    v13 = (v12) >> 2;
+    v14 = 5 * v13;
+    BignumADC(v16, carry, v0, v14, 0);
+    BignumADC(v17, carry, v1, 0, carry);
+    BignumADC(v18, carry, v2, 0, carry);
+    BignumADC(v19, carry, v3, 0, carry);
+    v20 = v4 + 0 + carry;
+    v21 = (v20) & ((((BignumInt)1) << 2)-1);
+    n->w[0] = v16;
+    n->w[1] = v17;
+    n->w[2] = v18;
+    n->w[3] = v19;
+    n->w[4] = v21;
+}
+
+#elif BIGNUM_INT_BITS == 64
+
+static void bigval_add(bigval *r, const bigval *a, const bigval *b)
+{
+    BignumInt v0, v1, v2, v3, v4, v5, v6, v7, v8;
+    BignumCarry carry;
+
+    v0 = a->w[0];
+    v1 = a->w[1];
+    v2 = a->w[2];
+    v3 = b->w[0];
+    v4 = b->w[1];
+    v5 = b->w[2];
+    BignumADC(v6, carry, v0, v3, 0);
+    BignumADC(v7, carry, v1, v4, carry);
+    v8 = v2 + v5 + carry;
+    r->w[0] = v6;
+    r->w[1] = v7;
+    r->w[2] = v8;
+}
+
+static void bigval_mul_mod_p(bigval *r, const bigval *a, const bigval *b)
+{
+    BignumInt v0, v1, v2, v3, v4, v5, v6, v7, v8, v9, v10, v11, v12, v13, v14;
+    BignumInt v15, v16, v17, v18, v19, v20, v21, v22, v24, v25, v26, v27, v28;
+    BignumInt v29, v30, v31, v32, v33, v34, v36, v38, v39, v40, v41, v42, v43;
+    BignumCarry carry;
+
+    v0 = a->w[0];
+    v1 = a->w[1];
+    v2 = a->w[2];
+    v3 = b->w[0];
+    v4 = b->w[1];
+    v5 = b->w[2];
+    BignumMUL(v7, v6, v0, v3);
+    BignumMULADD(v9, v8, v0, v4, v7);
+    BignumMULADD(v11, v10, v0, v5, v9);
+    BignumMULADD(v13, v12, v1, v3, v8);
+    BignumMULADD2(v15, v14, v1, v4, v10, v13);
+    BignumMULADD2(v17, v16, v1, v5, v11, v15);
+    BignumMULADD(v19, v18, v2, v3, v14);
+    BignumMULADD2(v21, v20, v2, v4, v16, v19);
+    v22 = v2 * v5 + v17 + v21;
+    v24 = (v18) & ((((BignumInt)1) << 2)-1);
+    v25 = ((v18) >> 2) | ((v20) << 62);
+    v26 = ((v20) >> 2) | ((v22) << 62);
+    v27 = (v22) >> 2;
+    v28 = (v27) & ((((BignumInt)1) << 2)-1);
+    v29 = (v22) >> 4;
+    BignumMUL(v31, v30, 5, v25);
+    BignumMULADD(v33, v32, 5, v26, v31);
+    v34 = 5 * v28 + v33;
+    v36 = 25 * v29;
+    BignumADC(v38, carry, v6, v30, 0);
+    BignumADC(v39, carry, v12, v32, carry);
+    v40 = v24 + v34 + carry;
+    BignumADC(v41, carry, v38, v36, 0);
+    BignumADC(v42, carry, v39, 0, carry);
+    v43 = v40 + 0 + carry;
+    r->w[0] = v41;
+    r->w[1] = v42;
+    r->w[2] = v43;
+}
+
+static void bigval_final_reduce(bigval *n)
+{
+    BignumInt v0, v1, v2, v3, v4, v6, v7, v8, v9, v10, v12, v13, v14, v15;
+    BignumCarry carry;
+
+    v0 = n->w[0];
+    v1 = n->w[1];
+    v2 = n->w[2];
+    v3 = (v2) >> 2;
+    v4 = 5 * v3;
+    BignumADC(v6, carry, v0, v4, 0);
+    (void)v6;
+    BignumADC(v7, carry, v1, 0, carry);
+    (void)v7;
+    v8 = v2 + 0 + carry;
+    v9 = (v8) >> 2;
+    v10 = 5 * v9;
+    BignumADC(v12, carry, v0, v10, 0);
+    BignumADC(v13, carry, v1, 0, carry);
+    v14 = v2 + 0 + carry;
+    v15 = (v14) & ((((BignumInt)1) << 2)-1);
+    n->w[0] = v12;
+    n->w[1] = v13;
+    n->w[2] = v15;
+}
+
 #else
-#error Run contrib/make1305.py again with a different bit count
+#error Add another bit count to contrib/make1305.py and rerun it
 #endif
-}
 
 struct poly1305 {
     unsigned char nonce[16];
@@ -951,7 +779,8 @@ static void poly1305_feed_chunk(struct poly1305 *ctx,
 {
     bigval c;
     bigval_import_le(&c, chunk, len);
-    c.w[len / BIGNUM_INT_BYTES] |= 1 << (8 * (len % BIGNUM_INT_BYTES));
+    c.w[len / BIGNUM_INT_BYTES] |=
+        (BignumInt)1 << (8 * (len % BIGNUM_INT_BYTES));
     bigval_add(&c, &c, &ctx->h);
     bigval_mul_mod_p(&ctx->h, &c, &ctx->r);
 }
@@ -1122,7 +951,7 @@ static const struct ssh_mac ssh2_poly1305 = {
     poly_start, poly_bytes, poly_genresult, poly_verresult,
 
     "", "", /* Not selectable individually, just part of ChaCha20-Poly1305 */
-    16, "Poly1305"
+    16, 0, "Poly1305"
 };
 
 static void *ccp_make_context(void)
@@ -1174,7 +1003,11 @@ static void ccp_length_op(struct ccp_context *ctx, unsigned char *blk, int len,
                           unsigned long seq)
 {
     unsigned char iv[8];
-    PUT_32BIT_LSB_FIRST(iv, seq >> 32);
+    /*
+     * According to RFC 4253 (section 6.4), the packet sequence number wraps
+     * at 2^32, so its 32 high-order bits will always be zero.
+     */
+    PUT_32BIT_LSB_FIRST(iv, 0);
     PUT_32BIT_LSB_FIRST(iv + 4, seq);
     chacha20_iv(&ctx->a_cipher, iv);
     chacha20_iv(&ctx->b_cipher, iv);
@@ -1211,7 +1044,7 @@ static const struct ssh2_cipher ssh2_chacha20_poly1305 = {
     ccp_decrypt_length,
 
     "chacha20-poly1305@openssh.com",
-    1, 512, SSH_CIPHER_SEPARATE_LENGTH, "ChaCha20",
+    1, 512, 64, SSH_CIPHER_SEPARATE_LENGTH, "ChaCha20",
 
     &ssh2_poly1305
 };