mirror of
https://github.com/logos-storage/constantine.git
synced 2026-01-05 22:53:12 +00:00
162 lines
6.6 KiB
Nim
162 lines
6.6 KiB
Nim
# 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
|
|
../config/[common, curves, type_bigint],
|
|
../io/io_bigints,
|
|
../towers,
|
|
../pairing/cyclotomic_fp6,
|
|
../isogeny/frobenius
|
|
|
|
# Slow generic implementation
|
|
# ------------------------------------------------------------
|
|
|
|
# 1st part: f_{u+1,Q}(P)
|
|
const BW6_761_pairing_ate_param_1_unopt* = block:
|
|
# BW6-761 unoptimized Miller loop first part is parametrized by u+1
|
|
# +1 to bitlength so that we can mul by 3 for NAF encoding
|
|
BigInt[64+1].fromHex"0x8508c00000000002"
|
|
|
|
const BW6_761_pairing_ate_param_1_unopt_isNeg* = false
|
|
|
|
|
|
# 2nd part: f_{u*(u²-u-1),Q}(P) followed by Frobenius application
|
|
const BW6_761_pairing_ate_param_2_unopt* = block:
|
|
# BW6 unoptimized Miller loop second part is parametrized by u*(u²-u-1)
|
|
# +1 to bitlength so that we can mul by 3 for NAF encoding
|
|
BigInt[190+1].fromHex"0x23ed1347970dec008a442f991fffffffffffffffffffffff"
|
|
|
|
const BW6_761_pairing_ate_param_2_unopt_isNeg* = false
|
|
|
|
|
|
# 1st part: f_{u,Q}(P)
|
|
const BW6_761_pairing_ate_param_1_opt* = block:
|
|
# BW6 Miller loop first part is parametrized by u
|
|
# no NAF for the optimized first Miller loop
|
|
BigInt[64].fromHex"0x8508c00000000001"
|
|
|
|
const BW6_761_pairing_ate_param_1_opt_isNeg* = false
|
|
|
|
|
|
# 2nd part: f_{u²-u-1,Q}(P) followed by Frobenius application
|
|
const BW6_761_pairing_ate_param_2_opt* = block:
|
|
# BW6 Miller loop second part is parametrized by u²-u-1
|
|
# +1 to bitlength so that we can mul by 3 for NAF encoding
|
|
BigInt[127+1].fromHex"0x452217cc900000008508bfffffffffff"
|
|
|
|
const BW6_761_pairing_ate_param_2_opt_isNeg* = false
|
|
|
|
|
|
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 |