Move pairings

This commit is contained in:
Mamy André-Ratsimbazafy 2020-09-27 21:00:35 +02:00
parent 2721131168
commit 00fa1ea7b6
No known key found for this signature in database
GPG Key ID: 7B88AD1FE79492E1
22 changed files with 324 additions and 270 deletions

View File

@ -340,10 +340,15 @@ func `*=`*(a: var Fp, b: Fp) {.inline.} =
## Multiplication modulo p
a.prod(a, b)
func square*(a: var Fp) {.inline.}=
func square*(a: var Fp) {.inline.} =
## Squaring modulo p
a.mres.montySquare(a.mres, Fp.C.Mod, Fp.C.getNegInvModWord(), Fp.C.canUseNoCarryMontySquare())
func square_repeated*(r: var Fp, num: int) {.inline.} =
## Repeated squarings
for _ in 0 ..< num:
r.square()
func `*=`*(a: var Fp, b: static int) {.inline.} =
## Multiplication by a small integer known at compile-time
# Implementation:

View File

@ -9,9 +9,9 @@
import
../config/[common, curves, type_fp],
./bigints,
../curves/addchain_inversions
../curves/zoo_inversions
export addchain_inversions
export zoo_inversions
# ############################################################
#

View File

@ -9,7 +9,7 @@
import
../primitives,
../config/[common, type_fp, curves],
../curves/addchain_square_roots,
../curves/zoo_square_roots,
../io/[io_bigints, io_fields],
./bigints, ./finite_fields, ./limbs_montgomery

View File

@ -0,0 +1,9 @@
# Curve-specific constants and procedures
This folder holds curve-specific constants and procedure in particular:
- Inversion addition chains
- Final exponentiation addition chains
- Square root constants for Tonelli Shanks
- Lattice decomposition constants for endomorphism acceleration
- Frobenius endomorphism constants

View File

@ -0,0 +1,56 @@
# 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/[curves, type_bigint],
../towers,
../io/io_bigints,
../pairing/cyclotomic_fp12
# The bit count must be exact for the Miller loop
const BLS12_377_pairing_ate_param* = block:
# BLS Miller loop is parametrized by u
# +1 so that we can take *3 and NAF encode it
BigInt[64+1].fromHex("0x8508c00000000001")
const BLS12_377_pairing_ate_param_isNeg* = false
const BLS12_377_pairing_finalexponent* = block:
# (p^12 - 1) / r
# BigInt[4269].fromHex"0x1b2ff68c1abdc48ab4f04ed12cc8f9b2f161b41c7eb8865b9ad3c9bb0571dd94c6bde66548dc13624d9d741024ceb315f46a89cc2482605eb6afc6d8977e5e2ccbec348dd362d59ec2b5bc62a1b467ae44572215548abc98bb4193886ed89cceaedd0221aba84fb33e5584ac29619a87a00c315178155496857c995eab4a8a9af95f4015db27955ae408d6927d0ab37d52f3917c4ddec88f8159f7bcba7eb65f1aae4eeb4e70cb20227159c08a7fdfea9b62bb308918eac3202569dd1bcdd86b431e3646356fc3fb79f89b30775e006993adb629586b6c874b7688f86f11ef7ad94a40eb020da3c532b317232fa56dc564637b331a8e8832eab84269f00b506602c8594b7f7da5a5d8d851fff6ab1d38a354fc8e0b8958e2a9e5ce2d7e50ec36d761d9505fe5e1f317257e2df2952fcd4c93b85278c20488b4ccaee94db3fec1ce8283473e4b493843fa73abe99af8bafce29170b2b863b9513b5a47312991f60c5a4f6872b5d574212bf00d797c0bea3c0f7dfd748e63679fda9b1c50f2df74de38f38e004ae0df997a10db31d209cacbf58ba0678bfe7cd0985bc43258d72d8d5106c21635ae1e527eb01fca3032d50d97756ec9ee756eaba7f21652a808a4e2539e838ef7ec4b178b29e3b976c46bd0ecdd32c1fb75e6e0aef2d8b5661f595a98023f3520381aba8da6cce785dbb0a0bba025478d75ee749619cdb7c42a21098ece86a00c6c2046c1e00000063c69000000000000"
# (p^12 - 1) / r * 3
BigInt[4271].fromHex"0x518fe3a450394da01ed0ec73865aed18d4251c557c299312d07b5d31105598be5439b32fda943a26e8d85c306e6c1941dd3f9d646d87211c240f5489c67b1a8663c49da97a2880dc48213527e51d370acd05663ffda035ca31c4ba994c89d66c0c97066502f8ef19bb008e047c24cf96e02493f4683ffdc39075cc1c01df9fd0ec1dc0419176c010ac1a83b777201a77f8dab474e99c59ae840de7362f7c231d500aecc1eb52616067540d419f7f9fbfd22831919b4ac04960703d9753698941c95aa2d2a04f4bf26de9d191661a013cbb09227c09424595e2639ae94d35ce708bdec2c10628eb4f981945698ef049502d2a71994fab9898c028c73dd021f13208590be27e78f0f18a88f5ffe40157a9e9fef5aa229c0aa7fdb16a887af2c4a486258bf11fb1a5d945707a89d7bf8f67e5bb28f76a460d9a1e660cbbe91bfc456b8789d5bae1dba8cbef5b03bcd0ea30f6a7b45218292b2bf3b20ed5937cb5e2250eee395821805c6383d0286c7423beb42e79f85dab2a36df8fd154f2d89e5e9aaadaaa00e0a29ecc6e329195761d6063e0a2e136a3fb7671c9134c970a8588a7f3144642a10a5af77c105f5e90987f28c6604c5dcb604c02f7d642f7f819eea6fadb8aace7c4e146a17dab2c644d4372c6979845f261b4a20cd88a20325e0c0fc806bd9f60a8502fa8f466b6919311e232e06fd6a861cb5dc24d69274c7e631cac6b93e0254460d445a0000012b53b000000000000"
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
## Warning: The parameter is odd and needs a correction
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)
r *= a
if invert:
r.cyclotomic_inv()

View File

@ -16,12 +16,6 @@ import
#
# ############################################################
# Field-specific inversion routines
func square_repeated(r: var Fp, num: int) =
## Repeated squarings
for _ in 0 ..< num:
r.square()
func inv_addchain*(r: var Fp[BLS12_381], a: Fp[BLS12_381]) =
var
x10 {.noinit.}: Fp[BLS12_381]

View File

@ -0,0 +1,51 @@
# 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/[curves, type_bigint],
../towers,
../io/io_bigints,
../pairing/cyclotomic_fp12
# The bit count must be exact for the Miller loop
const BLS12_381_pairing_ate_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_pairing_ate_param_isNeg* = true
const BLS12_381_pairing_finalexponent* = block:
# (p^12 - 1) / r
# BigInt[4314].fromHex"0x2ee1db5dcc825b7e1bda9c0496a1c0a89ee0193d4977b3f7d4507d07363baa13f8d14a917848517badc3a43d1073776ab353f2c30698e8cc7deada9c0aadff5e9cfee9a074e43b9a660835cc872ee83ff3a0f0f1c0ad0d6106feaf4e347aa68ad49466fa927e7bb9375331807a0dce2630d9aa4b113f414386b0e8819328148978e2b0dd39099b86e1ab656d2670d93e4d7acdd350da5359bc73ab61a0c5bf24c374693c49f570bcd2b01f3077ffb10bf24dde41064837f27611212596bc293c8d4c01f25118790f4684d0b9c40a68eb74bb22a40ee7169cdc1041296532fef459f12438dfc8e2886ef965e61a474c5c85b0129127a1b5ad0463434724538411d1676a53b5a62eb34c05739334f46c02c3f0bd0c55d3109cd15948d0a1fad20044ce6ad4c6bec3ec03ef19592004cedd556952c6d8823b19dadd7c2498345c6e5308f1c511291097db60b1749bf9b71a9f9e0100418a3ef0bc627751bbd81367066bca6a4c1b6dcfc5cceb73fc56947a403577dfa9e13c24ea820b09c1d9f7c31759c3635de3f7a3639991708e88adce88177456c49637fd7961be1a4c7e79fb02faa732e2f3ec2bea83d196283313492caa9d4aff1c910e9622d2a73f62537f2701aaef6539314043f7bbce5b78c7869aeb2181a67e49eeed2161daf3f881bd88592d767f67c4717489119226c2f011d4cab803e9d71650a6f80698e2f8491d12191a04406fbc8fbd5f48925f98630e68bfb24c0bcb9b55df57510"
# (p^12 - 1) / r * 3
BigInt[4316].fromHex"0x8ca592196587127a538fd40dc3e541f9dca04bb7dc671be77cf17715a2b2fe3bea73dfb468d8f473094aecb7315a664019fbd84913caba6579c08fd42009fe1bd6fcbce15eacb2cf3218a165958cb8bfdae2d2d54207282314fc0dea9d6ff3a07dbd34efb77b732ba5f994816e296a72928cfee133bdc3ca9412b984b9783d9c6aa81297ab1cd294a502304773528bbae8706979f28efa0d355b0224e2513d6e4a5d3bb4dde0523678105d9167ff1323d6e99ac312d8a7d762336370c4347bb5a7e405d6f3496b2dd38e722d4c1f3ac25e3167ec2cb543d69430c37c2f98fcdd0dd36caa9f5aa7994cec31b24ed5e515911037b376e521070d29c9d56cfa8c3574363efb20f28c19e4105ab99edd44084bd23725017931d6740bda71e5f07600ce6b407e543c4bc40bcd4c0b600e6c98003bf8548986b14d9098746dc89d154af91ad54f337b31c79222145dd3ed254fdeda0300c49ebcd2352765f533883a3513435f3ee452496f5166c25bf503bd6ec0a0679efda3b46ebf86211d458de749460d4a2a19abe6ea2accb451ab9a096b98465d044dc2a7f86c253a4ee57b6df108eff598a8dbc483bf8b74c2789939db85ffd7e0fd55b32bc26877f5be26fa7d750500ce2fab93c0cbe7336b126a5693d0c16484f37addccc7642590dbe98538990b88637e374d545d9b34b67448d0357e60280bbd8542f1f4e813caa8e8db57364b4e0cc14f35af381dd9b71ec9292b3a3f16e42362d2019e05f30"
func pow_xdiv2*(r: var Fp12[BLS12_381], a: Fp12[BLS12_381], invert = BLS12_381_pairing_ate_param_isNeg) =
## f^(x/2) with x the curve parameter
## For BLS12_381 f^-0xd201000000010000
r.cyclotomic_square(a)
r *= a
r.cycl_sqr_repeated(2)
r *= a
r.cycl_sqr_repeated(3)
r *= a
r.cycl_sqr_repeated(9)
r *= a
r.cycl_sqr_repeated(32) # TODO: use Karabina?
r *= a
r.cycl_sqr_repeated(16-1) # Don't do the last iteration
if invert:
r.cyclotomic_inv()
func pow_x*(r: var Fp12[BLS12_381], a: Fp12[BLS12_381], invert = BLS12_381_pairing_ate_param_isNeg) =
## f^x with x the curve parameter
## For BLS12_381 f^-0xd201000000010000
r.pow_xdiv2(a, invert)
r.cyclotomic_square()

View File

@ -0,0 +1,37 @@
# 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/[curves, type_bigint],
../towers,
../io/io_bigints,
../pairing/cyclotomic_fp12
# The bit count must be exact for the Miller loop
const BN254_Nogami_pairing_ate_param* = block:
# BN Miller loop is parametrized by 6u+2
# 65+2 bit for NAF x3 encoding
BigInt[65+2].fromHex"0x18300000000000004"
const BN254_Nogami_pairing_ate_param_isNeg* = true
const BN254_Nogami_pairing_finalexponent* = block:
# (p^12 - 1) / r
BigInt[2786].fromHex"0x2928fbb36b391596ee3fe4cbe857330da83e46fedf04d235a4a8daf5ff9f6eabcb4e3f20aa06f0a0d96b24f9af0cbbce750d61627dcbf5fec9139b8f1c46c86b49b4f8a202af26e4504f2c0f56570e9bd5b94c403f385d1908556486e24b396ddc2cdf13d06542f84fe8e82ccbad7b7423fc1ef4e8cc73d605e3e867c0a75f45ea7f6356d9846ce35d5a34f30396938818ad41914b97b99c289a7259b5d2e09477a77bd3c409b19f19e893f8ade90b0aed1b5fc8a07a3cebb41d4e9eee96b21a832ddb1e93e113edfb704fa532848c18593cd0ee90444a1b3499a800177ea38bdec62ec5191f2b6bbee449722f98d2173ad33077545c2ad10347e125a56fb40f086e9a4e62ad336a72c8b202ac3c1473d73b93d93dc0795ca0ca39226e7b4c1bb92f99248ec0806e0ad70744e9f2238736790f5185ea4c70808442a7d530c6ccd56b55a6973867ec6c73599bbd020bbe105da9c6b5c009ad8946cd6f0"
func pow_u*(r: var Fp12[BN254_Nogami], a: Fp12[BN254_Nogami], invert = BN254_Nogami_pairing_ate_param_isNeg) =
## f^u with u the curve parameter
## For BN254_Nogami f^-0x4080000000000001
r = a
r.cycl_sqr_repeated(7)
r *= a
r.cycl_sqr_repeated(55)
r *= a
if invert:
r.cyclotomic_inv()

View File

@ -16,12 +16,6 @@ import
#
# ############################################################
# Field-specific inversion routines
func square_repeated(r: var Fp, num: int) =
## Repeated squarings
for _ in 0 ..< num:
r.square()
func inv_addchain*(r: var Fp[BN254_Snarks], a: Fp[BN254_Snarks]) =
var
x10 {.noInit.}: Fp[BN254_Snarks]

View File

@ -0,0 +1,107 @@
# 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/[curves, type_bigint],
../towers,
../io/io_bigints,
../pairing/cyclotomic_fp12
# The bit count must be exact for the Miller loop
const BN254_Snarks_pairing_ate_param* = block:
# BN Miller loop is parametrized by 6u+2
BigInt[65+2].fromHex"0x19d797039be763ba8"
const BN254_Snarks_pairing_ate_param_isNeg* = false
const BN254_Snarks_pairing_finalexponent* = block:
# (p^12 - 1) / r
BigInt[2790].fromHex"0x2f4b6dc97020fddadf107d20bc842d43bf6369b1ff6a1c71015f3f7be2e1e30a73bb94fec0daf15466b2383a5d3ec3d15ad524d8f70c54efee1bd8c3b21377e563a09a1b705887e72eceaddea3790364a61f676baaf977870e88d5c6c8fef0781361e443ae77f5b63a2a2264487f2940a8b1ddb3d15062cd0fb2015dfc6668449aed3cc48a82d0d602d268c7daab6a41294c0cc4ebe5664568dfc50e1648a45a4a1e3a5195846a3ed011a337a02088ec80e0ebae8755cfe107acf3aafb40494e406f804216bb10cf430b0f37856b42db8dc5514724ee93dfb10826f0dd4a0364b9580291d2cd65664814fde37ca80bb4ea44eacc5e641bbadf423f9a2cbf813b8d145da90029baee7ddadda71c7f3811c4105262945bba1668c3be69a3c230974d83561841d766f9c9d570bb7fbe04c7e8a6c3c760c0de81def35692da361102b6b9b2b918837fa97896e84abb40a4efb7e54523a486964b64ca86f120"
func pow_u*(r: var Fp12[BN254_Snarks], a: Fp12[BN254_Snarks], invert = BN254_Snarks_pairing_ate_param_isNeg) =
## f^u with u the curve parameter
## For BN254_Snarks f^0x44e992b44a6909f1
when false:
cyclotomic_exp(
r, a,
BigInt[63].fromHex("0x44e992b44a6909f1"),
invert
)
else:
var # Hopefully the compiler optimizes away unused Fp12
# because those are huge
x10 {.noInit.}: Fp12[BN254_Snarks]
x11 {.noInit.}: Fp12[BN254_Snarks]
x100 {.noInit.}: Fp12[BN254_Snarks]
x110 {.noInit.}: Fp12[BN254_Snarks]
x1100 {.noInit.}: Fp12[BN254_Snarks]
x1111 {.noInit.}: Fp12[BN254_Snarks]
x10010 {.noInit.}: Fp12[BN254_Snarks]
x10110 {.noInit.}: Fp12[BN254_Snarks]
x11100 {.noInit.}: Fp12[BN254_Snarks]
x101110 {.noInit.}: Fp12[BN254_Snarks]
x1001010 {.noInit.}: Fp12[BN254_Snarks]
x1111000 {.noInit.}: Fp12[BN254_Snarks]
x10001110 {.noInit.}: Fp12[BN254_Snarks]
x10 .cyclotomic_square(a)
x11 .prod(x10, a)
x100 .prod(x11, a)
x110 .prod(x10, x100)
x1100 .cyclotomic_square(x110)
x1111 .prod(x11, x1100)
x10010 .prod(x11, x1111)
x10110 .prod(x100, x10010)
x11100 .prod(x110, x10110)
x101110 .prod(x10010, x11100)
x1001010 .prod(x11100, x101110)
x1111000 .prod(x101110, x1001010)
x10001110 .prod(x10110, x1111000)
var
i15 {.noInit.}: Fp12[BN254_Snarks]
i16 {.noInit.}: Fp12[BN254_Snarks]
i17 {.noInit.}: Fp12[BN254_Snarks]
i18 {.noInit.}: Fp12[BN254_Snarks]
i20 {.noInit.}: Fp12[BN254_Snarks]
i21 {.noInit.}: Fp12[BN254_Snarks]
i22 {.noInit.}: Fp12[BN254_Snarks]
i26 {.noInit.}: Fp12[BN254_Snarks]
i27 {.noInit.}: Fp12[BN254_Snarks]
i61 {.noInit.}: Fp12[BN254_Snarks]
i15.cyclotomic_square(x10001110)
i15 *= x1001010
i16.prod(x10001110, i15)
i17.prod(x1111, i16)
i18.prod(i16, i17)
i20.cyclotomic_square(i18)
i20 *= i17
i21.prod(x1111000, i20)
i22.prod(i15, i21)
i26.cyclotomic_square(i22)
i26.cyclotomic_square()
i26 *= i22
i26 *= i18
i27.prod(i22, i26)
i61.prod(i26, i27)
i61.cycl_sqr_repeated(17)
i61 *= i27
i61.cycl_sqr_repeated(14)
i61 *= i21
r = i61
r.cycl_sqr_repeated(16)
r *= i20
if invert:
r.cyclotomic_inv()

View File

@ -16,12 +16,6 @@ import
#
# ############################################################
# Field-specific inversion routines
func square_repeated(r: var Fp, num: int) =
## Repeated squarings
for _ in 0 ..< num:
r.square()
func inv_addchain*(r: var Fp[Secp256k1], a: Fp[Secp256k1]) {.used.}=
## We invert via Little Fermat's theorem
## a^(-1) ≡ a^(p-2) (mod p)

View File

@ -0,0 +1,23 @@
# 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
std/macros,
../config/curves,
./bls12_377_pairing,
./bls12_381_pairing,
./bn254_nogami_pairing,
./bn254_snarks_pairing
{.experimental: "dynamicBindSym".}
macro pairing*(C: static Curve, value: untyped): untyped =
## Get pairing related constants
return bindSym($C & "_pairing_" & $value)
export pow_x, pow_xdiv2, pow_u

View File

@ -14,4 +14,5 @@ import
{.experimental: "dynamicBindSym".}
macro tonelliShanks*(C: static Curve, value: untyped): untyped =
## Get Square Root via Tonelli-Shanks related constants
return bindSym($C & "_TonelliShanks_" & $value)

View File

@ -12,7 +12,7 @@ import
# Internal
../primitives,
../config/[common, curves, type_bigint],
../curves/constants_glv,
../curves/zoo_glv,
../arithmetic,
../io/io_bigints,
../towers,

View File

@ -10,7 +10,7 @@ import
std/macros,
../arithmetic,
../towers,
../curves/constants_frobenius
../curves/zoo_frobenius
# Frobenius Map
# ------------------------------------------------------------

View File

@ -225,6 +225,11 @@ func cyclotomic_square*[C](a: var Fp12[C]) =
else:
{.error: "Not implemented".}
func cycl_sqr_repeated*(f: var Fp12, num: int) {.inline.} =
## 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)

View File

@ -7,12 +7,8 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
std/macros,
../primitives,
../config/[common, curves],
../arithmetic,
../config/[curves, type_fp],
../towers,
../io/io_bigints,
../elliptic/[
ec_weierstrass_affine,
ec_weierstrass_projective
@ -20,7 +16,8 @@ import
../isogeny/frobenius,
./lines_projective,
./mul_fp12_by_lines,
./cyclotomic_fp12
./cyclotomic_fp12,
../curves/zoo_pairings
# ############################################################
#
@ -45,41 +42,10 @@ import
# Craig Costello, Tanja Lange, and Michael Naehrig, 2009
# https://eprint.iacr.org/2009/615.pdf
# TODO: should be part of curve parameters
# The bit count must be exact for the Miller loop
const BLS12_377_ate_param = block:
# BLS Miller loop is parametrized by u
BigInt[64+1].fromHex("0x8508c00000000001") # +1 so that we can take *3 and NAF encode it
const BLS12_377_ate_param_isNeg = false
const BLS12_381_ate_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_ate_param_isNeg = true
# Generic slow pairing implementation
# Generic pairing implementation
# ----------------------------------------------------------------
const BLS12_377_finalexponent = block:
# (p^12 - 1) / r
# BigInt[4269].fromHex"0x1b2ff68c1abdc48ab4f04ed12cc8f9b2f161b41c7eb8865b9ad3c9bb0571dd94c6bde66548dc13624d9d741024ceb315f46a89cc2482605eb6afc6d8977e5e2ccbec348dd362d59ec2b5bc62a1b467ae44572215548abc98bb4193886ed89cceaedd0221aba84fb33e5584ac29619a87a00c315178155496857c995eab4a8a9af95f4015db27955ae408d6927d0ab37d52f3917c4ddec88f8159f7bcba7eb65f1aae4eeb4e70cb20227159c08a7fdfea9b62bb308918eac3202569dd1bcdd86b431e3646356fc3fb79f89b30775e006993adb629586b6c874b7688f86f11ef7ad94a40eb020da3c532b317232fa56dc564637b331a8e8832eab84269f00b506602c8594b7f7da5a5d8d851fff6ab1d38a354fc8e0b8958e2a9e5ce2d7e50ec36d761d9505fe5e1f317257e2df2952fcd4c93b85278c20488b4ccaee94db3fec1ce8283473e4b493843fa73abe99af8bafce29170b2b863b9513b5a47312991f60c5a4f6872b5d574212bf00d797c0bea3c0f7dfd748e63679fda9b1c50f2df74de38f38e004ae0df997a10db31d209cacbf58ba0678bfe7cd0985bc43258d72d8d5106c21635ae1e527eb01fca3032d50d97756ec9ee756eaba7f21652a808a4e2539e838ef7ec4b178b29e3b976c46bd0ecdd32c1fb75e6e0aef2d8b5661f595a98023f3520381aba8da6cce785dbb0a0bba025478d75ee749619cdb7c42a21098ece86a00c6c2046c1e00000063c69000000000000"
# (p^12 - 1) / r * 3
BigInt[4271].fromHex"0x518fe3a450394da01ed0ec73865aed18d4251c557c299312d07b5d31105598be5439b32fda943a26e8d85c306e6c1941dd3f9d646d87211c240f5489c67b1a8663c49da97a2880dc48213527e51d370acd05663ffda035ca31c4ba994c89d66c0c97066502f8ef19bb008e047c24cf96e02493f4683ffdc39075cc1c01df9fd0ec1dc0419176c010ac1a83b777201a77f8dab474e99c59ae840de7362f7c231d500aecc1eb52616067540d419f7f9fbfd22831919b4ac04960703d9753698941c95aa2d2a04f4bf26de9d191661a013cbb09227c09424595e2639ae94d35ce708bdec2c10628eb4f981945698ef049502d2a71994fab9898c028c73dd021f13208590be27e78f0f18a88f5ffe40157a9e9fef5aa229c0aa7fdb16a887af2c4a486258bf11fb1a5d945707a89d7bf8f67e5bb28f76a460d9a1e660cbbe91bfc456b8789d5bae1dba8cbef5b03bcd0ea30f6a7b45218292b2bf3b20ed5937cb5e2250eee395821805c6383d0286c7423beb42e79f85dab2a36df8fd154f2d89e5e9aaadaaa00e0a29ecc6e329195761d6063e0a2e136a3fb7671c9134c970a8588a7f3144642a10a5af77c105f5e90987f28c6604c5dcb604c02f7d642f7f819eea6fadb8aace7c4e146a17dab2c644d4372c6979845f261b4a20cd88a20325e0c0fc806bd9f60a8502fa8f466b6919311e232e06fd6a861cb5dc24d69274c7e631cac6b93e0254460d445a0000012b53b000000000000"
const BLS12_381_finalexponent = block:
# (p^12 - 1) / r
# BigInt[4314].fromHex"0x2ee1db5dcc825b7e1bda9c0496a1c0a89ee0193d4977b3f7d4507d07363baa13f8d14a917848517badc3a43d1073776ab353f2c30698e8cc7deada9c0aadff5e9cfee9a074e43b9a660835cc872ee83ff3a0f0f1c0ad0d6106feaf4e347aa68ad49466fa927e7bb9375331807a0dce2630d9aa4b113f414386b0e8819328148978e2b0dd39099b86e1ab656d2670d93e4d7acdd350da5359bc73ab61a0c5bf24c374693c49f570bcd2b01f3077ffb10bf24dde41064837f27611212596bc293c8d4c01f25118790f4684d0b9c40a68eb74bb22a40ee7169cdc1041296532fef459f12438dfc8e2886ef965e61a474c5c85b0129127a1b5ad0463434724538411d1676a53b5a62eb34c05739334f46c02c3f0bd0c55d3109cd15948d0a1fad20044ce6ad4c6bec3ec03ef19592004cedd556952c6d8823b19dadd7c2498345c6e5308f1c511291097db60b1749bf9b71a9f9e0100418a3ef0bc627751bbd81367066bca6a4c1b6dcfc5cceb73fc56947a403577dfa9e13c24ea820b09c1d9f7c31759c3635de3f7a3639991708e88adce88177456c49637fd7961be1a4c7e79fb02faa732e2f3ec2bea83d196283313492caa9d4aff1c910e9622d2a73f62537f2701aaef6539314043f7bbce5b78c7869aeb2181a67e49eeed2161daf3f881bd88592d767f67c4717489119226c2f011d4cab803e9d71650a6f80698e2f8491d12191a04406fbc8fbd5f48925f98630e68bfb24c0bcb9b55df57510"
# (p^12 - 1) / r * 3
BigInt[4316].fromHex"0x8ca592196587127a538fd40dc3e541f9dca04bb7dc671be77cf17715a2b2fe3bea73dfb468d8f473094aecb7315a664019fbd84913caba6579c08fd42009fe1bd6fcbce15eacb2cf3218a165958cb8bfdae2d2d54207282314fc0dea9d6ff3a07dbd34efb77b732ba5f994816e296a72928cfee133bdc3ca9412b984b9783d9c6aa81297ab1cd294a502304773528bbae8706979f28efa0d355b0224e2513d6e4a5d3bb4dde0523678105d9167ff1323d6e99ac312d8a7d762336370c4347bb5a7e405d6f3496b2dd38e722d4c1f3ac25e3167ec2cb543d69430c37c2f98fcdd0dd36caa9f5aa7994cec31b24ed5e515911037b376e521070d29c9d56cfa8c3574363efb20f28c19e4105ab99edd44084bd23725017931d6740bda71e5f07600ce6b407e543c4bc40bcd4c0b600e6c98003bf8548986b14d9098746dc89d154af91ad54f337b31c79222145dd3ed254fdeda0300c49ebcd2352765f533883a3513435f3ee452496f5166c25bf503bd6ec0a0679efda3b46ebf86211d458de749460d4a2a19abe6ea2accb451ab9a096b98465d044dc2a7f86c253a4ee57b6df108eff598a8dbc483bf8b74c2789939db85ffd7e0fd55b32bc26877f5be26fa7d750500ce2fab93c0cbe7336b126a5693d0c16484f37addccc7642590dbe98538990b88637e374d545d9b34b67448d0357e60280bbd8542f1f4e813caa8e8db57364b4e0cc14f35af381dd9b71ec9292b3a3f16e42362d2019e05f30"
{.experimental: "dynamicBindSym".}
macro get(C: static Curve, value: untyped): untyped =
return bindSym($C & "_" & $value)
func millerLoopGenericBLS12*[C: static Curve](
func millerLoopGenericBLS12*[C](
f: var Fp12[C],
P: ECP_SWei_Aff[Fp[C]],
Q: ECP_SWei_Aff[Fp2[C]]
@ -129,8 +95,8 @@ func millerLoopGenericBLS12*[C: static Curve](
else:
f.mul_sparse_by_line_xy000z(line)
template u: untyped = C.get(ate_param)
let u3 = 3*C.get(ate_param)
template u: untyped = C.pairing(ate_param)
let u3 = 3*C.pairing(ate_param)
for i in countdown(u3.bits - 2, 1):
f.square()
line.line_double(T, P)
@ -145,7 +111,7 @@ func millerLoopGenericBLS12*[C: static Curve](
line.line_add(T, nQ, P)
f.mul(line)
when C.get(ate_param_isNeg):
when C.pairing(ate_param_isNeg):
# In GT, x^-1 == conjugate(x)
# Remark 7.1, chapter 7.1.1 of Guide to Pairing-Based Cryptography, El Mrabet, 2017
f.conj()
@ -153,7 +119,7 @@ func millerLoopGenericBLS12*[C: static Curve](
func finalExpGeneric[C: static Curve](f: var Fp12[C]) =
## A generic and slow implementation of final exponentiation
## for sanity checks purposes.
f.powUnsafeExponent(C.get(finalexponent), window = 3)
f.powUnsafeExponent(C.pairing(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
@ -171,66 +137,7 @@ func pairing_bls12_reference*[C](gt: var Fp12[C], P: ECP_SWei_Proj[Fp[C]], Q: EC
# Optimized pairing implementation
# ----------------------------------------------------------------
func cycl_sqr_repeated(f: var Fp12, num: int) =
## Repeated cyclotomic squarings
for _ in 0 ..< num:
f.cyclotomic_square()
func pow_xdiv2(r: var Fp12[BLS12_381], a: Fp12[BLS12_381], invert = BLS12_381_ate_param_isNeg) =
## f^(x/2) with x the curve parameter
## For BLS12_381 f^-0xd201000000010000
r.cyclotomic_square(a)
r *= a
r.cycl_sqr_repeated(2)
r *= a
r.cycl_sqr_repeated(3)
r *= a
r.cycl_sqr_repeated(9)
r *= a
r.cycl_sqr_repeated(32) # TODO: use Karabina?
r *= a
r.cycl_sqr_repeated(16-1) # Don't do the last iteration
if invert:
r.cyclotomic_inv()
func pow_x(r: var Fp12[BLS12_381], a: Fp12[BLS12_381], invert = BLS12_381_ate_param_isNeg) =
## f^x with x the curve parameter
## For BLS12_381 f^-0xd201000000010000
r.pow_xdiv2(a, invert)
r.cyclotomic_square()
func pow_x(r: var Fp12[BLS12_377], a: Fp12[BLS12_377], invert = BLS12_377_ate_param_isNeg) =
## f^x with x the curve parameter
## For BLS12_377 f^-0x8508c00000000001
## Warning: The parameter is odd and needs a correction
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)
r *= a
if invert:
r.cyclotomic_inv()
func finalExpHard_BLS12*[C: static Curve](f: var Fp12[C]) =
func finalExpHard_BLS12*[C](f: var Fp12[C]) =
## Hard part of the final exponentiation
## Specialized for BLS12 curves
##
@ -259,7 +166,7 @@ func finalExpHard_BLS12*[C: static Curve](f: var Fp12[C]) =
v2.cyclotomic_square(f) # v2 = f²
# (x1)²
when C.get(ate_param).isEven.bool:
when C.pairing(ate_param).isEven.bool:
v0.pow_xdiv2(v2) # v0 = (f²)^(x/2) = f^x
else:
v0.pow_x(f)

View File

@ -7,10 +7,7 @@
# at your option. This file may not be copied, modified, or distributed except according to those terms.
import
std/macros,
../primitives,
../config/[common, curves],
../arithmetic,
../config/[curves, type_fp],
../towers,
../io/io_bigints,
../elliptic/[
@ -20,7 +17,8 @@ import
./lines_projective,
./mul_fp12_by_lines,
./cyclotomic_fp12,
../isogeny/frobenius
../isogeny/frobenius,
../curves/zoo_pairings
# ############################################################
#
@ -42,37 +40,10 @@ import
# Craig Costello, Tanja Lange, and Michael Naehrig, 2009
# https://eprint.iacr.org/2009/615.pdf
# TODO: should be part of curve parameters
# The bit count must be exact for the Miller loop
const BN254_Snarks_ate_param = block:
# BN Miller loop is parametrized by 6u+2
BigInt[65+2].fromHex"0x19d797039be763ba8"
const BN254_Snarks_ate_param_isNeg = false
const BN254_Nogami_ate_param = block:
# BN Miller loop is parametrized by 6u+2
BigInt[65+2].fromHex"0x18300000000000004" # 65+2 bit for NAF x3 encoding
const BN254_Nogami_ate_param_isNeg = true
# Generic slow pairing implementation
# Generic pairing implementation
# ----------------------------------------------------------------
const BN254_Snarks_finalexponent = block:
# (p^12 - 1) / r
BigInt[2790].fromHex"0x2f4b6dc97020fddadf107d20bc842d43bf6369b1ff6a1c71015f3f7be2e1e30a73bb94fec0daf15466b2383a5d3ec3d15ad524d8f70c54efee1bd8c3b21377e563a09a1b705887e72eceaddea3790364a61f676baaf977870e88d5c6c8fef0781361e443ae77f5b63a2a2264487f2940a8b1ddb3d15062cd0fb2015dfc6668449aed3cc48a82d0d602d268c7daab6a41294c0cc4ebe5664568dfc50e1648a45a4a1e3a5195846a3ed011a337a02088ec80e0ebae8755cfe107acf3aafb40494e406f804216bb10cf430b0f37856b42db8dc5514724ee93dfb10826f0dd4a0364b9580291d2cd65664814fde37ca80bb4ea44eacc5e641bbadf423f9a2cbf813b8d145da90029baee7ddadda71c7f3811c4105262945bba1668c3be69a3c230974d83561841d766f9c9d570bb7fbe04c7e8a6c3c760c0de81def35692da361102b6b9b2b918837fa97896e84abb40a4efb7e54523a486964b64ca86f120"
const BN254_Nogami_finalexponent = block:
# (p^12 - 1) / r
BigInt[2786].fromHex"0x2928fbb36b391596ee3fe4cbe857330da83e46fedf04d235a4a8daf5ff9f6eabcb4e3f20aa06f0a0d96b24f9af0cbbce750d61627dcbf5fec9139b8f1c46c86b49b4f8a202af26e4504f2c0f56570e9bd5b94c403f385d1908556486e24b396ddc2cdf13d06542f84fe8e82ccbad7b7423fc1ef4e8cc73d605e3e867c0a75f45ea7f6356d9846ce35d5a34f30396938818ad41914b97b99c289a7259b5d2e09477a77bd3c409b19f19e893f8ade90b0aed1b5fc8a07a3cebb41d4e9eee96b21a832ddb1e93e113edfb704fa532848c18593cd0ee90444a1b3499a800177ea38bdec62ec5191f2b6bbee449722f98d2173ad33077545c2ad10347e125a56fb40f086e9a4e62ad336a72c8b202ac3c1473d73b93d93dc0795ca0ca39226e7b4c1bb92f99248ec0806e0ad70744e9f2238736790f5185ea4c70808442a7d530c6ccd56b55a6973867ec6c73599bbd020bbe105da9c6b5c009ad8946cd6f0"
{.experimental: "dynamicBindSym".}
macro get(C: static Curve, value: untyped): untyped =
return bindSym($C & "_" & $value)
func millerLoopGenericBN*[C: static Curve](
func millerLoopGenericBN*[C](
f: var Fp12[C],
P: ECP_SWei_Aff[Fp[C]],
Q: ECP_SWei_Aff[Fp2[C]]
@ -123,8 +94,8 @@ func millerLoopGenericBN*[C: static Curve](
else:
f.mul_sparse_by_line_xy000z(line)
template u: untyped = C.get(ate_param)
let u3 = 3*C.get(ate_param)
template u: untyped = C.pairing(ate_param)
let u3 = 3*C.pairing(ate_param)
for i in countdown(u3.bits - 2, 1):
f.square()
line.line_double(T, P)
@ -138,13 +109,13 @@ func millerLoopGenericBN*[C: static Curve](
line.line_add(T, nQ, P)
f.mul(line)
when C.get(ate_param_isNeg):
when C.pairing(ate_param_isNeg):
# In GT, x^-1 == conjugate(x)
# Remark 7.1, chapter 7.1.1 of Guide to Pairing-Based Cryptography, El Mrabet, 2017
f.conj()
# Ate pairing for BN curves need adjustment after Miller loop
when C.get(ate_param_isNeg):
when C.pairing(ate_param_isNeg):
T.neg()
var V {.noInit.}: typeof(Q)
@ -160,7 +131,7 @@ func millerLoopGenericBN*[C: static Curve](
func finalExpGeneric[C: static Curve](f: var Fp12[C]) =
## A generic and slow implementation of final exponentiation
## for sanity checks purposes.
f.powUnsafeExponent(C.get(finalexponent), window = 3)
f.powUnsafeExponent(C.pairing(finalexponent), window = 3)
func pairing_bn_reference*[C](gt: var Fp12[C], P: ECP_SWei_Proj[Fp[C]], Q: ECP_SWei_Proj[Fp2[C]]) =
## Compute the optimal Ate Pairing for BN curves
@ -178,106 +149,6 @@ func pairing_bn_reference*[C](gt: var Fp12[C], P: ECP_SWei_Proj[Fp[C]], Q: ECP_S
# Optimized pairing implementation
# ----------------------------------------------------------------
func cycl_sqr_repeated(f: var Fp12, num: int) =
## Repeated cyclotomic squarings
for _ in 0 ..< num:
f.cyclotomic_square()
func pow_u(r: var Fp12[BN254_Nogami], a: Fp12[BN254_Nogami], invert = BN254_Nogami_ate_param_isNeg) =
## f^u with u the curve parameter
## For BN254_Nogami f^-0x4080000000000001
r = a
r.cycl_sqr_repeated(7)
r *= a
r.cycl_sqr_repeated(55)
r *= a
if invert:
r.cyclotomic_inv()
func pow_u(r: var Fp12[BN254_Snarks], a: Fp12[BN254_Snarks], invert = BN254_Snarks_ate_param_isNeg) =
## f^u with u the curve parameter
## For BN254_Snarks f^0x44e992b44a6909f1
when false:
cyclotomic_exp(
r, a,
BigInt[63].fromHex("0x44e992b44a6909f1"),
invert
)
else:
var # Hopefully the compiler optimizes away unused Fp12
# because those are huge
x10 {.noInit.}: Fp12[BN254_Snarks]
x11 {.noInit.}: Fp12[BN254_Snarks]
x100 {.noInit.}: Fp12[BN254_Snarks]
x110 {.noInit.}: Fp12[BN254_Snarks]
x1100 {.noInit.}: Fp12[BN254_Snarks]
x1111 {.noInit.}: Fp12[BN254_Snarks]
x10010 {.noInit.}: Fp12[BN254_Snarks]
x10110 {.noInit.}: Fp12[BN254_Snarks]
x11100 {.noInit.}: Fp12[BN254_Snarks]
x101110 {.noInit.}: Fp12[BN254_Snarks]
x1001010 {.noInit.}: Fp12[BN254_Snarks]
x1111000 {.noInit.}: Fp12[BN254_Snarks]
x10001110 {.noInit.}: Fp12[BN254_Snarks]
x10 .cyclotomic_square(a)
x11 .prod(x10, a)
x100 .prod(x11, a)
x110 .prod(x10, x100)
x1100 .cyclotomic_square(x110)
x1111 .prod(x11, x1100)
x10010 .prod(x11, x1111)
x10110 .prod(x100, x10010)
x11100 .prod(x110, x10110)
x101110 .prod(x10010, x11100)
x1001010 .prod(x11100, x101110)
x1111000 .prod(x101110, x1001010)
x10001110 .prod(x10110, x1111000)
var
i15 {.noInit.}: Fp12[BN254_Snarks]
i16 {.noInit.}: Fp12[BN254_Snarks]
i17 {.noInit.}: Fp12[BN254_Snarks]
i18 {.noInit.}: Fp12[BN254_Snarks]
i20 {.noInit.}: Fp12[BN254_Snarks]
i21 {.noInit.}: Fp12[BN254_Snarks]
i22 {.noInit.}: Fp12[BN254_Snarks]
i26 {.noInit.}: Fp12[BN254_Snarks]
i27 {.noInit.}: Fp12[BN254_Snarks]
i61 {.noInit.}: Fp12[BN254_Snarks]
i15.cyclotomic_square(x10001110)
i15 *= x1001010
i16.prod(x10001110, i15)
i17.prod(x1111, i16)
i18.prod(i16, i17)
i20.cyclotomic_square(i18)
i20 *= i17
i21.prod(x1111000, i20)
i22.prod(i15, i21)
i26.cyclotomic_square(i22)
i26.cyclotomic_square()
i26 *= i22
i26 *= i18
i27.prod(i22, i26)
i61.prod(i26, i27)
i61.cycl_sqr_repeated(17)
i61 *= i27
i61.cycl_sqr_repeated(14)
i61 *= i21
r = i61
r.cycl_sqr_repeated(16)
r *= i20
if invert:
r.cyclotomic_inv()
func finalExpHard_BN*[C: static Curve](f: var Fp12[C]) =
## Hard part of the final exponentiation
## Specialized for BN curves
@ -302,7 +173,7 @@ func finalExpHard_BN*[C: static Curve](f: var Fp12[C]) =
t1 *= t0 # t1 = f^6|u|
t2.pow_u(t1, invert = false) # t2 = f^6u²
if C.get(ate_param_is_Neg):
if C.pairing(ate_param_is_Neg):
t3.cyclotomic_inv(t1) # t3 = f^6u
else:
t3 = t1 # t3 = f^6u
@ -311,7 +182,7 @@ func finalExpHard_BN*[C: static Curve](f: var Fp12[C]) =
t4.pow_u(t3) # t4 = f^12u³
t4 *= t1 # t4 = f^(6u + 6u² + 12u³) = f^λ₂
if not C.get(ate_param_is_Neg):
if not C.pairing(ate_param_is_Neg):
t0.cyclotomic_inv() # t0 = f^-2u
t3.prod(t4, t0) # t3 = f^(4u + 6u² + 12u³)

View File

@ -10,7 +10,7 @@ import std/unittest,
../constantine/config/common,
../constantine/arithmetic,
../constantine/config/curves,
../constantine/curves/constants_glv
../constantine/curves/zoo_glv
echo "\n------------------------------------------------------\n"