work in progress; to be tidied and fixed
[u/mdw/putty] / sshbn.c
diff --git a/sshbn.c b/sshbn.c
index 7c6b13a..580dd6f 100644 (file)
--- a/sshbn.c
+++ b/sshbn.c
@@ -1385,6 +1385,78 @@ Bignum bigsub(Bignum a, Bignum b)
 }
 
 /*
+ * Return a bignum which is the result of shifting another left by N bits.
+ * If N is negative then you get a right shift instead.
+ */
+Bignum biglsl(Bignum x, int n)
+{
+    Bignum d;
+    unsigned o, i;
+
+    if (!n || !x[0])
+        return copybn(x);
+    else if (n < 0)
+        return biglsr(x, -n);
+
+    o = n/BIGNUM_INT_BITS;
+    n %= BIGNUM_INT_BITS;
+    d = newbn(x[0] + o + !!n);
+
+    for (i = 1; i <= o; i++)
+        d[i] = 0;
+
+    if (!n) {
+        for (i = 1; i <= x[0]; i++)
+            d[o + i] = x[i];
+    } else {
+        d[o + 1] = x[1] << n;
+        for (i = 2; i <= x[0]; i--)
+            d[o + i] = (x[i] << n) | (x[i - 1] >> (BIGNUM_INT_BITS - n));
+        d[o + x[0] + 1] = x[x[0]] >> (BIGNUM_INT_BITS - n);
+    }
+
+    bn_restore_invariant(d);
+    return d;
+}
+
+/*
+ * Return a bignum which is the result of shifting another right by N bits
+ * (discarding the least significant N bits, and shifting zeroes in at the
+ * most significant end).  If N is negative then you get a left shift
+ * instead.
+ */
+Bignum biglsr(Bignum x, int n)
+{
+    Bignum d;
+    unsigned o, i;
+
+    if (!n || !x[0])
+        return copybn(x);
+    else if (n < 0)
+        return biglsl(x, -n);
+
+    o = n/BIGNUM_INT_BITS;
+    n %= BIGNUM_INT_BITS;
+    d = newbn(x[0]);
+
+    if (!n) {
+        for (i = o + 1; i <= x[0]; i++)
+            d[i - o] = x[i];
+    } else {
+        d[1] = x[o + 1] >> n;
+        for (i = o + 2; i < x[0]; i++)
+            d[i - o] = x[
+        d[o + x[0] + 1] = x[x[0]] >> (BIGNUM_INT_BITS - n);
+        for (i = x[0]; i > 1; i--)
+            d[o + i] = (x[i] << n) | (x[i - 1] >> (BIGNUM_INT_BITS - n));
+        d[o + 1] = x[1] << n;
+    }
+
+    bn_restore_invariant(d);
+    return d;
+}
+
+/*
  * Create a bignum which is the bitmask covering another one. That
  * is, the smallest integer which is >= N and is also one less than
  * a power of two.