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}