mirror of
https://github.com/logos-storage/constantine.git
synced 2026-01-07 07:33:08 +00:00
Move GLV constants
This commit is contained in:
parent
e676e06959
commit
34eb6fcfbd
66
constantine/curves/bls12_377_glv.nim
Normal file
66
constantine/curves/bls12_377_glv.nim
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# 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/type_bigint,
|
||||||
|
../io/io_bigints
|
||||||
|
|
||||||
|
# BLS12-377 G1
|
||||||
|
# ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const Lattice_BLS12_377_G1* = (
|
||||||
|
# (BigInt, isNeg)
|
||||||
|
((BigInt[127].fromHex"0x452217cc900000010a11800000000000", false), # u² - 1
|
||||||
|
(BigInt[1].fromHex"0x1", true)), # -1
|
||||||
|
((BigInt[1].fromHex"0x1", false), # 1
|
||||||
|
(BigInt[127].fromHex"0x452217cc900000010a11800000000001", false)) # u²
|
||||||
|
)
|
||||||
|
|
||||||
|
const Babai_BLS12_377_G1* = (
|
||||||
|
# Vector for Babai rounding
|
||||||
|
# (BigInt, isNeg)
|
||||||
|
(BigInt[130].fromHex"0x3b3f7aa969fd371607f72ed32af90182c", false),
|
||||||
|
(BigInt[4].fromHex"0xd", false)
|
||||||
|
)
|
||||||
|
|
||||||
|
# BLS12-377 G2
|
||||||
|
# ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const Lattice_BLS12_377_G2* = (
|
||||||
|
# Curve of order 254 -> mini scalars of size 65
|
||||||
|
# x = -0xd201000000010000
|
||||||
|
# Value, isNeg
|
||||||
|
((BigInt[64].fromHex"0x8508c00000000001", true), # -x
|
||||||
|
(BigInt[1].fromHex"0x1", false), # 1
|
||||||
|
(BigInt[1].fromHex"0x0", false), # 0
|
||||||
|
(BigInt[1].fromHex"0x0", false)), # 0
|
||||||
|
|
||||||
|
((BigInt[1].fromHex"0x0", false), # 0
|
||||||
|
(BigInt[64].fromHex"0x8508c00000000001", true), # -x
|
||||||
|
(BigInt[1].fromHex"0x1", false), # 1
|
||||||
|
(BigInt[1].fromHex"0x0", false)), # 0
|
||||||
|
|
||||||
|
((BigInt[1].fromHex"0x0", false), # 0
|
||||||
|
(BigInt[1].fromHex"0x0", false), # 0
|
||||||
|
(BigInt[64].fromHex"0x8508c00000000001", true), # -x
|
||||||
|
(BigInt[1].fromHex"0x1", false)), # 1
|
||||||
|
|
||||||
|
((BigInt[1].fromHex"0x1", false), # 1
|
||||||
|
(BigInt[1].fromHex"0x0", false), # 0
|
||||||
|
(BigInt[1].fromHex"0x1", true), # -1
|
||||||
|
(BigInt[64].fromHex"0x8508c00000000001", true)) # -x
|
||||||
|
)
|
||||||
|
|
||||||
|
const Babai_BLS12_377_G2* = (
|
||||||
|
# Vector for Babai rounding
|
||||||
|
# Value, isNeg
|
||||||
|
(BigInt[193].fromHex"0x1eca0125755aed064f63abaff9084ce152979759b442f60d1", true),
|
||||||
|
(BigInt[130].fromHex"0x3b3f7aa969fd371607f72ed32af90181f", true),
|
||||||
|
(BigInt[67].fromhex"0x72030ba8ee9c06415", true),
|
||||||
|
(BigInt[1].fromhex"0x0", false)
|
||||||
|
)
|
||||||
66
constantine/curves/bls12_381_glv.nim
Normal file
66
constantine/curves/bls12_381_glv.nim
Normal file
@ -0,0 +1,66 @@
|
|||||||
|
# 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/type_bigint,
|
||||||
|
../io/io_bigints
|
||||||
|
|
||||||
|
# BLS12-381 G1
|
||||||
|
# ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const Lattice_BLS12_381_G1* = (
|
||||||
|
# (BigInt, isNeg)
|
||||||
|
((BigInt[128].fromHex"0xac45a4010001a40200000000ffffffff", false), # u² - 1
|
||||||
|
(BigInt[1].fromHex"0x1", true)), # -1
|
||||||
|
((BigInt[1].fromHex"0x1", false), # 1
|
||||||
|
(BigInt[128].fromHex"0xac45a4010001a4020000000100000000", false)) # u²
|
||||||
|
)
|
||||||
|
|
||||||
|
const Babai_BLS12_381_G1* = (
|
||||||
|
# Vector for Babai rounding
|
||||||
|
# (BigInt, isNeg)
|
||||||
|
(BigInt[129].fromHex"0x17c6becf1e01faadd63f6e522f6cfee30", false),
|
||||||
|
(BigInt[2].fromHex"0x2", false)
|
||||||
|
)
|
||||||
|
|
||||||
|
# BLS12-381 G2
|
||||||
|
# ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const Lattice_BLS12_381_G2* = (
|
||||||
|
# Curve of order 254 -> mini scalars of size 65
|
||||||
|
# x = -0xd201000000010000
|
||||||
|
# Value, isNeg
|
||||||
|
((BigInt[64].fromHex"0xd201000000010000", false), # -x
|
||||||
|
(BigInt[1].fromHex"0x1", false), # 1
|
||||||
|
(BigInt[1].fromHex"0x0", false), # 0
|
||||||
|
(BigInt[1].fromHex"0x0", false)), # 0
|
||||||
|
|
||||||
|
((BigInt[1].fromHex"0x0", false), # 0
|
||||||
|
(BigInt[64].fromHex"0xd201000000010000", false), # -x
|
||||||
|
(BigInt[1].fromHex"0x1", false), # 1
|
||||||
|
(BigInt[1].fromHex"0x0", false)), # 0
|
||||||
|
|
||||||
|
((BigInt[1].fromHex"0x0", false), # 0
|
||||||
|
(BigInt[1].fromHex"0x0", false), # 0
|
||||||
|
(BigInt[64].fromHex"0xd201000000010000", false), # -x
|
||||||
|
(BigInt[1].fromHex"0x1", false)), # 1
|
||||||
|
|
||||||
|
((BigInt[1].fromHex"0x1", false), # 1
|
||||||
|
(BigInt[1].fromHex"0x0", false), # 0
|
||||||
|
(BigInt[1].fromHex"0x1", true), # -1
|
||||||
|
(BigInt[64].fromHex"0xd201000000010000", false)) # -x
|
||||||
|
)
|
||||||
|
|
||||||
|
const Babai_BLS12_381_G2* = (
|
||||||
|
# Vector for Babai rounding
|
||||||
|
# Value, isNeg
|
||||||
|
(BigInt[193].fromHex"0x1381204ca56cd56b533cfcc0d3e76ec2892078a5e8573b29c", false),
|
||||||
|
(BigInt[129].fromHex"0x17c6becf1e01faadd63f6e522f6cfee2f", true),
|
||||||
|
(BigInt[65].fromhex"0x1cfbe4f7bd0027db0", false),
|
||||||
|
(BigInt[1].fromhex"0x0", false)
|
||||||
|
)
|
||||||
69
constantine/curves/bn254_snarks_glv.nim
Normal file
69
constantine/curves/bn254_snarks_glv.nim
Normal file
@ -0,0 +1,69 @@
|
|||||||
|
# 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/type_bigint,
|
||||||
|
../io/io_bigints
|
||||||
|
|
||||||
|
# BN254 Snarks G1
|
||||||
|
# ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
# Chapter 6.3.1 - Guide to Pairing-based Cryptography
|
||||||
|
const Lattice_BN254_Snarks_G1* = (
|
||||||
|
# Curve of order 254 -> mini scalars of size 127
|
||||||
|
# u = 0x44E992B44A6909F1
|
||||||
|
# (BigInt, isNeg)
|
||||||
|
((BigInt[64].fromHex"0x89d3256894d213e3", false), # 2u + 1
|
||||||
|
(BigInt[127].fromHex"0x6f4d8248eeb859fd0be4e1541221250b", false)), # 6u² + 4u + 1
|
||||||
|
((BigInt[127].fromHex"0x6f4d8248eeb859fc8211bbeb7d4f1128", false), # 6u² + 2u
|
||||||
|
(BigInt[64].fromHex"0x89d3256894d213e3", true)) # -2u - 1
|
||||||
|
)
|
||||||
|
|
||||||
|
const Babai_BN254_Snarks_G1* = (
|
||||||
|
# Vector for Babai rounding
|
||||||
|
# (BigInt, isNeg)
|
||||||
|
(BigInt[66].fromHex"0x2d91d232ec7e0b3d7", false), # (2u + 1) << 2^256 // r
|
||||||
|
(BigInt[130].fromHex"0x24ccef014a773d2d25398fd0300ff6565", false) # (6u² + 4u + 1) << 2^256 // r
|
||||||
|
)
|
||||||
|
|
||||||
|
# BN254 Snarks G2
|
||||||
|
# ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
const Lattice_BN254_Snarks_G2* = (
|
||||||
|
# Curve of order 254 -> mini scalars of size 65
|
||||||
|
# x = 0x44E992B44A6909F1
|
||||||
|
# Value, isNeg
|
||||||
|
((BigInt[63].fromHex"0x44e992b44a6909f2", false), # x+1
|
||||||
|
(BigInt[63].fromHex"0x44e992b44a6909f1", false), # x
|
||||||
|
(BigInt[63].fromHex"0x44e992b44a6909f1", false), # x
|
||||||
|
(BigInt[64].fromHex"0x89d3256894d213e2", true)), # -2x
|
||||||
|
|
||||||
|
((BigInt[64].fromHex"0x89d3256894d213e3", false), # 2x+1
|
||||||
|
(BigInt[63].fromHex"0x44e992b44a6909f1", true), # -x
|
||||||
|
(BigInt[63].fromHex"0x44e992b44a6909f2", true), # -x-1
|
||||||
|
(BigInt[63].fromHex"0x44e992b44a6909f1", true)), # -x
|
||||||
|
|
||||||
|
((BigInt[64].fromHex"0x89d3256894d213e2", false), # 2x
|
||||||
|
(BigInt[64].fromHex"0x89d3256894d213e3", false), # 2x+1
|
||||||
|
(BigInt[64].fromHex"0x89d3256894d213e3", false), # 2x+1
|
||||||
|
(BigInt[64].fromHex"0x89d3256894d213e3", false)), # 2x+1
|
||||||
|
|
||||||
|
((BigInt[63].fromHex"0x44e992b44a6909f0", false), # x-1
|
||||||
|
(BigInt[65].fromHex"0x113a64ad129a427c6", false), # 4x+2
|
||||||
|
(BigInt[64].fromHex"0x89d3256894d213e1", true), # -2x+1
|
||||||
|
(BigInt[63].fromHex"0x44e992b44a6909f0", false)), # x-1
|
||||||
|
)
|
||||||
|
|
||||||
|
const Babai_BN254_Snarks_G2* = (
|
||||||
|
# Vector for Babai rounding
|
||||||
|
# Value, isNeg
|
||||||
|
(BigInt[128].fromHex"0xc444fab18d269b9dd0cb46fd51906254", false), # 2x²+3x+1 << 2^256 // r
|
||||||
|
(BigInt[193].fromHex"0x13d00631561b2572922df9f942d7d77c7001378f5ee78976d", false), # 3x³+8x²+x << 2^256 // r
|
||||||
|
(BigInt[192].fromhex"0x9e80318ab0d92b94916fcfca16bebbe436510546a93478ab", false), # 6x³+4x²+x << 2^256 // r
|
||||||
|
(BigInt[128].fromhex"0xc444fab18d269b9af7ae23ce89afae7d", true) # -2x²-x << 2^256 // r
|
||||||
|
)
|
||||||
31
constantine/curves/constants_glv.nim
Normal file
31
constantine/curves/constants_glv.nim
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# 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, type_fp],
|
||||||
|
../towers,
|
||||||
|
./bls12_377_glv,
|
||||||
|
./bls12_381_glv,
|
||||||
|
# ./bn254_nogami_glv,
|
||||||
|
./bn254_snarks_glv
|
||||||
|
|
||||||
|
{.experimental: "dynamicBindSym".}
|
||||||
|
|
||||||
|
macro dispatch(prefix: static string, C: static Curve, G: static string): untyped =
|
||||||
|
result = bindSym(prefix & $C & "_" & G)
|
||||||
|
|
||||||
|
template babai*(F: typedesc[Fp or Fp2]): untyped =
|
||||||
|
const G = if F is Fp: "G1"
|
||||||
|
else: "G2"
|
||||||
|
dispatch("Babai_", F.C, G)
|
||||||
|
|
||||||
|
template lattice*(F: typedesc[Fp or Fp2]): untyped =
|
||||||
|
const G = if F is Fp: "G1"
|
||||||
|
else: "G2"
|
||||||
|
dispatch("Lattice_", F.C, G)
|
||||||
@ -117,6 +117,12 @@ We use the complete addition law from Bos2014 for Jacobian coordinates, note tha
|
|||||||
https://eprint.iacr.org/2014/130
|
https://eprint.iacr.org/2014/130
|
||||||
https://www.imsc.res.in/~ecc14/slides/costello.pdf
|
https://www.imsc.res.in/~ecc14/slides/costello.pdf
|
||||||
|
|
||||||
|
- Efficient and Secure Algorithms for GLV-Based Scalar\
|
||||||
|
Multiplication and their Implementation\
|
||||||
|
on GLV-GLSCurves (Extended Version)\
|
||||||
|
Armando Faz-Hernández, Patrick Longa, Ana H. Sánchez, 2013\
|
||||||
|
https://eprint.iacr.org/2013/158.pdf
|
||||||
|
|
||||||
- Remote Timing Attacks are Still Practical\
|
- Remote Timing Attacks are Still Practical\
|
||||||
Billy Bob Brumley and Nicola Tuveri\
|
Billy Bob Brumley and Nicola Tuveri\
|
||||||
https://eprint.iacr.org/2011/232
|
https://eprint.iacr.org/2011/232
|
||||||
|
|||||||
@ -12,13 +12,13 @@ import
|
|||||||
# Internal
|
# Internal
|
||||||
../primitives,
|
../primitives,
|
||||||
../config/[common, curves, type_bigint],
|
../config/[common, curves, type_bigint],
|
||||||
|
../curves/constants_glv,
|
||||||
../arithmetic,
|
../arithmetic,
|
||||||
../io/io_bigints,
|
../io/io_bigints,
|
||||||
../towers,
|
../towers,
|
||||||
../isogeny/frobenius,
|
../isogeny/frobenius,
|
||||||
./ec_weierstrass_affine,
|
./ec_weierstrass_affine,
|
||||||
./ec_weierstrass_projective,
|
./ec_weierstrass_projective
|
||||||
./ec_endomorphism_params
|
|
||||||
|
|
||||||
# ############################################################
|
# ############################################################
|
||||||
#
|
#
|
||||||
@ -33,6 +33,84 @@ import
|
|||||||
# - GLV and GLS endomorphisms on G2 (Galbraith-Lin-Scott)
|
# - GLV and GLS endomorphisms on G2 (Galbraith-Lin-Scott)
|
||||||
# - NAF recoding (windowed Non-Adjacent-Form)
|
# - NAF recoding (windowed Non-Adjacent-Form)
|
||||||
|
|
||||||
|
# Decomposition into scalars -> miniscalars
|
||||||
|
# ----------------------------------------------------------------------------------------
|
||||||
|
|
||||||
|
type
|
||||||
|
MultiScalar[M, LengthInBits: static int] = array[M, BigInt[LengthInBits]]
|
||||||
|
## Decomposition of a secret scalar in multiple scalars
|
||||||
|
|
||||||
|
func decomposeEndo*[M, scalBits, L: static int](
|
||||||
|
miniScalars: var MultiScalar[M, L],
|
||||||
|
scalar: BigInt[scalBits],
|
||||||
|
F: typedesc[Fp or Fp2]
|
||||||
|
) =
|
||||||
|
## Decompose a secret scalar into M mini-scalars
|
||||||
|
## using a curve endomorphism(s) characteristics.
|
||||||
|
##
|
||||||
|
## A scalar decomposition might lead to negative miniscalar(s).
|
||||||
|
## For proper handling it requires either:
|
||||||
|
## 1. Negating it and then negating the corresponding curve point P
|
||||||
|
## 2. Adding an extra bit to the recoding, which will do the right thing™
|
||||||
|
##
|
||||||
|
## For implementation solution 1 is faster:
|
||||||
|
## - Double + Add is about 5000~8000 cycles on 6 64-bits limbs (BLS12-381)
|
||||||
|
## - Conditional negate is about 10 cycles per Fp, on G2 projective we have 3 (coords) * 2 (Fp2) * 10 (cycles) ~= 60 cycles
|
||||||
|
## We need to test the mini scalar, which is 65 bits so 2 Fp so about 2 cycles
|
||||||
|
## and negate it as well.
|
||||||
|
##
|
||||||
|
## However solution 1 seems to cause issues (TODO)
|
||||||
|
## with some of the BLS12-381 test cases (6 and 9)
|
||||||
|
## - 0x5668a2332db27199dcfb7cbdfca6317c2ff128db26d7df68483e0a095ec8e88f
|
||||||
|
## - 0x644dc62869683f0c93f38eaef2ba6912569dc91ec2806e46b4a3dd6a4421dad1
|
||||||
|
|
||||||
|
# Equal when no window or no negative handling, greater otherwise
|
||||||
|
static: doAssert L >= (scalBits + M - 1) div M + 1
|
||||||
|
const w = F.C.getCurveOrderBitwidth().wordsRequired()
|
||||||
|
|
||||||
|
when F is Fp:
|
||||||
|
var alphas{.noInit.}: (
|
||||||
|
BigInt[scalBits + babai(F)[0][0].bits],
|
||||||
|
BigInt[scalBits + babai(F)[1][0].bits]
|
||||||
|
)
|
||||||
|
else:
|
||||||
|
var alphas{.noInit.}: (
|
||||||
|
BigInt[scalBits + babai(F)[0][0].bits],
|
||||||
|
BigInt[scalBits + babai(F)[1][0].bits],
|
||||||
|
BigInt[scalBits + babai(F)[2][0].bits],
|
||||||
|
BigInt[scalBits + babai(F)[3][0].bits]
|
||||||
|
)
|
||||||
|
|
||||||
|
staticFor i, 0, M:
|
||||||
|
when bool babai(F)[i][0].isZero():
|
||||||
|
alphas[i].setZero()
|
||||||
|
else:
|
||||||
|
alphas[i].prod_high_words(babai(F)[i][0], scalar, w)
|
||||||
|
when babai(F)[i][1]:
|
||||||
|
# prod_high_words works like logical right shift
|
||||||
|
# When negative, we should add 1 to properly round toward -infinity
|
||||||
|
alphas[i] += SecretWord(1)
|
||||||
|
|
||||||
|
# We have k0 = s - 𝛼0 b00 - 𝛼1 b10 ... - 𝛼m bm0
|
||||||
|
# and kj = 0 - 𝛼j b0j - 𝛼1 b1j ... - 𝛼m bmj
|
||||||
|
var
|
||||||
|
k: array[M, BigInt[scalBits]] # zero-init required
|
||||||
|
alphaB {.noInit.}: BigInt[scalBits]
|
||||||
|
k[0] = scalar
|
||||||
|
staticFor miniScalarIdx, 0, M:
|
||||||
|
staticFor basisIdx, 0, M:
|
||||||
|
when not bool lattice(F)[basisIdx][miniScalarIdx][0].isZero():
|
||||||
|
when bool lattice(F)[basisIdx][miniScalarIdx][0].isOne():
|
||||||
|
alphaB.copyTruncatedFrom(alphas[basisIdx])
|
||||||
|
else:
|
||||||
|
alphaB.prod(alphas[basisIdx], lattice(F)[basisIdx][miniScalarIdx][0])
|
||||||
|
|
||||||
|
when lattice(F)[basisIdx][miniScalarIdx][1] xor babai(F)[basisIdx][1]:
|
||||||
|
k[miniScalarIdx] += alphaB
|
||||||
|
else:
|
||||||
|
k[miniScalarIdx] -= alphaB
|
||||||
|
|
||||||
|
miniScalars[miniScalarIdx].copyTruncatedFrom(k[miniScalarIdx])
|
||||||
|
|
||||||
# Secret scalar + dynamic point
|
# Secret scalar + dynamic point
|
||||||
# ----------------------------------------------------------------
|
# ----------------------------------------------------------------
|
||||||
|
|||||||
@ -1,289 +0,0 @@
|
|||||||
# 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,
|
|
||||||
# Internal
|
|
||||||
../primitives,
|
|
||||||
../config/[common, curves, type_bigint],
|
|
||||||
../arithmetic,
|
|
||||||
../io/io_bigints,
|
|
||||||
../towers,
|
|
||||||
./ec_weierstrass_projective
|
|
||||||
|
|
||||||
# ############################################################
|
|
||||||
#
|
|
||||||
# Endomorphism acceleration decomposition parameters
|
|
||||||
# for Scalar Multiplication
|
|
||||||
#
|
|
||||||
# ############################################################
|
|
||||||
#
|
|
||||||
# TODO: cleanup, those should be derived in the config folder
|
|
||||||
# and stored in a constant
|
|
||||||
# or generated from sage into a config file read at compile-time
|
|
||||||
|
|
||||||
type
|
|
||||||
MultiScalar*[M, LengthInBits: static int] = array[M, BigInt[LengthInBits]]
|
|
||||||
## Decomposition of a secret scalar in multiple scalars
|
|
||||||
|
|
||||||
# BN254 Snarks G1
|
|
||||||
# ----------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
# Chapter 6.3.1 - Guide to Pairing-based Cryptography
|
|
||||||
const Lattice_BN254_Snarks_G1 = (
|
|
||||||
# Curve of order 254 -> mini scalars of size 127
|
|
||||||
# u = 0x44E992B44A6909F1
|
|
||||||
# (BigInt, isNeg)
|
|
||||||
((BigInt[64].fromHex"0x89d3256894d213e3", false), # 2u + 1
|
|
||||||
(BigInt[127].fromHex"0x6f4d8248eeb859fd0be4e1541221250b", false)), # 6u² + 4u + 1
|
|
||||||
((BigInt[127].fromHex"0x6f4d8248eeb859fc8211bbeb7d4f1128", false), # 6u² + 2u
|
|
||||||
(BigInt[64].fromHex"0x89d3256894d213e3", true)) # -2u - 1
|
|
||||||
)
|
|
||||||
|
|
||||||
const Babai_BN254_Snarks_G1 = (
|
|
||||||
# Vector for Babai rounding
|
|
||||||
# (BigInt, isNeg)
|
|
||||||
(BigInt[66].fromHex"0x2d91d232ec7e0b3d7", false), # (2u + 1) << 2^256 // r
|
|
||||||
(BigInt[130].fromHex"0x24ccef014a773d2d25398fd0300ff6565", false) # (6u² + 4u + 1) << 2^256 // r
|
|
||||||
)
|
|
||||||
|
|
||||||
# BLS12-377 G1
|
|
||||||
# ----------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
const Lattice_BLS12_377_G1 = (
|
|
||||||
# (BigInt, isNeg)
|
|
||||||
((BigInt[127].fromHex"0x452217cc900000010a11800000000000", false), # u² - 1
|
|
||||||
(BigInt[1].fromHex"0x1", true)), # -1
|
|
||||||
((BigInt[1].fromHex"0x1", false), # 1
|
|
||||||
(BigInt[127].fromHex"0x452217cc900000010a11800000000001", false)) # u²
|
|
||||||
)
|
|
||||||
|
|
||||||
const Babai_BLS12_377_G1 = (
|
|
||||||
# Vector for Babai rounding
|
|
||||||
# (BigInt, isNeg)
|
|
||||||
(BigInt[130].fromHex"0x3b3f7aa969fd371607f72ed32af90182c", false),
|
|
||||||
(BigInt[4].fromHex"0xd", false)
|
|
||||||
)
|
|
||||||
|
|
||||||
# BLS12-381 G1
|
|
||||||
# ----------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
const Lattice_BLS12_381_G1 = (
|
|
||||||
# (BigInt, isNeg)
|
|
||||||
((BigInt[128].fromHex"0xac45a4010001a40200000000ffffffff", false), # u² - 1
|
|
||||||
(BigInt[1].fromHex"0x1", true)), # -1
|
|
||||||
((BigInt[1].fromHex"0x1", false), # 1
|
|
||||||
(BigInt[128].fromHex"0xac45a4010001a4020000000100000000", false)) # u²
|
|
||||||
)
|
|
||||||
|
|
||||||
const Babai_BLS12_381_G1 = (
|
|
||||||
# Vector for Babai rounding
|
|
||||||
# (BigInt, isNeg)
|
|
||||||
(BigInt[129].fromHex"0x17c6becf1e01faadd63f6e522f6cfee30", false),
|
|
||||||
(BigInt[2].fromHex"0x2", false)
|
|
||||||
)
|
|
||||||
|
|
||||||
# BN254 Snarks G2
|
|
||||||
# ----------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
const Lattice_BN254_Snarks_G2 = (
|
|
||||||
# Curve of order 254 -> mini scalars of size 65
|
|
||||||
# x = 0x44E992B44A6909F1
|
|
||||||
# Value, isNeg
|
|
||||||
((BigInt[63].fromHex"0x44e992b44a6909f2", false), # x+1
|
|
||||||
(BigInt[63].fromHex"0x44e992b44a6909f1", false), # x
|
|
||||||
(BigInt[63].fromHex"0x44e992b44a6909f1", false), # x
|
|
||||||
(BigInt[64].fromHex"0x89d3256894d213e2", true)), # -2x
|
|
||||||
|
|
||||||
((BigInt[64].fromHex"0x89d3256894d213e3", false), # 2x+1
|
|
||||||
(BigInt[63].fromHex"0x44e992b44a6909f1", true), # -x
|
|
||||||
(BigInt[63].fromHex"0x44e992b44a6909f2", true), # -x-1
|
|
||||||
(BigInt[63].fromHex"0x44e992b44a6909f1", true)), # -x
|
|
||||||
|
|
||||||
((BigInt[64].fromHex"0x89d3256894d213e2", false), # 2x
|
|
||||||
(BigInt[64].fromHex"0x89d3256894d213e3", false), # 2x+1
|
|
||||||
(BigInt[64].fromHex"0x89d3256894d213e3", false), # 2x+1
|
|
||||||
(BigInt[64].fromHex"0x89d3256894d213e3", false)), # 2x+1
|
|
||||||
|
|
||||||
((BigInt[63].fromHex"0x44e992b44a6909f0", false), # x-1
|
|
||||||
(BigInt[65].fromHex"0x113a64ad129a427c6", false), # 4x+2
|
|
||||||
(BigInt[64].fromHex"0x89d3256894d213e1", true), # -2x+1
|
|
||||||
(BigInt[63].fromHex"0x44e992b44a6909f0", false)), # x-1
|
|
||||||
)
|
|
||||||
|
|
||||||
const Babai_BN254_Snarks_G2 = (
|
|
||||||
# Vector for Babai rounding
|
|
||||||
# Value, isNeg
|
|
||||||
(BigInt[128].fromHex"0xc444fab18d269b9dd0cb46fd51906254", false), # 2x²+3x+1 << 2^256 // r
|
|
||||||
(BigInt[193].fromHex"0x13d00631561b2572922df9f942d7d77c7001378f5ee78976d", false), # 3x³+8x²+x << 2^256 // r
|
|
||||||
(BigInt[192].fromhex"0x9e80318ab0d92b94916fcfca16bebbe436510546a93478ab", false), # 6x³+4x²+x << 2^256 // r
|
|
||||||
(BigInt[128].fromhex"0xc444fab18d269b9af7ae23ce89afae7d", true) # -2x²-x << 2^256 // r
|
|
||||||
)
|
|
||||||
|
|
||||||
# BLS12-377 G2
|
|
||||||
# ----------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
const Lattice_BLS12_377_G2 = (
|
|
||||||
# Curve of order 254 -> mini scalars of size 65
|
|
||||||
# x = -0xd201000000010000
|
|
||||||
# Value, isNeg
|
|
||||||
((BigInt[64].fromHex"0x8508c00000000001", true), # -x
|
|
||||||
(BigInt[1].fromHex"0x1", false), # 1
|
|
||||||
(BigInt[1].fromHex"0x0", false), # 0
|
|
||||||
(BigInt[1].fromHex"0x0", false)), # 0
|
|
||||||
|
|
||||||
((BigInt[1].fromHex"0x0", false), # 0
|
|
||||||
(BigInt[64].fromHex"0x8508c00000000001", true), # -x
|
|
||||||
(BigInt[1].fromHex"0x1", false), # 1
|
|
||||||
(BigInt[1].fromHex"0x0", false)), # 0
|
|
||||||
|
|
||||||
((BigInt[1].fromHex"0x0", false), # 0
|
|
||||||
(BigInt[1].fromHex"0x0", false), # 0
|
|
||||||
(BigInt[64].fromHex"0x8508c00000000001", true), # -x
|
|
||||||
(BigInt[1].fromHex"0x1", false)), # 1
|
|
||||||
|
|
||||||
((BigInt[1].fromHex"0x1", false), # 1
|
|
||||||
(BigInt[1].fromHex"0x0", false), # 0
|
|
||||||
(BigInt[1].fromHex"0x1", true), # -1
|
|
||||||
(BigInt[64].fromHex"0x8508c00000000001", true)) # -x
|
|
||||||
)
|
|
||||||
|
|
||||||
const Babai_BLS12_377_G2 = (
|
|
||||||
# Vector for Babai rounding
|
|
||||||
# Value, isNeg
|
|
||||||
(BigInt[193].fromHex"0x1eca0125755aed064f63abaff9084ce152979759b442f60d1", true),
|
|
||||||
(BigInt[130].fromHex"0x3b3f7aa969fd371607f72ed32af90181f", true),
|
|
||||||
(BigInt[67].fromhex"0x72030ba8ee9c06415", true),
|
|
||||||
(BigInt[1].fromhex"0x0", false)
|
|
||||||
)
|
|
||||||
|
|
||||||
# BLS12-381 G2
|
|
||||||
# ----------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
const Lattice_BLS12_381_G2 = (
|
|
||||||
# Curve of order 254 -> mini scalars of size 65
|
|
||||||
# x = -0xd201000000010000
|
|
||||||
# Value, isNeg
|
|
||||||
((BigInt[64].fromHex"0xd201000000010000", false), # -x
|
|
||||||
(BigInt[1].fromHex"0x1", false), # 1
|
|
||||||
(BigInt[1].fromHex"0x0", false), # 0
|
|
||||||
(BigInt[1].fromHex"0x0", false)), # 0
|
|
||||||
|
|
||||||
((BigInt[1].fromHex"0x0", false), # 0
|
|
||||||
(BigInt[64].fromHex"0xd201000000010000", false), # -x
|
|
||||||
(BigInt[1].fromHex"0x1", false), # 1
|
|
||||||
(BigInt[1].fromHex"0x0", false)), # 0
|
|
||||||
|
|
||||||
((BigInt[1].fromHex"0x0", false), # 0
|
|
||||||
(BigInt[1].fromHex"0x0", false), # 0
|
|
||||||
(BigInt[64].fromHex"0xd201000000010000", false), # -x
|
|
||||||
(BigInt[1].fromHex"0x1", false)), # 1
|
|
||||||
|
|
||||||
((BigInt[1].fromHex"0x1", false), # 1
|
|
||||||
(BigInt[1].fromHex"0x0", false), # 0
|
|
||||||
(BigInt[1].fromHex"0x1", true), # -1
|
|
||||||
(BigInt[64].fromHex"0xd201000000010000", false)) # -x
|
|
||||||
)
|
|
||||||
|
|
||||||
const Babai_BLS12_381_G2 = (
|
|
||||||
# Vector for Babai rounding
|
|
||||||
# Value, isNeg
|
|
||||||
(BigInt[193].fromHex"0x1381204ca56cd56b533cfcc0d3e76ec2892078a5e8573b29c", false),
|
|
||||||
(BigInt[129].fromHex"0x17c6becf1e01faadd63f6e522f6cfee2f", true),
|
|
||||||
(BigInt[65].fromhex"0x1cfbe4f7bd0027db0", false),
|
|
||||||
(BigInt[1].fromhex"0x0", false)
|
|
||||||
)
|
|
||||||
|
|
||||||
# Decomposition routine
|
|
||||||
# ----------------------------------------------------------------------------------------
|
|
||||||
|
|
||||||
{.experimental: "dynamicbindsym".}
|
|
||||||
macro dispatch(prefix: static string, C: static Curve, G: static string): untyped =
|
|
||||||
result = bindSym(prefix & $C & "_" & G)
|
|
||||||
|
|
||||||
template babai(F: typedesc[Fp or Fp2]): untyped =
|
|
||||||
const G = if F is Fp: "G1"
|
|
||||||
else: "G2"
|
|
||||||
dispatch("Babai_", F.C, G)
|
|
||||||
|
|
||||||
template lattice(F: typedesc[Fp or Fp2]): untyped =
|
|
||||||
const G = if F is Fp: "G1"
|
|
||||||
else: "G2"
|
|
||||||
dispatch("Lattice_", F.C, G)
|
|
||||||
|
|
||||||
func decomposeEndo*[M, scalBits, L: static int](
|
|
||||||
miniScalars: var MultiScalar[M, L],
|
|
||||||
scalar: BigInt[scalBits],
|
|
||||||
F: typedesc[Fp or Fp2]
|
|
||||||
) =
|
|
||||||
## Decompose a secret scalar into M mini-scalars
|
|
||||||
## using a curve endomorphism(s) characteristics.
|
|
||||||
##
|
|
||||||
## A scalar decomposition might lead to negative miniscalar(s).
|
|
||||||
## For proper handling it requires either:
|
|
||||||
## 1. Negating it and then negating the corresponding curve point P
|
|
||||||
## 2. Adding an extra bit to the recoding, which will do the right thing™
|
|
||||||
##
|
|
||||||
## For implementation solution 1 is faster:
|
|
||||||
## - Double + Add is about 5000~8000 cycles on 6 64-bits limbs (BLS12-381)
|
|
||||||
## - Conditional negate is about 10 cycles per Fp, on G2 projective we have 3 (coords) * 2 (Fp2) * 10 (cycles) ~= 60 cycles
|
|
||||||
## We need to test the mini scalar, which is 65 bits so 2 Fp so about 2 cycles
|
|
||||||
## and negate it as well.
|
|
||||||
##
|
|
||||||
## However solution 1 seems to cause issues (TODO)
|
|
||||||
## with some of the BLS12-381 test cases (6 and 9)
|
|
||||||
## - 0x5668a2332db27199dcfb7cbdfca6317c2ff128db26d7df68483e0a095ec8e88f
|
|
||||||
## - 0x644dc62869683f0c93f38eaef2ba6912569dc91ec2806e46b4a3dd6a4421dad1
|
|
||||||
|
|
||||||
# Equal when no window or no negative handling, greater otherwise
|
|
||||||
static: doAssert L >= (scalBits + M - 1) div M + 1
|
|
||||||
const w = F.C.getCurveOrderBitwidth().wordsRequired()
|
|
||||||
|
|
||||||
when F is Fp:
|
|
||||||
var alphas{.noInit.}: (
|
|
||||||
BigInt[scalBits + babai(F)[0][0].bits],
|
|
||||||
BigInt[scalBits + babai(F)[1][0].bits]
|
|
||||||
)
|
|
||||||
else:
|
|
||||||
var alphas{.noInit.}: (
|
|
||||||
BigInt[scalBits + babai(F)[0][0].bits],
|
|
||||||
BigInt[scalBits + babai(F)[1][0].bits],
|
|
||||||
BigInt[scalBits + babai(F)[2][0].bits],
|
|
||||||
BigInt[scalBits + babai(F)[3][0].bits]
|
|
||||||
)
|
|
||||||
|
|
||||||
staticFor i, 0, M:
|
|
||||||
when bool babai(F)[i][0].isZero():
|
|
||||||
alphas[i].setZero()
|
|
||||||
else:
|
|
||||||
alphas[i].prod_high_words(babai(F)[i][0], scalar, w)
|
|
||||||
when babai(F)[i][1]:
|
|
||||||
# prod_high_words works like logical right shift
|
|
||||||
# When negative, we should add 1 to properly round toward -infinity
|
|
||||||
alphas[i] += SecretWord(1)
|
|
||||||
|
|
||||||
# We have k0 = s - 𝛼0 b00 - 𝛼1 b10 ... - 𝛼m bm0
|
|
||||||
# and kj = 0 - 𝛼j b0j - 𝛼1 b1j ... - 𝛼m bmj
|
|
||||||
var
|
|
||||||
k: array[M, BigInt[scalBits]] # zero-init required
|
|
||||||
alphaB {.noInit.}: BigInt[scalBits]
|
|
||||||
k[0] = scalar
|
|
||||||
staticFor miniScalarIdx, 0, M:
|
|
||||||
staticFor basisIdx, 0, M:
|
|
||||||
when not bool lattice(F)[basisIdx][miniScalarIdx][0].isZero():
|
|
||||||
when bool lattice(F)[basisIdx][miniScalarIdx][0].isOne():
|
|
||||||
alphaB.copyTruncatedFrom(alphas[basisIdx])
|
|
||||||
else:
|
|
||||||
alphaB.prod(alphas[basisIdx], lattice(F)[basisIdx][miniScalarIdx][0])
|
|
||||||
|
|
||||||
when lattice(F)[basisIdx][miniScalarIdx][1] xor babai(F)[basisIdx][1]:
|
|
||||||
k[miniScalarIdx] += alphaB
|
|
||||||
else:
|
|
||||||
k[miniScalarIdx] -= alphaB
|
|
||||||
|
|
||||||
miniScalars[miniScalarIdx].copyTruncatedFrom(k[miniScalarIdx])
|
|
||||||
@ -8,7 +8,6 @@
|
|||||||
|
|
||||||
import
|
import
|
||||||
std/macros,
|
std/macros,
|
||||||
../config/curves,
|
|
||||||
../arithmetic,
|
../arithmetic,
|
||||||
../towers,
|
../towers,
|
||||||
../curves/constants_frobenius
|
../curves/constants_frobenius
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user