From 1559bda56cdfbfccb998e7cc76547552b44312df Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Mamy=20Andr=C3=A9-Ratsimbazafy?= Date: Tue, 14 Apr 2020 20:46:39 +0200 Subject: [PATCH] Use our prng through most of the test suite --- helpers/prng_unsafe.nim | 8 ++++- tests/test_fp12.nim | 5 +-- tests/test_fp2.nim | 5 +-- tests/test_fp6.nim | 5 +-- tests/test_io_bigints.nim | 16 +++++++--- tests/test_io_fields.nim | 16 ++++++---- tests/test_primitives.nim | 64 +++++++++++++++++++++------------------ 7 files changed, 71 insertions(+), 48 deletions(-) diff --git a/helpers/prng_unsafe.nim b/helpers/prng_unsafe.nim index 2336522..1d95a3e 100644 --- a/helpers/prng_unsafe.nim +++ b/helpers/prng_unsafe.nim @@ -130,7 +130,7 @@ func random_unsafe_with_randZ[F](rng: var RngState, a: var ECP_SWei_Proj[F]) = # 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 ## Uses an unbiaised generation method ## 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 # ------------------------------------------------------------ +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 = ## Return a random integer in the given range. ## 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 when T is ECP_SWei_Proj: 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: rng.random_unsafe(result, T.C) diff --git a/tests/test_fp12.nim b/tests/test_fp12.nim index 14559cf..e4970b4 100644 --- a/tests/test_fp12.nim +++ b/tests/test_fp12.nim @@ -8,7 +8,7 @@ import # Standard library - unittest, times, random, + unittest, times, # Internals ../constantine/towers, ../constantine/config/[common, curves], @@ -18,6 +18,7 @@ import const Iters = 128 +# 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) @@ -348,7 +349,7 @@ suite "𝔽p12 = 𝔽p6[w] (irreducible polynomial w² - γ)": block: proc testInstance() = for _ in 0 ..< Iters: - let factor = rand(-30..30) + let factor = rng.random_unsafe(-30..30) let a = rng.random_unsafe(Fp12[C]) diff --git a/tests/test_fp2.nim b/tests/test_fp2.nim index a49c35c..c3b16be 100644 --- a/tests/test_fp2.nim +++ b/tests/test_fp2.nim @@ -8,7 +8,7 @@ import # Standard library - unittest, times, random, + unittest, times, # Internals ../constantine/towers, ../constantine/config/[common, curves], @@ -18,6 +18,7 @@ import const Iters = 128 +# 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) @@ -245,7 +246,7 @@ suite "𝔽p2 = 𝔽p[µ] (irreducible polynomial x²+µ)": block: proc testInstance() = for _ in 0 ..< Iters: - let factor = rand(-30..30) + let factor = rng.random_unsafe(-30..30) let a = rng.random_unsafe(Fp2[C]) diff --git a/tests/test_fp6.nim b/tests/test_fp6.nim index bde9bcf..7185db0 100644 --- a/tests/test_fp6.nim +++ b/tests/test_fp6.nim @@ -8,7 +8,7 @@ import # Standard library - unittest, times, random, + unittest, times, # Internals ../constantine/towers, ../constantine/config/[common, curves], @@ -18,6 +18,7 @@ import const Iters = 128 +# 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) @@ -348,7 +349,7 @@ suite "𝔽p6 = 𝔽p2[v] (irreducible polynomial v³ - ξ)": block: proc testInstance() = for _ in 0 ..< Iters: - let factor = rand(-30..30) + let factor = rng.random_unsafe(-30..30) let a = rng.random_unsafe(Fp6[C]) diff --git a/tests/test_io_bigints.nim b/tests/test_io_bigints.nim index 2a506c5..dd4c44c 100644 --- a/tests/test_io_bigints.nim +++ b/tests/test_io_bigints.nim @@ -6,12 +6,18 @@ # * 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. -import unittest, random, +import std/[unittest,times], ../constantine/io/io_bigints, ../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 proc main() = @@ -37,7 +43,7 @@ proc main() = check: x_bytes == r_bytes 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 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 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 big = BigInt[64].fromRawUint(x_bytes, littleEndian) # It's fine even on big-endian platform. We only want the byte-pattern diff --git a/tests/test_io_fields.nim b/tests/test_io_fields.nim index fbee1e2..405c294 100644 --- a/tests/test_io_fields.nim +++ b/tests/test_io_fields.nim @@ -6,14 +6,18 @@ # * 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. -import unittest, random, +import std/[unittest, times], ../constantine/io/[io_bigints, io_fields], ../constantine/config/curves, ../constantine/config/common, - ../constantine/arithmetic + ../constantine/arithmetic, + ../helpers/prng_unsafe -randomize(0xDEADBEEF) # Random seed for reproducibility -type T = BaseType +# 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_fields xoshiro512** seed: ", seed proc main() = suite "IO - Finite fields": @@ -99,7 +103,7 @@ proc main() = check: x_bytes == r_bytes[0 ..< 8] 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) var f: Fp[Mersenne127] f.fromUint(x) @@ -110,7 +114,7 @@ proc main() = block: # "Little-endian" - 10 random cases 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) var f: Fp[Mersenne127] f.fromUint(x) diff --git a/tests/test_primitives.nim b/tests/test_primitives.nim index a0892c5..68cfdfd 100644 --- a/tests/test_primitives.nim +++ b/tests/test_primitives.nim @@ -6,11 +6,15 @@ # * 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. -import unittest, random, math, - ../constantine/primitives +import std/[unittest, times, math], + ../constantine/primitives, + ../helpers/prng_unsafe # 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 = T(x) @@ -27,12 +31,12 @@ proc main() = 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 + let x1 = rng.random_unsafe(uint64) + let y1 = rng.random_unsafe(uint64) + let x2 = rng.random_unsafe(uint64) + let y2 = rng.random_unsafe(uint64) + let x3 = rng.random_unsafe(uint64) + let y3 = rng.random_unsafe(uint64) template bitwise_check(op: untyped): untyped = block: check: @@ -61,16 +65,16 @@ proc main() = not(ct(y3)).undistinct == not y3 test "Logical shifts": - let x1 = rand(high(int)).uint64 - 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 x1 = rng.random_unsafe(uint64) + let y1 = rng.random_unsafe(uint64) + let x2 = rng.random_unsafe(uint64) + let y2 = rng.random_unsafe(uint64) + let x3 = rng.random_unsafe(uint64) + let y3 = rng.random_unsafe(uint64) - let s1 = rand(10) - let s2 = rand(10) - let s3 = rand(10) + let s1 = uint64 rng.random_unsafe(10) + let s2 = uint64 rng.random_unsafe(10) + let s3 = uint64 rng.random_unsafe(10) template shift_check(op: untyped): untyped = block: @@ -96,12 +100,12 @@ proc main() = test "Operators `+`, `-`, `*`": - 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 + let x1 = rng.random_unsafe(uint64) + let y1 = rng.random_unsafe(uint64) + let x2 = rng.random_unsafe(uint64) + let y2 = rng.random_unsafe(uint64) + let x3 = rng.random_unsafe(uint64) + let y3 = rng.random_unsafe(uint64) template operator_check(op: untyped): untyped = block: check: @@ -117,12 +121,12 @@ proc main() = operator_check(`*`) test "Unary `-`, returning the 2-complement of an unsigned integer": - 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 + let x1 = rng.random_unsafe(uint64) + let y1 = rng.random_unsafe(uint64) + let x2 = rng.random_unsafe(uint64) + let y2 = rng.random_unsafe(uint64) + let x3 = rng.random_unsafe(uint64) + let y3 = rng.random_unsafe(uint64) check: (-ct(0'u32)).undistinct == 0 (-high(Ct[uint32])).undistinct == 1'u32