Files
mev-beta/vendor/github.com/consensys/gnark-crypto/ecc/bls12-381/bls12-381.go

166 lines
6.0 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
// Package bls12381 efficient elliptic curve, pairing and hash to curve implementation for bls12-381.
//
// bls12-381: A Barreto--Lynn--Scott curve
//
// embedding degree k=12
// seed x₀=-15132376222941642752
// 𝔽r: r=52435875175126190479447740508185965837690552500527637822603658699938581184513 (x₀⁴-x₀²+1)
// 𝔽p: p=4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787 ((x₀-1)² ⋅ r(x₀)/3+x₀)
// (E/𝔽p): Y²=X³+4
// (Eₜ/𝔽p²): Y² = X³+4(u+1) (M-type twist)
// r #E(Fp) and r #Eₜ(𝔽p²)
//
// Extension fields tower:
//
// 𝔽p²[u] = 𝔽p/u²+1
// 𝔽p⁶[v] = 𝔽p²/v³-1-u
// 𝔽p¹²[w] = 𝔽p⁶/w²-v
//
// optimal Ate loop size:
//
// x₀
//
// Security: estimated 126-bit level following [https://eprint.iacr.org/2019/885.pdf]
// (r is 255 bits and p¹² is 4569 bits)
//
// # Warning
//
// This code has been partially audited and is provided as-is. In particular, there is no security guarantees such as constant time implementation or side-channel attack resistance.
package bls12381
import (
"math/big"
"github.com/consensys/gnark-crypto/ecc"
"github.com/consensys/gnark-crypto/ecc/bls12-381/fp"
"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
"github.com/consensys/gnark-crypto/ecc/bls12-381/internal/fptower"
)
// ID bls381 ID
const ID = ecc.BLS12_381
// aCurveCoeff is the a coefficients of the curve Y²=X³+ax+b
var aCurveCoeff fp.Element
var bCurveCoeff fp.Element
// twist
var twist fptower.E2
// bTwistCurveCoeff b coeff of the twist (defined over 𝔽p²) curve
var bTwistCurveCoeff fptower.E2
// generators of the r-torsion group, resp. in ker(pi-id), ker(Tr)
var g1Gen G1Jac
var g2Gen G2Jac
var g1GenAff G1Affine
var g2GenAff G2Affine
// point at infinity
var g1Infinity G1Jac
var g2Infinity G2Jac
// optimal Ate loop counter
var LoopCounter [64]int8
// Parameters useful for the GLV scalar multiplication. The third roots define the
// endomorphisms ϕ₁ and ϕ₂ for <G1Affine> and <G2Affine>. lambda is such that <r, ϕ-λ> lies above
// <r> in the ring Z[ϕ]. More concretely it's the associated eigenvalue
// of ϕ₁ (resp ϕ₂) restricted to <G1Affine> (resp <G2Affine>)
// see https://link.springer.com/content/pdf/10.1007/3-540-36492-7_3
var thirdRootOneG1 fp.Element
var thirdRootOneG2 fp.Element
var lambdaGLV big.Int
// glvBasis stores R-linearly independent vectors (a,b), (c,d)
// in ker((u,v) → u+vλ[r]), and their determinant
var glvBasis ecc.Lattice
// g1ScalarMulChoose and g2ScalarmulChoose indicate the bitlength of the scalar
// in scalar multiplication from which it is more efficient to use the GLV
// decomposition. It is computed from the GLV basis and considers the overhead
// for the GLV decomposition. It is heuristic and may change in the future.
var g1ScalarMulChoose, g2ScalarMulChoose int
// ψ o π o ψ^{-1}, where ψ:E → E' is the degree 6 iso defined over 𝔽p¹²
var endo struct {
u fptower.E2
v fptower.E2
}
// seed x₀ of the curve
var xGen big.Int
// 𝔽
type E2 = fptower.E2
// 𝔽p⁶
type E6 = fptower.E6
// 𝔽p¹²
type E12 = fptower.E12
func init() {
aCurveCoeff.SetUint64(0)
bCurveCoeff.SetUint64(4)
// M-twist
twist.A0.SetUint64(1)
twist.A1.SetUint64(1)
bTwistCurveCoeff.MulByElement(&twist, &bCurveCoeff)
g1Gen.X.SetString("3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507")
g1Gen.Y.SetString("1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569")
g1Gen.Z.SetOne()
g2Gen.X.SetString("352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160",
"3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758")
g2Gen.Y.SetString("1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905",
"927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582")
g2Gen.Z.SetString("1",
"0")
g1GenAff.FromJacobian(&g1Gen)
g2GenAff.FromJacobian(&g2Gen)
// (X,Y,Z) = (1,1,0)
g1Infinity.X.SetOne()
g1Infinity.Y.SetOne()
g2Infinity.X.SetOne()
g2Infinity.Y.SetOne()
thirdRootOneG1.SetString("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436")
thirdRootOneG2.Square(&thirdRootOneG1)
lambdaGLV.SetString("228988810152649578064853576960394133503", 10) //(x₀²-1)
_r := fr.Modulus()
ecc.PrecomputeLattice(_r, &lambdaGLV, &glvBasis)
g1ScalarMulChoose = fr.Bits/16 + max(glvBasis.V1[0].BitLen(), glvBasis.V1[1].BitLen(), glvBasis.V2[0].BitLen(), glvBasis.V2[1].BitLen())
g2ScalarMulChoose = fr.Bits/32 + max(glvBasis.V1[0].BitLen(), glvBasis.V1[1].BitLen(), glvBasis.V2[0].BitLen(), glvBasis.V2[1].BitLen())
endo.u.A0.SetString("0")
endo.u.A1.SetString("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437")
endo.v.A0.SetString("2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530")
endo.v.A1.SetString("1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257")
// binary decomposition of -x₀ little endian
LoopCounter = [64]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1}
// -x₀
xGen.SetString("15132376222941642752", 10)
}
// Generators return the generators of the r-torsion group, resp. in ker(pi-id), ker(Tr)
func Generators() (g1Jac G1Jac, g2Jac G2Jac, g1Aff G1Affine, g2Aff G2Affine) {
g1Aff = g1GenAff
g2Aff = g2GenAff
g1Jac = g1Gen
g2Jac = g2Gen
return
}
// CurveCoefficients returns the a, b coefficients of the curve equation.
func CurveCoefficients() (a, b fp.Element) {
return aCurveCoeff, bCurveCoeff
}