constantine/constantine/math/curves/bls12_377_pairing.nim
Mamy Ratsimbazafy ffacf61e8a
Don't dump all in "backend" (#184)
* backend -> math

* towers -> extension fields

* move ISA and compiler specific code out of math/

* fix export
2022-02-27 01:49:08 +01:00

109 lines
5.3 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
../../platforms/abstractions,
../config/curves,
../io/io_bigints,
../extension_fields,
../elliptic/[ec_shortweierstrass_affine, ec_shortweierstrass_projective],
../pairing/[cyclotomic_subgroup, miller_loops],
../isogenies/frobenius
# Slow generic implementation
# ------------------------------------------------------------
# The bit count must be exact for the Miller loop
const BLS12_377_pairing_ate_param* = block:
# BLS12 Miller loop is parametrized by u
# +1 to bitlength so that we can mul by 3 for NAF encoding
BigInt[64+1].fromHex"0x8508c00000000001"
const BLS12_377_pairing_ate_param_isNeg* = false
const BLS12_377_pairing_finalexponent* = block:
# (p^12 - 1) / r * 3
BigInt[4271].fromHex"0x518fe3a450394da01ed0ec73865aed18d4251c557c299312d07b5d31105598be5439b32fda943a26e8d85c306e6c1941dd3f9d646d87211c240f5489c67b1a8663c49da97a2880dc48213527e51d370acd05663ffda035ca31c4ba994c89d66c0c97066502f8ef19bb008e047c24cf96e02493f4683ffdc39075cc1c01df9fd0ec1dc0419176c010ac1a83b777201a77f8dab474e99c59ae840de7362f7c231d500aecc1eb52616067540d419f7f9fbfd22831919b4ac04960703d9753698941c95aa2d2a04f4bf26de9d191661a013cbb09227c09424595e2639ae94d35ce708bdec2c10628eb4f981945698ef049502d2a71994fab9898c028c73dd021f13208590be27e78f0f18a88f5ffe40157a9e9fef5aa229c0aa7fdb16a887af2c4a486258bf11fb1a5d945707a89d7bf8f67e5bb28f76a460d9a1e660cbbe91bfc456b8789d5bae1dba8cbef5b03bcd0ea30f6a7b45218292b2bf3b20ed5937cb5e2250eee395821805c6383d0286c7423beb42e79f85dab2a36df8fd154f2d89e5e9aaadaaa00e0a29ecc6e329195761d6063e0a2e136a3fb7671c9134c970a8588a7f3144642a10a5af77c105f5e90987f28c6604c5dcb604c02f7d642f7f819eea6fadb8aace7c4e146a17dab2c644d4372c6979845f261b4a20cd88a20325e0c0fc806bd9f60a8502fa8f466b6919311e232e06fd6a861cb5dc24d69274c7e631cac6b93e0254460d445a0000012b53b000000000000"
# Addition chains
# ------------------------------------------------------------
#
# u = 0x8508c00000000001
# Ate BLS |u|
# hex: 0x8508c00000000001
# bin: 0b1000010100001000110000000000000000000000000000000000000000000001
#
# 71 naive operations to build a naive addition chain
# or 68 with optimizations, though unsure how to use them in the Miller Loop
# and for multi-pairing it would use too much temporaries anyway.
func millerLoopAddchain*(
f: var Fp12[BLS12_377],
Q: ECP_ShortW_Aff[Fp2[BLS12_377], G2],
P: ECP_ShortW_Aff[Fp[BLS12_377], G1]
) =
## Miller Loop for BLS12-377 curve
## Computes f{u,Q}(P) with u the BLS curve parameter
var T {.noInit.}: ECP_ShortW_Prj[Fp2[BLS12_377], G2]
f.miller_init_double_then_add(T, Q, P, 5) # 0b100001
f.miller_accum_double_then_add(T, Q, P, 2) # 0b10000101
f.miller_accum_double_then_add(T, Q, P, 5) # 0b1000010100001
f.miller_accum_double_then_add(T, Q, P, 4) # 0b10000101000010001
f.miller_accum_double_then_add(T, Q, P, 1) # 0b100001010000100011
f.miller_accum_double_then_add(T, Q, P, 46, add = true) # 0b1000010100001000110000000000000000000000000000000000000000000001
func millerLoopAddchain*[N: static int](
f: var Fp12[BLS12_377],
Qs: array[N, ECP_ShortW_Aff[Fp2[BLS12_377], G2]],
Ps: array[N, ECP_ShortW_Aff[Fp[BLS12_377], G1]]
) =
## Miller Loop for BLS12-377 curve
## Computes f{u,Q}(P) with u the BLS curve parameter
var Ts {.noInit.}: array[N, ECP_ShortW_Prj[Fp2[BLS12_377], G2]]
f.miller_init_double_then_add(Ts, Qs, Ps, 5) # 0b100001
f.miller_accum_double_then_add(Ts, Qs, Ps, 2) # 0b10000101
f.miller_accum_double_then_add(Ts, Qs, Ps, 5) # 0b1000010100001
f.miller_accum_double_then_add(Ts, Qs, Ps, 4) # 0b10000101000010001
f.miller_accum_double_then_add(Ts, Qs, Ps, 1) # 0b100001010000100011
f.miller_accum_double_then_add(Ts, Qs, Ps, 46, add = true) # 0b1000010100001000110000000000000000000000000000000000000000000001
func cycl_exp_by_curve_param*(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
r.cycl_sqr_repeated(a, 5)
r *= a
let t{.noInit.} = r
r.cycl_sqr_repeated(7)
r *= t
r.cycl_sqr_repeated(4)
r *= a
r.cyclotomic_square()
r *= a
r.cyclotomic_exp_compressed(r, [46])
r *= a
if invert:
r.cyclotomic_inv()
func isInPairingSubgroup*(a: Fp12[BLS12_377]): 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^u
var t0{.noInit.}, t1{.noInit.}: Fp12[BLS12_377]
t0.frobenius_map(a)
t1.cycl_exp_by_curve_param(a)
return t0 == t1