cleanup some code
This commit is contained in:
parent
8ea95078f4
commit
1657d841e7
|
@ -26,7 +26,7 @@ func u256*(n: SomeInteger): UInt256 {.inline.} = n.stuint(256)
|
|||
func u256*(s: string): UInt256 {.inline.} = s.parse(UInt256)
|
||||
|
||||
func i128*(n: SomeInteger): Int128 {.inline.} = n.stint(128)
|
||||
# func i128*(s: string): Int128 {.inline.} = s.parse(Int128)
|
||||
func i128*(s: string): Int128 {.inline.} = s.parse(Int128)
|
||||
|
||||
func i256*(n: SomeInteger): Int256 {.inline.} = n.stint(256)
|
||||
# func i256*(s: string): Int256 {.inline.} = s.parse(Int256)
|
||||
func i256*(s: string): Int256 {.inline.} = s.parse(Int256)
|
||||
|
|
|
@ -25,6 +25,8 @@ const
|
|||
{.push raises: [], inline, noinit, gcsafe.}
|
||||
|
||||
func sign*(a: StInt): int =
|
||||
## get the sign of `a`
|
||||
## either -1, 0, or 1
|
||||
if a.imp.isZero: return 0
|
||||
if a.limbs[^1] < signMask: 1
|
||||
else: -1
|
||||
|
@ -39,10 +41,12 @@ func setMSB(a: var StInt) =
|
|||
a.limbs[^1] = a.limbs[^1] or signMask
|
||||
|
||||
func negate*(a: var StInt) =
|
||||
## two complement negation
|
||||
a.imp.bitnot(a.imp)
|
||||
a.imp.inc
|
||||
|
||||
func neg*(a: StInt): StInt =
|
||||
## two complement negation
|
||||
result.imp.bitnot(a.imp)
|
||||
result.imp.inc
|
||||
|
||||
|
@ -53,6 +57,7 @@ func abs*(a: StInt): StInt =
|
|||
a
|
||||
|
||||
func `-`*(a: StInt): StInt =
|
||||
## two complement negation
|
||||
a.neg
|
||||
|
||||
{.pop.}
|
||||
|
@ -66,6 +71,7 @@ func setZero*(a: var StInt) =
|
|||
a.imp.setZero
|
||||
|
||||
func setOne*(a: var StInt) =
|
||||
## Set ``a`` to 1
|
||||
a.imp.setOne
|
||||
|
||||
func zero*[bits: static[int]](T: typedesc[StInt[bits]]): T =
|
||||
|
@ -172,12 +178,18 @@ func `shl`*(a: StInt, k: SomeInteger): StInt =
|
|||
result.imp.shiftLeft(a.imp, k)
|
||||
|
||||
func setBit*(a: var StInt, k: Natural) =
|
||||
## set bit at position `k`
|
||||
## k = 0..a.bits-1
|
||||
a.imp.setBit(k)
|
||||
|
||||
func clearBit*(a: var StInt, k: Natural) =
|
||||
## set bit at position `k`
|
||||
## k = 0..a.bits-1
|
||||
a.imp.clearBit(k)
|
||||
|
||||
func getBit*(a: StInt, k: Natural): bool =
|
||||
## set bit at position `k`
|
||||
## k = 0..a.bits-1
|
||||
a.imp.getBit(k)
|
||||
|
||||
{.pop.}
|
||||
|
@ -216,3 +228,16 @@ func `+=`*(a: var StInt, b: SomeUnsignedInt) =
|
|||
a.imp.inc(Word(b))
|
||||
|
||||
{.pop.}
|
||||
|
||||
# Exponentiation
|
||||
# --------------------------------------------------------
|
||||
|
||||
{.push raises: [], noinit, gcsafe.}
|
||||
|
||||
func pow*(a: StUint, e: Natural): StUint =
|
||||
## Compute ``a`` to the power of ``e``,
|
||||
## ``e`` must be non-negative
|
||||
|
||||
func pow*[aBits, eBits](a: StUint[aBits], e: StUint[eBits]): StUint[aBits] =
|
||||
## Compute ``x`` to the power of ``y``,
|
||||
## ``x`` must be non-negative
|
|
@ -135,16 +135,22 @@ func `shl`*(a: StUint, k: Natural): StUint =
|
|||
result.shiftLeft(a, k)
|
||||
|
||||
func setBit*(a: var StUint, k: Natural) =
|
||||
## set bit at position `k`
|
||||
## k = 0..a.bits-1
|
||||
let limbIndex = k div WordBitWidth
|
||||
let bitIndex = k mod WordBitWidth
|
||||
setBit(a.limbs[limbIndex], bitIndex)
|
||||
|
||||
func clearBit*(a: var StUint, k: Natural) =
|
||||
## set bit at position `k`
|
||||
## k = 0..a.bits-1
|
||||
let limbIndex = k div WordBitWidth
|
||||
let bitIndex = k mod WordBitWidth
|
||||
clearBit(a.limbs[limbIndex], bitIndex)
|
||||
|
||||
func getBit*(a: StUint, k: Natural): bool =
|
||||
## set bit at position `k`
|
||||
## k = 0..a.bits-1
|
||||
let limbIndex = k div WordBitWidth
|
||||
let bitIndex = k mod WordBitWidth
|
||||
getBit(a.limbs[limbIndex], bitIndex)
|
||||
|
|
|
@ -12,11 +12,11 @@ import
|
|||
test_uint_bitops2,
|
||||
test_uint_bitwise,
|
||||
test_uint_comparison,
|
||||
#test_uint_divmod,
|
||||
test_uint_divmod,
|
||||
test_uint_endianness,
|
||||
test_uint_endians2,
|
||||
test_uint_exp,
|
||||
#test_uint_modular_arithmetic,
|
||||
test_uint_modular_arithmetic,
|
||||
test_uint_mul
|
||||
|
||||
import
|
||||
|
@ -25,10 +25,10 @@ import
|
|||
test_int_comparison,
|
||||
test_int_bitwise,
|
||||
test_int_addsub,
|
||||
#[
|
||||
test_int_endianness,
|
||||
test_int_muldiv,
|
||||
test_int_muldiv
|
||||
|
||||
#[
|
||||
import test_io,
|
||||
test_conversion
|
||||
]#
|
||||
|
|
|
@ -20,36 +20,6 @@ template chkDivMod(chk: untyped, a, b, c, d: string, bits: int) =
|
|||
|
||||
template testdivmod(chk, tst: untyped) =
|
||||
tst "operator `div`":
|
||||
#[chkDiv(chk, "0", "3", "0", 8)
|
||||
chkDiv(chk, "1", "3", "0", 8)
|
||||
chkDiv(chk, "3", "3", "1", 8)
|
||||
chkDiv(chk, "3", "1", "3", 8)
|
||||
chkDiv(chk, "FF", "3", "55", 8)
|
||||
|
||||
chkDiv(chk, "0", "3", "0", 16)
|
||||
chkDiv(chk, "1", "3", "0", 16)
|
||||
chkDiv(chk, "3", "3", "1", 16)
|
||||
chkDiv(chk, "3", "1", "3", 16)
|
||||
chkDiv(chk, "FF", "3", "55", 16)
|
||||
chkDiv(chk, "FFFF", "3", "5555", 16)
|
||||
|
||||
chkDiv(chk, "0", "3", "0", 32)
|
||||
chkDiv(chk, "1", "3", "0", 32)
|
||||
chkDiv(chk, "3", "3", "1", 32)
|
||||
chkDiv(chk, "3", "1", "3", 32)
|
||||
chkDiv(chk, "FF", "3", "55", 32)
|
||||
chkDiv(chk, "FFFF", "3", "5555", 32)
|
||||
chkDiv(chk, "FFFFFFFF", "3", "55555555", 32)
|
||||
|
||||
chkDiv(chk, "0", "3", "0", 64)
|
||||
chkDiv(chk, "1", "3", "0", 64)
|
||||
chkDiv(chk, "3", "3", "1", 64)
|
||||
chkDiv(chk, "3", "1", "3", 64)
|
||||
chkDiv(chk, "FF", "3", "55", 64)
|
||||
chkDiv(chk, "FFFF", "3", "5555", 64)
|
||||
chkDiv(chk, "FFFFFFFF", "3", "55555555", 64)
|
||||
chkDiv(chk, "FFFFFFFFFFFFFFFF", "3", "5555555555555555", 64)]#
|
||||
|
||||
chkDiv(chk, "0", "3", "0", 128)
|
||||
chkDiv(chk, "1", "3", "0", 128)
|
||||
chkDiv(chk, "3", "3", "1", 128)
|
||||
|
@ -61,48 +31,6 @@ template testdivmod(chk, tst: untyped) =
|
|||
chkDiv(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "3", "55555555555555555555555555555555", 128)
|
||||
|
||||
tst "operator `mod`":
|
||||
#[chkMod(chk, "0", "3", "0", 8)
|
||||
chkMod(chk, "1", "3", "1", 8)
|
||||
chkMod(chk, "3", "3", "0", 8)
|
||||
chkMod(chk, "3", "1", "0", 8)
|
||||
chkMod(chk, "FF", "3", "0", 8)
|
||||
chkMod(chk, "FF", "4", "3", 8)
|
||||
|
||||
chkMod(chk, "0", "3", "0", 16)
|
||||
chkMod(chk, "1", "3", "1", 16)
|
||||
chkMod(chk, "3", "3", "0", 16)
|
||||
chkMod(chk, "3", "1", "0", 16)
|
||||
chkMod(chk, "FF", "3", "0", 16)
|
||||
chkMod(chk, "FF", "4", "3", 16)
|
||||
chkMod(chk, "FFFF", "3", "0", 16)
|
||||
chkMod(chk, "FFFF", "4", "3", 16)
|
||||
chkMod(chk, "FFFF", "17", "8", 16)
|
||||
|
||||
chkMod(chk, "0", "3", "0", 32)
|
||||
chkMod(chk, "1", "3", "1", 32)
|
||||
chkMod(chk, "3", "3", "0", 32)
|
||||
chkMod(chk, "3", "1", "0", 32)
|
||||
chkMod(chk, "FF", "3", "0", 32)
|
||||
chkMod(chk, "FF", "4", "3", 32)
|
||||
chkMod(chk, "FFFF", "3", "0", 32)
|
||||
chkMod(chk, "FFFF", "17", "8", 32)
|
||||
chkMod(chk, "FFFFFFFF", "3", "0", 32)
|
||||
chkMod(chk, "FFFFFFFF", "23", "A", 32)
|
||||
chkMod(chk, "FFFFFFFF", "27", "15", 32)
|
||||
|
||||
chkMod(chk, "0", "3", "0", 64)
|
||||
chkMod(chk, "1", "3", "1", 64)
|
||||
chkMod(chk, "3", "3", "0", 64)
|
||||
chkMod(chk, "3", "1", "0", 64)
|
||||
chkMod(chk, "FF", "3", "0", 64)
|
||||
chkMod(chk, "FF", "4", "3", 64)
|
||||
chkMod(chk, "FFFF", "3", "0", 64)
|
||||
chkMod(chk, "FFFF", "17", "8", 64)
|
||||
chkMod(chk, "FFFFFFFF", "3", "0", 64)
|
||||
chkMod(chk, "FFFFFFFF", "23", "A", 64)
|
||||
chkMod(chk, "FFFFFFFF", "27", "15", 64)
|
||||
chkMod(chk, "FFFFFFFFFFFFFFFF", "27", "F", 64)]#
|
||||
|
||||
chkMod(chk, "0", "3", "0", 128)
|
||||
chkMod(chk, "1", "3", "1", 128)
|
||||
chkMod(chk, "3", "3", "0", 128)
|
||||
|
@ -118,48 +46,6 @@ template testdivmod(chk, tst: untyped) =
|
|||
chkMod(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "27", "15", 128)
|
||||
|
||||
tst "operator `divmod`":
|
||||
#[chkDivMod(chk, "0", "3", "0", "0", 8)
|
||||
chkDivMod(chk, "1", "3", "0", "1", 8)
|
||||
chkDivMod(chk, "3", "3", "1", "0", 8)
|
||||
chkDivMod(chk, "3", "1", "3", "0", 8)
|
||||
chkDivMod(chk, "FF", "3", "55", "0", 8)
|
||||
chkDivMod(chk, "FF", "4", "3F", "3", 8)
|
||||
|
||||
chkDivMod(chk, "0", "3", "0", "0", 16)
|
||||
chkDivMod(chk, "1", "3", "0", "1", 16)
|
||||
chkDivMod(chk, "3", "3", "1", "0", 16)
|
||||
chkDivMod(chk, "3", "1", "3", "0", 16)
|
||||
chkDivMod(chk, "FF", "3", "55", "0", 16)
|
||||
chkDivMod(chk, "FF", "4", "3F", "3", 16)
|
||||
chkDivMod(chk, "FFFF", "3", "5555", "0", 16)
|
||||
chkDivMod(chk, "FFFF", "4", "3FFF", "3", 16)
|
||||
chkDivMod(chk, "FFFF", "17", "B21", "8", 16)
|
||||
|
||||
chkDivMod(chk, "0", "3", "0", "0", 32)
|
||||
chkDivMod(chk, "1", "3", "0", "1", 32)
|
||||
chkDivMod(chk, "3", "3", "1", "0", 32)
|
||||
chkDivMod(chk, "3", "1", "3", "0", 32)
|
||||
chkDivMod(chk, "FF", "3", "55", "0", 32)
|
||||
chkDivMod(chk, "FF", "4", "3F", "3", 32)
|
||||
chkDivMod(chk, "FFFF", "3", "5555", "0", 32)
|
||||
chkDivMod(chk, "FFFF", "17", "B21", "8", 32)
|
||||
chkDivMod(chk, "FFFFFFFF", "3", "55555555", "0", 32)
|
||||
chkDivMod(chk, "FFFFFFFF", "23", "7507507", "0A", 32)
|
||||
chkDivMod(chk, "FFFFFFFF", "27", "6906906", "15", 32)
|
||||
|
||||
chkDivMod(chk, "0", "3", "0", "0", 64)
|
||||
chkDivMod(chk, "1", "3", "0", "1", 64)
|
||||
chkDivMod(chk, "3", "3", "1", "0", 64)
|
||||
chkDivMod(chk, "3", "1", "3", "0", 64)
|
||||
chkDivMod(chk, "FF", "3", "55", "0", 64)
|
||||
chkDivMod(chk, "FF", "4", "3F", "3", 64)
|
||||
chkDivMod(chk, "FFFF", "3", "5555", "0", 64)
|
||||
chkDivMod(chk, "FFFF", "17", "B21", "8", 64)
|
||||
chkDivMod(chk, "FFFFFFFF", "3", "55555555", "0", 64)
|
||||
chkDivMod(chk, "FFFFFFFF", "23", "7507507", "0A", 64)
|
||||
chkDivMod(chk, "FFFFFFFF", "27", "6906906", "15", 64)
|
||||
chkDivMod(chk, "FFFFFFFFFFFFFFFF", "27", "690690690690690", "F", 64)]#
|
||||
|
||||
chkDivMod(chk, "0", "3", "0", "0", 128)
|
||||
chkDivMod(chk, "1", "3", "0", "1", 128)
|
||||
chkDivMod(chk, "3", "3", "1", "0", 128)
|
||||
|
@ -174,50 +60,47 @@ template testdivmod(chk, tst: untyped) =
|
|||
chkDivMod(chk, "FFFFFFFFFFFFFFFF", "27", "690690690690690", "F", 128)
|
||||
chkDivMod(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "27", "6906906906906906906906906906906", "15", 128)
|
||||
|
||||
static:
|
||||
testdivmod(ctCheck, ctTest)
|
||||
#static:
|
||||
#testdivmod(ctCheck, ctTest)
|
||||
|
||||
suite "Wider unsigned int muldiv coverage":
|
||||
testdivmod(check, test)
|
||||
|
||||
#[
|
||||
suite "Testing unsigned int division and modulo implementation":
|
||||
test "Divmod(100, 13) returns the correct result":
|
||||
|
||||
let a = 100.stuint(64)
|
||||
let b = 13.stuint(64)
|
||||
let a = 100.stuint(256)
|
||||
let b = 13.stuint(256)
|
||||
let qr = divmod(a, b)
|
||||
|
||||
check: cast[uint64](qr.quot) == 7'u64
|
||||
check: cast[uint64](qr.rem) == 9'u64
|
||||
check qr.quot == 7'u64.u256
|
||||
check qr.rem == 9'u64.u256
|
||||
|
||||
# TODO - no more .lo / .hi
|
||||
#
|
||||
# test "Divmod(2^64, 3) returns the correct result":
|
||||
# let a = 1.stuint(128) shl 64
|
||||
# let b = 3.stuint(128)
|
||||
#
|
||||
# let qr = divmod(a, b)
|
||||
#
|
||||
# let q = cast[UintImpl[uint64]](qr.quot)
|
||||
# let r = cast[UintImpl[uint64]](qr.rem)
|
||||
#
|
||||
# check: q.lo == 6148914691236517205'u64
|
||||
# check: q.hi == 0'u64
|
||||
# check: r.lo == 1'u64
|
||||
# check: r.hi == 0'u64
|
||||
test "Divmod(2^64, 3) returns the correct result":
|
||||
let a = 1.stuint(128) shl 64
|
||||
let b = 3.stuint(128)
|
||||
|
||||
let qr = divmod(a, b)
|
||||
|
||||
let q = qr.quot
|
||||
let r = qr.rem
|
||||
|
||||
check:
|
||||
q == 6148914691236517205'u64.u128
|
||||
r == 1'u64.u128
|
||||
|
||||
test "Divmod(1234567891234567890, 10) returns the correct result":
|
||||
let a = cast[StUint[64]](1234567891234567890'u64)
|
||||
let b = cast[StUint[64]](10'u64)
|
||||
let a = 1234567891234567890'u64.u256
|
||||
let b = 10'u64.u256
|
||||
|
||||
let qr = divmod(a, b)
|
||||
|
||||
let q = cast[uint64](qr.quot)
|
||||
let r = cast[uint64](qr.rem)
|
||||
let q = qr.quot
|
||||
let r = qr.rem
|
||||
|
||||
check: q == 123456789123456789'u64
|
||||
check: r == 0'u64
|
||||
check:
|
||||
q == 123456789123456789'u64.u256
|
||||
r == 0'u64.u256
|
||||
|
||||
suite "Testing specific failures highlighted by property-based testing":
|
||||
test "Modulo: 65696211516342324 mod 174261910798982":
|
||||
|
@ -225,23 +108,22 @@ suite "Testing specific failures highlighted by property-based testing":
|
|||
let u = 65696211516342324'u64
|
||||
let v = 174261910798982'u64
|
||||
|
||||
let a = cast[StUint[64]](u)
|
||||
let b = cast[StUint[64]](v)
|
||||
let a = u.u256
|
||||
let b = v.u256
|
||||
|
||||
let z = u mod v
|
||||
let tz = cast[uint64](a mod b)
|
||||
let tz = a mod b
|
||||
|
||||
check: z == tz
|
||||
check z.u256 == tz
|
||||
|
||||
test "Modulo: 15080397990160655 mod 600432699691":
|
||||
let u = 15080397990160655'u64
|
||||
let v = 600432699691'u64
|
||||
|
||||
let a = cast[StUint[64]](u)
|
||||
let b = cast[StUint[64]](v)
|
||||
let a = u.u256
|
||||
let b = v.u256
|
||||
|
||||
let z = u mod v
|
||||
let tz = cast[uint64](a mod b)
|
||||
let tz = a mod b
|
||||
|
||||
check: z == tz
|
||||
]#
|
||||
check z.u256 == tz
|
||||
|
|
|
@ -17,20 +17,6 @@ template chkPow(chk: untyped, a: string, b: SomeInteger, c: string, bits: int) =
|
|||
|
||||
template testExp(chk, tst: untyped) =
|
||||
tst "BigInt BigInt Pow":
|
||||
#[chkPow(chk, "F", "2", "E1", 8)
|
||||
|
||||
chkPow(chk, "F", "2", "E1", 16)
|
||||
chkPow(chk, "FF", "2", "FE01", 16)
|
||||
|
||||
chkPow(chk, "F", "2", "E1", 32)
|
||||
chkPow(chk, "FF", "2", "FE01", 32)
|
||||
chkPow(chk, "FF", "3", "FD02FF", 32)
|
||||
|
||||
chkPow(chk, "F", "2", "E1", 64)
|
||||
chkPow(chk, "FF", "2", "FE01", 64)
|
||||
chkPow(chk, "FF", "3", "FD02FF", 64)
|
||||
chkPow(chk, "FFF", "3", "FFD002FFF", 64)]#
|
||||
|
||||
chkPow(chk, "F", "2", "E1", 128)
|
||||
chkPow(chk, "FF", "2", "FE01", 128)
|
||||
chkPow(chk, "FF", "3", "FD02FF", 128)
|
||||
|
@ -38,20 +24,6 @@ template testExp(chk, tst: untyped) =
|
|||
chkPow(chk, "FFFFF", "3", "ffffd00002fffff", 128)
|
||||
|
||||
tst "BigInt Natural Pow":
|
||||
#[chkPow(chk, "F", 2, "E1", 8)
|
||||
|
||||
chkPow(chk, "F", 2, "E1", 16)
|
||||
chkPow(chk, "FF", 2, "FE01", 16)
|
||||
|
||||
chkPow(chk, "F", 2, "E1", 32)
|
||||
chkPow(chk, "FF", 2, "FE01", 32)
|
||||
chkPow(chk, "FF", 3, "FD02FF", 32)
|
||||
|
||||
chkPow(chk, "F", 2, "E1", 64)
|
||||
chkPow(chk, "FF", 2, "FE01", 64)
|
||||
chkPow(chk, "FF", 3, "FD02FF", 64)
|
||||
chkPow(chk, "FFF", 3, "FFD002FFF", 64)]#
|
||||
|
||||
chkPow(chk, "F", 2, "E1", 128)
|
||||
chkPow(chk, "FF", 2, "FE01", 128)
|
||||
chkPow(chk, "FF", 3, "FD02FF", 128)
|
||||
|
@ -64,7 +36,6 @@ static:
|
|||
suite "Wider unsigned int exp coverage":
|
||||
testExp(check, test)
|
||||
|
||||
#[
|
||||
suite "Testing unsigned exponentiation":
|
||||
test "Simple exponentiation 5^3":
|
||||
|
||||
|
@ -85,4 +56,3 @@ suite "Testing unsigned exponentiation":
|
|||
|
||||
check: a.pow(b) == "4922235242952026704037113243122008064".u256
|
||||
check: a.pow(b.stuint(256)) == "4922235242952026704037113243122008064".u256
|
||||
]#
|
|
@ -23,21 +23,6 @@ template chkPowMod(chk: untyped, a, b, m, c: string, bits: int) =
|
|||
|
||||
template testModArith(chk, tst: untyped) =
|
||||
tst "addmod":
|
||||
#[chkAddMod(chk, "F", "F", "7", "2", 8)
|
||||
chkAddMod(chk, "AAAA", "AA", "F", "0", 16)
|
||||
chkAddMod(chk, "BBBB", "AAAA", "9", "3", 16)
|
||||
|
||||
chkAddMod(chk, "F", "F", "7", "2", 32)
|
||||
chkAddMod(chk, "AAAA", "AA", "F", "0", 32)
|
||||
chkAddMod(chk, "BBBB", "AAAA", "9", "3", 32)
|
||||
chkAddMod(chk, "BBBBBBBB", "AAAAAAAA", "9", "6", 32)
|
||||
|
||||
chkAddMod(chk, "F", "F", "7", "2", 64)
|
||||
chkAddMod(chk, "AAAA", "AA", "F", "0", 64)
|
||||
chkAddMod(chk, "BBBB", "AAAA", "9", "3", 64)
|
||||
chkAddMod(chk, "BBBBBBBB", "AAAAAAAA", "9", "6", 64)
|
||||
chkAddMod(chk, "BBBBBBBBBBBBBBBB", "AAAAAAAAAAAAAAAA", "9", "3", 64)]#
|
||||
|
||||
chkAddMod(chk, "F", "F", "7", "2", 128)
|
||||
chkAddMod(chk, "AAAA", "AA", "F", "0", 128)
|
||||
chkAddMod(chk, "BBBB", "AAAA", "9", "3", 128)
|
||||
|
@ -45,27 +30,7 @@ template testModArith(chk, tst: untyped) =
|
|||
chkAddMod(chk, "BBBBBBBBBBBBBBBB", "AAAAAAAAAAAAAAAA", "9", "3", 128)
|
||||
chkAddMod(chk, "BBBBBBBBBBBBBBBBBBBBBBBBBBBBBBBB", "AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA", "9", "6", 128)
|
||||
|
||||
|
||||
tst "submod":
|
||||
#[chkSubMod(chk, "C", "3", "C", "9", 8)
|
||||
chkSubMod(chk, "1", "3", "C", "A", 8)
|
||||
chkSubMod(chk, "1", "FF", "C", "A", 8)
|
||||
|
||||
chkSubMod(chk, "C", "3", "C", "9", 16)
|
||||
chkSubMod(chk, "1", "3", "C", "A", 16)
|
||||
chkSubMod(chk, "1", "FFFF", "C", "A", 32)
|
||||
|
||||
chkSubMod(chk, "C", "3", "C", "9", 32)
|
||||
chkSubMod(chk, "1", "3", "C", "A", 32)
|
||||
chkSubMod(chk, "1", "FFFF", "C", "A", 32)
|
||||
chkSubMod(chk, "1", "FFFFFFFF", "C", "A", 32)
|
||||
|
||||
chkSubMod(chk, "C", "3", "C", "9", 64)
|
||||
chkSubMod(chk, "1", "3", "C", "A", 64)
|
||||
chkSubMod(chk, "1", "FFFF", "C", "A", 64)
|
||||
chkSubMod(chk, "1", "FFFFFFFF", "C", "A", 64)
|
||||
chkSubMod(chk, "1", "FFFFFFFFFFFFFFFF", "C", "A", 64)]#
|
||||
|
||||
chkSubMod(chk, "C", "3", "C", "9", 128)
|
||||
chkSubMod(chk, "1", "3", "C", "A", 128)
|
||||
chkSubMod(chk, "1", "FFFF", "C", "A", 128)
|
||||
|
@ -74,25 +39,6 @@ template testModArith(chk, tst: untyped) =
|
|||
chkSubMod(chk, "1", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "C", "A", 128)
|
||||
|
||||
tst "mulmod":
|
||||
#[chkMulMod(chk, "C", "3", "C", "0", 8)
|
||||
chkMulMod(chk, "1", "3", "C", "3", 8)
|
||||
chkMulMod(chk, "1", "FF", "C", "3", 8)
|
||||
|
||||
chkMulMod(chk, "C", "3", "C", "0", 16)
|
||||
chkMulMod(chk, "1", "3", "C", "3", 16)
|
||||
chkMulMod(chk, "1", "FFFF", "C", "3", 16)
|
||||
|
||||
chkMulMod(chk, "C", "3", "C", "0", 32)
|
||||
chkMulMod(chk, "1", "3", "C", "3", 32)
|
||||
chkMulMod(chk, "1", "FFFF", "C", "3", 32)
|
||||
chkMulMod(chk, "1", "FFFFFFFF", "C", "3", 32)
|
||||
|
||||
chkMulMod(chk, "C", "3", "C", "0", 64)
|
||||
chkMulMod(chk, "1", "3", "C", "3", 64)
|
||||
chkMulMod(chk, "1", "FFFF", "C", "3", 64)
|
||||
chkMulMod(chk, "1", "FFFFFFFF", "C", "3", 64)
|
||||
chkMulMod(chk, "1", "FFFFFFFFFFFFFFFF", "C", "3", 64)]#
|
||||
|
||||
chkMulMod(chk, "C", "3", "C", "0", 128)
|
||||
chkMulMod(chk, "1", "3", "C", "3", 128)
|
||||
chkMulMod(chk, "1", "FFFF", "C", "3", 128)
|
||||
|
@ -100,89 +46,57 @@ template testModArith(chk, tst: untyped) =
|
|||
chkMulMod(chk, "1", "FFFFFFFFFFFFFFFF", "C", "3", 128)
|
||||
chkMulMod(chk, "1", "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "C", "3", 128)
|
||||
|
||||
# TODO: bug #98
|
||||
when nimvm:
|
||||
# this ugly branch needed due to nim-lang/Nim#12518
|
||||
discard
|
||||
else:
|
||||
tst "powmod":
|
||||
#[chkPowMod(chk, "C", "3", "C", "0", 8)
|
||||
chkPowMod(chk, "1", "3", "C", "1", 8)
|
||||
chkPowMod(chk, "1", "FF", "C", "1", 8)
|
||||
chkPowMod(chk, "FF", "3", "C", "3", 8)
|
||||
tst "powmod":
|
||||
chkPowMod(chk, "C", "3", "C", "0", 128)
|
||||
chkPowMod(chk, "1", "3", "C", "1", 128)
|
||||
chkPowMod(chk, "1", "FF", "C", "1", 128)
|
||||
chkPowMod(chk, "FF", "3", "C", "3", 128)
|
||||
chkPowMod(chk, "FFFF", "3", "C", "3", 128)
|
||||
chkPowMod(chk, "FFFFFFFF", "3", "C", "3", 128)
|
||||
chkPowMod(chk, "FFFFFFFFFFFFFFFF", "3", "C", "3", 128)
|
||||
chkPowMod(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "3", "C", "3", 128)
|
||||
|
||||
chkPowMod(chk, "C", "3", "C", "0", 16)
|
||||
chkPowMod(chk, "1", "3", "C", "1", 16)
|
||||
chkPowMod(chk, "1", "FF", "C", "1", 16)
|
||||
chkPowMod(chk, "FF", "3", "C", "3", 16)
|
||||
chkPowMod(chk, "FFFF", "3", "C", "3", 16)
|
||||
|
||||
chkPowMod(chk, "C", "3", "C", "0", 32)
|
||||
chkPowMod(chk, "1", "3", "C", "1", 32)
|
||||
chkPowMod(chk, "1", "FF", "C", "1", 32)
|
||||
chkPowMod(chk, "FF", "3", "C", "3", 32)
|
||||
chkPowMod(chk, "FFFF", "3", "C", "3", 32)
|
||||
chkPowMod(chk, "FFFFFFFF", "3", "C", "3", 32)
|
||||
|
||||
chkPowMod(chk, "C", "3", "C", "0", 64)
|
||||
chkPowMod(chk, "1", "3", "C", "1", 64)
|
||||
chkPowMod(chk, "1", "FF", "C", "1", 64)
|
||||
chkPowMod(chk, "FF", "3", "C", "3", 64)
|
||||
chkPowMod(chk, "FFFF", "3", "C", "3", 64)
|
||||
chkPowMod(chk, "FFFFFFFF", "3", "C", "3", 64)
|
||||
chkPowMod(chk, "FFFFFFFFFFFFFFFF", "3", "C", "3", 64)]#
|
||||
|
||||
chkPowMod(chk, "C", "3", "C", "0", 128)
|
||||
chkPowMod(chk, "1", "3", "C", "1", 128)
|
||||
chkPowMod(chk, "1", "FF", "C", "1", 128)
|
||||
chkPowMod(chk, "FF", "3", "C", "3", 128)
|
||||
chkPowMod(chk, "FFFF", "3", "C", "3", 128)
|
||||
chkPowMod(chk, "FFFFFFFF", "3", "C", "3", 128)
|
||||
chkPowMod(chk, "FFFFFFFFFFFFFFFF", "3", "C", "3", 128)
|
||||
chkPowMod(chk, "FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF", "3", "C", "3", 128)
|
||||
|
||||
static:
|
||||
testModArith(ctCheck, ctTest)
|
||||
#static:
|
||||
#testModArith(ctCheck, ctTest)
|
||||
|
||||
suite "Wider unsigned Modular arithmetic coverage":
|
||||
testModArith(check, test)
|
||||
|
||||
#[
|
||||
suite "Modular arithmetic":
|
||||
test "Modular addition":
|
||||
|
||||
# uint16 rolls over at 65535
|
||||
let a = 50000'u16.stuint(16)
|
||||
let b = 20000'u16.stuint(16)
|
||||
let m = 60000'u16.stuint(16)
|
||||
let a = 50000.u256
|
||||
let b = 20000.u256
|
||||
let m = 60000.u256
|
||||
|
||||
check: addmod(a, b, m) == 10000'u16.stuint(16)
|
||||
check: addmod(a, b, m) == 10000.u256
|
||||
|
||||
test "Modular substraction":
|
||||
|
||||
let a = 5'u16.stuint(16)
|
||||
let b = 7'u16.stuint(16)
|
||||
let m = 20'u16.stuint(16)
|
||||
let a = 5.u256
|
||||
let b = 7.u256
|
||||
let m = 20.u256
|
||||
|
||||
check: submod(a, b, m) == 18'u16.stuint(16)
|
||||
check: submod(a, b, m) == 18.u256
|
||||
|
||||
test "Modular multiplication":
|
||||
# https://www.wolframalpha.com/input/?i=(1234567890+*+987654321)+mod+999999999
|
||||
# --> 345_679_002
|
||||
let a = 1234567890'u64.stuint(64)
|
||||
let b = 987654321'u64.stuint(64)
|
||||
let m = 999999999'u64.stuint(64)
|
||||
let a = 1234567890.u256
|
||||
let b = 987654321.u256
|
||||
let m = 999999999.u256
|
||||
|
||||
check: mulmod(a, b, m) == 345_679_002'u64.stuint(64)
|
||||
check: mulmod(a, b, m) == 345_679_002.u256
|
||||
|
||||
test "Modular exponentiation":
|
||||
block: # https://www.khanacademy.org/computing/computer-science/cryptography/modarithmetic/a/fast-modular-exponentiation
|
||||
check:
|
||||
powmod(5'u16.stuint(16), 117'u16.stuint(16), 19'u16.stuint(16)) == 1'u16.stuint(16)
|
||||
powmod(3'u16.stuint(16), 1993'u16.stuint(16), 17'u16.stuint(16)) == 14'u16.stuint(16)
|
||||
powmod(5.u256, 117.u256, 19.u256) == 1.u256
|
||||
powmod(3.u256, 1993.u256, 17.u256) == 14.u256
|
||||
|
||||
check:
|
||||
powmod(12.stuint(256), 34.stuint(256), high(UInt256)) == "4922235242952026704037113243122008064".u256
|
||||
powmod(12.u256, 34.u256, high(UInt256)) == "4922235242952026704037113243122008064".u256
|
||||
|
||||
block: # Little Fermat theorem
|
||||
# https://programmingpraxis.com/2014/08/08/big-modular-exponentiation/
|
||||
|
@ -203,4 +117,3 @@ suite "Modular arithmetic":
|
|||
|
||||
check:
|
||||
powmod(P, Q, M) == expected
|
||||
]#
|
||||
|
|
Loading…
Reference in New Issue