Use our prng through most of the test suite

This commit is contained in:
Mamy André-Ratsimbazafy 2020-04-14 20:46:39 +02:00 committed by Mamy Ratsimbazafy
parent 0115d3fd8e
commit 1559bda56c
7 changed files with 71 additions and 48 deletions

View File

@ -130,7 +130,7 @@ func random_unsafe_with_randZ[F](rng: var RngState, a: var ECP_SWei_Proj[F]) =
# Integer ranges # Integer ranges
# ------------------------------------------------------------ # ------------------------------------------------------------
func random_unsafe(rng: var RngState, maxExclusive: uint32): uint32 = func random_unsafe*(rng: var RngState, maxExclusive: uint32): uint32 =
## Generate a random integer in 0 ..< maxExclusive ## Generate a random integer in 0 ..< maxExclusive
## Uses an unbiaised generation method ## Uses an unbiaised generation method
## See Lemire's algorithm modified by Melissa O'Neill ## See Lemire's algorithm modified by Melissa O'Neill
@ -154,6 +154,10 @@ func random_unsafe(rng: var RngState, maxExclusive: uint32): uint32 =
# Generic over any supported type # Generic over any supported type
# ------------------------------------------------------------ # ------------------------------------------------------------
func sample_unsafe*[T](rng: var RngState, src: openarray[T]): T =
## Return a random sample from an array
result = src[rng.random_unsafe(uint32 src.len)]
func random_unsafe*[T: SomeInteger](rng: var RngState, inclRange: Slice[T]): T = func random_unsafe*[T: SomeInteger](rng: var RngState, inclRange: Slice[T]): T =
## Return a random integer in the given range. ## Return a random integer in the given range.
## The range bounds must fit in an int32. ## The range bounds must fit in an int32.
@ -166,6 +170,8 @@ func random_unsafe*(rng: var RngState, T: typedesc): T =
## Unsafe: for testing and benchmarking purposes only ## Unsafe: for testing and benchmarking purposes only
when T is ECP_SWei_Proj: when T is ECP_SWei_Proj:
rng.random_unsafe(result) rng.random_unsafe(result)
elif T is SomeNumber:
cast[T](rng.next()) # TODO: Rely on casting integer actually converting in C (i.e. uint64->uint32 is valid)
else: else:
rng.random_unsafe(result, T.C) rng.random_unsafe(result, T.C)

View File

@ -8,7 +8,7 @@
import import
# Standard library # Standard library
unittest, times, random, unittest, times,
# Internals # Internals
../constantine/towers, ../constantine/towers,
../constantine/config/[common, curves], ../constantine/config/[common, curves],
@ -18,6 +18,7 @@ import
const Iters = 128 const Iters = 128
# Random seed for reproducibility
var rng: RngState var rng: RngState
let seed = uint32(getTime().toUnix() and (1'i64 shl 32 - 1)) # unixTime mod 2^32 let seed = uint32(getTime().toUnix() and (1'i64 shl 32 - 1)) # unixTime mod 2^32
rng.seed(seed) rng.seed(seed)
@ -348,7 +349,7 @@ suite "𝔽p12 = 𝔽p6[w] (irreducible polynomial w² - γ)":
block: block:
proc testInstance() = proc testInstance() =
for _ in 0 ..< Iters: for _ in 0 ..< Iters:
let factor = rand(-30..30) let factor = rng.random_unsafe(-30..30)
let a = rng.random_unsafe(Fp12[C]) let a = rng.random_unsafe(Fp12[C])

View File

@ -8,7 +8,7 @@
import import
# Standard library # Standard library
unittest, times, random, unittest, times,
# Internals # Internals
../constantine/towers, ../constantine/towers,
../constantine/config/[common, curves], ../constantine/config/[common, curves],
@ -18,6 +18,7 @@ import
const Iters = 128 const Iters = 128
# Random seed for reproducibility
var rng: RngState var rng: RngState
let seed = uint32(getTime().toUnix() and (1'i64 shl 32 - 1)) # unixTime mod 2^32 let seed = uint32(getTime().toUnix() and (1'i64 shl 32 - 1)) # unixTime mod 2^32
rng.seed(seed) rng.seed(seed)
@ -245,7 +246,7 @@ suite "𝔽p2 = 𝔽p[µ] (irreducible polynomial x²+µ)":
block: block:
proc testInstance() = proc testInstance() =
for _ in 0 ..< Iters: for _ in 0 ..< Iters:
let factor = rand(-30..30) let factor = rng.random_unsafe(-30..30)
let a = rng.random_unsafe(Fp2[C]) let a = rng.random_unsafe(Fp2[C])

View File

@ -8,7 +8,7 @@
import import
# Standard library # Standard library
unittest, times, random, unittest, times,
# Internals # Internals
../constantine/towers, ../constantine/towers,
../constantine/config/[common, curves], ../constantine/config/[common, curves],
@ -18,6 +18,7 @@ import
const Iters = 128 const Iters = 128
# Random seed for reproducibility
var rng: RngState var rng: RngState
let seed = uint32(getTime().toUnix() and (1'i64 shl 32 - 1)) # unixTime mod 2^32 let seed = uint32(getTime().toUnix() and (1'i64 shl 32 - 1)) # unixTime mod 2^32
rng.seed(seed) rng.seed(seed)
@ -348,7 +349,7 @@ suite "𝔽p6 = 𝔽p2[v] (irreducible polynomial v³ - ξ)":
block: block:
proc testInstance() = proc testInstance() =
for _ in 0 ..< Iters: for _ in 0 ..< Iters:
let factor = rand(-30..30) let factor = rng.random_unsafe(-30..30)
let a = rng.random_unsafe(Fp6[C]) let a = rng.random_unsafe(Fp6[C])

View File

@ -6,12 +6,18 @@
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms. # at your option. This file may not be copied, modified, or distributed except according to those terms.
import unittest, random, import std/[unittest,times],
../constantine/io/io_bigints, ../constantine/io/io_bigints,
../constantine/config/common, ../constantine/config/common,
../constantine/arithmetic ../constantine/arithmetic,
../helpers/prng_unsafe
# Random seed for reproducibility
var rng: RngState
let seed = uint32(getTime().toUnix() and (1'i64 shl 32 - 1)) # unixTime mod 2^32
rng.seed(seed)
echo "test_io_bigints xoshiro512** seed: ", seed
randomize(0xDEADBEEF) # Random seed for reproducibility
type T = BaseType type T = BaseType
proc main() = proc main() =
@ -37,7 +43,7 @@ proc main() =
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 = rng.random_unsafe(uint64)
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
@ -47,7 +53,7 @@ proc main() =
block: # "Little-endian" - 10 random cases block: # "Little-endian" - 10 random cases
for _ in 0 ..< 10: for _ in 0 ..< 10:
let x = uint64 rand(0..high(int)) let x = rng.random_unsafe(uint64)
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

View File

@ -6,14 +6,18 @@
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms. # at your option. This file may not be copied, modified, or distributed except according to those terms.
import unittest, random, import std/[unittest, times],
../constantine/io/[io_bigints, io_fields], ../constantine/io/[io_bigints, io_fields],
../constantine/config/curves, ../constantine/config/curves,
../constantine/config/common, ../constantine/config/common,
../constantine/arithmetic ../constantine/arithmetic,
../helpers/prng_unsafe
randomize(0xDEADBEEF) # Random seed for reproducibility # Random seed for reproducibility
type T = BaseType var rng: RngState
let seed = uint32(getTime().toUnix() and (1'i64 shl 32 - 1)) # unixTime mod 2^32
rng.seed(seed)
echo "test_io_fields xoshiro512** seed: ", seed
proc main() = proc main() =
suite "IO - Finite fields": suite "IO - Finite fields":
@ -99,7 +103,7 @@ proc main() =
check: x_bytes == r_bytes[0 ..< 8] check: x_bytes == r_bytes[0 ..< 8]
block: # "Little-endian" - single random block: # "Little-endian" - single random
let x = uint64 rand(0..high(int)) let x = rng.random_unsafe(uint64)
let x_bytes = cast[array[8, byte]](x) let x_bytes = cast[array[8, byte]](x)
var f: Fp[Mersenne127] var f: Fp[Mersenne127]
f.fromUint(x) f.fromUint(x)
@ -110,7 +114,7 @@ proc main() =
block: # "Little-endian" - 10 random cases block: # "Little-endian" - 10 random cases
for _ in 0 ..< 10: for _ in 0 ..< 10:
let x = uint64 rand(0..high(int)) let x = rng.random_unsafe(uint64)
let x_bytes = cast[array[8, byte]](x) let x_bytes = cast[array[8, byte]](x)
var f: Fp[Mersenne127] var f: Fp[Mersenne127]
f.fromUint(x) f.fromUint(x)

View File

@ -6,11 +6,15 @@
# * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0). # * Apache v2 license (license terms in the root directory or at http://www.apache.org/licenses/LICENSE-2.0).
# at your option. This file may not be copied, modified, or distributed except according to those terms. # at your option. This file may not be copied, modified, or distributed except according to those terms.
import unittest, random, math, import std/[unittest, times, math],
../constantine/primitives ../constantine/primitives,
../helpers/prng_unsafe
# Random seed for reproducibility # Random seed for reproducibility
randomize(0xDEADBEEF) var rng: RngState
let seed = uint32(getTime().toUnix() and (1'i64 shl 32 - 1)) # unixTime mod 2^32
rng.seed(seed)
echo "test_primitives xoshiro512** seed: ", seed
template undistinct[T](x: Ct[T]): T = template undistinct[T](x: Ct[T]): T =
T(x) T(x)
@ -27,12 +31,12 @@ proc main() =
high(Ct[uint64]).undistinct == 0xFFFFFFFF_FFFFFFFF'u64 high(Ct[uint64]).undistinct == 0xFFFFFFFF_FFFFFFFF'u64
test "bitwise `and`, `or`, `xor`, `not`": test "bitwise `and`, `or`, `xor`, `not`":
let x1 = rand(high(int)).uint64 let x1 = rng.random_unsafe(uint64)
let y1 = rand(high(int)).uint64 let y1 = rng.random_unsafe(uint64)
let x2 = rand(high(int)).uint64 let x2 = rng.random_unsafe(uint64)
let y2 = rand(high(int)).uint64 let y2 = rng.random_unsafe(uint64)
let x3 = rand(high(int)).uint64 let x3 = rng.random_unsafe(uint64)
let y3 = rand(high(int)).uint64 let y3 = rng.random_unsafe(uint64)
template bitwise_check(op: untyped): untyped = template bitwise_check(op: untyped): untyped =
block: block:
check: check:
@ -61,16 +65,16 @@ proc main() =
not(ct(y3)).undistinct == not y3 not(ct(y3)).undistinct == not y3
test "Logical shifts": test "Logical shifts":
let x1 = rand(high(int)).uint64 let x1 = rng.random_unsafe(uint64)
let y1 = rand(high(int)).uint64 let y1 = rng.random_unsafe(uint64)
let x2 = rand(high(int)).uint64 let x2 = rng.random_unsafe(uint64)
let y2 = rand(high(int32)).uint64 let y2 = rng.random_unsafe(uint64)
let x3 = rand(high(int32)).uint64 let x3 = rng.random_unsafe(uint64)
let y3 = rand(high(int32)).uint64 let y3 = rng.random_unsafe(uint64)
let s1 = rand(10) let s1 = uint64 rng.random_unsafe(10)
let s2 = rand(10) let s2 = uint64 rng.random_unsafe(10)
let s3 = rand(10) let s3 = uint64 rng.random_unsafe(10)
template shift_check(op: untyped): untyped = template shift_check(op: untyped): untyped =
block: block:
@ -96,12 +100,12 @@ proc main() =
test "Operators `+`, `-`, `*`": test "Operators `+`, `-`, `*`":
let x1 = rand(high(int)).uint64 let x1 = rng.random_unsafe(uint64)
let y1 = rand(high(int)).uint64 let y1 = rng.random_unsafe(uint64)
let x2 = rand(high(int)).uint64 let x2 = rng.random_unsafe(uint64)
let y2 = rand(high(int)).uint64 let y2 = rng.random_unsafe(uint64)
let x3 = rand(high(int)).uint64 let x3 = rng.random_unsafe(uint64)
let y3 = rand(high(int)).uint64 let y3 = rng.random_unsafe(uint64)
template operator_check(op: untyped): untyped = template operator_check(op: untyped): untyped =
block: block:
check: check:
@ -117,12 +121,12 @@ proc main() =
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 = rng.random_unsafe(uint64)
let y1 = rand(high(int)).uint64 let y1 = rng.random_unsafe(uint64)
let x2 = rand(high(int)).uint64 let x2 = rng.random_unsafe(uint64)
let y2 = rand(high(int)).uint64 let y2 = rng.random_unsafe(uint64)
let x3 = rand(high(int)).uint64 let x3 = rng.random_unsafe(uint64)
let y3 = rand(high(int)).uint64 let y3 = rng.random_unsafe(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