anemoi/jubjub/
sbox.rs

1use super::Felt;
2use super::MontFp;
3
4use ark_ff::Field;
5
6#[allow(unused)]
7/// Exponent of the Anemoi S-Box
8pub(crate) const ALPHA: u32 = 5;
9
10#[allow(unused)]
11/// Inverse exponent
12pub(crate) const INV_ALPHA: Felt =
13    MontFp!("20974350070050476191779096203274386335076221000211055129041463479975432473805");
14
15/// Multiplier of the Anemoi S-Box
16#[allow(unused)]
17pub(crate) const BETA: u32 = 7;
18
19/// First added constant of the Anemoi S-Box
20pub(crate) const DELTA: Felt =
21    MontFp!("14981678621464625851270783002338847382197300714436467949315331057125308909861");
22
23#[allow(unused)]
24/// Second added constant of the Anemoi S-Box
25pub(crate) const QUAD: u32 = 2;
26
27#[inline(always)]
28pub(crate) fn exp_by_inv_alpha(x: &Felt) -> Felt {
29    let t7 = x.square(); //        1: 2
30    let t0 = t7.square(); //       2: 4
31    let t2 = t0.square(); //       3: 8
32    let t10 = t2 * x; //           4: 9
33    let t3 = t10 * t7; //          5: 11
34    let t1 = t10 * t0; //          6: 13
35    let t5 = t3 * t0; //           7: 15
36    let t9 = t10 * t2; //          8: 17
37    let t4 = t3 * t2; //           9: 19
38    let t15 = t5 * t2; //         10: 23
39    let t8 = t15 * t2; //         11: 31
40    let t13 = t8 * t7; //         12: 33
41    let t14 = t8 * t0; //         13: 35
42    let t12 = t13 * t0; //        14: 37
43    let t6 = t8 * t2; //          15: 39
44    let t11 = t14 * t2; //        16: 43
45    let mut t0 = t15.square(); // 17: 46
46    let t18 = t6 * t2; //         18: 47
47    let t2 = t11 * t2; //         19: 51
48    let t16 = t2 * t7; //         20: 53
49    let t7 = t0 * t3; //          21: 57
50    let t17 = t0 * t5; //         22: 61
51    t0 = t0.square(); //          23: 92
52    t0 = t0.square(); //          24: 184
53    t0 = t0.square(); //          25: 368
54    t0 = t0.square(); //          26: 736
55    t0 = t0.square(); //          27: 1472
56    t0 = t0.square(); //          28: 2944
57    t0 = t0.square(); //          29: 5888
58    t0 *= t18; //                 30: 5935
59    t0 = t0.square(); //          31: 11870
60    t0 = t0.square(); //          32: 23740
61    t0 = t0.square(); //          33: 47480
62    t0 = t0.square(); //          34: 94960
63    t0 = t0.square(); //          35: 189920
64    t0 = t0.square(); //          36: 379840
65    t0 *= t13; //                 37: 379873
66    t0 = t0.square(); //          38: 759746
67    t0 = t0.square(); //          39: 1519492
68    t0 = t0.square(); //          40: 3038984
69    t0 = t0.square(); //          41: 6077968
70    t0 = t0.square(); //          42: 12155936
71    t0 = t0.square(); //          43: 24311872
72    t0 *= t17; //                 44: 24311933
73    t0 = t0.square(); //          45: 48623866
74    t0 = t0.square(); //          46: 97247732
75    t0 = t0.square(); //          47: 194495464
76    t0 = t0.square(); //          48: 388990928
77    t0 = t0.square(); //          49: 777981856
78    t0 = t0.square(); //          50: 1555963712
79    t0 *= t16; //                 51: 1555963765
80    t0 = t0.square(); //          52: 3111927530
81    t0 = t0.square(); //          53: 6223855060
82    t0 = t0.square(); //          54: 12447710120
83    t0 = t0.square(); //          55: 24895420240
84    t0 = t0.square(); //          56: 49790840480
85    t0 *= t15; //                 57: 49790840503
86    t0 = t0.square(); //          58: 99581681006
87    t0 = t0.square(); //          59: 199163362012
88    t0 = t0.square(); //          60: 398326724024
89    t0 = t0.square(); //          61: 796653448048
90    t0 = t0.square(); //          62: 1593306896096
91    t0 = t0.square(); //          63: 3186613792192
92    t0 *= t15; //                 64: 3186613792215
93    t0 = t0.square(); //          65: 6373227584430
94    t0 = t0.square(); //          66: 12746455168860
95    t0 = t0.square(); //          67: 25492910337720
96    t0 = t0.square(); //          68: 50985820675440
97    t0 = t0.square(); //          69: 101971641350880
98    t0 = t0.square(); //          70: 203943282701760
99    t0 = t0.square(); //          71: 407886565403520
100    t0 = t0.square(); //          72: 815773130807040
101    t0 *= t14; //                 73: 815773130807075
102    t0 = t0.square(); //          74: 1631546261614150
103    t0 = t0.square(); //          75: 3263092523228300
104    t0 = t0.square(); //          76: 6526185046456600
105    t0 = t0.square(); //          77: 13052370092913200
106    t0 = t0.square(); //          78: 26104740185826400
107    t0 = t0.square(); //          79: 52209480371652800
108    t0 = t0.square(); //          80: 104418960743305600
109    t0 = t0.square(); //          81: 208837921486611200
110    t0 *= t13; //                 82: 208837921486611233
111    t0 = t0.square(); //          83: 417675842973222466
112    t0 = t0.square(); //          84: 835351685946444932
113    t0 = t0.square(); //          85: 1670703371892889864
114    t0 = t0.square(); //          86: 3341406743785779728
115    t0 = t0.square(); //          87: 6682813487571559456
116    t0 = t0.square(); //          88: 13365626975143118912
117    t0 *= t2; //                  89: 13365626975143118963
118    t0 = t0.square(); //          90: 26731253950286237926
119    t0 = t0.square(); //          91: 53462507900572475852
120    t0 = t0.square(); //          92: 106925015801144951704
121    t0 = t0.square(); //          93: 213850031602289903408
122    t0 = t0.square(); //          94: 427700063204579806816
123    t0 = t0.square(); //          95: 855400126409159613632
124    t0 *= t13; //                 96: 855400126409159613665
125    t0 = t0.square(); //          97: 1710800252818319227330
126    t0 = t0.square(); //          98: 3421600505636638454660
127    t0 = t0.square(); //          99: 6843201011273276909320
128    t0 = t0.square(); //         100: 13686402022546553818640
129    t0 = t0.square(); //         101: 27372804045093107637280
130    t0 = t0.square(); //         102: 54745608090186215274560
131    t0 = t0.square(); //         103: 109491216180372430549120
132    t0 *= t12; //                104: 109491216180372430549157
133    t0 = t0.square(); //         105: 218982432360744861098314
134    t0 = t0.square(); //         106: 437964864721489722196628
135    t0 = t0.square(); //         107: 875929729442979444393256
136    t0 = t0.square(); //         108: 1751859458885958888786512
137    t0 = t0.square(); //         109: 3503718917771917777573024
138    t0 = t0.square(); //         110: 7007437835543835555146048
139    t0 = t0.square(); //         111: 14014875671087671110292096
140    t0 = t0.square(); //         112: 28029751342175342220584192
141    t0 *= t11; //                113: 28029751342175342220584235
142    t0 = t0.square(); //         114: 56059502684350684441168470
143    t0 = t0.square(); //         115: 112119005368701368882336940
144    t0 = t0.square(); //         116: 224238010737402737764673880
145    t0 = t0.square(); //         117: 448476021474805475529347760
146    t0 = t0.square(); //         118: 896952042949610951058695520
147    t0 = t0.square(); //         119: 1793904085899221902117391040
148    t0 *= t1; //                 120: 1793904085899221902117391053
149    t0 = t0.square(); //         121: 3587808171798443804234782106
150    t0 = t0.square(); //         122: 7175616343596887608469564212
151    t0 = t0.square(); //         123: 14351232687193775216939128424
152    t0 = t0.square(); //         124: 28702465374387550433878256848
153    t0 = t0.square(); //         125: 57404930748775100867756513696
154    t0 = t0.square(); //         126: 114809861497550201735513027392
155    t0 = t0.square(); //         127: 229619722995100403471026054784
156    t0 = t0.square(); //         128: 459239445990200806942052109568
157    t0 *= t2; //                 129: 459239445990200806942052109619
158    t0 = t0.square(); //         130: 918478891980401613884104219238
159    t0 = t0.square(); //         131: 1836957783960803227768208438476
160    t0 = t0.square(); //         132: 3673915567921606455536416876952
161    t0 = t0.square(); //         133: 7347831135843212911072833753904
162    t0 = t0.square(); //         134: 14695662271686425822145667507808
163    t0 = t0.square(); //         135: 29391324543372851644291335015616
164    t0 *= t11; //                136: 29391324543372851644291335015659
165    t0 = t0.square(); //         137: 58782649086745703288582670031318
166    t0 = t0.square(); //         138: 117565298173491406577165340062636
167    t0 = t0.square(); //         139: 235130596346982813154330680125272
168    t0 = t0.square(); //         140: 470261192693965626308661360250544
169    t0 *= t10; //                141: 470261192693965626308661360250553
170    t0 = t0.square(); //         142: 940522385387931252617322720501106
171    t0 = t0.square(); //         143: 1881044770775862505234645441002212
172    t0 = t0.square(); //         144: 3762089541551725010469290882004424
173    t0 = t0.square(); //         145: 7524179083103450020938581764008848
174    t0 = t0.square(); //         146: 15048358166206900041877163528017696
175    t0 *= t8; //                 147: 15048358166206900041877163528017727
176    t0 = t0.square(); //         148: 30096716332413800083754327056035454
177    t0 = t0.square(); //         149: 60193432664827600167508654112070908
178    t0 = t0.square(); //         150: 120386865329655200335017308224141816
179    t0 = t0.square(); //         151: 240773730659310400670034616448283632
180    t0 = t0.square(); //         152: 481547461318620801340069232896567264
181    t0 = t0.square(); //         153: 963094922637241602680138465793134528
182    t0 = t0.square(); //         154: 1926189845274483205360276931586269056
183    t0 = t0.square(); //         155: 3852379690548966410720553863172538112
184    t0 = t0.square(); //         156: 7704759381097932821441107726345076224
185    t0 = t0.square(); //         157: 15409518762195865642882215452690152448
186    t0 = t0.square(); //         158: 30819037524391731285764430905380304896
187    t0 = t0.square(); //         159: 61638075048783462571528861810760609792
188    t0 = t0.square(); //         160: 123276150097566925143057723621521219584
189    t0 = t0.square(); //         161: 246552300195133850286115447243042439168
190    t0 = t0.square(); //         162: 493104600390267700572230894486084878336
191    t0 *= t9; //                 163: 493104600390267700572230894486084878353
192    t0 = t0.square(); //         164: 986209200780535401144461788972169756706
193    t0 = t0.square(); //         165: 1972418401561070802288923577944339513412
194    t0 = t0.square(); //         166: 3944836803122141604577847155888679026824
195    t0 = t0.square(); //         167: 7889673606244283209155694311777358053648
196    t0 = t0.square(); //         168: 15779347212488566418311388623554716107296
197    t0 = t0.square(); //         169: 31558694424977132836622777247109432214592
198    t0 = t0.square(); //         170: 63117388849954265673245554494218864429184
199    t0 = t0.square(); //         171: 126234777699908531346491108988437728858368
200    t0 *= t3; //                 172: 126234777699908531346491108988437728858379
201    t0 = t0.square(); //         173: 252469555399817062692982217976875457716758
202    t0 = t0.square(); //         174: 504939110799634125385964435953750915433516
203    t0 = t0.square(); //         175: 1009878221599268250771928871907501830867032
204    t0 = t0.square(); //         176: 2019756443198536501543857743815003661734064
205    t0 = t0.square(); //         177: 4039512886397073003087715487630007323468128
206    t0 *= t8; //                 178: 4039512886397073003087715487630007323468159
207    t0 = t0.square(); //         179: 8079025772794146006175430975260014646936318
208    t0 = t0.square(); //         180: 16158051545588292012350861950520029293872636
209    t0 = t0.square(); //         181: 32316103091176584024701723901040058587745272
210    t0 = t0.square(); //         182: 64632206182353168049403447802080117175490544
211    t0 = t0.square(); //         183: 129264412364706336098806895604160234350981088
212    t0 = t0.square(); //         184: 258528824729412672197613791208320468701962176
213    t0 = t0.square(); //         185: 517057649458825344395227582416640937403924352
214    t0 = t0.square(); //         186: 1034115298917650688790455164833281874807848704
215    t0 = t0.square(); //         187: 2068230597835301377580910329666563749615697408
216    t0 = t0.square(); //         188: 4136461195670602755161820659333127499231394816
217    t0 *= t7; //                 189: 4136461195670602755161820659333127499231394873
218    t0 = t0.square(); //         190: 8272922391341205510323641318666254998462789746
219    t0 = t0.square(); //         191: 16545844782682411020647282637332509996925579492
220    t0 = t0.square(); //         192: 33091689565364822041294565274665019993851158984
221    t0 = t0.square(); //         193: 66183379130729644082589130549330039987702317968
222    t0 = t0.square(); //         194: 132366758261459288165178261098660079975404635936
223    t0 = t0.square(); //         195: 264733516522918576330356522197320159950809271872
224    t0 *= t6; //                 196: 264733516522918576330356522197320159950809271911
225    t0 = t0.square(); //         197: 529467033045837152660713044394640319901618543822
226    t0 = t0.square(); //         198: 1058934066091674305321426088789280639803237087644
227    t0 = t0.square(); //         199: 2117868132183348610642852177578561279606474175288
228    t0 = t0.square(); //         200: 4235736264366697221285704355157122559212948350576
229    t0 = t0.square(); //         201: 8471472528733394442571408710314245118425896701152
230    t0 *= t4; //                 202: 8471472528733394442571408710314245118425896701171
231    t0 = t0.square(); //         203: 16942945057466788885142817420628490236851793402342
232    t0 = t0.square(); //         204: 33885890114933577770285634841256980473703586804684
233    t0 = t0.square(); //         205: 67771780229867155540571269682513960947407173609368
234    t0 = t0.square(); //         206: 135543560459734311081142539365027921894814347218736
235    t0 = t0.square(); //         207: 271087120919468622162285078730055843789628694437472
236    t0 = t0.square(); //         208: 542174241838937244324570157460111687579257388874944
237    t0 = t0.square(); //         209: 1084348483677874488649140314920223375158514777749888
238    t0 = t0.square(); //         210: 2168696967355748977298280629840446750317029555499776
239    t0 *= t2; //                 211: 2168696967355748977298280629840446750317029555499827
240    t0 = t0.square(); //         212: 4337393934711497954596561259680893500634059110999654
241    t0 = t0.square(); //         213: 8674787869422995909193122519361787001268118221999308
242    t0 = t0.square(); //         214: 17349575738845991818386245038723574002536236443998616
243    t0 = t0.square(); //         215: 34699151477691983636772490077447148005072472887997232
244    t0 = t0.square(); //         216: 69398302955383967273544980154894296010144945775994464
245    t0 = t0.square(); //         217: 138796605910767934547089960309788592020289891551988928
246    t0 = t0.square(); //         218: 277593211821535869094179920619577184040579783103977856
247    t0 *= t5; //                 219: 277593211821535869094179920619577184040579783103977871
248    t0 = t0.square(); //         220: 555186423643071738188359841239154368081159566207955742
249    t0 = t0.square(); //         221: 1110372847286143476376719682478308736162319132415911484
250    t0 = t0.square(); //         222: 2220745694572286952753439364956617472324638264831822968
251    t0 = t0.square(); //         223: 4441491389144573905506878729913234944649276529663645936
252    t0 = t0.square(); //         224: 8882982778289147811013757459826469889298553059327291872
253    t0 = t0.square(); //         225: 17765965556578295622027514919652939778597106118654583744
254    t0 = t0.square(); //         226: 35531931113156591244055029839305879557194212237309167488
255    t0 = t0.square(); //         227: 71063862226313182488110059678611759114388424474618334976
256    t0 = t0.square(); //         228: 142127724452626364976220119357223518228776848949236669952
257    t0 *= t2; //                 229: 142127724452626364976220119357223518228776848949236670003
258    t0 = t0.square(); //         230: 284255448905252729952440238714447036457553697898473340006
259    t0 = t0.square(); //         231: 568510897810505459904880477428894072915107395796946680012
260    t0 = t0.square(); //         232: 1137021795621010919809760954857788145830214791593893360024
261    t0 = t0.square(); //         233: 2274043591242021839619521909715576291660429583187786720048
262    t0 = t0.square(); //         234: 4548087182484043679239043819431152583320859166375573440096
263    t0 = t0.square(); //         235: 9096174364968087358478087638862305166641718332751146880192
264    t0 = t0.square(); //         236: 18192348729936174716956175277724610333283436665502293760384
265    t0 *= t4; //                 237: 18192348729936174716956175277724610333283436665502293760403
266    t0 = t0.square(); //         238: 36384697459872349433912350555449220666566873331004587520806
267    t0 = t0.square(); //         239: 72769394919744698867824701110898441333133746662009175041612
268    t0 = t0.square(); //         240: 145538789839489397735649402221796882666267493324018350083224
269    t0 = t0.square(); //         241: 291077579678978795471298804443593765332534986648036700166448
270    t0 = t0.square(); //         242: 582155159357957590942597608887187530665069973296073400332896
271    t0 = t0.square(); //         243: 1164310318715915181885195217774375061330139946592146800665792
272    t0 = t0.square(); //         244: 2328620637431830363770390435548750122660279893184293601331584
273    t0 = t0.square(); //         245: 4657241274863660727540780871097500245320559786368587202663168
274    t0 *= t2; //                 246: 4657241274863660727540780871097500245320559786368587202663219
275    t0 = t0.square(); //         247: 9314482549727321455081561742195000490641119572737174405326438
276    t0 = t0.square(); //         248: 18628965099454642910163123484390000981282239145474348810652876
277    t0 = t0.square(); //         249: 37257930198909285820326246968780001962564478290948697621305752
278    t0 = t0.square(); //         250: 74515860397818571640652493937560003925128956581897395242611504
279    t0 = t0.square(); //         251: 149031720795637143281304987875120007850257913163794790485223008
280    t0 = t0.square(); //         252: 298063441591274286562609975750240015700515826327589580970446016
281    t0 = t0.square(); //         253: 596126883182548573125219951500480031401031652655179161940892032
282    t0 = t0.square(); //         254: 1192253766365097146250439903000960062802063305310358323881784064
283    t0 *= t2; //                 255: 1192253766365097146250439903000960062802063305310358323881784115
284    t0 = t0.square(); //         256: 2384507532730194292500879806001920125604126610620716647763568230
285    t0 = t0.square(); //         257: 4769015065460388585001759612003840251208253221241433295527136460
286    t0 = t0.square(); //         258: 9538030130920777170003519224007680502416506442482866591054272920
287    t0 = t0.square(); //         259: 19076060261841554340007038448015361004833012884965733182108545840
288    t0 = t0.square(); //         260: 38152120523683108680014076896030722009666025769931466364217091680
289    t0 = t0.square(); //         261: 76304241047366217360028153792061444019332051539862932728434183360
290    t0 = t0.square(); //         262: 152608482094732434720056307584122888038664103079725865456868366720
291    t0 = t0.square(); //         263: 305216964189464869440112615168245776077328206159451730913736733440
292    t0 *= t2; //                 264: 305216964189464869440112615168245776077328206159451730913736733491
293    t0 = t0.square(); //         265: 610433928378929738880225230336491552154656412318903461827473466982
294    t0 = t0.square(); //         266: 1220867856757859477760450460672983104309312824637806923654946933964
295    t0 = t0.square(); //         267: 2441735713515718955520900921345966208618625649275613847309893867928
296    t0 = t0.square(); //         268: 4883471427031437911041801842691932417237251298551227694619787735856
297    t0 = t0.square(); //         269: 9766942854062875822083603685383864834474502597102455389239575471712
298    t0 = t0.square(); //         270: 19533885708125751644167207370767729668949005194204910778479150943424
299    t0 *= t3; //                 271: 19533885708125751644167207370767729668949005194204910778479150943435
300    t0 = t0.square(); //         272: 39067771416251503288334414741535459337898010388409821556958301886870
301    t0 = t0.square(); //         273: 78135542832503006576668829483070918675796020776819643113916603773740
302    t0 = t0.square(); //         274: 156271085665006013153337658966141837351592041553639286227833207547480
303    t0 = t0.square(); //         275: 312542171330012026306675317932283674703184083107278572455666415094960
304    t0 = t0.square(); //         276: 625084342660024052613350635864567349406368166214557144911332830189920
305    t0 = t0.square(); //         277: 1250168685320048105226701271729134698812736332429114289822665660379840
306    t0 = t0.square(); //         278: 2500337370640096210453402543458269397625472664858228579645331320759680
307    t0 = t0.square(); //         279: 5000674741280192420906805086916538795250945329716457159290662641519360
308    t0 *= t2; //                 280: 5000674741280192420906805086916538795250945329716457159290662641519411
309    t0 = t0.square(); //         281: 10001349482560384841813610173833077590501890659432914318581325283038822
310    t0 = t0.square(); //         282: 20002698965120769683627220347666155181003781318865828637162650566077644
311    t0 = t0.square(); //         283: 40005397930241539367254440695332310362007562637731657274325301132155288
312    t0 = t0.square(); //         284: 80010795860483078734508881390664620724015125275463314548650602264310576
313    t0 = t0.square(); //         285: 160021591720966157469017762781329241448030250550926629097301204528621152
314    t0 = t0.square(); //         286: 320043183441932314938035525562658482896060501101853258194602409057242304
315    t0 = t0.square(); //         287: 640086366883864629876071051125316965792121002203706516389204818114484608
316    t0 = t0.square(); //         288: 1280172733767729259752142102250633931584242004407413032778409636228969216
317    t0 *= t2; //                 289: 1280172733767729259752142102250633931584242004407413032778409636228969267
318    t0 = t0.square(); //         290: 2560345467535458519504284204501267863168484008814826065556819272457938534
319    t0 = t0.square(); //         291: 5120690935070917039008568409002535726336968017629652131113638544915877068
320    t0 = t0.square(); //         292: 10241381870141834078017136818005071452673936035259304262227277089831754136
321    t0 = t0.square(); //         293: 20482763740283668156034273636010142905347872070518608524454554179663508272
322    t0 = t0.square(); //         294: 40965527480567336312068547272020285810695744141037217048909108359327016544
323    t0 = t0.square(); //         295: 81931054961134672624137094544040571621391488282074434097818216718654033088
324    t0 = t0.square(); //         296: 163862109922269345248274189088081143242782976564148868195636433437308066176
325    t0 = t0.square(); //         297: 327724219844538690496548378176162286485565953128297736391272866874616132352
326    t0 *= t2; //                 298: 327724219844538690496548378176162286485565953128297736391272866874616132403
327    t0 = t0.square(); //         299: 655448439689077380993096756352324572971131906256595472782545733749232264806
328    t0 = t0.square(); //         300: 1310896879378154761986193512704649145942263812513190945565091467498464529612
329    t0 = t0.square(); //         301: 2621793758756309523972387025409298291884527625026381891130182934996929059224
330    t0 = t0.square(); //         302: 5243587517512619047944774050818596583769055250052763782260365869993858118448
331    t0 = t0.square(); //         303: 10487175035025238095889548101637193167538110500105527564520731739987716236896
332    t0 = t0.square(); //         304: 20974350070050476191779096203274386335076221000211055129041463479975432473792
333    t0 * t1 //                   305: 20974350070050476191779096203274386335076221000211055129041463479975432473805
334}
335
336#[cfg(test)]
337mod tests {
338    use super::*;
339    use ark_ff::One;
340    use ark_ff::PrimeField;
341
342    #[test]
343    fn test_alpha() {
344        let mut a = -Felt::one();
345        for _ in 0..100 {
346            assert_eq!(exp_by_inv_alpha(&a), a.pow(INV_ALPHA.into_bigint()));
347            a += a;
348        }
349    }
350}