github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-377/bls12-377.go (about) 1 // Package bls12377 efficient elliptic curve, pairing and hash to curve implementation for bls12-377. 2 // 3 // bls12-377: A Barreto--Lynn--Scott curve with 4 // 5 // embedding degree k=12 6 // seed x₀=9586122913090633729 7 // 𝔽r: r=8444461749428370424248824938781546531375899335154063827935233455917409239041 (x₀⁴-x₀²+1) 8 // 𝔽p: p=258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177 ((x₀-1)² ⋅ r(x₀)/3+x₀) 9 // (E/𝔽p): Y²=X³+1 10 // (Eₜ/𝔽p²): Y² = X³+1/u (D-type twist) 11 // r ∣ #E(Fp) and r ∣ #Eₜ(𝔽p²) 12 // 13 // Extension fields tower: 14 // 15 // 𝔽p²[u] = 𝔽p/u²+5 16 // 𝔽p⁶[v] = 𝔽p²/v³-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 253 bits and p¹² is 4521 bits) 25 // 26 // # Warning 27 // 28 // This code has not been 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 bls12377 30 31 import ( 32 "math/big" 33 34 "github.com/consensys/gnark-crypto/ecc" 35 "github.com/consensys/gnark-crypto/ecc/bls12-377/fp" 36 "github.com/consensys/gnark-crypto/ecc/bls12-377/fr" 37 "github.com/consensys/gnark-crypto/ecc/bls12-377/internal/fptower" 38 ) 39 40 // ID bls377 ID 41 const ID = ecc.BLS12_377 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 ψ⁻¹, 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 // expose the tower -- github.com/consensys/gnark uses it in a gnark circuit 90 91 // 𝔽p² 92 type E2 = fptower.E2 93 94 // 𝔽p⁶ 95 type E6 = fptower.E6 96 97 // 𝔽p¹² 98 type E12 = fptower.E12 99 100 func init() { 101 aCurveCoeff.SetUint64(0) 102 bCurveCoeff.SetUint64(1) 103 // D-twist 104 twist.A1.SetUint64(1) 105 bTwistCurveCoeff.Inverse(&twist) 106 107 g1Gen.X.SetString("81937999373150964239938255573465948239988671502647976594219695644855304257327692006745978603320413799295628339695") 108 g1Gen.Y.SetString("241266749859715473739788878240585681733927191168601896383759122102112907357779751001206799952863815012735208165030") 109 g1Gen.Z.SetOne() 110 111 g2Gen.X.SetString("233578398248691099356572568220835526895379068987715365179118596935057653620464273615301663571204657964920925606294", 112 "140913150380207355837477652521042157274541796891053068589147167627541651775299824604154852141315666357241556069118") 113 g2Gen.Y.SetString("63160294768292073209381361943935198908131692476676907196754037919244929611450776219210369229519898517858833747423", 114 "149157405641012693445398062341192467754805999074082136895788947234480009303640899064710353187729182149407503257491") 115 g2Gen.Z.SetString("1", 116 "0") 117 118 g1GenAff.FromJacobian(&g1Gen) 119 g2GenAff.FromJacobian(&g2Gen) 120 121 // (X,Y,Z) = (1,1,0) 122 g1Infinity.X.SetOne() 123 g1Infinity.Y.SetOne() 124 g2Infinity.X.SetOne() 125 g2Infinity.Y.SetOne() 126 127 thirdRootOneG1.SetString("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945") 128 thirdRootOneG2.Square(&thirdRootOneG1) 129 lambdaGLV.SetString("91893752504881257701523279626832445440", 10) //(x₀²-1) 130 _r := fr.Modulus() 131 ecc.PrecomputeLattice(_r, &lambdaGLV, &glvBasis) 132 133 endo.u.A0.SetString("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410946") 134 endo.v.A0.SetString("216465761340224619389371505802605247630151569547285782856803747159100223055385581585702401816380679166954762214499") 135 136 // binary decomposition of x₀ little endian 137 LoopCounter = [64]int8{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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 0, 0, 0, 0, 1} 138 139 // x₀ 140 xGen.SetString("9586122913090633729", 10) 141 142 } 143 144 // Generators return the generators of the r-torsion group, resp. in ker(pi-id), ker(Tr) 145 func Generators() (g1Jac G1Jac, g2Jac G2Jac, g1Aff G1Affine, g2Aff G2Affine) { 146 g1Aff = g1GenAff 147 g2Aff = g2GenAff 148 g1Jac = g1Gen 149 g2Jac = g2Gen 150 return 151 } 152 153 // CurveCoefficients returns the a, b coefficients of the curve equation. 154 func CurveCoefficients() (a, b fp.Element) { 155 return aCurveCoeff, bCurveCoeff 156 }