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

     1  // Package bw6761 efficient elliptic curve, pairing and hash to curve implementation for bw6-761.
     2  //
     3  // bw6-761: A Brezing--Weng curve (2-chain with bls12-377)
     4  //
     5  //	embedding degree k=6
     6  //	seed x₀=9586122913090633729
     7  //	𝔽p: p=6891450384315732539396789682275657542479668912536150109513790160209623422243491736087683183289411687640864567753786613451161759120554247759349511699125301598951605099378508850372543631423596795951899700429969112842764913119068299
     8  //	𝔽r: r=258664426012969094010652733694893533536393512754914660539884262666720468348340822774968888139573360124440321458177
     9  //	(E/𝔽p): Y²=X³-1
    10  //	(Eₜ/𝔽p): Y² = X³+4 (M-type twist)
    11  //	r ∣ #E(Fp) and r ∣ #Eₜ(𝔽p)
    12  //
    13  // case t % r % x₀ = 3
    14  //
    15  // Extension fields tower:
    16  //
    17  //	𝔽p³[u] = 𝔽p/u³+4
    18  //	𝔽p⁶[v] = 𝔽p³/v²-u
    19  //
    20  // optimal Ate loops:
    21  //
    22  //	x₀+1, x₀²-x₀-1
    23  //
    24  // Security: estimated 126-bit level following [https://eprint.iacr.org/2019/885.pdf]
    25  // (r is 377 bits and p⁶ is 4566 bits)
    26  //
    27  // https://eprint.iacr.org/2020/351.pdf
    28  //
    29  // # Warning
    30  //
    31  // 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.
    32  package bw6761
    33  
    34  import (
    35  	"math/big"
    36  
    37  	"github.com/consensys/gnark-crypto/ecc/bw6-761/internal/fptower"
    38  
    39  	"github.com/consensys/gnark-crypto/ecc"
    40  	"github.com/consensys/gnark-crypto/ecc/bw6-761/fp"
    41  	"github.com/consensys/gnark-crypto/ecc/bw6-761/fr"
    42  )
    43  
    44  // ID BW6_761 ID
    45  const ID = ecc.BW6_761
    46  
    47  // aCurveCoeff is the a coefficients of the curve Y²=X³+ax+b
    48  var aCurveCoeff fp.Element
    49  var bCurveCoeff fp.Element
    50  
    51  // bTwistCurveCoeff b coeff of the twist (defined over 𝔽p) curve
    52  var bTwistCurveCoeff fp.Element
    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 counters
    66  var LoopCounter [190]int8
    67  var LoopCounter1 [190]int8
    68  
    69  // Parameters useful for the GLV scalar multiplication. The third roots define the
    70  // endomorphisms ϕ₁ and ϕ₂ for <G1Affine> and <G2Affine>. lambda is such that <r, ϕ-λ> lies above
    71  // <r> in the ring Z[ϕ]. More concretely it's the associated eigenvalue
    72  // of ϕ₁ (resp ϕ₂) restricted to <G1Affine> (resp <G2Affine>)
    73  // see https://www.cosic.esat.kuleuven.be/nessie/reports/phase2/GLV.pdf
    74  var thirdRootOneG1 fp.Element
    75  var thirdRootOneG2 fp.Element
    76  var lambdaGLV big.Int
    77  
    78  // glvBasis stores R-linearly independent vectors (a,b), (c,d)
    79  // in ker((u,v) → u+vλ[r]), and their determinant
    80  var glvBasis ecc.Lattice
    81  
    82  // seed x₀ of the curve
    83  var xGen big.Int
    84  
    85  // 𝔽p3
    86  type E3 = fptower.E3
    87  
    88  // 𝔽p6
    89  type E6 = fptower.E6
    90  
    91  func init() {
    92  	aCurveCoeff.SetUint64(0)
    93  	bCurveCoeff.SetOne().Neg(&bCurveCoeff)
    94  	// M-twist
    95  	bTwistCurveCoeff.SetUint64(4)
    96  
    97  	g1Gen.X.SetString("6238772257594679368032145693622812838779005809760824733138787810501188623461307351759238099287535516224314149266511977132140828635950940021790489507611754366317801811090811367945064510304504157188661901055903167026722666149426237")
    98  	g1Gen.Y.SetString("2101735126520897423911504562215834951148127555913367997162789335052900271653517958562461315794228241561913734371411178226936527683203879553093934185950470971848972085321797958124416462268292467002957525517188485984766314758624099")
    99  	g1Gen.Z.SetOne()
   100  
   101  	g2Gen.X.SetString("6445332910596979336035888152774071626898886139774101364933948236926875073754470830732273879639675437155036544153105017729592600560631678554299562762294743927912429096636156401171909259073181112518725201388196280039960074422214428")
   102  	g2Gen.Y.SetString("562923658089539719386922163444547387757586534741080263946953401595155211934630598999300396317104182598044793758153214972605680357108252243146746187917218885078195819486220416605630144001533548163105316661692978285266378674355041")
   103  	g2Gen.Z.SetOne()
   104  
   105  	g1GenAff.FromJacobian(&g1Gen)
   106  	g2GenAff.FromJacobian(&g2Gen)
   107  
   108  	// x₀+1
   109  	LoopCounter = [190]int8{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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0, 1, 0, 0, 1, 0, 0, 0, 0, 1, 0, 1, 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, 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, 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, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0}
   110  
   111  	// x₀³-x₀²-x₀
   112  	T, _ := new(big.Int).SetString("880904806456922042166256752416502360955572640081583800319", 10)
   113  	ecc.NafDecomposition(T, LoopCounter1[:])
   114  
   115  	// (X,Y,Z) = (1,1,0)
   116  	g1Infinity.X.SetOne()
   117  	g1Infinity.Y.SetOne()
   118  	g2Infinity.X.SetOne()
   119  	g2Infinity.Y.SetOne()
   120  
   121  	thirdRootOneG1.SetString("1968985824090209297278610739700577151397666382303825728450741611566800370218827257750865013421937292370006175842381275743914023380727582819905021229583192207421122272650305267822868639090213645505120388400344940985710520836292650")
   122  	thirdRootOneG2.Square(&thirdRootOneG1)
   123  	lambdaGLV.SetString("80949648264912719408558363140637477264845294720710499478137287262712535938301461879813459410945", 10) // (x⁵-3x⁴+3x³-x+1)
   124  	_r := fr.Modulus()
   125  	ecc.PrecomputeLattice(_r, &lambdaGLV, &glvBasis)
   126  
   127  	// x₀
   128  	xGen.SetString("9586122913090633729", 10)
   129  
   130  }
   131  
   132  // Generators return the generators of the r-torsion group, resp. in ker(pi-id), ker(Tr)
   133  func Generators() (g1Jac G1Jac, g2Jac G2Jac, g1Aff G1Affine, g2Aff G2Affine) {
   134  	g1Aff = g1GenAff
   135  	g2Aff = g2GenAff
   136  	g1Jac = g1Gen
   137  	g2Jac = g2Gen
   138  	return
   139  }
   140  
   141  // CurveCoefficients returns the a, b coefficients of the curve equation.
   142  func CurveCoefficients() (a, b fp.Element) {
   143  	return aCurveCoeff, bCurveCoeff
   144  }