constantine/constantine/pairing/pairing_bls12.nim
2022-01-01 19:17:04 +01:00

173 lines
5.4 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
../config/[common, curves, type_ff],
../towers,
../elliptic/[
ec_shortweierstrass_affine,
ec_shortweierstrass_projective
],
../isogeny/frobenius,
../curves/zoo_pairings,
./cyclotomic_fp12,
./lines_common,
./miller_loops
export zoo_pairings # generic sandwich https://github.com/nim-lang/Nim/issues/11225
# No exceptions allowed
{.push raises: [].}
# ############################################################
#
# Optimal ATE pairing for
# BLS12 curves
#
# ############################################################
# - Efficient Final Exponentiation
# via Cyclotomic Structure for Pairings
# over Families of Elliptic Curves
# Daiki Hayashida and Kenichiro Hayasaka
# and Tadanori Teruya, 2020
# https://eprint.iacr.org/2020/875.pdf
#
# - Improving the computation of the optimal ate pairing
# for a high security level.
# Loubna Ghammam, Emmanuel Fouotsa
# J. Appl. Math. Comput.59, 2136 (2019)
#
# - Faster Pairing Computations on Curves with High-Degree Twists
# Craig Costello, Tanja Lange, and Michael Naehrig, 2009
# https://eprint.iacr.org/2009/615.pdf
# Generic pairing implementation
# ----------------------------------------------------------------
func millerLoopGenericBLS12*[C](
f: var Fp12[C],
P: ECP_ShortW_Aff[Fp[C], G1],
Q: ECP_ShortW_Aff[Fp2[C], G2]
) {.meter.} =
## Generic Miller Loop for BLS12 curve
## Computes f{u,Q}(P) with u the BLS curve parameter
var
T {.noInit.}: ECP_ShortW_Prj[Fp2[C], G2]
line {.noInit.}: Line[Fp2[C]]
nQ{.noInit.}: typeof(Q)
T.projectiveFromAffine(Q)
nQ.neg(Q)
basicMillerLoop(
f, T, line,
P, Q, nQ,
ate_param, ate_param_isNeg
)
func finalExpGeneric[C: static Curve](f: var Fp12[C]) =
## A generic and slow implementation of final exponentiation
## for sanity checks purposes.
f.powUnsafeExponent(C.pairing(finalexponent), window = 3)
func pairing_bls12_reference*[C](
gt: var Fp12[C],
P: ECP_ShortW_Aff[Fp[C], G1],
Q: ECP_ShortW_Aff[Fp2[C], G2]) =
## Compute the optimal Ate Pairing for BLS12 curves
## Input: P ∈ G1, Q ∈ G2
## Output: e(P, Q) ∈ Gt
##
## Reference implementation
gt.millerLoopGenericBLS12(P, Q)
gt.finalExpGeneric()
# Optimized pairing implementation
# ----------------------------------------------------------------
func finalExpHard_BLS12*[C](f: var Fp12[C]) {.meter.} =
## Hard part of the final exponentiation
## Specialized for BLS12 curves
##
# - Efficient Final Exponentiation
# via Cyclotomic Structure for Pairings
# over Families of Elliptic Curves
# Daiki Hayashida and Kenichiro Hayasaka
# and Tadanori Teruya, 2020
# https://eprint.iacr.org/2020/875.pdf
#
# p14: 3 Φ₁₂(p(x))/r(x) = (x1)² (x+p) (x²+p²1) + 3
#
# with
# - Eₓ being f^x
# - Eₓ/₂ being f^(x/2)
# - M₁₂ being mul in Fp12
# - S₁₂ being cyclotomic squaring
# - Fₙ being n Frobenius applications
var v0 {.noInit.}, v1 {.noInit.}, v2 {.noInit.}: Fp12[C]
# Save for f³ and (x1)²
v2.cyclotomic_square(f) # v2 = f²
# (x1)²
when C.pairing(ate_param).isEven.bool:
v0.pow_xdiv2(v2) # v0 = (f²)^(x/2) = f^x
else:
v0.pow_x(f)
v1.cyclotomic_inv(f) # v1 = f^-1
v0 *= v1 # v0 = f^(x-1)
v1.pow_x(v0) # v1 = (f^(x-1))^x
v0.cyclotomic_inv() # v0 = (f^(x-1))^-1
v0 *= v1 # v0 = (f^(x-1))^(x-1) = f^((x-1)*(x-1)) = f^((x-1)²)
# (x+p)
v1.pow_x(v0) # v1 = f^((x-1)².x)
v0.frobenius_map(v0) # v0 = f^((x-1)².p)
v0 *= v1 # v0 = f^((x-1)².(x+p))
# + 3
f *= v2 # f = f³
# (x²+p²1)
v2.pow_x(v0, invert = false)
v1.pow_x(v2, invert = false) # v1 = f^((x-1)².(x+p).x²)
v2.frobenius_map(v0, 2) # v2 = f^((x-1)².(x+p).p²)
v0.cyclotomic_inv() # v0 = f^((x-1)².(x+p).-1)
v0 *= v1 # v0 = f^((x-1)².(x+p).(x²-1))
v0 *= v2 # v0 = f^((x-1)².(x+p).(x²+p²-1))
# (x1)².(x+p).(x²+p²1) + 3
f *= v0
func pairing_bls12*[C](
gt: var Fp12[C],
P: ECP_ShortW_Aff[Fp[C], G1],
Q: ECP_ShortW_Aff[Fp2[C], G2]) {.meter.} =
## Compute the optimal Ate Pairing for BLS12 curves
## Input: P ∈ G1, Q ∈ G2
## Output: e(P, Q) ∈ Gt
gt.millerLoopAddchain(Q, P)
gt.finalExpEasy()
gt.finalExpHard_BLS12()
func pairing_bls12*[N: static int, C](
gt: var Fp12[C],
Ps: array[N, ECP_ShortW_Aff[Fp[C], G1]],
Qs: array[N, ECP_ShortW_Aff[Fp2[C], G2]]) {.meter.} =
## Compute the optimal Ate Pairing for BLS12 curves
## Input: an array of Ps ∈ G1 and Qs ∈ G2
## Output:
## The product of pairings
## e(P₀, Q₀) * e(P₁, Q₁) * e(P₂, Q₂) * ... * e(Pₙ, Qₙ) ∈ Gt
gt.millerLoopAddchain(Qs, Ps)
gt.finalExpEasy()
gt.finalExpHard_BLS12()