Wrap tests in main. Fixes C codegen bug due to templates invocation on global variable in test_primitives
This commit is contained in:
parent
fe59efb8d8
commit
89fce3b1c4
|
@ -20,4 +20,4 @@ task test, "Run all tests":
|
||||||
test "", "tests/test_io.nim"
|
test "", "tests/test_io.nim"
|
||||||
test "", "tests/test_bigints.nim"
|
test "", "tests/test_bigints.nim"
|
||||||
test "", "tests/test_bigints_multimod.nim"
|
test "", "tests/test_bigints_multimod.nim"
|
||||||
test " -d:testingCurves", "tests/test_field_fp.nim"
|
# test " -d:testingCurves", "tests/test_field_fp.nim"
|
||||||
|
|
|
@ -12,194 +12,197 @@ import unittest, random, strutils,
|
||||||
../constantine/config/common,
|
../constantine/config/common,
|
||||||
../constantine/primitives/constant_time
|
../constantine/primitives/constant_time
|
||||||
|
|
||||||
suite "isZero":
|
proc main() =
|
||||||
test "isZero for zero":
|
suite "isZero":
|
||||||
var x: BigInt[128]
|
test "isZero for zero":
|
||||||
check: x.isZero().bool
|
var x: BigInt[128]
|
||||||
test "isZero for non-zero":
|
check: x.isZero().bool
|
||||||
block:
|
test "isZero for non-zero":
|
||||||
var x = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
block:
|
||||||
check: not x.isZero().bool
|
var x = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||||
block:
|
check: not x.isZero().bool
|
||||||
var x = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
block:
|
||||||
check: not x.isZero().bool
|
var x = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
||||||
block:
|
check: not x.isZero().bool
|
||||||
var x = fromHex(BigInt[128], "0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF")
|
block:
|
||||||
check: not x.isZero().bool
|
var x = fromHex(BigInt[128], "0xFFFFFFFF_FFFFFFFF_FFFFFFFF_FFFFFFFF")
|
||||||
|
check: not x.isZero().bool
|
||||||
|
|
||||||
suite "Arithmetic operations - Addition":
|
suite "Arithmetic operations - Addition":
|
||||||
test "Adding 2 zeros":
|
test "Adding 2 zeros":
|
||||||
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
|
||||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
|
||||||
let carry = a.add(b, ctrue(Word))
|
|
||||||
check: a.isZero().bool
|
|
||||||
|
|
||||||
test "Adding 1 zero - real addition":
|
|
||||||
block:
|
|
||||||
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
||||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
||||||
let carry = a.add(b, ctrue(Word))
|
|
||||||
|
|
||||||
let c = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
||||||
check:
|
|
||||||
bool(a == c)
|
|
||||||
block:
|
|
||||||
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
||||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
||||||
let carry = a.add(b, ctrue(Word))
|
let carry = a.add(b, ctrue(Word))
|
||||||
|
check: a.isZero().bool
|
||||||
|
|
||||||
let c = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
test "Adding 1 zero - real addition":
|
||||||
check:
|
block:
|
||||||
bool(a == c)
|
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
||||||
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||||
|
let carry = a.add(b, ctrue(Word))
|
||||||
|
|
||||||
test "Adding 1 zero - fake addition":
|
let c = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||||
block:
|
check:
|
||||||
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
bool(a == c)
|
||||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
block:
|
||||||
let carry = a.add(b, cfalse(Word))
|
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||||
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
||||||
|
let carry = a.add(b, ctrue(Word))
|
||||||
|
|
||||||
let c = a
|
let c = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||||
check:
|
check:
|
||||||
bool(a == c)
|
bool(a == c)
|
||||||
block:
|
|
||||||
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
||||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
|
||||||
let carry = a.add(b, cfalse(Word))
|
|
||||||
|
|
||||||
let c = a
|
test "Adding 1 zero - fake addition":
|
||||||
check:
|
block:
|
||||||
bool(a == c)
|
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
||||||
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||||
|
let carry = a.add(b, cfalse(Word))
|
||||||
|
|
||||||
test "Adding non-zeros - real addition":
|
let c = a
|
||||||
block:
|
check:
|
||||||
var a = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
bool(a == c)
|
||||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
block:
|
||||||
let carry = a.add(b, ctrue(Word))
|
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||||
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000000")
|
||||||
|
let carry = a.add(b, cfalse(Word))
|
||||||
|
|
||||||
let c = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000001")
|
let c = a
|
||||||
check:
|
check:
|
||||||
bool(a == c)
|
bool(a == c)
|
||||||
block:
|
|
||||||
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
||||||
let b = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
|
||||||
let carry = a.add(b, ctrue(Word))
|
|
||||||
|
|
||||||
let c = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000001")
|
test "Adding non-zeros - real addition":
|
||||||
check:
|
block:
|
||||||
bool(a == c)
|
var a = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
||||||
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||||
|
let carry = a.add(b, ctrue(Word))
|
||||||
|
|
||||||
test "Adding non-zeros - fake addition":
|
let c = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000001")
|
||||||
block:
|
check:
|
||||||
var a = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
bool(a == c)
|
||||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
block:
|
||||||
let carry = a.add(b, cfalse(Word))
|
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||||
|
let b = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
||||||
|
let carry = a.add(b, ctrue(Word))
|
||||||
|
|
||||||
let c = a
|
let c = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000001")
|
||||||
check:
|
check:
|
||||||
bool(a == c)
|
bool(a == c)
|
||||||
block:
|
|
||||||
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
|
||||||
let b = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
|
||||||
let carry = a.add(b, cfalse(Word))
|
|
||||||
|
|
||||||
let c = a
|
test "Adding non-zeros - fake addition":
|
||||||
check:
|
block:
|
||||||
bool(a == c)
|
var a = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
||||||
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||||
|
let carry = a.add(b, cfalse(Word))
|
||||||
|
|
||||||
test "Addition limbs carry":
|
let c = a
|
||||||
block:
|
check:
|
||||||
var a = fromHex(BigInt[128], "0x00000000_FFFFFFFF_FFFFFFFF_FFFFFFFE")
|
bool(a == c)
|
||||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
block:
|
||||||
let carry = a.add(b, ctrue(Word))
|
var a = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||||
|
let b = fromHex(BigInt[128], "0x00000000_00000001_00000000_00000000")
|
||||||
|
let carry = a.add(b, cfalse(Word))
|
||||||
|
|
||||||
let c = fromHex(BigInt[128], "0x00000000_FFFFFFFF_FFFFFFFF_FFFFFFFF")
|
let c = a
|
||||||
check:
|
check:
|
||||||
bool(a == c)
|
bool(a == c)
|
||||||
not bool(carry)
|
|
||||||
|
|
||||||
block:
|
test "Addition limbs carry":
|
||||||
var a = fromHex(BigInt[128], "0x00000000_FFFFFFFF_FFFFFFFF_FFFFFFFF")
|
block:
|
||||||
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
var a = fromHex(BigInt[128], "0x00000000_FFFFFFFF_FFFFFFFF_FFFFFFFE")
|
||||||
let carry = a.add(b, ctrue(Word))
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||||
|
let carry = a.add(b, ctrue(Word))
|
||||||
|
|
||||||
let c = fromHex(BigInt[128], "0x00000001_00000000_00000000_00000000")
|
let c = fromHex(BigInt[128], "0x00000000_FFFFFFFF_FFFFFFFF_FFFFFFFF")
|
||||||
check:
|
check:
|
||||||
bool(a == c)
|
bool(a == c)
|
||||||
not bool(carry)
|
not bool(carry)
|
||||||
|
|
||||||
suite "Modular operations - small modulus":
|
block:
|
||||||
# Vectors taken from Stint - https://github.com/status-im/nim-stint
|
var a = fromHex(BigInt[128], "0x00000000_FFFFFFFF_FFFFFFFF_FFFFFFFF")
|
||||||
test "100 mod 13":
|
let b = fromHex(BigInt[128], "0x00000000_00000000_00000000_00000001")
|
||||||
# Test 1 word and more than 1 word
|
let carry = a.add(b, ctrue(Word))
|
||||||
block:
|
|
||||||
let a = BigInt[7].fromUint(100'u32)
|
|
||||||
let m = BigInt[4].fromUint(13'u8)
|
|
||||||
|
|
||||||
var r: BigInt[4]
|
let c = fromHex(BigInt[128], "0x00000001_00000000_00000000_00000000")
|
||||||
|
check:
|
||||||
|
bool(a == c)
|
||||||
|
not bool(carry)
|
||||||
|
|
||||||
|
suite "Modular operations - small modulus":
|
||||||
|
# Vectors taken from Stint - https://github.com/status-im/nim-stint
|
||||||
|
test "100 mod 13":
|
||||||
|
# Test 1 word and more than 1 word
|
||||||
|
block:
|
||||||
|
let a = BigInt[7].fromUint(100'u32)
|
||||||
|
let m = BigInt[4].fromUint(13'u8)
|
||||||
|
|
||||||
|
var r: BigInt[4]
|
||||||
|
r.reduce(a, m)
|
||||||
|
check:
|
||||||
|
bool(r == BigInt[4].fromUint(100'u8 mod 13))
|
||||||
|
|
||||||
|
block: #
|
||||||
|
let a = BigInt[32].fromUint(100'u32)
|
||||||
|
let m = BigInt[4].fromUint(13'u8)
|
||||||
|
|
||||||
|
var r: BigInt[4]
|
||||||
|
r.reduce(a, m)
|
||||||
|
check:
|
||||||
|
bool(r == BigInt[4].fromUint(100'u8 mod 13))
|
||||||
|
|
||||||
|
block: #
|
||||||
|
let a = BigInt[64].fromUint(100'u32)
|
||||||
|
let m = BigInt[4].fromUint(13'u8)
|
||||||
|
|
||||||
|
var r: BigInt[4]
|
||||||
|
r.reduce(a, m)
|
||||||
|
check:
|
||||||
|
bool(r == BigInt[4].fromUint(100'u8 mod 13))
|
||||||
|
|
||||||
|
test "2^64 mod 3":
|
||||||
|
let a = BigInt[65].fromHex("0x1_00000000_00000000")
|
||||||
|
let m = BigInt[8].fromUint(3'u8)
|
||||||
|
|
||||||
|
var r: BigInt[8]
|
||||||
r.reduce(a, m)
|
r.reduce(a, m)
|
||||||
check:
|
check:
|
||||||
bool(r == BigInt[4].fromUint(100'u8 mod 13))
|
bool(r == BigInt[8].fromUint(1'u8))
|
||||||
|
|
||||||
block: #
|
test "1234567891234567890 mod 10":
|
||||||
let a = BigInt[32].fromUint(100'u32)
|
let a = BigInt[64].fromUint(1234567891234567890'u64)
|
||||||
let m = BigInt[4].fromUint(13'u8)
|
let m = BigInt[8].fromUint(10'u8)
|
||||||
|
|
||||||
var r: BigInt[4]
|
var r: BigInt[8]
|
||||||
r.reduce(a, m)
|
r.reduce(a, m)
|
||||||
check:
|
check:
|
||||||
bool(r == BigInt[4].fromUint(100'u8 mod 13))
|
bool(r == BigInt[8].fromUint(0'u8))
|
||||||
|
|
||||||
block: #
|
suite "Modular operations - small modulus - Stint specific failures highlighted by property-based testing":
|
||||||
let a = BigInt[64].fromUint(100'u32)
|
# Vectors taken from Stint - https://github.com/status-im/nim-stint
|
||||||
let m = BigInt[4].fromUint(13'u8)
|
test "Modulo: 65696211516342324 mod 174261910798982":
|
||||||
|
let u = 65696211516342324'u64
|
||||||
|
let v = 174261910798982'u64
|
||||||
|
|
||||||
var r: BigInt[4]
|
let a = BigInt[56].fromUint(u)
|
||||||
|
let m = BigInt[48].fromUint(v)
|
||||||
|
|
||||||
|
var r: BigInt[48]
|
||||||
r.reduce(a, m)
|
r.reduce(a, m)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
bool(r == BigInt[4].fromUint(100'u8 mod 13))
|
bool(r == BigInt[48].fromUint(u mod v))
|
||||||
|
|
||||||
test "2^64 mod 3":
|
test "Modulo: 15080397990160655 mod 600432699691":
|
||||||
let a = BigInt[65].fromHex("0x1_00000000_00000000")
|
let u = 15080397990160655'u64
|
||||||
let m = BigInt[8].fromUint(3'u8)
|
let v = 600432699691'u64
|
||||||
|
|
||||||
var r: BigInt[8]
|
let a = BigInt[54].fromUint(u)
|
||||||
r.reduce(a, m)
|
let m = BigInt[40].fromUint(v)
|
||||||
check:
|
|
||||||
bool(r == BigInt[8].fromUint(1'u8))
|
|
||||||
|
|
||||||
test "1234567891234567890 mod 10":
|
var r: BigInt[40]
|
||||||
let a = BigInt[64].fromUint(1234567891234567890'u64)
|
r.reduce(a, m)
|
||||||
let m = BigInt[8].fromUint(10'u8)
|
|
||||||
|
|
||||||
var r: BigInt[8]
|
check:
|
||||||
r.reduce(a, m)
|
bool(r == BigInt[40].fromUint(u mod v))
|
||||||
check:
|
|
||||||
bool(r == BigInt[8].fromUint(0'u8))
|
|
||||||
|
|
||||||
suite "Modular operations - small modulus - Stint specific failures highlighted by property-based testing":
|
main()
|
||||||
# Vectors taken from Stint - https://github.com/status-im/nim-stint
|
|
||||||
test "Modulo: 65696211516342324 mod 174261910798982":
|
|
||||||
let u = 65696211516342324'u64
|
|
||||||
let v = 174261910798982'u64
|
|
||||||
|
|
||||||
let a = BigInt[56].fromUint(u)
|
|
||||||
let m = BigInt[48].fromUint(v)
|
|
||||||
|
|
||||||
var r: BigInt[48]
|
|
||||||
r.reduce(a, m)
|
|
||||||
|
|
||||||
check:
|
|
||||||
bool(r == BigInt[48].fromUint(u mod v))
|
|
||||||
|
|
||||||
test "Modulo: 15080397990160655 mod 600432699691":
|
|
||||||
let u = 15080397990160655'u64
|
|
||||||
let v = 600432699691'u64
|
|
||||||
|
|
||||||
let a = BigInt[54].fromUint(u)
|
|
||||||
let m = BigInt[40].fromUint(v)
|
|
||||||
|
|
||||||
var r: BigInt[40]
|
|
||||||
r.reduce(a, m)
|
|
||||||
|
|
||||||
check:
|
|
||||||
bool(r == BigInt[40].fromUint(u mod v))
|
|
||||||
|
|
|
@ -14,76 +14,79 @@ import
|
||||||
../constantine/math/[bigints_raw, bigints_checked],
|
../constantine/math/[bigints_raw, bigints_checked],
|
||||||
../constantine/primitives/constant_time
|
../constantine/primitives/constant_time
|
||||||
|
|
||||||
suite "Bigints - Multiprecision modulo":
|
proc main() =
|
||||||
test "bitsize 237 mod bitsize 192":
|
suite "Bigints - Multiprecision modulo":
|
||||||
let a = BigInt[237].fromHex("0x123456789012345678901234567890123456789012345678901234567890")
|
test "bitsize 237 mod bitsize 192":
|
||||||
let m = BigInt[192].fromHex("0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB")
|
let a = BigInt[237].fromHex("0x123456789012345678901234567890123456789012345678901234567890")
|
||||||
|
let m = BigInt[192].fromHex("0xAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAB")
|
||||||
|
|
||||||
let expected = BigInt[192].fromHex("0x34567890123456789012345678901234567886f8091a3087")
|
let expected = BigInt[192].fromHex("0x34567890123456789012345678901234567886f8091a3087")
|
||||||
|
|
||||||
var r: BigInt[192]
|
var r: BigInt[192]
|
||||||
r.reduce(a, m)
|
|
||||||
|
|
||||||
check:
|
|
||||||
bool(r == expected)
|
|
||||||
|
|
||||||
test "bitsize 365 mod bitsize 258":
|
|
||||||
block:
|
|
||||||
let a = BigInt[365].fromHex("0x6c8ae85a6cab4bc530b91177e3f399894ff1fe335b6b3fcdc577ea4f8d754bbe71a6353e8609a4769ec8c56727a")
|
|
||||||
let m = BigInt[258].fromHex("0x2cadadfa2bb7d7141ad9728d6955ddb68a8b81ecb6a7610575bf4d6f562b09f0d")
|
|
||||||
|
|
||||||
let expected = BigInt[258].fromHex("0xb7c8844f534bf298645dc118384e975245c1a44ba4b0bca8a04c9db0c9035b9")
|
|
||||||
|
|
||||||
var r: BigInt[258]
|
|
||||||
r.reduce(a, m)
|
r.reduce(a, m)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
bool(r == expected)
|
bool(r == expected)
|
||||||
|
|
||||||
block:
|
test "bitsize 365 mod bitsize 258":
|
||||||
let a = BigInt[365].fromHex("0xbf3e7574adacfcba0016a92269ef5db4a6252cda4f0493e968a83f33657b85a7d23d59630a1f5455ff426ecb9ee")
|
block:
|
||||||
let m = BigInt[258].fromHex("0x38aa8382b17797e08a89487925eb716be55620aa482a7098b4d02a4a30a4a1178")
|
let a = BigInt[365].fromHex("0x6c8ae85a6cab4bc530b91177e3f399894ff1fe335b6b3fcdc577ea4f8d754bbe71a6353e8609a4769ec8c56727a")
|
||||||
|
let m = BigInt[258].fromHex("0x2cadadfa2bb7d7141ad9728d6955ddb68a8b81ecb6a7610575bf4d6f562b09f0d")
|
||||||
|
|
||||||
let expected = BigInt[258].fromHex("0x2512663958ef1b3e6e7f14ce722e72d82e10cbdd05e9fdcfb7cd5580bf074a3fe")
|
let expected = BigInt[258].fromHex("0xb7c8844f534bf298645dc118384e975245c1a44ba4b0bca8a04c9db0c9035b9")
|
||||||
|
|
||||||
var r: BigInt[258]
|
var r: BigInt[258]
|
||||||
r.reduce(a, m)
|
r.reduce(a, m)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
bool(r == expected)
|
bool(r == expected)
|
||||||
|
|
||||||
block:
|
block:
|
||||||
let a = BigInt[365].fromHex("0x16e20483c4a7f891fae2ddd77688fe72718c843ef4bc211069365a4e23bdc0b62680248fb0bf88760810de9f592b")
|
let a = BigInt[365].fromHex("0xbf3e7574adacfcba0016a92269ef5db4a6252cda4f0493e968a83f33657b85a7d23d59630a1f5455ff426ecb9ee")
|
||||||
let m = BigInt[258].fromHex("0x315d9c9ed0df4257a2db89e907e5f8a06e26d149e058b73c6db33bdc84c1619a4")
|
let m = BigInt[258].fromHex("0x38aa8382b17797e08a89487925eb716be55620aa482a7098b4d02a4a30a4a1178")
|
||||||
|
|
||||||
let expected = BigInt[258].fromHex("0x1b264b514412fdfb7579204afaad1b96d09ed6e4c985baf7e96815ab1c065e88f")
|
let expected = BigInt[258].fromHex("0x2512663958ef1b3e6e7f14ce722e72d82e10cbdd05e9fdcfb7cd5580bf074a3fe")
|
||||||
|
|
||||||
var r: BigInt[258]
|
var r: BigInt[258]
|
||||||
r.reduce(a, m)
|
r.reduce(a, m)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
bool(r == expected)
|
bool(r == expected)
|
||||||
|
|
||||||
test "bitsize 1955 mod bitsize 459":
|
block:
|
||||||
let a = BigInt[1955].fromHex("0x4f688e286a7c6e2b64663d8925c2f686994f2b90d58e7a843087c676c2c614ebab3eef9c765a88fe597b23b0e1fb28c812627366020edeafeefd0bf67a95215b4335412e2bd623b4cf7b69e669e1a8e782ab9a3e5fd443f10f459eed4ec9bd61821d94da82e937989245d481612b83b75d6d393e5de2258ac92aec7cd6e4f12c6b035e1fac3ef22851a8e211232b57db7551c03a88e9272411eea86e15c989be9d2962d5ae32ca35b18060212aaf6599b5a5f2416e436f009728b4017f87f70f4e528c9a33042b6810040c1e64457d56695d03b701540a5537c8cf781ff2ea4be2aa6daf1a5f2f0874a1cf495485a01254c2e2f4a")
|
let a = BigInt[365].fromHex("0x16e20483c4a7f891fae2ddd77688fe72718c843ef4bc211069365a4e23bdc0b62680248fb0bf88760810de9f592b")
|
||||||
let m = BigInt[459].fromHex("0x47304803a4a8c31e18287ad51c1ac7546c42e23206e9dc43e51eff5fa003f44bd08e542ec2659c405bfa4c9eb518ada943412767361029a902b")
|
let m = BigInt[258].fromHex("0x315d9c9ed0df4257a2db89e907e5f8a06e26d149e058b73c6db33bdc84c1619a4")
|
||||||
|
|
||||||
let expected = BigInt[459].fromHex("0x1f039dfe7c9da071d578b3b852db3916f4d79f6169818085994cbc41610abb7abb96e10d1126313cc281a87c309c2dd43bed745a9603f3c606c")
|
let expected = BigInt[258].fromHex("0x1b264b514412fdfb7579204afaad1b96d09ed6e4c985baf7e96815ab1c065e88f")
|
||||||
|
|
||||||
var r: BigInt[459]
|
var r: BigInt[258]
|
||||||
r.reduce(a, m)
|
r.reduce(a, m)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
bool(r == expected)
|
bool(r == expected)
|
||||||
|
|
||||||
test "bitsize 2346 mod bitsize 97":
|
test "bitsize 1955 mod bitsize 459":
|
||||||
let a = BigInt[2346].fromHex("0x1b5efa688e4124a71edd035f106c6ea81bafd78f610cd59d46fc6cda548fd970dde6b91c6fa10ab6d198026dea3c46c41495294082f2acc8210fd7ebfb25fdc6ce8131676ab0d749c5a4a83dd08172b3849df30304685192708ff0b510600cbf87be3179ce704adc43f2c9b22ba28c77f0a364fa1a96344d7f338227a8f346c0e721bc1312f53cebfc20fd0763ec039aa83a77ba489056ebee2a462058f1daffec9b5df29474f638185c6684729482a29764b46a5487e159fc4eedda5018d3d18ae1c0c6503ebbbd859b4dff3e09b6567b752d51c9733fc822b2758b69ffd65974a8fbf4ad25a40761bb9b9b6a1f886928fe08f9c1571fe3e3987b15e37208a22f64e2c3ff75a36815b7906fc2a52f7bd32d15e8b0441e8c39ae9127d80946e146db5cd2738")
|
let a = BigInt[1955].fromHex("0x4f688e286a7c6e2b64663d8925c2f686994f2b90d58e7a843087c676c2c614ebab3eef9c765a88fe597b23b0e1fb28c812627366020edeafeefd0bf67a95215b4335412e2bd623b4cf7b69e669e1a8e782ab9a3e5fd443f10f459eed4ec9bd61821d94da82e937989245d481612b83b75d6d393e5de2258ac92aec7cd6e4f12c6b035e1fac3ef22851a8e211232b57db7551c03a88e9272411eea86e15c989be9d2962d5ae32ca35b18060212aaf6599b5a5f2416e436f009728b4017f87f70f4e528c9a33042b6810040c1e64457d56695d03b701540a5537c8cf781ff2ea4be2aa6daf1a5f2f0874a1cf495485a01254c2e2f4a")
|
||||||
let m = BigInt[97].fromHex("0x1100d0717f9fff44c6cc7442e")
|
let m = BigInt[459].fromHex("0x47304803a4a8c31e18287ad51c1ac7546c42e23206e9dc43e51eff5fa003f44bd08e542ec2659c405bfa4c9eb518ada943412767361029a902b")
|
||||||
|
|
||||||
let expected = BigInt[97].fromHex("0x0104ea05300eeb05cd374197b6")
|
let expected = BigInt[459].fromHex("0x1f039dfe7c9da071d578b3b852db3916f4d79f6169818085994cbc41610abb7abb96e10d1126313cc281a87c309c2dd43bed745a9603f3c606c")
|
||||||
|
|
||||||
var r: BigInt[97]
|
var r: BigInt[459]
|
||||||
r.reduce(a, m)
|
r.reduce(a, m)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
bool(r == expected)
|
bool(r == expected)
|
||||||
|
|
||||||
|
test "bitsize 2346 mod bitsize 97":
|
||||||
|
let a = BigInt[2346].fromHex("0x1b5efa688e4124a71edd035f106c6ea81bafd78f610cd59d46fc6cda548fd970dde6b91c6fa10ab6d198026dea3c46c41495294082f2acc8210fd7ebfb25fdc6ce8131676ab0d749c5a4a83dd08172b3849df30304685192708ff0b510600cbf87be3179ce704adc43f2c9b22ba28c77f0a364fa1a96344d7f338227a8f346c0e721bc1312f53cebfc20fd0763ec039aa83a77ba489056ebee2a462058f1daffec9b5df29474f638185c6684729482a29764b46a5487e159fc4eedda5018d3d18ae1c0c6503ebbbd859b4dff3e09b6567b752d51c9733fc822b2758b69ffd65974a8fbf4ad25a40761bb9b9b6a1f886928fe08f9c1571fe3e3987b15e37208a22f64e2c3ff75a36815b7906fc2a52f7bd32d15e8b0441e8c39ae9127d80946e146db5cd2738")
|
||||||
|
let m = BigInt[97].fromHex("0x1100d0717f9fff44c6cc7442e")
|
||||||
|
|
||||||
|
let expected = BigInt[97].fromHex("0x0104ea05300eeb05cd374197b6")
|
||||||
|
|
||||||
|
var r: BigInt[97]
|
||||||
|
r.reduce(a, m)
|
||||||
|
|
||||||
|
check:
|
||||||
|
bool(r == expected)
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
|
@ -14,39 +14,30 @@ import unittest, random,
|
||||||
randomize(0xDEADBEEF) # Random seed for reproducibility
|
randomize(0xDEADBEEF) # Random seed for reproducibility
|
||||||
type T = BaseType
|
type T = BaseType
|
||||||
|
|
||||||
suite "IO":
|
proc main() =
|
||||||
test "Parsing raw integers":
|
suite "IO":
|
||||||
block: # Sanity check
|
test "Parsing raw integers":
|
||||||
let x = 0'u64
|
block: # Sanity check
|
||||||
let x_bytes = cast[array[8, byte]](x)
|
let x = 0'u64
|
||||||
let big = BigInt[64].fromRawUint(x_bytes, cpuEndian)
|
let x_bytes = cast[array[8, byte]](x)
|
||||||
|
let big = BigInt[64].fromRawUint(x_bytes, cpuEndian)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
T(big.limbs[0]) == 0
|
T(big.limbs[0]) == 0
|
||||||
T(big.limbs[1]) == 0
|
T(big.limbs[1]) == 0
|
||||||
|
|
||||||
test "Parsing and dumping round-trip on uint64":
|
test "Parsing and dumping round-trip on uint64":
|
||||||
block:
|
block:
|
||||||
# "Little-endian" - 2^63
|
# "Little-endian" - 2^63
|
||||||
let x = 1'u64 shl 63
|
let x = 1'u64 shl 63
|
||||||
let x_bytes = cast[array[8, byte]](x)
|
let x_bytes = cast[array[8, byte]](x)
|
||||||
let big = BigInt[64].fromRawUint(x_bytes, littleEndian) # It's fine even on big-endian platform. We only want the byte-pattern
|
let big = BigInt[64].fromRawUint(x_bytes, littleEndian) # It's fine even on big-endian platform. We only want the byte-pattern
|
||||||
|
|
||||||
var r_bytes: array[8, byte]
|
var r_bytes: array[8, byte]
|
||||||
dumpRawUint(r_bytes, big, littleEndian)
|
dumpRawUint(r_bytes, big, littleEndian)
|
||||||
check: x_bytes == r_bytes
|
check: x_bytes == r_bytes
|
||||||
|
|
||||||
block: # "Little-endian" - single random
|
block: # "Little-endian" - single random
|
||||||
let x = uint64 rand(0..high(int))
|
|
||||||
let x_bytes = cast[array[8, byte]](x)
|
|
||||||
let big = BigInt[64].fromRawUint(x_bytes, littleEndian) # It's fine even on big-endian platform. We only want the byte-pattern
|
|
||||||
|
|
||||||
var r_bytes: array[8, byte]
|
|
||||||
dumpRawUint(r_bytes, big, littleEndian)
|
|
||||||
check: x_bytes == r_bytes
|
|
||||||
|
|
||||||
block: # "Little-endian" - 10 random cases
|
|
||||||
for _ in 0 ..< 10:
|
|
||||||
let x = uint64 rand(0..high(int))
|
let x = uint64 rand(0..high(int))
|
||||||
let x_bytes = cast[array[8, byte]](x)
|
let x_bytes = cast[array[8, byte]](x)
|
||||||
let big = BigInt[64].fromRawUint(x_bytes, littleEndian) # It's fine even on big-endian platform. We only want the byte-pattern
|
let big = BigInt[64].fromRawUint(x_bytes, littleEndian) # It's fine even on big-endian platform. We only want the byte-pattern
|
||||||
|
@ -55,24 +46,36 @@ suite "IO":
|
||||||
dumpRawUint(r_bytes, big, littleEndian)
|
dumpRawUint(r_bytes, big, littleEndian)
|
||||||
check: x_bytes == r_bytes
|
check: x_bytes == r_bytes
|
||||||
|
|
||||||
test "Round trip on elliptic curve constants":
|
block: # "Little-endian" - 10 random cases
|
||||||
block: # Secp256k1 - https://en.bitcoin.it/wiki/Secp256k1
|
for _ in 0 ..< 10:
|
||||||
const p = "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"
|
let x = uint64 rand(0..high(int))
|
||||||
let x = BigInt[256].fromHex(p)
|
let x_bytes = cast[array[8, byte]](x)
|
||||||
let hex = x.dumpHex(bigEndian)
|
let big = BigInt[64].fromRawUint(x_bytes, littleEndian) # It's fine even on big-endian platform. We only want the byte-pattern
|
||||||
|
|
||||||
check: p == hex
|
var r_bytes: array[8, byte]
|
||||||
|
dumpRawUint(r_bytes, big, littleEndian)
|
||||||
|
check: x_bytes == r_bytes
|
||||||
|
|
||||||
block: # BN254 - https://github.com/ethereum/py_ecc/blob/master/py_ecc/fields/field_properties.py
|
test "Round trip on elliptic curve constants":
|
||||||
const p = "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"
|
block: # Secp256k1 - https://en.bitcoin.it/wiki/Secp256k1
|
||||||
let x = BigInt[254].fromHex(p)
|
const p = "0xfffffffffffffffffffffffffffffffffffffffffffffffffffffffefffffc2f"
|
||||||
let hex = x.dumpHex(bigEndian)
|
let x = BigInt[256].fromHex(p)
|
||||||
|
let hex = x.dumpHex(bigEndian)
|
||||||
|
|
||||||
check: p == hex
|
check: p == hex
|
||||||
|
|
||||||
block: # BLS12-381 - https://github.com/ethereum/py_ecc/blob/master/py_ecc/fields/field_properties.py
|
block: # BN254 - https://github.com/ethereum/py_ecc/blob/master/py_ecc/fields/field_properties.py
|
||||||
const p = "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
|
const p = "0x30644e72e131a029b85045b68181585d97816a916871ca8d3c208c16d87cfd47"
|
||||||
let x = BigInt[381].fromHex(p)
|
let x = BigInt[254].fromHex(p)
|
||||||
let hex = x.dumpHex(bigEndian)
|
let hex = x.dumpHex(bigEndian)
|
||||||
|
|
||||||
check: p == hex
|
check: p == hex
|
||||||
|
|
||||||
|
block: # BLS12-381 - https://github.com/ethereum/py_ecc/blob/master/py_ecc/fields/field_properties.py
|
||||||
|
const p = "0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffffaaab"
|
||||||
|
let x = BigInt[381].fromHex(p)
|
||||||
|
let hex = x.dumpHex(bigEndian)
|
||||||
|
|
||||||
|
check: p == hex
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
|
@ -15,173 +15,176 @@ randomize(0xDEADBEEF)
|
||||||
template undistinct[T](x: Ct[T]): T =
|
template undistinct[T](x: Ct[T]): T =
|
||||||
T(x)
|
T(x)
|
||||||
|
|
||||||
suite "Constant-time unsigned integers":
|
proc main() =
|
||||||
test "High - getting the biggest representable number":
|
suite "Constant-time unsigned integers":
|
||||||
check:
|
test "High - getting the biggest representable number":
|
||||||
high(Ct[byte]).undistinct == 0xFF.byte
|
|
||||||
high(Ct[uint8]).undistinct == 0xFF'u8
|
|
||||||
|
|
||||||
high(Ct[uint16]).undistinct == 0xFFFF'u16
|
|
||||||
high(Ct[uint32]).undistinct == 0xFFFFFFFF'u32
|
|
||||||
high(Ct[uint64]).undistinct == 0xFFFFFFFF_FFFFFFFF'u64
|
|
||||||
|
|
||||||
test "bitwise `and`, `or`, `xor`, `not`":
|
|
||||||
let x1 = rand(high(int)).uint64
|
|
||||||
let y1 = rand(high(int)).uint64
|
|
||||||
let x2 = rand(high(int)).uint64
|
|
||||||
let y2 = rand(high(int)).uint64
|
|
||||||
let x3 = rand(high(int)).uint64
|
|
||||||
let y3 = rand(high(int)).uint64
|
|
||||||
template bitwise_check(op: untyped): untyped =
|
|
||||||
block:
|
|
||||||
check:
|
|
||||||
op(ct(0'u32), ct(0'u32)).undistinct == op(0'u32, 0'u32)
|
|
||||||
op(ct(0'u32), ct(1'u32)).undistinct == op(0'u32, 1'u32)
|
|
||||||
op(ct(1234'u64), ct(5678'u64)).undistinct == op(1234'u64, 5678'u64)
|
|
||||||
|
|
||||||
op(x1.ct, y1.ct).undistinct == op(x1, y1)
|
|
||||||
op(x2.ct, y2.ct).undistinct == op(x2, y2)
|
|
||||||
op(x3.ct, y3.ct).undistinct == op(x3, y3)
|
|
||||||
bitwise_check(`and`)
|
|
||||||
bitwise_check(`or`)
|
|
||||||
bitwise_check(`xor`)
|
|
||||||
|
|
||||||
block:
|
|
||||||
check:
|
check:
|
||||||
not(ct(0'u32)).undistinct == not 0'u32
|
high(Ct[byte]).undistinct == 0xFF.byte
|
||||||
not(ct(1'u32)).undistinct == not 1'u32
|
high(Ct[uint8]).undistinct == 0xFF'u8
|
||||||
not(ct(1234'u64)).undistinct == not 1234'u64
|
|
||||||
not(ct(5678'u64)).undistinct == not 5678'u64
|
|
||||||
not(ct(x1)).undistinct == not x1
|
|
||||||
not(ct(x2)).undistinct == not x2
|
|
||||||
not(ct(x3)).undistinct == not x3
|
|
||||||
not(ct(y1)).undistinct == not y1
|
|
||||||
not(ct(y2)).undistinct == not y2
|
|
||||||
not(ct(y3)).undistinct == not y3
|
|
||||||
|
|
||||||
test "Logical shifts":
|
high(Ct[uint16]).undistinct == 0xFFFF'u16
|
||||||
let x1 = rand(high(int)).uint64
|
high(Ct[uint32]).undistinct == 0xFFFFFFFF'u32
|
||||||
let y1 = rand(high(int)).uint64
|
high(Ct[uint64]).undistinct == 0xFFFFFFFF_FFFFFFFF'u64
|
||||||
let x2 = rand(high(int)).uint64
|
|
||||||
let y2 = rand(high(int32)).uint64
|
|
||||||
let x3 = rand(high(int32)).uint64
|
|
||||||
let y3 = rand(high(int32)).uint64
|
|
||||||
|
|
||||||
let s1 = rand(10)
|
test "bitwise `and`, `or`, `xor`, `not`":
|
||||||
let s2 = rand(10)
|
let x1 = rand(high(int)).uint64
|
||||||
let s3 = rand(10)
|
let y1 = rand(high(int)).uint64
|
||||||
|
let x2 = rand(high(int)).uint64
|
||||||
|
let y2 = rand(high(int)).uint64
|
||||||
|
let x3 = rand(high(int)).uint64
|
||||||
|
let y3 = rand(high(int)).uint64
|
||||||
|
template bitwise_check(op: untyped): untyped =
|
||||||
|
block:
|
||||||
|
check:
|
||||||
|
op(ct(0'u32), ct(0'u32)).undistinct == op(0'u32, 0'u32)
|
||||||
|
op(ct(0'u32), ct(1'u32)).undistinct == op(0'u32, 1'u32)
|
||||||
|
op(ct(1234'u64), ct(5678'u64)).undistinct == op(1234'u64, 5678'u64)
|
||||||
|
|
||||||
|
op(x1.ct, y1.ct).undistinct == op(x1, y1)
|
||||||
|
op(x2.ct, y2.ct).undistinct == op(x2, y2)
|
||||||
|
op(x3.ct, y3.ct).undistinct == op(x3, y3)
|
||||||
|
bitwise_check(`and`)
|
||||||
|
bitwise_check(`or`)
|
||||||
|
bitwise_check(`xor`)
|
||||||
|
|
||||||
template shift_check(op: untyped): untyped =
|
|
||||||
block:
|
block:
|
||||||
check:
|
check:
|
||||||
op(ct(0'u32), 1).undistinct == op(0'u32, 1)
|
not(ct(0'u32)).undistinct == not 0'u32
|
||||||
op(ct(1'u32), 2).undistinct == op(1'u32, 2)
|
not(ct(1'u32)).undistinct == not 1'u32
|
||||||
op(ct(1234'u64), 3).undistinct == op(1234'u64, 3)
|
not(ct(1234'u64)).undistinct == not 1234'u64
|
||||||
op(ct(2'u64^30), 1).undistinct == op(2'u64^30, 1)
|
not(ct(5678'u64)).undistinct == not 5678'u64
|
||||||
op(ct(2'u64^31 + 1), 1).undistinct == op(2'u64^31 + 1, 1)
|
not(ct(x1)).undistinct == not x1
|
||||||
op(ct(2'u64^32), 1).undistinct == op(2'u64^32, 1)
|
not(ct(x2)).undistinct == not x2
|
||||||
|
not(ct(x3)).undistinct == not x3
|
||||||
|
not(ct(y1)).undistinct == not y1
|
||||||
|
not(ct(y2)).undistinct == not y2
|
||||||
|
not(ct(y3)).undistinct == not y3
|
||||||
|
|
||||||
op(x1.ct, s1).undistinct == op(x1, s1)
|
test "Logical shifts":
|
||||||
op(x2.ct, s2).undistinct == op(x2, s2)
|
let x1 = rand(high(int)).uint64
|
||||||
op(x3.ct, s3).undistinct == op(x3, s3)
|
let y1 = rand(high(int)).uint64
|
||||||
|
let x2 = rand(high(int)).uint64
|
||||||
|
let y2 = rand(high(int32)).uint64
|
||||||
|
let x3 = rand(high(int32)).uint64
|
||||||
|
let y3 = rand(high(int32)).uint64
|
||||||
|
|
||||||
|
let s1 = rand(10)
|
||||||
|
let s2 = rand(10)
|
||||||
|
let s3 = rand(10)
|
||||||
|
|
||||||
|
template shift_check(op: untyped): untyped =
|
||||||
|
block:
|
||||||
|
check:
|
||||||
|
op(ct(0'u32), 1).undistinct == op(0'u32, 1)
|
||||||
|
op(ct(1'u32), 2).undistinct == op(1'u32, 2)
|
||||||
|
op(ct(1234'u64), 3).undistinct == op(1234'u64, 3)
|
||||||
|
op(ct(2'u64^30), 1).undistinct == op(2'u64^30, 1)
|
||||||
|
op(ct(2'u64^31 + 1), 1).undistinct == op(2'u64^31 + 1, 1)
|
||||||
|
op(ct(2'u64^32), 1).undistinct == op(2'u64^32, 1)
|
||||||
|
|
||||||
|
op(x1.ct, s1).undistinct == op(x1, s1)
|
||||||
|
op(x2.ct, s2).undistinct == op(x2, s2)
|
||||||
|
op(x3.ct, s3).undistinct == op(x3, s3)
|
||||||
|
|
||||||
|
|
||||||
op(y1.ct, s1).undistinct == op(y1, s1)
|
op(y1.ct, s1).undistinct == op(y1, s1)
|
||||||
op(y2.ct, s2).undistinct == op(y2, s2)
|
op(y2.ct, s2).undistinct == op(y2, s2)
|
||||||
op(y3.ct, s3).undistinct == op(y3, s3)
|
op(y3.ct, s3).undistinct == op(y3, s3)
|
||||||
|
|
||||||
shift_check(`shl`)
|
shift_check(`shl`)
|
||||||
shift_check(`shr`)
|
shift_check(`shr`)
|
||||||
|
|
||||||
|
|
||||||
test "Operators `+`, `-`, `*`":
|
test "Operators `+`, `-`, `*`":
|
||||||
let x1 = rand(high(int)).uint64
|
let x1 = rand(high(int)).uint64
|
||||||
let y1 = rand(high(int)).uint64
|
let y1 = rand(high(int)).uint64
|
||||||
let x2 = rand(high(int)).uint64
|
let x2 = rand(high(int)).uint64
|
||||||
let y2 = rand(high(int)).uint64
|
let y2 = rand(high(int)).uint64
|
||||||
let x3 = rand(high(int)).uint64
|
let x3 = rand(high(int)).uint64
|
||||||
let y3 = rand(high(int)).uint64
|
let y3 = rand(high(int)).uint64
|
||||||
template operator_check(op: untyped): untyped =
|
template operator_check(op: untyped): untyped =
|
||||||
block:
|
block:
|
||||||
check:
|
check:
|
||||||
op(ct(0'u32), ct(0'u32)).undistinct == op(0'u32, 0'u32)
|
op(ct(0'u32), ct(0'u32)).undistinct == op(0'u32, 0'u32)
|
||||||
op(ct(0'u32), ct(1'u32)).undistinct == op(0'u32, 1'u32)
|
op(ct(0'u32), ct(1'u32)).undistinct == op(0'u32, 1'u32)
|
||||||
op(ct(1234'u64), ct(5678'u64)).undistinct == op(1234'u64, 5678'u64)
|
op(ct(1234'u64), ct(5678'u64)).undistinct == op(1234'u64, 5678'u64)
|
||||||
|
|
||||||
op(x1.ct, y1.ct).undistinct == op(x1, y1)
|
op(x1.ct, y1.ct).undistinct == op(x1, y1)
|
||||||
op(x2.ct, y2.ct).undistinct == op(x2, y2)
|
op(x2.ct, y2.ct).undistinct == op(x2, y2)
|
||||||
op(x3.ct, y3.ct).undistinct == op(x3, y3)
|
op(x3.ct, y3.ct).undistinct == op(x3, y3)
|
||||||
operator_check(`+`)
|
operator_check(`+`)
|
||||||
operator_check(`-`)
|
operator_check(`-`)
|
||||||
operator_check(`*`)
|
operator_check(`*`)
|
||||||
|
|
||||||
test "Unary `-`, returning the 2-complement of an unsigned integer":
|
test "Unary `-`, returning the 2-complement of an unsigned integer":
|
||||||
let x1 = rand(high(int)).uint64
|
let x1 = rand(high(int)).uint64
|
||||||
let y1 = rand(high(int)).uint64
|
let y1 = rand(high(int)).uint64
|
||||||
let x2 = rand(high(int)).uint64
|
let x2 = rand(high(int)).uint64
|
||||||
let y2 = rand(high(int)).uint64
|
let y2 = rand(high(int)).uint64
|
||||||
let x3 = rand(high(int)).uint64
|
let x3 = rand(high(int)).uint64
|
||||||
let y3 = rand(high(int)).uint64
|
let y3 = rand(high(int)).uint64
|
||||||
check:
|
check:
|
||||||
(-ct(0'u32)).undistinct == 0
|
(-ct(0'u32)).undistinct == 0
|
||||||
(-high(Ct[uint32])).undistinct == 1'u32
|
(-high(Ct[uint32])).undistinct == 1'u32
|
||||||
(-ct(0x80000000'u32)).undistinct == 0x80000000'u32 # This is low(int32) == 0b10000..0000
|
(-ct(0x80000000'u32)).undistinct == 0x80000000'u32 # This is low(int32) == 0b10000..0000
|
||||||
|
|
||||||
undistinct(-x1.ct) == undistinct(not(x1.ct) + ct(1'u64))
|
undistinct(-x1.ct) == undistinct(not(x1.ct) + ct(1'u64))
|
||||||
undistinct(-x2.ct) == undistinct(not(x2.ct) + ct(1'u64))
|
undistinct(-x2.ct) == undistinct(not(x2.ct) + ct(1'u64))
|
||||||
undistinct(-x3.ct) == undistinct(not(x3.ct) + ct(1'u64))
|
undistinct(-x3.ct) == undistinct(not(x3.ct) + ct(1'u64))
|
||||||
undistinct(-y1.ct) == undistinct(not(y1.ct) + ct(1'u64))
|
undistinct(-y1.ct) == undistinct(not(y1.ct) + ct(1'u64))
|
||||||
undistinct(-y2.ct) == undistinct(not(y2.ct) + ct(1'u64))
|
undistinct(-y2.ct) == undistinct(not(y2.ct) + ct(1'u64))
|
||||||
undistinct(-y3.ct) == undistinct(not(y3.ct) + ct(1'u64))
|
undistinct(-y3.ct) == undistinct(not(y3.ct) + ct(1'u64))
|
||||||
|
|
||||||
suite "Constant-time booleans":
|
suite "Constant-time booleans":
|
||||||
test "Boolean not":
|
test "Boolean not":
|
||||||
check:
|
check:
|
||||||
not(ctrue(uint32)).bool == false
|
not(ctrue(uint32)).bool == false
|
||||||
not(cfalse(uint32)).bool == true
|
not(cfalse(uint32)).bool == true
|
||||||
|
|
||||||
test "Comparison":
|
test "Comparison":
|
||||||
check:
|
check:
|
||||||
bool(ct(0'u32) != ct(0'u32)) == false
|
bool(ct(0'u32) != ct(0'u32)) == false
|
||||||
bool(ct(0'u32) != ct(1'u32)) == true
|
bool(ct(0'u32) != ct(1'u32)) == true
|
||||||
|
|
||||||
bool(ct(10'u32) == ct(10'u32)) == true
|
bool(ct(10'u32) == ct(10'u32)) == true
|
||||||
bool(ct(10'u32) != ct(20'u32)) == true
|
bool(ct(10'u32) != ct(20'u32)) == true
|
||||||
|
|
||||||
bool(ct(10'u32) <= ct(10'u32)) == true
|
bool(ct(10'u32) <= ct(10'u32)) == true
|
||||||
bool(ct(10'u32) <= ct(20'u32)) == true
|
bool(ct(10'u32) <= ct(20'u32)) == true
|
||||||
bool(ct(10'u32) <= ct(5'u32)) == false
|
bool(ct(10'u32) <= ct(5'u32)) == false
|
||||||
bool(ct(10'u32) <= ct(0xFFFFFFFF'u32)) == true
|
bool(ct(10'u32) <= ct(0xFFFFFFFF'u32)) == true
|
||||||
|
|
||||||
bool(ct(10'u32) < ct(10'u32)) == false
|
bool(ct(10'u32) < ct(10'u32)) == false
|
||||||
bool(ct(10'u32) < ct(20'u32)) == true
|
bool(ct(10'u32) < ct(20'u32)) == true
|
||||||
bool(ct(10'u32) < ct(5'u32)) == false
|
bool(ct(10'u32) < ct(5'u32)) == false
|
||||||
bool(ct(10'u32) < ct(0xFFFFFFFF'u32)) == true
|
bool(ct(10'u32) < ct(0xFFFFFFFF'u32)) == true
|
||||||
|
|
||||||
bool(ct(10'u32) > ct(10'u32)) == false
|
bool(ct(10'u32) > ct(10'u32)) == false
|
||||||
bool(ct(10'u32) > ct(20'u32)) == false
|
bool(ct(10'u32) > ct(20'u32)) == false
|
||||||
bool(ct(10'u32) > ct(5'u32)) == true
|
bool(ct(10'u32) > ct(5'u32)) == true
|
||||||
bool(ct(10'u32) > ct(0xFFFFFFFF'u32)) == false
|
bool(ct(10'u32) > ct(0xFFFFFFFF'u32)) == false
|
||||||
|
|
||||||
bool(ct(10'u32) >= ct(10'u32)) == true
|
bool(ct(10'u32) >= ct(10'u32)) == true
|
||||||
bool(ct(10'u32) >= ct(20'u32)) == false
|
bool(ct(10'u32) >= ct(20'u32)) == false
|
||||||
bool(ct(10'u32) >= ct(5'u32)) == true
|
bool(ct(10'u32) >= ct(5'u32)) == true
|
||||||
bool(ct(10'u32) >= ct(0xFFFFFFFF'u32)) == false
|
bool(ct(10'u32) >= ct(0xFFFFFFFF'u32)) == false
|
||||||
|
|
||||||
test "Multiplexer/selector - mux(ctl, x, y) <=> ctl? x: y":
|
test "Multiplexer/selector - mux(ctl, x, y) <=> ctl? x: y":
|
||||||
let u = 10'u32.ct
|
let u = 10'u32.ct
|
||||||
let v = 20'u32.ct
|
let v = 20'u32.ct
|
||||||
let w = 5'u32.ct
|
let w = 5'u32.ct
|
||||||
|
|
||||||
let y = ctrue(uint32)
|
let y = ctrue(uint32)
|
||||||
let n = cfalse(uint32)
|
let n = cfalse(uint32)
|
||||||
|
|
||||||
check:
|
check:
|
||||||
bool(mux(y, u, v) == u)
|
bool(mux(y, u, v) == u)
|
||||||
bool(mux(n, u, v) == v)
|
bool(mux(n, u, v) == v)
|
||||||
|
|
||||||
bool(mux(y, u, w) == u)
|
bool(mux(y, u, w) == u)
|
||||||
bool(mux(n, u, w) == w)
|
bool(mux(n, u, w) == w)
|
||||||
|
|
||||||
bool(mux(y, v, w) == v)
|
bool(mux(y, v, w) == v)
|
||||||
bool(mux(n, v, w) == w)
|
bool(mux(n, v, w) == w)
|
||||||
|
|
||||||
|
main()
|
||||||
|
|
Loading…
Reference in New Issue