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  }