constantine/constantine/pairing/pairing_bls12.nim
Mamy Ratsimbazafy d84edcd217
Naive pairings + Naive cofactor clearing (#82)
* Pairing - initial commit
- line functions
- sparse Fp12 functions

* Small fixes:
- Line parametrized by twist for generic algorithm
- Add a conjugate operator for quadratic extensions
- Have frobenius use it
- Create an Affine coordinate type for elliptic curve

* Implement (failing) pairing test

* Stash pairing debug session, temp switch Fp12 over Fp4

* Proper naive pairing on BLS12-381

* Frobenius map

* Implement naive pairing for BN curves

* Add pairing tests to CI + reduce time spent on lower-level tests

* Test without assembler in Github Actions + less base layers test iterations
2020-09-21 23:24:00 +02:00

153 lines
7.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
../primitives,
../config/[common, curves],
../arithmetic,
../towers,
../io/io_bigints,
../elliptic/[
ec_weierstrass_affine,
ec_weierstrass_projective
],
./lines_projective,
./gt_fp12
# ############################################################
#
# 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
#
# - Faster Pairing Computations on Curves with High-Degree Twists
# Craig Costello, Tanja Lange, and Michael Naehrig, 2009
# https://eprint.iacr.org/2009/615.pdf
# TODO: implement quadruple-and-add and octuple-and-add
# from Costello2009 to trade multiplications in Fpᵏ
# for multiplications in Fp
# TODO: should be part of curve parameters
const BLS12_381_param = block:
# BLS Miller loop is parametrized by u
BigInt[64+2].fromHex("0xd201000000010000") # +2 so that we can take *3 and NAF encode it
const BLS12_381_param_isNeg = true
const BLS12_381_finalexponent = block:
# (p^12 - 1) / r
# BigInt[4314].fromHex"0x2ee1db5dcc825b7e1bda9c0496a1c0a89ee0193d4977b3f7d4507d07363baa13f8d14a917848517badc3a43d1073776ab353f2c30698e8cc7deada9c0aadff5e9cfee9a074e43b9a660835cc872ee83ff3a0f0f1c0ad0d6106feaf4e347aa68ad49466fa927e7bb9375331807a0dce2630d9aa4b113f414386b0e8819328148978e2b0dd39099b86e1ab656d2670d93e4d7acdd350da5359bc73ab61a0c5bf24c374693c49f570bcd2b01f3077ffb10bf24dde41064837f27611212596bc293c8d4c01f25118790f4684d0b9c40a68eb74bb22a40ee7169cdc1041296532fef459f12438dfc8e2886ef965e61a474c5c85b0129127a1b5ad0463434724538411d1676a53b5a62eb34c05739334f46c02c3f0bd0c55d3109cd15948d0a1fad20044ce6ad4c6bec3ec03ef19592004cedd556952c6d8823b19dadd7c2498345c6e5308f1c511291097db60b1749bf9b71a9f9e0100418a3ef0bc627751bbd81367066bca6a4c1b6dcfc5cceb73fc56947a403577dfa9e13c24ea820b09c1d9f7c31759c3635de3f7a3639991708e88adce88177456c49637fd7961be1a4c7e79fb02faa732e2f3ec2bea83d196283313492caa9d4aff1c910e9622d2a73f62537f2701aaef6539314043f7bbce5b78c7869aeb2181a67e49eeed2161daf3f881bd88592d767f67c4717489119226c2f011d4cab803e9d71650a6f80698e2f8491d12191a04406fbc8fbd5f48925f98630e68bfb24c0bcb9b55df57510"
# (p^12 - 1) / r * 3
BigInt[4316].fromHex"0x8ca592196587127a538fd40dc3e541f9dca04bb7dc671be77cf17715a2b2fe3bea73dfb468d8f473094aecb7315a664019fbd84913caba6579c08fd42009fe1bd6fcbce15eacb2cf3218a165958cb8bfdae2d2d54207282314fc0dea9d6ff3a07dbd34efb77b732ba5f994816e296a72928cfee133bdc3ca9412b984b9783d9c6aa81297ab1cd294a502304773528bbae8706979f28efa0d355b0224e2513d6e4a5d3bb4dde0523678105d9167ff1323d6e99ac312d8a7d762336370c4347bb5a7e405d6f3496b2dd38e722d4c1f3ac25e3167ec2cb543d69430c37c2f98fcdd0dd36caa9f5aa7994cec31b24ed5e515911037b376e521070d29c9d56cfa8c3574363efb20f28c19e4105ab99edd44084bd23725017931d6740bda71e5f07600ce6b407e543c4bc40bcd4c0b600e6c98003bf8548986b14d9098746dc89d154af91ad54f337b31c79222145dd3ed254fdeda0300c49ebcd2352765f533883a3513435f3ee452496f5166c25bf503bd6ec0a0679efda3b46ebf86211d458de749460d4a2a19abe6ea2accb451ab9a096b98465d044dc2a7f86c253a4ee57b6df108eff598a8dbc483bf8b74c2789939db85ffd7e0fd55b32bc26877f5be26fa7d750500ce2fab93c0cbe7336b126a5693d0c16484f37addccc7642590dbe98538990b88637e374d545d9b34b67448d0357e60280bbd8542f1f4e813caa8e8db57364b4e0cc14f35af381dd9b71ec9292b3a3f16e42362d2019e05f30"
func millerLoopGenericBLS12[C: static Curve](
f: var Fp12[C],
P: ECP_SWei_Aff[Fp[C]],
Q: ECP_SWei_Aff[Fp2[C]]
) =
## Generic Miller Loop for BLS12 curve
## Computes f{u,Q}(P) with u the BLS curve parameter
# TODO: retrieve the curve parameter from the curve declaration
# Boundary cases
# Loop start
# The litterature starts from both L-1 or L-2:
# L-1:
# - Scott2019, Pairing Implementation Revisited, Algorithm 1
# - Aranha2010, Faster Explicit Formulas ..., Algorithm 1
# L-2
# - Beuchat2010, High-Speed Software Implementation ..., Algorithm 1
# - Aranha2013, The Realm of The Pairings, Algorithm 1
# - Costello, Thesis, Algorithm 2.1
# - Costello2012, Pairings for Beginners, Algorithm 5.1
#
# Even the guide to pairing based cryptography has both
# Chapter 3: L-1 (Algorithm 3.1)
# Chapter 11: L-2 (Algorithm 11.1) but it explains why L-2 (unrolling)
# Loop end
# - Some implementation, for example Beuchat2010 or the Guide to Pairing-Based Cryptography
# have extra line additions after the main loop,
# this is needed for BN curves.
# - With r the order of G1 / G2 / GT,
# we have [r]T = Inf
# Hence, [r-1]T = -T
# so either we use complete addition
# or we special case line addition of T and -T (it's a vertical line)
# or we ensure the loop is done for a number of iterations strictly less
# than the curve order which is the case for BLS12 curves
static: doAssert C == BLS12_381, "Only BLS12-381 is supported at the moment"
var
T {.noInit.}: ECP_SWei_Proj[Fp2[C]]
line {.noInit.}: Line[Fp2[C], C.getSexticTwist()]
nQ{.noInit.}: typeof(Q)
T.projectiveFromAffine(Q)
nQ.neg(Q)
f.setOne()
template u: untyped = BLS12_381_param
let u3 = 3*BLS12_381_param
for i in countdown(u3.bits - 2, 1):
f.square()
line.line_double(T, P)
f.mul_sparse_by_line_xy000z(line)
let naf = u3.bit(i).int8 - u.bit(i).int8 # This can throw exception
if naf == 1:
line.line_add(T, Q, P)
f.mul_sparse_by_line_xy000z(line)
elif naf == -1:
line.line_add(T, nQ, P)
f.mul_sparse_by_line_xy000z(line)
when BLS12_381_param_isNeg: # TODO generic
# In GT, x^-1 == conjugate(x)
# Remark 7.1, chapter 7.1.1 of Guide to Pairing-Based Cryptography, El Mrabet, 2017
f.conj()
func finalExpGeneric[C: static Curve](f: var Fp12[C]) =
## A generic and slow implementation of final exponentiation
## for sanity checks purposes.
static: doAssert C == BLS12_381, "Only BLS12-381 is supported at the moment"
f.powUnsafeExponent(BLS12_381_finalexponent, window = 3)
func pairing_bls12_reference*[C](gt: var Fp12[C], P: ECP_SWei_Proj[Fp[C]], Q: ECP_SWei_Proj[Fp2[C]]) =
## Compute the optimal Ate Pairing for BLS12 curves
## Input: P ∈ G1, Q ∈ G2
## Output: e(P, Q) ∈ Gt
##
## Reference implementation
var Paff {.noInit.}: ECP_SWei_Aff[Fp[C]]
var Qaff {.noInit.}: ECP_SWei_Aff[Fp2[C]]
Paff.affineFromProjective(P)
Qaff.affineFromProjective(Q)
gt.millerLoopGenericBLS12(Paff, Qaff)
gt.finalExpGeneric()
func finalExpEasy[C: static Curve](f: var Fp12[C]) =
## Easy part of the final exponentiation
## We need to clear the GT cofactor to obtain
## an unique GT representation
## (reminder, GT is a multiplicative group hence we exponentiate by the cofactor)
##
## With an embedding degree of 12, the easy part of final exponentiation is
##
## f^(p⁶1)(p²+1)
discard