anemoi/pallas/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!("23158417847463239084714197001737581570690445185553248572763741411479974104269");
14
15/// Multiplier of the Anemoi S-Box
16#[allow(unused)]
17pub(crate) const BETA: u32 = 5;
18
19/// First added constant of the Anemoi S-Box
20pub(crate) const DELTA: Felt =
21 MontFp!("11579208923731619542357098500868790785345222592776624286381870705739987052135");
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 t2 = x.square(); // 1: 2
30 let t0 = t2.square(); // 2: 4
31 let t2 = t0 * t2; // 3: 6
32 let t6 = t2 * x; // 4: 7
33 let t3 = t0.square(); // 5: 8
34 let t0 = t2.square(); // 6: 12
35 let t9 = t6 * t2; // 7: 13
36 let t4 = t3 * t6; // 8: 15
37 let t7 = t0 * t6; // 9: 19
38 let t5 = t4 * t3; // 10: 23
39 let t10 = t9 * t0; // 11: 25
40 let t8 = t10 * t3; // 12: 33
41 let t11 = t8 * t2; // 13: 39
42 let t2 = t11 * t0; // 14: 51
43 let t3 = t2 * t0; // 15: 63
44 let mut t0 = t2.square(); // 16: 102
45 t0 = t0.square(); // 17: 204
46 t0 = t0.square(); // 18: 408
47 t0 = t0.square(); // 19: 816
48 t0 = t0.square(); // 20: 1632
49 t0 = t0.square(); // 21: 3264
50 t0 = t0.square(); // 22: 6528
51 t0 = t0.square(); // 23: 13056
52 t0 *= t2; // 24: 13107
53 t0 = t0.square(); // 25: 26214
54 t0 = t0.square(); // 26: 52428
55 t0 = t0.square(); // 27: 104856
56 t0 = t0.square(); // 28: 209712
57 t0 = t0.square(); // 29: 419424
58 t0 = t0.square(); // 30: 838848
59 t0 = t0.square(); // 31: 1677696
60 t0 = t0.square(); // 32: 3355392
61 t0 *= t2; // 33: 3355443
62 t0 = t0.square(); // 34: 6710886
63 t0 = t0.square(); // 35: 13421772
64 t0 = t0.square(); // 36: 26843544
65 t0 = t0.square(); // 37: 53687088
66 t0 = t0.square(); // 38: 107374176
67 t0 = t0.square(); // 39: 214748352
68 t0 = t0.square(); // 40: 429496704
69 t0 = t0.square(); // 41: 858993408
70 t0 *= t2; // 42: 858993459
71 t0 = t0.square(); // 43: 1717986918
72 t0 = t0.square(); // 44: 3435973836
73 t0 = t0.square(); // 45: 6871947672
74 t0 = t0.square(); // 46: 13743895344
75 t0 = t0.square(); // 47: 27487790688
76 t0 = t0.square(); // 48: 54975581376
77 t0 = t0.square(); // 49: 109951162752
78 t0 = t0.square(); // 50: 219902325504
79 t0 *= t2; // 51: 219902325555
80 t0 = t0.square(); // 52: 439804651110
81 t0 = t0.square(); // 53: 879609302220
82 t0 = t0.square(); // 54: 1759218604440
83 t0 = t0.square(); // 55: 3518437208880
84 t0 = t0.square(); // 56: 7036874417760
85 t0 = t0.square(); // 57: 14073748835520
86 t0 = t0.square(); // 58: 28147497671040
87 t0 = t0.square(); // 59: 56294995342080
88 t0 *= t2; // 60: 56294995342131
89 t0 = t0.square(); // 61: 112589990684262
90 t0 = t0.square(); // 62: 225179981368524
91 t0 = t0.square(); // 63: 450359962737048
92 t0 = t0.square(); // 64: 900719925474096
93 t0 = t0.square(); // 65: 1801439850948192
94 t0 = t0.square(); // 66: 3602879701896384
95 t0 = t0.square(); // 67: 7205759403792768
96 t0 = t0.square(); // 68: 14411518807585536
97 t0 *= t2; // 69: 14411518807585587
98 t0 = t0.square(); // 70: 28823037615171174
99 t0 = t0.square(); // 71: 57646075230342348
100 t0 = t0.square(); // 72: 115292150460684696
101 t0 = t0.square(); // 73: 230584300921369392
102 t0 = t0.square(); // 74: 461168601842738784
103 t0 = t0.square(); // 75: 922337203685477568
104 t0 = t0.square(); // 76: 1844674407370955136
105 t0 = t0.square(); // 77: 3689348814741910272
106 t0 *= t2; // 78: 3689348814741910323
107 t0 = t0.square(); // 79: 7378697629483820646
108 t0 = t0.square(); // 80: 14757395258967641292
109 t0 = t0.square(); // 81: 29514790517935282584
110 t0 = t0.square(); // 82: 59029581035870565168
111 t0 = t0.square(); // 83: 118059162071741130336
112 t0 = t0.square(); // 84: 236118324143482260672
113 t0 = t0.square(); // 85: 472236648286964521344
114 t0 = t0.square(); // 86: 944473296573929042688
115 t0 *= t2; // 87: 944473296573929042739
116 t0 = t0.square(); // 88: 1888946593147858085478
117 t0 = t0.square(); // 89: 3777893186295716170956
118 t0 = t0.square(); // 90: 7555786372591432341912
119 t0 = t0.square(); // 91: 15111572745182864683824
120 t0 = t0.square(); // 92: 30223145490365729367648
121 t0 = t0.square(); // 93: 60446290980731458735296
122 t0 = t0.square(); // 94: 120892581961462917470592
123 t0 = t0.square(); // 95: 241785163922925834941184
124 t0 *= t2; // 96: 241785163922925834941235
125 t0 = t0.square(); // 97: 483570327845851669882470
126 t0 = t0.square(); // 98: 967140655691703339764940
127 t0 = t0.square(); // 99: 1934281311383406679529880
128 t0 = t0.square(); // 100: 3868562622766813359059760
129 t0 = t0.square(); // 101: 7737125245533626718119520
130 t0 = t0.square(); // 102: 15474250491067253436239040
131 t0 = t0.square(); // 103: 30948500982134506872478080
132 t0 = t0.square(); // 104: 61897001964269013744956160
133 t0 *= t2; // 105: 61897001964269013744956211
134 t0 = t0.square(); // 106: 123794003928538027489912422
135 t0 = t0.square(); // 107: 247588007857076054979824844
136 t0 = t0.square(); // 108: 495176015714152109959649688
137 t0 = t0.square(); // 109: 990352031428304219919299376
138 t0 = t0.square(); // 110: 1980704062856608439838598752
139 t0 = t0.square(); // 111: 3961408125713216879677197504
140 t0 = t0.square(); // 112: 7922816251426433759354395008
141 t0 = t0.square(); // 113: 15845632502852867518708790016
142 t0 *= t2; // 114: 15845632502852867518708790067
143 t0 = t0.square(); // 115: 31691265005705735037417580134
144 t0 = t0.square(); // 116: 63382530011411470074835160268
145 t0 = t0.square(); // 117: 126765060022822940149670320536
146 t0 = t0.square(); // 118: 253530120045645880299340641072
147 t0 = t0.square(); // 119: 507060240091291760598681282144
148 t0 = t0.square(); // 120: 1014120480182583521197362564288
149 t0 = t0.square(); // 121: 2028240960365167042394725128576
150 t0 = t0.square(); // 122: 4056481920730334084789450257152
151 t0 *= t2; // 123: 4056481920730334084789450257203
152 t0 = t0.square(); // 124: 8112963841460668169578900514406
153 t0 = t0.square(); // 125: 16225927682921336339157801028812
154 t0 = t0.square(); // 126: 32451855365842672678315602057624
155 t0 = t0.square(); // 127: 64903710731685345356631204115248
156 t0 = t0.square(); // 128: 129807421463370690713262408230496
157 t0 = t0.square(); // 129: 259614842926741381426524816460992
158 t0 = t0.square(); // 130: 519229685853482762853049632921984
159 t0 = t0.square(); // 131: 1038459371706965525706099265843968
160 t0 *= t2; // 132: 1038459371706965525706099265844019
161 t0 = t0.square(); // 133: 2076918743413931051412198531688038
162 t0 = t0.square(); // 134: 4153837486827862102824397063376076
163 t0 = t0.square(); // 135: 8307674973655724205648794126752152
164 t0 = t0.square(); // 136: 16615349947311448411297588253504304
165 t0 = t0.square(); // 137: 33230699894622896822595176507008608
166 t0 = t0.square(); // 138: 66461399789245793645190353014017216
167 t0 = t0.square(); // 139: 132922799578491587290380706028034432
168 t0 = t0.square(); // 140: 265845599156983174580761412056068864
169 t0 *= t2; // 141: 265845599156983174580761412056068915
170 t0 = t0.square(); // 142: 531691198313966349161522824112137830
171 t0 = t0.square(); // 143: 1063382396627932698323045648224275660
172 t0 = t0.square(); // 144: 2126764793255865396646091296448551320
173 t0 = t0.square(); // 145: 4253529586511730793292182592897102640
174 t0 = t0.square(); // 146: 8507059173023461586584365185794205280
175 t0 = t0.square(); // 147: 17014118346046923173168730371588410560
176 t0 = t0.square(); // 148: 34028236692093846346337460743176821120
177 t0 = t0.square(); // 149: 68056473384187692692674921486353642240
178 t0 *= t2; // 150: 68056473384187692692674921486353642291
179 t0 = t0.square(); // 151: 136112946768375385385349842972707284582
180 t0 = t0.square(); // 152: 272225893536750770770699685945414569164
181 t0 = t0.square(); // 153: 544451787073501541541399371890829138328
182 t0 = t0.square(); // 154: 1088903574147003083082798743781658276656
183 t0 = t0.square(); // 155: 2177807148294006166165597487563316553312
184 t0 = t0.square(); // 156: 4355614296588012332331194975126633106624
185 t0 = t0.square(); // 157: 8711228593176024664662389950253266213248
186 t0 *= t11; // 158: 8711228593176024664662389950253266213287
187 t0 = t0.square(); // 159: 17422457186352049329324779900506532426574
188 t0 = t0.square(); // 160: 34844914372704098658649559801013064853148
189 t0 = t0.square(); // 161: 69689828745408197317299119602026129706296
190 t0 = t0.square(); // 162: 139379657490816394634598239204052259412592
191 t0 = t0.square(); // 163: 278759314981632789269196478408104518825184
192 t0 = t0.square(); // 164: 557518629963265578538392956816209037650368
193 t0 = t0.square(); // 165: 1115037259926531157076785913632418075300736
194 t0 *= t11; // 166: 1115037259926531157076785913632418075300775
195 t0 = t0.square(); // 167: 2230074519853062314153571827264836150601550
196 t0 = t0.square(); // 168: 4460149039706124628307143654529672301203100
197 t0 = t0.square(); // 169: 8920298079412249256614287309059344602406200
198 t0 = t0.square(); // 170: 17840596158824498513228574618118689204812400
199 t0 = t0.square(); // 171: 35681192317648997026457149236237378409624800
200 t0 *= t5; // 172: 35681192317648997026457149236237378409624823
201 t0 = t0.square(); // 173: 71362384635297994052914298472474756819249646
202 t0 = t0.square(); // 174: 142724769270595988105828596944949513638499292
203 t0 = t0.square(); // 175: 285449538541191976211657193889899027276998584
204 t0 = t0.square(); // 176: 570899077082383952423314387779798054553997168
205 t0 = t0.square(); // 177: 1141798154164767904846628775559596109107994336
206 t0 = t0.square(); // 178: 2283596308329535809693257551119192218215988672
207 t0 = t0.square(); // 179: 4567192616659071619386515102238384436431977344
208 t0 = t0.square(); // 180: 9134385233318143238773030204476768872863954688
209 t0 = t0.square(); // 181: 18268770466636286477546060408953537745727909376
210 t0 = t0.square(); // 182: 36537540933272572955092120817907075491455818752
211 t0 *= t10; // 183: 36537540933272572955092120817907075491455818777
212 t0 = t0.square(); // 184: 73075081866545145910184241635814150982911637554
213 t0 = t0.square(); // 185: 146150163733090291820368483271628301965823275108
214 t0 = t0.square(); // 186: 292300327466180583640736966543256603931646550216
215 t0 = t0.square(); // 187: 584600654932361167281473933086513207863293100432
216 t0 = t0.square(); // 188: 1169201309864722334562947866173026415726586200864
217 t0 = t0.square(); // 189: 2338402619729444669125895732346052831453172401728
218 t0 *= t9; // 190: 2338402619729444669125895732346052831453172401741
219 t0 = t0.square(); // 191: 4676805239458889338251791464692105662906344803482
220 t0 = t0.square(); // 192: 9353610478917778676503582929384211325812689606964
221 t0 = t0.square(); // 193: 18707220957835557353007165858768422651625379213928
222 t0 = t0.square(); // 194: 37414441915671114706014331717536845303250758427856
223 t0 = t0.square(); // 195: 74828883831342229412028663435073690606501516855712
224 t0 = t0.square(); // 196: 149657767662684458824057326870147381213003033711424
225 t0 = t0.square(); // 197: 299315535325368917648114653740294762426006067422848
226 t0 = t0.square(); // 198: 598631070650737835296229307480589524852012134845696
227 t0 = t0.square(); // 199: 1197262141301475670592458614961179049704024269691392
228 t0 = t0.square(); // 200: 2394524282602951341184917229922358099408048539382784
229 t0 *= t8; // 201: 2394524282602951341184917229922358099408048539382817
230 t0 = t0.square(); // 202: 4789048565205902682369834459844716198816097078765634
231 t0 = t0.square(); // 203: 9578097130411805364739668919689432397632194157531268
232 t0 = t0.square(); // 204: 19156194260823610729479337839378864795264388315062536
233 t0 = t0.square(); // 205: 38312388521647221458958675678757729590528776630125072
234 t0 = t0.square(); // 206: 76624777043294442917917351357515459181057553260250144
235 t0 = t0.square(); // 207: 153249554086588885835834702715030918362115106520500288
236 t0 *= t7; // 208: 153249554086588885835834702715030918362115106520500307
237 t0 = t0.square(); // 209: 306499108173177771671669405430061836724230213041000614
238 t0 = t0.square(); // 210: 612998216346355543343338810860123673448460426082001228
239 t0 = t0.square(); // 211: 1225996432692711086686677621720247346896920852164002456
240 t0 = t0.square(); // 212: 2451992865385422173373355243440494693793841704328004912
241 t0 = t0.square(); // 213: 4903985730770844346746710486880989387587683408656009824
242 t0 = t0.square(); // 214: 9807971461541688693493420973761978775175366817312019648
243 t0 = t0.square(); // 215: 19615942923083377386986841947523957550350733634624039296
244 t0 = t0.square(); // 216: 39231885846166754773973683895047915100701467269248078592
245 t0 *= t6; // 217: 39231885846166754773973683895047915100701467269248078599
246 t0 = t0.square(); // 218: 78463771692333509547947367790095830201402934538496157198
247 t0 = t0.square(); // 219: 156927543384667019095894735580191660402805869076992314396
248 t0 = t0.square(); // 220: 313855086769334038191789471160383320805611738153984628792
249 t0 = t0.square(); // 221: 627710173538668076383578942320766641611223476307969257584
250 t0 = t0.square(); // 222: 1255420347077336152767157884641533283222446952615938515168
251 t0 = t0.square(); // 223: 2510840694154672305534315769283066566444893905231877030336
252 t0 = t0.square(); // 224: 5021681388309344611068631538566133132889787810463754060672
253 t0 = t0.square(); // 225: 10043362776618689222137263077132266265779575620927508121344
254 t0 *= t5; // 226: 10043362776618689222137263077132266265779575620927508121367
255 t0 = t0.square(); // 227: 20086725553237378444274526154264532531559151241855016242734
256 t0 = t0.square(); // 228: 40173451106474756888549052308529065063118302483710032485468
257 t0 = t0.square(); // 229: 80346902212949513777098104617058130126236604967420064970936
258 t0 = t0.square(); // 230: 160693804425899027554196209234116260252473209934840129941872
259 t0 = t0.square(); // 231: 321387608851798055108392418468232520504946419869680259883744
260 t0 = t0.square(); // 232: 642775217703596110216784836936465041009892839739360519767488
261 t0 = t0.square(); // 233: 1285550435407192220433569673872930082019785679478721039534976
262 t0 = t0.square(); // 234: 2571100870814384440867139347745860164039571358957442079069952
263 t0 = t0.square(); // 235: 5142201741628768881734278695491720328079142717914884158139904
264 t0 *= t4; // 236: 5142201741628768881734278695491720328079142717914884158139919
265 t0 = t0.square(); // 237: 10284403483257537763468557390983440656158285435829768316279838
266 t0 = t0.square(); // 238: 20568806966515075526937114781966881312316570871659536632559676
267 t0 = t0.square(); // 239: 41137613933030151053874229563933762624633141743319073265119352
268 t0 = t0.square(); // 240: 82275227866060302107748459127867525249266283486638146530238704
269 t0 = t0.square(); // 241: 164550455732120604215496918255735050498532566973276293060477408
270 t0 = t0.square(); // 242: 329100911464241208430993836511470100997065133946552586120954816
271 t0 = t0.square(); // 243: 658201822928482416861987673022940201994130267893105172241909632
272 t0 = t0.square(); // 244: 1316403645856964833723975346045880403988260535786210344483819264
273 t0 *= t4; // 245: 1316403645856964833723975346045880403988260535786210344483819279
274 t0 = t0.square(); // 246: 2632807291713929667447950692091760807976521071572420688967638558
275 t0 = t0.square(); // 247: 5265614583427859334895901384183521615953042143144841377935277116
276 t0 = t0.square(); // 248: 10531229166855718669791802768367043231906084286289682755870554232
277 t0 = t0.square(); // 249: 21062458333711437339583605536734086463812168572579365511741108464
278 t0 = t0.square(); // 250: 42124916667422874679167211073468172927624337145158731023482216928
279 t0 = t0.square(); // 251: 84249833334845749358334422146936345855248674290317462046964433856
280 t0 = t0.square(); // 252: 168499666669691498716668844293872691710497348580634924093928867712
281 t0 = t0.square(); // 253: 336999333339382997433337688587745383420994697161269848187857735424
282 t0 *= t3; // 254: 336999333339382997433337688587745383420994697161269848187857735487
283 t0 = t0.square(); // 255: 673998666678765994866675377175490766841989394322539696375715470974
284 t0 = t0.square(); // 256: 1347997333357531989733350754350981533683978788645079392751430941948
285 t0 = t0.square(); // 257: 2695994666715063979466701508701963067367957577290158785502861883896
286 t0 = t0.square(); // 258: 5391989333430127958933403017403926134735915154580317571005723767792
287 t0 = t0.square(); // 259: 10783978666860255917866806034807852269471830309160635142011447535584
288 t0 = t0.square(); // 260: 21567957333720511835733612069615704538943660618321270284022895071168
289 t0 = t0.square(); // 261: 43135914667441023671467224139231409077887321236642540568045790142336
290 t0 = t0.square(); // 262: 86271829334882047342934448278462818155774642473285081136091580284672
291 t0 = t0.square(); // 263: 172543658669764094685868896556925636311549284946570162272183160569344
292 t0 = t0.square(); // 264: 345087317339528189371737793113851272623098569893140324544366321138688
293 t0 *= t2; // 265: 345087317339528189371737793113851272623098569893140324544366321138739
294 t0 = t0.square(); // 266: 690174634679056378743475586227702545246197139786280649088732642277478
295 t0 = t0.square(); // 267: 1380349269358112757486951172455405090492394279572561298177465284554956
296 t0 = t0.square(); // 268: 2760698538716225514973902344910810180984788559145122596354930569109912
297 t0 = t0.square(); // 269: 5521397077432451029947804689821620361969577118290245192709861138219824
298 t0 = t0.square(); // 270: 11042794154864902059895609379643240723939154236580490385419722276439648
299 t0 = t0.square(); // 271: 22085588309729804119791218759286481447878308473160980770839444552879296
300 t0 = t0.square(); // 272: 44171176619459608239582437518572962895756616946321961541678889105758592
301 t0 = t0.square(); // 273: 88342353238919216479164875037145925791513233892643923083357778211517184
302 t0 *= t2; // 274: 88342353238919216479164875037145925791513233892643923083357778211517235
303 t0 = t0.square(); // 275: 176684706477838432958329750074291851583026467785287846166715556423034470
304 t0 = t0.square(); // 276: 353369412955676865916659500148583703166052935570575692333431112846068940
305 t0 = t0.square(); // 277: 706738825911353731833319000297167406332105871141151384666862225692137880
306 t0 = t0.square(); // 278: 1413477651822707463666638000594334812664211742282302769333724451384275760
307 t0 = t0.square(); // 279: 2826955303645414927333276001188669625328423484564605538667448902768551520
308 t0 = t0.square(); // 280: 5653910607290829854666552002377339250656846969129211077334897805537103040
309 t0 = t0.square(); // 281: 11307821214581659709333104004754678501313693938258422154669795611074206080
310 t0 = t0.square(); // 282: 22615642429163319418666208009509357002627387876516844309339591222148412160
311 t0 *= t2; // 283: 22615642429163319418666208009509357002627387876516844309339591222148412211
312 t0 = t0.square(); // 284: 45231284858326638837332416019018714005254775753033688618679182444296824422
313 t0 = t0.square(); // 285: 90462569716653277674664832038037428010509551506067377237358364888593648844
314 t0 = t0.square(); // 286: 180925139433306555349329664076074856021019103012134754474716729777187297688
315 t0 = t0.square(); // 287: 361850278866613110698659328152149712042038206024269508949433459554374595376
316 t0 = t0.square(); // 288: 723700557733226221397318656304299424084076412048539017898866919108749190752
317 t0 = t0.square(); // 289: 1447401115466452442794637312608598848168152824097078035797733838217498381504
318 t0 = t0.square(); // 290: 2894802230932904885589274625217197696336305648194156071595467676434996763008
319 t0 = t0.square(); // 291: 5789604461865809771178549250434395392672611296388312143190935352869993526016
320 t0 *= t2; // 292: 5789604461865809771178549250434395392672611296388312143190935352869993526067
321 t0 = t0.square(); // 293: 11579208923731619542357098500868790785345222592776624286381870705739987052134
322 t0 = t0.square(); // 294: 23158417847463239084714197001737581570690445185553248572763741411479974104268
323 t0 * x // 295: 23158417847463239084714197001737581570690445185553248572763741411479974104269
324}
325
326#[cfg(test)]
327mod tests {
328 use super::*;
329 use ark_ff::One;
330 use ark_ff::PrimeField;
331
332 #[test]
333 fn test_alpha() {
334 let mut a = -Felt::one();
335 for _ in 0..100 {
336 assert_eq!(exp_by_inv_alpha(&a), a.pow(INV_ALPHA.into_bigint()));
337 a += a;
338 }
339 }
340}