github.com/consensys/gnark-crypto@v0.14.0/ecc/bn254/bn254.go (about) 1 // Copyright 2020 ConsenSys Software Inc. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 // Package bn254 efficient elliptic curve, pairing and hash to curve implementation for bn254. This curve appears in 16 // Ethereum pre-compiles as altbn128. 17 // 18 // bn254: A Barreto--Naerig curve with 19 // 20 // seed x₀=4965661367192848881 21 // 𝔽r: r=21888242871839275222246405745257275088548364400416034343698204186575808495617 (36x₀⁴+36x₀³+18x₀²+6x₀+1) 22 // 𝔽p: p=21888242871839275222246405745257275088696311157297823662689037894645226208583 (36x₀⁴+36x₀³+24x₀²+6x₀+1) 23 // (E/𝔽p): Y²=X³+3 24 // (Eₜ/𝔽p²): Y² = X³+3/(u+9) (D-type twist) 25 // r ∣ #E(Fp) and r ∣ #Eₜ(𝔽p²) 26 // 27 // Extension fields tower: 28 // 29 // 𝔽p²[u] = 𝔽p/u²+1 30 // 𝔽p⁶[v] = 𝔽p²/v³-9-u 31 // 𝔽p¹²[w] = 𝔽p⁶/w²-v 32 // 33 // optimal Ate loop size: 34 // 35 // 6x₀+2 36 // 37 // Security: estimated 103-bit level following [https://eprint.iacr.org/2019/885.pdf] 38 // (r is 254 bits and p¹² is 3044 bits) 39 // 40 // # Warning 41 // 42 // 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. 43 package bn254 44 45 import ( 46 "math/big" 47 48 "github.com/consensys/gnark-crypto/ecc" 49 "github.com/consensys/gnark-crypto/ecc/bn254/fp" 50 "github.com/consensys/gnark-crypto/ecc/bn254/fr" 51 "github.com/consensys/gnark-crypto/ecc/bn254/internal/fptower" 52 ) 53 54 // ID bn254 ID 55 const ID = ecc.BN254 56 57 // aCurveCoeff is the a coefficients of the curve Y²=X³+ax+b 58 var aCurveCoeff fp.Element 59 var bCurveCoeff fp.Element 60 61 // twist 62 var twist fptower.E2 63 64 // bTwistCurveCoeff b coeff of the twist (defined over 𝔽p²) curve 65 var bTwistCurveCoeff fptower.E2 66 67 // generators of the r-torsion group, resp. in ker(pi-id), ker(Tr) 68 var g1Gen G1Jac 69 var g2Gen G2Jac 70 71 var g1GenAff G1Affine 72 var g2GenAff G2Affine 73 74 // point at infinity 75 var g1Infinity G1Jac 76 var g2Infinity G2Jac 77 78 // optimal Ate loop counter 79 var LoopCounter [66]int8 80 81 // Parameters useful for the GLV scalar multiplication. The third roots define the 82 // endomorphisms ϕ₁ and ϕ₂ for <G1Affine> and <G2Affine>. lambda is such that <r, ϕ-λ> lies above 83 // <r> in the ring Z[ϕ]. More concretely it's the associated eigenvalue 84 // of ϕ₁ (resp ϕ₂) restricted to <G1Affine> (resp <G2Affine>) 85 // see https://www.cosic.esat.kuleuven.be/nessie/reports/phase2/GLV.pdf 86 var thirdRootOneG1 fp.Element 87 var thirdRootOneG2 fp.Element 88 var lambdaGLV big.Int 89 90 // glvBasis stores R-linearly independent vectors (a,b), (c,d) 91 // in ker((u,v) → u+vλ[r]), and their determinant 92 var glvBasis ecc.Lattice 93 94 // ψ o π o ψ⁻¹, where ψ:E → E' is the degree 6 iso defined over 𝔽p¹² 95 var endo struct { 96 u fptower.E2 97 v fptower.E2 98 } 99 100 // seed x₀ of the curve 101 var xGen big.Int 102 103 // expose the tower -- github.com/consensys/gnark uses it in a gnark circuit 104 105 // 𝔽p² 106 type E2 = fptower.E2 107 108 // 𝔽p⁶ 109 type E6 = fptower.E6 110 111 // 𝔽p¹² 112 type E12 = fptower.E12 113 114 func init() { 115 aCurveCoeff.SetUint64(0) 116 bCurveCoeff.SetUint64(3) 117 // D-twist 118 twist.A0.SetUint64(9) 119 twist.A1.SetUint64(1) 120 bTwistCurveCoeff.Inverse(&twist).MulByElement(&bTwistCurveCoeff, &bCurveCoeff) 121 122 g1Gen.X.SetOne() 123 g1Gen.Y.SetUint64(2) 124 g1Gen.Z.SetOne() 125 126 g2Gen.X.SetString("10857046999023057135944570762232829481370756359578518086990519993285655852781", 127 "11559732032986387107991004021392285783925812861821192530917403151452391805634") 128 g2Gen.Y.SetString("8495653923123431417604973247489272438418190587263600148770280649306958101930", 129 "4082367875863433681332203403145435568316851327593401208105741076214120093531") 130 g2Gen.Z.SetString("1", 131 "0") 132 133 g1GenAff.FromJacobian(&g1Gen) 134 g2GenAff.FromJacobian(&g2Gen) 135 136 // (X,Y,Z) = (1,1,0) 137 g1Infinity.X.SetOne() 138 g1Infinity.Y.SetOne() 139 g2Infinity.X.SetOne() 140 g2Infinity.Y.SetOne() 141 142 thirdRootOneG1.SetString("2203960485148121921418603742825762020974279258880205651966") 143 thirdRootOneG2.Square(&thirdRootOneG1) 144 lambdaGLV.SetString("4407920970296243842393367215006156084916469457145843978461", 10) // (36x₀³+18x₀²+6x₀+1) 145 _r := fr.Modulus() 146 ecc.PrecomputeLattice(_r, &lambdaGLV, &glvBasis) 147 148 endo.u.A0.SetString("21575463638280843010398324269430826099269044274347216827212613867836435027261") 149 endo.u.A1.SetString("10307601595873709700152284273816112264069230130616436755625194854815875713954") 150 endo.v.A0.SetString("2821565182194536844548159561693502659359617185244120367078079554186484126554") 151 endo.v.A1.SetString("3505843767911556378687030309984248845540243509899259641013678093033130930403") 152 153 // 2-NAF decomposition of 6x₀+2 little endian 154 optimaAteLoop, _ := new(big.Int).SetString("29793968203157093288", 10) 155 ecc.NafDecomposition(optimaAteLoop, LoopCounter[:]) 156 157 xGen.SetString("4965661367192848881", 10) 158 159 } 160 161 // Generators return the generators of the r-torsion group, resp. in ker(pi-id), ker(Tr) 162 func Generators() (g1Jac G1Jac, g2Jac G2Jac, g1Aff G1Affine, g2Aff G2Affine) { 163 g1Aff = g1GenAff 164 g2Aff = g2GenAff 165 g1Jac = g1Gen 166 g2Jac = g2Gen 167 return 168 } 169 170 // CurveCoefficients returns the a, b coefficients of the curve equation. 171 func CurveCoefficients() (a, b fp.Element) { 172 return aCurveCoeff, bCurveCoeff 173 }