github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-378/fp/element_exp.go (about)

     1  // Copyright 2020 ConsenSys Software Inc.
     2  //
     3  // Licensed under the Apache License, Version 2.0 (the "License");
     4  // you may not use this file except in compliance with the License.
     5  // You may obtain a copy of the License at
     6  //
     7  //     http://www.apache.org/licenses/LICENSE-2.0
     8  //
     9  // Unless required by applicable law or agreed to in writing, software
    10  // distributed under the License is distributed on an "AS IS" BASIS,
    11  // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    12  // See the License for the specific language governing permissions and
    13  // limitations under the License.
    14  
    15  // Code generated by consensys/gnark-crypto DO NOT EDIT
    16  
    17  package fp
    18  
    19  // expBySqrtExp is equivalent to z.Exp(x, fbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d83429275ff3a5fddaa08b0000265228)
    20  //
    21  // uses github.com/mmcloughlin/addchain v0.4.0 to generate a shorter addition chain
    22  func (z *Element) expBySqrtExp(x Element) *Element {
    23  	// addition chain:
    24  	//
    25  	//	_10      = 2*1
    26  	//	_11      = 1 + _10
    27  	//	_101     = _10 + _11
    28  	//	_110     = 1 + _101
    29  	//	_1001    = _11 + _110
    30  	//	_1011    = _10 + _1001
    31  	//	_1100    = 1 + _1011
    32  	//	_1101    = 1 + _1100
    33  	//	_10001   = _101 + _1100
    34  	//	_10011   = _10 + _10001
    35  	//	_10101   = _10 + _10011
    36  	//	_11011   = _110 + _10101
    37  	//	_11101   = _10 + _11011
    38  	//	_100011  = _110 + _11101
    39  	//	_100111  = _1100 + _11011
    40  	//	_101001  = _10 + _100111
    41  	//	_110101  = _1100 + _101001
    42  	//	_110111  = _10 + _110101
    43  	//	_111001  = _10 + _110111
    44  	//	_111011  = _10 + _111001
    45  	//	_111101  = _10 + _111011
    46  	//	_111111  = _10 + _111101
    47  	//	_1111100 = _111101 + _111111
    48  	//	_1111111 = _11 + _1111100
    49  	//	i39      = ((_1111100 << 4 + _11101) << 3 + _11) << 6
    50  	//	i57      = ((1 + i39) << 9 + _1011) << 6 + _1101
    51  	//	i78      = ((i57 << 9 + _10011) << 7 + _100011) << 3
    52  	//	i98      = ((1 + i78) << 11 + _101001) << 6 + _111001
    53  	//	i117     = ((i98 << 7 + _110101) << 4 + _1101) << 6
    54  	//	i138     = ((_1001 + i117) << 12 + _111011) << 6 + _10001
    55  	//	i162     = ((i138 << 11 + _111101) << 6 + _101) << 5
    56  	//	i184     = ((1 + i162) << 11 + _1011) << 8 + _111101
    57  	//	i205     = ((i184 << 6 + _11011) << 8 + _100011) << 5
    58  	//	i227     = ((_10001 + i205) << 12 + _100011) << 7 + _10011
    59  	//	i257     = ((i227 << 6 + _10011) << 13 + _110111) << 9
    60  	//	i279     = ((_11011 + i257) << 9 + _1101) << 10 + _101001
    61  	//	i299     = ((i279 << 8 + _100111) << 2 + 1) << 8
    62  	//	i311     = ((_1111111 + i299) << 2 + _11) << 7 + _11101
    63  	//	i331     = ((i311 << 3 + 1) << 8 + _1111111) << 7
    64  	//	i350     = ((_111011 + i331) << 6 + _10101) << 10 + _10001
    65  	//	i386     = ((i350 << 3 + _11) << 23 + _10011) << 8
    66  	//	return     ((_101001 + i386) << 6 + _101) << 3
    67  	//
    68  	// Operations: 330 squares 67 multiplies
    69  
    70  	// Allocate Temporaries.
    71  	var (
    72  		t0  = new(Element)
    73  		t1  = new(Element)
    74  		t2  = new(Element)
    75  		t3  = new(Element)
    76  		t4  = new(Element)
    77  		t5  = new(Element)
    78  		t6  = new(Element)
    79  		t7  = new(Element)
    80  		t8  = new(Element)
    81  		t9  = new(Element)
    82  		t10 = new(Element)
    83  		t11 = new(Element)
    84  		t12 = new(Element)
    85  		t13 = new(Element)
    86  		t14 = new(Element)
    87  		t15 = new(Element)
    88  		t16 = new(Element)
    89  		t17 = new(Element)
    90  		t18 = new(Element)
    91  	)
    92  
    93  	// var t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18 Element
    94  	// Step 1: t6 = x^0x2
    95  	t6.Square(&x)
    96  
    97  	// Step 2: t2 = x^0x3
    98  	t2.Mul(&x, t6)
    99  
   100  	// Step 3: z = x^0x5
   101  	z.Mul(t6, t2)
   102  
   103  	// Step 4: t0 = x^0x6
   104  	t0.Mul(&x, z)
   105  
   106  	// Step 5: t15 = x^0x9
   107  	t15.Mul(t2, t0)
   108  
   109  	// Step 6: t14 = x^0xb
   110  	t14.Mul(t6, t15)
   111  
   112  	// Step 7: t5 = x^0xc
   113  	t5.Mul(&x, t14)
   114  
   115  	// Step 8: t9 = x^0xd
   116  	t9.Mul(&x, t5)
   117  
   118  	// Step 9: t3 = x^0x11
   119  	t3.Mul(z, t5)
   120  
   121  	// Step 10: t1 = x^0x13
   122  	t1.Mul(t6, t3)
   123  
   124  	// Step 11: t4 = x^0x15
   125  	t4.Mul(t6, t1)
   126  
   127  	// Step 12: t10 = x^0x1b
   128  	t10.Mul(t0, t4)
   129  
   130  	// Step 13: t7 = x^0x1d
   131  	t7.Mul(t6, t10)
   132  
   133  	// Step 14: t12 = x^0x23
   134  	t12.Mul(t0, t7)
   135  
   136  	// Step 15: t8 = x^0x27
   137  	t8.Mul(t5, t10)
   138  
   139  	// Step 16: t0 = x^0x29
   140  	t0.Mul(t6, t8)
   141  
   142  	// Step 17: t16 = x^0x35
   143  	t16.Mul(t5, t0)
   144  
   145  	// Step 18: t11 = x^0x37
   146  	t11.Mul(t6, t16)
   147  
   148  	// Step 19: t17 = x^0x39
   149  	t17.Mul(t6, t11)
   150  
   151  	// Step 20: t5 = x^0x3b
   152  	t5.Mul(t6, t17)
   153  
   154  	// Step 21: t13 = x^0x3d
   155  	t13.Mul(t6, t5)
   156  
   157  	// Step 22: t6 = x^0x3f
   158  	t6.Mul(t6, t13)
   159  
   160  	// Step 23: t18 = x^0x7c
   161  	t18.Mul(t13, t6)
   162  
   163  	// Step 24: t6 = x^0x7f
   164  	t6.Mul(t2, t18)
   165  
   166  	// Step 28: t18 = x^0x7c0
   167  	for s := 0; s < 4; s++ {
   168  		t18.Square(t18)
   169  	}
   170  
   171  	// Step 29: t18 = x^0x7dd
   172  	t18.Mul(t7, t18)
   173  
   174  	// Step 32: t18 = x^0x3ee8
   175  	for s := 0; s < 3; s++ {
   176  		t18.Square(t18)
   177  	}
   178  
   179  	// Step 33: t18 = x^0x3eeb
   180  	t18.Mul(t2, t18)
   181  
   182  	// Step 39: t18 = x^0xfbac0
   183  	for s := 0; s < 6; s++ {
   184  		t18.Square(t18)
   185  	}
   186  
   187  	// Step 40: t18 = x^0xfbac1
   188  	t18.Mul(&x, t18)
   189  
   190  	// Step 49: t18 = x^0x1f758200
   191  	for s := 0; s < 9; s++ {
   192  		t18.Square(t18)
   193  	}
   194  
   195  	// Step 50: t18 = x^0x1f75820b
   196  	t18.Mul(t14, t18)
   197  
   198  	// Step 56: t18 = x^0x7dd6082c0
   199  	for s := 0; s < 6; s++ {
   200  		t18.Square(t18)
   201  	}
   202  
   203  	// Step 57: t18 = x^0x7dd6082cd
   204  	t18.Mul(t9, t18)
   205  
   206  	// Step 66: t18 = x^0xfbac1059a00
   207  	for s := 0; s < 9; s++ {
   208  		t18.Square(t18)
   209  	}
   210  
   211  	// Step 67: t18 = x^0xfbac1059a13
   212  	t18.Mul(t1, t18)
   213  
   214  	// Step 74: t18 = x^0x7dd6082cd0980
   215  	for s := 0; s < 7; s++ {
   216  		t18.Square(t18)
   217  	}
   218  
   219  	// Step 75: t18 = x^0x7dd6082cd09a3
   220  	t18.Mul(t12, t18)
   221  
   222  	// Step 78: t18 = x^0x3eeb0416684d18
   223  	for s := 0; s < 3; s++ {
   224  		t18.Square(t18)
   225  	}
   226  
   227  	// Step 79: t18 = x^0x3eeb0416684d19
   228  	t18.Mul(&x, t18)
   229  
   230  	// Step 90: t18 = x^0x1f75820b34268c800
   231  	for s := 0; s < 11; s++ {
   232  		t18.Square(t18)
   233  	}
   234  
   235  	// Step 91: t18 = x^0x1f75820b34268c829
   236  	t18.Mul(t0, t18)
   237  
   238  	// Step 97: t18 = x^0x7dd6082cd09a320a40
   239  	for s := 0; s < 6; s++ {
   240  		t18.Square(t18)
   241  	}
   242  
   243  	// Step 98: t17 = x^0x7dd6082cd09a320a79
   244  	t17.Mul(t17, t18)
   245  
   246  	// Step 105: t17 = x^0x3eeb0416684d19053c80
   247  	for s := 0; s < 7; s++ {
   248  		t17.Square(t17)
   249  	}
   250  
   251  	// Step 106: t16 = x^0x3eeb0416684d19053cb5
   252  	t16.Mul(t16, t17)
   253  
   254  	// Step 110: t16 = x^0x3eeb0416684d19053cb50
   255  	for s := 0; s < 4; s++ {
   256  		t16.Square(t16)
   257  	}
   258  
   259  	// Step 111: t16 = x^0x3eeb0416684d19053cb5d
   260  	t16.Mul(t9, t16)
   261  
   262  	// Step 117: t16 = x^0xfbac1059a1346414f2d740
   263  	for s := 0; s < 6; s++ {
   264  		t16.Square(t16)
   265  	}
   266  
   267  	// Step 118: t15 = x^0xfbac1059a1346414f2d749
   268  	t15.Mul(t15, t16)
   269  
   270  	// Step 130: t15 = x^0xfbac1059a1346414f2d749000
   271  	for s := 0; s < 12; s++ {
   272  		t15.Square(t15)
   273  	}
   274  
   275  	// Step 131: t15 = x^0xfbac1059a1346414f2d74903b
   276  	t15.Mul(t5, t15)
   277  
   278  	// Step 137: t15 = x^0x3eeb0416684d19053cb5d240ec0
   279  	for s := 0; s < 6; s++ {
   280  		t15.Square(t15)
   281  	}
   282  
   283  	// Step 138: t15 = x^0x3eeb0416684d19053cb5d240ed1
   284  	t15.Mul(t3, t15)
   285  
   286  	// Step 149: t15 = x^0x1f75820b34268c829e5ae920768800
   287  	for s := 0; s < 11; s++ {
   288  		t15.Square(t15)
   289  	}
   290  
   291  	// Step 150: t15 = x^0x1f75820b34268c829e5ae92076883d
   292  	t15.Mul(t13, t15)
   293  
   294  	// Step 156: t15 = x^0x7dd6082cd09a320a796ba481da20f40
   295  	for s := 0; s < 6; s++ {
   296  		t15.Square(t15)
   297  	}
   298  
   299  	// Step 157: t15 = x^0x7dd6082cd09a320a796ba481da20f45
   300  	t15.Mul(z, t15)
   301  
   302  	// Step 162: t15 = x^0xfbac1059a1346414f2d74903b441e8a0
   303  	for s := 0; s < 5; s++ {
   304  		t15.Square(t15)
   305  	}
   306  
   307  	// Step 163: t15 = x^0xfbac1059a1346414f2d74903b441e8a1
   308  	t15.Mul(&x, t15)
   309  
   310  	// Step 174: t15 = x^0x7dd6082cd09a320a796ba481da20f450800
   311  	for s := 0; s < 11; s++ {
   312  		t15.Square(t15)
   313  	}
   314  
   315  	// Step 175: t14 = x^0x7dd6082cd09a320a796ba481da20f45080b
   316  	t14.Mul(t14, t15)
   317  
   318  	// Step 183: t14 = x^0x7dd6082cd09a320a796ba481da20f45080b00
   319  	for s := 0; s < 8; s++ {
   320  		t14.Square(t14)
   321  	}
   322  
   323  	// Step 184: t13 = x^0x7dd6082cd09a320a796ba481da20f45080b3d
   324  	t13.Mul(t13, t14)
   325  
   326  	// Step 190: t13 = x^0x1f75820b34268c829e5ae92076883d14202cf40
   327  	for s := 0; s < 6; s++ {
   328  		t13.Square(t13)
   329  	}
   330  
   331  	// Step 191: t13 = x^0x1f75820b34268c829e5ae92076883d14202cf5b
   332  	t13.Mul(t10, t13)
   333  
   334  	// Step 199: t13 = x^0x1f75820b34268c829e5ae92076883d14202cf5b00
   335  	for s := 0; s < 8; s++ {
   336  		t13.Square(t13)
   337  	}
   338  
   339  	// Step 200: t13 = x^0x1f75820b34268c829e5ae92076883d14202cf5b23
   340  	t13.Mul(t12, t13)
   341  
   342  	// Step 205: t13 = x^0x3eeb0416684d19053cb5d240ed107a284059eb6460
   343  	for s := 0; s < 5; s++ {
   344  		t13.Square(t13)
   345  	}
   346  
   347  	// Step 206: t13 = x^0x3eeb0416684d19053cb5d240ed107a284059eb6471
   348  	t13.Mul(t3, t13)
   349  
   350  	// Step 218: t13 = x^0x3eeb0416684d19053cb5d240ed107a284059eb6471000
   351  	for s := 0; s < 12; s++ {
   352  		t13.Square(t13)
   353  	}
   354  
   355  	// Step 219: t12 = x^0x3eeb0416684d19053cb5d240ed107a284059eb6471023
   356  	t12.Mul(t12, t13)
   357  
   358  	// Step 226: t12 = x^0x1f75820b34268c829e5ae92076883d14202cf5b23881180
   359  	for s := 0; s < 7; s++ {
   360  		t12.Square(t12)
   361  	}
   362  
   363  	// Step 227: t12 = x^0x1f75820b34268c829e5ae92076883d14202cf5b23881193
   364  	t12.Mul(t1, t12)
   365  
   366  	// Step 233: t12 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464c0
   367  	for s := 0; s < 6; s++ {
   368  		t12.Square(t12)
   369  	}
   370  
   371  	// Step 234: t12 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d3
   372  	t12.Mul(t1, t12)
   373  
   374  	// Step 247: t12 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a6000
   375  	for s := 0; s < 13; s++ {
   376  		t12.Square(t12)
   377  	}
   378  
   379  	// Step 248: t11 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a6037
   380  	t11.Mul(t11, t12)
   381  
   382  	// Step 257: t11 = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e00
   383  	for s := 0; s < 9; s++ {
   384  		t11.Square(t11)
   385  	}
   386  
   387  	// Step 258: t10 = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b
   388  	t10.Mul(t10, t11)
   389  
   390  	// Step 267: t10 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc3600
   391  	for s := 0; s < 9; s++ {
   392  		t10.Square(t10)
   393  	}
   394  
   395  	// Step 268: t9 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d
   396  	t9.Mul(t9, t10)
   397  
   398  	// Step 278: t9 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d83400
   399  	for s := 0; s < 10; s++ {
   400  		t9.Square(t9)
   401  	}
   402  
   403  	// Step 279: t9 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d83429
   404  	t9.Mul(t0, t9)
   405  
   406  	// Step 287: t9 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d8342900
   407  	for s := 0; s < 8; s++ {
   408  		t9.Square(t9)
   409  	}
   410  
   411  	// Step 288: t8 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d8342927
   412  	t8.Mul(t8, t9)
   413  
   414  	// Step 290: t8 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49c
   415  	for s := 0; s < 2; s++ {
   416  		t8.Square(t8)
   417  	}
   418  
   419  	// Step 291: t8 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d
   420  	t8.Mul(&x, t8)
   421  
   422  	// Step 299: t8 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d00
   423  	for s := 0; s < 8; s++ {
   424  		t8.Square(t8)
   425  	}
   426  
   427  	// Step 300: t8 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d7f
   428  	t8.Mul(t6, t8)
   429  
   430  	// Step 302: t8 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d83429275fc
   431  	for s := 0; s < 2; s++ {
   432  		t8.Square(t8)
   433  	}
   434  
   435  	// Step 303: t8 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d83429275ff
   436  	t8.Mul(t2, t8)
   437  
   438  	// Step 310: t8 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff80
   439  	for s := 0; s < 7; s++ {
   440  		t8.Square(t8)
   441  	}
   442  
   443  	// Step 311: t7 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff9d
   444  	t7.Mul(t7, t8)
   445  
   446  	// Step 314: t7 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d7fce8
   447  	for s := 0; s < 3; s++ {
   448  		t7.Square(t7)
   449  	}
   450  
   451  	// Step 315: t7 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d7fce9
   452  	t7.Mul(&x, t7)
   453  
   454  	// Step 323: t7 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d7fce900
   455  	for s := 0; s < 8; s++ {
   456  		t7.Square(t7)
   457  	}
   458  
   459  	// Step 324: t6 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d7fce97f
   460  	t6.Mul(t6, t7)
   461  
   462  	// Step 331: t6 = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bf80
   463  	for s := 0; s < 7; s++ {
   464  		t6.Square(t6)
   465  	}
   466  
   467  	// Step 332: t5 = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bfbb
   468  	t5.Mul(t5, t6)
   469  
   470  	// Step 338: t5 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff9d2feec0
   471  	for s := 0; s < 6; s++ {
   472  		t5.Square(t5)
   473  	}
   474  
   475  	// Step 339: t4 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff9d2feed5
   476  	t4.Mul(t4, t5)
   477  
   478  	// Step 349: t4 = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bfbb5400
   479  	for s := 0; s < 10; s++ {
   480  		t4.Square(t4)
   481  	}
   482  
   483  	// Step 350: t3 = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bfbb5411
   484  	t3.Mul(t3, t4)
   485  
   486  	// Step 353: t3 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d83429275ff3a5fddaa088
   487  	for s := 0; s < 3; s++ {
   488  		t3.Square(t3)
   489  	}
   490  
   491  	// Step 354: t2 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d83429275ff3a5fddaa08b
   492  	t2.Mul(t2, t3)
   493  
   494  	// Step 377: t2 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff9d2feed5045800000
   495  	for s := 0; s < 23; s++ {
   496  		t2.Square(t2)
   497  	}
   498  
   499  	// Step 378: t1 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff9d2feed5045800013
   500  	t1.Mul(t1, t2)
   501  
   502  	// Step 386: t1 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff9d2feed504580001300
   503  	for s := 0; s < 8; s++ {
   504  		t1.Square(t1)
   505  	}
   506  
   507  	// Step 387: t0 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff9d2feed504580001329
   508  	t0.Mul(t0, t1)
   509  
   510  	// Step 393: t0 = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bfbb5411600004ca40
   511  	for s := 0; s < 6; s++ {
   512  		t0.Square(t0)
   513  	}
   514  
   515  	// Step 394: z = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bfbb5411600004ca45
   516  	z.Mul(z, t0)
   517  
   518  	// Step 397: z = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d83429275ff3a5fddaa08b0000265228
   519  	for s := 0; s < 3; s++ {
   520  		z.Square(z)
   521  	}
   522  
   523  	return z
   524  }
   525  
   526  // expByLegendreExp is equivalent to z.Exp(x, 1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bfbb5411600004ca4510000000000)
   527  //
   528  // uses github.com/mmcloughlin/addchain v0.4.0 to generate a shorter addition chain
   529  func (z *Element) expByLegendreExp(x Element) *Element {
   530  	// addition chain:
   531  	//
   532  	//	_10      = 2*1
   533  	//	_11      = 1 + _10
   534  	//	_101     = _10 + _11
   535  	//	_110     = 1 + _101
   536  	//	_1001    = _11 + _110
   537  	//	_1011    = _10 + _1001
   538  	//	_1100    = 1 + _1011
   539  	//	_1101    = 1 + _1100
   540  	//	_10001   = _101 + _1100
   541  	//	_10011   = _10 + _10001
   542  	//	_10101   = _10 + _10011
   543  	//	_11011   = _110 + _10101
   544  	//	_11101   = _10 + _11011
   545  	//	_100011  = _110 + _11101
   546  	//	_100111  = _1100 + _11011
   547  	//	_101001  = _10 + _100111
   548  	//	_110101  = _1100 + _101001
   549  	//	_110111  = _10 + _110101
   550  	//	_111001  = _10 + _110111
   551  	//	_111011  = _10 + _111001
   552  	//	_111101  = _10 + _111011
   553  	//	_111111  = _10 + _111101
   554  	//	_1111100 = _111101 + _111111
   555  	//	_1111111 = _11 + _1111100
   556  	//	i39      = ((_1111100 << 4 + _11101) << 3 + _11) << 6
   557  	//	i57      = ((1 + i39) << 9 + _1011) << 6 + _1101
   558  	//	i78      = ((i57 << 9 + _10011) << 7 + _100011) << 3
   559  	//	i98      = ((1 + i78) << 11 + _101001) << 6 + _111001
   560  	//	i117     = ((i98 << 7 + _110101) << 4 + _1101) << 6
   561  	//	i138     = ((_1001 + i117) << 12 + _111011) << 6 + _10001
   562  	//	i162     = ((i138 << 11 + _111101) << 6 + _101) << 5
   563  	//	i184     = ((1 + i162) << 11 + _1011) << 8 + _111101
   564  	//	i205     = ((i184 << 6 + _11011) << 8 + _100011) << 5
   565  	//	i227     = ((_10001 + i205) << 12 + _100011) << 7 + _10011
   566  	//	i257     = ((i227 << 6 + _10011) << 13 + _110111) << 9
   567  	//	i279     = ((_11011 + i257) << 9 + _1101) << 10 + _101001
   568  	//	i299     = ((i279 << 8 + _100111) << 2 + 1) << 8
   569  	//	i311     = ((_1111111 + i299) << 2 + _11) << 7 + _11101
   570  	//	i331     = ((i311 << 3 + 1) << 8 + _1111111) << 7
   571  	//	i350     = ((_111011 + i331) << 6 + _10101) << 10 + _10001
   572  	//	i386     = ((i350 << 3 + _11) << 23 + _10011) << 8
   573  	//	i399     = ((_101001 + i386) << 6 + _101) << 4 + 1
   574  	//	return     i399 << 40
   575  	//
   576  	// Operations: 371 squares 68 multiplies
   577  
   578  	// Allocate Temporaries.
   579  	var (
   580  		t0  = new(Element)
   581  		t1  = new(Element)
   582  		t2  = new(Element)
   583  		t3  = new(Element)
   584  		t4  = new(Element)
   585  		t5  = new(Element)
   586  		t6  = new(Element)
   587  		t7  = new(Element)
   588  		t8  = new(Element)
   589  		t9  = new(Element)
   590  		t10 = new(Element)
   591  		t11 = new(Element)
   592  		t12 = new(Element)
   593  		t13 = new(Element)
   594  		t14 = new(Element)
   595  		t15 = new(Element)
   596  		t16 = new(Element)
   597  		t17 = new(Element)
   598  		t18 = new(Element)
   599  	)
   600  
   601  	// var t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18 Element
   602  	// Step 1: t6 = x^0x2
   603  	t6.Square(&x)
   604  
   605  	// Step 2: t2 = x^0x3
   606  	t2.Mul(&x, t6)
   607  
   608  	// Step 3: z = x^0x5
   609  	z.Mul(t6, t2)
   610  
   611  	// Step 4: t0 = x^0x6
   612  	t0.Mul(&x, z)
   613  
   614  	// Step 5: t15 = x^0x9
   615  	t15.Mul(t2, t0)
   616  
   617  	// Step 6: t14 = x^0xb
   618  	t14.Mul(t6, t15)
   619  
   620  	// Step 7: t5 = x^0xc
   621  	t5.Mul(&x, t14)
   622  
   623  	// Step 8: t9 = x^0xd
   624  	t9.Mul(&x, t5)
   625  
   626  	// Step 9: t3 = x^0x11
   627  	t3.Mul(z, t5)
   628  
   629  	// Step 10: t1 = x^0x13
   630  	t1.Mul(t6, t3)
   631  
   632  	// Step 11: t4 = x^0x15
   633  	t4.Mul(t6, t1)
   634  
   635  	// Step 12: t10 = x^0x1b
   636  	t10.Mul(t0, t4)
   637  
   638  	// Step 13: t7 = x^0x1d
   639  	t7.Mul(t6, t10)
   640  
   641  	// Step 14: t12 = x^0x23
   642  	t12.Mul(t0, t7)
   643  
   644  	// Step 15: t8 = x^0x27
   645  	t8.Mul(t5, t10)
   646  
   647  	// Step 16: t0 = x^0x29
   648  	t0.Mul(t6, t8)
   649  
   650  	// Step 17: t16 = x^0x35
   651  	t16.Mul(t5, t0)
   652  
   653  	// Step 18: t11 = x^0x37
   654  	t11.Mul(t6, t16)
   655  
   656  	// Step 19: t17 = x^0x39
   657  	t17.Mul(t6, t11)
   658  
   659  	// Step 20: t5 = x^0x3b
   660  	t5.Mul(t6, t17)
   661  
   662  	// Step 21: t13 = x^0x3d
   663  	t13.Mul(t6, t5)
   664  
   665  	// Step 22: t6 = x^0x3f
   666  	t6.Mul(t6, t13)
   667  
   668  	// Step 23: t18 = x^0x7c
   669  	t18.Mul(t13, t6)
   670  
   671  	// Step 24: t6 = x^0x7f
   672  	t6.Mul(t2, t18)
   673  
   674  	// Step 28: t18 = x^0x7c0
   675  	for s := 0; s < 4; s++ {
   676  		t18.Square(t18)
   677  	}
   678  
   679  	// Step 29: t18 = x^0x7dd
   680  	t18.Mul(t7, t18)
   681  
   682  	// Step 32: t18 = x^0x3ee8
   683  	for s := 0; s < 3; s++ {
   684  		t18.Square(t18)
   685  	}
   686  
   687  	// Step 33: t18 = x^0x3eeb
   688  	t18.Mul(t2, t18)
   689  
   690  	// Step 39: t18 = x^0xfbac0
   691  	for s := 0; s < 6; s++ {
   692  		t18.Square(t18)
   693  	}
   694  
   695  	// Step 40: t18 = x^0xfbac1
   696  	t18.Mul(&x, t18)
   697  
   698  	// Step 49: t18 = x^0x1f758200
   699  	for s := 0; s < 9; s++ {
   700  		t18.Square(t18)
   701  	}
   702  
   703  	// Step 50: t18 = x^0x1f75820b
   704  	t18.Mul(t14, t18)
   705  
   706  	// Step 56: t18 = x^0x7dd6082c0
   707  	for s := 0; s < 6; s++ {
   708  		t18.Square(t18)
   709  	}
   710  
   711  	// Step 57: t18 = x^0x7dd6082cd
   712  	t18.Mul(t9, t18)
   713  
   714  	// Step 66: t18 = x^0xfbac1059a00
   715  	for s := 0; s < 9; s++ {
   716  		t18.Square(t18)
   717  	}
   718  
   719  	// Step 67: t18 = x^0xfbac1059a13
   720  	t18.Mul(t1, t18)
   721  
   722  	// Step 74: t18 = x^0x7dd6082cd0980
   723  	for s := 0; s < 7; s++ {
   724  		t18.Square(t18)
   725  	}
   726  
   727  	// Step 75: t18 = x^0x7dd6082cd09a3
   728  	t18.Mul(t12, t18)
   729  
   730  	// Step 78: t18 = x^0x3eeb0416684d18
   731  	for s := 0; s < 3; s++ {
   732  		t18.Square(t18)
   733  	}
   734  
   735  	// Step 79: t18 = x^0x3eeb0416684d19
   736  	t18.Mul(&x, t18)
   737  
   738  	// Step 90: t18 = x^0x1f75820b34268c800
   739  	for s := 0; s < 11; s++ {
   740  		t18.Square(t18)
   741  	}
   742  
   743  	// Step 91: t18 = x^0x1f75820b34268c829
   744  	t18.Mul(t0, t18)
   745  
   746  	// Step 97: t18 = x^0x7dd6082cd09a320a40
   747  	for s := 0; s < 6; s++ {
   748  		t18.Square(t18)
   749  	}
   750  
   751  	// Step 98: t17 = x^0x7dd6082cd09a320a79
   752  	t17.Mul(t17, t18)
   753  
   754  	// Step 105: t17 = x^0x3eeb0416684d19053c80
   755  	for s := 0; s < 7; s++ {
   756  		t17.Square(t17)
   757  	}
   758  
   759  	// Step 106: t16 = x^0x3eeb0416684d19053cb5
   760  	t16.Mul(t16, t17)
   761  
   762  	// Step 110: t16 = x^0x3eeb0416684d19053cb50
   763  	for s := 0; s < 4; s++ {
   764  		t16.Square(t16)
   765  	}
   766  
   767  	// Step 111: t16 = x^0x3eeb0416684d19053cb5d
   768  	t16.Mul(t9, t16)
   769  
   770  	// Step 117: t16 = x^0xfbac1059a1346414f2d740
   771  	for s := 0; s < 6; s++ {
   772  		t16.Square(t16)
   773  	}
   774  
   775  	// Step 118: t15 = x^0xfbac1059a1346414f2d749
   776  	t15.Mul(t15, t16)
   777  
   778  	// Step 130: t15 = x^0xfbac1059a1346414f2d749000
   779  	for s := 0; s < 12; s++ {
   780  		t15.Square(t15)
   781  	}
   782  
   783  	// Step 131: t15 = x^0xfbac1059a1346414f2d74903b
   784  	t15.Mul(t5, t15)
   785  
   786  	// Step 137: t15 = x^0x3eeb0416684d19053cb5d240ec0
   787  	for s := 0; s < 6; s++ {
   788  		t15.Square(t15)
   789  	}
   790  
   791  	// Step 138: t15 = x^0x3eeb0416684d19053cb5d240ed1
   792  	t15.Mul(t3, t15)
   793  
   794  	// Step 149: t15 = x^0x1f75820b34268c829e5ae920768800
   795  	for s := 0; s < 11; s++ {
   796  		t15.Square(t15)
   797  	}
   798  
   799  	// Step 150: t15 = x^0x1f75820b34268c829e5ae92076883d
   800  	t15.Mul(t13, t15)
   801  
   802  	// Step 156: t15 = x^0x7dd6082cd09a320a796ba481da20f40
   803  	for s := 0; s < 6; s++ {
   804  		t15.Square(t15)
   805  	}
   806  
   807  	// Step 157: t15 = x^0x7dd6082cd09a320a796ba481da20f45
   808  	t15.Mul(z, t15)
   809  
   810  	// Step 162: t15 = x^0xfbac1059a1346414f2d74903b441e8a0
   811  	for s := 0; s < 5; s++ {
   812  		t15.Square(t15)
   813  	}
   814  
   815  	// Step 163: t15 = x^0xfbac1059a1346414f2d74903b441e8a1
   816  	t15.Mul(&x, t15)
   817  
   818  	// Step 174: t15 = x^0x7dd6082cd09a320a796ba481da20f450800
   819  	for s := 0; s < 11; s++ {
   820  		t15.Square(t15)
   821  	}
   822  
   823  	// Step 175: t14 = x^0x7dd6082cd09a320a796ba481da20f45080b
   824  	t14.Mul(t14, t15)
   825  
   826  	// Step 183: t14 = x^0x7dd6082cd09a320a796ba481da20f45080b00
   827  	for s := 0; s < 8; s++ {
   828  		t14.Square(t14)
   829  	}
   830  
   831  	// Step 184: t13 = x^0x7dd6082cd09a320a796ba481da20f45080b3d
   832  	t13.Mul(t13, t14)
   833  
   834  	// Step 190: t13 = x^0x1f75820b34268c829e5ae92076883d14202cf40
   835  	for s := 0; s < 6; s++ {
   836  		t13.Square(t13)
   837  	}
   838  
   839  	// Step 191: t13 = x^0x1f75820b34268c829e5ae92076883d14202cf5b
   840  	t13.Mul(t10, t13)
   841  
   842  	// Step 199: t13 = x^0x1f75820b34268c829e5ae92076883d14202cf5b00
   843  	for s := 0; s < 8; s++ {
   844  		t13.Square(t13)
   845  	}
   846  
   847  	// Step 200: t13 = x^0x1f75820b34268c829e5ae92076883d14202cf5b23
   848  	t13.Mul(t12, t13)
   849  
   850  	// Step 205: t13 = x^0x3eeb0416684d19053cb5d240ed107a284059eb6460
   851  	for s := 0; s < 5; s++ {
   852  		t13.Square(t13)
   853  	}
   854  
   855  	// Step 206: t13 = x^0x3eeb0416684d19053cb5d240ed107a284059eb6471
   856  	t13.Mul(t3, t13)
   857  
   858  	// Step 218: t13 = x^0x3eeb0416684d19053cb5d240ed107a284059eb6471000
   859  	for s := 0; s < 12; s++ {
   860  		t13.Square(t13)
   861  	}
   862  
   863  	// Step 219: t12 = x^0x3eeb0416684d19053cb5d240ed107a284059eb6471023
   864  	t12.Mul(t12, t13)
   865  
   866  	// Step 226: t12 = x^0x1f75820b34268c829e5ae92076883d14202cf5b23881180
   867  	for s := 0; s < 7; s++ {
   868  		t12.Square(t12)
   869  	}
   870  
   871  	// Step 227: t12 = x^0x1f75820b34268c829e5ae92076883d14202cf5b23881193
   872  	t12.Mul(t1, t12)
   873  
   874  	// Step 233: t12 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464c0
   875  	for s := 0; s < 6; s++ {
   876  		t12.Square(t12)
   877  	}
   878  
   879  	// Step 234: t12 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d3
   880  	t12.Mul(t1, t12)
   881  
   882  	// Step 247: t12 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a6000
   883  	for s := 0; s < 13; s++ {
   884  		t12.Square(t12)
   885  	}
   886  
   887  	// Step 248: t11 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a6037
   888  	t11.Mul(t11, t12)
   889  
   890  	// Step 257: t11 = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e00
   891  	for s := 0; s < 9; s++ {
   892  		t11.Square(t11)
   893  	}
   894  
   895  	// Step 258: t10 = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b
   896  	t10.Mul(t10, t11)
   897  
   898  	// Step 267: t10 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc3600
   899  	for s := 0; s < 9; s++ {
   900  		t10.Square(t10)
   901  	}
   902  
   903  	// Step 268: t9 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d
   904  	t9.Mul(t9, t10)
   905  
   906  	// Step 278: t9 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d83400
   907  	for s := 0; s < 10; s++ {
   908  		t9.Square(t9)
   909  	}
   910  
   911  	// Step 279: t9 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d83429
   912  	t9.Mul(t0, t9)
   913  
   914  	// Step 287: t9 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d8342900
   915  	for s := 0; s < 8; s++ {
   916  		t9.Square(t9)
   917  	}
   918  
   919  	// Step 288: t8 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d8342927
   920  	t8.Mul(t8, t9)
   921  
   922  	// Step 290: t8 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49c
   923  	for s := 0; s < 2; s++ {
   924  		t8.Square(t8)
   925  	}
   926  
   927  	// Step 291: t8 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d
   928  	t8.Mul(&x, t8)
   929  
   930  	// Step 299: t8 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d00
   931  	for s := 0; s < 8; s++ {
   932  		t8.Square(t8)
   933  	}
   934  
   935  	// Step 300: t8 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d7f
   936  	t8.Mul(t6, t8)
   937  
   938  	// Step 302: t8 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d83429275fc
   939  	for s := 0; s < 2; s++ {
   940  		t8.Square(t8)
   941  	}
   942  
   943  	// Step 303: t8 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d83429275ff
   944  	t8.Mul(t2, t8)
   945  
   946  	// Step 310: t8 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff80
   947  	for s := 0; s < 7; s++ {
   948  		t8.Square(t8)
   949  	}
   950  
   951  	// Step 311: t7 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff9d
   952  	t7.Mul(t7, t8)
   953  
   954  	// Step 314: t7 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d7fce8
   955  	for s := 0; s < 3; s++ {
   956  		t7.Square(t7)
   957  	}
   958  
   959  	// Step 315: t7 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d7fce9
   960  	t7.Mul(&x, t7)
   961  
   962  	// Step 323: t7 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d7fce900
   963  	for s := 0; s < 8; s++ {
   964  		t7.Square(t7)
   965  	}
   966  
   967  	// Step 324: t6 = x^0x3eeb0416684d19053cb5d240ed107a284059eb647102326980dc360d0a49d7fce97f
   968  	t6.Mul(t6, t7)
   969  
   970  	// Step 331: t6 = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bf80
   971  	for s := 0; s < 7; s++ {
   972  		t6.Square(t6)
   973  	}
   974  
   975  	// Step 332: t5 = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bfbb
   976  	t5.Mul(t5, t6)
   977  
   978  	// Step 338: t5 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff9d2feec0
   979  	for s := 0; s < 6; s++ {
   980  		t5.Square(t5)
   981  	}
   982  
   983  	// Step 339: t4 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff9d2feed5
   984  	t4.Mul(t4, t5)
   985  
   986  	// Step 349: t4 = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bfbb5400
   987  	for s := 0; s < 10; s++ {
   988  		t4.Square(t4)
   989  	}
   990  
   991  	// Step 350: t3 = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bfbb5411
   992  	t3.Mul(t3, t4)
   993  
   994  	// Step 353: t3 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d83429275ff3a5fddaa088
   995  	for s := 0; s < 3; s++ {
   996  		t3.Square(t3)
   997  	}
   998  
   999  	// Step 354: t2 = x^0xfbac1059a1346414f2d74903b441e8a10167ad91c408c9a60370d83429275ff3a5fddaa08b
  1000  	t2.Mul(t2, t3)
  1001  
  1002  	// Step 377: t2 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff9d2feed5045800000
  1003  	for s := 0; s < 23; s++ {
  1004  		t2.Square(t2)
  1005  	}
  1006  
  1007  	// Step 378: t1 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff9d2feed5045800013
  1008  	t1.Mul(t1, t2)
  1009  
  1010  	// Step 386: t1 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff9d2feed504580001300
  1011  	for s := 0; s < 8; s++ {
  1012  		t1.Square(t1)
  1013  	}
  1014  
  1015  	// Step 387: t0 = x^0x7dd6082cd09a320a796ba481da20f45080b3d6c8e20464d301b86c1a1493aff9d2feed504580001329
  1016  	t0.Mul(t0, t1)
  1017  
  1018  	// Step 393: t0 = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bfbb5411600004ca40
  1019  	for s := 0; s < 6; s++ {
  1020  		t0.Square(t0)
  1021  	}
  1022  
  1023  	// Step 394: z = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bfbb5411600004ca45
  1024  	z.Mul(z, t0)
  1025  
  1026  	// Step 398: z = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bfbb5411600004ca450
  1027  	for s := 0; s < 4; s++ {
  1028  		z.Square(z)
  1029  	}
  1030  
  1031  	// Step 399: z = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bfbb5411600004ca451
  1032  	z.Mul(&x, z)
  1033  
  1034  	// Step 439: z = x^0x1f75820b34268c829e5ae92076883d14202cf5b238811934c06e1b068524ebfe74bfbb5411600004ca4510000000000
  1035  	for s := 0; s < 40; s++ {
  1036  		z.Square(z)
  1037  	}
  1038  
  1039  	return z
  1040  }