Move GLV constants
This commit is contained in:
parent
e676e06959
commit
34eb6fcfbd
|
@ -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)
|
||||
)
|
|
@ -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)
|
||||
)
|
|
@ -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
|
||||
)
|
|
@ -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://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\
|
||||
Billy Bob Brumley and Nicola Tuveri\
|
||||
https://eprint.iacr.org/2011/232
|
||||
|
|
|
@ -12,13 +12,13 @@ import
|
|||
# Internal
|
||||
../primitives,
|
||||
../config/[common, curves, type_bigint],
|
||||
../curves/constants_glv,
|
||||
../arithmetic,
|
||||
../io/io_bigints,
|
||||
../towers,
|
||||
../isogeny/frobenius,
|
||||
./ec_weierstrass_affine,
|
||||
./ec_weierstrass_projective,
|
||||
./ec_endomorphism_params
|
||||
./ec_weierstrass_projective
|
||||
|
||||
# ############################################################
|
||||
#
|
||||
|
@ -33,6 +33,84 @@ import
|
|||
# - GLV and GLS endomorphisms on G2 (Galbraith-Lin-Scott)
|
||||
# - 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
|
||||
# ----------------------------------------------------------------
|
||||
|
|
|
@ -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
|
||||
std/macros,
|
||||
../config/curves,
|
||||
../arithmetic,
|
||||
../towers,
|
||||
../curves/constants_frobenius
|
||||
|
|
Loading…
Reference in New Issue