2020-06-15 20:58:56 +00:00
|
|
|
# Constantine
|
|
|
|
# Copyright (c) 2018-2019 Status Research & Development GmbH
|
|
|
|
# Copyright (c) 2020-Present Mamy André-Ratsimbazafy
|
|
|
|
# Licensed and distributed under either of
|
|
|
|
# * MIT license (license terms in the root directory or at http://opensource.org/licenses/MIT).
|
|
|
|
# * 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.
|
|
|
|
|
|
|
|
# ############################################################
|
|
|
|
#
|
|
|
|
# Template tests for elliptic curve operations
|
|
|
|
#
|
|
|
|
# ############################################################
|
|
|
|
|
|
|
|
import
|
|
|
|
# Standard library
|
|
|
|
std/[unittest, times],
|
|
|
|
# Internals
|
|
|
|
../constantine/config/[common, curves],
|
|
|
|
../constantine/arithmetic,
|
|
|
|
../constantine/towers,
|
2020-10-01 22:01:09 +00:00
|
|
|
../constantine/elliptic/[
|
|
|
|
ec_shortweierstrass_affine,
|
|
|
|
ec_shortweierstrass_jacobian,
|
|
|
|
ec_shortweierstrass_projective,
|
|
|
|
ec_scalar_mul],
|
|
|
|
../constantine/io/[io_bigints, io_fields],
|
2020-06-15 20:58:56 +00:00
|
|
|
# Test utilities
|
|
|
|
../helpers/prng_unsafe,
|
|
|
|
./support/ec_reference_scalar_mult
|
|
|
|
|
2020-06-20 16:55:27 +00:00
|
|
|
type
|
2020-08-31 21:18:48 +00:00
|
|
|
RandomGen* = enum
|
2020-06-20 16:55:27 +00:00
|
|
|
Uniform
|
|
|
|
HighHammingWeight
|
|
|
|
Long01Sequence
|
|
|
|
|
2020-09-21 21:24:00 +00:00
|
|
|
func random_point*(rng: var RngState, EC: typedesc, randZ: bool, gen: RandomGen): EC {.noInit.} =
|
|
|
|
if not randZ:
|
|
|
|
if gen == Uniform:
|
|
|
|
result = rng.random_unsafe(EC)
|
2020-06-20 16:55:27 +00:00
|
|
|
elif gen == HighHammingWeight:
|
2020-09-21 21:24:00 +00:00
|
|
|
result = rng.random_highHammingWeight(EC)
|
2020-06-20 16:55:27 +00:00
|
|
|
else:
|
2020-09-21 21:24:00 +00:00
|
|
|
result = rng.random_long01Seq(EC)
|
2020-06-20 16:55:27 +00:00
|
|
|
else:
|
2020-09-21 21:24:00 +00:00
|
|
|
if gen == Uniform:
|
|
|
|
result = rng.random_unsafe_with_randZ(EC)
|
2020-06-20 16:55:27 +00:00
|
|
|
elif gen == HighHammingWeight:
|
2020-09-21 21:24:00 +00:00
|
|
|
result = rng.random_highHammingWeight_with_randZ(EC)
|
2020-06-20 16:55:27 +00:00
|
|
|
else:
|
2020-09-21 21:24:00 +00:00
|
|
|
result = rng.random_long01Seq_with_randZ(EC)
|
2020-06-20 16:55:27 +00:00
|
|
|
|
2020-06-15 20:58:56 +00:00
|
|
|
proc run_EC_addition_tests*(
|
|
|
|
ec: typedesc,
|
|
|
|
Iters: static int,
|
|
|
|
moduleName: string
|
|
|
|
) =
|
|
|
|
|
|
|
|
# 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 "\n------------------------------------------------------\n"
|
|
|
|
echo moduleName, " xoshiro512** seed: ", seed
|
|
|
|
|
2020-10-09 05:51:47 +00:00
|
|
|
when ec.Tw == NotOnTwist:
|
2020-06-15 20:58:56 +00:00
|
|
|
const G1_or_G2 = "G1"
|
|
|
|
else:
|
|
|
|
const G1_or_G2 = "G2"
|
|
|
|
|
|
|
|
const testSuiteDesc = "Elliptic curve in Short Weierstrass form with projective coordinates"
|
|
|
|
|
|
|
|
suite testSuiteDesc & " - " & $ec & " - [" & $WordBitwidth & "-bit mode]":
|
|
|
|
test "The infinity point is the neutral element w.r.t. to EC " & G1_or_G2 & " addition":
|
2020-09-21 21:24:00 +00:00
|
|
|
proc test(EC: typedesc, randZ: bool, gen: RandomGen) =
|
2020-06-15 20:58:56 +00:00
|
|
|
var inf {.noInit.}: EC
|
|
|
|
inf.setInf()
|
|
|
|
check: bool inf.isInf()
|
|
|
|
|
|
|
|
for _ in 0 ..< Iters:
|
|
|
|
var r{.noInit.}: EC
|
2020-06-20 16:55:27 +00:00
|
|
|
let P = rng.random_point(EC, randZ, gen)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
r.sum(P, inf)
|
|
|
|
check: bool(r == P)
|
|
|
|
|
|
|
|
r.sum(inf, P)
|
|
|
|
check: bool(r == P)
|
|
|
|
|
2020-06-20 16:55:27 +00:00
|
|
|
test(ec, randZ = false, gen = Uniform)
|
|
|
|
test(ec, randZ = true, gen = Uniform)
|
|
|
|
test(ec, randZ = false, gen = HighHammingWeight)
|
|
|
|
test(ec, randZ = true, gen = HighHammingWeight)
|
|
|
|
test(ec, randZ = false, gen = Long01Sequence)
|
|
|
|
test(ec, randZ = true, gen = Long01Sequence)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
test "Adding opposites gives an infinity point":
|
2020-09-21 21:24:00 +00:00
|
|
|
proc test(EC: typedesc, randZ: bool, gen: RandomGen) =
|
2020-06-15 20:58:56 +00:00
|
|
|
for _ in 0 ..< Iters:
|
|
|
|
var r{.noInit.}: EC
|
2020-06-20 16:55:27 +00:00
|
|
|
let P = rng.random_point(EC, randZ, gen)
|
2020-06-15 20:58:56 +00:00
|
|
|
var Q = P
|
|
|
|
Q.neg()
|
|
|
|
|
|
|
|
r.sum(P, Q)
|
|
|
|
check: bool r.isInf()
|
|
|
|
|
|
|
|
r.sum(Q, P)
|
|
|
|
check: bool r.isInf()
|
|
|
|
|
2020-06-20 16:55:27 +00:00
|
|
|
test(ec, randZ = false, gen = Uniform)
|
|
|
|
test(ec, randZ = true, gen = Uniform)
|
|
|
|
test(ec, randZ = false, gen = HighHammingWeight)
|
|
|
|
test(ec, randZ = true, gen = HighHammingWeight)
|
|
|
|
test(ec, randZ = false, gen = Long01Sequence)
|
|
|
|
test(ec, randZ = true, gen = Long01Sequence)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
test "EC " & G1_or_G2 & " add is commutative":
|
2020-09-21 21:24:00 +00:00
|
|
|
proc test(EC: typedesc, randZ: bool, gen: RandomGen) =
|
2020-06-15 20:58:56 +00:00
|
|
|
for _ in 0 ..< Iters:
|
|
|
|
var r0{.noInit.}, r1{.noInit.}: EC
|
2020-06-20 16:55:27 +00:00
|
|
|
let P = rng.random_point(EC, randZ, gen)
|
|
|
|
let Q = rng.random_point(EC, randZ, gen)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
r0.sum(P, Q)
|
|
|
|
r1.sum(Q, P)
|
|
|
|
check: bool(r0 == r1)
|
|
|
|
|
2020-06-20 16:55:27 +00:00
|
|
|
test(ec, randZ = false, gen = Uniform)
|
|
|
|
test(ec, randZ = true, gen = Uniform)
|
|
|
|
test(ec, randZ = false, gen = HighHammingWeight)
|
|
|
|
test(ec, randZ = true, gen = HighHammingWeight)
|
|
|
|
test(ec, randZ = false, gen = Long01Sequence)
|
|
|
|
test(ec, randZ = true, gen = Long01Sequence)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
test "EC " & G1_or_G2 & " add is associative":
|
2020-09-21 21:24:00 +00:00
|
|
|
proc test(EC: typedesc, randZ: bool, gen: RandomGen) =
|
2020-06-15 20:58:56 +00:00
|
|
|
for _ in 0 ..< Iters:
|
2020-06-20 16:55:27 +00:00
|
|
|
let a = rng.random_point(EC, randZ, gen)
|
|
|
|
let b = rng.random_point(EC, randZ, gen)
|
|
|
|
let c = rng.random_point(EC, randZ, gen)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
var tmp1{.noInit.}, tmp2{.noInit.}: EC
|
|
|
|
|
|
|
|
# r0 = (a + b) + c
|
|
|
|
tmp1.sum(a, b)
|
|
|
|
tmp2.sum(tmp1, c)
|
|
|
|
let r0 = tmp2
|
|
|
|
|
|
|
|
# r1 = a + (b + c)
|
|
|
|
tmp1.sum(b, c)
|
|
|
|
tmp2.sum(a, tmp1)
|
|
|
|
let r1 = tmp2
|
|
|
|
|
|
|
|
# r2 = (a + c) + b
|
|
|
|
tmp1.sum(a, c)
|
|
|
|
tmp2.sum(tmp1, b)
|
|
|
|
let r2 = tmp2
|
|
|
|
|
|
|
|
# r3 = a + (c + b)
|
|
|
|
tmp1.sum(c, b)
|
|
|
|
tmp2.sum(a, tmp1)
|
|
|
|
let r3 = tmp2
|
|
|
|
|
|
|
|
# r4 = (c + a) + b
|
|
|
|
tmp1.sum(c, a)
|
|
|
|
tmp2.sum(tmp1, b)
|
|
|
|
let r4 = tmp2
|
|
|
|
|
|
|
|
# ...
|
|
|
|
|
|
|
|
check:
|
|
|
|
bool(r0 == r1)
|
|
|
|
bool(r0 == r2)
|
|
|
|
bool(r0 == r3)
|
|
|
|
bool(r0 == r4)
|
|
|
|
|
2020-06-20 16:55:27 +00:00
|
|
|
test(ec, randZ = false, gen = Uniform)
|
|
|
|
test(ec, randZ = true, gen = Uniform)
|
|
|
|
test(ec, randZ = false, gen = HighHammingWeight)
|
|
|
|
test(ec, randZ = true, gen = HighHammingWeight)
|
|
|
|
test(ec, randZ = false, gen = Long01Sequence)
|
|
|
|
test(ec, randZ = true, gen = Long01Sequence)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
test "EC " & G1_or_G2 & " double and EC " & G1_or_G2 & " add are consistent":
|
2020-09-21 21:24:00 +00:00
|
|
|
proc test(EC: typedesc, randZ: bool, gen: RandomGen) =
|
2020-06-15 20:58:56 +00:00
|
|
|
for _ in 0 ..< Iters:
|
2020-06-20 16:55:27 +00:00
|
|
|
let a = rng.random_point(EC, randZ, gen)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
var r0{.noInit.}, r1{.noInit.}: EC
|
|
|
|
|
|
|
|
r0.double(a)
|
|
|
|
r1.sum(a, a)
|
|
|
|
|
|
|
|
check: bool(r0 == r1)
|
|
|
|
|
2020-06-20 16:55:27 +00:00
|
|
|
test(ec, randZ = false, gen = Uniform)
|
|
|
|
test(ec, randZ = true, gen = Uniform)
|
|
|
|
test(ec, randZ = false, gen = HighHammingWeight)
|
|
|
|
test(ec, randZ = true, gen = HighHammingWeight)
|
|
|
|
test(ec, randZ = false, gen = Long01Sequence)
|
|
|
|
test(ec, randZ = true, gen = Long01Sequence)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
proc run_EC_mul_sanity_tests*(
|
|
|
|
ec: typedesc,
|
|
|
|
ItersMul: static int,
|
|
|
|
moduleName: string
|
|
|
|
) =
|
|
|
|
|
|
|
|
# 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 "\n------------------------------------------------------\n"
|
|
|
|
echo moduleName, " xoshiro512** seed: ", seed
|
|
|
|
|
2020-10-09 05:51:47 +00:00
|
|
|
when ec.Tw == NotOnTwist:
|
2020-06-15 20:58:56 +00:00
|
|
|
const G1_or_G2 = "G1"
|
|
|
|
else:
|
|
|
|
const G1_or_G2 = "G2"
|
|
|
|
|
2020-10-01 22:01:09 +00:00
|
|
|
const testSuiteDesc = "Elliptic curve in Short Weierstrass form"
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
suite testSuiteDesc & " - " & $ec & " - [" & $WordBitwidth & "-bit mode]":
|
|
|
|
test "EC " & G1_or_G2 & " mul [0]P == Inf":
|
2020-09-21 21:24:00 +00:00
|
|
|
proc test(EC: typedesc, bits: static int, randZ: bool, gen: RandomGen) =
|
2020-06-15 20:58:56 +00:00
|
|
|
for _ in 0 ..< ItersMul:
|
2020-06-20 16:55:27 +00:00
|
|
|
let a = rng.random_point(EC, randZ, gen)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
var
|
|
|
|
impl = a
|
|
|
|
reference = a
|
|
|
|
|
2020-09-03 21:10:48 +00:00
|
|
|
impl.scalarMulGeneric(BigInt[bits]())
|
|
|
|
reference.unsafe_ECmul_double_add(BigInt[bits]())
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
check:
|
|
|
|
bool(impl.isInf())
|
|
|
|
bool(reference.isInf())
|
|
|
|
|
2020-06-20 16:55:27 +00:00
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = Uniform)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = Uniform)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = HighHammingWeight)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = HighHammingWeight)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = Long01Sequence)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = Long01Sequence)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
test "EC " & G1_or_G2 & " mul [1]P == P":
|
2020-09-21 21:24:00 +00:00
|
|
|
proc test(EC: typedesc, bits: static int, randZ: bool, gen: RandomGen) =
|
2020-06-15 20:58:56 +00:00
|
|
|
for _ in 0 ..< ItersMul:
|
2020-06-20 16:55:27 +00:00
|
|
|
let a = rng.random_point(EC, randZ, gen)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
var exponent{.noInit.}: BigInt[bits]
|
|
|
|
exponent.setOne()
|
|
|
|
|
|
|
|
var
|
|
|
|
impl = a
|
|
|
|
reference = a
|
|
|
|
|
2020-09-03 21:10:48 +00:00
|
|
|
impl.scalarMulGeneric(exponent)
|
|
|
|
reference.unsafe_ECmul_double_add(exponent)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
check:
|
|
|
|
bool(impl == a)
|
|
|
|
bool(reference == a)
|
|
|
|
|
2020-06-20 16:55:27 +00:00
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = Uniform)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = Uniform)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = HighHammingWeight)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = HighHammingWeight)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = Long01Sequence)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = Long01Sequence)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
test "EC " & G1_or_G2 & " mul [2]P == P.double()":
|
2020-09-21 21:24:00 +00:00
|
|
|
proc test(EC: typedesc, bits: static int, randZ: bool, gen: RandomGen) =
|
2020-06-15 20:58:56 +00:00
|
|
|
for _ in 0 ..< ItersMul:
|
2020-06-20 16:55:27 +00:00
|
|
|
let a = rng.random_point(EC, randZ, gen)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
var doubleA{.noInit.}: EC
|
|
|
|
doubleA.double(a)
|
|
|
|
|
|
|
|
let exponent = BigInt[bits].fromUint(2)
|
|
|
|
|
|
|
|
var
|
|
|
|
impl = a
|
|
|
|
reference = a
|
|
|
|
|
2020-09-03 21:10:48 +00:00
|
|
|
impl.scalarMulGeneric(exponent)
|
|
|
|
reference.unsafe_ECmul_double_add(exponent)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
check:
|
|
|
|
bool(impl == doubleA)
|
|
|
|
bool(reference == doubleA)
|
|
|
|
|
2020-06-20 16:55:27 +00:00
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = Uniform)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = Uniform)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = HighHammingWeight)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = HighHammingWeight)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = Long01Sequence)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = Long01Sequence)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
proc run_EC_mul_distributive_tests*(
|
|
|
|
ec: typedesc,
|
|
|
|
ItersMul: static int,
|
|
|
|
moduleName: string
|
|
|
|
) =
|
|
|
|
|
|
|
|
# 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 "\n------------------------------------------------------\n"
|
|
|
|
echo moduleName, " xoshiro512** seed: ", seed
|
|
|
|
|
2020-10-09 05:51:47 +00:00
|
|
|
when ec.Tw == NotOnTwist:
|
2020-06-15 20:58:56 +00:00
|
|
|
const G1_or_G2 = "G1"
|
|
|
|
else:
|
|
|
|
const G1_or_G2 = "G2"
|
|
|
|
|
2020-10-01 22:01:09 +00:00
|
|
|
const testSuiteDesc = "Elliptic curve in Short Weierstrass form"
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
suite testSuiteDesc & " - " & $ec & " - [" & $WordBitwidth & "-bit mode]":
|
|
|
|
|
|
|
|
test "EC " & G1_or_G2 & " mul is distributive over EC add":
|
2020-09-21 21:24:00 +00:00
|
|
|
proc test(EC: typedesc, bits: static int, randZ: bool, gen: RandomGen) =
|
2020-06-15 20:58:56 +00:00
|
|
|
for _ in 0 ..< ItersMul:
|
2020-06-20 16:55:27 +00:00
|
|
|
let a = rng.random_point(EC, randZ, gen)
|
|
|
|
let b = rng.random_point(EC, randZ, gen)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
let exponent = rng.random_unsafe(BigInt[bits])
|
|
|
|
|
|
|
|
# [k](a + b) - Factorized
|
|
|
|
var
|
|
|
|
fImpl{.noInit.}: EC
|
|
|
|
fReference{.noInit.}: EC
|
|
|
|
|
|
|
|
fImpl.sum(a, b)
|
|
|
|
fReference.sum(a, b)
|
|
|
|
|
2020-09-03 21:10:48 +00:00
|
|
|
fImpl.scalarMulGeneric(exponent)
|
|
|
|
fReference.unsafe_ECmul_double_add(exponent)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
# [k]a + [k]b - Distributed
|
|
|
|
var kaImpl = a
|
|
|
|
var kaRef = a
|
|
|
|
|
2020-09-03 21:10:48 +00:00
|
|
|
kaImpl.scalarMulGeneric(exponent)
|
|
|
|
kaRef.unsafe_ECmul_double_add(exponent)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
var kbImpl = b
|
|
|
|
var kbRef = b
|
|
|
|
|
2020-09-03 21:10:48 +00:00
|
|
|
kbImpl.scalarMulGeneric(exponent)
|
|
|
|
kbRef.unsafe_ECmul_double_add(exponent)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
var kakbImpl{.noInit.}, kakbRef{.noInit.}: EC
|
|
|
|
kakbImpl.sum(kaImpl, kbImpl)
|
|
|
|
kakbRef.sum(kaRef, kbRef)
|
|
|
|
|
|
|
|
check:
|
|
|
|
bool(fImpl == kakbImpl)
|
|
|
|
bool(fReference == kakbRef)
|
|
|
|
bool(fImpl == fReference)
|
|
|
|
|
2020-06-20 16:55:27 +00:00
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = Uniform)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = Uniform)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = HighHammingWeight)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = HighHammingWeight)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = Long01Sequence)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = Long01Sequence)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
proc run_EC_mul_vs_ref_impl*(
|
|
|
|
ec: typedesc,
|
|
|
|
ItersMul: static int,
|
|
|
|
moduleName: string
|
|
|
|
) =
|
|
|
|
|
|
|
|
# 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 "\n------------------------------------------------------\n"
|
|
|
|
echo moduleName, " xoshiro512** seed: ", seed
|
|
|
|
|
2020-10-09 05:51:47 +00:00
|
|
|
when ec.Tw == NotOnTwist:
|
2020-06-15 20:58:56 +00:00
|
|
|
const G1_or_G2 = "G1"
|
|
|
|
else:
|
|
|
|
const G1_or_G2 = "G2"
|
|
|
|
|
2020-10-01 22:01:09 +00:00
|
|
|
const testSuiteDesc = "Elliptic curve in Short Weierstrass form"
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
suite testSuiteDesc & " - " & $ec & " - [" & $WordBitwidth & "-bit mode]":
|
|
|
|
test "EC " & G1_or_G2 & " mul constant-time is equivalent to a simple double-and-add algorithm":
|
2020-09-21 21:24:00 +00:00
|
|
|
proc test(EC: typedesc, bits: static int, randZ: bool, gen: RandomGen) =
|
2020-06-15 20:58:56 +00:00
|
|
|
for _ in 0 ..< ItersMul:
|
2020-06-20 16:55:27 +00:00
|
|
|
let a = rng.random_point(EC, randZ, gen)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
let exponent = rng.random_unsafe(BigInt[bits])
|
|
|
|
|
|
|
|
var
|
|
|
|
impl = a
|
|
|
|
reference = a
|
|
|
|
|
2020-09-03 21:10:48 +00:00
|
|
|
impl.scalarMulGeneric(exponent)
|
|
|
|
reference.unsafe_ECmul_double_add(exponent)
|
2020-06-15 20:58:56 +00:00
|
|
|
|
|
|
|
check: bool(impl == reference)
|
|
|
|
|
2020-06-20 16:55:27 +00:00
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = Uniform)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = Uniform)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = HighHammingWeight)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = HighHammingWeight)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = Long01Sequence)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = Long01Sequence)
|
2020-09-26 07:16:29 +00:00
|
|
|
|
|
|
|
proc run_EC_mixed_add_impl*(
|
|
|
|
ec: typedesc,
|
|
|
|
Iters: static int,
|
|
|
|
moduleName: string
|
|
|
|
) =
|
|
|
|
|
|
|
|
# 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 "\n------------------------------------------------------\n"
|
|
|
|
echo moduleName, " xoshiro512** seed: ", seed
|
|
|
|
|
2020-10-09 05:51:47 +00:00
|
|
|
when ec.Tw == NotOnTwist:
|
2020-09-26 07:16:29 +00:00
|
|
|
const G1_or_G2 = "G1"
|
|
|
|
else:
|
|
|
|
const G1_or_G2 = "G2"
|
|
|
|
|
|
|
|
const testSuiteDesc = "Elliptic curve mixed addition for Short Weierstrass form"
|
|
|
|
|
|
|
|
suite testSuiteDesc & " - " & $ec & " - [" & $WordBitwidth & "-bit mode]":
|
|
|
|
test "EC " & G1_or_G2 & " mixed addition is consistent with general addition":
|
|
|
|
proc test(EC: typedesc, bits: static int, randZ: bool, gen: RandomGen) =
|
|
|
|
for _ in 0 ..< Iters:
|
|
|
|
let a = rng.random_point(EC, randZ, gen)
|
|
|
|
let b = rng.random_point(EC, randZ, gen)
|
2020-10-09 05:51:47 +00:00
|
|
|
var bAff: ECP_ShortW_Aff[EC.F, EC.Tw]
|
2020-09-26 07:16:29 +00:00
|
|
|
bAff.affineFromProjective(b)
|
|
|
|
|
|
|
|
var r_generic, r_mixed: EC
|
|
|
|
|
|
|
|
r_generic.sum(a, b)
|
|
|
|
r_mixed.madd(a, bAff)
|
|
|
|
|
|
|
|
check: bool(r_generic == r_mixed)
|
|
|
|
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = Uniform)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = Uniform)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = HighHammingWeight)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = HighHammingWeight)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = false, gen = Long01Sequence)
|
|
|
|
test(ec, bits = ec.F.C.getCurveOrderBitwidth(), randZ = true, gen = Long01Sequence)
|