# 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. import # Standard library std/[tables, unittest, times], # Internals ../constantine/config/common, ../constantine/[arithmetic, primitives], ../constantine/towers, ../constantine/config/curves, ../constantine/io/io_towers, ../constantine/pairing/[ lines_projective, gt_fp12 ], # Test utilities ../helpers/[prng_unsafe, static_for] const Iters = 8 TestCurves = [ # BN254_Snarks, BLS12_381 ] type RandomGen = enum Uniform HighHammingWeight Long01Sequence 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 "test_pairing_fp12_sparse xoshiro512** seed: ", seed func random_elem(rng: var RngState, F: typedesc, gen: RandomGen): F {.inline, noInit.} = if gen == Uniform: result = rng.random_unsafe(F) elif gen == HighHammingWeight: result = rng.random_highHammingWeight(F) else: result = rng.random_long01Seq(F) suite "Pairing - Sparse 𝔽p12 multiplication by line function is consistent with dense 𝔽p12 mul": test "Dense 𝔽p6 by Sparse 0y0": proc test_fp6_0y0(C: static Curve, gen: static RandomGen) = for _ in 0 ..< Iters: let a = rng.random_elem(Fp6[C], gen) let y = rng.random_elem(Fp2[C], gen) let b = Fp6[C](c1: y) var r {.noInit.}, r2 {.noInit.}: Fp6[C] r.prod(a, b) r2.mul_sparse_by_0y0(a, y) check: bool(r == r2) staticFor(curve, TestCurves): test_fp6_0y0(curve, gen = Uniform) test_fp6_0y0(curve, gen = HighHammingWeight) test_fp6_0y0(curve, gen = Long01Sequence) test "Dense 𝔽p6 by Sparse xy0": proc test_fp6_0y0(C: static Curve, gen: static RandomGen) = for _ in 0 ..< Iters: let a = rng.random_elem(Fp6[C], gen) let x = rng.random_elem(Fp2[C], gen) let y = rng.random_elem(Fp2[C], gen) let b = Fp6[C](c0: x, c1: y) let line = Line[Fp2[C], M_twist](x: x, y: y) var r {.noInit.}, r2 {.noInit.}: Fp6[C] r.prod(a, b) r2.mul_by_line_xy0(a, line) check: bool(r == r2) staticFor(curve, TestCurves): test_fp6_0y0(curve, gen = Uniform) test_fp6_0y0(curve, gen = HighHammingWeight) test_fp6_0y0(curve, gen = Long01Sequence) when Fp12[BN254_Snarks]().c0.typeof is Fp6: test "Sparse 𝔽p12 resulting from xy00z0 line function": proc test_fp12_xy00z0(C: static Curve, gen: static RandomGen) = for _ in 0 ..< Iters: var a = rng.random_elem(Fp12[C], gen) var a2 = a var x = rng.random_elem(Fp2[C], gen) var y = rng.random_elem(Fp2[C], gen) var z = rng.random_elem(Fp2[C], gen) let line = Line[Fp2[C], Mtwist](x: x, y: y, z: z) let b = Fp12[C]( c0: Fp6[C](c0: x, c1: y), c1: Fp6[C](c1: z) ) a *= b a2.mul_sparse_by_line_xy00z0(line) check: bool(a == a2) staticFor(curve, TestCurves): test_fp12_xy00z0(curve, gen = Uniform) test_fp12_xy00z0(curve, gen = HighHammingWeight) test_fp12_xy00z0(curve, gen = Long01Sequence) test "Sparse 𝔽p12 resulting from xyz000 line function": proc test_fp12_xyz000(C: static Curve, gen: static RandomGen) = for _ in 0 ..< Iters: var a = rng.random_elem(Fp12[C], gen) var a2 = a var x = rng.random_elem(Fp2[C], gen) var y = rng.random_elem(Fp2[C], gen) var z = rng.random_elem(Fp2[C], gen) let line = Line[Fp2[C], Mtwist](x: x, y: y, z: z) let b = Fp12[C]( c0: Fp6[C](c0: x, c1: y, c2: z) ) a *= b a2.mul_sparse_by_line_xyz000(line) check: bool(a == a2) staticFor(curve, TestCurves): test_fp12_xyz000(curve, gen = Uniform) test_fp12_xyz000(curve, gen = HighHammingWeight) test_fp12_xyz000(curve, gen = Long01Sequence)