anemoi/ed_on_bls12_377/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 = 11;
9
10#[allow(unused)]
11/// Inverse exponent
12pub(crate) const INV_ALPHA: Felt =
13 MontFp!("6909105067714121256203584040821265343853008546944234041037918282114243922851");
14
15/// Multiplier of the Anemoi S-Box
16#[allow(unused)]
17pub(crate) const BETA: u32 = 22;
18
19/// First added constant of the Anemoi S-Box
20pub(crate) const DELTA: Felt =
21 MontFp!("1151517511285686876033930673470210890642168091157372340172986380352373987142");
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 t10 = x.square(); // 1: 2
30 let t0 = t10 * x; // 2: 3
31 let t7 = t10.square(); // 3: 4
32 let t14 = t0 * t10; // 4: 5
33 let t0 = t7.square(); // 5: 8
34 let t8 = t14 * t7; // 6: 9
35 let t4 = t8 * t0; // 7: 17
36 let t5 = t4 * t7; // 8: 21
37 let t2 = t5 * t10; // 9: 23
38 let t15 = t4 * t0; // 10: 25
39 let t9 = t2 * t7; // 11: 27
40 let t3 = t5 * t0; // 12: 29
41 let t18 = t15 * t0; // 13: 33
42 let t1 = t9 * t0; // 14: 35
43 let t6 = t3 * t0; // 15: 37
44 let t16 = t18 * t0; // 16: 41
45 let t11 = t6 * t0; // 17: 45
46 let t12 = t16 * t0; // 18: 49
47 let t19 = t12 * t10; // 19: 51
48 let t17 = t11 * t0; // 20: 53
49 let t13 = t19 * t7; // 21: 55
50 let t10 = t12 * t0; // 22: 57
51 let t7 = t17 * t0; // 23: 61
52 let mut t0 = t7.square(); // 24: 122
53 t0 = t0.square(); // 25: 244
54 t0 = t0.square(); // 26: 488
55 t0 = t0.square(); // 27: 976
56 t0 = t0.square(); // 28: 1952
57 t0 = t0.square(); // 29: 3904
58 t0 = t0.square(); // 30: 7808
59 t0 = t0.square(); // 31: 15616
60 t0 = t0.square(); // 32: 31232
61 t0 *= t19; // 33: 31283
62 t0 = t0.square(); // 34: 62566
63 t0 = t0.square(); // 35: 125132
64 t0 = t0.square(); // 36: 250264
65 t0 = t0.square(); // 37: 500528
66 t0 *= t14; // 38: 500533
67 t0 = t0.square(); // 39: 1001066
68 t0 = t0.square(); // 40: 2002132
69 t0 = t0.square(); // 41: 4004264
70 t0 = t0.square(); // 42: 8008528
71 t0 = t0.square(); // 43: 16017056
72 t0 = t0.square(); // 44: 32034112
73 t0 = t0.square(); // 45: 64068224
74 t0 = t0.square(); // 46: 128136448
75 t0 *= t9; // 47: 128136475
76 t0 = t0.square(); // 48: 256272950
77 t0 = t0.square(); // 49: 512545900
78 t0 = t0.square(); // 50: 1025091800
79 t0 = t0.square(); // 51: 2050183600
80 t0 = t0.square(); // 52: 4100367200
81 t0 = t0.square(); // 53: 8200734400
82 t0 = t0.square(); // 54: 16401468800
83 t0 = t0.square(); // 55: 32802937600
84 t0 = t0.square(); // 56: 65605875200
85 t0 *= t18; // 57: 65605875233
86 t0 = t0.square(); // 58: 131211750466
87 t0 = t0.square(); // 59: 262423500932
88 t0 = t0.square(); // 60: 524847001864
89 t0 = t0.square(); // 61: 1049694003728
90 t0 = t0.square(); // 62: 2099388007456
91 t0 = t0.square(); // 63: 4198776014912
92 t0 = t0.square(); // 64: 8397552029824
93 t0 = t0.square(); // 65: 16795104059648
94 t0 = t0.square(); // 66: 33590208119296
95 t0 = t0.square(); // 67: 67180416238592
96 t0 *= t17; // 68: 67180416238645
97 t0 = t0.square(); // 69: 134360832477290
98 t0 = t0.square(); // 70: 268721664954580
99 t0 = t0.square(); // 71: 537443329909160
100 t0 = t0.square(); // 72: 1074886659818320
101 t0 = t0.square(); // 73: 2149773319636640
102 t0 = t0.square(); // 74: 4299546639273280
103 t0 = t0.square(); // 75: 8599093278546560
104 t0 = t0.square(); // 76: 17198186557093120
105 t0 = t0.square(); // 77: 34396373114186240
106 t0 = t0.square(); // 78: 68792746228372480
107 t0 *= t2; // 79: 68792746228372503
108 t0 = t0.square(); // 80: 137585492456745006
109 t0 = t0.square(); // 81: 275170984913490012
110 t0 = t0.square(); // 82: 550341969826980024
111 t0 = t0.square(); // 83: 1100683939653960048
112 t0 = t0.square(); // 84: 2201367879307920096
113 t0 = t0.square(); // 85: 4402735758615840192
114 t0 = t0.square(); // 86: 8805471517231680384
115 t0 *= t16; // 87: 8805471517231680425
116 t0 = t0.square(); // 88: 17610943034463360850
117 t0 = t0.square(); // 89: 35221886068926721700
118 t0 = t0.square(); // 90: 70443772137853443400
119 t0 = t0.square(); // 91: 140887544275706886800
120 t0 = t0.square(); // 92: 281775088551413773600
121 t0 *= t2; // 93: 281775088551413773623
122 t0 = t0.square(); // 94: 563550177102827547246
123 t0 = t0.square(); // 95: 1127100354205655094492
124 t0 = t0.square(); // 96: 2254200708411310188984
125 t0 = t0.square(); // 97: 4508401416822620377968
126 t0 = t0.square(); // 98: 9016802833645240755936
127 t0 *= t9; // 99: 9016802833645240755963
128 t0 = t0.square(); // 100: 18033605667290481511926
129 t0 = t0.square(); // 101: 36067211334580963023852
130 t0 = t0.square(); // 102: 72134422669161926047704
131 t0 = t0.square(); // 103: 144268845338323852095408
132 t0 = t0.square(); // 104: 288537690676647704190816
133 t0 = t0.square(); // 105: 577075381353295408381632
134 t0 = t0.square(); // 106: 1154150762706590816763264
135 t0 *= t5; // 107: 1154150762706590816763285
136 t0 = t0.square(); // 108: 2308301525413181633526570
137 t0 = t0.square(); // 109: 4616603050826363267053140
138 t0 = t0.square(); // 110: 9233206101652726534106280
139 t0 = t0.square(); // 111: 18466412203305453068212560
140 t0 = t0.square(); // 112: 36932824406610906136425120
141 t0 = t0.square(); // 113: 73865648813221812272850240
142 t0 *= t15; // 114: 73865648813221812272850265
143 t0 = t0.square(); // 115: 147731297626443624545700530
144 t0 = t0.square(); // 116: 295462595252887249091401060
145 t0 = t0.square(); // 117: 590925190505774498182802120
146 t0 = t0.square(); // 118: 1181850381011548996365604240
147 t0 = t0.square(); // 119: 2363700762023097992731208480
148 t0 = t0.square(); // 120: 4727401524046195985462416960
149 t0 = t0.square(); // 121: 9454803048092391970924833920
150 t0 *= t7; // 122: 9454803048092391970924833981
151 t0 = t0.square(); // 123: 18909606096184783941849667962
152 t0 = t0.square(); // 124: 37819212192369567883699335924
153 t0 = t0.square(); // 125: 75638424384739135767398671848
154 t0 = t0.square(); // 126: 151276848769478271534797343696
155 t0 *= t14; // 127: 151276848769478271534797343701
156 t0 = t0.square(); // 128: 302553697538956543069594687402
157 t0 = t0.square(); // 129: 605107395077913086139189374804
158 t0 = t0.square(); // 130: 1210214790155826172278378749608
159 t0 = t0.square(); // 131: 2420429580311652344556757499216
160 t0 = t0.square(); // 132: 4840859160623304689113514998432
161 t0 = t0.square(); // 133: 9681718321246609378227029996864
162 t0 = t0.square(); // 134: 19363436642493218756454059993728
163 t0 = t0.square(); // 135: 38726873284986437512908119987456
164 t0 *= t4; // 136: 38726873284986437512908119987473
165 t0 = t0.square(); // 137: 77453746569972875025816239974946
166 t0 = t0.square(); // 138: 154907493139945750051632479949892
167 t0 = t0.square(); // 139: 309814986279891500103264959899784
168 t0 = t0.square(); // 140: 619629972559783000206529919799568
169 t0 = t0.square(); // 141: 1239259945119566000413059839599136
170 t0 = t0.square(); // 142: 2478519890239132000826119679198272
171 t0 *= t5; // 143: 2478519890239132000826119679198293
172 t0 = t0.square(); // 144: 4957039780478264001652239358396586
173 t0 = t0.square(); // 145: 9914079560956528003304478716793172
174 t0 = t0.square(); // 146: 19828159121913056006608957433586344
175 t0 = t0.square(); // 147: 39656318243826112013217914867172688
176 t0 = t0.square(); // 148: 79312636487652224026435829734345376
177 t0 = t0.square(); // 149: 158625272975304448052871659468690752
178 t0 = t0.square(); // 150: 317250545950608896105743318937381504
179 t0 *= t3; // 151: 317250545950608896105743318937381533
180 t0 = t0.square(); // 152: 634501091901217792211486637874763066
181 t0 = t0.square(); // 153: 1269002183802435584422973275749526132
182 t0 = t0.square(); // 154: 2538004367604871168845946551499052264
183 t0 = t0.square(); // 155: 5076008735209742337691893102998104528
184 t0 = t0.square(); // 156: 10152017470419484675383786205996209056
185 t0 = t0.square(); // 157: 20304034940838969350767572411992418112
186 t0 = t0.square(); // 158: 40608069881677938701535144823984836224
187 t0 = t0.square(); // 159: 81216139763355877403070289647969672448
188 t0 = t0.square(); // 160: 162432279526711754806140579295939344896
189 t0 *= t13; // 161: 162432279526711754806140579295939344951
190 t0 = t0.square(); // 162: 324864559053423509612281158591878689902
191 t0 = t0.square(); // 163: 649729118106847019224562317183757379804
192 t0 = t0.square(); // 164: 1299458236213694038449124634367514759608
193 t0 = t0.square(); // 165: 2598916472427388076898249268735029519216
194 t0 = t0.square(); // 166: 5197832944854776153796498537470059038432
195 t0 = t0.square(); // 167: 10395665889709552307592997074940118076864
196 t0 = t0.square(); // 168: 20791331779419104615185994149880236153728
197 t0 *= t12; // 169: 20791331779419104615185994149880236153777
198 t0 = t0.square(); // 170: 41582663558838209230371988299760472307554
199 t0 = t0.square(); // 171: 83165327117676418460743976599520944615108
200 t0 = t0.square(); // 172: 166330654235352836921487953199041889230216
201 t0 = t0.square(); // 173: 332661308470705673842975906398083778460432
202 t0 = t0.square(); // 174: 665322616941411347685951812796167556920864
203 t0 = t0.square(); // 175: 1330645233882822695371903625592335113841728
204 t0 = t0.square(); // 176: 2661290467765645390743807251184670227683456
205 t0 = t0.square(); // 177: 5322580935531290781487614502369340455366912
206 t0 = t0.square(); // 178: 10645161871062581562975229004738680910733824
207 t0 *= t11; // 179: 10645161871062581562975229004738680910733869
208 t0 = t0.square(); // 180: 21290323742125163125950458009477361821467738
209 t0 = t0.square(); // 181: 42580647484250326251900916018954723642935476
210 t0 = t0.square(); // 182: 85161294968500652503801832037909447285870952
211 t0 = t0.square(); // 183: 170322589937001305007603664075818894571741904
212 t0 = t0.square(); // 184: 340645179874002610015207328151637789143483808
213 t0 = t0.square(); // 185: 681290359748005220030414656303275578286967616
214 t0 = t0.square(); // 186: 1362580719496010440060829312606551156573935232
215 t0 = t0.square(); // 187: 2725161438992020880121658625213102313147870464
216 t0 *= t10; // 188: 2725161438992020880121658625213102313147870521
217 t0 = t0.square(); // 189: 5450322877984041760243317250426204626295741042
218 t0 = t0.square(); // 190: 10900645755968083520486634500852409252591482084
219 t0 = t0.square(); // 191: 21801291511936167040973269001704818505182964168
220 t0 = t0.square(); // 192: 43602583023872334081946538003409637010365928336
221 t0 = t0.square(); // 193: 87205166047744668163893076006819274020731856672
222 t0 = t0.square(); // 194: 174410332095489336327786152013638548041463713344
223 t0 *= t9; // 195: 174410332095489336327786152013638548041463713371
224 t0 = t0.square(); // 196: 348820664190978672655572304027277096082927426742
225 t0 = t0.square(); // 197: 697641328381957345311144608054554192165854853484
226 t0 = t0.square(); // 198: 1395282656763914690622289216109108384331709706968
227 t0 = t0.square(); // 199: 2790565313527829381244578432218216768663419413936
228 t0 = t0.square(); // 200: 5581130627055658762489156864436433537326838827872
229 t0 = t0.square(); // 201: 11162261254111317524978313728872867074653677655744
230 t0 *= t8; // 202: 11162261254111317524978313728872867074653677655753
231 t0 = t0.square(); // 203: 22324522508222635049956627457745734149307355311506
232 t0 = t0.square(); // 204: 44649045016445270099913254915491468298614710623012
233 t0 = t0.square(); // 205: 89298090032890540199826509830982936597229421246024
234 t0 = t0.square(); // 206: 178596180065781080399653019661965873194458842492048
235 t0 = t0.square(); // 207: 357192360131562160799306039323931746388917684984096
236 t0 = t0.square(); // 208: 714384720263124321598612078647863492777835369968192
237 t0 *= t3; // 209: 714384720263124321598612078647863492777835369968221
238 t0 = t0.square(); // 210: 1428769440526248643197224157295726985555670739936442
239 t0 = t0.square(); // 211: 2857538881052497286394448314591453971111341479872884
240 t0 = t0.square(); // 212: 5715077762104994572788896629182907942222682959745768
241 t0 = t0.square(); // 213: 11430155524209989145577793258365815884445365919491536
242 t0 = t0.square(); // 214: 22860311048419978291155586516731631768890731838983072
243 t0 = t0.square(); // 215: 45720622096839956582311173033463263537781463677966144
244 t0 = t0.square(); // 216: 91441244193679913164622346066926527075562927355932288
245 t0 = t0.square(); // 217: 182882488387359826329244692133853054151125854711864576
246 t0 *= t2; // 218: 182882488387359826329244692133853054151125854711864599
247 t0 = t0.square(); // 219: 365764976774719652658489384267706108302251709423729198
248 t0 = t0.square(); // 220: 731529953549439305316978768535412216604503418847458396
249 t0 = t0.square(); // 221: 1463059907098878610633957537070824433209006837694916792
250 t0 = t0.square(); // 222: 2926119814197757221267915074141648866418013675389833584
251 t0 = t0.square(); // 223: 5852239628395514442535830148283297732836027350779667168
252 t0 = t0.square(); // 224: 11704479256791028885071660296566595465672054701559334336
253 t0 *= t4; // 225: 11704479256791028885071660296566595465672054701559334353
254 t0 = t0.square(); // 226: 23408958513582057770143320593133190931344109403118668706
255 t0 = t0.square(); // 227: 46817917027164115540286641186266381862688218806237337412
256 t0 = t0.square(); // 228: 93635834054328231080573282372532763725376437612474674824
257 t0 = t0.square(); // 229: 187271668108656462161146564745065527450752875224949349648
258 t0 = t0.square(); // 230: 374543336217312924322293129490131054901505750449898699296
259 t0 = t0.square(); // 231: 749086672434625848644586258980262109803011500899797398592
260 t0 = t0.square(); // 232: 1498173344869251697289172517960524219606023001799594797184
261 t0 *= t7; // 233: 1498173344869251697289172517960524219606023001799594797245
262 t0 = t0.square(); // 234: 2996346689738503394578345035921048439212046003599189594490
263 t0 = t0.square(); // 235: 5992693379477006789156690071842096878424092007198379188980
264 t0 = t0.square(); // 236: 11985386758954013578313380143684193756848184014396758377960
265 t0 = t0.square(); // 237: 23970773517908027156626760287368387513696368028793516755920
266 t0 = t0.square(); // 238: 47941547035816054313253520574736775027392736057587033511840
267 t0 = t0.square(); // 239: 95883094071632108626507041149473550054785472115174067023680
268 t0 *= t6; // 240: 95883094071632108626507041149473550054785472115174067023717
269 t0 = t0.square(); // 241: 191766188143264217253014082298947100109570944230348134047434
270 t0 = t0.square(); // 242: 383532376286528434506028164597894200219141888460696268094868
271 t0 = t0.square(); // 243: 767064752573056869012056329195788400438283776921392536189736
272 t0 = t0.square(); // 244: 1534129505146113738024112658391576800876567553842785072379472
273 t0 = t0.square(); // 245: 3068259010292227476048225316783153601753135107685570144758944
274 t0 = t0.square(); // 246: 6136518020584454952096450633566307203506270215371140289517888
275 t0 *= t5; // 247: 6136518020584454952096450633566307203506270215371140289517909
276 t0 = t0.square(); // 248: 12273036041168909904192901267132614407012540430742280579035818
277 t0 = t0.square(); // 249: 24546072082337819808385802534265228814025080861484561158071636
278 t0 = t0.square(); // 250: 49092144164675639616771605068530457628050161722969122316143272
279 t0 = t0.square(); // 251: 98184288329351279233543210137060915256100323445938244632286544
280 t0 = t0.square(); // 252: 196368576658702558467086420274121830512200646891876489264573088
281 t0 = t0.square(); // 253: 392737153317405116934172840548243661024401293783752978529146176
282 t0 = t0.square(); // 254: 785474306634810233868345681096487322048802587567505957058292352
283 t0 = t0.square(); // 255: 1570948613269620467736691362192974644097605175135011914116584704
284 t0 = t0.square(); // 256: 3141897226539240935473382724385949288195210350270023828233169408
285 t0 *= t4; // 257: 3141897226539240935473382724385949288195210350270023828233169425
286 t0 = t0.square(); // 258: 6283794453078481870946765448771898576390420700540047656466338850
287 t0 = t0.square(); // 259: 12567588906156963741893530897543797152780841401080095312932677700
288 t0 = t0.square(); // 260: 25135177812313927483787061795087594305561682802160190625865355400
289 t0 = t0.square(); // 261: 50270355624627854967574123590175188611123365604320381251730710800
290 t0 = t0.square(); // 262: 100540711249255709935148247180350377222246731208640762503461421600
291 t0 = t0.square(); // 263: 201081422498511419870296494360700754444493462417281525006922843200
292 t0 *= t3; // 264: 201081422498511419870296494360700754444493462417281525006922843229
293 t0 = t0.square(); // 265: 402162844997022839740592988721401508888986924834563050013845686458
294 t0 = t0.square(); // 266: 804325689994045679481185977442803017777973849669126100027691372916
295 t0 = t0.square(); // 267: 1608651379988091358962371954885606035555947699338252200055382745832
296 t0 = t0.square(); // 268: 3217302759976182717924743909771212071111895398676504400110765491664
297 t0 = t0.square(); // 269: 6434605519952365435849487819542424142223790797353008800221530983328
298 t0 = t0.square(); // 270: 12869211039904730871698975639084848284447581594706017600443061966656
299 t0 = t0.square(); // 271: 25738422079809461743397951278169696568895163189412035200886123933312
300 t0 = t0.square(); // 272: 51476844159618923486795902556339393137790326378824070401772247866624
301 t0 *= t2; // 273: 51476844159618923486795902556339393137790326378824070401772247866647
302 t0 = t0.square(); // 274: 102953688319237846973591805112678786275580652757648140803544495733294
303 t0 = t0.square(); // 275: 205907376638475693947183610225357572551161305515296281607088991466588
304 t0 = t0.square(); // 276: 411814753276951387894367220450715145102322611030592563214177982933176
305 t0 = t0.square(); // 277: 823629506553902775788734440901430290204645222061185126428355965866352
306 t0 = t0.square(); // 278: 1647259013107805551577468881802860580409290444122370252856711931732704
307 t0 = t0.square(); // 279: 3294518026215611103154937763605721160818580888244740505713423863465408
308 t0 *= t4; // 280: 3294518026215611103154937763605721160818580888244740505713423863465425
309 t0 = t0.square(); // 281: 6589036052431222206309875527211442321637161776489481011426847726930850
310 t0 = t0.square(); // 282: 13178072104862444412619751054422884643274323552978962022853695453861700
311 t0 = t0.square(); // 283: 26356144209724888825239502108845769286548647105957924045707390907723400
312 t0 = t0.square(); // 284: 52712288419449777650479004217691538573097294211915848091414781815446800
313 t0 = t0.square(); // 285: 105424576838899555300958008435383077146194588423831696182829563630893600
314 t0 = t0.square(); // 286: 210849153677799110601916016870766154292389176847663392365659127261787200
315 t0 *= t3; // 287: 210849153677799110601916016870766154292389176847663392365659127261787229
316 t0 = t0.square(); // 288: 421698307355598221203832033741532308584778353695326784731318254523574458
317 t0 = t0.square(); // 289: 843396614711196442407664067483064617169556707390653569462636509047148916
318 t0 = t0.square(); // 290: 1686793229422392884815328134966129234339113414781307138925273018094297832
319 t0 = t0.square(); // 291: 3373586458844785769630656269932258468678226829562614277850546036188595664
320 t0 = t0.square(); // 292: 6747172917689571539261312539864516937356453659125228555701092072377191328
321 t0 = t0.square(); // 293: 13494345835379143078522625079729033874712907318250457111402184144754382656
322 t0 = t0.square(); // 294: 26988691670758286157045250159458067749425814636500914222804368289508765312
323 t0 = t0.square(); // 295: 53977383341516572314090500318916135498851629273001828445608736579017530624
324 t0 *= t2; // 296: 53977383341516572314090500318916135498851629273001828445608736579017530647
325 t0 = t0.square(); // 297: 107954766683033144628181000637832270997703258546003656891217473158035061294
326 t0 = t0.square(); // 298: 215909533366066289256362001275664541995406517092007313782434946316070122588
327 t0 = t0.square(); // 299: 431819066732132578512724002551329083990813034184014627564869892632140245176
328 t0 = t0.square(); // 300: 863638133464265157025448005102658167981626068368029255129739785264280490352
329 t0 = t0.square(); // 301: 1727276266928530314050896010205316335963252136736058510259479570528560980704
330 t0 = t0.square(); // 302: 3454552533857060628101792020410632671926504273472117020518959141057121961408
331 t0 = t0.square(); // 303: 6909105067714121256203584040821265343853008546944234041037918282114243922816
332 t0 * t1 // 304: 6909105067714121256203584040821265343853008546944234041037918282114243922851
333}
334
335#[cfg(test)]
336mod tests {
337 use super::*;
338 use ark_ff::One;
339 use ark_ff::PrimeField;
340
341 #[test]
342 fn test_alpha() {
343 let mut a = -Felt::one();
344 for _ in 0..100 {
345 assert_eq!(exp_by_inv_alpha(&a), a.pow(INV_ALPHA.into_bigint()));
346 a += a;
347 }
348 }
349}