constantine/tests/math/t_pairing_mul_fp12_by_lines...

596 lines
20 KiB
Nim
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# 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/platforms/abstractions,
../../constantine/math/arithmetic,
../../constantine/math/extension_fields,
../../constantine/math/config/curves,
../../constantine/math/io/io_extfields,
../../constantine/math/pairing/lines_eval,
# Test utilities
../../helpers/[prng_unsafe, static_for]
const
Iters = 8
TestCurves = [
BN254_Nogami,
BN254_Snarks,
BLS12_377,
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 𝔽p4 by Sparse 0y":
proc test_fp4_0y(C: static Curve, gen: static RandomGen) =
for _ in 0 ..< Iters:
let a = rng.random_elem(Fp4[C], gen)
let y = rng.random_elem(Fp2[C], gen)
let b = Fp4[C](coords: [Fp2[C](), y])
var r, r2: Fp4[C]
r.prod(a, b)
r2.mul_sparse_by_0y(a, y)
check: bool(r == r2)
staticFor(curve, TestCurves):
test_fp4_0y(curve, gen = Uniform)
test_fp4_0y(curve, gen = HighHammingWeight)
test_fp4_0y(curve, gen = Long01Sequence)
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](coords: [Fp2[C](), y, Fp2[C]()])
var r, r2: 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_xy0(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](coords: [x, y, Fp2[C]()])
var r, r2: Fp6[C]
r.prod(a, b)
r2.mul_sparse_by_xy0(a, x, y)
check: bool(r == r2)
staticFor(curve, TestCurves):
test_fp6_xy0(curve, gen = Uniform)
test_fp6_xy0(curve, gen = HighHammingWeight)
test_fp6_xy0(curve, gen = Long01Sequence)
test "Dense 𝔽p6 by Sparse 0yz":
proc test_fp6_0yz(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 z = rng.random_elem(Fp2[C], gen)
let b = Fp6[C](coords: [Fp2[C](), y, z])
var r, r2: Fp6[C]
r.prod(a, b)
r2.mul_sparse_by_0yz(a, y, z)
check: bool(r == r2)
staticFor(curve, TestCurves):
test_fp6_0yz(curve, gen = Uniform)
test_fp6_0yz(curve, gen = HighHammingWeight)
test_fp6_0yz(curve, gen = Long01Sequence)
when Fp12[BN254_Snarks]().c0.typeof is Fp6:
# =========== Towering 𝔽p12/𝔽p6 ======================================
test "Sparse 𝔽p12/𝔽p6 resulting from a00bc0 line function":
proc test_fp12_a00bc0(C: static Curve, gen: static RandomGen) =
when C.getSexticTwist() == D_Twist:
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]](a: x, b: y, c: z)
let b = Fp12[C]( coords: [
Fp6[C](coords: [ x, Fp2[C](), Fp2[C]()]),
Fp6[C](coords: [ y, z, Fp2[C]()])
])
a *= b
a2.mul_sparse_by_line_a00bc0(line)
check: bool(a == a2)
staticFor(curve, TestCurves):
test_fp12_a00bc0(curve, gen = Uniform)
test_fp12_a00bc0(curve, gen = HighHammingWeight)
test_fp12_a00bc0(curve, gen = Long01Sequence)
test "Sparse 𝔽p12/𝔽p6 resulting from cb00a0 line function":
proc test_fp12_cb00a0(C: static Curve, gen: static RandomGen) =
when C.getSexticTwist() == M_Twist:
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]](a: x, b: y, c: z)
let b = Fp12[C](coords: [
Fp6[C](coords: [ z, y, Fp2[C]()]),
Fp6[C](coords: [Fp2[C](), x, Fp2[C]()])
])
a *= b
a2.mul_sparse_by_line_cb00a0(line)
check: bool(a == a2)
staticFor(curve, TestCurves):
test_fp12_cb00a0(curve, gen = Uniform)
test_fp12_cb00a0(curve, gen = HighHammingWeight)
test_fp12_cb00a0(curve, gen = Long01Sequence)
test "Somewhat-sparse 𝔽p12/𝔽p6 resulting from a00bc0*a00bc0 line functions (D-twist only)":
proc test_fp12_a00bc0_a00bc0(C: static Curve, gen: static RandomGen) =
when C.getSexticTwist() == D_Twist:
for _ in 0 ..< Iters:
var x0 = rng.random_elem(Fp2[C], gen)
var y0 = rng.random_elem(Fp2[C], gen)
var z0 = rng.random_elem(Fp2[C], gen)
let line0 = Line[Fp2[C]](a: x0, b: y0, c: z0)
let f0 = Fp12[C]( coords: [
Fp6[C](coords: [ x0, Fp2[C](), Fp2[C]()]),
Fp6[C](coords: [ y0, z0, Fp2[C]()])
])
var x1 = rng.random_elem(Fp2[C], gen)
var y1 = rng.random_elem(Fp2[C], gen)
var z1 = rng.random_elem(Fp2[C], gen)
let line1 = Line[Fp2[C]](a: x1, b: y1, c: z1)
let f1 = Fp12[C]( coords: [
Fp6[C](coords: [ x1, Fp2[C](), Fp2[C]()]),
Fp6[C](coords: [ y1, z1, Fp2[C]()])
])
var r: Fp12[C]
r.prod(f0, f1)
var rl: Fp12[C]
rl.prod_x00yz0_x00yz0_into_abcdefghij00(line0, line1)
check: bool(r == rl)
staticFor(curve, TestCurves):
test_fp12_a00bc0_a00bc0(curve, gen = Uniform)
test_fp12_a00bc0_a00bc0(curve, gen = HighHammingWeight)
test_fp12_a00bc0_a00bc0(curve, gen = Long01Sequence)
test "Somewhat-sparse 𝔽p12/𝔽p6 resulting from cb00a0*cb00a0 line functions (M-twist only)":
proc test_fp12_cb00a0_cb00a0(C: static Curve, gen: static RandomGen) =
when C.getSexticTwist() == M_Twist:
for _ in 0 ..< Iters:
var x0 = rng.random_elem(Fp2[C], gen)
var y0 = rng.random_elem(Fp2[C], gen)
var z0 = rng.random_elem(Fp2[C], gen)
let line0 = Line[Fp2[C]](a: x0, b: y0, c: z0)
let f0 = Fp12[C](coords: [
Fp6[C](coords: [ z0, y0, Fp2[C]()]),
Fp6[C](coords: [Fp2[C](), x0, Fp2[C]()])
])
var x1 = rng.random_elem(Fp2[C], gen)
var y1 = rng.random_elem(Fp2[C], gen)
var z1 = rng.random_elem(Fp2[C], gen)
let line1 = Line[Fp2[C]](a: x1, b: y1, c: z1)
let f1 = Fp12[C](coords: [
Fp6[C](coords: [ z1, y1, Fp2[C]()]),
Fp6[C](coords: [Fp2[C](), x1, Fp2[C]()])
])
var r: Fp12[C]
r.prod(f0, f1)
var rl: Fp12[C]
rl.prod_zy00x0_zy00x0_into_abcdef00ghij(line0, line1)
check: bool(r == rl)
staticFor(curve, TestCurves):
test_fp12_cb00a0_cb00a0(curve, gen = Uniform)
test_fp12_cb00a0_cb00a0(curve, gen = HighHammingWeight)
test_fp12_cb00a0_cb00a0(curve, gen = Long01Sequence)
test "Somewhat-sparse 𝔽p12/𝔽p6 mul by the product a00bc0*a00bc0 of line functions (D-twist only)":
proc test_fp12_abcdefghij00(C: static Curve, gen: static RandomGen) =
when C.getSexticTwist() == D_Twist:
for _ in 0 ..< Iters:
var x0 = rng.random_elem(Fp2[C], gen)
var y0 = rng.random_elem(Fp2[C], gen)
var z0 = rng.random_elem(Fp2[C], gen)
let line0 = Line[Fp2[C]](a: x0, b: y0, c: z0)
let f0 = Fp12[C]( coords: [
Fp6[C](coords: [ x0, Fp2[C](), Fp2[C]()]),
Fp6[C](coords: [ y0, z0, Fp2[C]()])
])
var x1 = rng.random_elem(Fp2[C], gen)
var y1 = rng.random_elem(Fp2[C], gen)
var z1 = rng.random_elem(Fp2[C], gen)
let line1 = Line[Fp2[C]](a: x1, b: y1, c: z1)
let f1 = Fp12[C]( coords: [
Fp6[C](coords: [ x1, Fp2[C](), Fp2[C]()]),
Fp6[C](coords: [ y1, z1, Fp2[C]()])
])
var r: Fp12[C]
r.prod(f0, f1)
var rl: Fp12[C]
rl.prod_x00yz0_x00yz0_into_abcdefghij00(line0, line1)
var f = rng.random_elem(Fp12[C], gen)
var f2 = f
f *= rl
f2.mul_sparse_by_abcdefghij00_quad_over_cube(rl)
check: bool(f == f2)
staticFor(curve, TestCurves):
test_fp12_abcdefghij00(curve, gen = Uniform)
test_fp12_abcdefghij00(curve, gen = HighHammingWeight)
test_fp12_abcdefghij00(curve, gen = Long01Sequence)
test "Somewhat-sparse 𝔽p12/𝔽p6 mul by the product (cb00a0*cb00a0) of line functions (M-twist only)":
proc test_fp12_abcdef00ghij(C: static Curve, gen: static RandomGen) =
when C.getSexticTwist() == M_Twist:
for _ in 0 ..< Iters:
var x0 = rng.random_elem(Fp2[C], gen)
var y0 = rng.random_elem(Fp2[C], gen)
var z0 = rng.random_elem(Fp2[C], gen)
let line0 = Line[Fp2[C]](a: x0, b: y0, c: z0)
let f0 = Fp12[C](coords: [
Fp6[C](coords: [ z0, y0, Fp2[C]()]),
Fp6[C](coords: [Fp2[C](), x0, Fp2[C]()])
])
var x1 = rng.random_elem(Fp2[C], gen)
var y1 = rng.random_elem(Fp2[C], gen)
var z1 = rng.random_elem(Fp2[C], gen)
let line1 = Line[Fp2[C]](a: x1, b: y1, c: z1)
let f1 = Fp12[C](coords: [
Fp6[C](coords: [ z1, y1, Fp2[C]()]),
Fp6[C](coords: [Fp2[C](), x1, Fp2[C]()])
])
var r: Fp12[C]
r.prod(f0, f1)
var rl: Fp12[C]
rl.prod_zy00x0_zy00x0_into_abcdef00ghij(line0, line1)
var f = rng.random_elem(Fp12[C], gen)
var f2 = f
f *= rl
f2.mul_sparse_by_abcdef00ghij_quad_over_cube(rl)
check: bool(f == f2)
staticFor(curve, TestCurves):
test_fp12_abcdef00ghij(curve, gen = Uniform)
test_fp12_abcdef00ghij(curve, gen = HighHammingWeight)
test_fp12_abcdef00ghij(curve, gen = Long01Sequence)
else: # =========== Towering 𝔽p12/𝔽p4 ======================================
static: doAssert Fp12[BN254_Snarks]().c0.typeof is Fp4
test "Sparse 𝔽p12/𝔽p4 resulting from ca00b0 line function (M-twist only)":
proc test_fp12_ca00b0(C: static Curve, gen: static RandomGen) =
when C.getSexticTwist() == M_Twist:
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]](a: x, b: y, c: z)
let b = Fp12[C](
coords: [
Fp4[C](coords: [z, x]),
Fp4[C](),
Fp4[C](coords: [y, Fp2[C]()])
]
)
a *= b
a2.mul_sparse_by_line_ca00b0(line)
check: bool(a == a2)
staticFor(curve, TestCurves):
test_fp12_ca00b0(curve, gen = Uniform)
test_fp12_ca00b0(curve, gen = HighHammingWeight)
test_fp12_ca00b0(curve, gen = Long01Sequence)
test "Sparse 𝔽p12/𝔽p4 resulting from xyz000 line function (D-twist only)":
proc test_fp12_acb000(C: static Curve, gen: static RandomGen) =
when C.getSexticTwist() == D_Twist:
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]](a: x, b: y, c: z)
let b = Fp12[C](
coords: [
Fp4[C](coords: [x, z]),
Fp4[C](coords: [y, Fp2[C]()]),
Fp4[C]()
]
)
a *= b
a2.mul_sparse_by_line_acb000(line)
check: bool(a == a2)
staticFor(curve, TestCurves):
test_fp12_acb000(curve, gen = Uniform)
test_fp12_acb000(curve, gen = HighHammingWeight)
test_fp12_acb000(curve, gen = Long01Sequence)
test "Somewhat-sparse 𝔽p12/𝔽p4 resulting from ca00b0*ca00b0 line functions (M-twist only)":
proc test_fp12_ca00b0_ca00b0(C: static Curve, gen: static RandomGen) =
when C.getSexticTwist() == M_Twist:
for _ in 0 ..< Iters:
var x0 = rng.random_elem(Fp2[C], gen)
var y0 = rng.random_elem(Fp2[C], gen)
var z0 = rng.random_elem(Fp2[C], gen)
let line0 = Line[Fp2[C]](a: x0, b: y0, c: z0)
let f0 = Fp12[C](
coords: [
Fp4[C](coords: [z0, x0]),
Fp4[C](),
Fp4[C](coords: [y0, Fp2[C]()])
]
)
var x1 = rng.random_elem(Fp2[C], gen)
var y1 = rng.random_elem(Fp2[C], gen)
var z1 = rng.random_elem(Fp2[C], gen)
let line1 = Line[Fp2[C]](a: x1, b: y1, c: z1)
let f1 = Fp12[C](
coords: [
Fp4[C](coords: [z1, x1]),
Fp4[C](),
Fp4[C](coords: [y1, Fp2[C]()])
]
)
var r: Fp12[C]
r.prod(f0, f1)
var rl: Fp12[C]
rl.prod_zx00y0_zx00y0_into_abcd00efghij(line0, line1)
check: bool(r == rl)
staticFor(curve, TestCurves):
test_fp12_ca00b0_ca00b0(curve, gen = Uniform)
test_fp12_ca00b0_ca00b0(curve, gen = HighHammingWeight)
test_fp12_ca00b0_ca00b0(curve, gen = Long01Sequence)
test "Somewhat-sparse 𝔽p12/𝔽p4 resulting from acb000*acb000 line functions (D-twist only)":
proc test_fp12_acb000_acb000(C: static Curve, gen: static RandomGen) =
when C.getSexticTwist() == D_Twist:
for _ in 0 ..< Iters:
var x0 = rng.random_elem(Fp2[C], gen)
var y0 = rng.random_elem(Fp2[C], gen)
var z0 = rng.random_elem(Fp2[C], gen)
let line0 = Line[Fp2[C]](a: x0, b: y0, c: z0)
let f0 = Fp12[C](
coords: [
Fp4[C](coords: [x0, z0]),
Fp4[C](coords: [y0, Fp2[C]()]),
Fp4[C]()
]
)
var x1 = rng.random_elem(Fp2[C], gen)
var y1 = rng.random_elem(Fp2[C], gen)
var z1 = rng.random_elem(Fp2[C], gen)
let line1 = Line[Fp2[C]](a: x1, b: y1, c: z1)
let f1 = Fp12[C](
coords: [
Fp4[C](coords: [x1, z1]),
Fp4[C](coords: [y1, Fp2[C]()]),
Fp4[C]()
]
)
var r: Fp12[C]
r.prod(f0, f1)
var rl: Fp12[C]
rl.prod_xzy000_xzy000_into_abcdefghij00(line0, line1)
check: bool(r == rl)
staticFor(curve, TestCurves):
test_fp12_acb000_acb000(curve, gen = Uniform)
test_fp12_acb000_acb000(curve, gen = HighHammingWeight)
test_fp12_acb000_acb000(curve, gen = Long01Sequence)
test "Somewhat-sparse 𝔽p12/𝔽p4 mul by the product (acb000*acb000) of line functions (D-twist only)":
proc test_fp12_abcdefghij00(C: static Curve, gen: static RandomGen) =
when C.getSexticTwist() == D_Twist:
for _ in 0 ..< Iters:
var x0 = rng.random_elem(Fp2[C], gen)
var y0 = rng.random_elem(Fp2[C], gen)
var z0 = rng.random_elem(Fp2[C], gen)
let line0 = Line[Fp2[C]](a: x0, b: y0, c: z0)
let f0 = Fp12[C](
coords: [
Fp4[C](coords: [x0, z0]),
Fp4[C](coords: [y0, Fp2[C]()]),
Fp4[C]()
]
)
var x1 = rng.random_elem(Fp2[C], gen)
var y1 = rng.random_elem(Fp2[C], gen)
var z1 = rng.random_elem(Fp2[C], gen)
let line1 = Line[Fp2[C]](a: x1, b: y1, c: z1)
let f1 = Fp12[C](
coords: [
Fp4[C](coords: [x1, z1]),
Fp4[C](coords: [y1, Fp2[C]()]),
Fp4[C]()
]
)
var r: Fp12[C]
r.prod(f0, f1)
var rl: Fp12[C]
rl.prod_xzy000_xzy000_into_abcdefghij00(line0, line1)
var f = rng.random_elem(Fp12[C], gen)
var f2 = f
f *= rl
f2.mul_sparse_by_abcdefghij00_cube_over_quad(rl)
check: bool(f == f2)
staticFor(curve, TestCurves):
test_fp12_abcdefghij00(curve, gen = Uniform)
test_fp12_abcdefghij00(curve, gen = HighHammingWeight)
test_fp12_abcdefghij00(curve, gen = Long01Sequence)
test "Somewhat-sparse 𝔽p12/𝔽p4 mul by the product (ca00b0*ca00b0) of line functions (M-twist only)":
proc test_fp12_abcdef00ghij(C: static Curve, gen: static RandomGen) =
when C.getSexticTwist() == M_Twist:
for _ in 0 ..< Iters:
var x0 = rng.random_elem(Fp2[C], gen)
var y0 = rng.random_elem(Fp2[C], gen)
var z0 = rng.random_elem(Fp2[C], gen)
let line0 = Line[Fp2[C]](a: x0, b: y0, c: z0)
let f0 = Fp12[C](
coords: [
Fp4[C](coords: [z0, x0]),
Fp4[C](),
Fp4[C](coords: [y0, Fp2[C]()])
]
)
var x1 = rng.random_elem(Fp2[C], gen)
var y1 = rng.random_elem(Fp2[C], gen)
var z1 = rng.random_elem(Fp2[C], gen)
let line1 = Line[Fp2[C]](a: x1, b: y1, c: z1)
let f1 = Fp12[C](
coords: [
Fp4[C](coords: [z1, x1]),
Fp4[C](),
Fp4[C](coords: [y1, Fp2[C]()])
]
)
var r: Fp12[C]
r.prod(f0, f1)
var rl: Fp12[C]
rl.prod_zx00y0_zx00y0_into_abcd00efghij(line0, line1)
var f = rng.random_elem(Fp12[C], gen)
var f2 = f
f *= rl
f2.mul_sparse_by_abcd00efghij_cube_over_quad(rl)
check: bool(f == f2)
staticFor(curve, TestCurves):
test_fp12_abcdef00ghij(curve, gen = Uniform)
test_fp12_abcdef00ghij(curve, gen = HighHammingWeight)
test_fp12_abcdef00ghij(curve, gen = Long01Sequence)