github.com/consensys/gnark-crypto@v0.14.0/ecc/bls24-315/bls24-315.go (about)

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