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}