ref: 9caea584295b183afde4d272c2c7127da0ff1dc7
parent: 7dc87d28e166fe2989e002fa650d2a345cf0461e
author: Ori Bernstein <ori@eigenstate.org>
date: Thu Dec 8 10:40:59 EST 2016
Add a few more convenience functions to bigint.
--- a/lib/std/bigint.myr
+++ b/lib/std/bigint.myr
@@ -23,6 +23,7 @@
/* administrivia */
generic mkbigint : (v : @a::(numeric,integral) -> bigint#)
+ const bigfrombytes : (isneg : bool, v : byte[:] -> bigint#)
const bigfree : (a : bigint# -> void)
const bigdup : (a : bigint# -> bigint#)
const bigassign : (d : bigint#, s : bigint# -> bigint#)
@@ -61,11 +62,13 @@
const bigdivmod : (a : bigint#, b : bigint# -> (bigint#, bigint#))
const bigshl : (a : bigint#, b : bigint# -> bigint#)
const bigshr : (a : bigint#, b : bigint# -> bigint#)
+ const bigand : (a : bigint#, b : bigint# -> bigint#)
+ const bigor : (a : bigint#, b : bigint# -> bigint#)
+
const bigmodpow : (b : bigint#, e : bigint#, m : bigint# -> bigint#)
- /*
- const bigpow : (a : bigint#, b : bigint# -> bigint#)
- */
+ //const bigpow : (a : bigint#, b : bigint# -> bigint#)
+
/* bigint*int -> bigint ops */
generic bigaddi : (a : bigint#, b : @a::(integral,numeric) -> bigint#)
generic bigsubi : (a : bigint#, b : @a::(integral,numeric) -> bigint#)
@@ -73,10 +76,12 @@
generic bigdivi : (a : bigint#, b : @a::(integral,numeric) -> bigint#)
generic bigshli : (a : bigint#, b : @a::(integral,numeric) -> bigint#)
generic bigshri : (a : bigint#, b : @a::(integral,numeric) -> bigint#)
- /*
- const bigpowi : (a : bigint#, b : uint64 -> bigint#)
- */
+ generic bigandi : (a : bigint#, b : @a::(integral,numeric) -> bigint#)
+ generic bigori : (a : bigint#, b : @a::(integral,numeric) -> bigint#)
+ //const bigpowi : (a : bigint#, b : uint64 -> bigint#)
+ //const bigmodpowi : (b : bigint#, e : bigint#, m : bigint# -> bigint#)
+
/* information about bigints */
const bigbitcount : (a : bigint# -> size)
;;
@@ -102,6 +107,32 @@
-> trim(a)
}
+const bigfrombytes = {isneg, v
+ var i, off, a, last
+
+ a = mkbigint(0)
+ if isneg
+ a.sign = -1
+ else
+ a.sign = 1
+ ;;
+
+ for i = 0; i + 4 <= v.len; i += 4
+ std.slpush(&a.dig, \
+ (v[i + 0] << 0 : uint32) | \
+ (v[i + 1] << 8 : uint32) | \
+ (v[i + 2] << 16 : uint32) | \
+ (v[i + 3] << 24 : uint32))
+ ;;
+ last = 0
+ for i; i < v.len; i++
+ off = i & 0x3
+ last |= (v[off] : uint32) << (8 *off)
+ ;;
+ std.slpush(&a.dig, last)
+ -> trim(a)
+}
+
const bigfree = {a
slfree(a.dig)
free(a)
@@ -624,6 +655,21 @@
-> (trim(q), trim(u))
}
+const bigand = {a, b
+ for var i = 0; i < min(a.dig.len, b.dig.len); i++
+ a.dig[i] &= b.dig[i]
+ ;;
+ -> trim(a)
+}
+
+const bigor = {a, b
+ slzgrow(&a.dig, max(a.dig.len, b.dig.len))
+ for var i = 0; i < a.dig.len; i++
+ a.dig[i] |= b.dig[i]
+ ;;
+ -> trim(a)
+}
+
/* computes b^e % m */
const bigmodpow = {base, exp, mod
var r, n
@@ -789,6 +835,20 @@
carry = t << (32 - shift)
;;
-> trim(a)
+}
+
+generic bigandi = {a, b
+ var v
+ var dig : uint32[2]
+ bigdigit(&v, b < 0, (b : uint64), dig[:])
+ -> bigand(a, &v)
+}
+
+generic bigori = {a, b
+ var v
+ var dig : uint32[2]
+ bigdigit(&v, b < 0, (b : uint64), dig[:])
+ -> bigor(a, &v)
}
/* creates a bigint on the stack; should not be modified. */