diff --git a/CHANGELOG.md b/CHANGELOG.md index a6f8e7045..5e197e121 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - [\#1044](https://github.com/arkworks-rs/algebra/pull/1044), [\#1084](https://github.com/arkworks-rs/algebra/pull/1084), [\#1088](https://github.com/arkworks-rs/algebra/pull/1088) Add implementation for small field with native integer types - [\#1061](https://github.com/arkworks-rs/algebra/pull/1061) (`ark-poly`) Reduce allocations in `DenseMultilinearExtension::{concat, fix_variables, evaluate}`. - [\#1112](https://github.com/arkworks-rs/algebra/pull/1112) (`ark-ec`) Fix rayon::ThreadPoolBuilder panicking in wasm32 when parallel feature is enabled +- [\#1119](https://github.com/arkworks-rs/algebra/pull/1119) (`ark-ff`, `ark-pallas`) Add Sarkar2020 square root - useful for pasta ### Breaking changes diff --git a/curves/pallas/src/fields/fq.rs b/curves/pallas/src/fields/fq.rs index 5ddecd35a..335d02a12 100644 --- a/curves/pallas/src/fields/fq.rs +++ b/curves/pallas/src/fields/fq.rs @@ -3,5 +3,6 @@ use ark_ff::fields::{Fp256, MontBackend, MontConfig}; #[derive(MontConfig)] #[modulus = "28948022309329048855892746252171976963363056481941560715954676764349967630337"] #[generator = "5"] +#[sqrt_precomp = "crate::fields::fq_sqrt_table::SQRT_PRECOMP"] pub struct FqConfig; pub type Fq = Fp256>; diff --git a/curves/pallas/src/fields/fq_sqrt_table.rs b/curves/pallas/src/fields/fq_sqrt_table.rs new file mode 100644 index 000000000..896961fce --- /dev/null +++ b/curves/pallas/src/fields/fq_sqrt_table.rs @@ -0,0 +1,974 @@ +// @generated by `cargo test -p ark-pallas --test gen_sqrt_tables -- --ignored`. +// Sarkar (2020) square-root tables; see `ark_ff::SqrtPrecomputation::Sarkar2020`. +// Do not edit by hand. + +use super::Fq; +use ark_ff::{MontFp, SqrtPrecomputation}; + +pub(crate) const SQRT_PRECOMP: Option> = + Some(SqrtPrecomputation::Sarkar2020 { + trace_minus_one_div_two: &[ + 0x04a67c8dcc969876, + 0x0000000011234c7e, + 0x0000000000000000, + 0x0000000020000000, + ], + g0: G0, + g1: G1, + g2: G2, + g3: G3, + inv: INV, + hash_xor: 0x11be, + hash_mod: 1098, + }); + +const G0: &[Fq] = &[ + MontFp!("1"), + MontFp!("19814229590243028906643993866117402072516588566294623396325693409366934201135"), + MontFp!("20019177140809064856865169274912835413481202136612124135236710364734458304827"), + MontFp!("10322960402126329015066598839303488828044311568020905812926837507672732938737"), + MontFp!("21078271063022430028696728003872866149171842417899417285171528540187692932029"), + MontFp!("28333470709154160398483046285549987038354231431211542913062972638564176977924"), + MontFp!("19006925554968504816359936809847955939787128587616950469497412477184513008468"), + MontFp!("5502296064312145673757596732280485486122572242476798388150213060669188000279"), + MontFp!("15482997364772194801093354052371644584317737593254729763616822834061572187373"), + MontFp!("6371425162744549038927838480802306418884615321270277782205737519592341692873"), + MontFp!("292819629968370755915714553159092743142749851600133996301475667383419075140"), + MontFp!("21417821667286396985928993603844508272104402934459575547536647440539663880283"), + MontFp!("11073511170277481083584852681226265017157981278021582560430285947213862282768"), + MontFp!("7077410616453059027758662575727442099236384117594699398242638718102500727141"), + MontFp!("23933794409820260598323854793126629917172888539876241648080130184437332870291"), + MontFp!("12118090487180933733342279272857051172546999864498507444444997356121053869132"), + MontFp!("3871080950800814625523412335787101644253574632347917159652859787415357107205"), + MontFp!("21268223672629892185948200847661926013431343433076960208520333079683993055858"), + MontFp!("23489054647158899793093227382854690131902618696751030662314020817118588660667"), + MontFp!("9065351758564610219421680209134839606921590391389740736324573406489429103494"), + MontFp!("12148905795911782372235484606446249202418543072797956324343191361859234739500"), + MontFp!("3689195682457510432767863003709581825863061093017132972296726180442138398898"), + MontFp!("6923082823437747520320247641383068311882115050321444222138238908748282302882"), + MontFp!("5422405327006710031108340347457225999432927866487068938527267230091364608975"), + MontFp!("19925379356166865965368544439474303077423128194071205157810056501184379668790"), + MontFp!("4637998594417890500948275146335378567125468178155325821279210430287685516348"), + MontFp!("7023677231072726651661874764604378383794851382362728659656205129213002121117"), + MontFp!("9251172592500808789530550885958160011157260055888573839546388187566524956118"), + MontFp!("4201161516223326156894410098444521006857146250182234935255173053057814296126"), + MontFp!("15834390080935287111554976277986348724995196102040386227569333929446834243594"), + MontFp!("11989175002223705231092251588667995186758241171487887220681614099538639157584"), + MontFp!("28810546740926998515180818394350327003159915284484673919153381431971833608518"), + MontFp!("1603855361858706592844816436429150474566938456649022744208671126049801197523"), + MontFp!("12397258822206161895879271565932920700496045483935999644819956080421873343372"), + MontFp!("12135792172515834333451656088244236379014900085454559070322198101399338311428"), + MontFp!("3655918794011830545315512661755708476146579652069727979495574998032511820156"), + MontFp!("21886949404672347964332692455965191365653474766798491229561137805378839580733"), + MontFp!("8505230523543539406381456070775123958257310437715283074061316388384825872316"), + MontFp!("27011269827122236467882473871475160914975923406532308027887524289188354138841"), + MontFp!("15811476453123103854258877022815693661789490758015600892850347491339389029638"), + MontFp!("16635457615894313961844206837940182677006448721624441232675149407469000978440"), + MontFp!("26077120379164298675457595740026472558136872413446248000369676323033510895788"), + MontFp!("14280825222090052482892640210872177738747772607443057917733793251111219523846"), + MontFp!("2711052039574922391889784388542171741741355002667734470735807447481972423322"), + MontFp!("20214367088922741092348744291013762895537844534543453512049775509150405047966"), + MontFp!("17618277738176758716192402476673680885704219693852966183752042872404451577945"), + MontFp!("28256547575601365888728093102215919939670805520544786516687203345500558000297"), + MontFp!("25152830836175344729383793551503574953184522668250809097602131948313896967216"), + MontFp!("16581836034278871345503434649091419069208826948601588562721141757914299813652"), + MontFp!("9933717307172683656999749364481957056181714921867110420983517634645410054792"), + MontFp!("3418253120279227053245422678621805114340748724348501911927667670485851976100"), + MontFp!("6043251970223416848298276967000172194835984210066278969123563368782849745969"), + MontFp!("15720697092596730245146141449498925663888616364690010760548135915568273206370"), + MontFp!("3442905318551293696781951750599632299784266099699708101118428131710848946805"), + MontFp!("9222731033359219486295736460034903295286458561510217690405222470016595849067"), + MontFp!("28931058341734435229753727914704002787330318649942130994668930375354531545902"), + MontFp!("12406624674323542554343541570595502461497393843310086226685661765223383355578"), + MontFp!("24487505106045662151796157208929739249130468353503393760410914045954495472418"), + MontFp!("20519127261720135811589166837939742082806415900239903247503917352078319441025"), + MontFp!("22384997461042959006248023024578904632078987910073107434413907716660336236363"), + MontFp!("2458021301897719801237888581060189456269637031546327655985064389353012295918"), + MontFp!("22500213656644744267403848179708605164638358447701212304952533520405558138085"), + MontFp!("27047059075611221838000682175658660393220077188589460576735750005918565641936"), + MontFp!("23835626947141044998195682705302294140291795023725534069697496776349543246958"), + MontFp!("19539024977649559784260714624876575250810510507969145056159375673016375986401"), + MontFp!("11269649842271633267234789705252929618231186849562273223227710678344506574039"), + MontFp!("15523508619278826400960003871185449165387852436145685754691085021160363062412"), + MontFp!("24468894688067683137725838563320050377323672240880274732752631905066627489899"), + MontFp!("23080398197158684349675408645571373076163051251574496586973676852411906288617"), + MontFp!("591035296071370079224939826882343904962748462557204053056540392513785393492"), + MontFp!("23617759965383182878480522505300077395542363553069929007209495349607296842377"), + MontFp!("21975152721167203028688967578964185974131609708302193116989738363237024699461"), + MontFp!("2418655391677592415756440573526180163989194765277916801910670410241105431370"), + MontFp!("2348610592503392647054139442632438515974138290684737865926809649930989307829"), + MontFp!("15322572677567125159270216342721640897348862785799420719939475685245716650588"), + MontFp!("20438615516366121143599526260987822084590848274724727734042205336969758838114"), + MontFp!("12052188589019339014351043290875533552096015406435552242171790609760398217635"), + MontFp!("20326606641268416363093943126727545921094727887377218532777936989918224938272"), + MontFp!("7578506611505138637878033341672888024238194114812263568279235889327887664719"), + MontFp!("6943490257189343847480391297041747593953117817021431998037230079803108537746"), + MontFp!("13684491874646436212948398289218830547964219815226363763408106265263205563073"), + MontFp!("17084396686704471961923938272224951846597414676846335687643777384756499297738"), + MontFp!("8394063778157995231648168580820841997979871183724541462393738749063270368155"), + MontFp!("24855275707850262206503891483084713110187471778721281258053034731172018551827"), + MontFp!("19052803036112610604359427029029197768105070089440745199084081935742076138397"), + MontFp!("10140018018467173288773738740067215944223379891040988032188528422007692515036"), + MontFp!("18014353629650768823170974141501484105999655303049940371562812545634401645097"), + MontFp!("19424531000271950722364939191236934685421742270923034223613901855180934170483"), + MontFp!("5188658905033165915518753303888360856295569044338850101037671669528677765147"), + MontFp!("17503154636902430463074212124592058839655482086862645079693334262971111485054"), + MontFp!("4080474559509509180355195553849783442702639993711892226395924596353857230523"), + MontFp!("12482593784143490413698579256953601668528044333708208456610840719788851976918"), + MontFp!("11941744388336353901329237251221477234999806543985386208192465225218895440252"), + MontFp!("4427865903090610274565212582709140090597162123272677573142177927268032617823"), + MontFp!("8912777325113039206041298488795725781132033790027326844738347903180530444156"), + MontFp!("8431673718327695789787205051192565253990063859051589749480431103100444819230"), + MontFp!("22464703321078117725716914685967487003327517093984696777614746289247936103659"), + MontFp!("16532361952818383217067100393102225013041139898014563179978337850983198116762"), + MontFp!("22965085050813797579472057935358742924977869746011862587142697380930231975811"), + MontFp!("8005822972346745335050682876233525259853603097375026982852063324390551082105"), + MontFp!("27450857849957093909140493810708803142531909731240161394181225694414607764693"), + MontFp!("10275478878080021321014742978751337743310547839020833081323499472218778392770"), + MontFp!("10416197291853789269238850126383111125191620660375907581286323074888147213074"), + MontFp!("20822075423391742790013056971726282080836016932054938724665350934930316168183"), + MontFp!("26580063498946493080170251907472028071548453611062386674712602722374551357584"), + MontFp!("9946345841921672267961975502076772771047463697084169377441801163173704598133"), + MontFp!("20114026469804332884939461484196664492512559417401757500944217813751616874950"), + MontFp!("6573919354753449704761525329331918021460891799362921422483358021831832178114"), + MontFp!("14897745297275815064638216783664503993278503609876031050250718659064686963225"), + MontFp!("2474929399786682195571038667062082541843064517240507684817427290915574204838"), + MontFp!("9604191865661135341573580752193768352554843893232262845792389188402491743293"), + MontFp!("13888652411826060892239513774213619572084087401681567798304791855256864400170"), + MontFp!("17417389190266288483952868336909892344797311292305358661169346407390703021293"), + MontFp!("8264202090075000890483161208561007393256477325998702280159568855496395277670"), + MontFp!("24172103144829795588590177041048200558148250090286032234300391513373399318574"), + MontFp!("7821958252204005431258151218338572812529268708076848007414516314663094163434"), + MontFp!("10744306518061159447443434693223109362443433279762883524030547793412337402838"), + MontFp!("5844372846658084528781024276323026175139739130812386989268410374761326535353"), + MontFp!("33874860109221189859449848027554199271822201741080216367291108520624044223"), + MontFp!("5283400598291284097397655670188846909834334679737100929678809284366502368698"), + MontFp!("15181952157828044174021077163161217388957470456185862419450854972232381161365"), + MontFp!("19804600904920209533240941682760395720090486093176085117993621280261158432608"), + MontFp!("19164146164924009957431231473828341965018582411606810532155921866644519172511"), + MontFp!("20280583879275884835051243336266464727646526940455908939723863792962334045258"), + MontFp!("25724547165085208546797974513100586265895657535297139882323221110827315951946"), + MontFp!("9678050564739235245423836049192195883761568588269534386423011926107742772395"), + MontFp!("7845197979437392636510445179214489408922217212343096905193174353383226303031"), + MontFp!("18943328927952174274385984876977705741702188068009225903918680542593397742053"), + MontFp!("24587127671840133213791902490924627443001969603097575553283109427075701688787"), + MontFp!("26796283150467083715575308804147538344862265804762721358257949095037593015996"), + MontFp!("1416087470848013819904978519083669509017890761371015647073460109263396385910"), + MontFp!("24625411382199414356783763510405281552004256859893116095484352237934605670837"), + MontFp!("3400055075450642724643170303362889560555574910168200500740765165073949391325"), + MontFp!("18230918631826386551707405340260504416970627570634485795792415164352988902216"), + MontFp!("13401756809151409032397591057053734925893641408565892527200476358978465667242"), + MontFp!("4219215727857705522079563186346576857173762661807070975149323102571444179740"), + MontFp!("12700045101191416183710614080799206492615300209165372457341928937107002651567"), + MontFp!("24150784723010506495623468809652494183603021374949948112614211287011081715804"), + MontFp!("21596720878609619338312864081043442164565083840690179324919289470913319133098"), + MontFp!("13901202035629936980606273554163789121775599802892035603263333916691878020784"), + MontFp!("26792066625334956688845285034569969572938494683046514647967473038625735789124"), + MontFp!("24527035587632481487608922550729579420225623366790936000466982131032149501628"), + MontFp!("10876553378223715032838542366955301326434624476970945454292681901327298380973"), + MontFp!("20595420174408968399648500181681551830357154286349271248156728819592414824045"), + MontFp!("3576078826275133901550378813627859480607457379837249389690637278880521669996"), + MontFp!("13564006962575051726663536861683153954247076615653175916596646438407948813550"), + MontFp!("11702377627645655308619868530655205041826799845123512221303280655298243612364"), + MontFp!("16113509943737328491438697667546314368460928710838633126415109751209554473498"), + MontFp!("18701625582063921860746070186514473676566011348714392394711311187061034137146"), + MontFp!("5967361756302523537902706502052570907511325339242328790632059733307036255700"), + MontFp!("21142003824503404904575361022989171663117697892142725584466521049333820911763"), + MontFp!("19528736927471215050776988488280262147352243765720238244348182364230830066828"), + MontFp!("22953420935764290802151584803367468810442703581235406205476694002003194634968"), + MontFp!("22256696346964613037007515565258848742101884724869530664659165051777997324123"), + MontFp!("12635070337357928456442690426671895087399147576183200860753391885779537513040"), + MontFp!("15108972103988016839755163066022544360788859339164941364865118176490744073596"), + MontFp!("18843481335737021341473651973782383686752284464650783469366210094868292420651"), + MontFp!("6131635123455773881211553507082416864099186680705317975233157377533668618009"), + MontFp!("28732980897120985647990582491786219745788985651940249584027680104215745785561"), + MontFp!("25763309124717056909593490164700406433788409930662068994426666518623104157016"), + MontFp!("2281821723529446984065305328573841186304887028260915109700947095047310871539"), + MontFp!("21721895833462186481968838246095581923104240346353935835877584307670567452751"), + MontFp!("23722014983696507396982012585406361209103925718439273044809519574987880455947"), + MontFp!("22758362831912067728931238804053547787410159694764478067746448538016860855246"), + MontFp!("2754350358496623209395837870977360195365365263615027045819648863320693538575"), + MontFp!("19908273646340584191452872183506452167361536873254612044193581185815325153946"), + MontFp!("9509816323690915406117546423139316404379517167956026299366201454403124981672"), + MontFp!("24173895775068348973875143487191955373295834551377081748982704747625127662032"), + MontFp!("20631635414669894550280126433028831505636161769302009271812210285753703239117"), + MontFp!("14779047872146821790912086657116333178944700119070352689212108088022694994306"), + MontFp!("10670085644660095656073690183711191771245523861452317765608649640607218800820"), + MontFp!("15150071388595744030530020013377848404755531801320663801917006292786068372278"), + MontFp!("8287894137853127777466876253297900632248392355216667147735935548564850866138"), + MontFp!("21258551683622424862419438637712815720640048601043052779640413765629108089130"), + MontFp!("27844382211137906581502079591250421275454616222094655650999196817542685727717"), + MontFp!("8349414002724407982593862335705459637857724178638646741455511294019629806691"), + MontFp!("18612285473582681668168007337583564766014724878467841612559591829757012632193"), + MontFp!("24248323517232394991811084555950123231794953425994878960002677994873619232304"), + MontFp!("21193402038238282927845536839047409977607143127283403142780680676850967151312"), + MontFp!("24679241754936082428813659562902816145557650988859399304561188673210834459725"), + MontFp!("22231906695037000057664743425276442364643846811643609102612348257807968184014"), + MontFp!("13697804066119280052520524844474785116670163690441190165972380981109810712753"), + MontFp!("24952060094943812923412905966006803463641145804269656271068205831544907159830"), + MontFp!("20980215330826589445629263442061718831086793968576581036623609195729075744366"), + MontFp!("24529612717944174160860544600953761134510372503580376045406682241063938264311"), + MontFp!("8212028470104404398397736639334118596221418562758353288499262833186460638621"), + MontFp!("25475956744202080449417631857335452751163986770279602206014902990534727468839"), + MontFp!("6729540003825661093031420984449480201495425503342720197473118369871879496157"), + MontFp!("28248804473282254884762156695038875277961239116929803231640467700304799960552"), + MontFp!("12393774615819616608234583298142215541798046302356519242228934916800608423232"), + MontFp!("3626391350578880168332214112408479982265221163823580344576948272936948050490"), + MontFp!("26120502884510310415521646694999178879212307765191367474212479101739982995107"), + MontFp!("78057356232145288667795056578240893501544399453824581160838278725417816445"), + MontFp!("20373338067782472484833117532520992033108323694998790766017859004310271537304"), + MontFp!("28560946465870901662230159604998741988164076239722001356491980054303398128314"), + MontFp!("1169635335910565841908129697298250619284910135091067998205374197728295238083"), + MontFp!("20577392892554134891029690908959136438099519190008528588133852411692475483889"), + MontFp!("13682677606013991973507568964593042774019774617198738328250227546736719195161"), + MontFp!("25225454014569027023114401188220311054974672146077308277435278551618979241004"), + MontFp!("16728101659245489709193999855986543020199556123666360948048807943707097781635"), + MontFp!("8346561647089625411033155860338943463711192416676470554910552822120549157363"), + MontFp!("13969676871598302041871992029780291606814242288007692492962267801795789396074"), + MontFp!("24804000305714706042123501135047577669705256297610450803641189707295987826628"), + MontFp!("1286798699289419454655497097572233912635887679656533727901900330864991976038"), + MontFp!("5864634902591358553472276924780942816887696245237239502745681709172605708243"), + MontFp!("18901097235683464468945280350237106594628808231356360135941496001427368186834"), + MontFp!("4894505412513410376582683984336422396023720176681378538266632766892341430357"), + MontFp!("13783953765780711784065650621230540023461342043088588997513252779381796338102"), + MontFp!("28152757804434429937266805375178708637864336621349977236807666142280236768163"), + MontFp!("3891510431890856843479951481486385787822788187983009815760559111012299919790"), + MontFp!("10984062351945852172985095161679670787228183252263029323632057805868773411733"), + MontFp!("23387091211634779645902199018116146765082491341723506749352045070607513788120"), + MontFp!("11996106318777315918260601729183853200380439428261794922398217571055556453137"), + MontFp!("11105257251390201313091675485583145514922079981682170163470780897272595905407"), + MontFp!("633980040691071987938793316237501832663754491895039535554412370182111847497"), + MontFp!("1261981377450226360256202264216862780221276230953637113469156054770399476208"), + MontFp!("21464037274528713300151869283647058358394892905175822798206551545491872288782"), + MontFp!("22372127023793964958099453544653599371910470610806899772042187111767264354942"), + MontFp!("892096303115978646889735599785848815064316297180940091762266698903710869083"), + MontFp!("18212886334133377773114933759672958332113545674159052602511724792384215340247"), + MontFp!("17997596797433676896267391303452460626119365818245639450785068215525693692837"), + MontFp!("26161358992231180588047067516242514609872238744711446080201849060154432066701"), + MontFp!("10640126132084355774860099966961601212837822350651353733532931489539587873039"), + MontFp!("12385562769388165829428694270365354706682395528707234443516988985674172280729"), + MontFp!("20187661872191683574983498869847573288548835722729475825172757684894415593932"), + MontFp!("23306843108298180473819591100865971961522823549543536559669472225857090274314"), + MontFp!("26276687597973827065491167761066960848556250507812121100783605305707393617221"), + MontFp!("3842933786376662931814178979896021731347518557609593612805190558542802385667"), + MontFp!("11080308986773343213460480302414187477893660837700952554899015979988273889807"), + MontFp!("7101967760220107646624525885898524357129491087321445855543879523162659236269"), + MontFp!("6186778677773354646640467796370511310902830124990582275223306390019431839995"), + MontFp!("291366067404543288820267899306379162059548261054315911717102362550282326557"), + MontFp!("8340365897658603304267291363063858382165495290811409677242559292672989979199"), + MontFp!("11194816252822078517999637139209581309381379294432036595600500636827055339804"), + MontFp!("16344933171678765316407737035949697207918807429038623874684248921494088487941"), + MontFp!("4575606483951683512652698722440110385654946573939705075772439086707749026423"), + MontFp!("5300199185080460827853802221431146852790216182228870595306604048568951290958"), + MontFp!("13361631941995071847210591847452670846826773315496321540299601320967096346163"), + MontFp!("8326104634440450354857717232108774548719414283761363312001036464908654911728"), + MontFp!("9961179948290386384908948681407203296073887210835155388482265480312896883863"), + MontFp!("3516966495703055877494600134321770894197497382409625788425152641806937273454"), + MontFp!("15005083968169986203531927993496410947033101400925721337341556707853871873350"), + MontFp!("11939900782795961498032472177440015459128496010704420769434427187173695726197"), + MontFp!("7857416391704118658741983909038318463039508276738910545522502614833103268246"), + MontFp!("2454925146902270097428769315112755958084844063974838290224682623533424072762"), + MontFp!("12662217335612807610972144707883207489730059868164122326257701302069300961377"), + MontFp!("22280201436678711728813473597070636980096229529854013424451290938691708292425"), + MontFp!("3199246053956001065461519323141256370048856745487225918011985146312810331509"), + MontFp!("6237356432145691127608376743620371839617138769459358313708688838027566884467"), + MontFp!("18151521008661840130720973687059189136020023724210289126815793636413590218360"), + MontFp!("16101771359952366292817859042495808997908717354467522975649482388746563202366"), + MontFp!("22281221324939633452191521031534044193578999127987044009245454050302938027274"), + MontFp!("16615792524516839910844389158331061305000025804082880522334235867066841375892"), + MontFp!("18780714296473604696257496911555278314517994115851019851946479760948007177087"), + MontFp!("3134984439002756664041627406444921196585943201248272320301354620076366900035"), + MontFp!("28220862643113830803795829245390440336273624763938361505318736236584257147091"), +]; + +const G1: &[Fq] = &[ + MontFp!("1"), + MontFp!("22426793038789574175596682555510011126446827461592694588596954912018649138537"), + MontFp!("12852111537791153370818599713791219374604951663217502622770936290355990203569"), + MontFp!("19326658700411042673632733044682789978851986966449552305255917965588664008587"), + MontFp!("6127652191210016876084848799392911130047036598987912435258055609820060102924"), + MontFp!("26221493651844320702656806785030943095653834188627226606979403202954881673526"), + MontFp!("28876692267422314534705733250827066925663597531254463079653699632853857278719"), + MontFp!("17025916998848101659682523416674342896135475616613032469211234262296440989972"), + MontFp!("1933957670562101914585955443663740425677241861165284373991835618452614157454"), + MontFp!("10936618740538372280227318034444816831120697271307473796858328253413843394286"), + MontFp!("9130454323831944780739598294335343198497060265605566011011726380736387183102"), + MontFp!("24411370358693713185594781241193796310095455355859556409607434134376510011182"), + MontFp!("6840318787645295284437501013282846759686927112485079622846436935995433234216"), + MontFp!("20130100247985555557089587153190935878482655392067682454727749812721876971829"), + MontFp!("22596778221401532608871772020715238967190151450223847723921894533847779399034"), + MontFp!("25304764311865322096002352072898508378691684299870308641857359385562304844905"), + MontFp!("26364943572312187422331641474781443956155564383082617186147261935296699093787"), + MontFp!("28514231070563287263812610202370573931206157770151956017760605522381302779234"), + MontFp!("409152127045458166610879055554132688991852777939377786584202110156213306395"), + MontFp!("22686518589774677123114400985023035787141868489218512449930235087199218236886"), + MontFp!("7038630247377169304876219789928412047839365286573382779116143248223437941103"), + MontFp!("19749306171321647381776006404235886882115625918681283823483362895059273163121"), + MontFp!("24072607780982219510532173009349050722215712782561837326037746006065508469537"), + MontFp!("24525572993863611033454517199096669416424960449313919032939384732037101448925"), + MontFp!("28926534109867045486336911090733834641236361251998930714249141147425040415740"), + MontFp!("12730098082044807895033979226436380102028575977169307154939078058623015181640"), + MontFp!("11395194311209844222030962861860317953295087181802823438105606867380439496375"), + MontFp!("5824798130006368407271414228052805806086671753273547025221579854173674259099"), + MontFp!("13978485107837385602481355528983998223654434182526836228678144978542074394426"), + MontFp!("3314290124098145282480195516874491589417273126244918690535486973274941885050"), + MontFp!("1878952307940134478709928263670720684048776379327776375250280336329921037420"), + MontFp!("19499827360473070994511697308335246130942669561476408759901887106692589060082"), + MontFp!("12848565923572960245609794472388991153395081762360797542600869404653966990207"), + MontFp!("17907208954503211911672889361971205748077530691765973848707600641168672235506"), + MontFp!("9111805574528225436462378700571550282511779416398868619605411083535950260325"), + MontFp!("9595087068362831501644542484656760975788592544390952467802581301998442461414"), + MontFp!("24738210881936581174235913204528343642783940717617978613841785340423914265060"), + MontFp!("17405656744345240534535247039744682356440172598102877823018366842879624229452"), + MontFp!("2154054475815265907386039602131048142560434692009615010206035559273431121258"), + MontFp!("17195250571928635606294953235696331705620654984804137113470013666673813271237"), + MontFp!("10540084063377680844881992238596493165845778059321522753973982983494023971524"), + MontFp!("21039807114358084234549909640001770931068139259256520224929025472891783209811"), + MontFp!("28450181958757886682997772212698305572050605711331151603271091104891762006001"), + MontFp!("14589157545659635520188449256762940118189961187843019574908044700352942666414"), + MontFp!("15526956227055448975858861572527263057743979061160160589793585459841365121430"), + MontFp!("3501364964126113956532031306219533456419103761581901266706177707748335603014"), + MontFp!("12199667400895254013534245859950634161291239088457996291799435343180030999128"), + MontFp!("16682040924273793155616286986894686396180842721128163235642732406329236881253"), + MontFp!("19570910051511604459243058587810986290698577272560815753159344361048948691044"), + MontFp!("27188101986178377783631123546258897703208601373805707414949573071120372134521"), + MontFp!("9010002449080792203231648162947688021205674788651983830809804207166162277560"), + MontFp!("26310160475576562882132362750535847190414245681111990093556416798954805826256"), + MontFp!("16936484295858405671795143945363179235038179251988432094804694658757783207526"), + MontFp!("5644844871228944877459495510497541801276355643400581943542747926808512478040"), + MontFp!("1331176369972396139358569560624896914114946366186663239997072704878560344965"), + MontFp!("26375590481930916556239482732834638306964968049022999916017825801454179539609"), + MontFp!("12394666367691331330247379642202696030938232734411414971244161956834759271204"), + MontFp!("6657383400541677098085664567628338882688266979932272154137169581462528735207"), + MontFp!("25419579312236459749783727473918170199456156029172589890330801822655059831575"), + MontFp!("14016952185249427165601774416447130399101420177234543464169898063591498545669"), + MontFp!("5327593864609788928348940687258006455469719163022036189156490827707796262169"), + MontFp!("4430429434297016825679439841447857467429062773177517230607101328877588067182"), + MontFp!("26202435221483461697338582436497684786075041498548431022774150701383983283688"), + MontFp!("25113663532461612096599098108347720000407232539222182467516526788249802022828"), + MontFp!("9059609500058202843104638863342248746504599822352244150423200420585762349764"), + MontFp!("10075272686938682263337985998776370896905168101707862813168776212420911488029"), + MontFp!("17504480255948124648872472053336796529030386976468026021584447115702978781833"), + MontFp!("2530260251739024224935292837503850882629324784099834139556457154570837093042"), + MontFp!("16980326092438357047919824360222547684147983276956582889010825243953309518131"), + MontFp!("11602713152610578014970312037525032202606717669682911531609874394506411158511"), + MontFp!("28709991284345507577462396202914566929867090015072413707258087526023074595478"), + MontFp!("17750029050499626666154910684553465152182578122491249290304080539240329669491"), + MontFp!("7591914145282845005300167258394739097170583888464311906783437172270202777318"), + MontFp!("15525314240763954183851692472947808638994704323586961065610859825895756826782"), + MontFp!("8847756829265580073772971895753428770458656626162050663386935741333480397567"), + MontFp!("19256433515937994523721952738621694193318744936603280091718380157014906936808"), + MontFp!("27591821543279633198412110928467865001809416224891109012269521866454634551101"), + MontFp!("23423003765188567590829769206318171729135143202990123340751618149204897254614"), + MontFp!("1825223721140058491959197289302135994503898264211557067923051329015941572708"), + MontFp!("1230707062952641073164824606498557068918931895662746641235187050928123023125"), + MontFp!("16893402130752063619136022771164134833589316482583916096199819911162231961910"), + MontFp!("3693000326841797862371935752475798275663572882032743612257327760202487883846"), + MontFp!("3190074895798605636712829558795127723975026920219361738395687109427259826036"), + MontFp!("20671203863269630857185473531105052754863007964139404174931464849229173294861"), + MontFp!("10692797992078975440826444568294567736386355985680599505011175822062559346875"), + MontFp!("7661228445442804234987745193098981389914761027372512138497489695054149460689"), + MontFp!("2954752513314702655953731512868043934228576636239137170996999472159017363385"), + MontFp!("6028963817731990424283231152900247244492952580776188165247315629767945087234"), + MontFp!("2758827343485019844520733777642072672205161372124397858234624480638715283338"), + MontFp!("3884993752010595748397737711384296033321920892962304448886439208214846492791"), + MontFp!("12547390201588675237042160136067434607265902351400918314434150045488483839435"), + MontFp!("13246612673358613292356693076830819334762263491253046267157395568218889130949"), + MontFp!("13617231869919303851186741039149665015468522569189612939928378725800878669798"), + MontFp!("17350324835300319985356026010120424197838537265485247439546404777756682253353"), + MontFp!("23160639418442704416799890493611349855211262356128386980528666692136708102294"), + MontFp!("28921722400413365152769660927535045163131324106026584906058397551043374573071"), + MontFp!("18446343292466194394631899835837243368476558910803552884128732378016778572997"), + MontFp!("20458046255279729652080428115628888363224919333802700258898453994716494368431"), + MontFp!("5623149416359428317006846021651588974227398620698309271454901783330352701636"), + MontFp!("7896700212797068148897405559498596412541474369195762654831273174605070862863"), + MontFp!("1030967591062040389667793670163119615567239350149461977151790242805355832401"), + MontFp!("28782879244082238672946605788123301408801309008410447965466785681733419379532"), + MontFp!("24981401926874127736998198883956677608782448071522558908884854907542509919261"), + MontFp!("5111151178214791257159424224925132772267613087297333708680834684149056102307"), + MontFp!("21750104515348790430028900724605312596300604138952806729708807218722779982237"), + MontFp!("15970413033231930822903023132719962878994346282270433050307923780137284214792"), + MontFp!("525227855913656679559765378388041825795119539015911895546266403265573435596"), + MontFp!("4886637558120856177284548315858253622340485147762340739428621757246212430010"), + MontFp!("22713114022449472930704751062127361911996729792700701757645626234614709958085"), + MontFp!("12744297137358469724564895896478246595476564043919999099961249606498726044798"), + MontFp!("500329255241868524000403448474094732084492691446935395764477703788100338614"), + MontFp!("4065027078438828820234938802839718824410292899906981794792395138808323200542"), + MontFp!("20764304708646630571529670643953877532503146261612809713290422505630453663495"), + MontFp!("9836535648714568415156798849814711397307711068132980472270233588914694034280"), + MontFp!("22636414705853682652453816216805498108364123423032523038389763412052911026672"), + MontFp!("10336929897679389747387476969621311770180991788334725452436057379957630806586"), + MontFp!("7608359464485854954020094900402450108568600505102328259423256755939404798028"), + MontFp!("22368612723153062394336433306919440188659867202326930295279713051413169798631"), + MontFp!("14136397960333071036782058147384444914988495342394893102675932948185871858580"), + MontFp!("24481813518757189847570112553534825523666213538096311436799221042011061726843"), + MontFp!("20150736320987890219470032909674452660218734910518572733574370402695355300132"), + MontFp!("11993553656462546138320848247298384457861790643317154930738716608915518198645"), + MontFp!("8319964736809834468798475063142281281233430887263974879841766563305473528908"), + MontFp!("27182805795936164126639892131808801401285613135245808432222916408230926054943"), + MontFp!("22688594526037952239428147542192351741041122687493253863274182395997478270007"), + MontFp!("28109112510570501228312924884942456762549111553537690163909678000619503235916"), + MontFp!("10415897729255940950529818119300496449281541481533955337166053640681053599958"), + MontFp!("5757228664585555668022440939564652022731072375445267986578293070929325521530"), + MontFp!("7051704889939846324003508128306593720494677068301380723225854977337514624816"), + MontFp!("11703798539570077638001759255400992364734374521234250366061670096740083282671"), + MontFp!("25369911129583252436671010120051368003055135456901790566551815686931700900281"), + MontFp!("6614637034342910199505208890820082792681282493453030634172847683836628204075"), + MontFp!("21490196372844953971774304547222764069960570558792977780990011013939376090786"), + MontFp!("20703155875742262980970997112997311297258091288688130812363973757829923906300"), + MontFp!("10896906857098001068094398379735260819872089169725297848775330555478679219427"), + MontFp!("12325903059883434931210235569907609415329277258255659906877844847840282640144"), + MontFp!("28077495010964343494312030494560527936454221749076543975036727642839149316211"), + MontFp!("16158588935593763050038770226714294415359792218468544866069922090227331164091"), + MontFp!("6465710685847530771601055590082520270977532969675290891032406335236714419773"), + MontFp!("26974388186620062232584734045349180436465811900309463861120965721163950892358"), + MontFp!("12757813735906099846438779779620850510276667899853316844756405639900780983353"), + MontFp!("4098822086384234735771457663415759285174429540305667817899123403833700392952"), + MontFp!("15922629312615963326937497592314852132886991173475570755825201831569832365923"), + MontFp!("16298154063066094681805603612691186557354997199234947857652431608140061154010"), + MontFp!("17327983859744263538520139270879440336709982434231735243432132458285822312917"), + MontFp!("23956095037500139290469224709267154326698857039546336800539340184142177223519"), + MontFp!("25363112685851361304601716615374655687441139421114560070441981469368063731043"), + MontFp!("8406725966990521284694081622278480333555928255618910249517824874274091350809"), + MontFp!("26209536214835239373806153783036237875561447941234035869963404971706940160881"), + MontFp!("14449383425200369239043929369078510664255902122475213794623385779884448738155"), + MontFp!("13886515267208676612947919878576514195453260416942428216377495354446372367048"), + MontFp!("2597817068170217159686096414078710634585765067058124387718951162141044385257"), + MontFp!("25875933067278922618469028909712854011791536827667191667186063490327001332710"), + MontFp!("26665225447242252820788887628807837826374367785455339528480232422529814213637"), + MontFp!("14501869095386405187705064593670874873210372044842166746462647504597529624271"), + MontFp!("6511535277053855064656531514519946839797881560578628425890189136799833467119"), + MontFp!("3336374257968950276717544145426616240552391903514133835644006580478773069058"), + MontFp!("10983247597776821792039782911678266081192924450994119553684682449916917670554"), + MontFp!("19426281114453569180857612520207325371953393358618573996358073744293304674242"), + MontFp!("21327765340980903468324967098867481346065204386120893299485904260397471559844"), + MontFp!("1213608473622956041832359210347255693220568479727667705852115480872069620614"), + MontFp!("4339764863180792694036784482921434740170078055807030152597232950610148396219"), + MontFp!("2126606079752223281103869278863949519285961325445537619717698531879495612413"), + MontFp!("18082219565474911947364373744816247487156584330520705084219331618570510129141"), + MontFp!("14305298973218162845444343235395317753429597939391382445777895050299615750402"), + MontFp!("8240765294387861274854954700041860151943060366327887059042482903094301053482"), + MontFp!("12027899924764423812672808311259626368510387334341671120915671350037098771813"), + MontFp!("8517678082244796505422321761579954150752413155728096897403553150960078862218"), + MontFp!("26519026132399405399940340632992599533819733969495282313453047792124953419596"), + MontFp!("25367741124869100148718090903658278092603128638967789990712283766821495866716"), + MontFp!("6954761884496093878570303270624100266423499765415694546443916390473557457767"), + MontFp!("4168117132086248107547920939774210685988364027266288515890913632809925207537"), + MontFp!("3425181188454464879002671276792294415364454667601658165676081935081428802863"), + MontFp!("28110287569749882795712947274407557521838364923757580443582655405834702714429"), + MontFp!("6813068901548137061011750071274042776334393298652502322795190263196000564050"), + MontFp!("11562854504189429615432161514630882847036071684911012618656568588249921821442"), + MontFp!("6833027016480496051937666600264882800548818581062578345878462643401822222714"), + MontFp!("8704427842398587496972904634442977054623155210288609969352361484362560852284"), + MontFp!("12950131049013062607476096545303907379883516331865199574274071466391901872049"), + MontFp!("9263887235933646544026389172138067438039496129545420674994924506780200004139"), + MontFp!("836138004460468963461391409697398434929459785070531427051461940102506515957"), + MontFp!("1843037217776817983287402645567312262997590781119961837169823476390796236941"), + MontFp!("10729110552051857657094766626115824654308843738479519247316585495861382345746"), + MontFp!("22811670043175475537502792910310970404411157802036280049844053789926134406068"), + MontFp!("27710415765499991300979051646463122057555801249261700559402333075787342211358"), + MontFp!("28732516428889676197793979188472598954278830883700561422362392869290306055641"), + MontFp!("26424460642355849241027238409544978201286796595255848255440285709756368527060"), + MontFp!("1049803025379522180746291354510021641902213843062814310268180888098893354078"), + MontFp!("15186079395165828122049722673615008152047087817699994950525100540818015444946"), + MontFp!("28476010056398225349585825446327929093896470576068155665710956846584266810156"), + MontFp!("8358120294292955607500453697238234639204574179004501346224242819561026441583"), + MontFp!("19296578967671428760275320777506435527596247638335720780912113748353422488184"), + MontFp!("25069513126358560624215976381071770699174656018752076568747416805924919020727"), + MontFp!("3444146399442433196466639193712372040149049169548700659116635161196881792492"), + MontFp!("28869015706764175377112267536810936199864275959052575827018520529051487285575"), + MontFp!("24474499141914927621180097884632055130435050936611007942290193698071238564176"), + MontFp!("2101076971405858197304981532936880270863821354713152176849746625217873379162"), + MontFp!("10834831562440844970738916611362556276622140550215925712903494056124237742589"), + MontFp!("23025944721898867060012739281432137469752733724932390922021534759495729660185"), + MontFp!("19608560509510803922107197298192390762294102188386059642630591655109362299836"), + MontFp!("25869441558740014736838427754799196309618930976635796170917075755273712066153"), + MontFp!("25955090977243687310836677574925559536132754977117544266493266650772701694323"), + MontFp!("4475345735218664752833350604257711862432493842668362076644971333110394763556"), + MontFp!("3773116598161609040473979292811377766907822883137449041285615609368148715395"), + MontFp!("4127002051317062549806841477219465916442470735883766933546688437499449902133"), + MontFp!("10677603849809840052848033820904369488826385357450551442684144633293415915757"), + MontFp!("16921141646783244258297978466532029739214522045947718493336025108986328395464"), + MontFp!("948974364093264850854593237712747736205072113560646613352477972178207860101"), + MontFp!("20450573738284852860301237669903031142412152665446515701518721132288429707010"), + MontFp!("5206354254905942788805451858800840060664215612158991677714169362335342241597"), + MontFp!("27938173474214791361795154186375942866115825287871314201979081132805874873147"), + MontFp!("7877111044042581635194191653274978597139526011995379806719095275145003577592"), + MontFp!("15093112975728885428950223583484585061909935397242527373647330981151494439645"), + MontFp!("19440825965954260067804595251423118979827243721958740389775890601779164084321"), + MontFp!("26951676338331254346800610838259735913773912958567802265918397083915434224938"), + MontFp!("15519723611293446132987173594393279742432109043797205984620275165103258835866"), + MontFp!("18470799109614903650140099438988646944054958661728325462609748613135679405418"), + MontFp!("20402112419300121040875436717956216583834880473176805937736181273818854084428"), + MontFp!("16926560377815730822434699743815937428404524735557785069925173186819860188217"), + MontFp!("7093560166446334102798291243888300437555417093614312836911701330078189235019"), + MontFp!("4429564134236670355926622136877968948830503010905084820677326415243863382619"), + MontFp!("13700768031627431229257881153036374562622610655120085612489773058832505965079"), + MontFp!("24449839462560377667696293376975012813935059650402651471226845163068407431328"), + MontFp!("26236087436655411578289936592714933981644259050670394118906243354592914166410"), + MontFp!("26788260278180800210520254875830456498255312567156507961972243222287631707211"), + MontFp!("7410113811641439431338581333394970971799789081712803811690346461915446943763"), + MontFp!("4603791506310032419441196082538125572035088816761872732675970472568820325722"), + MontFp!("5112603988287913338493654123055220353844654006521841580647817695913518842826"), + MontFp!("14903521093770909706150922075489719179508236688635418492353923164458714066693"), + MontFp!("28678864085277014704154645275698176345403370746064844920828238893601467135464"), + MontFp!("22568646187991407584098063253300348210142784891951688059153325898717894965172"), + MontFp!("13747787501929836079824748313933134909036706519290209567213734343260319502773"), + MontFp!("7443112245457585593904831877433863263950846178430817699504168599355545973502"), + MontFp!("26932850238859123083425896939898783580210129924891959538656475809963338242012"), + MontFp!("10684282546242641871390603274098754335788355719152675880559059909993508608810"), + MontFp!("28044234226410617835191486650513329344782766313481796704709760771480882420469"), + MontFp!("6932125276399977675027660192888337058677267339039080879130004947518528508907"), + MontFp!("24782727922195311836925837175696264447048444045939450225964271506853856114191"), + MontFp!("25444993695685206065474821694022468028968485171860189819056816072702321681534"), + MontFp!("12060512338038353734678962432384920426538119042503132918107660061596121288666"), + MontFp!("19102085810339277215156411808449804613744564397531362087870340434105072121498"), + MontFp!("26313202647417557458917740654617506936802884809361399813197612612570303007532"), + MontFp!("2856998129954394244641365284801368625083594721116128281840073859610018704582"), + MontFp!("20726290780681207102407968989650117580974157323280908376877202541265740712212"), + MontFp!("2919700603009613020502108130665123122646338663416393432755475455042542896860"), + MontFp!("14428441161709944246307596176236764530584495371426506798990835549091968325072"), + MontFp!("16086162753327806582909018730326862475406928832247622826446465027128655026277"), + MontFp!("1924199232064107240597218355876682150091940991544539668740868608101413166594"), + MontFp!("18273136852870849491855678398795330089925272298869961073352242021088770777883"), + MontFp!("178190568021730882087872887007441533260766224211193671165688951208225201978"), + MontFp!("14627393013235862731512736721616951087296324229670901638204208456991715945755"), + MontFp!("8686538882697522456454217958070498723027337175050664294470889205293681519567"), + MontFp!("5828621423548501568827897345338338504055145314660309871643022407758452449570"), + MontFp!("22858411310720189445216663597104277946369897566584306506628121311935361171924"), + MontFp!("574192207426475506663013361818984114425011041544332952917700069639893538723"), + MontFp!("28722857516577367214355751658018685299272663421434274300387414966654331816216"), +]; + +const G2: &[Fq] = &[ + MontFp!("1"), + MontFp!("15891333241237338948802440868534957611422987089162911289567511717843897011994"), + MontFp!("21627025687819550616493670481423056333531177319425453730855097519004345700158"), + MontFp!("21664831381467185929310380991503564239310549671109903700708928487814454409606"), + MontFp!("12043652267913829104424453152065363373444247972138387934002476851683108699844"), + MontFp!("15065958625607021778953428046418579344481769858555320497797412682419049489069"), + MontFp!("22907395973527520771575883569343391693863554463409418570565229120634228042430"), + MontFp!("8016173723792773804470645411648468778821211785002301479097792313169625452183"), + MontFp!("1674990072596474548996780762090548712788842389735467493870383261050817303250"), + MontFp!("24480392035292599925988710794161466430149732278589631543300519611197665761724"), + MontFp!("7245193593798194755667320916952328632439197003300817530819736793958669155535"), + MontFp!("13040822196097738282660937211019620730990694038246944153589194864346418252422"), + MontFp!("15840345274519131105054888573241540401797901264765099604374282831916790214311"), + MontFp!("23862305301235394488169352898611015693916427079645176480902892681244660635374"), + MontFp!("26978782307852121186795614845160979590154740381301273946900021441871513497074"), + MontFp!("12256169526842180642788092688029559287575032868737893112137142634879898082414"), + MontFp!("1147358278881152226139897583034437610548207651353113727904064508220574543873"), + MontFp!("7413544939361600218127790489031559504725651214720038430892699734999299651486"), + MontFp!("28088796472400266603952312122192247524920240220788340193487367085722212258146"), + MontFp!("24243997933001175884959883262087469016691598624713791403740390428752095532301"), + MontFp!("17181797402406507561373632642606221037516451537909661407914013189985109997536"), + MontFp!("12880486536320943634706883310870263985459304645190959248331453847737566834125"), + MontFp!("9617435045907103193505979530186421430609253994959110804481290506056405889406"), + MontFp!("15022256543450308815668686656858814100945418108492729437406339283566192243897"), + MontFp!("1038575718032928389733118170494275443670184536266431283206088730364733543290"), + MontFp!("18654704688645813530347862010352283979332078641904075418405320949759055698076"), + MontFp!("14526038952331415832119084789134219087068596796072843621108109717953960703880"), + MontFp!("7537294246748989503172262863896721589423210412492417240488964526602665422886"), + MontFp!("13839301525249344180920382159248279532419692405702109263298565505743579960013"), + MontFp!("11772027908665547327615839876376790233623055161690257574067106323751210212355"), + MontFp!("13546141888241000418162894333099657862141119021493037923709077414876523925178"), + MontFp!("8794345835604030558401153332194480260526711314237300022976729457211130406166"), + MontFp!("10903770050551191186451481744535548418731134600017891582826719412432433936403"), + MontFp!("24859277032492834866727269455997736410339900342920666701358171341352932879901"), + MontFp!("15941523112192304983086569286062146565722848334750721171013659898902782223238"), + MontFp!("12011810926625486084477586660826736963145911934139307627528657362256447873268"), + MontFp!("7857315789818618409951379332110150630521043447014973291396128369149207082289"), + MontFp!("2692978664832651553697544658147945534924501039514185004985587791115799362990"), + MontFp!("15090679311701211439652471743510601407250226818603547022925683367328687372893"), + MontFp!("14636676464481544665650364646805903504936504807525555522155159938686182027117"), + MontFp!("18835214874065621690683801485686219860865678945261212945142800785029831522432"), + MontFp!("14356810423875154019269461050502073833954847652218497024369789754901900035197"), + MontFp!("6892949348392914548184127548486291875869312998373601025962293530848208070388"), + MontFp!("3258436587854780876750514399641000732346573949128015363330227260168557129731"), + MontFp!("15285779687555367838654098472491282974307202675135736485543063001461773602670"), + MontFp!("11085212609731951984867761080104507878432217940508481804464076728302971704631"), + MontFp!("20473204910209302040159448842105889506866653080650187569391461835159745645341"), + MontFp!("24793121727845242284068601185484598117277141756549636925794142680943478054598"), + MontFp!("2262158240331427447296172269605463270940308886619829394724455504633567245257"), + MontFp!("1094637683631139061523228231857726612741244872019057491130517154710225456068"), + MontFp!("12950124956529939810507905325645140960311862170678058856076620258562478192839"), + MontFp!("22367217097209891377845703559564453031324367555693215851768667592847703499468"), + MontFp!("22404723598747482493494570769159202466167363967358426995658057727268020484029"), + MontFp!("14402251842896394107515398879025024330769992579895848248373268790951886796417"), + MontFp!("8145822729977182601042551564213186483673961466882541113545787163168014652605"), + MontFp!("19737508418846444635326400486316571503993017054166243507557218924875751022170"), + MontFp!("23152628449190875775727955987235309758150797141166060158616111414605467954596"), + MontFp!("26360043472784830093881348671311978299945511582677119783543055652306115710243"), + MontFp!("27591738496211821961164575888103145610744331617217112532229023122763810601768"), + MontFp!("21114019199437763020793180225649527307568558300213139032143021861900505098467"), + MontFp!("19895908948496451454721154068416483549286741394995421421948710344952818341446"), + MontFp!("9066085763456866446322433810316010748347957295999867939041143071171930901805"), + MontFp!("27088421255166966564091252950419093734861151196706678043838145629695240140047"), + MontFp!("21092987359304744098765927507010528048867318291780607351788465342884372749182"), + MontFp!("9106099894445439554041483310221810032050718587061999431783437374285003063682"), + MontFp!("773959571811320990833575106630851845910490037729214018763502972229574589030"), + MontFp!("8723355172040189147492765194048901476425315055021057699195426950141319792795"), + MontFp!("24225193140987592712387905838320419624720972647638840676148135297939729658145"), + MontFp!("3785193750175054016346100524082278955650223328310146548078412657238278625577"), + MontFp!("1612427052869433662159800824418821354911332201963430606716916170013332187665"), + MontFp!("7311673390441782232023816960364758116998946970560924543926245251054272405608"), + MontFp!("16549296161909743750909183580347787326890367987934113216478641318607301603146"), + MontFp!("24216049536033169540546549163154940823087109416699040630485604173748316573005"), + MontFp!("17447086333451471958511238420368019810327820530653194996586057952676122705756"), + MontFp!("21093361447429167824730423138920552768205692979283197121905709625214317766601"), + MontFp!("128452452574303848004586069708833812480258212190536042069856086619513315535"), + MontFp!("18412659402435520502111786129848574985108970502743098206621655128246202082002"), + MontFp!("23272451735671243321556774972035989516319293871600103296465438351366291309283"), + MontFp!("17738388873720292032052298748264211787888527096741750207178509565888778311540"), + MontFp!("15752108427773483390702453097656473101405176942948776128603194105862576166739"), + MontFp!("16028174568794628952240233180039132985129710066978236705421743924681008140930"), + MontFp!("871153955208010187148660956277329036265605673039250873694661123472338547690"), + MontFp!("19058478116599101850527060967128337491480039115838650065276094875247629360602"), + MontFp!("11687534489382068198466023835417603105962181351639131701886779350708581441868"), + MontFp!("8311530192791484946447686110404808805299419831896277011767984316457655909577"), + MontFp!("11528240782891243105429583730273022600531774263784437131478813014204667470441"), + MontFp!("28115851501541195668071637388780949247454658244079554261447139086764422860363"), + MontFp!("6733589749310121063648854537075929173298599372123831818928933840408939216355"), + MontFp!("22950375355273796491125017725368280947572434020098019275922787916957232853297"), + MontFp!("9319155711389779976631343019267966430521493559825729748768523863911836822201"), + MontFp!("26798224968852499840795879696125713586548440100001343987028015475026190818881"), + MontFp!("19178875223864248707482816843120112511935590014798319408509136808259424998512"), + MontFp!("23235105188751417575825586159889935985855501294038397319104049367808192014185"), + MontFp!("2409527706334216864941071192690165215256185265513966251989333942234451116057"), + MontFp!("26298848985269389286589127003426307127754945951374308936997948010505798763735"), + MontFp!("24994330471163339848462581584386861377351183075787129271815101557328644114759"), + MontFp!("1310745875361954448089577342768613245780546702582845709443699402706482508172"), + MontFp!("18332778821461113955735939509988703012180782118386558315382483399147823965173"), + MontFp!("11971937345537079015114070057553524272508452441563556722446120559685624193189"), + MontFp!("23949528795241531937379784355968438042465021419310148719593739817867244594896"), + MontFp!("20901770778264999265403308343509467370854337236147874059235344626191055888427"), + MontFp!("2497425006222086407464831040524589757951202369187391231163601810454409107903"), + MontFp!("6937915907292788461082632081674045034221230168661892218463239865127514456910"), + MontFp!("12717335783766397670596086519993825051009243833128838579807736232450512240683"), + MontFp!("1138358123745371002746440766793336687782640695551644163187477098709834767556"), + MontFp!("3942967486009317940623239443764260780145225997826171766313933994866328990567"), + MontFp!("8467043159194008967331034394908693567879855750086585678335506776097585651300"), + MontFp!("8641613953252493881688414504073390236194578660573043451994326603350426832028"), + MontFp!("486341285597430815255939941317213495634016854415826938791458906384365635909"), + MontFp!("19042497457796942336944216251292355501773677896976642736376492176789215707702"), + MontFp!("27283530608978670325286451734218545517137695084514796128027346487966133844888"), + MontFp!("20829500450979047629009608454357428008165768988498880747755472260007145888131"), + MontFp!("26587131049200359484721682631075443810017266857279967838428615995631326638083"), + MontFp!("12261922986805275447711458219971221700044051505139187999051968449370636778667"), + MontFp!("12471650746662944255567429294055474682986152968034471467632381169396682619516"), + MontFp!("5545644535309824799448050093637331953233594936396470974128267303771107353921"), + MontFp!("17329981273613038967037051520243177107700143891815068278056773180473362659470"), + MontFp!("28054051930081483080501510012308259923324986726556597871269936714379125164903"), + MontFp!("1016973897425242205861795400274188134616299599965714711550330853560048234428"), + MontFp!("12846085008229918899013215886171067528105012792501649495018936927102117481487"), + MontFp!("20007597510880006160287761302157267703072585428147771041375651661364848416082"), + MontFp!("578494254786456012765668671156533433929413976305456698592437834023484684024"), + MontFp!("3431125002462906627806887964258811343212030827051643025302470846491453706942"), + MontFp!("17076821322598927351561108429908992306384710411237505443438728417707050286069"), + MontFp!("6779268341877422152567096200436900264856889407819803794552044991339779561698"), + MontFp!("5275221974417170409851792954794828306601535174894613092548898613487407223969"), + MontFp!("16413120710698959210168395059369962474121710525877608709059640884136480087392"), + MontFp!("9097779896728009522260685510311571528158575755476699805553889747628114869221"), + MontFp!("5752965684179714134970464751995402357640113293282967639033716269094137333220"), + MontFp!("2192746992346339960169103684401882592556910137651298077572143340745156640946"), + MontFp!("8320412883196092580163140968627576363990684044634829811285490995800521721409"), + MontFp!("15539037813695421876549376534542497050078140288841081776682183545312485739405"), + MontFp!("10277189246058078405647663899522676270175323194218886374300400667479341402665"), + MontFp!("25867445123938084096839424906966905219975408905305856819235342323879121561921"), + MontFp!("10303528335122302055915965560662316500591196801736870117552523167493698243722"), + MontFp!("3187061939500963521773759508238888928187056404381715101435515002063364858524"), + MontFp!("11946027087519965720060721037065325134741908684677827249766065653993144700409"), + MontFp!("1457722304426600747916559644214220893428895522552363692327072515101184610325"), + MontFp!("20784297163787811542084753896683958222142971110638976523650720505485498717137"), + MontFp!("21768740374243578895106806888928024570461818597705444531669999099422873421617"), + MontFp!("22498034256586348153996724769285779332405702222794674482896735868834842707823"), + MontFp!("26730685215224287218627549297084600424229159610435848014852436299020907717601"), + MontFp!("7041906493981495835475196961879422030574373337686763273860706400497865257135"), + MontFp!("25656553003288704805862161526124366753507617880178821323168241239900061362352"), + MontFp!("11035316244048600635443763250423108595451188653208551531889737515080191605093"), + MontFp!("4828539278018581413037675067183327950224774331200113885599070084116445845094"), + MontFp!("14270610763951745066522064626434999251391524171305422270147239049467465263920"), + MontFp!("19109080468738748969689919117628148245167696786238639762075773273374495922316"), + MontFp!("18714408839139320809599377166835930477556432726621853800801457660439385031590"), + MontFp!("21975255950467831182094890442510030560175123533977234171572670992991842821030"), + MontFp!("7132575333849069564086468761773299825677404710067569825136361630737629689342"), + MontFp!("25722434484099795788731909107802880570758315656545484367196234164617334495804"), + MontFp!("12443911976107364671367502231798217992721170842613035774222405613185521950114"), + MontFp!("18375627658461043387341301990704806217628229335456263550777409625966320461111"), + MontFp!("15438928446196902899356888121139274557742037328905072100032536943070521608418"), + MontFp!("27357303650558728776487602691373805894343335307102492101723007389807550307913"), + MontFp!("28112440927057290247524868367432505318459803388901031733543780941395226536125"), + MontFp!("22453990663444741047128111494640772158295562387363353359911847813742859766625"), + MontFp!("5739198404351728384736611715913313864794043040476886721183074921082553867863"), + MontFp!("11137955396345707174828878156409977549829408007218944271160308838202795224465"), + MontFp!("15684732987417944264169447533774280177462503671870647022516333594580625914548"), + MontFp!("7903578448009414207172922556448626002768325208707510507885662694636757487917"), + MontFp!("15994715024988382009751703676128193882531797216119168221991533624061351320691"), + MontFp!("23017800099308341351331781181348210641132406222771810764691724047305097775046"), + MontFp!("18176782233394835027049473343337726943900774408523844557339774838033732207839"), + MontFp!("1175948846977899068771216469158730417606116497042931644404499568907060939303"), + MontFp!("26221195418059230673576816547650312404876197773883250938923080788720080912775"), + MontFp!("11921339185745910617018171474022797725901075095535886770490204556882477404844"), + MontFp!("21458880052422644780990248839499742234768380613292696766451902030798322670304"), + MontFp!("15028158811198204164736354374460984425180877674280083656981494082686625692278"), + MontFp!("18966557900657693668257781158193086592200475450442814246719992323628638069172"), + MontFp!("22702376226728245144555556380111408755997033773501929921121029143122695796165"), + MontFp!("26907539980315259773133215132319089933321222488244097044027435643132020687589"), + MontFp!("25388190324233200704009788621330084367132246719547654640130269074838464258978"), + MontFp!("12036358120305384186939832725627976646537834048963401003079951064742303245673"), + MontFp!("5538510125023719238158478423219648873094886998021934449496483828096702875471"), + MontFp!("26966934741581439381287249758174836465833111926653300280041772165362210700721"), + MontFp!("28003382235165276339813134652922581796919238583797648382095575179597721053057"), + MontFp!("14642085435604086163426996959679114639897944383254296009947743306259481424020"), + MontFp!("23929282784849145092292746341941022485780933778509610294121257430526606762173"), + MontFp!("26202682253869159070996626303057413443003963165941479462558860504674369724158"), + MontFp!("8721029956722467908819830372178227046041152629692875142883131937457776748000"), + MontFp!("24728042446256635735880753186148655820013546328499512972748713881116879356529"), + MontFp!("6617817479173209180260413758774000996733789604471610854047842148702816340004"), + MontFp!("10535181451256170911733813824669054103351330785293568184317324060595803459258"), + MontFp!("14323664406878914359158187764661916181348672536342230217618095273828777994972"), + MontFp!("27048648996772392485461507599559557851428493040089507709529006751014278855409"), + MontFp!("27458333062767737800036455154201142922772512035497118508906917179785293416588"), + MontFp!("11242133467176342543596475458385115263207165774700184479259255075672127227568"), + MontFp!("27256631541829730484116660412322251215508461154456754642019553496217932136205"), + MontFp!("11044205761043865960242896831150784454021187132349708818841781506720078906276"), + MontFp!("16672049351819728466013580133312180411120886161870121325729360498961387511537"), + MontFp!("27784773800610315790530366763934820920363986019969365149650707380230160764664"), + MontFp!("17248516385608083062976395502781190784073469574336548170238219107175130955210"), + MontFp!("5892465136420946936743252895085405308765027712836867446525110828710533177710"), + MontFp!("16036262508284629329626040730652983419712039358700363650033629624287385048316"), + MontFp!("2336497963125591606987174377116713147570041676618986284105612798568237888399"), + MontFp!("13015402717520760171077930163623202930798708111906706116645141731062543838997"), + MontFp!("18098127559973203088980834502842120449232118266986078091080327718665663311774"), + MontFp!("22737773055740434663250523998832304573598492081033905679219061637597612777896"), + MontFp!("6630795951794147241326310991053751095121942137879975540757825966336490042754"), + MontFp!("16692327767247684176947681937192310535869708625628256100023312467197085050887"), + MontFp!("16918847965614602517633755128124356799535137986069930427326842989485554405818"), + MontFp!("22888188105742987882134837711100010559421674970385228960613273315856651691681"), + MontFp!("12916871875509006881699906943615943002861422622270002207220040727556025970238"), + MontFp!("1386817265864484270404061028512477328065753824433494279428042688283164257698"), + MontFp!("10240353699547226705843176482505984015111216118341379013169458845763753106538"), + MontFp!("19952208487021521042448500328895571400060756463683823301002683559512284824851"), + MontFp!("15661892554396612121239358209881376539226791722692797254265549143100274478856"), + MontFp!("458469949725672187686542675156459969544358327239499362012443263876570460319"), + MontFp!("8393642660228168107387882743833662987448670954401360548365430970333476979702"), + MontFp!("9408383171952020770210592816647690285818291345227981922427288982840018578109"), + MontFp!("13037556588265604661708525504406539680998950609699087476310181085155648320464"), + MontFp!("2577861126542086432717797898243542398283840893988727390313436123784259794755"), + MontFp!("26882668622678255312838376109445182123888156308733454692647085310209469274278"), + MontFp!("16819021387342163476959639171783232893445816033610918846748929574924759513390"), + MontFp!("11632504770241724177777834657772065473241004909891669496508730549094946643107"), + MontFp!("26639229667968700564150439803284290547724636481351076633785476903285656911662"), + MontFp!("24573402290116339293742888206397854554210072060024782040784905020259778924393"), + MontFp!("8337353364495832415659318265597821702797482855600635046533145821282895815746"), + MontFp!("17736625367238442199554943765836300027024543612207496434277715843397175411901"), + MontFp!("3192824103207677118355127210252303362013758429741747826702117847841864203501"), + MontFp!("19620962278420840487382206406579884047597795733882569060041865152373646146039"), + MontFp!("26113787348482587243346236441707894937775076267677699511752142140580646687127"), + MontFp!("23656908083061084093488693488591948604886418438210535617281086415523722258142"), + MontFp!("15262827531057630303677513759317506553537141443189914752716063015221590671008"), + MontFp!("1943147960241877577232985418509819045872512298004004429877764436958387386420"), + MontFp!("24325350967520204721641983580283117826005735947077951064457160823546144148482"), + MontFp!("7273103719621776386504100518018600305091713714222983132646347519193271862460"), + MontFp!("7733873158611923153826681591216398352857484979572523468133485402720847835220"), + MontFp!("15362603114642990542670410498700171989661329111086773650377606096018621854629"), + MontFp!("4336549919391386837107544546564729464762793032079001506041801858927874681035"), + MontFp!("20002467693299015154068559720550386417131929917616009494224173118777143341676"), + MontFp!("5378118115813886281441837561368406593047193395362966361661220023119934221440"), + MontFp!("6149897398409122251637897868573389084307644536085737671974371495319672852644"), + MontFp!("11525180344932597487484083797507231396518491559744313875632264858227300123722"), + MontFp!("5597220283405341699256021186879698596937531865287573543011563567532649094783"), + MontFp!("26433192338345664198930629507848866335416630139727875355356855834582358669970"), + MontFp!("9237775234729245761882398841405768669478309325275597953256940301705937074110"), + MontFp!("8330399772460744619921415012588351911470723564549254332913706437289710953970"), + MontFp!("3377758542915754361936108537856895958212431860101876045475710305238853000224"), + MontFp!("8861106124030551796209263564340341735184456837886064376781230565380656027297"), + MontFp!("2886702460530653574825211760227514066536726084888655865026105909499829458125"), + MontFp!("20879951464439098658035006302495570915796502731309272079422839324286695520144"), + MontFp!("20388741176915796221656101947659091266368248354316835973365752522241726701940"), + MontFp!("15267427232840186255019064618518615521104281932823477136492518882186445759822"), + MontFp!("16946942525195309778435155699992619109610235907568121444970475052417112240244"), + MontFp!("462418473019142658310748810039075941708939328097725811530001917829633527751"), + MontFp!("27835002284129415919210532962404164421599648863693105603105924844658846573764"), + MontFp!("8580631619417273426292673630571197323828943997319480871947522631720318126099"), + MontFp!("28462197086778502253853444642768690464105662662969944414339072855934368496546"), + MontFp!("11987610618946556543690562281668980211310714242666264111238569591089746210966"), + MontFp!("16699009464600706820008404069118984495542873132170955464148676652773298424773"), + MontFp!("6205742910337613482236556215906896488499335352963946496523300160384644115001"), + MontFp!("12100665641029282129284185117052929565355041537978738296241566854169943967590"), + MontFp!("21633655935514499832162083254893592027920501016652940055780220762006697887510"), +]; + +const G3: &[Fq] = &[ + MontFp!("1"), + MontFp!("15295047314588049363205688878885713081714252101405780765746130714907616084937"), + MontFp!("288195195989970865595953050291169946180633938140535531749119684549404807107"), + MontFp!("10376879765270512973443425701780046345875574242004928019573081145599658877178"), + MontFp!("11040656779064531051815708477879237280965365687019251452313259605788299423418"), + MontFp!("7829912342032897466085237282776596388161120002072817676481337059646016454810"), + MontFp!("28168451038091191301733386487144277950341282892615515281749495515998477658283"), + MontFp!("15495304879233494885007167795899486795932443131585125624428697059777236816265"), + MontFp!("5772676229766982871441818714777438643955918462675337216809979342233538361548"), + MontFp!("10292614940914634298803612880893801412281707210271725674518686261760487400957"), + MontFp!("26966431151434080522860504465871072066990753448592924053577411923341619857148"), + MontFp!("27928880724099313908716888049426391434764345578750453046534880798059624775713"), + MontFp!("7706416109157057683202310390089588121557635944078513546328038633808351282727"), + MontFp!("19244275465576424035847432975766744739049977947805059015090430918799068747259"), + MontFp!("1779874528754727715998556875811803773980341578665500623907226425447735978109"), + MontFp!("16732467765775641266659557810075217924463849010359248644807376449433055929518"), + MontFp!("10810933018019022645195840712901647754980539521123437677405037345586003209325"), + MontFp!("15991473285719041627824280404615383295460329177111726414592284128065644563936"), + MontFp!("10141589704325427187430406385463819816100118398519790311397552412082287063408"), + MontFp!("25640100283945965291331050873326708787046571251257155722052453998905530798555"), + MontFp!("1930271661137040497428870249389205785798535158202347335544926803385530455235"), + MontFp!("12813378209084995506698350407623867409031457191603016223922891362496478609245"), + MontFp!("11149032948721636055237773739488121247790270583347261671588658277019629321064"), + MontFp!("19262243814541120338354914238025440046308490316218396962234902118667941072494"), + MontFp!("28927873613512997338984079504709125823114588469001366784989010108676608500662"), + MontFp!("781492828225546517542979124169111270383247787116239072754191371755187731419"), + MontFp!("26530558788497598025071426996600997467330410968575437155247771148574055829785"), + MontFp!("28067423954137869802815014518511237061534391870139972122227835876495827048046"), + MontFp!("4629861048389778692225887911703105718142648958981714743495329580617719606540"), + MontFp!("2253248627653689950351122584881555881009822727038635098531165807437996022509"), + MontFp!("23332360242386653897580810596265620869497818967829786426501282429245826972307"), + MontFp!("28241464945907992243660259821707590564241251916445339776100538721694154924626"), + MontFp!("28748567179285097778645480393348152976133485958885051689470484605533749429678"), + MontFp!("7264643943052961015755578447550611704937156815136031387671780344415599576946"), + MontFp!("21401551765715232603184550547918661802106850201772241535469606692448426905652"), + MontFp!("513700766607541574376791410869966864627693466265795696768049752854987443204"), + MontFp!("3081596822199059242881552874025778609430685781911731456056934104770603820251"), + MontFp!("13002377135352854846982620452490951854859156622633306119475589468200400989243"), + MontFp!("3980629322010764872448421705173008309408403508855203088764564924186173997433"), + MontFp!("23551717521433160824422993467681447777449128420479724880394308514456837765101"), + MontFp!("25335869536511363323124110616071378877925545796716743509439626796797013523573"), + MontFp!("25799552791308849458149844697168367700906404303614100036567338695859265498307"), + MontFp!("24394205250759827916627497913569546652580199369305765574839331561185151804768"), + MontFp!("9856880053120960046680488871422667237954960545062568667419765696231243180616"), + MontFp!("11211792866460000572785116176911496065841353189587794177300366648780871775173"), + MontFp!("10754632469571506087950729369116983326417636507687083088557673722165620439887"), + MontFp!("12527137070261822563578142672910630117439894652443610042911320401592873223284"), + MontFp!("7668767446573631929311116951036413425872263356128873678575279599854479437460"), + MontFp!("660244141754169355488305123138759597407776857181055172495333098980379692821"), + MontFp!("14318508170418761447725295239506994064760916887630698302263199806637625416032"), + MontFp!("23522794242987895817271751846618975265166536289478666898230695079287376949216"), + MontFp!("20326101483017784520793382448878995921294908129629280896568269910639113637557"), + MontFp!("20859870424060745935569420489397498499447429802610567437496064710585092082491"), + MontFp!("23692685744005816481424929253249866475360293751445976741406164118468705843520"), + MontFp!("17467801172319522227124770719748191070132625867231090755100205999019134357593"), + MontFp!("21431246539843076721255918438176637273586307919340337818141390135053486539430"), + MontFp!("1618822930033692285392564695720491615371502594141606183385413982905114100571"), + MontFp!("25870539334641365693463151419899213137628196508484344019478001135942130159138"), + MontFp!("28808891125937682342786348787844406320337877691204085726482476210371859385321"), + MontFp!("19510651306942277804564302789695672870579169288763544839710031754765641283647"), + MontFp!("8507777805206195555679857502652678240633389620260914157221552310262609058769"), + MontFp!("27596149447223011749464805092908811515870569472963337615444765487502586128444"), + MontFp!("7015260833606462960601503696657871521816218749329685487929309450813836952427"), + MontFp!("19554523734332861251988240740538885427628057344241865210864987516235757656054"), + MontFp!("24760239192664116622385963963284001971067308018068707868888628426778644166363"), + MontFp!("8001625505769354959018964991013488738825495193325187201818274379644881677257"), + MontFp!("11931980072012469048271368305093751619352825490693866119620359344187220543001"), + MontFp!("1745260166773772027992007144774613254954515697927653636312509142993776037095"), + MontFp!("21458672170686283467215596992577008101911766366152753062371778095676048576657"), + MontFp!("18271328101635728578887153322825417202926987777083951970132391469571905206855"), + MontFp!("17569207109743096955856851960666112452438172731038503023435747151956388235114"), + MontFp!("8347677098328351020990389783813241275921792397665675129658111270668371174804"), + MontFp!("6542831720037568734652403898353769008654288510814939097497897009914155340054"), + MontFp!("24421741704020151282143801222208801349370536853037625242206240727692231866459"), + MontFp!("13476477551001398078098966755952896109943148890505195244478947458815657821046"), + MontFp!("13618052785272329005073074057385165128253520559167894197497946619099459771614"), + MontFp!("28738133424525681190983654470474961051027202329763903624627935710094237538689"), + MontFp!("11482878816288981242453047734371444120362188993391892333049230296177172123755"), + MontFp!("12115548588257620416794305490894057494384355596596442139094368766888827871747"), + MontFp!("23872761386092421927944477521241621235683637573750341775262570627556354262337"), + MontFp!("14450201850503471296781915119640920297985789873634237091629829669980153907901"), + MontFp!("6857193909762597521318592119619966437158424332411572282790419346988155335944"), + MontFp!("4527235068970136314472216036198591064043503426988609445599027830350411981101"), + MontFp!("13466909486630062089096748994613948269865456535157000594414697528350324978484"), + MontFp!("11781895726301772692785590603218125362717120742055410248369775177502601875659"), + MontFp!("12476269748656126002721064604030120315334428349889174916070209098984622978581"), + MontFp!("5682665033066534464808239921895772654135148311514788724845241794167488993383"), + MontFp!("12884663369585213745665736964737970527097927084137850652741259384944840235764"), + MontFp!("7087230862238469092715416923815015960278355200407053025868010340510389549327"), + MontFp!("21371633418494477275370105611947646443244153115281515369743028377606706897664"), + MontFp!("7140346902647213902804054354773146255740368640693259147134064871122968559220"), + MontFp!("27568443488918910487913710324665401552292074249947861195601369764616032235701"), + MontFp!("17373346280560710249184708840794616196139738505441243500178999648982826004485"), + MontFp!("18646493458433293212860584247772655479048794534108906561939863661560253642425"), + MontFp!("15935979335758753672108601728821171965520849676914353977363960730784337883433"), + MontFp!("15490199706352892287178338077938698880516205788976035417322750414708247193873"), + MontFp!("1152459932539271282502412778315321715656910685009367906131991176140061168337"), + MontFp!("12387530331239093240147138940179632228444595365300400705771335010166030190400"), + MontFp!("14356202300399890206969536895407936637273006615727503971833018554181164941398"), + MontFp!("13597409465869229712793030569856133775120455044003746815988675871003177271150"), + MontFp!("10171780664325487851058285678011882347840373769590836449854243761237446658704"), + MontFp!("21510613755476733652336446765202081695315250112988468840610386227508796652062"), + MontFp!("28708294778800139535190536475857313434463151043240664053765026349266888077745"), + MontFp!("11126441339517102276947051603187695960120266536886176676842389145213050176959"), + MontFp!("4359357694318969819135303062177570054811813698659552827551672948080665471152"), + MontFp!("12866472168012901793165976479291019381673706315019392812343069172369933093721"), + MontFp!("7356716530956153652314774863381845254278968224778478050456563329565810467774"), + MontFp!("10313915154945057286213247934395015813797971151153246690888463621728394327043"), + MontFp!("24527551478063010013689579947635559439295019160418631498489757408548216919124"), + MontFp!("11137834107379392266740822404562042989119923312401374357100965220416842160177"), + MontFp!("20557708550303156685150508369520234377327263411350415000236111656410940050966"), + MontFp!("9944528485400207967383521943924950909305697711863859581775178859825585184719"), + MontFp!("26783472413614050188091822979959023561484063941893927451961882097471855478785"), + MontFp!("10332386121261200330994680493485411413111888253970546538883557204270761164911"), + MontFp!("6919034400549130027666174894729461055685216822941150781078903136418742746001"), + MontFp!("24657831644623912268769103755012839675646300287275427340855486489528633845122"), + MontFp!("912939552989491275299121111229998844008289751483874440787562874783799172632"), + MontFp!("3306143388045196171762867823149207512753245505850026389662509913850591650338"), + MontFp!("14685802629241945209917357145082402062539388223455314475628829289137138118715"), + MontFp!("1804819123106314678305852784976928044877497696172404788773952648940350504037"), + MontFp!("19817400835707730990350412194970115893504248415979344542305465915773061324410"), + MontFp!("15028526494216482870934319927512910055033891985155019098843324834611507169022"), + MontFp!("16729174876699158962664788593668194770834833882402990136414599900995944194389"), + MontFp!("686022013414795596780553511262740203087628753182923611137767179856176364030"), + MontFp!("7854344634716614784451786664746990734246806146938689639043823249962907775273"), + MontFp!("20025667761348634018101986961187515440585789676408983953433545231084538913586"), + MontFp!("28372261470082054398841769514191205723503784120612998787639903805213262897204"), + MontFp!("20818254111219770073219792436430392957647683754904926008385106824424726424560"), + MontFp!("28948022309329048855892746252171976963363056481941560715954676764349967630336"), +]; + +const INV: &[u8] = &[ + 0, 0, 88, 125, 141, 0, 0, 161, 0, 95, 0, 0, 0, 0, 0, 124, 0, 0, 0, 212, 0, 160, 0, 0, 0, 0, 19, + 0, 0, 0, 0, 0, 140, 0, 0, 0, 0, 0, 158, 0, 92, 0, 36, 0, 0, 0, 90, 0, 0, 0, 0, 244, 234, 0, + 109, 0, 0, 0, 0, 0, 0, 153, 0, 215, 0, 39, 40, 149, 0, 0, 0, 0, 0, 0, 6, 0, 17, 0, 203, 0, 0, + 3, 0, 0, 0, 227, 0, 211, 0, 0, 0, 0, 0, 179, 0, 0, 0, 0, 0, 0, 0, 0, 166, 0, 0, 94, 0, 0, 0, + 154, 0, 0, 0, 0, 0, 0, 213, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 118, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 128, 0, 91, 0, 0, 178, 0, 31, 238, 0, 0, 0, 0, 144, 0, 0, + 0, 0, 221, 200, 0, 0, 0, 204, 9, 53, 186, 0, 0, 0, 42, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 133, 0, + 0, 0, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 226, 0, 0, 0, 0, 61, + 191, 207, 0, 0, 0, 136, 0, 0, 0, 0, 132, 103, 0, 23, 243, 0, 0, 0, 0, 0, 242, 66, 0, 107, 0, + 193, 0, 0, 0, 0, 0, 0, 0, 52, 0, 0, 0, 0, 0, 248, 0, 0, 0, 195, 0, 157, 0, 0, 0, 0, 0, 117, 0, + 46, 81, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 49, 0, 0, 0, 0, 86, 199, 0, 0, 0, 0, 0, 119, + 0, 0, 0, 37, 0, 0, 0, 0, 0, 74, 236, 0, 0, 127, 0, 0, 0, 0, 2, 152, 0, 0, 0, 232, 0, 0, 208, 0, + 20, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 112, 190, 0, 0, 169, 0, 0, 0, 0, 0, 59, 78, 0, 0, 150, 0, + 121, 0, 0, 0, 0, 0, 229, 0, 0, 0, 89, 0, 44, 0, 0, 0, 0, 0, 0, 0, 210, 0, 0, 188, 0, 0, 34, 57, + 182, 0, 0, 0, 0, 0, 224, 45, 77, 0, 0, 0, 175, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 201, 0, 0, 0, + 0, 0, 0, 28, 122, 0, 0, 0, 0, 0, 0, 250, 156, 0, 0, 0, 0, 0, 0, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 47, 0, 0, 0, 205, 173, 96, 0, 0, 0, 0, 0, 54, 185, 162, 0, 180, 60, 0, 0, 82, 0, 0, 0, 0, + 0, 0, 0, 172, 0, 217, 0, 0, 0, 101, 16, 0, 0, 0, 0, 249, 0, 22, 0, 0, 206, 187, 0, 0, 0, 0, 0, + 41, 0, 0, 62, 240, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 148, 0, 80, 0, 0, 104, 0, 0, 0, 24, 130, 0, 0, + 0, 0, 255, 0, 0, 108, 202, 0, 0, 0, 0, 0, 165, 0, 0, 0, 247, 0, 0, 0, 0, 0, 71, 214, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 209, 174, 0, 245, 0, 0, 0, 0, 0, 29, 0, 67, 0, + 0, 0, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 0, 235, 0, 194, 114, 0, 0, 0, 0, 0, 115, + 151, 0, 231, 4, 0, 0, 0, 0, 8, 0, 0, 0, 79, 63, 189, 0, 0, 0, 0, 98, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 167, 5, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 170, 0, 0, + 0, 58, 181, 137, 76, 0, 0, 0, 72, 93, 0, 0, 0, 177, 0, 0, 0, 0, 0, 110, 0, 0, 50, 0, 0, 219, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 183, 246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 85, 0, 0, 0, 0, 0, 0, 26, 0, 0, 0, 222, 0, 0, 38, 0, 0, 0, 0, 0, 0, 0, 0, 51, 0, 0, + 0, 0, 0, 83, 0, 99, 0, 0, 0, 131, 0, 0, 0, 0, 145, 0, 134, 0, 0, 0, 0, 0, 0, 21, 168, 0, 0, 87, + 0, 25, 0, 0, 0, 0, 0, 0, 237, 0, 106, 116, 0, 0, 0, 0, 218, 0, 0, 0, 164, 0, 220, 0, 30, 0, 0, + 0, 0, 0, 12, 0, 0, 159, 0, 0, 147, 0, 0, 0, 0, 32, 0, 84, 0, 0, 0, 252, 0, 0, 0, 0, 0, 223, 0, + 33, 0, 0, 13, 253, 216, 0, 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 126, 192, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, 0, 0, 0, 230, 0, 0, 155, 0, 0, 0, 0, 0, 0, 56, 0, + 75, 233, 0, 0, 143, 251, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 69, 142, 0, 0, 0, 0, 0, 0, 0, 176, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 68, 0, 0, 111, 139, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 10, 163, 0, 0, 0, 0, 241, 0, 0, 7, 228, 0, 0, 0, 43, 0, 0, 0, 0, 0, 0, 0, 0, 171, 0, 0, 0, 100, + 135, 0, 0, 113, 0, 0, 0, 0, 35, 138, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 11, 239, 0, 0, 196, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 14, 197, 0, 0, 146, 0, 0, 0, 0, 0, + 0, 0, 0, 123, 15, 0, 0, 105, 0, 0, 184, 0, 0, 0, 0, 0, 0, 27, 0, 0, 102, 0, 0, 0, 225, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 64, 254, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 198, 0, 0, +]; diff --git a/curves/pallas/src/fields/fr.rs b/curves/pallas/src/fields/fr.rs index 88783b3e9..e660c7c5e 100644 --- a/curves/pallas/src/fields/fr.rs +++ b/curves/pallas/src/fields/fr.rs @@ -3,5 +3,6 @@ use ark_ff::fields::{Fp256, MontBackend, MontConfig}; #[derive(MontConfig)] #[modulus = "28948022309329048855892746252171976963363056481941647379679742748393362948097"] #[generator = "5"] +#[sqrt_precomp = "crate::fields::fr_sqrt_table::SQRT_PRECOMP"] pub struct FrConfig; pub type Fr = Fp256>; diff --git a/curves/pallas/src/fields/fr_sqrt_table.rs b/curves/pallas/src/fields/fr_sqrt_table.rs new file mode 100644 index 000000000..dbba97397 --- /dev/null +++ b/curves/pallas/src/fields/fr_sqrt_table.rs @@ -0,0 +1,978 @@ +// @generated by `cargo test -p ark-pallas --test gen_sqrt_tables -- --ignored`. +// Sarkar (2020) square-root tables; see `ark_ff::SqrtPrecomputation::Sarkar2020`. +// Do not edit by hand. + +use super::Fr; +use ark_ff::{MontFp, SqrtPrecomputation}; + +pub(crate) const SQRT_PRECOMP: Option> = + Some(SqrtPrecomputation::Sarkar2020 { + trace_minus_one_div_two: &[ + 0x04ca546ec6237590, + 0x0000000011234c7e, + 0x0000000000000000, + 0x0000000020000000, + ], + g0: G0, + g1: G1, + g2: G2, + g3: G3, + inv: INV, + hash_xor: 0x116a9e, + hash_mod: 1206, + }); + +const G0: &[Fr] = &[ + MontFp!("1"), + MontFp!("20761624379169977859705911634190121761503565370703356079647768903521299517535"), + MontFp!("16433095692735945303185004931083643981434465884121075650227802576650109544768"), + MontFp!("21072114672819995762202173356002239575696270036099880116652445698144873517408"), + MontFp!("18777355761321686825060947926532614526486796698585194982281091352721456712701"), + MontFp!("17258991436146355810119973685376275095218533441298334782752184209675844280604"), + MontFp!("27797327507283089324873767129394703145373167725827379946381898943628228102265"), + MontFp!("7731924740350478907485513010628116166508644282157767306134348358477160783581"), + MontFp!("25831901382065728664867960153155101148897150874178967238763243381138493467167"), + MontFp!("12653775985598794081123099185622764624095865431129132832686222345805629960120"), + MontFp!("3615400179577588840656773984226464440343417320963190535831964289361770568210"), + MontFp!("5416161029413008278382021021624773725195907867504177848771129841912824155080"), + MontFp!("11259925651627164334881635171602812500114059475427844340696813343903138111094"), + MontFp!("28355670648771483490224680380533120232342273591943348466048207424447551447662"), + MontFp!("4180951019783468693670098039008749576609177599505980828151810429442380310166"), + MontFp!("2028317125934973174799852804663668800563970832651450256457570122099653256987"), + MontFp!("22773247635032904119164032893125837000117110417590199562155140318113127410057"), + MontFp!("11494455961328564087819274090618969303667363263311105951339583464918934070699"), + MontFp!("19684138730829868100013104333711847524649871836417240896556685773303492491026"), + MontFp!("11164340852763508466339340459887687150908719986097997733588597674490565259868"), + MontFp!("21126863336283975662912415787330438001949531924978833296977921697588494931774"), + MontFp!("10131876587253645935772064573524725631389303880316760190444188969106229384186"), + MontFp!("10104204138541192481527509842540323621925921953869429088262191377176540551154"), + MontFp!("9121060571648894530726847180990992785150863619052333989552114756065415067687"), + MontFp!("22534705776987701833015514080593272786965165480514511310149191540493404156394"), + MontFp!("22267344986629007524568153963993371143298966226209784567833848362196600268252"), + MontFp!("9324469068598030576177038640056665169943831070649441945890747493737067816231"), + MontFp!("21897363000591280299475985811205500098238647803808944638770274903175407302461"), + MontFp!("18864540883879520854227019035015808151022735484174207314745861083291651909652"), + MontFp!("11969898399752339473153040556360000572120940299354840433906117451911556610370"), + MontFp!("9495573933158690788313608023749165170343899373427105752059361212327220690558"), + MontFp!("15849005707458555107374709343765659173566581413271474983044048281980783123606"), + MontFp!("16374165908474017255363312111776283654221082517704864233135435813379123366990"), + MontFp!("21801357014707014361169018647192924816183248901598188020725867334678385722424"), + MontFp!("12778822755673685200909725248381398305499436272791317808336434391647198892987"), + MontFp!("14054473248239940843590983459266045099364270520696694105138859605176763305144"), + MontFp!("12145264854906919137144267084573274999023129041057242607543122130425866637334"), + MontFp!("18354537436803727557297211245686173126695591991879974705123375127898920605144"), + MontFp!("8105126578977669539915736892158727546363744888571203156324001179711366923366"), + MontFp!("16433897783182729718320976464103017475848966480360195157832312982220478632699"), + MontFp!("7442273002436561654120446290887557308455090774801743248073554927997090313185"), + MontFp!("5848916041263535363244097925152162141623495156886527523200775851763672381311"), + MontFp!("22028078250799304503769561285898265270436360789569421977188952480344817917891"), + MontFp!("10767454236229421877740087775267414435559733771052530998007587239559009087615"), + MontFp!("23439571006351848386429844640599475508484193261979913265165342051644580505710"), + MontFp!("4851026052654751555052045349957763723053048567016560945088149018137384690529"), + MontFp!("3826814316366020831950345968067304387586751443644706642203408984685293991554"), + MontFp!("28818608295493571479565477901953001920548575060146902990909463402394959024719"), + MontFp!("810835282432913643451856148970144659777707867364811992076342287877256842941"), + MontFp!("23508475623287025267971921313084849408255929015754558509581027392296721806679"), + MontFp!("6480760830296719364075169599487512974198054325642867163224328240150347551142"), + MontFp!("18826221092713861511815510799214156898624625553628348061064047758680489955350"), + MontFp!("16679796839108360218457214023223414415303916892144782837601051533353204141223"), + MontFp!("27244712036740999009655289455740754687392841178051745652712535473083707169185"), + MontFp!("26460081660397206340191244953369859089878885290420356090208955582104366876036"), + MontFp!("4743447803334099842654650239489537772064677721387028733806147244205992544549"), + MontFp!("11193205822194034343537649587374456528188281407662776308106215417035543588846"), + MontFp!("25560028412647011718411964941158601765615154745488958672313994306770043853046"), + MontFp!("12951217545859904401361874683438828857683521464157751659238138837533959808932"), + MontFp!("9111863911441264256240191803708615141722252019051723112764562826704019029302"), + MontFp!("1154130591214889026811901258445163367738123304540488708909189217081068670659"), + MontFp!("6045285078160332561005654360996497378603062371964035884723025445914988353730"), + MontFp!("19652058420628366664975273171622948998204014333113030394255445784129200824373"), + MontFp!("16012248077001260602575823675306759231185069431840288519695387319650866845102"), + MontFp!("6994246201078078115052998405476578293716892730818213730095610406795858604598"), + MontFp!("5745994788002087797460191002569212107304949576006661408032478246462264672095"), + MontFp!("4508605432339034469261368468115624982874784604752006945649190054927327257973"), + MontFp!("21296541581447780463717093786721879903452368459092976761742010830857530558524"), + MontFp!("7687655443984009105119589537149006773451065604876569265741419698471214195106"), + MontFp!("1558107477656180372718911598378747058946513392368304928661681101788506188126"), + MontFp!("25600367352073576841796010907955775628128307062649418790937558210190936818352"), + MontFp!("12680401241758786032726789407915727789146669204002624726573463931017824535743"), + MontFp!("9532483845055010457012858366509677882603577458153377564860580271151230051359"), + MontFp!("19427909902129905318658573528053882499273970718343417097929568225205563138693"), + MontFp!("16290946441861325845156219837007940678342983358688633891061360756427413877448"), + MontFp!("16871167579025671184450174817823530026002728194736972687739975972234937268027"), + MontFp!("8779106342227212393803994358929969742140602488680528078581726977455943898875"), + MontFp!("9716856872796495163156744938772235203038146494816332376446103281407124517388"), + MontFp!("12005188446565590953571827411561587557141478808510398384349599764248485466141"), + MontFp!("22443376800489118954920172767001187234435470394997830476226810946341354756557"), + MontFp!("24524927900152215990042117840046230152521193374283291295805683736437754469487"), + MontFp!("7998541800432021761041048724442692753998436068407738332286968407388996596299"), + MontFp!("6022155843209121432232457710575512813433703566078928595585912092660115374584"), + MontFp!("16092107316689935325783420133734552195684271273500340957830020043586801576267"), + MontFp!("17933961588375546770617329592856916303429461187603449899593724045940497019970"), + MontFp!("6958926975488804452918811988699101312714985386890861410860986598600553257757"), + MontFp!("6854958761643515963511615033031242006952903237498340431232815611360853929651"), + MontFp!("20021410107120142881860939967550752088321403538841913660801371424764644327952"), + MontFp!("25010958909910877745522438855004976163536328605704936832862628487944510720587"), + MontFp!("25596088543025932023756962390608331385731495581386994311259990974802724080199"), + MontFp!("924192583065274662311768635485927526663726989997085717318234803302111412762"), + MontFp!("21194344261593408864155247016694777820577060871821097688169995842334659994267"), + MontFp!("24557474455222377149374643781149614477474687379681876827389866943526370071130"), + MontFp!("2329103408406631803236689400723229238431668866657982513783574815454068696782"), + MontFp!("18538537305901268223786753049760752358103991584689983082096414590628568123933"), + MontFp!("1781436594349331118866253461201061179321802683596534858257237796366861724977"), + MontFp!("123839892934474656487099268533726221265617661442911357232757735650804649955"), + MontFp!("15910417109549273753881526103453435311690542317135244041187504522799843425143"), + MontFp!("16149797473935255760069874668275228699155694852797445443573586885549759509219"), + MontFp!("8800095331101931552799971906694839539039208598379772749921319461294698308052"), + MontFp!("17813439067260664419872099143714427640189789916868178704599867356083606242147"), + MontFp!("28934426814723779585045951630822890422798851171525583564199750466678315627753"), + MontFp!("23690478223929900572217545871042907772085058373478301956902204837696131578127"), + MontFp!("15417751307128022426912355123125251521598265170646739289118385348954461070013"), + MontFp!("23671984221326393660102302551977401581202774505271543468418491820530700649268"), + MontFp!("10172253231022646116901682299201127705180298660778226356901197184792072218016"), + MontFp!("13734059899157120493601662225051149374171887058857552687370737797742420309359"), + MontFp!("740840083433489319128705754178071378226539068683691892227117846575186700421"), + MontFp!("19814190836331652519220383340130485744610316211848427361844196915078024533851"), + MontFp!("27978512297909170134279424472660670032901844041682256855039482838307554085995"), + MontFp!("1685069788284625053404060835681952921373630056513837971583047993687722692367"), + MontFp!("3313266744805482992301310057823283915953190349195300028633689156046471430276"), + MontFp!("10797084613311076821457784981497175532239708537611986963012575472801900549644"), + MontFp!("8525347601878249941884308034498532067411014283616456069105659214101863408890"), + MontFp!("13055128297696821224140920782410686557537306102763719317718539278681295368550"), + MontFp!("8984804096083430672242981063648376788040182636103676772519778360361614047687"), + MontFp!("21475070104439221455765645659506879480566460160072220137537350029123313645028"), + MontFp!("10387286233884942220050558617983126020243698677117423993361850645886623195699"), + MontFp!("24871874859448132480427037208672859710663394057395634064908881526201258156823"), + MontFp!("14125086253514593898135293950885761888510816711089895325457717990334737798566"), + MontFp!("10968172849111788386907079857298310366554015010927253076523133710801107903317"), + MontFp!("13414400250175316712647001949342017622825309584793529804065376276610611611687"), + MontFp!("214360564295156699658692154364332001642937105831672332332890997802167352559"), + MontFp!("7434078383923266053666214880900527876283599288849564456317015911350639204129"), + MontFp!("16435790958131564074553768635790213221782907252588157766281074285734710098038"), + MontFp!("13571740009525558368283578322772880347098595036837654034307609980347533476405"), + MontFp!("16492029923693297908539877403318171725824562757135718499424339178408626950145"), + MontFp!("1109206712201973929793876300710895620705074713507461334092424713158366702883"), + MontFp!("20538633354915317735728431944271817692417354819955745238307097304564131773413"), + MontFp!("22673989497923523700883844157891528576243941221484569147102756335083299557938"), + MontFp!("2827239891306644338807603924010573098437580667328121728503279978254604716"), + MontFp!("11594958009993862156886705635660132112851756968793733369435344410197709932445"), + MontFp!("18874214599269817505284238322051710606976307843266815386498432004439829056959"), + MontFp!("14715815474150533413757744154083622317880141673955572821090173648704320488149"), + MontFp!("19296984146148892463537464013587282938632489005780660211881983566305926594899"), + MontFp!("27886598134173523550130192726014297340447769268495005445823677849578734840785"), + MontFp!("10355370416653226161599833635978224122163484313693582291016745201922493866080"), + MontFp!("364433062166793853262105630170540333784800379154112532060718631554484662774"), + MontFp!("27613677903351677839871785568340328798758637517994643809875744186151919011940"), + MontFp!("16370768045694547912821474367684453844938051982673703982141218183194689772185"), + MontFp!("18925659299476471457027277184649112775661931688388346682902462054537624046803"), + MontFp!("28290521259089489270595812228875572698855538321013735853192166359708918072781"), + MontFp!("9760421434875566611199558719356103058000230039534664789825567227993934746552"), + MontFp!("15761854809351666909994856537599865242556421766211873722096192833459925940426"), + MontFp!("18697498541399782094732855555619079345144655466370049560872087351881328115797"), + MontFp!("4522028395380689857466116723270655787814654686022616751825444148478115024304"), + MontFp!("12720737398387557238968502716902689103005186583326774099431607912601642284229"), + MontFp!("9825310168881356502813449586795528678472049522275355088265027955865251728395"), + MontFp!("7272667914245129970399620943473472502537011524929219097838563560167144092068"), + MontFp!("17687746913668128102738036375587654265249716349159819012431237428824092530916"), + MontFp!("2837636670129335306179867204356151476295855804266703900242421606338662021542"), + MontFp!("14899036155408502970447933863590872121683433242564822758837098402476480305159"), + MontFp!("20900086656888606048999475036160867736518853039477396657174855819996809582400"), + MontFp!("22007610224189074369338963148028797037581748398652434467017105663256776717086"), + MontFp!("13516724124126051629576955998193189109233047007645565275330207565933178207541"), + MontFp!("14825765394450153151619410666730347972049991784290520010832619732011617213912"), + MontFp!("23500830607750475988067087671399936570705150149239887446831811037101004089821"), + MontFp!("3699012919716403760320180760068370945341801215296700479327708963076555668637"), + MontFp!("13957860472881778299881464101990484463805074580667999031445942832730408576526"), + MontFp!("23740481172154666772917112556369947574408722766020548354228224437436823649170"), + MontFp!("18520388538065708043781779826605296064096723577443583505383614163317730562813"), + MontFp!("20989818048025377110077267023844445877428823530480579820758011268040467052488"), + MontFp!("22838524038489716872825036724960600097142848778092125562632817223946821056127"), + MontFp!("18974594970810854534081123760376547829110253333217942560915417089248198480859"), + MontFp!("10935631276345052592983777101819549782754586284241461622069656671366795580176"), + MontFp!("11878492719653336649423001521423098844074268303637860011963604433075518169395"), + MontFp!("9494755432842053802681347810862509975231725664003180791292962987316790672832"), + MontFp!("21920118413304793879844074652798692044346446897229939599530817705344088352759"), + MontFp!("24357865871485124114479578736560040933387003100110328960910643826873304621108"), + MontFp!("19075699014292784899366433772409105998187262845912836380034666365410565517270"), + MontFp!("11904739635671036579061881929675862467912248654332317257841846061428860694942"), + MontFp!("12279052030491304661883465842622059065837185365298533264851827914660206719118"), + MontFp!("1742523774047959100834537844105849254268529993783875424398623759117975771449"), + MontFp!("14539802447422851089981590732926321174379932777597698296742423759342912021735"), + MontFp!("27649983213244808651643562102042802393072618312402071980274146628123656651825"), + MontFp!("627812057811130943907873155449376490301212761128624420738488621086720475499"), + MontFp!("22299229331200095866877229283710692866065327697653068300303785912699442893317"), + MontFp!("22436962218205739890134139095421023150517775874278518271849418998343568866801"), + MontFp!("18664770796967019739525000534466873796608687503716745925905242492195601299155"), + MontFp!("24214927149259399768092971632776527778172721567906087395682793325692461957524"), + MontFp!("9095419792245327718681411616080713059238322694288284740081392582417883414252"), + MontFp!("22161062590156960980769923259376933970877900257130875725648822580754309629978"), + MontFp!("13065146783105211219568020205698071507940121747246763940455812671389461873928"), + MontFp!("23779203610256657012950719480564360657378702248314664067972154420844500097469"), + MontFp!("13073681896268553994172726493690055778871515464444050714672250026793491390463"), + MontFp!("22017862685841647973285452541319258348127195541901339285038666561996841671974"), + MontFp!("25348219642461505015623489739867049030229391167912225982829127291831709398568"), + MontFp!("1646577138363862606424895764530978509446590034704625371044661879231917249461"), + MontFp!("26211223597981507233075263962767662742195089774582448168856285815302517998018"), + MontFp!("23755113069970827551619769834159115474583526825647690927449623741547019228213"), + MontFp!("21063246977433357950905145468885649818092886843923955963057924245325868327888"), + MontFp!("10492431385696590773264399277917438810864624762062486139605360459371048359078"), + MontFp!("1798138829850206102114637324130145882143711928109419487755238628249731916329"), + MontFp!("14392468233732266901547806298535759141528495679672404317688067497124496277100"), + MontFp!("24363628940589202196542233832921043755644811123097690897383711580585337845781"), + MontFp!("20755883773663946135953473497512931728960092905520469625862499055555022735266"), + MontFp!("2386436301450240233685994632975259799099212433266791663600177012145591459591"), + MontFp!("20589059866399563833992327970896804186663901317068859848304954385221928618309"), + MontFp!("18241429646016980666236789128887042976998779478768115122665455275709374157181"), + MontFp!("312397102227249291144268908116117628256638544828782444176470708629977056496"), + MontFp!("20738490874180604366230739502473046700456000536870127111932166214571449261912"), + MontFp!("5125436583566366489353655036771983519373646378545713092034153100691215538747"), + MontFp!("27753915346478435236479708232677570937009329677670585273848745095921858650692"), + MontFp!("17362797651413242470544548404562230087095420716224132015398271936476932846120"), + MontFp!("4975170235298965041991748375223448872011641888674302507281435260901898971979"), + MontFp!("11468110667223756424201449976978582472030090560927014288342577975819537695801"), + MontFp!("5511186048468227819415991476857118082139691420035463869557703396659536741744"), + MontFp!("23094891717878970267984883105367469289608466121711282501792151223484728995014"), + MontFp!("14148713160522752418782400020191247787816384942887461184765671911196071403428"), + MontFp!("1158030648110410790397162310399540859233686531362111376561912249807142245902"), + MontFp!("9385337714828462105502780501790710030719899294133536189749672470209579937493"), + MontFp!("17734168332838742947083505087021840690960734583329385142321847799516018757578"), + MontFp!("7660380501602205423233532419084291078645721436150077783159528307258987954424"), + MontFp!("7195585616368678474033131007151836597568747505314420721611451881563316082891"), + MontFp!("8023398645601830057525601541050587255745630572420287951424760236011037263770"), + MontFp!("22537996724388902449113845986232846226446984089362675486119232548968340171369"), + MontFp!("26444911583096359457019826618390157496291363629148329725594745356390598246438"), + MontFp!("18959685524822874225446583235806466051612914642266654731808783206024273939387"), + MontFp!("16816430004038374678500916043347106883851050472189249075477074372144917270759"), + MontFp!("10499955409090869371010660056633315324477380848522169264663869206776578871843"), + MontFp!("4102458086747131777509485616179052397590322588704586332020318998099549452539"), + MontFp!("27015170771312718863774227976162266442350861099828159010330427173689767308847"), + MontFp!("4789298529417884797452534646243942218042854175951834875267033116008412673861"), + MontFp!("5258838522963571437974995545772151153435664449230825776486243502511409431323"), + MontFp!("23486935925843295769074705366940989083696659649020232673360266345745686325827"), + MontFp!("441113126987833576155364932012476009433623927920257062890812502190406036094"), + MontFp!("20113642636897268322899869879720786526167509392640961477966494865649166637552"), + MontFp!("32077801484273931025100913797943156649194328848408714622555730009594447127"), + MontFp!("13588780846437310341370897597740963898034786862116883444599524911996854472552"), + MontFp!("4302021790819371408851304592478838271410422069401419953129110219556419508979"), + MontFp!("186036337103329436158944293112835123133175242578458709433626256383021322750"), + MontFp!("24097254935595673743814721328146857887671264112792088370589391181797692336300"), + MontFp!("5348293834031263655218928048875190233138224839784390104740502763167861514676"), + MontFp!("21845140615585489229327569409815432769966462225030493531147302766307527527584"), + MontFp!("21799889522396158894609824996931012432227267502473838128146660618297599258314"), + MontFp!("19669485876747640248829082018986361038700197539324689568413928606771921257223"), + MontFp!("6962071267039094169397628630783687041869738534424771018297812739689817716743"), + MontFp!("3027351618332571873174301371463358736904119455454064787938069230651156762300"), + MontFp!("22549681756686284870732045324470936981698672746927528812144867349872202716728"), + MontFp!("28633195942131640203017476333565272796300305849441815836245977636995777876997"), + MontFp!("21451930426603515456020332681327918570894142433489886340161155048990551201702"), + MontFp!("584962749971221686864106756080574116954497924273881982399626094420131946399"), + MontFp!("14786194979616741556917033520317864280702725004593021776173444969502127418145"), + MontFp!("19129455806954999971192977003159811087107340285669326231126273794011077459164"), + MontFp!("9841738749297347562741796462384479070512745310333702845560286461288621881857"), + MontFp!("21955874905889950141914383239473687310562390427032161310340791972052810817572"), + MontFp!("11107674333734357117845573957394788423997873516179152927219703654276631849934"), + MontFp!("11315795314720136504316131913773878317002549146981248999832289396657470041350"), + MontFp!("9463664697766302399769905836862827936737871275689517112452877655241526923540"), + MontFp!("14548883171711015098066168537209469785054506149477876393382464985937037668436"), + MontFp!("15048727976663140518463853122193016426890439075690229878748830752154825701349"), + MontFp!("6330698687260382397271683093235485103217514453190912755487111677291098510013"), + MontFp!("1562214249447278054906270653656926121677737978067866295920405567178135863104"), + MontFp!("28378441999225076009438500278233735192787340292475219705944257603473665658831"), + MontFp!("20520343098172838174513878646168389581098796765205655989651697234189383817338"), + MontFp!("2997051300247261039307243225861525820654411601867305645363491585782426197064"), +]; + +const G1: &[Fr] = &[ + MontFp!("1"), + MontFp!("9184835260888211923606117520784197778532238690982563737220614710555161475838"), + MontFp!("1741238373790734165276792884374561543758314828808135130497238787665395601053"), + MontFp!("541416221503736071553275631469135413045285769845711298693102868225072253726"), + MontFp!("23742353948330808019316511830601700476157065930332715549048460604277611443280"), + MontFp!("13997600715602221169956421313534463649923159406863046760872559769206161864140"), + MontFp!("10593073657864184434077744163200442296987405918821514718920898662987231484747"), + MontFp!("17500792007060653180581526633370990181235019908805065043396971506258005295736"), + MontFp!("2095012359923450174901864870051868117908165457306906180047936153240862409747"), + MontFp!("25007823114970140040455160412006498958615936100820145471328374366828335640937"), + MontFp!("14954059034378184092522874914207077202425638802224621196968943166998963803797"), + MontFp!("6444422013696482428357097370721800485571347690200597323050139118531183558026"), + MontFp!("14781787882221284606048072759163668262794110459174569229318427883816622348319"), + MontFp!("22344766121099263422122575482060448748041865319653896874173948834107898123463"), + MontFp!("11155225742808527574489468358040745796680292943791509797082405929022703294695"), + MontFp!("25528342429487856103559845675357600275536030868821737300117929355997791039452"), + MontFp!("11721039313012387933861353830749489271763273499470579900985461546509774571625"), + MontFp!("3085266517926615034991123949787857718289440181475545129658505991190270540576"), + MontFp!("3359876123967030628263845928198157822612305898077292310626301575669731228690"), + MontFp!("3335634853918117183091764984625116521323222387045006004955447028795789232616"), + MontFp!("21294602415327772121954931973825297909073489650918425700195776041102102192584"), + MontFp!("17877242333961511069832667079946918199474319279291475319960398782258528700022"), + MontFp!("4008236355654056157358421486644623749218519258966634501315212880622435144761"), + MontFp!("21088323802954785758413468678246889053816378356022951819498340197392931460779"), + MontFp!("27828779900550157063555260418392500157517003047258771046876189594297804930286"), + MontFp!("5954233736665713403607132157286380249484476086451549397290749746345030669456"), + MontFp!("746746742688266692756078604162754132543016921645077258441946179710722996929"), + MontFp!("17077864674846234000610810182494458675161905607425677530578984728401270335490"), + MontFp!("23054126065126448984418504476668906404230008395707966198695440263618529326134"), + MontFp!("341632420771304165886357159691329824440703995386819953265507078826408045687"), + MontFp!("11773191243930733733799056972438965014318633134093801839872140139475307774494"), + MontFp!("28470598070230852311115233720975523808731620729454775390805677362057245185804"), + MontFp!("24765410221021998114056579869882687256732934083230951195503663650676864026780"), + MontFp!("10730958431565497431344246018443587383189596722809539639535033787133220015154"), + MontFp!("2710556064125206144486043341019311574740480567405015870592683686273762591736"), + MontFp!("13215046638375041062154995746928142494191449971406541354555877408452566265408"), + MontFp!("23915213576758940795213045746749013273371721859884148194359490997100051339872"), + MontFp!("14289055843227563976699932244948461835905173066259967873830542976964066883023"), + MontFp!("3939881321347732498612170463529413263993288902453454460078361280117940426297"), + MontFp!("24535888014155795278378794632429229662056474039521734181068800652084626433684"), + MontFp!("7415305758648590016759340418658568701303102237326858025406061661479809364044"), + MontFp!("18315434601591291877312527918254302981070436570049958610819491869129736393693"), + MontFp!("11133970990795421538576644960382280778892033190905496078673147923082595513572"), + MontFp!("6756028086582314927924968589434876789670086491672441911671782030476510688403"), + MontFp!("8795648331581715799930219831140487322432335806968179785969088614549148668628"), + MontFp!("8421842912193304329239488908102737900579998798493952989112171073416488572182"), + MontFp!("424079129950871424203277218984084412159593283460370290259141246913366911601"), + MontFp!("8072832874882039092883838253328294597763007242222906829737847872787933925744"), + MontFp!("25620816897025735624465887708714079804433813534947966634876926284110577972583"), + MontFp!("13229744248913521847901955161990309931439787340899700850310512785521717386952"), + MontFp!("28223506723283726381879545150212270233694312930216742551535723741261852122126"), + MontFp!("11268145467738982825550606136221013821869226442306359604985489613489187054861"), + MontFp!("12504126843997106919376583046325351628438852404123165783019773188888814479681"), + MontFp!("1886864731496342474826379453726802018982494618731865390318798613069415655218"), + MontFp!("9111836271697635655430217459768050224899446498437565966969133247162829701534"), + MontFp!("26734665122106066283177641165234481190811915153843424092573106794438903729049"), + MontFp!("27963215877306556444620901588093594687149157395537399858563704861206582435518"), + MontFp!("3565973857784108883318326438476475420173349661945788676701120746792431836966"), + MontFp!("23914395511398589641677272413958319567044316159277887166847406857267393901316"), + MontFp!("3731677656455318881843378577621089035717480614097789495610195368793916728020"), + MontFp!("4015413104958801443177263359953441958362718436855438079344020735796736798664"), + MontFp!("24089343455043424248081683268336321361286281592899187788416201503578817055218"), + MontFp!("5745803775533383965139212329075095844177572632029461861689929566178524488378"), + MontFp!("27391475114199146251958154086805649625070642524187431070511012857039155941217"), + MontFp!("11210613499189137433890860267777244133646082437103805267688089100263657462004"), + MontFp!("7915439440313387288944916402994598257426723250920217428973966202264150228923"), + MontFp!("21284079611033471478615573751830454784920473273959685987849664184878299042887"), + MontFp!("23557595163619095656120399287123142673322361118545548908222326858178766919464"), + MontFp!("27153980286990838530816089026330275627009336394880837451473690390402749768812"), + MontFp!("27922035725262534448180273642960599764824163272846560695337401287012564820047"), + MontFp!("17001694344430819221615094720986308902133418613168201089999231507348513356469"), + MontFp!("26985472076413813914476884504943802085100998905889222319077292909563750613778"), + MontFp!("8023079107555005672702320215420042032968579402139593266209277759602329704271"), + MontFp!("28897978485642036405450056059879229237785058331422257009800570615999767646889"), + MontFp!("6856982619321111825676401120572772305594179211495434937343609808073271836025"), + MontFp!("13002231808445565252196981143628474819491940291840595303001406909498458450339"), + MontFp!("23820608234709105198784254091622192302958963886051411422301459412739746134040"), + MontFp!("24364019522884213039278889777597293822907349355477173743721060392415056231733"), + MontFp!("20813237021607222856474397613504578073493843547218384992718104689210791393828"), + MontFp!("10955324067748764838814610566058001740867103963567796221456700086626217542892"), + MontFp!("16693689564799182546887764769242235102907327420904500509921452392746504606063"), + MontFp!("21019593418404072597330590629334971843030224628775887749600886606127313302907"), + MontFp!("5371335416314849334031890994386242142092422962646991759326210345451041047335"), + MontFp!("9699790622419890334399960430070684702907490480772814748070712496472969493579"), + MontFp!("14702436936761936793301719663189994254312090634401698329205558380885099873190"), + MontFp!("15062448825279426679655292698674647913241397373765493161394727517313706387728"), + MontFp!("1845791790178970631805946099130782412249659889256043151610481940540235994559"), + MontFp!("25427303556214166354727744733026471932079112571350706932305714421918049225855"), + MontFp!("26772493566884057316620370104789310712832245012128066065957998345638980860763"), + MontFp!("28227711305025620583545155182193860388841938762692675144628380656148517654479"), + MontFp!("16302355415070628455149119924759897754431601829247854850783241212494000898298"), + MontFp!("24228458336272934788458026631595783699156953825991594330421859135699341538721"), + MontFp!("13492866399170985628583404745394373316348000149644450913204057731742540688421"), + MontFp!("13322530797593286720312403017135715192541962863613528150475166198109985598065"), + MontFp!("8174490519756723665823176241154708955265606180688330687816146036876928165773"), + MontFp!("10571185713626747985259689479240392286851566055501684882774650788840658978829"), + MontFp!("24552163511873086848512222633258784788735431140709033407151205634166328282885"), + MontFp!("13238372117390327949174064482886393025806340848626580879662520720215269327724"), + MontFp!("17120248078512376206885796154655036133435039627453973962273909699824212641969"), + MontFp!("25866760146200273138456645648722456222226832447049304661552218273901930206197"), + MontFp!("18421647705461619076304174819537145587265890802099555783274822814611142204761"), + MontFp!("10376728646580067535127802189682317752352729259102969845246703677236469487779"), + MontFp!("15223360509274398774813854462332974560285955089035743015117866027706531847686"), + MontFp!("1189852255305415014376947414825428710227615749265848341445082042985480374454"), + MontFp!("9172062416185244737297089348401243202557259014774452256889696715292937919379"), + MontFp!("28169456681225770235116698796452448816086429895485522706584210925071203832044"), + MontFp!("15689029665516802879139727335682647271791060367888933129697044670266257509929"), + MontFp!("25275182413933207311340728519444362297734181604940102210607076403065094384281"), + MontFp!("15041291094634299682495387386092961860054121538102899569655410771717136393740"), + MontFp!("21387064973617424171233371227606911105501072096280841034890425752992135923667"), + MontFp!("15760898179764509845853978712354003288623129431310791745003138839366187800568"), + MontFp!("28794110389533359103722851975141296353444605055891507413993489464294800982504"), + MontFp!("3429028186898940846376107409406900482493709971608769443099199270047951370826"), + MontFp!("15780301660254521309264465495095532366519730253668694216084479672121948740405"), + MontFp!("9207228625309036761135990195942289051933666442383119506698162861416503339197"), + MontFp!("4440462412958518074590106383659705589059811592474327720473035277868798870667"), + MontFp!("7167230027896868398299581988942743693925096669618189603884349205881639728088"), + MontFp!("21898946057890173538625661915094583799141670397207311542137786522739600638988"), + MontFp!("7385771250518455877070582366951907544729486722251661660622957414163662841630"), + MontFp!("9383021463319318752843494154212099378363431073905604694997629779337382113666"), + MontFp!("1080881589863451258479824130996053957612402512192716416493007448530011625802"), + MontFp!("11943331082359588463095692577674375912399860658907103821674392778518521805945"), + MontFp!("6138971103530592230870905685160742788461342379096548765938531942274027105514"), + MontFp!("17886286675916425962762889915586877138167946801537680144456048407026179881692"), + MontFp!("14957590861832751268757967754472594122621052354962555137712085572824186351874"), + MontFp!("4966906301816793365032635755487023317080441600982169755436785023752171876254"), + MontFp!("24205150953059524279481503218022494685107591827969393068826670991327768940670"), + MontFp!("24713770004863212597139115888052054237943844051500781879495148244779975604757"), + MontFp!("7164276914317930276599276463669632978808040252946251374608613133198557740551"), + MontFp!("13682362015293116676581119062130373542366628304880851572061583187230753219925"), + MontFp!("22706685674434598039168254120823256482627639919824860362431093398002357470439"), + MontFp!("5794219320905150786611058872277303089583471064298807808130955882202024084157"), + MontFp!("28563266655327060466746715137607888331332804466746065646071156247304457720806"), + MontFp!("18927384876496432903999792784088177128700604205610332916275588824775339082380"), + MontFp!("11677535237553105209701990783695506310245863956992198848177156597525981317301"), + MontFp!("15358239526999333894033547700594794998981172605053459518208078857034434887842"), + MontFp!("5501122621254364858674193536329732805561902778596294438336956915074532947659"), + MontFp!("4783365670591820108042751663812600868502973690199050419717234392012417083513"), + MontFp!("23739505938606737784033265445309574747125480447273941010769293915315846638516"), + MontFp!("11348587316770997861057941794238447139532333104129482962129923100268681982820"), + MontFp!("26409106723878914410635431791906830593456002360033815323772749802104721300384"), + MontFp!("7591243107539953623010573776214929725938990890960121181512960128677673206612"), + MontFp!("11245417310829113443979157853224297639600886877234756494880279682359689627772"), + MontFp!("18581549738115396315664918008625435765832785754780834823722444695759657578584"), + MontFp!("17644763831604328920828445944436773213859678107447132143020443236087563742860"), + MontFp!("19740775778102167248959944224262807232883636018255609543743200097513981563936"), + MontFp!("4318210110395138711323198547714568598444772614850521214253367885412520564016"), + MontFp!("3679614845807192912224232531445084191789899009568275430722848522043365003900"), + MontFp!("19879737953797826121791979920066352840437168883129665512128098634921762082291"), + MontFp!("19697307116477219461661098846640473485084369565534037367187768083127684736748"), + MontFp!("10293091682072009350958956304096033473368734432013812415871504868870805773108"), + MontFp!("27951006755909032812057184124807553218625259291184990550476346611129361011017"), + MontFp!("24820039520582142708096451230038564104087700377550201927941359150117274922215"), + MontFp!("6474861206569207504396932101279650711805777088149257820854077372021786130612"), + MontFp!("16798749824465428110885802558135855970010954933594059523528712036428732601956"), + MontFp!("23880220273649549073262239511880053208975720290680866296293715065182589832408"), + MontFp!("10587958281704720085817611342582036793351726140743124510624809558165629484535"), + MontFp!("26965448712911091625311858301723405615841394044816211618451104209287057393428"), + MontFp!("3628156654146683092635013199945392911723012040976472610801677642602271262996"), + MontFp!("20459046778370572183837136464486190945973494592457911684835806037632025979516"), + MontFp!("3318333830591707508542859212730782240340435879517229079167165678332279767503"), + MontFp!("24336686152327383276497402859698507253594874230585845966794141641004244864658"), + MontFp!("27019087796568238147979305156019735359219249718041824252456253917896921778969"), + MontFp!("9138259287154805500852104476861991764709809573146823730440588223297564830035"), + MontFp!("3364021808437739347503234075720239285212428794684490137878828035521627044475"), + MontFp!("10389561203830120340514226975086046201406806842316620496856941544726448791155"), + MontFp!("17660183026561958710206750755365104268195445368130086454820269542366515023648"), + MontFp!("24406605375913943973407877710219727373101024933667799244236688307948497707640"), + MontFp!("15037341823165351447898546382180318168011503085414493783772455672428111996700"), + MontFp!("17200377716409586969743825875284705348031650645757295595921695181356445114824"), + MontFp!("13776523402655345522710546288214590551824934126231322793891961995032142974423"), + MontFp!("483488151578408604334091644286845187041197184544295083736600329264319491891"), + MontFp!("25264593285675989136686666999180493677234537429983744659749186902820507055703"), + MontFp!("3801892518566373091408684643524048336275628536464693879278115868331508705625"), + MontFp!("10296687801755000261150844113035340766169672068204409361408106910152372215732"), + MontFp!("15126810257142808956881925190496250724963693129876695817081145423922473683106"), + MontFp!("6337470468329278420866368611991140366123126021209112485476614860287783153551"), + MontFp!("278232156268925460542799062539488382096381481070830340474856424493444836651"), + MontFp!("8984616086694246480869001597661864173773316381778327366409104416835191875846"), + MontFp!("25224982218818353666135596825046103114346553441513926435557081089951471734112"), + MontFp!("27939978882207687018846582865783922396768013361300965146413847063735750328425"), + MontFp!("20357678005618318615219843032632052813353671738855452866222026242159790970272"), + MontFp!("16533607204054795569629808603668780690580036912019225953738545189707711519329"), + MontFp!("5260385922757189509767231618882913507030623571710597140404179670101378952150"), + MontFp!("20513985032633032419462609083689158766498542611321945607369594228276095309484"), + MontFp!("21599101008310650185533909872541407505970200362518408334752807966119589621407"), + MontFp!("18481353257412020987341433832568489209712792436498174461979078098419716832109"), + MontFp!("22795316253774989396045514403202099055934664250661854579855330441617186716521"), + MontFp!("20309113821870795873627354266280990549207615524100502551653597531662964329931"), + MontFp!("19837698392511124298399622845583646958883127846422582306007746811062990467422"), + MontFp!("28713895170323512843428462768629570438906531106540899490677154256302629440227"), + MontFp!("15282328237469364960959545246271090261785967660210036898343186438223066463823"), + MontFp!("5738042386797263063400703430907823965500407824929164276409402963325676485528"), + MontFp!("19546310762137857339346892637992800575272866569843873215643160672044856422430"), + MontFp!("12226220499879266874679838567561683353551808020094987270094374806050343324555"), + MontFp!("20504066623108373170572210284286563749801482929857518680750892675369183562343"), + MontFp!("18677607994336047869744944199885814381839285548259180879727861935647883400274"), + MontFp!("4076929713643203521119967408804779337739443717994591218390279554033563593011"), + MontFp!("4835896034252602099337705845115400486789781039729698873766963303311451518475"), + MontFp!("1887490908386657916978570362180429523471915824853192122212874643105535293742"), + MontFp!("5853268486539474789010533599108133611954006488238227065222890238838829420390"), + MontFp!("2668845692024656007893956451625112630818988080934361720012935183838547000265"), + MontFp!("7603606772529380164988619734561643911962288742625291981159436534630972578389"), + MontFp!("6796564290708487166684928407837287945826178589997790074695074625817126062475"), + MontFp!("23801902977399114954551604403154278666642443730101529803973093218820531144476"), + MontFp!("1991536534025877804447228136603813019837499639746281350765447541373605051145"), + MontFp!("25934759834651331457816582564115622260898000542300814467003277317795912000031"), + MontFp!("27735010293634131141395947168562716067410990609496727841588430290647934949291"), + MontFp!("12208465471778801894171404048403450125700397003382459837307649367749393305337"), + MontFp!("11971196575072801559044810898253096383991266479536606595605092622906388582044"), + MontFp!("27979060052178541284935410631493337599656199281068575288025217837447038841664"), + MontFp!("16018698603509446225754803522901952875120253153831848528269112143196780476061"), + MontFp!("8173868051349853469873908106716460574341346678170765571218996094947160980437"), + MontFp!("13463565751425075164099743477564209830917436816351144030794994973926464575803"), + MontFp!("27027310225911569313369778670016392307982013651433746625463959804449237675584"), + MontFp!("15821282071281344113633381125362725134767882051374799488919878159737768349491"), + MontFp!("27944245312490764558350128865982739969215405377071915472609229013219778324009"), + MontFp!("26359137065710325569394931061370140574621374769842386636220230797161385226749"), + MontFp!("15647087123329094395706483349737013473351956487945737736176940651084033963465"), + MontFp!("15290159803798850577327413546662626855765081911438980500249390995095736922535"), + MontFp!("19228459219758501275391545664498058056467243812019414748704266182076256082613"), + MontFp!("7547289641061563883695844747198272695426042704563904926843389122693454783274"), + MontFp!("26077562659674280118552663300569057623046343590848783663689730219555555936720"), + MontFp!("8753249771664857461584636457162066995628381743535547187813662319623440600648"), + MontFp!("8211986605966255278627054182213449639673086009079076568344114752651718737163"), + MontFp!("3892747055599545246984294365694524348325134759468294395203223907104711187466"), + MontFp!("6074652047131246519595185567857281241519111361355851332395469289678798837627"), + MontFp!("11229847878288562893712634311712206510164080715051477067032122328644290224013"), + MontFp!("1783939989353172094978347281060364038133717741490190137772423360660384349519"), + MontFp!("1735913140589007626551865326036597362610776056787071661479795431839898125253"), + MontFp!("24027346916148106787785233248053537616676773277082009956983224655442249564731"), + MontFp!("13756182959895674882346490166110909849340904395865234967992868413557543188858"), + MontFp!("9784512086157729641867841905560966604280258205932549678664143681656875019315"), + MontFp!("24012714634591694128544234095353475266319491232997674967315504669461672078282"), + MontFp!("7747516829371599765621948023391663330212943976404020187576587977899859518968"), + MontFp!("13723862536154407462687771162368324601786332664330859751358261913544976664247"), + MontFp!("26560329409869289106357198215605349918475956781164091793668582612583619239788"), + MontFp!("73760229184314233604467109178614580923847280325867614412361778322345618219"), + MontFp!("17700891900937244141000557421410941165092392383839075463987897011342235713102"), + MontFp!("12602835962424323767247861736643072990939456244983004258319021457450274849911"), + MontFp!("13527596131453591060456975425247861241712593764199195756471352225816423642053"), + MontFp!("25881304542719977399936426047823887345687339117274748358905479021476608854361"), + MontFp!("2390758679088669928041266290303337296813577957480098248210091237159979933934"), + MontFp!("23926018927950974668065412928623066401673584197112501528775819793723916328051"), + MontFp!("16009212831809063163023199643265762185351467780861989777097329075634675026634"), + MontFp!("25607189576768242783622741069421734673362513990824085372433093560285343312945"), + MontFp!("3302015630971194801879717802458716014449414285504655818796799223892303912433"), + MontFp!("12240876008489276878144504387489368437339436322936258249292989987403676954802"), + MontFp!("13909768306241992473747310901988842640978890499223636456477699053491741058356"), + MontFp!("23371918845332827515466987895728499021796928423054335415710600358104805941422"), + MontFp!("4727162176580664079617653943431748544557351318887320182976476861042141865748"), + MontFp!("16490410094037192879357777010568552874769658484099937911528135504710665537212"), + MontFp!("28155802889441108277622119622050772664815661085918666125675923722703752066376"), + MontFp!("20093141791768816538096134925391761538062150163793842665427551386112477835613"), + MontFp!("27577466337038349222808323899547589290996520516481324825619169079254135200258"), + MontFp!("2547091855993118394310137659642050604373384267299520821191914288852104888909"), +]; + +const G2: &[Fr] = &[ + MontFp!("1"), + MontFp!("25495844600287922982375847825735118051357973597388778743844222198976976347033"), + MontFp!("8617115995329920206430890306720892888304016404053385418898020543807777256037"), + MontFp!("2249955825032018467848168360223159951148706593540406287628921355120671328689"), + MontFp!("13720502009405270468270247285101677286753189198487843249698478072631298866919"), + MontFp!("14367644081176781211790609827159158114790850921818665499000019743709717780087"), + MontFp!("26913798635704810066968711506873702985167561510857110951208122627544089538951"), + MontFp!("19189225704375023087868771433557596818037614324744191623350931487983157620650"), + MontFp!("5567937543998984163587088440767478500966827595555460377548789436081190518055"), + MontFp!("17069464802380973803295001861799122459733829198265590273500304377501505074545"), + MontFp!("9582243100913254159431767899747002153953943068910526871577368630428639149654"), + MontFp!("14678758399800595437849111300741253894956644933501535597512581447068579615565"), + MontFp!("24320649283456700508846519522630276605541443939293173511448095194471544808752"), + MontFp!("1330912478412635793017765052117989547217030794067541520548025953014698427915"), + MontFp!("1352668573138912275694480116865131507883672196493653684191256274532734688123"), + MontFp!("17290315865729615830399733828962999006592857704287154159443575876007282913793"), + MontFp!("5941528852119656486547009376921379859061890492327158217287419805481663145328"), + MontFp!("24195281356599827979245315611572407131296467281076964006358683955501672657408"), + MontFp!("27177417442460435245032483610825481126003242705556086143710949446602674643897"), + MontFp!("10396160877241552287306013104639033804992293788429728884925504588770089187893"), + MontFp!("13810432936129103645570547924238876899428902776513355376829570435811444138774"), + MontFp!("21913287887979588824572295834138920519957680668381215767933302607345899827335"), + MontFp!("20666478641955917646473706630847563931456205414127112739780080613614786294183"), + MontFp!("6130193074192028835518350319688336652731870639577934599724137709958818529911"), + MontFp!("11554460389700527264964748497351312606093411842747709453986491694759221474540"), + MontFp!("5990478161510855069174646028878289553953229180800049305636629657571837613589"), + MontFp!("19589113074933367440563417337574296745193940653728770903595539618077700962162"), + MontFp!("9939250949731599620396225152946502029356677718643243871898918416417641914749"), + MontFp!("23053704336461615371017925279944059251867641239886369727607543080537599043744"), + MontFp!("24933705626886504058098389484266735605620549106424357956390706455053628577842"), + MontFp!("14937657941973621722188389349511146149016130373295176913766728665356795197722"), + MontFp!("27519594980884823894627996910308205068050523215565480308931423033556323190245"), + MontFp!("26338948342977721520891988711654847344182798231233709352645110692825450890678"), + MontFp!("19743100320612481574887790509321440181165197944149188101499335585978435035064"), + MontFp!("21821940358387892979297433939569029679274033398799134942761506542002428607367"), + MontFp!("21837021983055945307461074526714300530084760863954019812027334391199005359912"), + MontFp!("4061190451788803921268913837335396114168640671975060417741978048966127182157"), + MontFp!("16455410351276739004492930088981280672439440767564551078175331107437938093469"), + MontFp!("13039605259208627462866839339188199218675125586879728269089667191839000964146"), + MontFp!("2481145776943260284460410946151947069304808092558664753672368286480702169694"), + MontFp!("10612732878093268246976733976689428484533719702763506373000166864891846830250"), + MontFp!("10222801310986904649552054803709355899844012396437644551489650527418782677889"), + MontFp!("20756537684672280984510008614163710727352512757469389660621529697536076982610"), + MontFp!("24266048676849043309884774942918475955454722688332868389677943669474857455090"), + MontFp!("5874549941685763827090067416177334203855405438551049756136877551681703726199"), + MontFp!("25460651904093113645778192583886686356695820671996498176945287117647413276216"), + MontFp!("28504946862368369728714147893145505790446336341117026342750081480131863326962"), + MontFp!("21918313840979154361845510734335678469826023384860722681802034930779851740295"), + MontFp!("9752771782698968646135698096772483075715649524039981997015713168734327179780"), + MontFp!("7948294241534826735937407619576744674372316814115522861937255759772201291527"), + MontFp!("17874061883263391480059943279469035030376230674857964295497517953400202621969"), + MontFp!("6103804994110497625480004759811556293508551022323052274648866237876138428798"), + MontFp!("22691623305049064931045075118295139984402888345777331752345708118718949381082"), + MontFp!("7456154069361657632436772459051109169872213355734944582652149138991955760517"), + MontFp!("19942905124031509510522630273106056925431793319393344000830026592882831215250"), + MontFp!("5423025221574732580668887427115296731551397106280745102497820685855453769020"), + MontFp!("4088228604209939037121605905705511649041569489522934548262729268481999843932"), + MontFp!("21726044828941095694481489718701135355299659977819509459201918289178808125730"), + MontFp!("1650363963388690453100062682408358919224357990501140980649820329465524412307"), + MontFp!("1922105423488747805342497233753533550452131396573612603363404241966264827509"), + MontFp!("18845229282064417546957351103053596167607138857208429698923999385653245980506"), + MontFp!("28306187498839321966628610659904523741828886284725875928271385276030138078012"), + MontFp!("4848793988745023817592426630083046869581010752017218741078362958651148667207"), + MontFp!("11329335487023862446284387179170618508902984379382725858872571508138458637370"), + MontFp!("6029840605409716029039145981374630916618202962808146989375357992541758151786"), + MontFp!("11299400890370890459501857907995523625854755376229953696109326527031360177995"), + MontFp!("27630594415098193092799185122680066621851588548563039243682448097297190792974"), + MontFp!("390791524852030617262959993630641478045157260332757209495265748801660003621"), + MontFp!("13072342652739484736104795833399069027427544842716068044884380729411674578446"), + MontFp!("17731058981847402024488740158951862534596635311744512158401403904451233705419"), + MontFp!("28432045683048767851696696347548362365637855589292781633986105062020191349633"), + MontFp!("28378045166029007923035215700960269545551338499086942142044797165004994922880"), + MontFp!("21151220154374048503411235271707290549017505057941095474629446697626231396740"), + MontFp!("1922640490432949307940436686238905064971364489097277975637873931625877795818"), + MontFp!("8425372778684283531409103592753871814633947201361432568264067481392568209326"), + MontFp!("22090629948114323753987104088924831872476812599648865349245799138406388610428"), + MontFp!("16560729817529685755600727687191899144560359212246374869055495593325370743169"), + MontFp!("13083084287382419544243608315350113101545510664083061162797113119403736037661"), + MontFp!("975381460432217498276747831430995572741162611452523256231735085981738225321"), + MontFp!("11798857528387562775644672761515007651896018885095696272811940321929328626125"), + MontFp!("28108949444154646428532909109147072584178666175862945217844723229615866080223"), + MontFp!("11468406038797570808626032974693195524560839527880212979863791084021583697366"), + MontFp!("2580759161573100748847758047216765676240176152333068400831336145589475444569"), + MontFp!("8272525709261988007219685254367764191436987379182740388162431993881002444840"), + MontFp!("21360611168355821547252500710454950999650974412559024590698084472397493677209"), + MontFp!("24763533380401457994822816427365897301550589786585665244286685333708753650875"), + MontFp!("5380508959803787239392314871825183101407304354906695640520669473072528758864"), + MontFp!("925383132633573035091439899810904626599461664935759593632501819565276266983"), + MontFp!("27061207164256538720932275435482541829321764936644070245524657151957260350905"), + MontFp!("10777518544810134736903753882829870988333974568605794928814682901635419901112"), + MontFp!("17415355654044297289100242658470899706539447967852697354984941607375024584835"), + MontFp!("27227960157062928041515119749738875355732015828207599637827899618501671835684"), + MontFp!("23474944032628565355768831721605621863217628988568433840388026828645867172567"), + MontFp!("27003535686788177007538139910428372176934860752706100461537528749099729113417"), + MontFp!("10302048668344164011785806813785539375519521548065515533111594469860997193382"), + MontFp!("9433433764894480354110574284962648747889839818830190573500771575856070224607"), + MontFp!("20025161372696141558806889766778253207760587373165916274421158994588674652760"), + MontFp!("6496319112637640133091610622541791534070483635488720666509439371765059498846"), + MontFp!("6327154203900154525569711415762241701756347924102062166309812035790857759498"), + MontFp!("17616523040731244420412419645161208369045326786283364676971047413639098300428"), + MontFp!("20172562334974257690548805491255843929934998170853694664456117721832212233163"), + MontFp!("11018817246462425165147947139383696096040562508740625240646593432849543140566"), + MontFp!("6101374879170194695393034061044890585819264309689613488131071596777136061642"), + MontFp!("27830632174194429152260475546006457459400278479265653193695319778168094999345"), + MontFp!("13548287447841053529900420149015861494877987067187462477370061654634019762681"), + MontFp!("25646757430227538384918041786381296505841034157742188400673538389336835114334"), + MontFp!("9959249192222609745636447861401100406848521352523286278953576805344715874020"), + MontFp!("1930018918786192026965384782875269201373856394831081564015666996184047687129"), + MontFp!("7667619559926818307361321942706213715394614318892932524408556924292235528686"), + MontFp!("22581108560663881356436128806857149051155188511494253662431752402135180595833"), + MontFp!("22152616072567744300193665472134954696223419689153736605434088981501446429534"), + MontFp!("15893335886973835656107614705382125255988671945716836627149259759132018188156"), + MontFp!("10110583466107038429617127313591413389926130272449319930283787259308864716483"), + MontFp!("19789900694881215195136218759396846755216755578575736073338990137355363015372"), + MontFp!("8519069017492273879310616684483254835949552447264758820452885479442495245901"), + MontFp!("17417230448316955348639995228682523277347908920247159091008010257039224895284"), + MontFp!("2584053924937686178399774597611689576040656700882160259716755056902617374892"), + MontFp!("13496528412950851725381154320051797328626252041266364331055606789118848014338"), + MontFp!("22649760258419974086350025634545300790879633489711898010027137617303365570731"), + MontFp!("1303207292259211421410856844729221902198199685659290515342157666826613979734"), + MontFp!("12219053075513652931407110983998972067812813148632488011660355406342499458383"), + MontFp!("15221827227245983274395062968738977008948454964728759502300746276422545460796"), + MontFp!("12823166584605938600689390778132655677646419494563073905465808977965664633050"), + MontFp!("17579622386212353268225150722081435575251856523983998550187409668341417487525"), + MontFp!("6011605375526861355525825587570346783901265762929139329641533641914921193002"), + MontFp!("2664610635988371226224013458217609513098602471740693714258036759494550111939"), + MontFp!("26474327506727074859300021408377502347500424795796875207732597494078501652410"), + MontFp!("18211612504749934474695340082757148733971180199007974359552441634322054893968"), + MontFp!("4732856566951780977490840117445510418141068801563323774232132705307561697797"), + MontFp!("2306852656257300086823932432261794670878186997241576425222778369522557675543"), + MontFp!("528783048357071544284642868060282668913353037832248776825227350982596067774"), + MontFp!("5990807287733809396285898542576862127408101041636010060988345513925369549378"), + MontFp!("2670948517138547577320689575841002814202234363275410183805672541737309373962"), + MontFp!("6062923816460903909483381844172458338164393345431737893605174544449421142866"), + MontFp!("24460506559796886764550836637047565854589558697503126190572435512350206090782"), + MontFp!("20838383753223931886647380486778870235231647260452097034024362916768586614164"), + MontFp!("26814155596268363044730056964848840619170312139764342804935127397601265190753"), + MontFp!("25821188966565706360915238294023487690727110672893860348500695279373166897140"), + MontFp!("5311845480888918730663531408014212260732087991521208126916434801122686889692"), + MontFp!("5308120410935881914907147005416041495412151456158564307175138634263940411576"), + MontFp!("15675134125193917630037768465994260139674331589995892756377708716617452275721"), + MontFp!("28766373778138814488686577857795909935556610672803742559864376049039979657508"), + MontFp!("6140329059802169496595398911675149093643945223586128273168370528377790977334"), + MontFp!("10146842129035452532461806446686773865767916614988014906728699814091050770276"), + MontFp!("28211121245456823391551115130553304654279523212901125036041924089982668927408"), + MontFp!("26539036560049644226325955326897543293209186693744007832956716526296961016679"), + MontFp!("21293980796799284500206310917912072462646541537689343050634953988042756230310"), + MontFp!("15493361534136156769634225679026880395421717943310991014470358275166642758227"), + MontFp!("13355191475187601116963788236610304969042623061004946819829836418820386555629"), + MontFp!("14278150947383305270936079047741054236624370230054254428896044837695297295248"), + MontFp!("8625865387924382292239818326201215552820960862222795025494731460985981227235"), + MontFp!("3014679029160738885585296713310546986657486536812970548778188092409099346680"), + MontFp!("2015141542057872387587816111950570203193810322999130112882639925855762799366"), + MontFp!("1804109903428180532744509564902915419086110610386928254034162756387077119500"), + MontFp!("23699325072273219534550925404212771724286521572841021233036603852069077316228"), + MontFp!("6853027115982749770120516172148489490662920805861343400362156085313821117341"), + MontFp!("17042736312639288600759976134427790474117301029744535771575741595956675709920"), + MontFp!("22369178137336275148086426490523570067348929716414801620781504457178436409543"), + MontFp!("17615353262218436961971529010917771102071096548299043636707515250329622845631"), + MontFp!("19308541151855670836307145857281177870331058995732035321919420908738867911324"), + MontFp!("17852015073984035096778820639608195284256146727033949798572438278737157464268"), + MontFp!("20308529279112027566474319377353686344218236751365227129851453233019416519966"), + MontFp!("22692189399740054086881577933355024222893630471552327885770434066228385839140"), + MontFp!("17656154953378808245374964121302916451110262675661118618370723021358296570903"), + MontFp!("25621147361225702356074055201494277589585246972645355448637071996054176791516"), + MontFp!("23042556046581593873700850057823079724842999799473544749172598457805462546048"), + MontFp!("16114018100024896683691907398231205607180899475941812105594458709222620712710"), + MontFp!("27484658207579629276465174180885999076674395722914847298722303595513617415616"), + MontFp!("27435264194841153592259179499053115659197049123015683948124097315377491801728"), + MontFp!("25792184843305572175398825240191708265559495832628760983015132179277919339081"), + MontFp!("17771029332106820818477196588580862715638921648813385244706073108866393652693"), + MontFp!("24872745773216990289700022718465567719493231909638701288832791827524654593211"), + MontFp!("9072618343076279816866050384563305602331787412261048350506299984898287515154"), + MontFp!("5755644280475904824641735942661162829320598040322014586734260245283807841137"), + MontFp!("18943920297707378315123194115473111114397308721726604837053891213559682564084"), + MontFp!("11845909029168101118387849634554412644772314384418342244940279700273879921611"), + MontFp!("28655676646760206340572547851369863064546460056573234292698793141422682287949"), + MontFp!("7558071623297774407110476563762568417066560314459575412555486129145965218192"), + MontFp!("9965633441444631637418516078927597924867863918995908536954789040927642724819"), + MontFp!("14440557756192256555015198365584137153551246454271048278110877441714442265645"), + MontFp!("8529604934482294191797189024282806527204175539993217691641491029079659695306"), + MontFp!("24123072984364656361756106545645438081347896246469255623856549974384882368956"), + MontFp!("611819890513402025911918740272909649748282133409659731212774178777255018009"), + MontFp!("13350319488916282562614679492988656177920714865243033713288330024963952530322"), + MontFp!("531195029232696186164440832375844971719135900632846679512921842625736148035"), + MontFp!("1001792683620530116317730114751932894909474816688396957900937364553907677134"), + MontFp!("20979666913698389297017687528615966195416669024009903175741554227978067105327"), + MontFp!("27948950472646435891252994894054338725928200931843053740348213911783699749290"), + MontFp!("22055172483315487174997524918135464794849776906182232776602507751746168651372"), + MontFp!("13066289628447568905451573584191517994288551567631388953779206137861433103357"), + MontFp!("1385285563873358488007758338060999843371222181257744322552564134768964759006"), + MontFp!("11917964305639538578143433957667622094851065438473191802972226430436958138863"), + MontFp!("590334814252503988621733906873069294246877754341946989832305221114340965843"), + MontFp!("8694578801729833474060225487448835607350604487811445702029132804551086561375"), + MontFp!("64472364953867007252421214014439452628925204213177378256439774156580264651"), + MontFp!("20874757857738836656619862025226003125191916300496894587642881067898110609763"), + MontFp!("6918017459227865792563011335263395281814237402080877013653144499537513222618"), + MontFp!("1869830605329426072384674215140021476006872666743402899698585433141561629228"), + MontFp!("20600580786541624530942459168903350154859207981106320530345371866600498711604"), + MontFp!("7628371805303803965461120422783515132694831204372225987559275969195152932170"), + MontFp!("6089956762625150275735648226889817136797108541116510427442658589854747593285"), + MontFp!("23077896922123723593381744717759219881115369688983556565099301362024574571983"), + MontFp!("21848617155768501631428337970990362339546905196891875604497525330088213930473"), + MontFp!("25741334215268416884772315416388584878625247287976905818870018183237951923686"), + MontFp!("21103391319276662741647084747129405475000281526706803415228020517133878569350"), + MontFp!("27395064281463888191997228201189074927859839511300824538817707109760023889359"), + MontFp!("22787274744688430941354128544581102863483686333264844871822223284774316447165"), + MontFp!("8564023937847999230753090748613687962477117543637871699158597825682967108853"), + MontFp!("9575299431064924705817971908270802965723051612164544462640178330142578093793"), + MontFp!("13471993477320055445030738714324509956280118993157306913413021416586821429001"), + MontFp!("10806878258641761010662410034227792046718642811354703630248631064673697939636"), + MontFp!("13726514647698542634816968540584445153241969696203464806633475583903362207594"), + MontFp!("20787559988694377365090154402645892380921814091599383028344272547375852022286"), + MontFp!("27418489962581634008145633582497467210715620661374319659191206198275894665793"), + MontFp!("1461567723371803002431031412358360720916490053096275008106159090213916939851"), + MontFp!("24446328186279846183031596779021197136177078901780287489031214234787239050650"), + MontFp!("21627439024699211598407119552641649384692327728340129412413862822096596581597"), + MontFp!("23533352699175137571894129663505174799528097572051558837098821277235598160477"), + MontFp!("10369408860312117981273761573482635768188162438213560513449447447786893408735"), + MontFp!("19307462657664767133643843119544958948399658959114819167086221797145950754883"), + MontFp!("16517361329429894284529546440274843659778802331498279645572110054700333515926"), + MontFp!("24337520090290309218705972394652732407148908446085570940558443036183841302080"), + MontFp!("18674056588741452335157737676252960384435182209175293127004076139900473480456"), + MontFp!("8310414681483334368287604679006031253893783287091613627135362270667546430552"), + MontFp!("15412688018657573742812481687838811964062596464409532921309658462058718939585"), + MontFp!("3703495609198165238197943732333284018507247476944274977398878916869859606091"), + MontFp!("5885645846915015321268480471282682776718241215881947628750002640933600299922"), + MontFp!("14761687965058487776774113773410040695627182263368822292974780800800414430631"), + MontFp!("7885140915503727039139858318717615630496538738751496836969174472041812810653"), + MontFp!("11474306243815928058249514408721130164760800811782068378880836393018736661680"), + MontFp!("14570320758488592761846038302112894138173084034884696084764485647239623457325"), + MontFp!("17714823289450106374273291536448092055300711014652142251060268780048541868292"), + MontFp!("10506790724242652266015831592379561746786716376435036557224940010456015168897"), + MontFp!("7655565387398129395698987339089887424138292528345663614527047152030192934620"), + MontFp!("3227070655085938517405457182884154862786142586698633024377446901350578957581"), + MontFp!("6479203932071401622955050190087015799026438839863522204616184381493124730383"), + MontFp!("24120592457971109909928031159725049470391977694719134868882338383851184998467"), + MontFp!("19907550176792778104040550747548270887414244535564502304722868638625789031071"), + MontFp!("15637324515384360411572934434667469853104730794934621413284317755356806721187"), + MontFp!("11468882434904807955743069761644357053913218350211893720139967787000359388478"), + MontFp!("10012330928230408704918328836215386884759588935850084183765994404155032937058"), + MontFp!("26924175309339894529619874615279727278601293952109429756124227850130833035588"), + MontFp!("2109974328359905219802450794741096452766416676872704458584265123840267062350"), + MontFp!("6560479261898654979289403268335045324196418334074928848131160435914973715141"), + MontFp!("1202607689901746424751014186078310457944517845434855076825180114471977113443"), + MontFp!("12273924640400923918872424212178128979745148162288332260699534270254532864277"), + MontFp!("4890410063882751397816628864685956596891462624200773022428555764926871055665"), + MontFp!("6488332735526981605733425974477476717816345205355292718156681681280329836002"), + MontFp!("27985900653592139062248152398691431934557879712491426532224835314503907411155"), + MontFp!("14275582251691651411991074469794525773309210748294805098833884437465103957304"), + MontFp!("22783432640236320710691436752539817035496099043418700740692797504709728268021"), + MontFp!("18164055675907082235738423489360470114102058171700041345925549109109715711185"), + MontFp!("12819759885408818385898341793987148691041919566686907954815601413209670457857"), + MontFp!("4581659802222331355517889180235340517967778076590829826269456701402683614699"), + MontFp!("28139020473157017215997147803224594851568231755964263512834692737272765557596"), + MontFp!("4945541743612201351663252872636828703685075560560938873687383391036573370423"), +]; + +const G3: &[Fr] = &[ + MontFp!("1"), + MontFp!("4752082627567591492616531505088555851849790050702598907433266709543862595952"), + MontFp!("4867128723518192607816771421235245851793570716687419434502469644371358085568"), + MontFp!("9372952954832826632533814286649940389485949554849071640355201857635052355981"), + MontFp!("25961116482043150460867137388278539457567790903019167062834835943706184420729"), + MontFp!("9006952071340857095704990254640236177092767966452295961669401044649381190650"), + MontFp!("18905820416106754749396230394192459606055613625664031703312288230879784985388"), + MontFp!("12568495413203922916879182704163418582422447021678569462909239121903912616100"), + MontFp!("27501409206494711691355527580883116883093225617019546582005012710742353445868"), + MontFp!("11131289866424844467264272909418932314818454258975340898485022087530688586595"), + MontFp!("24132251486970315768351840787891211448361152969743581628672061737213278940426"), + MontFp!("7021674726157371418887163583232590999030095944618797255808452397421238015722"), + MontFp!("23188773718882707986726067583825152932253058015917634433285986905601944667644"), + MontFp!("12824667989037596154897005652966097162583731581798152876294550724866987086633"), + MontFp!("24698294087689380905413301433645638822512249225335496287801248502888936034135"), + MontFp!("16550920975626445064366249801900823535005158066845477705365928056222401991853"), + MontFp!("11481482255349729633518114981653122293104571379370059034730689000824048736923"), + MontFp!("7516573378485835257941354315886728627455368982010725099205025135253188069829"), + MontFp!("27670727337226848938852999164261348837849110621634482144168465321883600043762"), + MontFp!("27974150841073621333137809309123223908245836242623565230240944332626569553180"), + MontFp!("26498665526009565504680916883126095651425929774897930294313347476415614173773"), + MontFp!("16591945418947374759906371857814779828681089970928766948929609907258881930137"), + MontFp!("26208590080110806171545948359725558958427738004967954581162919223591356193193"), + MontFp!("1371624191613284532329667378237039477069822325933546031932051305406839866890"), + MontFp!("26148046779140453558331511348347369066283963079853252061593579028948399205697"), + MontFp!("28061374430263720165478626584239365093598337541170434205192580889772956163773"), + MontFp!("15612808196781090073387187105676892200012191603324142444864498977545815390130"), + MontFp!("9410790558699568842819184002062690070110661738926751417887859786607733561857"), + MontFp!("28082048700136849660884969840230864013751141737597151800199664150168165916819"), + MontFp!("17243075234029471668693261957301206769908791350945273930030305129331602659798"), + MontFp!("13613328436532380881461572365432151302275695473356385249845760230344591614623"), + MontFp!("21861557858999932676402960252518422282616746751096087810343201713921944382468"), + MontFp!("26389178552394651245246837090492411671330744266237564696174733440959711379620"), + MontFp!("3062819507026297739338378252654007578382982108034866079115456942241669759490"), + MontFp!("23114842963047486452573854519050013120964388062743522283257853092692279933324"), + MontFp!("19300591736506035700890103524069966544138563614442053655922719437336584114944"), + MontFp!("23975262707097072261755240054622756971405456217690968012365681105551026309576"), + MontFp!("9625576302248692092609566938867255808992637108013810130768292972399134797893"), + MontFp!("6698776759143980709127005280355312562687280772330703051377500708948590756057"), + MontFp!("6971489102697523924316083338816896860108796246728195637337418472308579231809"), + MontFp!("312810427971157527095078834851326616217733624637582415126618485160226302819"), + MontFp!("27035164554321823059206369767155148581018686281916332747061414873093234632280"), + MontFp!("9488514599859395626973015526211465401157676295974443096864885157397922097273"), + MontFp!("20649527319449213622121685783749464678777847476349132265325453123684375686431"), + MontFp!("17446008661797338256647773030992335683119160097188709837185308351716369620626"), + MontFp!("12335304744444807954640134612335857983909918898151425830903145644486253800460"), + MontFp!("16701978979270916519028243406200969177506167463962697352028512076443719798426"), + MontFp!("15238809197564493860483400844684190738065238889165576525951195941989187216742"), + MontFp!("19366951025174438143523342051730202536500593522667444600037456491292628123146"), + MontFp!("26516158385939800902781420459922463250659294900249640511814630072206912433581"), + MontFp!("10117338598017857528225254377343902088225422302995344413627601130385510541534"), + MontFp!("20406162866908888653425069393176433404558180282626759233524330349859168426307"), + MontFp!("13001415536424045190982850150917256739036297695647806636178571356295185308613"), + MontFp!("23279406097796033973278576913165343422196943322642493262727615842740047050775"), + MontFp!("4589322241807849370985426537851237816643296028528905921275505081495296571404"), + MontFp!("1850255065896862597570685844309461307305326614293093648919652430376173070952"), + MontFp!("2075893226741026260742404419909093844729781417207167274898647849230073888515"), + MontFp!("2918864160332863876219027325668804712761324387470245818089915112714909320292"), + MontFp!("8191036522026386528457825006267613308971462757598627457744456630822729241069"), + MontFp!("25843923719602532887607370776376127633384401455212406431069351552900278098865"), + MontFp!("23732832178096749527339051359203764278284877955277525515678857563330709416426"), + MontFp!("8824020262456918957308272624413911920413264573899987435720954223778887989068"), + MontFp!("17276292741785279265151711948118674368796329754382075377630315926528905218916"), + MontFp!("21986653108763006540267036525617228016683400059944146544103329210113390621951"), + MontFp!("24682508875525884897641270952488416149830453149035712389703207095981135804695"), + MontFp!("24583698698095335441026800851772390188131321541266391576604330301364254319012"), + MontFp!("8290517863954231725773065804995791358696980123246663980451844081279149974274"), + MontFp!("1713123319377825411583782286509602689935449801972997199085517858020641609093"), + MontFp!("7238437022492246062624530126048974738121657510965057789866135595249560591141"), + MontFp!("23457337658314847499060862173460204447202088726417003854260301270538599300080"), + MontFp!("7185430721381105374506152435712892779547184246545171389621259635065578987677"), + MontFp!("10447797857873013823520846472883529596964052901769293866642943662942924394843"), + MontFp!("14142632382396362861749408490781569038771276212902001775337252613132120841952"), + MontFp!("10119252401865791282499126403396803642834150509873971983143760761859319347782"), + MontFp!("14619571402913868484028990866201259828808718041482856196853059836363207395290"), + MontFp!("12957579527045787791529254828906556950780884805545109574356059520478315400357"), + MontFp!("3720610574422079025890859090329826078637513377508736054788757034911920217424"), + MontFp!("22348496500077121761815884033104288658069486960409687698535739441316187146411"), + MontFp!("4010142134229457729810796499048092375382104942327917024525978169149911948726"), + MontFp!("26622111131377730171012121803896909492448092430869218025291634042991127898566"), + MontFp!("13803942648357170028780649679183673168585732045000043587712121170790388377178"), + MontFp!("16247125783183009813143057774712089284936971070772928494328524139646535167272"), + MontFp!("24400096089448761669694558697226561108493739853202092738379679016996309081299"), + MontFp!("16758410276743181024692019569005700125908639551402573929772398805820119894020"), + MontFp!("7261390444258021210379124932433745457138260463003656311102917416895313198245"), + MontFp!("16028766843198350742509614418731909110041917541853535656605020781351810627513"), + MontFp!("13645148443898549148810953158871792249108563689886096991684319186764798090404"), + MontFp!("14005328322807320755099702001682297598577128384412956652741983464767671665824"), + MontFp!("24686403341594955054270995782711035935712615263395767822138081001279319529399"), + MontFp!("25635996527549419906623902259254266892654761552454612383857607581576193235272"), + MontFp!("27335032098879799253261979951449445392804885034256459110362492254958718893004"), + MontFp!("20623388298615270385692519498831209905477995613005807768093009621882665730806"), + MontFp!("4053654159642339034214130061575326662580700632106663710039071654948181974938"), + MontFp!("6651832178791503370343273580837925927205033073752399955530037696021439501889"), + MontFp!("2412105391381560560113634895911606574494748781413357477134942737632942447582"), + MontFp!("12999494815468863052005581271236476599697805722742661638167184679067844708993"), + MontFp!("4855188899445002300170730717563617051094175372704778513906105166874447905568"), + MontFp!("3569590651280218823093221321238764199222447129583898159234697034334265127990"), + MontFp!("3414811574091837165023663512520193968982632555766929692024305066893819823262"), + MontFp!("12455442903192927588317506718060523994480132045945572221585649657032895945112"), + MontFp!("27186562367422895357569963486876394268047922290194064321991928649379561495570"), + MontFp!("1473830868613023132439325626972941502380512679146301624616716408155254515563"), + MontFp!("24118114923975171970075748640221677083961848771131734379542430306560974812756"), + MontFp!("16204937521178630728277472875781337901659359461555501082527267093139180282018"), + MontFp!("3088194831311024929819249596666706311463695096252554022102332351507152600272"), + MontFp!("16674176030373922194018114609462972046063328781049185723041117402205498120122"), + MontFp!("16730699677359874541477272839673617512091575213990646510488352939792525566391"), + MontFp!("1828371098204383752746643262995781269687022991505674089141878269408912142521"), + MontFp!("10266767850789221218645686420260291412843717713177640347217184376296669561832"), + MontFp!("1155851761097816184997931791723359103692747583104957635841370970199311029358"), + MontFp!("2569609454352884505578401923772873487474446720289931510130569242328843098369"), + MontFp!("13414155898667986265733671072571241554039054723344385380927838202574625415204"), + MontFp!("7647462460044754377138012042832421639600278595043442379234736860226630831964"), + MontFp!("27459704580255879011432352184835358806513916341384046373228120058012587920640"), + MontFp!("9990923935064443053465456629605733462391663956776145989196157863036796873426"), + MontFp!("16239465864838880137347078549360457412590409415497548657532714627111819534766"), + MontFp!("7380490886133355160591548990727230763465580646819083424899444657100084863426"), + MontFp!("7034914658176390703182990368846743979189794789573846247283001936919051256308"), + MontFp!("8587502848924294420923578668636664211036207334187738380728484406835053281550"), + MontFp!("19963879351468217396370901172020495274879472954985822963664787889744602927681"), + MontFp!("21384539133249249107138887349263191638217044791325676289498855084047389450605"), + MontFp!("15018590291850510627192640359885289524712449297935868047649425389088651636530"), + MontFp!("19353544777461715556833541863638307084839564667561199913766376168056657470133"), + MontFp!("10124259251452253852719268669491275694909689813541671655301271663125110708774"), + MontFp!("20526753443159731193465022353577443532622398196152316041739825890013503895382"), + MontFp!("1499473651834760471729151840235999810520017893609497145137716998525683633022"), + MontFp!("5846280402787891511993341239156351246524448328154063789980410896674908703994"), + MontFp!("26655885220255097234061501588939112229047519634006213327849029764296032457872"), + MontFp!("28948022309329048855892746252171976963363056481941647379679742748393362948096"), +]; + +const INV: &[u8] = &[ + 0, 0, 60, 203, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 167, 0, 0, 243, 0, 0, 0, 0, 0, 146, 0, 0, 113, 17, + 182, 0, 0, 0, 0, 0, 0, 0, 0, 0, 202, 179, 0, 0, 100, 0, 151, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 31, 0, 0, 0, 0, 0, 0, 72, 0, 0, 0, 0, 2, 0, 0, 0, 127, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 9, 186, 0, 0, 0, 0, 0, 0, 0, 185, 244, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 234, 0, 0, + 180, 97, 142, 0, 0, 0, 0, 0, 0, 0, 0, 47, 195, 0, 0, 0, 147, 0, 0, 0, 0, 0, 0, 0, 0, 0, 89, 0, + 0, 0, 227, 0, 211, 0, 143, 7, 0, 50, 91, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 93, 0, 0, 0, 49, 0, 232, + 0, 213, 0, 0, 21, 242, 0, 0, 0, 0, 0, 0, 0, 0, 0, 121, 208, 28, 0, 0, 0, 0, 0, 25, 0, 0, 0, 34, + 212, 0, 154, 0, 0, 0, 0, 73, 65, 0, 0, 0, 0, 0, 0, 0, 245, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 118, 0, 0, 0, 0, 0, 0, 0, 150, 0, 0, 40, 0, 0, 0, 0, 0, 0, 0, 0, 32, 0, 16, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 176, 0, 0, 197, 0, 253, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 181, 209, 0, 206, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 172, 0, 0, 164, 0, 0, 0, 166, 0, 0, 0, 0, 0, 33, 0, 0, + 0, 0, 0, 230, 0, 0, 94, 0, 0, 152, 0, 0, 0, 0, 0, 0, 231, 0, 0, 0, 0, 0, 216, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 98, 0, 0, 29, 0, 0, 0, 163, 0, 0, 0, 229, 158, 0, 0, 0, 0, 0, 0, 214, 0, 68, 0, 0, + 0, 0, 0, 0, 0, 0, 64, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 4, 0, 0, 0, 0, 0, 161, 0, + 59, 0, 0, 0, 0, 0, 155, 0, 0, 0, 0, 0, 0, 0, 0, 224, 0, 238, 174, 0, 0, 0, 10, 0, 0, 233, 0, + 79, 0, 0, 218, 108, 120, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 247, 0, 239, 0, 0, 111, 0, 119, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 248, 236, 90, 0, 0, 207, 0, 105, 0, 0, 138, 0, 0, 0, 46, + 110, 0, 96, 0, 0, 0, 0, 0, 0, 0, 0, 27, 0, 0, 0, 0, 0, 187, 0, 0, 0, 0, 0, 0, 0, 132, 0, 0, + 134, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 192, 0, 0, 0, 0, 128, 0, 0, 0, 196, 0, 86, 0, 0, 0, + 0, 0, 0, 30, 0, 0, 0, 0, 0, 0, 0, 0, 157, 0, 0, 226, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 88, 0, 0, 0, + 0, 0, 103, 0, 0, 0, 0, 0, 0, 24, 0, 0, 222, 0, 0, 102, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 38, 0, + 0, 0, 36, 0, 0, 44, 0, 0, 0, 0, 0, 0, 0, 35, 0, 0, 0, 0, 0, 0, 0, 0, 78, 0, 81, 53, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 125, 0, 69, 0, 0, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 144, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 168, 0, 0, 22, 0, 0, 0, 0, 0, 0, 0, 246, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 117, + 0, 0, 0, 0, 0, 0, 0, 193, 201, 0, 0, 0, 0, 26, 0, 84, 162, 0, 0, 0, 153, 0, 0, 0, 0, 0, 156, + 80, 249, 0, 160, 0, 0, 0, 0, 0, 0, 0, 114, 149, 0, 0, 85, 0, 0, 0, 177, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 219, 178, 0, 135, 0, 0, 83, 0, 99, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, + 0, 0, 0, 67, 175, 0, 0, 0, 0, 0, 0, 0, 0, 14, 225, 52, 0, 0, 106, 0, 0, 0, 0, 0, 104, 0, 0, 0, + 0, 0, 0, 116, 57, 0, 0, 0, 0, 0, 0, 0, 58, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 217, 210, 0, + 255, 0, 0, 0, 130, 0, 0, 0, 0, 200, 0, 0, 0, 0, 0, 0, 159, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 23, 0, 228, 0, 0, 51, 74, 0, 0, 0, 0, 0, 0, 0, 0, 0, 54, 145, 241, 0, 137, 0, 0, 0, 0, 0, 0, + 115, 0, 0, 39, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 75, 188, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 124, 0, 251, 95, 0, 0, 0, 0, 0, 0, 0, 20, 0, 0, 8, 0, 141, 0, 0, 92, 0, 0, 0, 12, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 199, 0, 0, 0, 170, 0, 0, 0, 237, 5, 0, 0, 194, 0, 0, 0, 61, 0, 0, + 0, 0, 0, 0, 0, 139, 0, 0, 0, 70, 0, 0, 0, 0, 0, 0, 37, 0, 0, 0, 0, 129, 0, 0, 0, 0, 0, 190, 0, + 0, 0, 0, 0, 169, 87, 0, 0, 0, 0, 0, 0, 77, 0, 0, 63, 0, 240, 0, 0, 0, 126, 0, 0, 131, 0, 0, 0, + 250, 0, 0, 0, 173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 56, 183, 0, 101, 0, 0, 0, 0, 235, 43, 204, 76, + 171, 107, 0, 221, 0, 0, 0, 0, 55, 0, 0, 0, 0, 0, 0, 0, 0, 0, 15, 0, 45, 0, 0, 0, 122, 0, 0, 0, + 3, 0, 0, 0, 0, 0, 0, 112, 0, 191, 0, 0, 205, 0, 0, 0, 0, 0, 0, 215, 0, 0, 0, 0, 0, 0, 62, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 0, 165, 0, 0, 0, 0, 0, 0, 198, 184, 0, 0, 11, 0, 0, 0, 0, 0, 0, 0, 189, 0, + 0, 0, 66, 0, 0, 133, 109, 0, 0, 254, 42, 0, 0, 0, 71, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 41, 140, + 0, 0, 0, 220, 0, 0, 13, 0, 136, 0, 0, 148, 0, 0, 0, 0, 0, 0, 0, 223, 123, 0, 252, 0, 0, 0, 0, + 0, 0, 18, 0, 0, 0, 0, 0, 0, 0, +]; diff --git a/curves/pallas/src/fields/mod.rs b/curves/pallas/src/fields/mod.rs index 00906f279..f1b1a5abe 100644 --- a/curves/pallas/src/fields/mod.rs +++ b/curves/pallas/src/fields/mod.rs @@ -2,11 +2,15 @@ pub mod fq; #[cfg(feature = "base_field")] pub use self::fq::*; +#[cfg(feature = "base_field")] +mod fq_sqrt_table; #[cfg(feature = "scalar_field")] pub mod fr; #[cfg(feature = "scalar_field")] pub use self::fr::*; +#[cfg(feature = "scalar_field")] +mod fr_sqrt_table; #[cfg(all(feature = "curve", test))] mod tests; diff --git a/curves/pallas/tests/gen_sqrt_tables.rs b/curves/pallas/tests/gen_sqrt_tables.rs new file mode 100644 index 000000000..57f1e8e82 --- /dev/null +++ b/curves/pallas/tests/gen_sqrt_tables.rs @@ -0,0 +1,191 @@ +//! One-off generator for the Sarkar (2020) square-root tables used by +//! `ark_ff::SqrtPrecomputation::Sarkar2020` for the Pasta fields. +//! +//! The table-building logic here is adapted from `SqrtTables::new` in +//! `zcash/pasta_curves`: +//! +//! It produces the same tables that pasta builds lazily at runtime, but emits +//! them as `const` source so the runtime has no allocation/initialization cost +//! +//! Run with: +//! ```text +//! cargo test -p ark-pallas --test gen_sqrt_tables -- --ignored --nocapture +//! ``` +//! +//! It writes two generated modules: +//! - `curves/pallas/src/fields/fq_sqrt_table.rs` (p field) +//! - `curves/pallas/src/fields/fr_sqrt_table.rs` (q field) +//! +//! `ark_pallas::Fq` is the Pallas base field (p); `ark_pallas::Fr` is the +//! Pallas scalar field (q). Vesta reuses Pallas's `FqConfig`/`FrConfig` +//! (`ark_vesta::Fq == ark_pallas::Fr`, `ark_vesta::Fr == ark_pallas::Fq`). + +use ark_ff::{FftField, PrimeField}; +use std::fmt::Write as _; +use std::fs; +use std::path::PathBuf; + +/// Perfect-hash parameters taken verbatim from `zcash/pasta_curves` — the +/// `lazy_static! { FP_TABLES / FQ_TABLES }` definitions in `src/fields/fp.rs` +/// and `src/fields/fq.rs` — where they are originally produced by the +/// `squareroottab.sage` in the `zcash/pasta` repo: +/// - +/// - +/// +/// They are valid because arkworks' `TWO_ADIC_ROOT_OF_UNITY` equals pasta's +/// `ROOT_OF_UNITY` (both = `GENERATOR^T` with `GENERATOR = 5`). We do NOT +/// re-run the sage search; instead `build` below asserts the resulting hash is +/// collision-free over all 256 subgroup elements, so a wrong value would panic +/// rather than emit a broken table. +const P_FIELD_HASH: (u32, u32) = (0x11BE, 1098); // pasta Fp = Pallas base = ark Pallas Fq +const Q_FIELD_HASH: (u32, u32) = (0x116A9E, 1206); // pasta Fq = Vesta base = ark Pallas Fr + +struct Dataset { + g0: Vec, + g1: Vec, + g2: Vec, + g3: Vec, // length 129 + inv: Vec, + trace: Vec, // (T-1)/2 little-endian limbs + hash_xor: u32, + hash_mod: u32, +} + +fn build(hash_xor: u32, hash_mod: u32) -> Dataset { + assert_eq!( + F::TWO_ADICITY, + 32, + "the Sarkar2020 variant splits S into four 8-bit windows and assumes S == 32" + ); + + // Follows from `zcash/pasta_curves`'s `SqrtTables` + let g = F::TWO_ADIC_ROOT_OF_UNITY; + let row = |base: F, n: usize| -> Vec { + let mut v = Vec::with_capacity(n); + let mut acc = F::ONE; + for _ in 0..n { + v.push(acc); + acc *= base; + } + v + }; + + // g0[i] = g^i, g1[i] = g^(2^8 i), g2[i] = g^(2^16 i), g3full[i] = g^(2^24 i). + let g0 = row(g, 256); + let g_8 = g0[255] * g; // g^(2^8) + let g1 = row(g_8, 256); + let g_16 = g1[255] * g_8; // g^(2^16) + let g2 = row(g_16, 256); + let g_24 = g2[255] * g_16; // g^(2^24) + let g3full = row(g_24, 256); + + let low32 = |x: &F| -> usize { (x.into_bigint().as_ref()[0] as u32) as usize }; + let hash = |x: &F| -> usize { (low32(x) ^ (hash_xor as usize)) % (hash_mod as usize) }; + + // inv maps g^(2^24 j) -> (256 - j) & 0xFF over the order-256 subgroup. + let mut inv = vec![0u8; hash_mod as usize]; + let mut used = vec![false; hash_mod as usize]; + for j in 0..256usize { + let h = hash(&g3full[j]); + assert!( + !used[h], + "perfect-hash collision at j={j}: params (xor={hash_xor:#x}, mod={hash_mod}) are \ + not valid for this field's ROOT_OF_UNITY" + ); + used[h] = true; + inv[h] = ((256 - j) & 0xFF) as u8; + } + + let dec = |v: &[F]| { + v.iter() + .map(|e| e.into_bigint().to_string()) + .collect::>() + }; + let trace = F::TRACE_MINUS_ONE_DIV_TWO.as_ref().to_vec(); + + Dataset { + g0: dec(&g0), + g1: dec(&g1), + g2: dec(&g2), + g3: dec(&g3full[..129]), + inv, + trace, + hash_xor, + hash_mod, + } +} + +fn emit(type_name: &str, d: &Dataset) -> String { + let mont_array = |name: &str, vals: &[String]| -> String { + let mut s = String::new(); + write!(s, "const {name}: &[{type_name}] = &[\n").unwrap(); + for v in vals { + write!(s, " MontFp!(\"{v}\"),\n").unwrap(); + } + s.push_str("];\n\n"); + s + }; + + let mut out = String::new(); + out.push_str( + "// @generated by `cargo test -p ark-pallas --test gen_sqrt_tables -- --ignored`.\n\ + // Sarkar (2020) square-root tables; see `ark_ff::SqrtPrecomputation::Sarkar2020`.\n\ + // Do not edit by hand.\n\ + #![allow(clippy::all)]\n\n\ + use ark_ff::{MontFp, SqrtPrecomputation};\n", + ); + write!(out, "use super::{type_name};\n\n").unwrap(); + + let trace = d + .trace + .iter() + .map(|l| format!("0x{l:016x}")) + .collect::>() + .join(", "); + write!( + out, + "pub(crate) const SQRT_PRECOMP: Option> =\n \ + Some(SqrtPrecomputation::Sarkar2020 {{\n \ + trace_minus_one_div_two: &[{trace}],\n \ + g0: G0,\n g1: G1,\n g2: G2,\n g3: G3,\n \ + inv: INV,\n hash_xor: {:#x},\n hash_mod: {},\n }});\n\n", + d.hash_xor, d.hash_mod + ) + .unwrap(); + + out.push_str(&mont_array("G0", &d.g0)); + out.push_str(&mont_array("G1", &d.g1)); + out.push_str(&mont_array("G2", &d.g2)); + out.push_str(&mont_array("G3", &d.g3)); + + out.push_str("const INV: &[u8] = &[\n"); + for chunk in d.inv.chunks(16) { + out.push_str(" "); + for b in chunk { + write!(out, "{b}, ").unwrap(); + } + out.push('\n'); + } + out.push_str("];\n"); + out +} + +#[test] +#[ignore = "regenerates committed source files; run explicitly"] +fn generate() { + // ark_pallas::Fq is the p field; ark_pallas::Fr is the q field. + let p = build::(P_FIELD_HASH.0, P_FIELD_HASH.1); + let q = build::(Q_FIELD_HASH.0, Q_FIELD_HASH.1); + + let pallas = PathBuf::from(env!("CARGO_MANIFEST_DIR")); + + let targets = [ + (pallas.join("src/fields/fq_sqrt_table.rs"), "Fq", &p), + (pallas.join("src/fields/fr_sqrt_table.rs"), "Fr", &q), + ]; + + for (path, ty, data) in targets { + fs::write(&path, emit(ty, data)).unwrap(); + println!("wrote {}", path.display()); + } +} diff --git a/curves/pallas/tests/sqrt_bench.rs b/curves/pallas/tests/sqrt_bench.rs new file mode 100644 index 000000000..bbdedb78f --- /dev/null +++ b/curves/pallas/tests/sqrt_bench.rs @@ -0,0 +1,56 @@ +//! Run with: +//! `cargo test --release --manifest-path curves/pallas/Cargo.toml --test sqrt_bench -- --ignored --nocapture` + +use ark_ff::{FftField, PrimeField, SqrtPrecomputation}; +use ark_std::test_rng; +use std::time::Instant; + +#[test] +#[ignore = "timing comparison; run explicitly with --release --nocapture"] +fn compare() { + bench::("Pallas Fq (p)"); + bench::("Pallas Fr (q)"); +} + +fn bench(name: &str) { + let rng = &mut test_rng(); + // Squares only, so both algorithms take the "found a root" path. + let inputs: Vec = (0..1000).map(|_| F::rand(rng).square()).collect(); + + // The installed precomputation (Sarkar2020 for these fields). + let sarkar_owned = F::SQRT_PRECOMP; + let sarkar = sarkar_owned.as_ref().expect("Sarkar precomp installed"); + + // A reference Tonelli-Shanks precomputation for the same field. + let trace: &'static [u64] = Box::leak( + F::TRACE_MINUS_ONE_DIV_TWO + .as_ref() + .to_vec() + .into_boxed_slice(), + ); + let ts: SqrtPrecomputation = SqrtPrecomputation::TonelliShanks { + two_adicity: F::TWO_ADICITY, + quadratic_nonresidue_to_trace: F::TWO_ADIC_ROOT_OF_UNITY, + trace_of_modulus_minus_one_div_two: trace, + }; + + let run = |p: &SqrtPrecomputation| { + let t = Instant::now(); + let mut acc = vec![]; + for x in &inputs { + acc.push(p.sqrt(x).unwrap()); + } + (t.elapsed(), acc) + }; + + let (ts_time, a1) = run(&ts); + let (sk_time, a2) = run(sarkar); + assert_eq!(a1, a2); + + println!( + "{name}: tonelli-shanks {:?}, sarkar {:?} ({:.2}x)", + ts_time, + sk_time, + ts_time.as_secs_f64() / sk_time.as_secs_f64() + ); +} diff --git a/curves/pallas/tests/sqrt_sarkar.rs b/curves/pallas/tests/sqrt_sarkar.rs new file mode 100644 index 000000000..2abd7c496 --- /dev/null +++ b/curves/pallas/tests/sqrt_sarkar.rs @@ -0,0 +1,47 @@ +use ark_ff::{Field, LegendreSymbol}; +use ark_std::test_rng; + +fn check() { + assert!(F::SQRT_PRECOMP.is_some()); + + let rng = &mut test_rng(); + + assert_eq!(F::ZERO.sqrt(), Some(F::ZERO)); + let one = F::ONE; + assert_eq!(one.sqrt().map(|r| r * r), Some(one)); + + let mut squares = 0u32; + let mut nonsquares = 0u32; + for _ in 0..3000 { + let x = F::rand(rng); + match x.legendre() { + LegendreSymbol::Zero => {}, + LegendreSymbol::QuadraticResidue => { + squares += 1; + let r = x + .sqrt() + .expect("a quadratic residue must have a square root"); + assert_eq!(r * r, x, "returned root does not square back to input"); + }, + LegendreSymbol::QuadraticNonResidue => { + nonsquares += 1; + assert!( + x.sqrt().is_none(), + "a quadratic non-residue must not yield a square root" + ); + }, + } + } + // Sanity that we actually exercised both branches. + assert!(squares > 0 && nonsquares > 0); +} + +#[test] +fn pallas_fq_p_field() { + check::(); +} + +#[test] +fn pallas_fr_q_field() { + check::(); +} diff --git a/ff-macros/src/lib.rs b/ff-macros/src/lib.rs index afe629a0c..563df3054 100644 --- a/ff-macros/src/lib.rs +++ b/ff-macros/src/lib.rs @@ -86,6 +86,7 @@ pub fn define_field(input: TokenStream) -> TokenStream { generator_big, small_subgroup_base, small_subgroup_power, + None, config_name.clone(), ); @@ -110,7 +111,13 @@ pub fn define_field(input: TokenStream) -> TokenStream { // This code was adapted from the `PrimeField` Derive Macro in ff-derive. #[proc_macro_derive( MontConfig, - attributes(modulus, generator, small_subgroup_base, small_subgroup_power) + attributes( + modulus, + generator, + small_subgroup_base, + small_subgroup_power, + sqrt_precomp + ) )] pub fn mont_config(input: proc_macro::TokenStream) -> proc_macro::TokenStream { // Parse the type definition @@ -135,11 +142,17 @@ pub fn mont_config(input: proc_macro::TokenStream) -> proc_macro::TokenStream { let small_subgroup_power: Option = fetch_attr("small_subgroup_power", &ast.attrs) .map(|s| s.parse().expect("small_subgroup_power should be a number")); + // Optional path to a `const SQRT_PRECOMP: Option>` that + // overrides the default (Tonelli-Shanks / Case3Mod4 / Case5Mod8) precomputation. + // Used to plug in a table-based square root for high-2-adicity fields. + let sqrt_precomp: Option = fetch_attr("sqrt_precomp", &ast.attrs); + montgomery::mont_config_helper( modulus, generator, small_subgroup_base, small_subgroup_power, + sqrt_precomp, ast.ident, ) .into() diff --git a/ff-macros/src/montgomery/mod.rs b/ff-macros/src/montgomery/mod.rs index f07facf0d..801d72599 100644 --- a/ff-macros/src/montgomery/mod.rs +++ b/ff-macros/src/montgomery/mod.rs @@ -26,6 +26,7 @@ pub(crate) fn mont_config_helper( generator: BigUint, small_subgroup_base: Option, small_subgroup_power: Option, + sqrt_precomp: Option, config_name: proc_macro2::Ident, ) -> proc_macro2::TokenStream { let mut limbs = 1usize; @@ -99,6 +100,17 @@ pub(crate) fn mont_config_helper( quote::quote! {} }; + let sqrt_precomp = if let Some(path) = sqrt_precomp { + let path: proc_macro2::TokenStream = path + .parse() + .expect("`sqrt_precomp` should be a path to a `const`"); + quote::quote! { + const SQRT_PRECOMP: Option> = #path; + } + } else { + quote::quote! {} + }; + quote::quote! { const _: () = { use ark_ff::{fields::Fp, BigInt, BigInteger, biginteger::arithmetic as fa, fields::*}; @@ -115,6 +127,8 @@ pub(crate) fn mont_config_helper( #mixed_radix + #sqrt_precomp + #[inline(always)] fn add_assign(a: &mut F, b: &F) { #add_assign diff --git a/ff/src/fields/sqrt.rs b/ff/src/fields/sqrt.rs index 839129132..4f874ead0 100644 --- a/ff/src/fields/sqrt.rs +++ b/ff/src/fields/sqrt.rs @@ -80,6 +80,36 @@ pub enum SqrtPrecomputation { modulus_plus_three_div_eight: &'static [u64], modulus_minus_one_div_four: &'static [u64], }, + /// Table-based square root for fields with high 2-adicity. + /// + /// Adapted from the `SqrtTables` implementation in `zcash/pasta_curves` + /// (the `sqrt_alt` / `sqrt_common` / `SqrtHasher::hash` functions), + /// It in turn implements Sarkar 2020 and BDLSY 2012: + /// - + /// - Sarkar 2020: + /// + /// Write `p - 1 = T * 2^S` with `T` odd, and let `g` be a generator of the + /// order-`2^S` subgroup (i.e. `TWO_ADIC_ROOT_OF_UNITY`). The tables are: + /// - `g0[i] = g^i`, `g1[i] = g^(2^8 * i)`, `g2[i] = g^(2^16 * i)` for + /// `i in 0..256`, and `g3[i] = g^(2^24 * i)` for `i in 0..129`. + /// - `inv` is a perfect-hash lookup of length `hash_mod` mapping an element + /// `g^(2^24 * j)` of the order-256 subgroup back to `(256 - j) & 0xFF`, + /// keyed by `((canonical_low_32_bits ^ hash_xor) % hash_mod)`. + /// + /// This variant is currently only constructed for fields with `S == 32` + /// (it splits `S` into four 8-bit windows). The tables and `hash_*` + /// parameters are produced by `curves/pallas/tests/gen_sqrt_tables.rs` + Sarkar2020 { + /// `(T - 1) / 2` in little-endian limbs. + trace_minus_one_div_two: &'static [u64], + g0: &'static [F], + g1: &'static [F], + g2: &'static [F], + g3: &'static [F], + inv: &'static [u8], + hash_xor: u32, + hash_mod: u32, + }, } impl SqrtPrecomputation { @@ -212,6 +242,80 @@ impl SqrtPrecomputation { (result.square() == *elem).then_some(result) }, + Self::Sarkar2020 { + trace_minus_one_div_two, + g0, + g1, + g2, + g3, + inv, + hash_xor, + hash_mod, + } => { + // Ported from `zcash/pasta_curves`, `SqrtTables::sqrt_alt` and + // `SqrtTables::sqrt_common` (plus `SqrtHasher::hash`): + // + if elem.is_zero() { + return Some(F::zero()); + } + + // Canonical low 32 bits of a prime-field element. This variant is + // only ever constructed for prime fields, so the (single) base + // prime field element is `x` itself. + let low32 = |x: &F| -> usize { + let c = x + .to_base_prime_field_elements() + .next() + .expect("a prime field element has exactly one base element"); + ::into_bigint(c).as_ref()[0] as u32 + as usize + }; + let inv_lookup = |x: &F| -> usize { + let h = (low32(x) ^ (*hash_xor as usize)) % (*hash_mod as usize); + inv[h] as usize + }; + let sqr = |mut x: F, i: u32| { + for _ in 0..i { + x.square_in_place(); + } + x + }; + + // v = elem^((T-1)/2), uv = elem * v. This single exponentiation is + // the dominant cost and is shared with Tonelli-Shanks; the rest of + // the algorithm replaces the data-dependent discrete-log search + // with four windowed table lookups. + let v = elem.pow(trace_minus_one_div_two); + let uv = *elem * v; + + // Project `uv * v` (which lies in the order-2^32 subgroup) down to + // the order-256 subgroup by successive 8-bit squarings, then peel + // off the discrete log one 8-bit window at a time using `inv`/`g*`. + let x3 = uv * v; + let x2 = sqr(x3, 8); + let x1 = sqr(x2, 8); + let x0 = sqr(x1, 8); + + let mut t = inv_lookup(&x0); + let alpha = x1 * g2[t]; + + t += inv_lookup(&alpha) << 8; + let alpha = x2 * g1[t & 0xFF] * g2[t >> 8]; + + t += inv_lookup(&alpha) << 16; + let alpha = x3 * g0[t & 0xFF] * g1[(t >> 8) & 0xFF] * g2[t >> 16]; + + t += inv_lookup(&alpha) << 24; + t = (((t as u64) + 1) >> 1) as usize; + assert!(t <= 0x80000000); + + let res = + uv * g0[t & 0xFF] * g1[(t >> 8) & 0xFF] * g2[(t >> 16) & 0xFF] * g3[t >> 24]; + + // The algorithm returns the correct root iff `elem` is a square; + // otherwise the squared candidate disagrees, signalling no root. + (res.square() == *elem).then_some(res) + }, } } }