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}