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

     1  // Package bls12381 efficient elliptic curve, pairing and hash to curve implementation for bls12-381.
     2  //
     3  // bls12-381: A Barreto--Lynn--Scott curve
     4  //
     5  //	embedding degree k=12
     6  //	seed x₀=-15132376222941642752
     7  //	𝔽r: r=52435875175126190479447740508185965837690552500527637822603658699938581184513 (x₀⁴-x₀²+1)
     8  //	𝔽p: p=4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787 ((x₀-1)² ⋅ r(x₀)/3+x₀)
     9  //	(E/𝔽p): Y²=X³+4
    10  //	(Eₜ/𝔽p²): Y² = X³+4(u+1) (M-type twist)
    11  //	r ∣ #E(Fp) and r ∣ #Eₜ(𝔽p²)
    12  //
    13  // Extension fields tower:
    14  //
    15  //	𝔽p²[u] = 𝔽p/u²+1
    16  //	𝔽p⁶[v] = 𝔽p²/v³-1-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 255 bits and p¹² is 4569 bits)
    25  //
    26  // # Warning
    27  //
    28  // 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.
    29  package bls12381
    30  
    31  import (
    32  	"math/big"
    33  
    34  	"github.com/consensys/gnark-crypto/ecc"
    35  	"github.com/consensys/gnark-crypto/ecc/bls12-381/fp"
    36  	"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
    37  	"github.com/consensys/gnark-crypto/ecc/bls12-381/internal/fptower"
    38  )
    39  
    40  // ID bls381 ID
    41  const ID = ecc.BLS12_381
    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 ψ^{-1}, 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  // 𝔽p²
    90  type E2 = fptower.E2
    91  
    92  // 𝔽p⁶
    93  type E6 = fptower.E6
    94  
    95  // 𝔽p¹²
    96  type E12 = fptower.E12
    97  
    98  func init() {
    99  	aCurveCoeff.SetUint64(0)
   100  	bCurveCoeff.SetUint64(4)
   101  	// M-twist
   102  	twist.A0.SetUint64(1)
   103  	twist.A1.SetUint64(1)
   104  	bTwistCurveCoeff.MulByElement(&twist, &bCurveCoeff)
   105  
   106  	g1Gen.X.SetString("3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507")
   107  	g1Gen.Y.SetString("1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569")
   108  	g1Gen.Z.SetOne()
   109  
   110  	g2Gen.X.SetString("352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160",
   111  		"3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758")
   112  	g2Gen.Y.SetString("1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905",
   113  		"927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582")
   114  	g2Gen.Z.SetString("1",
   115  		"0")
   116  
   117  	g1GenAff.FromJacobian(&g1Gen)
   118  	g2GenAff.FromJacobian(&g2Gen)
   119  
   120  	// (X,Y,Z) = (1,1,0)
   121  	g1Infinity.X.SetOne()
   122  	g1Infinity.Y.SetOne()
   123  	g2Infinity.X.SetOne()
   124  	g2Infinity.Y.SetOne()
   125  
   126  	thirdRootOneG1.SetString("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436")
   127  	thirdRootOneG2.Square(&thirdRootOneG1)
   128  	lambdaGLV.SetString("228988810152649578064853576960394133503", 10) //(x₀²-1)
   129  	_r := fr.Modulus()
   130  	ecc.PrecomputeLattice(_r, &lambdaGLV, &glvBasis)
   131  
   132  	endo.u.A0.SetString("0")
   133  	endo.u.A1.SetString("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437")
   134  	endo.v.A0.SetString("2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530")
   135  	endo.v.A1.SetString("1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257")
   136  
   137  	// binary decomposition of -x₀ little endian
   138  	LoopCounter = [64]int8{0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 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, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 1, 1}
   139  
   140  	// -x₀
   141  	xGen.SetString("15132376222941642752", 10)
   142  
   143  }
   144  
   145  // Generators return the generators of the r-torsion group, resp. in ker(pi-id), ker(Tr)
   146  func Generators() (g1Jac G1Jac, g2Jac G2Jac, g1Aff G1Affine, g2Aff G2Affine) {
   147  	g1Aff = g1GenAff
   148  	g2Aff = g2GenAff
   149  	g1Jac = g1Gen
   150  	g2Jac = g2Gen
   151  	return
   152  }
   153  
   154  // CurveCoefficients returns the a, b coefficients of the curve equation.
   155  func CurveCoefficients() (a, b fp.Element) {
   156  	return aCurveCoeff, bCurveCoeff
   157  }