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

     1  // Copyright 2020 Consensys Software Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Code generated by consensys/gnark-crypto DO NOT EDIT
    16  
    17  package bls12377
    18  
    19  import (
    20  	"github.com/consensys/gnark-crypto/ecc/bls12-377/fp"
    21  	"github.com/consensys/gnark-crypto/ecc/bls12-377/internal/fptower"
    22  
    23  	"math/big"
    24  )
    25  
    26  //Note: This only works for simple extensions
    27  
    28  func g2IsogenyXNumerator(dst *fptower.E2, x *fptower.E2) {
    29  	g2EvalPolynomial(dst,
    30  		false,
    31  		[]fptower.E2{
    32  			{
    33  				A0: fp.Element{3551783286045471771, 15672698349814166255, 7201714524012399751, 9685135133462022557, 11459791422433132438, 34279211894444158},
    34  				A1: fp.Element{6733784119909728882, 8027365598504339614, 9826395261252013434, 17766961605401961078, 16718790361550578585, 8827310132881948},
    35  			},
    36  			{
    37  				A0: fp.Element{10039326048219096853, 8025585753053690704, 15692757884719051200, 14081267914923412694, 12483400733579637594, 41501995942887693},
    38  				A1: fp.Element{3285050121746765179, 16424976010740556635, 13525960835401060630, 8230390587856081588, 332312595686915068, 58693565636984574},
    39  			},
    40  			{
    41  				A0: fp.Element{17569899329826403508, 9637548884483664645, 11559603533194429416, 509473447889017775, 16843450937194425803, 11820413515158522},
    42  				A1: fp.Element{18082143759519379917, 7350976797508953919, 8718515184478260262, 11424641547646470649, 12610734036362352161, 109931236078585740},
    43  			},
    44  			{
    45  				A0: fp.Element{14344095877598929896, 14770204065590636976, 13870643972022067464, 14327299415926938990, 2100218127689809229, 111985606372347998},
    46  				A1: fp.Element{18166912950538149334, 7903342274102247275, 11235613814926762637, 6048582781848067329, 9865957781737849443, 72257053590751229},
    47  			},
    48  			{
    49  				A0: fp.Element{9289693438943775070, 611273684478921638, 3161020385710416475, 2286858861996231773, 14631078872284738786, 101751379483637100},
    50  				A1: fp.Element{218371821390517888, 3239557307852648611, 7956123978234311251, 4433191957359481551, 7602230667186897987, 36183482319693410},
    51  			},
    52  			{
    53  				A0: fp.Element{7524026848147356443, 15899508093607509001, 9269755160329214834, 12526651159477248728, 3756002781809695765, 101164747683440023},
    54  				A1: fp.Element{6220885675233469595, 1070578225745722143, 9028649589122227273, 241265531361573072, 17722097355684345537, 59426317598728635},
    55  			},
    56  			{
    57  				A0: fp.Element{1147337684740884862, 11995598217907408439, 6334092051568104396, 4490620767408292574, 16484486820571077628, 32056264099725884},
    58  				A1: fp.Element{1626504798254052117, 15843967556282260399, 3222912561813979091, 1092398256542226755, 15613117580878270463, 35759440311789519},
    59  			},
    60  			{
    61  				A0: fp.Element{9456818710433496904, 8738575976265225627, 17481785322204872502, 10252666647792359788, 13007033241788380867, 54062177864773120},
    62  				A1: fp.Element{7857657292788377886, 18159261954362575139, 6957043223229770024, 101887390030524213, 7411469664095682342, 17462521019270966},
    63  			},
    64  			{
    65  				A0: fp.Element{5935437080311313022, 4869272223104979307, 14892623520420170949, 6274040211921387638, 190450687675494048, 100326942952217018},
    66  				A1: fp.Element{4080141112519796596, 14389619698824585061, 15572076811388758383, 5573262239497616930, 5714216936392065098, 10910945353280475},
    67  			},
    68  			{
    69  				A0: fp.Element{12050383421129197508, 7679000367015579641, 4181895471589351098, 4488864303009131705, 1755297417051974713, 33780283701258651},
    70  				A1: fp.Element{11393221592097145268, 10835918896706663346, 4746287363995169177, 6169630568067228482, 11259555703140136465, 52771734216395635},
    71  			},
    72  			{
    73  				A0: fp.Element{4577617767559140265, 568504000295320317, 4739467389388831592, 9537638546299567945, 11669151734363428413, 119097732794758712},
    74  				A1: fp.Element{5691235310984308451, 13601281267571106288, 7819292534586961743, 11652278682059157182, 2231701566242469994, 110966193728844398},
    75  			},
    76  			{
    77  				A0: fp.Element{8957158313166077105, 5669155713645675267, 17333896861619738764, 4892240835897020648, 8492829473755858526, 70767002641220602},
    78  				A1: fp.Element{8355305174234995113, 16726408794609999189, 6819868380250046496, 9302398329327482182, 3371252083110614225, 32903157732774708},
    79  			},
    80  			{
    81  				A0: fp.Element{3562726361589542410, 15642076536163677636, 3828009540728039550, 5513538145598570884, 1202255355797680138, 19209968154720986},
    82  				A1: fp.Element{2433342667414904247, 14430646666116795259, 7881503288178112304, 10086912537277758921, 14321155618236575013, 84224128485096326},
    83  			},
    84  			{
    85  				A0: fp.Element{7543845460144717594, 14101022520017632284, 6419288061290617259, 11326768478076341964, 18432026940412127132, 85359846879027793},
    86  				A1: fp.Element{17142157839755119212, 5159976764710014065, 6393633352893279233, 8672509349035392886, 7859431465567482570, 62163334379266093},
    87  			},
    88  			{
    89  				A0: fp.Element{2954881934412060022, 10898916794193723070, 10915833338735408379, 703491535562714344, 14589964434689495439, 90051679935520087},
    90  				A1: fp.Element{18417998714611085978, 11039054240270137506, 9972891257774348246, 13263552626589315210, 4522668809484918556, 63885995997825101},
    91  			},
    92  			{
    93  				A0: fp.Element{9864134077459603571, 12525567282624341376, 5205345924937688700, 12649124091757575439, 14636003906379491067, 96025183135833306},
    94  				A1: fp.Element{10316403063861314867, 10750711173072110600, 4513675589861596212, 2635673197095740125, 16720951430549947037, 31390298180493148},
    95  			},
    96  			{
    97  				A0: fp.Element{3003952238586646516, 3250841642932517220, 7061834734009117554, 16259415476002355236, 1626926148029432162, 77189086665928784},
    98  				A1: fp.Element{14450051585993059472, 11823315281584113748, 6929304997500454604, 15344892292748160673, 15787768514545706202, 69813057053620435},
    99  			},
   100  			{
   101  				A0: fp.Element{4228110392233474072, 18010581486575392207, 13699345898545483049, 17704744337446085874, 5487913134051621310, 112205105149111207},
   102  				A1: fp.Element{14824585485470590037, 7637124239293942071, 1041102438278370701, 4207950142422409777, 9639439542389544094, 106832755917361143},
   103  			},
   104  			{
   105  				A0: fp.Element{10744145886747796703, 8741979218876153119, 4537642647264646058, 9645243825719833866, 16643801652280184094, 57528843479739428},
   106  				A1: fp.Element{5785935421797206370, 847985697064985249, 11478142027129258160, 12741057482356268413, 10148591557028647803, 106797667835022069},
   107  			},
   108  			{
   109  				A0: fp.Element{6454832842704992412, 9977685523482313420, 413111938383295655, 13594952949000658414, 17807487788385728582, 108984464456649540},
   110  				A1: fp.Element{17048359867690489456, 2859252502285541521, 10818623701995947153, 7550564651763690537, 459333235977057482, 37663478480017988},
   111  			},
   112  			{
   113  				A0: fp.Element{8658783637463168087, 13532094408327228336, 12875492560745818922, 6809856611120372218, 2853890452345629690, 87034840621524077},
   114  				A1: fp.Element{16301307707120111515, 9104654412985804807, 12475785366789695268, 4024450921325678435, 5626908908910088752, 56687303925216568},
   115  			},
   116  			{
   117  				A0: fp.Element{9729408098285946449, 14379177692720606450, 15077053755146607368, 1299576162980711320, 13990524355831736308, 88070216003513722},
   118  				A1: fp.Element{5766436769337206504, 1093294963802231624, 1118315683159380206, 16238633443172785277, 5463682062430385614, 116508026946667814},
   119  			},
   120  			{
   121  				A0: fp.Element{16584249698770136319, 8326278446225484560, 3131917383401484830, 4756633391835977312, 7642636045510739113, 6547192373501023},
   122  				A1: fp.Element{10803045440816594384, 6133821182275761752, 7762705812675926549, 15035799326051880159, 10201360843527298396, 76693252438359195},
   123  			},
   124  			{
   125  				A0: fp.Element{3621702609341817994, 1179514540952803843, 9695126383219869545, 4861853798003230532, 15648444733987506481, 103088924877589738},
   126  				A1: fp.Element{0},
   127  			},
   128  		},
   129  		x)
   130  }
   131  
   132  func g2IsogenyXDenominator(dst *fptower.E2, x *fptower.E2) {
   133  	g2EvalPolynomial(dst,
   134  		true,
   135  		[]fptower.E2{
   136  			{
   137  				A0: fp.Element{1063048776114699222, 13419136991291290443, 17670140655952814712, 17007170270485437006, 2714055472280753035, 14919040757258909},
   138  				A1: fp.Element{16666868668043867029, 10413023948165423527, 2513282340300795191, 5135056029366772344, 18074639060500180041, 66260525510488187},
   139  			},
   140  			{
   141  				A0: fp.Element{10940415603117103310, 2845175453419864190, 16971099885047235913, 4517542951822462583, 12015180195047358700, 101962474939260879},
   142  				A1: fp.Element{1812172074217037271, 9040376510937171745, 1548369375982775200, 5323713323104515663, 11625954855074087334, 4220230277540083},
   143  			},
   144  			{
   145  				A0: fp.Element{8797262280793960976, 17802450974932240081, 10157003283304584770, 593225980605733121, 14184353532500093055, 108979035901112461},
   146  				A1: fp.Element{15554837140147424903, 1512405638789788986, 3262333938884419786, 4638305243452530609, 139542405126620667, 54024907639584882},
   147  			},
   148  			{
   149  				A0: fp.Element{11424716963860540790, 13456329776215064369, 1929697779149270213, 6306593112502705131, 13859057472975507250, 41785102954052035},
   150  				A1: fp.Element{7602541488494927932, 4897344463908346766, 17005994653424089316, 17216735712046963938, 3756018940504096168, 5402674048264985},
   151  			},
   152  			{
   153  				A0: fp.Element{2416535722849524790, 4831233808757576698, 17297774284520319797, 6772473332127607735, 18174962172090050489, 58994994344686536},
   154  				A1: fp.Element{15610410799617712282, 9543692017702705957, 8970286522052539731, 12714219237879632746, 2449975609997710437, 10121059733973512},
   155  			},
   156  			{
   157  				A0: fp.Element{15388608950644940213, 15178518612850901922, 4663566445208062329, 3999751164791233677, 7358895960008222342, 33044898311505685},
   158  				A1: fp.Element{2356569524239497521, 4634121806982763800, 13294827248503187097, 18379906191200424608, 13949207972645393879, 37350653623873291},
   159  			},
   160  			{
   161  				A0: fp.Element{4970487283568561993, 8451944303783250587, 10744185545939488302, 297910826254460501, 5663064319185246782, 55864728573479562},
   162  				A1: fp.Element{13676619861655804765, 9740179349809417716, 1447466405783296044, 7262347140551810932, 4460517809397706328, 48696693541469882},
   163  			},
   164  			{
   165  				A0: fp.Element{4218670501850515232, 1300837062036343562, 6322288902222626865, 2517640049285419442, 15933997662514683752, 35742655751559900},
   166  				A1: fp.Element{8671399843829082486, 10727571055999201132, 18066412728811459184, 2077243532292929295, 18402906919639961112, 11053564656556137},
   167  			},
   168  			{
   169  				A0: fp.Element{13549293427847064273, 13454861990004702789, 12625716182603551974, 16289223817658875114, 709786698748164395, 79373748066056979},
   170  				A1: fp.Element{9755261456181601166, 8062867867952015070, 11667298511884909423, 12783693965971962594, 5335701901003645771, 118924945769569072},
   171  			},
   172  			{
   173  				A0: fp.Element{5024330816113629597, 9162185537450801251, 14637535063833510048, 5042964231794706299, 10987285991634226322, 46336617111585333},
   174  				A1: fp.Element{17451698037621354790, 10238258568486351103, 10306732172443683782, 16783673474705190959, 2366024509224094980, 27102949281362657},
   175  			},
   176  			{
   177  				A0: fp.Element{1779719694787807439, 13682444363499832102, 319805876265464201, 10878143779945294209, 5260570358490406259, 111384964548942529},
   178  				A1: fp.Element{10364815279125342799, 5955681787042171859, 16259776976357711022, 698420282628335564, 14458917752432688041, 9951241155641633},
   179  			},
   180  			{
   181  				A0: fp.Element{9860169129499874274, 4710132861939245083, 16729683163954203081, 1163919786098698325, 16999533791398931846, 45007426249965870},
   182  				A1: fp.Element{1554156753268998897, 13001788039766734041, 13083055690099472212, 15457335577166095794, 9225717367159961098, 40091861438122274},
   183  			},
   184  			{
   185  				A0: fp.Element{15170394446649694794, 515688257282406708, 7546053921359572147, 2040402108618036352, 14910633907967741865, 51620635462170312},
   186  				A1: fp.Element{14097816726424606264, 12505549891408832791, 13993079436736795338, 10172463092702817360, 608991345474995671, 70034669163571313},
   187  			},
   188  			{
   189  				A0: fp.Element{4643108199199003526, 15736620484932148216, 15681664113334307244, 17299685843716562967, 13906356132799386736, 93346316071232156},
   190  				A1: fp.Element{4605618257264761423, 18021103018327472901, 16108946406338519358, 9045268489748282166, 5059321869053749600, 110536556169650965},
   191  			},
   192  			{
   193  				A0: fp.Element{11517108407780568371, 7978619811691229504, 9264608640258152436, 8451802924690124465, 4675285626878377699, 109463398958344863},
   194  				A1: fp.Element{3597960821476001565, 3759680844169152876, 14302414818654496990, 17433096654117785124, 17967041042193057544, 85366167313641495},
   195  			},
   196  			{
   197  				A0: fp.Element{9939822412604413185, 13452127979624463736, 5130248585009642508, 3885932386715663181, 5051687816649505884, 77901780572240613},
   198  				A1: fp.Element{519763984047258436, 9600915485628319569, 15140529797299450996, 9971542775239334883, 8807015558507490608, 948222705021672},
   199  			},
   200  			{
   201  				A0: fp.Element{2827339587428175511, 6895834130469522434, 13331059522798479027, 13955187059915735579, 14378880524037078149, 37849146151734053},
   202  				A1: fp.Element{5659129353366385472, 1315670479643534676, 5263307416551198333, 6925817959331280727, 2077163856293267360, 78059303625906606},
   203  			},
   204  			{
   205  				A0: fp.Element{12063007979636530410, 11856928215255593909, 11875394835884852884, 7779285203935234969, 6621016507099994054, 58081312732574672},
   206  				A1: fp.Element{16883486087598545310, 13020319043706888256, 13790070886127375971, 1584348143126996741, 14269751476430075034, 39520851290632316},
   207  			},
   208  			{
   209  				A0: fp.Element{10496651096160116529, 17447330314090714314, 7901980568892205616, 12523643767284114259, 14047697587913173436, 75967257029771325},
   210  				A1: fp.Element{928850053641029162, 14269106311960337185, 16222409674828338261, 5805191570224440459, 18405225593952050465, 81611267238126250},
   211  			},
   212  			{
   213  				A0: fp.Element{11963245856892367752, 10425756598646938656, 18335238837348744770, 15086772981218061512, 16514870314421827966, 31505685309500160},
   214  				A1: fp.Element{12503518650914401765, 9253053408485518576, 7574198415595259890, 9578781703355827570, 4997060354564847196, 4129967821132897},
   215  			},
   216  			{
   217  				A0: fp.Element{2031421031641935199, 11357963626711833272, 3216176135850906142, 18356175605205399499, 14930266308542898024, 45166487627178747},
   218  				A1: fp.Element{4224679465464892278, 5162816687557914011, 9625001313214472999, 9646089844316603379, 3042432097393437616, 116654205222221531},
   219  			},
   220  			{
   221  				A0: fp.Element{707631102761073363, 4675040476129639901, 7917747947488915690, 10109499984363985170, 8993410474198507338, 72712009800189820},
   222  				A1: fp.Element{13149412355826661761, 13738163990683470943, 2035497293527985654, 18119267602401018212, 2631647798265895027, 2795783216290358},
   223  			},
   224  		},
   225  		x)
   226  }
   227  
   228  func g2IsogenyYNumerator(dst *fptower.E2, x *fptower.E2, y *fptower.E2) {
   229  	var _dst fptower.E2
   230  	g2EvalPolynomial(&_dst,
   231  		false,
   232  		[]fptower.E2{
   233  			{
   234  				A0: fp.Element{17926225976816550695, 14023720841551579195, 6357178813752170559, 1429363592569423041, 10398153225153858948, 33711798988254397},
   235  				A1: fp.Element{2451854115792992988, 8983506616720050336, 2910564589437158732, 14075622914381394491, 9210830493684175792, 3356683084380210},
   236  			},
   237  			{
   238  				A0: fp.Element{5363401642911389912, 1675875184098052872, 15320530934239994732, 16287584047609698426, 10234580471621189795, 40152057551620421},
   239  				A1: fp.Element{2205557896318444105, 4065007897235623968, 4049591920488634456, 16004168804099107709, 13290522222905374988, 70089339901218536},
   240  			},
   241  			{
   242  				A0: fp.Element{1887285394871164447, 7142690945990485012, 11190732658400833066, 6881717282640585612, 12116088968278807379, 103071704289665226},
   243  				A1: fp.Element{15968649428224979513, 622837296484333259, 15527184444320989860, 2221190225062639140, 16647213690505955661, 110449865605275384},
   244  			},
   245  			{
   246  				A0: fp.Element{8732294600695513394, 7924365878303510912, 12588020556237861366, 10068029016225118132, 785053188876688927, 120347068207419939},
   247  				A1: fp.Element{14514622768737464893, 5553264648606662629, 12707457796658055665, 6066303778837734141, 8279024849745683367, 3564406469625657},
   248  			},
   249  			{
   250  				A0: fp.Element{10035254538193759291, 9758866910217654439, 2724217928072676653, 3087232989313988901, 14980280964270815877, 34590022796322467},
   251  				A1: fp.Element{15702474365778911803, 7256912742043165018, 1566344877835261304, 4035729625101537726, 16346625826270990512, 84087754076446931},
   252  			},
   253  			{
   254  				A0: fp.Element{8353555275402615800, 6017666668033757053, 13076202439893933084, 1913164921831891521, 13296563472388407395, 43485447354470561},
   255  				A1: fp.Element{12571296156797641372, 13988198528186614994, 5672291450663514913, 7033607850615758657, 16846880911077910300, 44471894806759326},
   256  			},
   257  			{
   258  				A0: fp.Element{1319289899879823718, 1591088360172441240, 7805677496653365276, 5569897284498525554, 5635591756513279404, 74901024143303203},
   259  				A1: fp.Element{10251017843654697682, 10395107644570958416, 3071938417266745181, 16127666859700570668, 5111665418914357408, 2168588371926498},
   260  			},
   261  			{
   262  				A0: fp.Element{7692831217085618076, 6702179445852008930, 11308520252707392151, 12038365346701529390, 7201289518723110646, 24757234241788495},
   263  				A1: fp.Element{17948859968330001914, 10144279887227452625, 5167544611537672341, 4094514978127885079, 17912079766649616973, 45691468580901020},
   264  			},
   265  			{
   266  				A0: fp.Element{3911440855998194160, 13198838254872822648, 13301641437413064797, 11598620320741753383, 6260523097595092689, 78284230929812985},
   267  				A1: fp.Element{7876366075466990529, 13523468790275433139, 982512625724968021, 2122595334378906057, 14803785928219626498, 71415583741911053},
   268  			},
   269  			{
   270  				A0: fp.Element{14923926944529083273, 3172840012894527710, 8293434476071337387, 16713256045335958267, 14057165773167995662, 57626475506313562},
   271  				A1: fp.Element{1362417042314121750, 3304417561071796103, 17626406775105189491, 11748219015558348173, 14151421547261463616, 82460535821434588},
   272  			},
   273  			{
   274  				A0: fp.Element{3641967463568066103, 8959416625663108732, 5147508997828480363, 16811352377666989046, 1441182181356889676, 52012247235371457},
   275  				A1: fp.Element{17686146190561162997, 11457769513035421935, 11629039572857129752, 16013548565551254584, 3489389447040062088, 108111902919606578},
   276  			},
   277  			{
   278  				A0: fp.Element{3810472718885394006, 2981020169366520013, 2816385682378197235, 153866317221550159, 11847618666936524337, 45551005605881971},
   279  				A1: fp.Element{3468095351662354134, 4642197759139584052, 4233923780028877603, 17495173774535575422, 6042084483130094534, 67695926977382460},
   280  			},
   281  			{
   282  				A0: fp.Element{1324953063484934482, 15924484690572898301, 11397027945012096698, 2650928770069584769, 15779309286157100138, 107280353846472153},
   283  				A1: fp.Element{7825813464319090460, 9031312139767459777, 142189155675192148, 6582610291000324889, 17102396003811978688, 22084094988625284},
   284  			},
   285  			{
   286  				A0: fp.Element{5210064249141309135, 1705543797894948713, 2628665872375881350, 13536211673960271710, 18420806283098729881, 115824256193502087},
   287  				A1: fp.Element{15082907751180860242, 6568697878451242210, 16244491021091296231, 17790448340613041754, 7733097786923840729, 14504831353209381},
   288  			},
   289  			{
   290  				A0: fp.Element{1708526764431582271, 13958279355051552323, 14990211071762970223, 7884242526085975541, 16332397605884981291, 80533848446738849},
   291  				A1: fp.Element{14979957683309612745, 6077136825354362762, 8344075647158254715, 10162044015152162839, 5892600246835629906, 87516868768986919},
   292  			},
   293  			{
   294  				A0: fp.Element{13823384149985104375, 400062563487168190, 14946453239900597346, 3063239780002983931, 12307299790663558215, 82575345472847758},
   295  				A1: fp.Element{4955387593349539956, 11580263215419679285, 13810204272372323220, 15118104627613044122, 5709821153764726112, 97792497530186865},
   296  			},
   297  			{
   298  				A0: fp.Element{8029106480647627463, 9339835209992361362, 2257747803917390435, 13841766612482081060, 11846105036367819521, 10985089103756089},
   299  				A1: fp.Element{12896564185217823813, 11446288085903243988, 7990576940036837900, 3323202217483830000, 8230734762253073878, 36590510406546600},
   300  			},
   301  			{
   302  				A0: fp.Element{9258620980666570289, 14799769271847025124, 3337623733744503313, 7847288847664005088, 4443979768963902018, 60018570132140318},
   303  				A1: fp.Element{2675246192261018596, 15150250319428322656, 8044595947793549351, 17819017498503740634, 8168003399719773701, 50802205070212383},
   304  			},
   305  			{
   306  				A0: fp.Element{6416675551757596528, 11137110755893373387, 12196234615749865580, 10261229930898283794, 16443034629854739148, 92762661836396101},
   307  				A1: fp.Element{2617757450501858457, 13481841765161333192, 14399351126797435540, 14845648777279341476, 16479218442290092360, 58694504406226241},
   308  			},
   309  			{
   310  				A0: fp.Element{2498292483400110656, 17577335584861186499, 17782334663901894811, 2829649086165738601, 1498570879458573752, 54126946483698861},
   311  				A1: fp.Element{13664305368410221366, 15519373467383236285, 6930373704919785768, 5035259077705758702, 15118622066815350587, 76218461077450180},
   312  			},
   313  			{
   314  				A0: fp.Element{2359464294290896887, 15126005627433822176, 8745471049496239338, 16249169944251666409, 5887779353961924474, 9756279022859315},
   315  				A1: fp.Element{4564346538121733135, 7083224900235365477, 12708889282498498077, 7850548098138279688, 14178174888234998222, 79663491154927524},
   316  			},
   317  			{
   318  				A0: fp.Element{2363371748841007386, 8201543480932182326, 3606722496785934427, 11335897361905574349, 7238564335142183540, 28370763379089425},
   319  				A1: fp.Element{17773120842166679454, 6968817275085296949, 589078002303466881, 11901496965136831973, 17508389603594408067, 105726710734816064},
   320  			},
   321  			{
   322  				A0: fp.Element{7295712044514929446, 1419749005841863626, 15921158613862149232, 9464988326326595083, 4254037448365833139, 69144288462579473},
   323  				A1: fp.Element{2330521880128496868, 6942731841460529291, 16753201799444057524, 5125438220420299042, 743707329901356982, 86418732453789215},
   324  			},
   325  			{
   326  				A0: fp.Element{10073672469351267894, 7530218602938011234, 12150950127635720924, 14699101300080070173, 3657462378365608060, 50677269975209252},
   327  				A1: fp.Element{16217326474471800173, 12182932688121705224, 9523557196391803719, 13559107473982584173, 14264388955497449506, 89155196038187526},
   328  			},
   329  			{
   330  				A0: fp.Element{8500524953883552338, 13471246252006481381, 399342016929624192, 15321780621361720165, 1735807610194144505, 81584295376527434},
   331  				A1: fp.Element{3028140852425956403, 9738549527114127103, 13145547273810927, 15439064114192138046, 15332022320720552951, 84308032823666865},
   332  			},
   333  			{
   334  				A0: fp.Element{8795699974103596314, 642987394252844125, 12559698238980671421, 15439596853334509309, 8192837603484177265, 86858193154220713},
   335  				A1: fp.Element{13665577425741482529, 6924526015867702055, 8773433633434605845, 4385776193759960181, 14751123844375383386, 84259094466106596},
   336  			},
   337  			{
   338  				A0: fp.Element{6308743764871173820, 14529376135552483358, 3992864522868188832, 16018150786687814926, 14942376479240309869, 30721880050281254},
   339  				A1: fp.Element{8640235552523037016, 9835096537876469025, 789797926152341591, 17554386444425767744, 2184317346571194421, 105569965705365467},
   340  			},
   341  			{
   342  				A0: fp.Element{10895141504918788686, 5671269070898752172, 9721970862384110947, 6958416614840799556, 18087813302866953828, 120526621462965167},
   343  				A1: fp.Element{4966785024859028542, 18182687130036955400, 10092534947477547130, 11367367723010839926, 7417818378683193783, 94369912047147779},
   344  			},
   345  			{
   346  				A0: fp.Element{5709922971951703245, 10382852257937442526, 3453842328747730539, 16133368957829378910, 8271517063962590774, 9539719803485949},
   347  				A1: fp.Element{1704900793320796784, 8995901783485359023, 9994857694012530400, 7408202244508772902, 18055801701001909838, 109149704128086904},
   348  			},
   349  			{
   350  				A0: fp.Element{8357460663115985094, 5765296628618444602, 6421674075164890879, 1651079036919805888, 1287520506307076832, 98975482931648514},
   351  				A1: fp.Element{8078944849704442787, 4038716179863104913, 8864619430523621449, 11983583689047803099, 2541042365160408900, 28281336919305267},
   352  			},
   353  			{
   354  				A0: fp.Element{13472601104608613638, 521231156844377864, 4649313698209759510, 5796371833735044995, 8684999192663632207, 51033152603009675},
   355  				A1: fp.Element{3409558318672010377, 10145443448574304058, 3995874611835909177, 15021984820089990008, 15242143999191686238, 73656911605031936},
   356  			},
   357  			{
   358  				A0: fp.Element{9770462122700591808, 17547477902406858790, 14010124614813851222, 4165622522809648336, 16982670942141592785, 28856170353703120},
   359  				A1: fp.Element{15290128055618535720, 17454664547186830394, 2442682438806360163, 18129275600450347134, 4187898517238597724, 22281223126461925},
   360  			},
   361  			{
   362  				A0: fp.Element{12998303454550796060, 5752293956714303316, 6752814987597331313, 3166668351495264669, 9929418606104908953, 29385282975911842},
   363  				A1: fp.Element{8756413506556179286, 143408982899135549, 2705277708630136288, 5154523209628123430, 6318572504564936509, 15532021916109921},
   364  			},
   365  			{
   366  				A0: fp.Element{18250508560718013179, 7486164413457419330, 8732750857092323232, 457033717118918321, 12167888022606617966, 20277559260742340},
   367  				A1: fp.Element{0},
   368  			},
   369  		},
   370  		x)
   371  
   372  	dst.Mul(&_dst, y)
   373  }
   374  
   375  func g2IsogenyYDenominator(dst *fptower.E2, x *fptower.E2) {
   376  	g2EvalPolynomial(dst,
   377  		true,
   378  		[]fptower.E2{
   379  			{
   380  				A0: fp.Element{2775408832476871526, 9008699192344519496, 1102884431771657931, 11532306452895462867, 5856674524343862704, 99430919144638985},
   381  				A1: fp.Element{15551301223123894338, 11614654532478001117, 17328204268627498271, 15544698294678786409, 1484472732893154418, 94605104690421825},
   382  			},
   383  			{
   384  				A0: fp.Element{15538486723908094425, 10978766348102143722, 15056964343960721360, 8732109610906448146, 8620899699042055528, 1351681984895437},
   385  				A1: fp.Element{3175104032835843731, 9314571151837830613, 14059118678096680542, 2500500275627160283, 18190796245603721369, 49058560079762280},
   386  			},
   387  			{
   388  				A0: fp.Element{2177050294381443304, 18124514285214412099, 9381797198372716589, 8046190315005422985, 9931273159159670369, 8036418831901820},
   389  				A1: fp.Element{1549742439238596983, 15619417821567290543, 9431498181016104480, 2850048082163302555, 17545915875775834651, 72687252788290726},
   390  			},
   391  			{
   392  				A0: fp.Element{16572119218800158686, 13113809656757589233, 12872678318679566545, 3255385198038960565, 17070551903094984362, 19742086936927308},
   393  				A1: fp.Element{12635717383520653743, 12204869003999147728, 8256611698395114158, 12382254302890131233, 603685913325391887, 60927550204070150},
   394  			},
   395  			{
   396  				A0: fp.Element{15497795759006280655, 16847324196958114585, 8218328297664216257, 15353718428023978640, 6357440186573265200, 109435672289072692},
   397  				A1: fp.Element{17126430308003109280, 8510055147921463837, 2424009275722614739, 9284383313721206596, 12867548350984534889, 46750493171897961},
   398  			},
   399  			{
   400  				A0: fp.Element{6993808529266055670, 10024278910497662817, 6638820395273369627, 17550512930522052164, 11971278025880956390, 4218694435301565},
   401  				A1: fp.Element{4117072311900938869, 8052759146924035127, 1883914237959498468, 843437547616490150, 1332392274725871932, 100467415201018114},
   402  			},
   403  			{
   404  				A0: fp.Element{10031273074038578964, 6635740043384123318, 2357760728051263554, 12405057037224522557, 2967360385882286162, 53130165628915609},
   405  				A1: fp.Element{9340276074750471546, 8779557686584984578, 12118682911992514942, 8792287004994786286, 11729922744948342197, 97115621599174349},
   406  			},
   407  			{
   408  				A0: fp.Element{8243258075199662251, 789646305137795307, 9501755430432007632, 15339245131080115010, 3036491630055907252, 4720358405852701},
   409  				A1: fp.Element{6272873484523042114, 18180794113363272037, 10135093694274252446, 13006427779172872075, 12612518697452888675, 4088970499189038},
   410  			},
   411  			{
   412  				A0: fp.Element{12559327402496405011, 13162954855686166920, 2622361684062280170, 16985128559432625018, 10671934355632922492, 22106668982430516},
   413  				A1: fp.Element{10342048742210368049, 4070662490021521195, 9050590024293164750, 6778744574336170333, 16385669267342466637, 110676722503289309},
   414  			},
   415  			{
   416  				A0: fp.Element{8257142434361782318, 11625188549524762434, 4162174183904813140, 15534648919830235837, 15345786270187761745, 49274740272907617},
   417  				A1: fp.Element{17452699565973497082, 1589725784862892127, 17590303103109791779, 8233530623701537904, 717929863606521126, 42679722481449639},
   418  			},
   419  			{
   420  				A0: fp.Element{17135289411523873787, 11725292909156152853, 16347014946116696110, 13323937426977246609, 8703182288833044255, 99079409785168386},
   421  				A1: fp.Element{9130446173903866415, 12010725389601806440, 9146179391205715125, 12338366065383252573, 9136251064810045627, 19315728226188373},
   422  			},
   423  			{
   424  				A0: fp.Element{13754907156191096138, 22846764546901886, 362622052532339515, 17013010775786408901, 13860043181928645305, 41171875858186406},
   425  				A1: fp.Element{16141340011263075417, 18360728019638818576, 16264128300543356196, 12473458415555386384, 18336837302801391285, 63727493440743041},
   426  			},
   427  			{
   428  				A0: fp.Element{3658804449581456923, 1347747705877184398, 3978302900333357541, 5081865331785059868, 1329643100050532471, 64102076251113639},
   429  				A1: fp.Element{6980160750786278877, 11782099681251246419, 5400025369843657828, 9848695260591786723, 7987487093370334558, 27115517650078156},
   430  			},
   431  			{
   432  				A0: fp.Element{408044901411159465, 18068234941175928745, 2992890619264445487, 8810813216534328625, 4005157550725594837, 26065038549738560},
   433  				A1: fp.Element{10975300981822504330, 15715038812214651197, 7602692888794350386, 12917547374269268270, 422938878523833779, 36305463980543648},
   434  			},
   435  			{
   436  				A0: fp.Element{10382180122959422967, 15807168734599653808, 18372044240449882372, 17642941170379477011, 10340644338271517361, 36063527972088465},
   437  				A1: fp.Element{17969075460977832752, 9177853432360197657, 2917850475625504299, 7079850467696515295, 787036529903063845, 107077168732108508},
   438  			},
   439  			{
   440  				A0: fp.Element{6502963492633373835, 9890663567118850708, 12445720805224431135, 6172862156806685987, 16576315346783950860, 5856337016358393},
   441  				A1: fp.Element{4476660199518722374, 3771101137683024451, 489075951782192448, 6489873046594013732, 280944977367484653, 69709094171715534},
   442  			},
   443  			{
   444  				A0: fp.Element{5629815848909521275, 5316587566230943622, 7982019375390215350, 15543803108203970386, 5941855484214597918, 5142365312974746},
   445  				A1: fp.Element{3442509802156923890, 6170315030905476396, 2122926024914179804, 17368567939581660282, 12200117156652989113, 7492215668086454},
   446  			},
   447  			{
   448  				A0: fp.Element{15017092692882720799, 2306085001940265068, 6863750251390498522, 772425548835188093, 7866794496176459304, 119478713276832042},
   449  				A1: fp.Element{539473290914229032, 10680532665300974652, 2401493774971219183, 771791041055281045, 17266300769954562072, 46203199265737132},
   450  			},
   451  			{
   452  				A0: fp.Element{12080185159744170157, 6121786867780957883, 13378966825252880343, 16978399570563241468, 13189121794372052505, 31306179382417939},
   453  				A1: fp.Element{6033582013845463960, 10201637616554513673, 3729832524646428556, 2564427389283182369, 662893124657004215, 101996692818942248},
   454  			},
   455  			{
   456  				A0: fp.Element{14864583376459179927, 16267452113314442715, 14135040057928255187, 712462212063179204, 12089188474131830930, 36841165809084721},
   457  				A1: fp.Element{13089068048776542239, 1568107234484844315, 4262841373517201534, 572974140393742986, 13114372614372436015, 221271375458892},
   458  			},
   459  			{
   460  				A0: fp.Element{15352358256255559128, 14776149476170502093, 13834021062045579807, 16108249515581661111, 7563707564996631205, 86582638494403858},
   461  				A1: fp.Element{16813570010660423536, 3065722476932153407, 8938713923763210470, 2255995557158728394, 8016474455897300271, 84052925693202818},
   462  			},
   463  			{
   464  				A0: fp.Element{15615825726181497195, 5658715128964929728, 13877560309241249627, 15409847795806183219, 382506108092986341, 33112756833083889},
   465  				A1: fp.Element{4921115267284233431, 2093038862301396370, 11859221373400371788, 14840702906540650688, 3187022540654844811, 12940014803022939},
   466  			},
   467  			{
   468  				A0: fp.Element{10653597201928750109, 13006094245282229535, 13295987796930539448, 16777781019019743602, 516306931828031556, 114717773318043797},
   469  				A1: fp.Element{235309942988776203, 14860563794932685398, 4559874204394395321, 16639699308077583607, 9227151754747780541, 15908917446924874},
   470  			},
   471  			{
   472  				A0: fp.Element{17337820088369903748, 8586614709689721762, 1507576901396006569, 12700849903501888588, 17971589925911161601, 108264042385722694},
   473  				A1: fp.Element{16945398252920060844, 12661842631743740793, 3757011696927843364, 15267617233875676717, 4747339870779259550, 34661428542359791},
   474  			},
   475  			{
   476  				A0: fp.Element{16466466374773138846, 14279763770124955377, 2253148650834359538, 7990858085823320889, 7124676177871440280, 94151727797031734},
   477  				A1: fp.Element{15321139925728056718, 15122461222407649886, 17533799169860262777, 16804941505997951982, 1600681788854461369, 44486672743339990},
   478  			},
   479  			{
   480  				A0: fp.Element{8867142699562737491, 18199028041645162481, 3517239929170429351, 775467166380995197, 5868381756625215392, 6197719424154602},
   481  				A1: fp.Element{9737125075096738524, 9629792455358261596, 11564279494282885105, 5089237230157463720, 17189088638807565425, 106712839297101083},
   482  			},
   483  			{
   484  				A0: fp.Element{10270843696704620770, 13223598872017291793, 9010388952516938805, 15912131807459901749, 6846913031975448418, 86431140578472953},
   485  				A1: fp.Element{15439335117817990542, 18208862128889198852, 1680174721576182500, 13180416124629130962, 7418066627384568449, 3653571306187636},
   486  			},
   487  			{
   488  				A0: fp.Element{1131060365675191416, 10374247235014096023, 5274169106847399340, 9643591707517384578, 8354961201546942085, 16860653124975415},
   489  				A1: fp.Element{7591061314547569259, 3687653994280978709, 14906524746128876973, 7376139658567228596, 3304769414542873433, 39389809689964413},
   490  			},
   491  			{
   492  				A0: fp.Element{15061500520004024506, 13781868913987378153, 1311923405823490306, 13614698003779137726, 2734567429318555742, 41565578486180068},
   493  				A1: fp.Element{2264606496492496938, 7463181801259856780, 4974231603582406689, 12631973597673125932, 13768142234619696863, 69859376569568629},
   494  			},
   495  			{
   496  				A0: fp.Element{12977806950220507699, 9598682745345891240, 12727041082031765282, 13876739454320532788, 16731345162096153922, 52377912619410421},
   497  				A1: fp.Element{9749487977108607359, 9452745135768007871, 17734899000824388188, 6032906020241168466, 3891046964558379200, 42965172988847872},
   498  			},
   499  			{
   500  				A0: fp.Element{15134142718037669741, 2650609953202022541, 18444582952265559358, 10072051383647105272, 1614233522361858494, 6353896085976033},
   501  				A1: fp.Element{1244819074686382314, 16827930012669440062, 7409202602064068605, 7833164804348414003, 14093967246945573989, 91886691830462491},
   502  			},
   503  			{
   504  				A0: fp.Element{3481568382353274479, 1454015438048276221, 18321294391133087854, 11721714833000613979, 10732204074831352562, 71241856315356756},
   505  				A1: fp.Element{2091942538387325776, 9875355486415603002, 12623384858601965052, 7559030465493899268, 7674739998354242578, 75767137192853634},
   506  			},
   507  			{
   508  				A0: fp.Element{5491757234451068988, 6182298996664147147, 1538132785577256287, 4999224323735886804, 6348107227722746450, 48518858347037381},
   509  				A1: fp.Element{15293807953430533698, 2990763629845967503, 13391735075948095730, 9673810945847290845, 11089480180973857099, 64742831177682886},
   510  			},
   511  		},
   512  		x)
   513  }
   514  
   515  func g2Isogeny(p *G2Affine) {
   516  
   517  	den := make([]fptower.E2, 2)
   518  
   519  	g2IsogenyYDenominator(&den[1], &p.X)
   520  	g2IsogenyXDenominator(&den[0], &p.X)
   521  
   522  	g2IsogenyYNumerator(&p.Y, &p.X, &p.Y)
   523  	g2IsogenyXNumerator(&p.X, &p.X)
   524  
   525  	den = fptower.BatchInvertE2(den)
   526  
   527  	p.X.Mul(&p.X, &den[0])
   528  	p.Y.Mul(&p.Y, &den[1])
   529  }
   530  
   531  // g2SqrtRatio computes the square root of u/v and returns 0 iff u/v was indeed a quadratic residue
   532  // if not, we get sqrt(Z * u / v). Recall that Z is non-residue
   533  // If v = 0, u/v is meaningless and the output is unspecified, without raising an error.
   534  // The main idea is that since the computation of the square root involves taking large powers of u/v, the inversion of v can be avoided
   535  func g2SqrtRatio(z *fptower.E2, u *fptower.E2, v *fptower.E2) uint64 {
   536  
   537  	// https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-sqrt_ratio-for-any-field
   538  
   539  	tv1 := fptower.E2{
   540  		A0: fp.Element{0},
   541  		A1: fp.Element{9669507733633691314, 13074846433352412541, 11948543988290594071, 11104573675215509690, 878729975203857826, 120237394476367878},
   542  	} //tv1 = c6
   543  
   544  	var tv2, tv3, tv4, tv5 fptower.E2
   545  	var exp big.Int
   546  	// c4 = 140737488355327 = 2⁴⁷ - 1
   547  	// q is odd so c1 is at least 1.
   548  	exp.SetBytes([]byte{127, 255, 255, 255, 255, 255})
   549  
   550  	tv2.Exp(*v, &exp) // 2. tv2 = vᶜ⁴
   551  	tv3.Square(&tv2)  // 3. tv3 = tv2²
   552  	tv3.Mul(&tv3, v)  // 4. tv3 = tv3 * v
   553  	tv5.Mul(u, &tv3)  // 5. tv5 = u * tv3
   554  
   555  	// c3 = 237702427642072544657662731610863241996908072983433720914596829155825880635712864411696995402952020023758239370111403151139377997388748144480691770738487127695940799749981367718443673617185911789718419957467908625
   556  	exp.SetBytes([]byte{2, 211, 7, 208, 187, 175, 251, 34, 86, 145, 59, 179, 97, 38, 60, 75, 184, 184, 125, 164, 174, 233, 63, 31, 94, 113, 65, 61, 218, 77, 92, 9, 208, 24, 175, 185, 6, 96, 205, 192, 20, 231, 18, 80, 42, 77, 108, 70, 10, 170, 170, 139, 183, 10, 224, 49, 131, 36, 185, 88, 99, 140, 157, 107, 203, 251, 210, 53, 241, 192, 154, 74, 218, 38, 143, 46, 27, 216, 0, 115, 56, 210, 84, 240, 0, 0, 1, 10, 17})
   557  
   558  	tv5.Exp(tv5, &exp)  // 6. tv5 = tv5ᶜ³
   559  	tv5.Mul(&tv5, &tv2) // 7. tv5 = tv5 * tv2
   560  	tv2.Mul(&tv5, v)    // 8. tv2 = tv5 * v
   561  	tv3.Mul(&tv5, u)    // 9. tv3 = tv5 * u
   562  	tv4.Mul(&tv3, &tv2) // 10. tv4 = tv3 * tv2
   563  
   564  	// c5 = 70368744177664
   565  	exp.SetBytes([]byte{64, 0, 0, 0, 0, 0})
   566  	tv5.Exp(tv4, &exp)      // 11. tv5 = tv4ᶜ⁵
   567  	isQNr := g2NotOne(&tv5) // 12. isQR = tv5 == 1
   568  	c7 := fptower.E2{
   569  		A0: fp.Element{1479358275892676257, 2814264704614556731, 13691179386454739330, 7530671302001941842, 60362263363904715, 37906327945374822},
   570  		A1: fp.Element{5350190547200862053, 10822704806123199611, 5122684409451163826, 10616884767534481491, 1436196917100294910, 20226740120672211},
   571  	}
   572  	tv2.Mul(&tv3, &c7)                 // 13. tv2 = tv3 * c7
   573  	tv5.Mul(&tv4, &tv1)                // 14. tv5 = tv4 * tv1
   574  	tv3.Select(int(isQNr), &tv3, &tv2) // 15. tv3 = CMOV(tv2, tv3, isQR)
   575  	tv4.Select(int(isQNr), &tv4, &tv5) // 16. tv4 = CMOV(tv5, tv4, isQR)
   576  	exp.Lsh(big.NewInt(1), 47-2)       // 18, 19: tv5 = 2ⁱ⁻² for i = c1
   577  
   578  	for i := 47; i >= 2; i-- { // 17. for i in (c1, c1 - 1, ..., 2):
   579  
   580  		tv5.Exp(tv4, &exp)               // 20.    tv5 = tv4ᵗᵛ⁵
   581  		nE1 := g2NotOne(&tv5)            // 21.    e1 = tv5 == 1
   582  		tv2.Mul(&tv3, &tv1)              // 22.    tv2 = tv3 * tv1
   583  		tv1.Mul(&tv1, &tv1)              // 23.    tv1 = tv1 * tv1    Why not write square?
   584  		tv5.Mul(&tv4, &tv1)              // 24.    tv5 = tv4 * tv1
   585  		tv3.Select(int(nE1), &tv3, &tv2) // 25.    tv3 = CMOV(tv2, tv3, e1)
   586  		tv4.Select(int(nE1), &tv4, &tv5) // 26.    tv4 = CMOV(tv5, tv4, e1)
   587  
   588  		if i > 2 {
   589  			exp.Rsh(&exp, 1) // 18, 19. tv5 = 2ⁱ⁻²
   590  		}
   591  	}
   592  
   593  	*z = tv3
   594  	return isQNr
   595  }
   596  
   597  func g2NotOne(x *fptower.E2) uint64 {
   598  
   599  	//Assuming hash is implemented for G1 and that the curve is over Fp
   600  	var one fp.Element
   601  	return one.SetOne().NotEqual(&x.A0) | g1NotZero(&x.A1)
   602  
   603  }
   604  
   605  // g2MulByZ multiplies x by [12, 1] and stores the result in z
   606  func g2MulByZ(z *fptower.E2, x *fptower.E2) {
   607  
   608  	z.Mul(x, &fptower.E2{
   609  		A0: fp.Element{10560307807486212317, 9936456306313395274, 2092561269709285211, 8738829082964617622, 5243865315912343348, 114311569748804731},
   610  		A1: fp.Element{202099033278250856, 5854854902718660529, 11492539364873682930, 8885205928937022213, 5545221690922665192, 39800542322357402},
   611  	})
   612  
   613  }
   614  
   615  // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-simplified-swu-method
   616  // MapToCurve2 implements the SSWU map
   617  // No cofactor clearing or isogeny
   618  func MapToCurve2(u *fptower.E2) G2Affine {
   619  
   620  	var sswuIsoCurveCoeffA = fptower.E2{
   621  		A0: fp.Element{4274545572028848265, 14157081418478689358, 13123833976752631407, 4466041663276938746, 9062541850312583986, 90030181981586611},
   622  		A1: fp.Element{4627353644986202063, 14941155654691983603, 14266958733709189881, 10264689865410103271, 10052798319587953375, 111844286035220969},
   623  	}
   624  	var sswuIsoCurveCoeffB = fptower.E2{
   625  		A0: fp.Element{10237434857876739089, 8476639787604822147, 6641637803208190023, 1721529389316620686, 8656544759275761743, 38999476160258021},
   626  		A1: fp.Element{2360755569119276357, 10390833517265838837, 12467133771585386911, 8219721226907645480, 3130947551623757939, 83517800164149569},
   627  	}
   628  
   629  	var tv1 fptower.E2
   630  	tv1.Square(u) // 1.  tv1 = u²
   631  
   632  	//mul tv1 by Z
   633  	g2MulByZ(&tv1, &tv1) // 2.  tv1 = Z * tv1
   634  
   635  	var tv2 fptower.E2
   636  	tv2.Square(&tv1)    // 3.  tv2 = tv1²
   637  	tv2.Add(&tv2, &tv1) // 4.  tv2 = tv2 + tv1
   638  
   639  	var tv3 fptower.E2
   640  	var tv4 fptower.E2
   641  	tv4.SetOne()
   642  	tv3.Add(&tv2, &tv4)                // 5.  tv3 = tv2 + 1
   643  	tv3.Mul(&tv3, &sswuIsoCurveCoeffB) // 6.  tv3 = B * tv3
   644  
   645  	tv2NZero := g2NotZero(&tv2)
   646  
   647  	// tv4 = Z
   648  	tv4 = fptower.E2{
   649  		A0: fp.Element{10560307807486212317, 9936456306313395274, 2092561269709285211, 8738829082964617622, 5243865315912343348, 114311569748804731},
   650  		A1: fp.Element{202099033278250856, 5854854902718660529, 11492539364873682930, 8885205928937022213, 5545221690922665192, 39800542322357402},
   651  	}
   652  
   653  	tv2.Neg(&tv2)
   654  	tv4.Select(int(tv2NZero), &tv4, &tv2) // 7.  tv4 = CMOV(Z, -tv2, tv2 != 0)
   655  	tv4.Mul(&tv4, &sswuIsoCurveCoeffA)    // 8.  tv4 = A * tv4
   656  
   657  	tv2.Square(&tv3) // 9.  tv2 = tv3²
   658  
   659  	var tv6 fptower.E2
   660  	tv6.Square(&tv4) // 10. tv6 = tv4²
   661  
   662  	var tv5 fptower.E2
   663  	tv5.Mul(&tv6, &sswuIsoCurveCoeffA) // 11. tv5 = A * tv6
   664  
   665  	tv2.Add(&tv2, &tv5) // 12. tv2 = tv2 + tv5
   666  	tv2.Mul(&tv2, &tv3) // 13. tv2 = tv2 * tv3
   667  	tv6.Mul(&tv6, &tv4) // 14. tv6 = tv6 * tv4
   668  
   669  	tv5.Mul(&tv6, &sswuIsoCurveCoeffB) // 15. tv5 = B * tv6
   670  	tv2.Add(&tv2, &tv5)                // 16. tv2 = tv2 + tv5
   671  
   672  	var x fptower.E2
   673  	x.Mul(&tv1, &tv3) // 17.   x = tv1 * tv3
   674  
   675  	var y1 fptower.E2
   676  	gx1NSquare := g2SqrtRatio(&y1, &tv2, &tv6) // 18. (is_gx1_square, y1) = sqrt_ratio(tv2, tv6)
   677  
   678  	var y fptower.E2
   679  	y.Mul(&tv1, u) // 19.   y = tv1 * u
   680  
   681  	y.Mul(&y, &y1) // 20.   y = y * y1
   682  
   683  	x.Select(int(gx1NSquare), &tv3, &x) // 21.   x = CMOV(x, tv3, is_gx1_square)
   684  	y.Select(int(gx1NSquare), &y1, &y)  // 22.   y = CMOV(y, y1, is_gx1_square)
   685  
   686  	y1.Neg(&y)
   687  	y.Select(int(g2Sgn0(u)^g2Sgn0(&y)), &y, &y1)
   688  
   689  	// 23.  e1 = sgn0(u) == sgn0(y)
   690  	// 24.   y = CMOV(-y, y, e1)
   691  
   692  	x.Div(&x, &tv4) // 25.   x = x / tv4
   693  
   694  	return G2Affine{x, y}
   695  }
   696  
   697  func g2EvalPolynomial(z *fptower.E2, monic bool, coefficients []fptower.E2, x *fptower.E2) {
   698  	dst := coefficients[len(coefficients)-1]
   699  
   700  	if monic {
   701  		dst.Add(&dst, x)
   702  	}
   703  
   704  	for i := len(coefficients) - 2; i >= 0; i-- {
   705  		dst.Mul(&dst, x)
   706  		dst.Add(&dst, &coefficients[i])
   707  	}
   708  
   709  	z.Set(&dst)
   710  }
   711  
   712  // g2Sgn0 is an algebraic substitute for the notion of sign in ordered fields
   713  // Namely, every non-zero quadratic residue in a finite field of characteristic =/= 2 has exactly two square roots, one of each sign
   714  // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#name-the-sgn0-function
   715  // The sign of an element is not obviously related to that of its Montgomery form
   716  func g2Sgn0(z *fptower.E2) uint64 {
   717  
   718  	nonMont := z.Bits()
   719  
   720  	sign := uint64(0) // 1. sign = 0
   721  	zero := uint64(1) // 2. zero = 1
   722  	var signI uint64
   723  	var zeroI uint64
   724  
   725  	// 3. i = 1
   726  	signI = nonMont.A0[0] % 2 // 4.   sign_i = x_i mod 2
   727  	zeroI = g1NotZero(&nonMont.A0)
   728  	zeroI = 1 ^ (zeroI|-zeroI)>>63 // 5.   zero_i = x_i == 0
   729  	sign = sign | (zero & signI)   // 6.   sign = sign OR (zero AND sign_i) # Avoid short-circuit logic ops
   730  	zero = zero & zeroI            // 7.   zero = zero AND zero_i
   731  	// 3. i = 2
   732  	signI = nonMont.A1[0] % 2 // 4.   sign_i = x_i mod 2
   733  	// 5.   zero_i = x_i == 0
   734  	sign = sign | (zero & signI) // 6.   sign = sign OR (zero AND sign_i) # Avoid short-circuit logic ops
   735  	// 7.   zero = zero AND zero_i
   736  	return sign
   737  
   738  }
   739  
   740  // MapToG2 invokes the SSWU map, and guarantees that the result is in g2
   741  func MapToG2(u fptower.E2) G2Affine {
   742  	res := MapToCurve2(&u)
   743  	//this is in an isogenous curve
   744  	g2Isogeny(&res)
   745  	res.ClearCofactor(&res)
   746  	return res
   747  }
   748  
   749  // EncodeToG2 hashes a message to a point on the G2 curve using the SSWU map.
   750  // It is faster than HashToG2, but the result is not uniformly distributed. Unsuitable as a random oracle.
   751  // dst stands for "domain separation tag", a string unique to the construction using the hash function
   752  // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap
   753  func EncodeToG2(msg, dst []byte) (G2Affine, error) {
   754  
   755  	var res G2Affine
   756  	u, err := fp.Hash(msg, dst, 2)
   757  	if err != nil {
   758  		return res, err
   759  	}
   760  
   761  	res = MapToCurve2(&fptower.E2{
   762  		A0: u[0],
   763  		A1: u[1],
   764  	})
   765  
   766  	//this is in an isogenous curve
   767  	g2Isogeny(&res)
   768  	res.ClearCofactor(&res)
   769  	return res, nil
   770  }
   771  
   772  // HashToG2 hashes a message to a point on the G2 curve using the SSWU map.
   773  // Slower than EncodeToG2, but usable as a random oracle.
   774  // dst stands for "domain separation tag", a string unique to the construction using the hash function
   775  // https://www.ietf.org/archive/id/draft-irtf-cfrg-hash-to-curve-16.html#roadmap
   776  func HashToG2(msg, dst []byte) (G2Affine, error) {
   777  	u, err := fp.Hash(msg, dst, 2*2)
   778  	if err != nil {
   779  		return G2Affine{}, err
   780  	}
   781  
   782  	Q0 := MapToCurve2(&fptower.E2{
   783  		A0: u[0],
   784  		A1: u[1],
   785  	})
   786  	Q1 := MapToCurve2(&fptower.E2{
   787  		A0: u[2+0],
   788  		A1: u[2+1],
   789  	})
   790  
   791  	//TODO (perf): Add in E' first, then apply isogeny
   792  	g2Isogeny(&Q0)
   793  	g2Isogeny(&Q1)
   794  
   795  	var _Q0, _Q1 G2Jac
   796  	_Q0.FromAffine(&Q0)
   797  	_Q1.FromAffine(&Q1).AddAssign(&_Q0)
   798  
   799  	_Q1.ClearCofactor(&_Q1)
   800  
   801  	Q1.FromJacobian(&_Q1)
   802  	return Q1, nil
   803  }
   804  
   805  func g2NotZero(x *fptower.E2) uint64 {
   806  	//Assuming G1 is over Fp and that if hashing is available for G2, it also is for G1
   807  	return g1NotZero(&x.A0) | g1NotZero(&x.A1)
   808  
   809  }