}
/*
+ * 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.