From 50717d8de6715647320fb69935bf8926b5769f95 Mon Sep 17 00:00:00 2001 From: Mamy Ratsimbazafy Date: Sat, 8 Jan 2022 17:30:26 +0100 Subject: [PATCH] Test GT-subgroup for BW6-761 (#171) --- constantine.nimble | 1 + constantine/curves/bls12_377_pairing.nim | 4 +- constantine/curves/bls12_377_subgroups.nim | 4 +- constantine/curves/bls12_381_subgroups.nim | 4 +- constantine/curves/bw6_761_pairing.nim | 111 ++++++++- constantine/curves/bw6_761_subgroups.nim | 2 +- constantine/pairing/cyclotomic_fp6.nim | 233 ++++++++++++++++++ .../pairing}/pairing_bw6_761.nim | 24 +- tests/t_pairing_bw6_761_gt_subgroup.nim | 19 ++ tests/t_pairing_template.nim | 4 +- 10 files changed, 384 insertions(+), 22 deletions(-) create mode 100644 constantine/pairing/cyclotomic_fp6.nim rename {research/bw6_761 => constantine/pairing}/pairing_bw6_761.nim (87%) create mode 100644 tests/t_pairing_bw6_761_gt_subgroup.nim diff --git a/constantine.nimble b/constantine.nimble index 18a4d06..66c137d 100644 --- a/constantine.nimble +++ b/constantine.nimble @@ -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 # ---------------------------------------------------------- diff --git a/constantine/curves/bls12_377_pairing.nim b/constantine/curves/bls12_377_pairing.nim index 8e184ca..2072851 100644 --- a/constantine/curves/bls12_377_pairing.nim +++ b/constantine/curves/bls12_377_pairing.nim @@ -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) diff --git a/constantine/curves/bls12_377_subgroups.nim b/constantine/curves/bls12_377_subgroups.nim index 1e13c7c..d543ff3 100644 --- a/constantine/curves/bls12_377_subgroups.nim +++ b/constantine/curves/bls12_377_subgroups.nim @@ -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 diff --git a/constantine/curves/bls12_381_subgroups.nim b/constantine/curves/bls12_381_subgroups.nim index 0d9d247..3ce2152 100644 --- a/constantine/curves/bls12_381_subgroups.nim +++ b/constantine/curves/bls12_381_subgroups.nim @@ -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 diff --git a/constantine/curves/bw6_761_pairing.nim b/constantine/curves/bw6_761_pairing.nim index a3d0cf5..e14434b 100644 --- a/constantine/curves/bw6_761_pairing.nim +++ b/constantine/curves/bw6_761_pairing.nim @@ -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 -# ------------------------------------------------------------ \ No newline at end of file +# ------------------------------------------------------------ + +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 \ No newline at end of file diff --git a/constantine/curves/bw6_761_subgroups.nim b/constantine/curves/bw6_761_subgroups.nim index 694c2f2..baa72c3 100644 --- a/constantine/curves/bw6_761_subgroups.nim +++ b/constantine/curves/bw6_761_subgroups.nim @@ -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) \ No newline at end of file + P.scalarMulGeneric(Cofactor_Eff_BW6_761_G2) diff --git a/constantine/pairing/cyclotomic_fp6.nim b/constantine/pairing/cyclotomic_fp6.nim new file mode 100644 index 0000000..fbe6476 --- /dev/null +++ b/constantine/pairing/cyclotomic_fp6.nim @@ -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 \ No newline at end of file diff --git a/research/bw6_761/pairing_bw6_761.nim b/constantine/pairing/pairing_bw6_761.nim similarity index 87% rename from research/bw6_761/pairing_bw6_761.nim rename to constantine/pairing/pairing_bw6_761.nim index 52e7d29..08401f5 100644 --- a/research/bw6_761/pairing_bw6_761.nim +++ b/constantine/pairing/pairing_bw6_761.nim @@ -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() \ No newline at end of file diff --git a/tests/t_pairing_bw6_761_gt_subgroup.nim b/tests/t_pairing_bw6_761_gt_subgroup.nim new file mode 100644 index 0000000..454dcad --- /dev/null +++ b/tests/t_pairing_bw6_761_gt_subgroup.nim @@ -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) diff --git a/tests/t_pairing_template.nim b/tests/t_pairing_template.nim index dc8ceeb..e8aa62b 100644 --- a/tests/t_pairing_template.nim +++ b/tests/t_pairing_template.nim @@ -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