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  }