github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-381/bls12-381.go (about) 1 // Package bls12381 efficient elliptic curve, pairing and hash to curve implementation for bls12-381. 2 // 3 // bls12-381: A Barreto--Lynn--Scott curve 4 // 5 // embedding degree k=12 6 // seed x₀=-15132376222941642752 7 // 𝔽r: r=52435875175126190479447740508185965837690552500527637822603658699938581184513 (x₀⁴-x₀²+1) 8 // 𝔽p: p=4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787 ((x₀-1)² ⋅ r(x₀)/3+x₀) 9 // (E/𝔽p): Y²=X³+4 10 // (Eₜ/𝔽p²): Y² = X³+4(u+1) (M-type twist) 11 // r ∣ #E(Fp) and r ∣ #Eₜ(𝔽p²) 12 // 13 // Extension fields tower: 14 // 15 // 𝔽p²[u] = 𝔽p/u²+1 16 // 𝔽p⁶[v] = 𝔽p²/v³-1-u 17 // 𝔽p¹²[w] = 𝔽p⁶/w²-v 18 // 19 // optimal Ate loop size: 20 // 21 // x₀ 22 // 23 // Security: estimated 126-bit level following [https://eprint.iacr.org/2019/885.pdf] 24 // (r is 255 bits and p¹² is 4569 bits) 25 // 26 // # Warning 27 // 28 // 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. 29 package bls12381 30 31 import ( 32 "math/big" 33 34 "github.com/consensys/gnark-crypto/ecc" 35 "github.com/consensys/gnark-crypto/ecc/bls12-381/fp" 36 "github.com/consensys/gnark-crypto/ecc/bls12-381/fr" 37 "github.com/consensys/gnark-crypto/ecc/bls12-381/internal/fptower" 38 ) 39 40 // ID bls381 ID 41 const ID = ecc.BLS12_381 42 43 // aCurveCoeff is the a coefficients of the curve Y²=X³+ax+b 44 var aCurveCoeff fp.Element 45 var bCurveCoeff fp.Element 46 47 // twist 48 var twist fptower.E2 49 50 // bTwistCurveCoeff b coeff of the twist (defined over 𝔽p²) curve 51 var bTwistCurveCoeff fptower.E2 52 53 // generators of the r-torsion group, resp. in ker(pi-id), ker(Tr) 54 var g1Gen G1Jac 55 var g2Gen G2Jac 56 57 var g1GenAff G1Affine 58 var g2GenAff G2Affine 59 60 // point at infinity 61 var g1Infinity G1Jac 62 var g2Infinity G2Jac 63 64 // optimal Ate loop counter 65 var LoopCounter [64]int8 66 67 // Parameters useful for the GLV scalar multiplication. The third roots define the 68 // endomorphisms ϕ₁ and ϕ₂ for <G1Affine> and <G2Affine>. lambda is such that <r, ϕ-λ> lies above 69 // <r> in the ring Z[ϕ]. More concretely it's the associated eigenvalue 70 // of ϕ₁ (resp ϕ₂) restricted to <G1Affine> (resp <G2Affine>) 71 // see https://www.cosic.esat.kuleuven.be/nessie/reports/phase2/GLV.pdf 72 var thirdRootOneG1 fp.Element 73 var thirdRootOneG2 fp.Element 74 var lambdaGLV big.Int 75 76 // glvBasis stores R-linearly independent vectors (a,b), (c,d) 77 // in ker((u,v) → u+vλ[r]), and their determinant 78 var glvBasis ecc.Lattice 79 80 // ψ o π o ψ^{-1}, where ψ:E → E' is the degree 6 iso defined over 𝔽p¹² 81 var endo struct { 82 u fptower.E2 83 v fptower.E2 84 } 85 86 // seed x₀ of the curve 87 var xGen big.Int 88 89 // 𝔽p² 90 type E2 = fptower.E2 91 92 // 𝔽p⁶ 93 type E6 = fptower.E6 94 95 // 𝔽p¹² 96 type E12 = fptower.E12 97 98 func init() { 99 aCurveCoeff.SetUint64(0) 100 bCurveCoeff.SetUint64(4) 101 // M-twist 102 twist.A0.SetUint64(1) 103 twist.A1.SetUint64(1) 104 bTwistCurveCoeff.MulByElement(&twist, &bCurveCoeff) 105 106 g1Gen.X.SetString("3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507") 107 g1Gen.Y.SetString("1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569") 108 g1Gen.Z.SetOne() 109 110 g2Gen.X.SetString("352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160", 111 "3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758") 112 g2Gen.Y.SetString("1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905", 113 "927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582") 114 g2Gen.Z.SetString("1", 115 "0") 116 117 g1GenAff.FromJacobian(&g1Gen) 118 g2GenAff.FromJacobian(&g2Gen) 119 120 // (X,Y,Z) = (1,1,0) 121 g1Infinity.X.SetOne() 122 g1Infinity.Y.SetOne() 123 g2Infinity.X.SetOne() 124 g2Infinity.Y.SetOne() 125 126 thirdRootOneG1.SetString("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436") 127 thirdRootOneG2.Square(&thirdRootOneG1) 128 lambdaGLV.SetString("228988810152649578064853576960394133503", 10) //(x₀²-1) 129 _r := fr.Modulus() 130 ecc.PrecomputeLattice(_r, &lambdaGLV, &glvBasis) 131 132 endo.u.A0.SetString("0") 133 endo.u.A1.SetString("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437") 134 endo.v.A0.SetString("2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530") 135 endo.v.A1.SetString("1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257") 136 137 // binary decomposition of -x₀ little endian 138 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} 139 140 // -x₀ 141 xGen.SetString("15132376222941642752", 10) 142 143 } 144 145 // Generators return the generators of the r-torsion group, resp. in ker(pi-id), ker(Tr) 146 func Generators() (g1Jac G1Jac, g2Jac G2Jac, g1Aff G1Affine, g2Aff G2Affine) { 147 g1Aff = g1GenAff 148 g2Aff = g2GenAff 149 g1Jac = g1Gen 150 g2Jac = g2Gen 151 return 152 } 153 154 // CurveCoefficients returns the a, b coefficients of the curve equation. 155 func CurveCoefficients() (a, b fp.Element) { 156 return aCurveCoeff, bCurveCoeff 157 }