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