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}