1package bls12381
2
3import (
4	"math/big"
5
6	"github.com/consensys/gnark-crypto/ecc"
7	"github.com/consensys/gnark-crypto/ecc/bls12-381/fp"
8	"github.com/consensys/gnark-crypto/ecc/bls12-381/fr"
9	"github.com/consensys/gnark-crypto/ecc/bls12-381/internal/fptower"
10)
11
12// E: y**2=x**3+4
13// Etwist: y**2 = x**3+4*(u+1)
14// Tower: Fp->Fp2, u**2=-1 -> Fp12, v**6=u+1
15// Generator (BLS12 family): x=-15132376222941642752
16// optimal Ate loop: trace(frob)-1=x
17// trace of pi: x+1
18// Fp: p=4002409555221667393417789825735904156556882819939007885332058136124031650490837864442687629129015664037894272559787
19// Fr: r=52435875175126190479447740508185965837690552500527637822603658699938581184513 (x**4-x**2+1)
20
21// ID bls381 ID
22const ID = ecc.BLS12_381
23
24// bCurveCoeff b coeff of the curve
25var bCurveCoeff fp.Element
26
27// twist
28var twist fptower.E2
29
30// bTwistCurveCoeff b coeff of the twist (defined over Fp2) curve
31var bTwistCurveCoeff fptower.E2
32
33// twoInv 1/2 mod p (needed for DoubleStep in Miller loop)
34var twoInv fp.Element
35
36// generators of the r-torsion group, resp. in ker(pi-id), ker(Tr)
37var g1Gen G1Jac
38var g2Gen G2Jac
39
40var g1GenAff G1Affine
41var g2GenAff G2Affine
42
43// point at infinity
44var g1Infinity G1Jac
45var g2Infinity G2Jac
46
47// optimal Ate loop counter (=trace-1 = x in BLS family)
48var loopCounter [64]int8
49
50// Parameters useful for the GLV scalar multiplication. The third roots define the
51//  endomorphisms phi1 and phi2 for <G1Affine> and <G2Affine>. lambda is such that <r, phi-lambda> lies above
52// <r> in the ring Z[phi]. More concretely it's the associated eigenvalue
53// of phi1 (resp phi2) restricted to <G1Affine> (resp <G2Affine>)
54// cf https://www.cosic.esat.kuleuven.be/nessie/reports/phase2/GLV.pdf
55var thirdRootOneG1 fp.Element
56var thirdRootOneG2 fp.Element
57var lambdaGLV big.Int
58
59// glvBasis stores R-linearly independant vectors (a,b), (c,d)
60// in ker((u,v)->u+vlambda[r]), and their determinant
61var glvBasis ecc.Lattice
62
63// psi o pi o psi**-1, where psi:E->E' is the degree 6 iso defined over Fp12
64var endo struct {
65	u fptower.E2
66	v fptower.E2
67}
68
69// generator of the curve
70var xGen big.Int
71
72func init() {
73
74	bCurveCoeff.SetUint64(4)
75	twist.A0.SetUint64(1)
76	twist.A1.SetUint64(1)
77	bTwistCurveCoeff.MulByElement(&twist, &bCurveCoeff)
78
79	twoInv.SetOne().Double(&twoInv).Inverse(&twoInv)
80
81	g1Gen.X.SetString("3685416753713387016781088315183077757961620795782546409894578378688607592378376318836054947676345821548104185464507")
82	g1Gen.Y.SetString("1339506544944476473020471379941921221584933875938349620426543736416511423956333506472724655353366534992391756441569")
83	g1Gen.Z.SetString("1")
84
85	g2Gen.X.SetString("352701069587466618187139116011060144890029952792775240219908644239793785735715026873347600343865175952761926303160",
86		"3059144344244213709971259814753781636986470325476647558659373206291635324768958432433509563104347017837885763365758")
87	g2Gen.Y.SetString("1985150602287291935568054521177171638300868978215655730859378665066344726373823718423869104263333984641494340347905",
88		"927553665492332455747201965776037880757740193453592970025027978793976877002675564980949289727957565575433344219582")
89	g2Gen.Z.SetString("1",
90		"0")
91
92	g1GenAff.FromJacobian(&g1Gen)
93	g2GenAff.FromJacobian(&g2Gen)
94
95	g1Infinity.X.SetOne()
96	g1Infinity.Y.SetOne()
97	g2Infinity.X.SetOne()
98	g2Infinity.Y.SetOne()
99
100	thirdRootOneG1.SetString("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939436")
101	thirdRootOneG2.Square(&thirdRootOneG1)
102	lambdaGLV.SetString("228988810152649578064853576960394133503", 10) //(x**2-1)
103	_r := fr.Modulus()
104	ecc.PrecomputeLattice(_r, &lambdaGLV, &glvBasis)
105
106	endo.u.A0.SetString("0")
107	endo.u.A1.SetString("4002409555221667392624310435006688643935503118305586438271171395842971157480381377015405980053539358417135540939437")
108	endo.v.A0.SetString("2973677408986561043442465346520108879172042883009249989176415018091420807192182638567116318576472649347015917690530")
109	endo.v.A1.SetString("1028732146235106349975324479215795277384839936929757896155643118032610843298655225875571310552543014690878354869257")
110
111	// binary decomposition of 15132376222941642752 little endian
112	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}
113
114	xGen.SetString("15132376222941642752", 10)
115
116}
117
118// Generators return the generators of the r-torsion group, resp. in ker(pi-id), ker(Tr)
119func Generators() (g1Jac G1Jac, g2Jac G2Jac, g1Aff G1Affine, g2Aff G2Affine) {
120	g1Aff = g1GenAff
121	g2Aff = g2GenAff
122	g1Jac = g1Gen
123	g2Jac = g2Gen
124	return
125}
126