cleanup some code

This commit is contained in:
jangko 2023-06-14 08:06:44 +07:00
parent 8ea95078f4
commit 1657d841e7
No known key found for this signature in database
GPG Key ID: 31702AE10541E6B9
7 changed files with 102 additions and 306 deletions

View File

@ -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)

View File

@ -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.}
@ -215,4 +227,17 @@ func `+=`*(a: var StInt, b: SomeUnsignedInt) =
## with an unsigned integer
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

View File

@ -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)

View File

@ -7,28 +7,28 @@
#
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
import
test_uint_addsub,
test_uint_bitops2,
test_uint_bitwise,
test_uint_comparison,
#test_uint_divmod,
test_uint_divmod,
test_uint_endianness,
test_uint_endians2,
test_uint_endians2,
test_uint_exp,
#test_uint_modular_arithmetic,
test_uint_modular_arithmetic,
test_uint_mul
import
import
test_int_signedness,
test_int_initialization,
test_int_comparison,
test_int_bitwise,
test_int_addsub,
#[
test_int_endianness,
test_int_muldiv,
test_int_endianness,
test_int_muldiv
#[
import test_io,
test_conversion
]#

View File

@ -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

View File

@ -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
]#

View File

@ -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
]#