anemoi/vesta/
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!("23158417847463239084714197001737581570690445185553317903743794198714690358477");
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!("11579208923731619542357098500868790785345222592776658951871897099357345179239");
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 * x; //           2: 3
31    let t1 = t2.square(); //      3: 4
32    let t0 = t1 * t0; //          4: 7
33    let t3 = t0 * t2; //          5: 9
34    let t1 = t3 * t1; //          6: 13
35    let t0 = t1 * t0; //          7: 20
36    let t11 = t0 * t3; //         8: 29
37    let t3 = t11 * t3; //         9: 38
38    let t6 = t3 * x; //          10: 39
39    let t7 = t6 * t1; //         11: 52
40    let t4 = t7 * t0; //         12: 72
41    let t5 = t4 * t2; //         13: 74
42    let t0 = t5 * t0; //         14: 94
43    let t2 = t0 * t2; //         15: 96
44    let t7 = t7.square(); //     16: 104
45    let t8 = t0 * t6; //         17: 133
46    let t12 = t8 * t4; //        18: 205
47    let t4 = t7.square(); //     19: 208
48    let t10 = t4 * t6; //        20: 247
49    let t6 = t12 * t0; //        21: 299
50    let t9 = t6 * t7; //         22: 403
51    let t7 = t9 * t5; //         23: 477
52    let t3 = t7 * t3; //         24: 515
53    let t5 = t3 * t4; //         25: 723
54    let t2 = t5 * t2; //         26: 819
55    let t4 = t2 * t0; //         27: 913
56    let mut t0 = t2.square(); // 28: 1638
57    t0 = t0.square(); //         29: 3276
58    t0 = t0.square(); //         30: 6552
59    t0 = t0.square(); //         31: 13104
60    t0 = t0.square(); //         32: 26208
61    t0 = t0.square(); //         33: 52416
62    t0 = t0.square(); //         34: 104832
63    t0 = t0.square(); //         35: 209664
64    t0 = t0.square(); //         36: 419328
65    t0 = t0.square(); //         37: 838656
66    t0 = t0.square(); //         38: 1677312
67    t0 = t0.square(); //         39: 3354624
68    t0 *= t2; //                 40: 3355443
69    t0 = t0.square(); //         41: 6710886
70    t0 = t0.square(); //         42: 13421772
71    t0 = t0.square(); //         43: 26843544
72    t0 = t0.square(); //         44: 53687088
73    t0 = t0.square(); //         45: 107374176
74    t0 = t0.square(); //         46: 214748352
75    t0 = t0.square(); //         47: 429496704
76    t0 = t0.square(); //         48: 858993408
77    t0 = t0.square(); //         49: 1717986816
78    t0 = t0.square(); //         50: 3435973632
79    t0 = t0.square(); //         51: 6871947264
80    t0 = t0.square(); //         52: 13743894528
81    t0 *= t2; //                 53: 13743895347
82    t0 = t0.square(); //         54: 27487790694
83    t0 = t0.square(); //         55: 54975581388
84    t0 = t0.square(); //         56: 109951162776
85    t0 = t0.square(); //         57: 219902325552
86    t0 = t0.square(); //         58: 439804651104
87    t0 = t0.square(); //         59: 879609302208
88    t0 = t0.square(); //         60: 1759218604416
89    t0 = t0.square(); //         61: 3518437208832
90    t0 = t0.square(); //         62: 7036874417664
91    t0 = t0.square(); //         63: 14073748835328
92    t0 = t0.square(); //         64: 28147497670656
93    t0 = t0.square(); //         65: 56294995341312
94    t0 *= t2; //                 66: 56294995342131
95    t0 = t0.square(); //         67: 112589990684262
96    t0 = t0.square(); //         68: 225179981368524
97    t0 = t0.square(); //         69: 450359962737048
98    t0 = t0.square(); //         70: 900719925474096
99    t0 = t0.square(); //         71: 1801439850948192
100    t0 = t0.square(); //         72: 3602879701896384
101    t0 = t0.square(); //         73: 7205759403792768
102    t0 = t0.square(); //         74: 14411518807585536
103    t0 = t0.square(); //         75: 28823037615171072
104    t0 = t0.square(); //         76: 57646075230342144
105    t0 = t0.square(); //         77: 115292150460684288
106    t0 = t0.square(); //         78: 230584300921368576
107    t0 *= t2; //                 79: 230584300921369395
108    t0 = t0.square(); //         80: 461168601842738790
109    t0 = t0.square(); //         81: 922337203685477580
110    t0 = t0.square(); //         82: 1844674407370955160
111    t0 = t0.square(); //         83: 3689348814741910320
112    t0 = t0.square(); //         84: 7378697629483820640
113    t0 = t0.square(); //         85: 14757395258967641280
114    t0 = t0.square(); //         86: 29514790517935282560
115    t0 = t0.square(); //         87: 59029581035870565120
116    t0 = t0.square(); //         88: 118059162071741130240
117    t0 = t0.square(); //         89: 236118324143482260480
118    t0 = t0.square(); //         90: 472236648286964520960
119    t0 = t0.square(); //         91: 944473296573929041920
120    t0 *= t2; //                 92: 944473296573929042739
121    t0 = t0.square(); //         93: 1888946593147858085478
122    t0 = t0.square(); //         94: 3777893186295716170956
123    t0 = t0.square(); //         95: 7555786372591432341912
124    t0 = t0.square(); //         96: 15111572745182864683824
125    t0 = t0.square(); //         97: 30223145490365729367648
126    t0 = t0.square(); //         98: 60446290980731458735296
127    t0 = t0.square(); //         99: 120892581961462917470592
128    t0 = t0.square(); //        100: 241785163922925834941184
129    t0 = t0.square(); //        101: 483570327845851669882368
130    t0 = t0.square(); //        102: 967140655691703339764736
131    t0 = t0.square(); //        103: 1934281311383406679529472
132    t0 = t0.square(); //        104: 3868562622766813359058944
133    t0 *= t2; //                105: 3868562622766813359059763
134    t0 = t0.square(); //        106: 7737125245533626718119526
135    t0 = t0.square(); //        107: 15474250491067253436239052
136    t0 = t0.square(); //        108: 30948500982134506872478104
137    t0 = t0.square(); //        109: 61897001964269013744956208
138    t0 = t0.square(); //        110: 123794003928538027489912416
139    t0 = t0.square(); //        111: 247588007857076054979824832
140    t0 = t0.square(); //        112: 495176015714152109959649664
141    t0 = t0.square(); //        113: 990352031428304219919299328
142    t0 = t0.square(); //        114: 1980704062856608439838598656
143    t0 = t0.square(); //        115: 3961408125713216879677197312
144    t0 = t0.square(); //        116: 7922816251426433759354394624
145    t0 = t0.square(); //        117: 15845632502852867518708789248
146    t0 *= t2; //                118: 15845632502852867518708790067
147    t0 = t0.square(); //        119: 31691265005705735037417580134
148    t0 = t0.square(); //        120: 63382530011411470074835160268
149    t0 = t0.square(); //        121: 126765060022822940149670320536
150    t0 = t0.square(); //        122: 253530120045645880299340641072
151    t0 = t0.square(); //        123: 507060240091291760598681282144
152    t0 = t0.square(); //        124: 1014120480182583521197362564288
153    t0 = t0.square(); //        125: 2028240960365167042394725128576
154    t0 = t0.square(); //        126: 4056481920730334084789450257152
155    t0 = t0.square(); //        127: 8112963841460668169578900514304
156    t0 = t0.square(); //        128: 16225927682921336339157801028608
157    t0 = t0.square(); //        129: 32451855365842672678315602057216
158    t0 = t0.square(); //        130: 64903710731685345356631204114432
159    t0 *= t2; //                131: 64903710731685345356631204115251
160    t0 = t0.square(); //        132: 129807421463370690713262408230502
161    t0 = t0.square(); //        133: 259614842926741381426524816461004
162    t0 = t0.square(); //        134: 519229685853482762853049632922008
163    t0 = t0.square(); //        135: 1038459371706965525706099265844016
164    t0 = t0.square(); //        136: 2076918743413931051412198531688032
165    t0 = t0.square(); //        137: 4153837486827862102824397063376064
166    t0 = t0.square(); //        138: 8307674973655724205648794126752128
167    t0 = t0.square(); //        139: 16615349947311448411297588253504256
168    t0 = t0.square(); //        140: 33230699894622896822595176507008512
169    t0 = t0.square(); //        141: 66461399789245793645190353014017024
170    t0 = t0.square(); //        142: 132922799578491587290380706028034048
171    t0 = t0.square(); //        143: 265845599156983174580761412056068096
172    t0 *= t2; //                144: 265845599156983174580761412056068915
173    t0 = t0.square(); //        145: 531691198313966349161522824112137830
174    t0 = t0.square(); //        146: 1063382396627932698323045648224275660
175    t0 = t0.square(); //        147: 2126764793255865396646091296448551320
176    t0 = t0.square(); //        148: 4253529586511730793292182592897102640
177    t0 = t0.square(); //        149: 8507059173023461586584365185794205280
178    t0 = t0.square(); //        150: 17014118346046923173168730371588410560
179    t0 = t0.square(); //        151: 34028236692093846346337460743176821120
180    t0 = t0.square(); //        152: 68056473384187692692674921486353642240
181    t0 = t0.square(); //        153: 136112946768375385385349842972707284480
182    t0 = t0.square(); //        154: 272225893536750770770699685945414568960
183    t0 *= t12; //               155: 272225893536750770770699685945414569165
184    t0 = t0.square(); //        156: 544451787073501541541399371890829138330
185    t0 = t0.square(); //        157: 1088903574147003083082798743781658276660
186    t0 = t0.square(); //        158: 2177807148294006166165597487563316553320
187    t0 = t0.square(); //        159: 4355614296588012332331194975126633106640
188    t0 = t0.square(); //        160: 8711228593176024664662389950253266213280
189    t0 = t0.square(); //        161: 17422457186352049329324779900506532426560
190    t0 = t0.square(); //        162: 34844914372704098658649559801013064853120
191    t0 *= t11; //               163: 34844914372704098658649559801013064853149
192    t0 = t0.square(); //        164: 69689828745408197317299119602026129706298
193    t0 = t0.square(); //        165: 139379657490816394634598239204052259412596
194    t0 = t0.square(); //        166: 278759314981632789269196478408104518825192
195    t0 = t0.square(); //        167: 557518629963265578538392956816209037650384
196    t0 = t0.square(); //        168: 1115037259926531157076785913632418075300768
197    t0 = t0.square(); //        169: 2230074519853062314153571827264836150601536
198    t0 = t0.square(); //        170: 4460149039706124628307143654529672301203072
199    t0 = t0.square(); //        171: 8920298079412249256614287309059344602406144
200    t0 = t0.square(); //        172: 17840596158824498513228574618118689204812288
201    t0 = t0.square(); //        173: 35681192317648997026457149236237378409624576
202    t0 *= t10; //               174: 35681192317648997026457149236237378409624823
203    t0 = t0.square(); //        175: 71362384635297994052914298472474756819249646
204    t0 = t0.square(); //        176: 142724769270595988105828596944949513638499292
205    t0 = t0.square(); //        177: 285449538541191976211657193889899027276998584
206    t0 = t0.square(); //        178: 570899077082383952423314387779798054553997168
207    t0 = t0.square(); //        179: 1141798154164767904846628775559596109107994336
208    t0 = t0.square(); //        180: 2283596308329535809693257551119192218215988672
209    t0 = t0.square(); //        181: 4567192616659071619386515102238384436431977344
210    t0 = t0.square(); //        182: 9134385233318143238773030204476768872863954688
211    t0 = t0.square(); //        183: 18268770466636286477546060408953537745727909376
212    t0 = t0.square(); //        184: 36537540933272572955092120817907075491455818752
213    t0 = t0.square(); //        185: 73075081866545145910184241635814150982911637504
214    t0 = t0.square(); //        186: 146150163733090291820368483271628301965823275008
215    t0 = t0.square(); //        187: 292300327466180583640736966543256603931646550016
216    t0 = t0.square(); //        188: 584600654932361167281473933086513207863293100032
217    t0 *= t9; //                189: 584600654932361167281473933086513207863293100435
218    t0 = t0.square(); //        190: 1169201309864722334562947866173026415726586200870
219    t0 = t0.square(); //        191: 2338402619729444669125895732346052831453172401740
220    t0 = t0.square(); //        192: 4676805239458889338251791464692105662906344803480
221    t0 = t0.square(); //        193: 9353610478917778676503582929384211325812689606960
222    t0 = t0.square(); //        194: 18707220957835557353007165858768422651625379213920
223    t0 = t0.square(); //        195: 37414441915671114706014331717536845303250758427840
224    t0 = t0.square(); //        196: 74828883831342229412028663435073690606501516855680
225    t0 = t0.square(); //        197: 149657767662684458824057326870147381213003033711360
226    t0 = t0.square(); //        198: 299315535325368917648114653740294762426006067422720
227    t0 *= t8; //                199: 299315535325368917648114653740294762426006067422853
228    t0 = t0.square(); //        200: 598631070650737835296229307480589524852012134845706
229    t0 = t0.square(); //        201: 1197262141301475670592458614961179049704024269691412
230    t0 = t0.square(); //        202: 2394524282602951341184917229922358099408048539382824
231    t0 = t0.square(); //        203: 4789048565205902682369834459844716198816097078765648
232    t0 = t0.square(); //        204: 9578097130411805364739668919689432397632194157531296
233    t0 = t0.square(); //        205: 19156194260823610729479337839378864795264388315062592
234    t0 = t0.square(); //        206: 38312388521647221458958675678757729590528776630125184
235    t0 = t0.square(); //        207: 76624777043294442917917351357515459181057553260250368
236    t0 = t0.square(); //        208: 153249554086588885835834702715030918362115106520500736
237    t0 = t0.square(); //        209: 306499108173177771671669405430061836724230213041001472
238    t0 = t0.square(); //        210: 612998216346355543343338810860123673448460426082002944
239    t0 = t0.square(); //        211: 1225996432692711086686677621720247346896920852164005888
240    t0 = t0.square(); //        212: 2451992865385422173373355243440494693793841704328011776
241    t0 *= t7; //                213: 2451992865385422173373355243440494693793841704328012253
242    t0 = t0.square(); //        214: 4903985730770844346746710486880989387587683408656024506
243    t0 = t0.square(); //        215: 9807971461541688693493420973761978775175366817312049012
244    t0 = t0.square(); //        216: 19615942923083377386986841947523957550350733634624098024
245    t0 = t0.square(); //        217: 39231885846166754773973683895047915100701467269248196048
246    t0 = t0.square(); //        218: 78463771692333509547947367790095830201402934538496392096
247    t0 = t0.square(); //        219: 156927543384667019095894735580191660402805869076992784192
248    t0 = t0.square(); //        220: 313855086769334038191789471160383320805611738153985568384
249    t0 = t0.square(); //        221: 627710173538668076383578942320766641611223476307971136768
250    t0 = t0.square(); //        222: 1255420347077336152767157884641533283222446952615942273536
251    t0 = t0.square(); //        223: 2510840694154672305534315769283066566444893905231884547072
252    t0 = t0.square(); //        224: 5021681388309344611068631538566133132889787810463769094144
253    t0 *= t6; //                225: 5021681388309344611068631538566133132889787810463769094443
254    t0 = t0.square(); //        226: 10043362776618689222137263077132266265779575620927538188886
255    t0 = t0.square(); //        227: 20086725553237378444274526154264532531559151241855076377772
256    t0 = t0.square(); //        228: 40173451106474756888549052308529065063118302483710152755544
257    t0 = t0.square(); //        229: 80346902212949513777098104617058130126236604967420305511088
258    t0 = t0.square(); //        230: 160693804425899027554196209234116260252473209934840611022176
259    t0 = t0.square(); //        231: 321387608851798055108392418468232520504946419869681222044352
260    t0 = t0.square(); //        232: 642775217703596110216784836936465041009892839739362444088704
261    t0 = t0.square(); //        233: 1285550435407192220433569673872930082019785679478724888177408
262    t0 = t0.square(); //        234: 2571100870814384440867139347745860164039571358957449776354816
263    t0 = t0.square(); //        235: 5142201741628768881734278695491720328079142717914899552709632
264    t0 = t0.square(); //        236: 10284403483257537763468557390983440656158285435829799105419264
265    t0 *= t5; //                237: 10284403483257537763468557390983440656158285435829799105419987
266    t0 = t0.square(); //        238: 20568806966515075526937114781966881312316570871659598210839974
267    t0 = t0.square(); //        239: 41137613933030151053874229563933762624633141743319196421679948
268    t0 = t0.square(); //        240: 82275227866060302107748459127867525249266283486638392843359896
269    t0 = t0.square(); //        241: 164550455732120604215496918255735050498532566973276785686719792
270    t0 = t0.square(); //        242: 329100911464241208430993836511470100997065133946553571373439584
271    t0 = t0.square(); //        243: 658201822928482416861987673022940201994130267893107142746879168
272    t0 = t0.square(); //        244: 1316403645856964833723975346045880403988260535786214285493758336
273    t0 = t0.square(); //        245: 2632807291713929667447950692091760807976521071572428570987516672
274    t0 = t0.square(); //        246: 5265614583427859334895901384183521615953042143144857141975033344
275    t0 = t0.square(); //        247: 10531229166855718669791802768367043231906084286289714283950066688
276    t0 *= t4; //                248: 10531229166855718669791802768367043231906084286289714283950067601
277    t0 = t0.square(); //        249: 21062458333711437339583605536734086463812168572579428567900135202
278    t0 = t0.square(); //        250: 42124916667422874679167211073468172927624337145158857135800270404
279    t0 = t0.square(); //        251: 84249833334845749358334422146936345855248674290317714271600540808
280    t0 = t0.square(); //        252: 168499666669691498716668844293872691710497348580635428543201081616
281    t0 = t0.square(); //        253: 336999333339382997433337688587745383420994697161270857086402163232
282    t0 = t0.square(); //        254: 673998666678765994866675377175490766841989394322541714172804326464
283    t0 = t0.square(); //        255: 1347997333357531989733350754350981533683978788645083428345608652928
284    t0 = t0.square(); //        256: 2695994666715063979466701508701963067367957577290166856691217305856
285    t0 = t0.square(); //        257: 5391989333430127958933403017403926134735915154580333713382434611712
286    t0 = t0.square(); //        258: 10783978666860255917866806034807852269471830309160667426764869223424
287    t0 = t0.square(); //        259: 21567957333720511835733612069615704538943660618321334853529738446848
288    t0 *= t3; //                260: 21567957333720511835733612069615704538943660618321334853529738447363
289    t0 = t0.square(); //        261: 43135914667441023671467224139231409077887321236642669707059476894726
290    t0 = t0.square(); //        262: 86271829334882047342934448278462818155774642473285339414118953789452
291    t0 = t0.square(); //        263: 172543658669764094685868896556925636311549284946570678828237907578904
292    t0 = t0.square(); //        264: 345087317339528189371737793113851272623098569893141357656475815157808
293    t0 = t0.square(); //        265: 690174634679056378743475586227702545246197139786282715312951630315616
294    t0 = t0.square(); //        266: 1380349269358112757486951172455405090492394279572565430625903260631232
295    t0 = t0.square(); //        267: 2760698538716225514973902344910810180984788559145130861251806521262464
296    t0 = t0.square(); //        268: 5521397077432451029947804689821620361969577118290261722503613042524928
297    t0 = t0.square(); //        269: 11042794154864902059895609379643240723939154236580523445007226085049856
298    t0 = t0.square(); //        270: 22085588309729804119791218759286481447878308473161046890014452170099712
299    t0 = t0.square(); //        271: 44171176619459608239582437518572962895756616946322093780028904340199424
300    t0 = t0.square(); //        272: 88342353238919216479164875037145925791513233892644187560057808680398848
301    t0 *= t2; //                273: 88342353238919216479164875037145925791513233892644187560057808680399667
302    t0 = t0.square(); //        274: 176684706477838432958329750074291851583026467785288375120115617360799334
303    t0 = t0.square(); //        275: 353369412955676865916659500148583703166052935570576750240231234721598668
304    t0 = t0.square(); //        276: 706738825911353731833319000297167406332105871141153500480462469443197336
305    t0 = t0.square(); //        277: 1413477651822707463666638000594334812664211742282307000960924938886394672
306    t0 = t0.square(); //        278: 2826955303645414927333276001188669625328423484564614001921849877772789344
307    t0 = t0.square(); //        279: 5653910607290829854666552002377339250656846969129228003843699755545578688
308    t0 = t0.square(); //        280: 11307821214581659709333104004754678501313693938258456007687399511091157376
309    t0 = t0.square(); //        281: 22615642429163319418666208009509357002627387876516912015374799022182314752
310    t0 = t0.square(); //        282: 45231284858326638837332416019018714005254775753033824030749598044364629504
311    t0 = t0.square(); //        283: 90462569716653277674664832038037428010509551506067648061499196088729259008
312    t0 = t0.square(); //        284: 180925139433306555349329664076074856021019103012135296122998392177458518016
313    t0 = t0.square(); //        285: 361850278866613110698659328152149712042038206024270592245996784354917036032
314    t0 *= t2; //                286: 361850278866613110698659328152149712042038206024270592245996784354917036851
315    t0 = t0.square(); //        287: 723700557733226221397318656304299424084076412048541184491993568709834073702
316    t0 = t0.square(); //        288: 1447401115466452442794637312608598848168152824097082368983987137419668147404
317    t0 = t0.square(); //        289: 2894802230932904885589274625217197696336305648194164737967974274839336294808
318    t0 = t0.square(); //        290: 5789604461865809771178549250434395392672611296388329475935948549678672589616
319    t0 = t0.square(); //        291: 11579208923731619542357098500868790785345222592776658951871897099357345179232
320    t0 = t0.square(); //        292: 23158417847463239084714197001737581570690445185553317903743794198714690358464
321    t0 * t1 //                  293: 23158417847463239084714197001737581570690445185553317903743794198714690358477
322}
323
324#[cfg(test)]
325mod tests {
326    use super::*;
327    use ark_ff::One;
328    use ark_ff::PrimeField;
329
330    #[test]
331    fn test_alpha() {
332        let mut a = -Felt::one();
333        for _ in 0..100 {
334            assert_eq!(exp_by_inv_alpha(&a), a.pow(INV_ALPHA.into_bigint()));
335            a += a;
336        }
337    }
338}