github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-378/bls12-378.go (about) 1 // Package bls12378 efficient elliptic curve, pairing and hash to curve implementation for bls12-378. 2 // 3 // bls12-378: A Barreto--Lynn--Scott curve 4 // 5 // embedding degree k=12 6 // seed x₀=11045256207009841153 7 // 𝔽r: r=14883435066912132899950318861128167269793560281114003360875131245101026639873 (x₀⁴-x₀²+1) 8 // 𝔽p: p=605248206075306171733248481581800960739847691770924913753520744034740935903401304776283802348837311170974282940417 ((x₀-1)² ⋅ r(x₀)/3+x₀) 9 // (E/𝔽p): Y²=X³+1 10 // (Eₜ/𝔽p²): Y² = X³+u (M-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 254 bits and p¹² is 4536 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 bls12378 30 31 import ( 32 "math/big" 33 34 "github.com/consensys/gnark-crypto/ecc" 35 "github.com/consensys/gnark-crypto/ecc/bls12-378/fp" 36 "github.com/consensys/gnark-crypto/ecc/bls12-378/fr" 37 "github.com/consensys/gnark-crypto/ecc/bls12-378/internal/fptower" 38 ) 39 40 // ID bls378 ID 41 const ID = ecc.BLS12_378 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 // bTwistCurveCoeff b coeff of the twist (defined over 𝔽p²) curve 48 var bTwistCurveCoeff fptower.E2 49 50 // generators of the r-torsion group, resp. in ker(pi-id), ker(Tr) 51 var g1Gen G1Jac 52 var g2Gen G2Jac 53 54 var g1GenAff G1Affine 55 var g2GenAff G2Affine 56 57 // point at infinity 58 var g1Infinity G1Jac 59 var g2Infinity G2Jac 60 61 // optimal Ate loop counter 62 var LoopCounter [64]int8 63 64 // Parameters useful for the GLV scalar multiplication. The third roots define the 65 // endomorphisms ϕ₁ and ϕ₂ for <G1Affine> and <G2Affine>. lambda is such that <r, ϕ-λ> lies above 66 // <r> in the ring Z[ϕ]. More concretely it's the associated eigenvalue 67 // of ϕ₁ (resp ϕ₂) restricted to <G1Affine> (resp <G2Affine>) 68 // see https://www.cosic.esat.kuleuven.be/nessie/reports/phase2/GLV.pdf 69 var thirdRootOneG1 fp.Element 70 var thirdRootOneG2 fp.Element 71 var lambdaGLV big.Int 72 73 // glvBasis stores R-linearly independent vectors (a,b), (c,d) 74 // in ker((u,v) → u+vλ[r]), and their determinant 75 var glvBasis ecc.Lattice 76 77 // ψ o π o ψ⁻¹, where ψ:E → E' is the degree 6 iso defined over 𝔽p¹² 78 var endo struct { 79 u fptower.E2 80 v fptower.E2 81 } 82 83 // seed x₀ of the curve 84 var xGen big.Int 85 86 // expose the tower -- github.com/consensys/gnark uses it in a gnark circuit 87 88 // 𝔽p² 89 type E2 = fptower.E2 90 91 // 𝔽p⁶ 92 type E6 = fptower.E6 93 94 // 𝔽p¹² 95 type E12 = fptower.E12 96 97 func init() { 98 aCurveCoeff.SetUint64(0) 99 bCurveCoeff.SetUint64(1) 100 bTwistCurveCoeff.A1.SetUint64(1) // M-twist 101 102 // E(3,y) * cofactor 103 g1Gen.X.SetString("302027100877540500544138164010696035562809807233645104772290911818386302983750063098216015456036850656714568735197") 104 g1Gen.Y.SetString("232851047397483214541821965369374725182070455016459237170823497053622811786333462699984177726412751508198874482530") 105 g1Gen.Z.SetOne() 106 107 // E_t(1,y) * cofactor' 108 g2Gen.X.SetString("470810816643554779222760025249941413452299198622737082648784137654933833261310635469274149014014206108405592809732", 109 "317092959336227428400228502739777439718827088477410533227996105067347670094088101088421556743730925535231685964487") 110 g2Gen.Y.SetString("248853758964950314624408411876149087897475217517523838449839260719963153199419627931373025216041741725848318074460", 111 "389162134924826972299508957175841717907876177152103852864177212390074067430801162403069988146334006672491106545644") 112 g2Gen.Z.SetString("1", 113 "0") 114 115 g1GenAff.FromJacobian(&g1Gen) 116 g2GenAff.FromJacobian(&g2Gen) 117 118 // (X,Y,Z) = (1,1,0) 119 g1Infinity.X.SetOne() 120 g1Infinity.Y.SetOne() 121 g2Infinity.X.SetOne() 122 g2Infinity.Y.SetOne() 123 124 thirdRootOneG1.SetString("164391353554439166353793911729193406645071739502673898176639736370075683438438023898983435337729") 125 thirdRootOneG2.Square(&thirdRootOneG1) 126 lambdaGLV.SetString("121997684678489422961514670190292369408", 10) //(x₀²-1) 127 _r := fr.Modulus() 128 ecc.PrecomputeLattice(_r, &lambdaGLV, &glvBasis) 129 130 endo.u.A0.SetString("164391353554439166353793911729193406645071739502673898176639736370075683438438023898983435337730") 131 endo.v.A0.SetString("595603361117066405543541008735167904222384847192046901135681663787023479658010166685728902742824780272831835669219") 132 133 // binary decomposition of x₀ little endian 134 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, 1, 0, 0, 0, 1, 0, 1, 0, 0, 0, 1, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 1} 135 136 // x₀ 137 xGen.SetString("11045256207009841153", 10) 138 139 } 140 141 // Generators return the generators of the r-torsion group, resp. in ker(pi-id), ker(Tr) 142 func Generators() (g1Jac G1Jac, g2Jac G2Jac, g1Aff G1Affine, g2Aff G2Affine) { 143 g1Aff = g1GenAff 144 g2Aff = g2GenAff 145 g1Jac = g1Gen 146 g2Jac = g2Gen 147 return 148 } 149 150 // CurveCoefficients returns the a, b coefficients of the curve equation. 151 func CurveCoefficients() (a, b fp.Element) { 152 return aCurveCoeff, bCurveCoeff 153 }