mirror of
https://github.com/status-im/constantine.git
synced 2025-02-22 08:58:05 +00:00
Test GT-subgroup for BW6-761 (#171)
This commit is contained in:
parent
f6c02fe075
commit
50717d8de6
@ -155,6 +155,7 @@ const testDesc: seq[tuple[path: string, useGMP: bool]] = @[
|
||||
("tests/t_pairing_bn254_snarks_gt_subgroup.nim", false),
|
||||
("tests/t_pairing_bls12_377_gt_subgroup.nim", false),
|
||||
("tests/t_pairing_bls12_381_gt_subgroup.nim", false),
|
||||
("tests/t_pairing_bw6_761_gt_subgroup.nim", false),
|
||||
|
||||
# Pairing
|
||||
# ----------------------------------------------------------
|
||||
|
@ -60,7 +60,7 @@ func millerLoopAddchain*(
|
||||
|
||||
func pow_x*(r: var Fp12[BLS12_377], a: Fp12[BLS12_377], invert = BLS12_377_pairing_ate_param_isNeg) =
|
||||
## f^x with x the curve parameter
|
||||
## For BLS12_377 f^-0x8508c00000000001
|
||||
## For BLS12_377 f^0x8508c00000000001
|
||||
r.cyclotomic_square(a)
|
||||
r *= a
|
||||
r.cyclotomic_square()
|
||||
@ -92,7 +92,7 @@ func isInPairingSubgroup*(a: Fp12[BLS12_377]): SecretBool =
|
||||
# Implementation: Scott, https://eprint.iacr.org/2021/1130.pdf
|
||||
# A note on group membership tests for G1, G2 and GT
|
||||
# on BLS pairing-friendly curves
|
||||
# P is in the G1 subgroup iff a^p == a^u
|
||||
# a is in the GT subgroup iff a^p == a^u
|
||||
var t0{.noInit.}, t1{.noInit.}: Fp12[BLS12_377]
|
||||
t0.frobenius_map(a)
|
||||
t1.pow_x(a)
|
||||
|
@ -181,14 +181,14 @@ func isInSubgroup*(P: ECP_ShortW_Prj[Fp[BLS12_377], G1]): SecretBool =
|
||||
# Implementation: Scott, https://eprint.iacr.org/2021/1130.pdf
|
||||
# A note on group membership tests for G1, G2 and GT
|
||||
# on BLS pairing-friendly curves
|
||||
# P is in the G1 subgroup iff phi(P) == [-u²](P)
|
||||
# P is in the G1 subgroup iff ϕ(P) == [-u²](P)
|
||||
var t0{.noInit.}, t1{.noInit.}: ECP_ShortW_Prj[Fp[BLS12_377], G1]
|
||||
|
||||
# [-u²]P
|
||||
t0.pow_bls12_377_x(P)
|
||||
t1.pow_bls12_377_minus_x(t0)
|
||||
|
||||
# phi(P)
|
||||
# ϕ(P)
|
||||
t0.x.prod(P.x, BLS12_377.getCubicRootOfUnity_mod_p())
|
||||
t0.y = P.y
|
||||
t0.z = P.z
|
||||
|
@ -175,14 +175,14 @@ func isInSubgroup*(P: ECP_ShortW_Prj[Fp[BLS12_381], G1]): SecretBool =
|
||||
# Implementation: Scott, https://eprint.iacr.org/2021/1130.pdf
|
||||
# A note on group membership tests for G1, G2 and GT
|
||||
# on BLS pairing-friendly curves
|
||||
# P is in the G1 subgroup iff phi(P) == [-u²](P)
|
||||
# P is in the G1 subgroup iff ϕ(P) == [-u²](P)
|
||||
var t0{.noInit.}, t1{.noInit.}: ECP_ShortW_Prj[Fp[BLS12_381], G1]
|
||||
|
||||
# [-u²]P
|
||||
t0.pow_bls12_381_x(P)
|
||||
t1.pow_bls12_381_minus_x(t0)
|
||||
|
||||
# phi(P)
|
||||
# ϕ(P)
|
||||
t0.x.prod(P.x, BLS12_381.getCubicRootOfUnity_mod_p())
|
||||
t0.y = P.y
|
||||
t0.z = P.z
|
||||
|
@ -7,8 +7,11 @@
|
||||
# at your option. This file may not be copied, modified, or distributed except according to those terms.
|
||||
|
||||
import
|
||||
../config/[curves, type_bigint],
|
||||
../io/io_bigints
|
||||
../config/[common, curves, type_bigint],
|
||||
../io/io_bigints,
|
||||
../towers,
|
||||
../pairing/cyclotomic_fp6,
|
||||
../isogeny/frobenius
|
||||
|
||||
# Slow generic implementation
|
||||
# ------------------------------------------------------------
|
||||
@ -53,5 +56,107 @@ const BW6_761_pairing_finalexponent* = block:
|
||||
# (p^6 - 1) / r * 3*(u^3-u^2+1)
|
||||
BigInt[4376].fromHex"0x8a168e18d34ff984b8399b649a12265bcdd3023623c45b9a1d38314c4fdd4547f8a0c18b88468482c0ff74c94606e4e5734c43d4e9fa977c1196361496699ea26e4d912e4918fff3cbe177b5d47cd9ba63103cb2a7a1699ef2a48dd77d1f939ca33d35dadabf0aab681703a3340126ab78a2a76c2147cc4f5897f610596fed83ccdcab13b919d48f9365b50ad005a6fbcf41412c73ad8d03f465568acbb86d9b97d5216af6a67fe6d16f12c069cdc44035adc99b54e9e68095349af476057b5bc94bca6e4e23b8de4afd24d6fc655448269a02123b8c4d25115d8d09fc4b2774042d2c744568b132b11cb1fae68e025a6d8c7e405ce52092154a56523f2abeb3ec693419f8402799b08ae023360be4468046e81033e3e1d172d19d5ce5e3441140c26e710015f97bdbbddce57396c565d1a9d4f81d571415dacf2686171f2679797d97a35c59c372cca29eeb8556e2576912edb846235fb723a75a0cc5acc8ace1e5628f8e14c931f0a0d58372a44d0eba074e4fefff61efaf4bde1adf999e6194cf12c73cba39732fe059618901d4c0924b8a5d15ad9bea271be5f6679b6f0148f15d36a9269c4b6a07d08b2aa9b9365ab295a8c6a7eb4088e86fb5e30843798bf1bf426f07c2c39f4b8beef71b3da9c1d656ba3c23bbc8d3b54399d0e6fd1ec64616566ee1471934d0763fe360fb9a02bc3a5d4ccdf6fcaf52be7b67955a89b522a5e0a45e935f1794a038aeca4b9a6d8ae28da00178304c7dfc3d0e13ade8564b78"
|
||||
|
||||
const BW6_761_pairing_finalexponent_hard* = block:
|
||||
# (p^2 - p + 1) / r * 3*(u^3-u^2+1)
|
||||
BigInt[1335].fromHex"0x52d03a3bd1dd9aa185df830823e31f28dd2231c308bd86210eefcc7623b1c28d6b1e42eabf464f9161e52f11542cbacc962137fe3971d52652188b8ef74af13b0a049a4806e46f50f0c6eda7965e4275a966ebba028d346efe221daebfbbd9ca698a0ed763e9b1b0945bd554b2b8511e18bd7338b3355d3b2419c6fa6d71346b955d466ea17d418f7e444b5c67cd440c20be53ff99df9b79934de2c001a91809a300000000e0cd"
|
||||
|
||||
|
||||
# Addition chain
|
||||
# ------------------------------------------------------------
|
||||
# ------------------------------------------------------------
|
||||
|
||||
func pow_u*(r: var Fp6[BW6_761], a: Fp6[BW6_761], invert = false) =
|
||||
## f^u with u the curve parameter
|
||||
## For BLS12_377/BW6_761 f^0x8508c00000000001
|
||||
r.cyclotomic_square(a)
|
||||
r *= a
|
||||
r.cyclotomic_square()
|
||||
r *= a
|
||||
let t111 = r
|
||||
|
||||
r.cycl_sqr_repeated(2)
|
||||
let t111000 = r
|
||||
|
||||
r *= t111
|
||||
let t100011 = r
|
||||
|
||||
r.cyclotomic_square()
|
||||
r *= t100011
|
||||
r *= t111000
|
||||
|
||||
r.cycl_sqr_repeated(10)
|
||||
r *= t100011
|
||||
|
||||
r.cycl_sqr_repeated(46) # TODO: Karabina's compressed squarings
|
||||
r *= a
|
||||
|
||||
if invert:
|
||||
r.cyclotomic_inv()
|
||||
|
||||
func isInPairingSubgroup*(a: Fp6[BW6_761]): SecretBool =
|
||||
## Returns true if a is in GT subgroup, i.e. a is an element of order r
|
||||
## Warning ⚠: Assumes that a is in the cyclotomic subgroup
|
||||
# Implementation: Scott, https://eprint.iacr.org/2021/1130.pdf
|
||||
# A note on group membership tests for G1, G2 and GT
|
||||
# on BLS pairing-friendly curves
|
||||
# a is in the GT subgroup iff a^(p) == a^(t-1)
|
||||
# with t the trace of the curve
|
||||
|
||||
var u0{.noInit.}, u1{.noInit.}, u3{.noInit.}: Fp6[BW6_761]
|
||||
var u4{.noInit.}, u5{.noInit.}, u6{.noInit.}: Fp6[BW6_761]
|
||||
|
||||
# t-1 = (13u⁶ - 23u⁵ - 9u⁴ + 35u³ + 10u + 19)/3
|
||||
u0.cyclotomic_square(a) # u0 = 2
|
||||
u0.cycl_sqr_repeated(2) # u0 = 8
|
||||
u0 *= a # u0 = 9
|
||||
u0.cyclotomic_square() # u0 = 18
|
||||
u0 *= a # u0 = 19
|
||||
|
||||
u1.pow_u(a) # u1 = u
|
||||
u4.pow_u(u1) # u4 = u²
|
||||
|
||||
u3.cyclotomic_square(u1) # u3 = 2u
|
||||
u3.cyclotomic_square() # u3 = 4u
|
||||
u1 *= u3 # u1 = 5u
|
||||
u1.cyclotomic_square() # u1 = 10u
|
||||
|
||||
u0 *= u1 # u0 = 10u + 19
|
||||
|
||||
u1.pow_u(u4) # u1 = u³
|
||||
u3.cyclotomic_square(u1) # u3 = 2u³
|
||||
u3.cycl_sqr_repeated(3) # u3 = 16u³
|
||||
u3 *= u1 # u3 = 17u³
|
||||
u3.cyclotomic_square() # u3 = 34u³
|
||||
u3 *= u1 # u3 = 35u³
|
||||
|
||||
u0 *= u3 # u0 = 35u³ + 10u + 19
|
||||
u4.pow_u(u1) # u4 = u⁴
|
||||
u5.pow_u(u4) # u5 = u⁵
|
||||
u6.pow_u(u5) # u6 = u⁶
|
||||
|
||||
u1.cyclotomic_square(u4) # u1 = 2u⁴
|
||||
u1.cycl_sqr_repeated(2) # u1 = 8u⁴
|
||||
u4 *= u1 # u4 = 9u⁴
|
||||
u4.cyclotomic_inv() # u4 = -9u⁴
|
||||
|
||||
u0 *= u4 # u0 = -9u⁴ + 35u³ + 10u + 19
|
||||
|
||||
u1.cyclotomic_inv(u5) # u1 = -u⁵
|
||||
u1.cycl_sqr_repeated(3) # u1 = -8u⁵
|
||||
u5 *= u1 # u5 = -7u⁵
|
||||
u1.cyclotomic_square() # u1 = -16u⁵
|
||||
u5 *= u1 # u5 = -23u⁵
|
||||
|
||||
u0 *= u5 # u0 = -23u⁵ - 9u⁴ + 35u³ + 10u + 19
|
||||
|
||||
u1.cyclotomic_square(u6) # u1 = 2u⁶
|
||||
u1 *= u6 # u1 = 3u⁶
|
||||
u1.cycl_sqr_repeated(2) # u1 = 12u⁶
|
||||
u6 *= u1 # u6 = 13u⁶
|
||||
|
||||
u0 *= u6 # u0 = 3(t-1) = 13u⁶ - 23u⁵ - 9u⁴ + 35u³ + 10u + 19
|
||||
|
||||
u1.frobenius_map(a) # u1 = p
|
||||
u3.cyclotomic_square(u1) # u3 = 2p
|
||||
u3 *= u1 # u3 = 3p
|
||||
|
||||
return u0 == u3
|
@ -37,4 +37,4 @@ func clearCofactorReference*(P: var ECP_ShortW_Prj[Fp[BW6_761], G1]) {.inline.}
|
||||
func clearCofactorReference*(P: var ECP_ShortW_Prj[Fp[BW6_761], G2]) {.inline.} =
|
||||
## Clear the cofactor of BW6_761 G2
|
||||
# Endomorphism acceleration cannot be used if cofactor is not cleared
|
||||
P.scalarMulGeneric(Cofactor_Eff_BW6_761_G2)
|
||||
P.scalarMulGeneric(Cofactor_Eff_BW6_761_G2)
|
||||
|
233
constantine/pairing/cyclotomic_fp6.nim
Normal file
233
constantine/pairing/cyclotomic_fp6.nim
Normal file
@ -0,0 +1,233 @@
|
||||
# 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
|
||||
../primitives,
|
||||
../config/[common, curves],
|
||||
../arithmetic,
|
||||
../towers,
|
||||
../isogeny/frobenius
|
||||
|
||||
# No exceptions allowed
|
||||
{.push raises: [].}
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# Gϕ₆, Cyclotomic subgroup of Fp6
|
||||
# with GΦₙ(p) = {α ∈ Fpⁿ : α^Φₙ(p) ≡ 1 (mod pⁿ)}
|
||||
#
|
||||
# ############################################################
|
||||
|
||||
# - Faster Squaring in the Cyclotomic Subgroup of Sixth Degree Extensions
|
||||
# Granger, Scott, 2009
|
||||
# https://eprint.iacr.org/2009/565.pdf
|
||||
#
|
||||
# - On the final exponentiation for calculating
|
||||
# pairings on ordinary elliptic curves
|
||||
# Scott, Benger, Charlemagne, Perez, Kachisa, 2008
|
||||
# https://eprint.iacr.org/2008/490.pdf
|
||||
|
||||
# 𝔽p6 -> Gϕ₆ - Mapping to Cyclotomic group
|
||||
# ----------------------------------------------------------------
|
||||
func finalExpEasy*[C: static Curve](f: var Fp6[C]) {.meter.} =
|
||||
## Easy part of the final exponentiation
|
||||
##
|
||||
## This maps the result of the Miller loop into the cyclotomic subgroup Gϕ₆
|
||||
##
|
||||
## We need to clear the Gₜ cofactor to obtain
|
||||
## an unique Gₜ representation
|
||||
## (reminder, Gₜ is a multiplicative group hence we exponentiate by the cofactor)
|
||||
##
|
||||
## i.e. Fp⁶ --> (fexp easy) --> Gϕ₆ --> (fexp hard) --> Gₜ
|
||||
##
|
||||
## The final exponentiation is fexp = f^((p⁶ - 1) / r)
|
||||
## It is separated into:
|
||||
## f^((p⁶ - 1) / r) = (p⁶ - 1) / ϕ₆(p) * ϕ₆(p) / r
|
||||
##
|
||||
## with the cyclotomic polynomial ϕ₆(p) = (p²-p+1)
|
||||
##
|
||||
## With an embedding degree of 6, the easy part of final exponentiation is
|
||||
##
|
||||
## f^(p³−1)(p+1)
|
||||
##
|
||||
## And properties are
|
||||
## 0. f^(p³) ≡ conj(f) (mod p⁶) for all f in Fp6
|
||||
##
|
||||
## After g = f^(p³−1) the result g is on the cyclotomic subgroup
|
||||
## 1. g^(-1) ≡ g^(p³) (mod p⁶)
|
||||
## 2. Inversion can be done with conjugate
|
||||
## 3. g is unitary, its norm |g| (the product of conjugates) is 1
|
||||
## 4. Squaring has a fast compressed variant.
|
||||
#
|
||||
# Proofs:
|
||||
#
|
||||
# Fp6 can be defined as a quadratic extension over Fp³
|
||||
# with g = g₀ + x g₁ with x a quadratic non-residue
|
||||
#
|
||||
# with q = p³, q² = p⁶
|
||||
# The frobenius map f^q ≡ (f₀ + x f₁)^q (mod q²)
|
||||
# ≡ f₀^q + x^q f₁^q (mod q²)
|
||||
# ≡ f₀ + x^q f₁ (mod q²)
|
||||
# ≡ f₀ - x f₁ (mod q²)
|
||||
# hence
|
||||
# f^p³ ≡ conj(f) (mod p⁶)
|
||||
# Q.E.D. of (0)
|
||||
#
|
||||
# ----------------
|
||||
#
|
||||
# p⁶ - 1 = (p³−1)(p³+1) = (p³−1)(p+1)(p²-p+1)
|
||||
# by Fermat's little theorem we have
|
||||
# f^(p⁶ - 1) ≡ 1 (mod p⁶)
|
||||
#
|
||||
# Hence f^(p³−1)(p³+1) ≡ 1 (mod p⁶)
|
||||
#
|
||||
# We call g = f^(p³−1) we have
|
||||
# g^(p³+1) ≡ 1 (mod p⁶) <=> g^(p³) * g ≡ 1 (mod p⁶)
|
||||
# hence g^(-1) ≡ g^(p³) (mod p⁶)
|
||||
# Q.E.D. of (1)
|
||||
#
|
||||
# --
|
||||
#
|
||||
# From (1) g^(-1) ≡ g^(p³) (mod p⁶) for g = f^(p³−1)
|
||||
# and (0) f^p³ ≡ conj(f) (mod p⁶) for all f in fp12
|
||||
#
|
||||
# so g^(-1) ≡ conj(g) (mod p⁶) for g = f^(p³−1)
|
||||
# Q.E.D. of (2)
|
||||
#
|
||||
# --
|
||||
#
|
||||
# f^(p⁶ - 1) ≡ 1 (mod p⁶) by Fermat's Little Theorem
|
||||
# f^(p³−1)(p³+1) ≡ 1 (mod p⁶)
|
||||
# g^(p³+1) ≡ 1 (mod p⁶)
|
||||
# g * g^p³ ≡ 1 (mod p⁶)
|
||||
# g * conj(g) ≡ 1 (mod p⁶)
|
||||
# Q.E.D. of (3)
|
||||
var g {.noinit.}: typeof(f)
|
||||
g.inv(f) # g = f^-1
|
||||
conj(f) # f = f^p³
|
||||
g *= f # g = f^(p³-1)
|
||||
f.frobenius_map(g) # f = f^((p³-1) p)
|
||||
f *= g # f = f^((p³-1) (p+1))
|
||||
|
||||
# Gϕ₆ - Cyclotomic functions
|
||||
# ----------------------------------------------------------------
|
||||
# A cyclotomic group is a subgroup of Fp^n defined by
|
||||
#
|
||||
# GΦₙ(p) = {α ∈ Fpⁿ : α^Φₙ(p) = 1}
|
||||
#
|
||||
# The result of any pairing is in a cyclotomic subgroup
|
||||
|
||||
func cyclotomic_inv*(a: var Fp6) {.meter.} =
|
||||
## Fast inverse for a
|
||||
## `a` MUST be in the cyclotomic subgroup
|
||||
## consequently `a` MUST be unitary
|
||||
a.conj()
|
||||
|
||||
func cyclotomic_inv*(r: var Fp6, a: Fp6) {.meter.} =
|
||||
## Fast inverse for a
|
||||
## `a` MUST be in the cyclotomic subgroup
|
||||
## consequently `a` MUST be unitary
|
||||
r.conj(a)
|
||||
|
||||
func cyclotomic_square*[C](r: var Fp6[C], a: Fp6[C]) {.meter.} =
|
||||
## Square `a` into `r`
|
||||
## `a` MUST be in the cyclotomic subgroup
|
||||
## consequently `a` MUST be unitary
|
||||
#
|
||||
# Faster Squaring in the Cyclotomic Subgroup of Sixth Degree Extensions
|
||||
# Granger, Scott, 2009
|
||||
# https://eprint.iacr.org/2009/565.pdf
|
||||
|
||||
when a.c0 is Fp2:
|
||||
# Cubic over quadratic
|
||||
# A = 3a² − 2 ̄a
|
||||
# B = 3 √i c² + 2 ̄b
|
||||
# C = 3b² − 2 ̄c
|
||||
var t0{.noinit.}, t1{.noinit.}: Fp2[C]
|
||||
|
||||
t0.square(a.c0) # t0 = a²
|
||||
t1.double(t0) # t1 = 2a²
|
||||
t1 += t0 # t1 = 3a²
|
||||
|
||||
t0.conj(a.c0) # t0 = ̄a
|
||||
t0.double() # t0 = 2 ̄a
|
||||
r.c0.diff(t1, t0) # r0 = 3a² − 2 ̄a
|
||||
|
||||
# Aliasing: a.c0 unused
|
||||
|
||||
t0.square(a.c2) # t0 = c²
|
||||
t0 *= NonResidue # t0 = √i c²
|
||||
t1.double(t0) # t1 = 2 √i c²
|
||||
t0 += t1 # t0 = 3 √i c²
|
||||
|
||||
t1.square(a.c1) # t1 = b²
|
||||
|
||||
r.c1.conj(a.c1) # r1 = ̄b
|
||||
r.c1.double() # r1 = 2 ̄b
|
||||
r.c1 += t0 # r1 = 3 √i c² + 2 ̄b
|
||||
|
||||
# Aliasing: a.c1 unused
|
||||
|
||||
t0.double(t1) # t0 = 2b²
|
||||
t0 += t1 # t0 = 3b²
|
||||
|
||||
t1.conj(a.c2) # r2 = ̄c
|
||||
t1.double() # r2 = 2 ̄c
|
||||
r.c2.diff(t0, t1) # r2 = 3b² - 2 ̄c
|
||||
|
||||
else:
|
||||
{.error: "Not implemented".}
|
||||
|
||||
func cyclotomic_square*[C](a: var Fp6[C]) {.meter.} =
|
||||
## Square `a` into `r`
|
||||
## `a` MUST be in the cyclotomic subgroup
|
||||
## consequently `a` MUST be unitary
|
||||
#
|
||||
# Faster Squaring in the Cyclotomic Subgroup of Sixth Degree Extensions
|
||||
# Granger, Scott, 2009
|
||||
# https://eprint.iacr.org/2009/565.pdf
|
||||
a.cyclotomic_square(a)
|
||||
|
||||
func cycl_sqr_repeated*(f: var Fp6, num: int) {.inline, meter.} =
|
||||
## Repeated cyclotomic squarings
|
||||
for _ in 0 ..< num:
|
||||
f.cyclotomic_square()
|
||||
|
||||
iterator unpack(scalarByte: byte): bool =
|
||||
yield bool((scalarByte and 0b10000000) shr 7)
|
||||
yield bool((scalarByte and 0b01000000) shr 6)
|
||||
yield bool((scalarByte and 0b00100000) shr 5)
|
||||
yield bool((scalarByte and 0b00010000) shr 4)
|
||||
yield bool((scalarByte and 0b00001000) shr 3)
|
||||
yield bool((scalarByte and 0b00000100) shr 2)
|
||||
yield bool((scalarByte and 0b00000010) shr 1)
|
||||
yield bool( scalarByte and 0b00000001)
|
||||
|
||||
func cyclotomic_exp*[C](r: var Fp6[C], a: Fp6[C], exponent: BigInt, invert: bool) {.meter.} =
|
||||
var eBytes: array[(exponent.bits+7) div 8, byte]
|
||||
eBytes.exportRawUint(exponent, bigEndian)
|
||||
|
||||
r.setOne()
|
||||
for b in eBytes:
|
||||
for bit in unpack(b):
|
||||
r.cyclotomic_square()
|
||||
if bit:
|
||||
r *= a
|
||||
if invert:
|
||||
r.cyclotomic_inv()
|
||||
|
||||
func isInCyclotomicSubgroup*[C](a: Fp6[C]): SecretBool =
|
||||
## Check if a ∈ Fpⁿ: a^Φₙ(p) = 1
|
||||
## Φ₆(p) = p⁴-p²+1
|
||||
var t{.noInit.}, p{.noInit.}: Fp6[C]
|
||||
|
||||
t.frobenius_map(a, 2) # a^(p²)
|
||||
t *= a # a^(p²+1)
|
||||
p.frobenius_map(a) # a^(p)
|
||||
|
||||
return t == p
|
@ -20,6 +20,8 @@ import
|
||||
./mul_fp6_by_lines,
|
||||
./miller_loops
|
||||
|
||||
export zoo_pairings # generic sandwich https://github.com/nim-lang/Nim/issues/11225
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
# Optimal ATE pairing for
|
||||
@ -29,7 +31,6 @@ import
|
||||
|
||||
# Generic pairing implementation
|
||||
# ----------------------------------------------------------------
|
||||
# TODO: debug this
|
||||
|
||||
func millerLoopBW6_761_naive[C](
|
||||
f: var Fp6[C],
|
||||
@ -59,7 +60,7 @@ func millerLoopBW6_761_naive[C](
|
||||
basicMillerLoop(
|
||||
f2, T, line,
|
||||
P, Q, nQ,
|
||||
ate_param_1_unopt, ate_param_1_unopt_isNeg
|
||||
ate_param_2_unopt, ate_param_2_unopt_isNeg
|
||||
)
|
||||
|
||||
let t = f2
|
||||
@ -71,6 +72,11 @@ func finalExpGeneric[C: static Curve](f: var Fp6[C]) =
|
||||
## for sanity checks purposes.
|
||||
f.powUnsafeExponent(C.pairing(finalexponent), window = 3)
|
||||
|
||||
func finalExpHard_BW6_761*[C: static Curve](f: var Fp6[C]) =
|
||||
## A generic and slow implementation of final exponentiation
|
||||
## for sanity checks purposes.
|
||||
f.powUnsafeExponent(C.pairing(finalexponent_hard), window = 3)
|
||||
|
||||
# Optimized pairing implementation
|
||||
# ----------------------------------------------------------------
|
||||
|
||||
@ -150,16 +156,14 @@ func millerLoopBW6_761_opt_to_debug[C](
|
||||
|
||||
func pairing_bw6_761_reference*[C](
|
||||
gt: var Fp6[C],
|
||||
P: ECP_ShortW_Prj[Fp[C], G1],
|
||||
Q: ECP_ShortW_Prj[Fp[C], G2]) =
|
||||
P: ECP_ShortW_Aff[Fp[C], G1],
|
||||
Q: ECP_ShortW_Aff[Fp[C], G2]) =
|
||||
## Compute the optimal Ate Pairing for BW6 curves
|
||||
## Input: P ∈ G1, Q ∈ G2
|
||||
## Output: e(P, Q) ∈ Gt
|
||||
##
|
||||
## Reference implementation
|
||||
var Paff {.noInit.}: ECP_ShortW_Aff[Fp[C], G1]
|
||||
var Qaff {.noInit.}: ECP_ShortW_Aff[Fp[C], G2]
|
||||
Paff.affineFromProjective(P)
|
||||
Qaff.affineFromProjective(Q)
|
||||
gt.millerLoopBW6_761_naive(Paff, Qaff)
|
||||
gt.finalExpGeneric()
|
||||
{.error: "BW6_761 Miller loop is not working yet".}
|
||||
gt.millerLoopBW6_761_naive(P, Q)
|
||||
gt.finalExpEasy()
|
||||
gt.finalExpHard_BW6_761()
|
19
tests/t_pairing_bw6_761_gt_subgroup.nim
Normal file
19
tests/t_pairing_bw6_761_gt_subgroup.nim
Normal file
@ -0,0 +1,19 @@
|
||||
# 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
|
||||
../constantine/config/common,
|
||||
../constantine/config/curves,
|
||||
../constantine/pairing/pairing_bw6_761,
|
||||
# Test utilities
|
||||
./t_pairing_template
|
||||
|
||||
runGTsubgroupTests(
|
||||
Iters = 4,
|
||||
GT = Fp6[BW6_761],
|
||||
finalExpHard_BW6_761)
|
@ -16,7 +16,7 @@ import
|
||||
../constantine/config/curves,
|
||||
../constantine/elliptic/[ec_shortweierstrass_affine, ec_shortweierstrass_projective],
|
||||
../constantine/curves/[zoo_subgroups, zoo_pairings],
|
||||
../constantine/pairing/cyclotomic_fp12,
|
||||
../constantine/pairing/[cyclotomic_fp12, cyclotomic_fp6],
|
||||
../constantine/io/io_towers,
|
||||
|
||||
# Test utilities
|
||||
@ -27,7 +27,7 @@ export
|
||||
ec_shortweierstrass_affine, ec_shortweierstrass_projective,
|
||||
arithmetic, towers,
|
||||
primitives, io_towers,
|
||||
cyclotomic_fp12
|
||||
cyclotomic_fp12, cyclotomic_fp6
|
||||
|
||||
type
|
||||
RandomGen* = enum
|
||||
|
Loading…
x
Reference in New Issue
Block a user