github.com/consensys/gnark-crypto@v0.14.0/ecc/bls12-381/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, 680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc34a83dac3d8907aaffffac54ffffee7fbfffffffeaab) 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 // _100 = 2*_10 27 // _1000 = 2*_100 28 // _1001 = 1 + _1000 29 // _1011 = _10 + _1001 30 // _1100 = 1 + _1011 31 // _10001 = _1000 + _1001 32 // _10100 = _1000 + _1100 33 // _10110 = _10 + _10100 34 // _11001 = _1000 + _10001 35 // _11010 = 1 + _11001 36 // _101011 = _10001 + _11010 37 // _110100 = _1001 + _101011 38 // _110111 = _1100 + _101011 39 // _1001101 = _10110 + _110111 40 // _1001111 = _10 + _1001101 41 // _1010101 = _1000 + _1001101 42 // _1011101 = _1000 + _1010101 43 // _1100111 = _11010 + _1001101 44 // _1101001 = _10 + _1100111 45 // _1110111 = _11010 + _1011101 46 // _1111011 = _100 + _1110111 47 // _10001001 = _110100 + _1010101 48 // _10010101 = _1100 + _10001001 49 // _10010111 = _10 + _10010101 50 // _10101001 = _10100 + _10010101 51 // _10110001 = _1000 + _10101001 52 // _10111111 = _10110 + _10101001 53 // _11000011 = _100 + _10111111 54 // _11010000 = _10001 + _10111111 55 // _11010111 = _10100 + _11000011 56 // _11100001 = _10001 + _11010000 57 // _11100101 = _100 + _11100001 58 // _11101011 = _10100 + _11010111 59 // _11110101 = _10100 + _11100001 60 // _11111111 = _10100 + _11101011 61 // i58 = ((_10111111 + _11100001) << 8 + _10001) << 11 + _11110101 62 // i86 = ((i58 << 11 + _11100101) << 8 + _11111111) << 7 63 // i108 = ((_1001101 + i86) << 9 + _1101001) << 10 + _10110001 64 // i132 = ((i108 << 7 + _1011101) << 9 + _1111011) << 6 65 // i155 = ((_11001 + i132) << 11 + _1101001) << 9 + _11101011 66 // i183 = ((i155 << 10 + _11010111) << 6 + _11001) << 10 67 // i206 = ((_1110111 + i183) << 9 + _10010111) << 11 + _1001111 68 // i236 = ((i206 << 10 + _11100001) << 9 + _10001001) << 9 69 // i257 = ((_10111111 + i236) << 8 + _1100111) << 10 + _11000011 70 // i285 = ((i257 << 9 + _10010101) << 12 + _1111011) << 5 71 // i306 = ((_1011 + i285) << 11 + _1111011) << 7 + _1001 72 // i338 = ((i306 << 13 + _11110101) << 9 + _10111111) << 8 73 // i360 = ((_11111111 + i338) << 8 + _11101011) << 11 + _10101001 74 // i384 = ((i360 << 8 + _11111111) << 8 + _11111111) << 6 75 // i406 = ((_110111 + i384) << 10 + _11111111) << 9 + _11111111 76 // i432 = ((i406 << 8 + _11111111) << 8 + _11111111) << 8 77 // return ((_11111111 + i432) << 7 + _1010101) << 7 + _101011 78 // 79 // Operations: 373 squares 76 multiplies 80 81 // Allocate Temporaries. 82 var ( 83 t0 = new(Element) 84 t1 = new(Element) 85 t2 = new(Element) 86 t3 = new(Element) 87 t4 = new(Element) 88 t5 = new(Element) 89 t6 = new(Element) 90 t7 = new(Element) 91 t8 = new(Element) 92 t9 = new(Element) 93 t10 = new(Element) 94 t11 = new(Element) 95 t12 = new(Element) 96 t13 = new(Element) 97 t14 = new(Element) 98 t15 = new(Element) 99 t16 = new(Element) 100 t17 = new(Element) 101 t18 = new(Element) 102 t19 = new(Element) 103 t20 = new(Element) 104 t21 = new(Element) 105 t22 = new(Element) 106 t23 = new(Element) 107 t24 = new(Element) 108 t25 = new(Element) 109 t26 = new(Element) 110 ) 111 112 // var t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25,t26 Element 113 // Step 1: t3 = x^0x2 114 t3.Square(&x) 115 116 // Step 2: t4 = x^0x4 117 t4.Square(t3) 118 119 // Step 3: t6 = x^0x8 120 t6.Square(t4) 121 122 // Step 4: t7 = x^0x9 123 t7.Mul(&x, t6) 124 125 // Step 5: t9 = x^0xb 126 t9.Mul(t3, t7) 127 128 // Step 6: t10 = x^0xc 129 t10.Mul(&x, t9) 130 131 // Step 7: t25 = x^0x11 132 t25.Mul(t6, t7) 133 134 // Step 8: t1 = x^0x14 135 t1.Mul(t6, t10) 136 137 // Step 9: t5 = x^0x16 138 t5.Mul(t3, t1) 139 140 // Step 10: t18 = x^0x19 141 t18.Mul(t6, t25) 142 143 // Step 11: t8 = x^0x1a 144 t8.Mul(&x, t18) 145 146 // Step 12: z = x^0x2b 147 z.Mul(t25, t8) 148 149 // Step 13: t11 = x^0x34 150 t11.Mul(t7, z) 151 152 // Step 14: t2 = x^0x37 153 t2.Mul(t10, z) 154 155 // Step 15: t23 = x^0x4d 156 t23.Mul(t5, t2) 157 158 // Step 16: t15 = x^0x4f 159 t15.Mul(t3, t23) 160 161 // Step 17: t0 = x^0x55 162 t0.Mul(t6, t23) 163 164 // Step 18: t21 = x^0x5d 165 t21.Mul(t6, t0) 166 167 // Step 19: t12 = x^0x67 168 t12.Mul(t8, t23) 169 170 // Step 20: t20 = x^0x69 171 t20.Mul(t3, t12) 172 173 // Step 21: t17 = x^0x77 174 t17.Mul(t8, t21) 175 176 // Step 22: t8 = x^0x7b 177 t8.Mul(t4, t17) 178 179 // Step 23: t13 = x^0x89 180 t13.Mul(t11, t0) 181 182 // Step 24: t10 = x^0x95 183 t10.Mul(t10, t13) 184 185 // Step 25: t16 = x^0x97 186 t16.Mul(t3, t10) 187 188 // Step 26: t3 = x^0xa9 189 t3.Mul(t1, t10) 190 191 // Step 27: t22 = x^0xb1 192 t22.Mul(t6, t3) 193 194 // Step 28: t5 = x^0xbf 195 t5.Mul(t5, t3) 196 197 // Step 29: t11 = x^0xc3 198 t11.Mul(t4, t5) 199 200 // Step 30: t6 = x^0xd0 201 t6.Mul(t25, t5) 202 203 // Step 31: t19 = x^0xd7 204 t19.Mul(t1, t11) 205 206 // Step 32: t14 = x^0xe1 207 t14.Mul(t25, t6) 208 209 // Step 33: t24 = x^0xe5 210 t24.Mul(t4, t14) 211 212 // Step 34: t4 = x^0xeb 213 t4.Mul(t1, t19) 214 215 // Step 35: t6 = x^0xf5 216 t6.Mul(t1, t14) 217 218 // Step 36: t1 = x^0xff 219 t1.Mul(t1, t4) 220 221 // Step 37: t26 = x^0x1a0 222 t26.Mul(t5, t14) 223 224 // Step 45: t26 = x^0x1a000 225 for s := 0; s < 8; s++ { 226 t26.Square(t26) 227 } 228 229 // Step 46: t25 = x^0x1a011 230 t25.Mul(t25, t26) 231 232 // Step 57: t25 = x^0xd008800 233 for s := 0; s < 11; s++ { 234 t25.Square(t25) 235 } 236 237 // Step 58: t25 = x^0xd0088f5 238 t25.Mul(t6, t25) 239 240 // Step 69: t25 = x^0x680447a800 241 for s := 0; s < 11; s++ { 242 t25.Square(t25) 243 } 244 245 // Step 70: t24 = x^0x680447a8e5 246 t24.Mul(t24, t25) 247 248 // Step 78: t24 = x^0x680447a8e500 249 for s := 0; s < 8; s++ { 250 t24.Square(t24) 251 } 252 253 // Step 79: t24 = x^0x680447a8e5ff 254 t24.Mul(t1, t24) 255 256 // Step 86: t24 = x^0x340223d472ff80 257 for s := 0; s < 7; s++ { 258 t24.Square(t24) 259 } 260 261 // Step 87: t23 = x^0x340223d472ffcd 262 t23.Mul(t23, t24) 263 264 // Step 96: t23 = x^0x680447a8e5ff9a00 265 for s := 0; s < 9; s++ { 266 t23.Square(t23) 267 } 268 269 // Step 97: t23 = x^0x680447a8e5ff9a69 270 t23.Mul(t20, t23) 271 272 // Step 107: t23 = x^0x1a0111ea397fe69a400 273 for s := 0; s < 10; s++ { 274 t23.Square(t23) 275 } 276 277 // Step 108: t22 = x^0x1a0111ea397fe69a4b1 278 t22.Mul(t22, t23) 279 280 // Step 115: t22 = x^0xd0088f51cbff34d25880 281 for s := 0; s < 7; s++ { 282 t22.Square(t22) 283 } 284 285 // Step 116: t21 = x^0xd0088f51cbff34d258dd 286 t21.Mul(t21, t22) 287 288 // Step 125: t21 = x^0x1a0111ea397fe69a4b1ba00 289 for s := 0; s < 9; s++ { 290 t21.Square(t21) 291 } 292 293 // Step 126: t21 = x^0x1a0111ea397fe69a4b1ba7b 294 t21.Mul(t8, t21) 295 296 // Step 132: t21 = x^0x680447a8e5ff9a692c6e9ec0 297 for s := 0; s < 6; s++ { 298 t21.Square(t21) 299 } 300 301 // Step 133: t21 = x^0x680447a8e5ff9a692c6e9ed9 302 t21.Mul(t18, t21) 303 304 // Step 144: t21 = x^0x340223d472ffcd3496374f6c800 305 for s := 0; s < 11; s++ { 306 t21.Square(t21) 307 } 308 309 // Step 145: t20 = x^0x340223d472ffcd3496374f6c869 310 t20.Mul(t20, t21) 311 312 // Step 154: t20 = x^0x680447a8e5ff9a692c6e9ed90d200 313 for s := 0; s < 9; s++ { 314 t20.Square(t20) 315 } 316 317 // Step 155: t20 = x^0x680447a8e5ff9a692c6e9ed90d2eb 318 t20.Mul(t4, t20) 319 320 // Step 165: t20 = x^0x1a0111ea397fe69a4b1ba7b6434bac00 321 for s := 0; s < 10; s++ { 322 t20.Square(t20) 323 } 324 325 // Step 166: t19 = x^0x1a0111ea397fe69a4b1ba7b6434bacd7 326 t19.Mul(t19, t20) 327 328 // Step 172: t19 = x^0x680447a8e5ff9a692c6e9ed90d2eb35c0 329 for s := 0; s < 6; s++ { 330 t19.Square(t19) 331 } 332 333 // Step 173: t18 = x^0x680447a8e5ff9a692c6e9ed90d2eb35d9 334 t18.Mul(t18, t19) 335 336 // Step 183: t18 = x^0x1a0111ea397fe69a4b1ba7b6434bacd76400 337 for s := 0; s < 10; s++ { 338 t18.Square(t18) 339 } 340 341 // Step 184: t17 = x^0x1a0111ea397fe69a4b1ba7b6434bacd76477 342 t17.Mul(t17, t18) 343 344 // Step 193: t17 = x^0x340223d472ffcd3496374f6c869759aec8ee00 345 for s := 0; s < 9; s++ { 346 t17.Square(t17) 347 } 348 349 // Step 194: t16 = x^0x340223d472ffcd3496374f6c869759aec8ee97 350 t16.Mul(t16, t17) 351 352 // Step 205: t16 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b800 353 for s := 0; s < 11; s++ { 354 t16.Square(t16) 355 } 356 357 // Step 206: t15 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f 358 t15.Mul(t15, t16) 359 360 // Step 216: t15 = x^0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13c00 361 for s := 0; s < 10; s++ { 362 t15.Square(t15) 363 } 364 365 // Step 217: t14 = x^0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce1 366 t14.Mul(t14, t15) 367 368 // Step 226: t14 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c200 369 for s := 0; s < 9; s++ { 370 t14.Square(t14) 371 } 372 373 // Step 227: t13 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c289 374 t13.Mul(t13, t14) 375 376 // Step 236: t13 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f3851200 377 for s := 0; s < 9; s++ { 378 t13.Square(t13) 379 } 380 381 // Step 237: t13 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf 382 t13.Mul(t5, t13) 383 384 // Step 245: t13 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf00 385 for s := 0; s < 8; s++ { 386 t13.Square(t13) 387 } 388 389 // Step 246: t12 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf67 390 t12.Mul(t12, t13) 391 392 // Step 256: t12 = x^0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9c00 393 for s := 0; s < 10; s++ { 394 t12.Square(t12) 395 } 396 397 // Step 257: t11 = x^0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc3 398 t11.Mul(t11, t12) 399 400 // Step 266: t11 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb398600 401 for s := 0; s < 9; s++ { 402 t11.Square(t11) 403 } 404 405 // Step 267: t10 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb398695 406 t10.Mul(t10, t11) 407 408 // Step 279: t10 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb398695000 409 for s := 0; s < 12; s++ { 410 t10.Square(t10) 411 } 412 413 // Step 280: t10 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b 414 t10.Mul(t8, t10) 415 416 // Step 285: t10 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f60 417 for s := 0; s < 5; s++ { 418 t10.Square(t10) 419 } 420 421 // Step 286: t9 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b 422 t9.Mul(t9, t10) 423 424 // Step 297: t9 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b5800 425 for s := 0; s < 11; s++ { 426 t9.Square(t9) 427 } 428 429 // Step 298: t8 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b 430 t8.Mul(t8, t9) 431 432 // Step 305: t8 = x^0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc34a83dac3d80 433 for s := 0; s < 7; s++ { 434 t8.Square(t8) 435 } 436 437 // Step 306: t7 = x^0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc34a83dac3d89 438 t7.Mul(t7, t8) 439 440 // Step 319: t7 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b12000 441 for s := 0; s < 13; s++ { 442 t7.Square(t7) 443 } 444 445 // Step 320: t6 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f5 446 t6.Mul(t6, t7) 447 448 // Step 329: t6 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241ea00 449 for s := 0; s < 9; s++ { 450 t6.Square(t6) 451 } 452 453 // Step 330: t5 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabf 454 t5.Mul(t5, t6) 455 456 // Step 338: t5 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabf00 457 for s := 0; s < 8; s++ { 458 t5.Square(t5) 459 } 460 461 // Step 339: t5 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfff 462 t5.Mul(t1, t5) 463 464 // Step 347: t5 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfff00 465 for s := 0; s < 8; s++ { 466 t5.Square(t5) 467 } 468 469 // Step 348: t4 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb 470 t4.Mul(t4, t5) 471 472 // Step 359: t4 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff5800 473 for s := 0; s < 11; s++ { 474 t4.Square(t4) 475 } 476 477 // Step 360: t3 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9 478 t3.Mul(t3, t4) 479 480 // Step 368: t3 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a900 481 for s := 0; s < 8; s++ { 482 t3.Square(t3) 483 } 484 485 // Step 369: t3 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ff 486 t3.Mul(t1, t3) 487 488 // Step 377: t3 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ff00 489 for s := 0; s < 8; s++ { 490 t3.Square(t3) 491 } 492 493 // Step 378: t3 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffff 494 t3.Mul(t1, t3) 495 496 // Step 384: t3 = x^0x340223d472ffcd3496374f6c869759aec8ee9709e70a257ece61a541ed61ec483d57fffd62a7fffc0 497 for s := 0; s < 6; s++ { 498 t3.Square(t3) 499 } 500 501 // Step 385: t2 = x^0x340223d472ffcd3496374f6c869759aec8ee9709e70a257ece61a541ed61ec483d57fffd62a7ffff7 502 t2.Mul(t2, t3) 503 504 // Step 395: t2 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffffdc00 505 for s := 0; s < 10; s++ { 506 t2.Square(t2) 507 } 508 509 // Step 396: t2 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffffdcff 510 t2.Mul(t1, t2) 511 512 // Step 405: t2 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9fe00 513 for s := 0; s < 9; s++ { 514 t2.Square(t2) 515 } 516 517 // Step 406: t2 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feff 518 t2.Mul(t1, t2) 519 520 // Step 414: t2 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feff00 521 for s := 0; s < 8; s++ { 522 t2.Square(t2) 523 } 524 525 // Step 415: t2 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffff 526 t2.Mul(t1, t2) 527 528 // Step 423: t2 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffff00 529 for s := 0; s < 8; s++ { 530 t2.Square(t2) 531 } 532 533 // Step 424: t2 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffff 534 t2.Mul(t1, t2) 535 536 // Step 432: t2 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffff00 537 for s := 0; s < 8; s++ { 538 t2.Square(t2) 539 } 540 541 // Step 433: t1 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffff 542 t1.Mul(t1, t2) 543 544 // Step 440: t1 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffffdcff7fffffff80 545 for s := 0; s < 7; s++ { 546 t1.Square(t1) 547 } 548 549 // Step 441: t0 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffffdcff7fffffffd5 550 t0.Mul(t0, t1) 551 552 // Step 448: t0 = x^0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc34a83dac3d8907aaffffac54ffffee7fbfffffffea80 553 for s := 0; s < 7; s++ { 554 t0.Square(t0) 555 } 556 557 // Step 449: z = x^0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc34a83dac3d8907aaffffac54ffffee7fbfffffffeaab 558 z.Mul(z, t0) 559 560 return z 561 } 562 563 // expByLegendreExp is equivalent to z.Exp(x, d0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffffdcff7fffffffd555) 564 // 565 // uses github.com/mmcloughlin/addchain v0.4.0 to generate a shorter addition chain 566 func (z *Element) expByLegendreExp(x Element) *Element { 567 // addition chain: 568 // 569 // _10 = 2*1 570 // _100 = 2*_10 571 // _1000 = 2*_100 572 // _1001 = 1 + _1000 573 // _1011 = _10 + _1001 574 // _1101 = _10 + _1011 575 // _10001 = _100 + _1101 576 // _10100 = _1001 + _1011 577 // _11001 = _1000 + _10001 578 // _11010 = 1 + _11001 579 // _110100 = 2*_11010 580 // _110110 = _10 + _110100 581 // _110111 = 1 + _110110 582 // _1001101 = _11001 + _110100 583 // _1001111 = _10 + _1001101 584 // _1010101 = _1000 + _1001101 585 // _1011101 = _1000 + _1010101 586 // _1100111 = _11010 + _1001101 587 // _1101001 = _10 + _1100111 588 // _1110111 = _11010 + _1011101 589 // _1111011 = _100 + _1110111 590 // _10001001 = _110100 + _1010101 591 // _10010101 = _11010 + _1111011 592 // _10010111 = _10 + _10010101 593 // _10101001 = _10100 + _10010101 594 // _10110001 = _1000 + _10101001 595 // _10111111 = _110110 + _10001001 596 // _11000011 = _100 + _10111111 597 // _11010000 = _1101 + _11000011 598 // _11010111 = _10100 + _11000011 599 // _11100001 = _10001 + _11010000 600 // _11100101 = _100 + _11100001 601 // _11101011 = _10100 + _11010111 602 // _11110101 = _10100 + _11100001 603 // _11111111 = _10100 + _11101011 604 // i57 = ((_10111111 + _11100001) << 8 + _10001) << 11 + _11110101 605 // i85 = ((i57 << 11 + _11100101) << 8 + _11111111) << 7 606 // i107 = ((_1001101 + i85) << 9 + _1101001) << 10 + _10110001 607 // i131 = ((i107 << 7 + _1011101) << 9 + _1111011) << 6 608 // i154 = ((_11001 + i131) << 11 + _1101001) << 9 + _11101011 609 // i182 = ((i154 << 10 + _11010111) << 6 + _11001) << 10 610 // i205 = ((_1110111 + i182) << 9 + _10010111) << 11 + _1001111 611 // i235 = ((i205 << 10 + _11100001) << 9 + _10001001) << 9 612 // i256 = ((_10111111 + i235) << 8 + _1100111) << 10 + _11000011 613 // i284 = ((i256 << 9 + _10010101) << 12 + _1111011) << 5 614 // i305 = ((_1011 + i284) << 11 + _1111011) << 7 + _1001 615 // i337 = ((i305 << 13 + _11110101) << 9 + _10111111) << 8 616 // i359 = ((_11111111 + i337) << 8 + _11101011) << 11 + _10101001 617 // i383 = ((i359 << 8 + _11111111) << 8 + _11111111) << 6 618 // i405 = ((_110111 + i383) << 10 + _11111111) << 9 + _11111111 619 // i431 = ((i405 << 8 + _11111111) << 8 + _11111111) << 8 620 // return ((_11111111 + i431) << 7 + _1010101) << 8 + _1010101 621 // 622 // Operations: 375 squares 74 multiplies 623 624 // Allocate Temporaries. 625 var ( 626 t0 = new(Element) 627 t1 = new(Element) 628 t2 = new(Element) 629 t3 = new(Element) 630 t4 = new(Element) 631 t5 = new(Element) 632 t6 = new(Element) 633 t7 = new(Element) 634 t8 = new(Element) 635 t9 = new(Element) 636 t10 = new(Element) 637 t11 = new(Element) 638 t12 = new(Element) 639 t13 = new(Element) 640 t14 = new(Element) 641 t15 = new(Element) 642 t16 = new(Element) 643 t17 = new(Element) 644 t18 = new(Element) 645 t19 = new(Element) 646 t20 = new(Element) 647 t21 = new(Element) 648 t22 = new(Element) 649 t23 = new(Element) 650 t24 = new(Element) 651 t25 = new(Element) 652 ) 653 654 // var t0,t1,t2,t3,t4,t5,t6,t7,t8,t9,t10,t11,t12,t13,t14,t15,t16,t17,t18,t19,t20,t21,t22,t23,t24,t25 Element 655 // Step 1: t2 = x^0x2 656 t2.Square(&x) 657 658 // Step 2: t3 = x^0x4 659 t3.Square(t2) 660 661 // Step 3: t10 = x^0x8 662 t10.Square(t3) 663 664 // Step 4: t6 = x^0x9 665 t6.Mul(&x, t10) 666 667 // Step 5: t8 = x^0xb 668 t8.Mul(t2, t6) 669 670 // Step 6: t5 = x^0xd 671 t5.Mul(t2, t8) 672 673 // Step 7: t24 = x^0x11 674 t24.Mul(t3, t5) 675 676 // Step 8: t0 = x^0x14 677 t0.Mul(t6, t8) 678 679 // Step 9: t17 = x^0x19 680 t17.Mul(t10, t24) 681 682 // Step 10: t9 = x^0x1a 683 t9.Mul(&x, t17) 684 685 // Step 11: t12 = x^0x34 686 t12.Square(t9) 687 688 // Step 12: t4 = x^0x36 689 t4.Mul(t2, t12) 690 691 // Step 13: t1 = x^0x37 692 t1.Mul(&x, t4) 693 694 // Step 14: t22 = x^0x4d 695 t22.Mul(t17, t12) 696 697 // Step 15: t14 = x^0x4f 698 t14.Mul(t2, t22) 699 700 // Step 16: z = x^0x55 701 z.Mul(t10, t22) 702 703 // Step 17: t20 = x^0x5d 704 t20.Mul(t10, z) 705 706 // Step 18: t11 = x^0x67 707 t11.Mul(t9, t22) 708 709 // Step 19: t19 = x^0x69 710 t19.Mul(t2, t11) 711 712 // Step 20: t16 = x^0x77 713 t16.Mul(t9, t20) 714 715 // Step 21: t7 = x^0x7b 716 t7.Mul(t3, t16) 717 718 // Step 22: t12 = x^0x89 719 t12.Mul(t12, z) 720 721 // Step 23: t9 = x^0x95 722 t9.Mul(t9, t7) 723 724 // Step 24: t15 = x^0x97 725 t15.Mul(t2, t9) 726 727 // Step 25: t2 = x^0xa9 728 t2.Mul(t0, t9) 729 730 // Step 26: t21 = x^0xb1 731 t21.Mul(t10, t2) 732 733 // Step 27: t4 = x^0xbf 734 t4.Mul(t4, t12) 735 736 // Step 28: t10 = x^0xc3 737 t10.Mul(t3, t4) 738 739 // Step 29: t5 = x^0xd0 740 t5.Mul(t5, t10) 741 742 // Step 30: t18 = x^0xd7 743 t18.Mul(t0, t10) 744 745 // Step 31: t13 = x^0xe1 746 t13.Mul(t24, t5) 747 748 // Step 32: t23 = x^0xe5 749 t23.Mul(t3, t13) 750 751 // Step 33: t3 = x^0xeb 752 t3.Mul(t0, t18) 753 754 // Step 34: t5 = x^0xf5 755 t5.Mul(t0, t13) 756 757 // Step 35: t0 = x^0xff 758 t0.Mul(t0, t3) 759 760 // Step 36: t25 = x^0x1a0 761 t25.Mul(t4, t13) 762 763 // Step 44: t25 = x^0x1a000 764 for s := 0; s < 8; s++ { 765 t25.Square(t25) 766 } 767 768 // Step 45: t24 = x^0x1a011 769 t24.Mul(t24, t25) 770 771 // Step 56: t24 = x^0xd008800 772 for s := 0; s < 11; s++ { 773 t24.Square(t24) 774 } 775 776 // Step 57: t24 = x^0xd0088f5 777 t24.Mul(t5, t24) 778 779 // Step 68: t24 = x^0x680447a800 780 for s := 0; s < 11; s++ { 781 t24.Square(t24) 782 } 783 784 // Step 69: t23 = x^0x680447a8e5 785 t23.Mul(t23, t24) 786 787 // Step 77: t23 = x^0x680447a8e500 788 for s := 0; s < 8; s++ { 789 t23.Square(t23) 790 } 791 792 // Step 78: t23 = x^0x680447a8e5ff 793 t23.Mul(t0, t23) 794 795 // Step 85: t23 = x^0x340223d472ff80 796 for s := 0; s < 7; s++ { 797 t23.Square(t23) 798 } 799 800 // Step 86: t22 = x^0x340223d472ffcd 801 t22.Mul(t22, t23) 802 803 // Step 95: t22 = x^0x680447a8e5ff9a00 804 for s := 0; s < 9; s++ { 805 t22.Square(t22) 806 } 807 808 // Step 96: t22 = x^0x680447a8e5ff9a69 809 t22.Mul(t19, t22) 810 811 // Step 106: t22 = x^0x1a0111ea397fe69a400 812 for s := 0; s < 10; s++ { 813 t22.Square(t22) 814 } 815 816 // Step 107: t21 = x^0x1a0111ea397fe69a4b1 817 t21.Mul(t21, t22) 818 819 // Step 114: t21 = x^0xd0088f51cbff34d25880 820 for s := 0; s < 7; s++ { 821 t21.Square(t21) 822 } 823 824 // Step 115: t20 = x^0xd0088f51cbff34d258dd 825 t20.Mul(t20, t21) 826 827 // Step 124: t20 = x^0x1a0111ea397fe69a4b1ba00 828 for s := 0; s < 9; s++ { 829 t20.Square(t20) 830 } 831 832 // Step 125: t20 = x^0x1a0111ea397fe69a4b1ba7b 833 t20.Mul(t7, t20) 834 835 // Step 131: t20 = x^0x680447a8e5ff9a692c6e9ec0 836 for s := 0; s < 6; s++ { 837 t20.Square(t20) 838 } 839 840 // Step 132: t20 = x^0x680447a8e5ff9a692c6e9ed9 841 t20.Mul(t17, t20) 842 843 // Step 143: t20 = x^0x340223d472ffcd3496374f6c800 844 for s := 0; s < 11; s++ { 845 t20.Square(t20) 846 } 847 848 // Step 144: t19 = x^0x340223d472ffcd3496374f6c869 849 t19.Mul(t19, t20) 850 851 // Step 153: t19 = x^0x680447a8e5ff9a692c6e9ed90d200 852 for s := 0; s < 9; s++ { 853 t19.Square(t19) 854 } 855 856 // Step 154: t19 = x^0x680447a8e5ff9a692c6e9ed90d2eb 857 t19.Mul(t3, t19) 858 859 // Step 164: t19 = x^0x1a0111ea397fe69a4b1ba7b6434bac00 860 for s := 0; s < 10; s++ { 861 t19.Square(t19) 862 } 863 864 // Step 165: t18 = x^0x1a0111ea397fe69a4b1ba7b6434bacd7 865 t18.Mul(t18, t19) 866 867 // Step 171: t18 = x^0x680447a8e5ff9a692c6e9ed90d2eb35c0 868 for s := 0; s < 6; s++ { 869 t18.Square(t18) 870 } 871 872 // Step 172: t17 = x^0x680447a8e5ff9a692c6e9ed90d2eb35d9 873 t17.Mul(t17, t18) 874 875 // Step 182: t17 = x^0x1a0111ea397fe69a4b1ba7b6434bacd76400 876 for s := 0; s < 10; s++ { 877 t17.Square(t17) 878 } 879 880 // Step 183: t16 = x^0x1a0111ea397fe69a4b1ba7b6434bacd76477 881 t16.Mul(t16, t17) 882 883 // Step 192: t16 = x^0x340223d472ffcd3496374f6c869759aec8ee00 884 for s := 0; s < 9; s++ { 885 t16.Square(t16) 886 } 887 888 // Step 193: t15 = x^0x340223d472ffcd3496374f6c869759aec8ee97 889 t15.Mul(t15, t16) 890 891 // Step 204: t15 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b800 892 for s := 0; s < 11; s++ { 893 t15.Square(t15) 894 } 895 896 // Step 205: t14 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f 897 t14.Mul(t14, t15) 898 899 // Step 215: t14 = x^0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13c00 900 for s := 0; s < 10; s++ { 901 t14.Square(t14) 902 } 903 904 // Step 216: t13 = x^0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce1 905 t13.Mul(t13, t14) 906 907 // Step 225: t13 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c200 908 for s := 0; s < 9; s++ { 909 t13.Square(t13) 910 } 911 912 // Step 226: t12 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c289 913 t12.Mul(t12, t13) 914 915 // Step 235: t12 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f3851200 916 for s := 0; s < 9; s++ { 917 t12.Square(t12) 918 } 919 920 // Step 236: t12 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf 921 t12.Mul(t4, t12) 922 923 // Step 244: t12 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf00 924 for s := 0; s < 8; s++ { 925 t12.Square(t12) 926 } 927 928 // Step 245: t11 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf67 929 t11.Mul(t11, t12) 930 931 // Step 255: t11 = x^0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9c00 932 for s := 0; s < 10; s++ { 933 t11.Square(t11) 934 } 935 936 // Step 256: t10 = x^0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc3 937 t10.Mul(t10, t11) 938 939 // Step 265: t10 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb398600 940 for s := 0; s < 9; s++ { 941 t10.Square(t10) 942 } 943 944 // Step 266: t9 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb398695 945 t9.Mul(t9, t10) 946 947 // Step 278: t9 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb398695000 948 for s := 0; s < 12; s++ { 949 t9.Square(t9) 950 } 951 952 // Step 279: t9 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b 953 t9.Mul(t7, t9) 954 955 // Step 284: t9 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f60 956 for s := 0; s < 5; s++ { 957 t9.Square(t9) 958 } 959 960 // Step 285: t8 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b 961 t8.Mul(t8, t9) 962 963 // Step 296: t8 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b5800 964 for s := 0; s < 11; s++ { 965 t8.Square(t8) 966 } 967 968 // Step 297: t7 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b 969 t7.Mul(t7, t8) 970 971 // Step 304: t7 = x^0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc34a83dac3d80 972 for s := 0; s < 7; s++ { 973 t7.Square(t7) 974 } 975 976 // Step 305: t6 = x^0x680447a8e5ff9a692c6e9ed90d2eb35d91dd2e13ce144afd9cc34a83dac3d89 977 t6.Mul(t6, t7) 978 979 // Step 318: t6 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b12000 980 for s := 0; s < 13; s++ { 981 t6.Square(t6) 982 } 983 984 // Step 319: t5 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f5 985 t5.Mul(t5, t6) 986 987 // Step 328: t5 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241ea00 988 for s := 0; s < 9; s++ { 989 t5.Square(t5) 990 } 991 992 // Step 329: t4 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabf 993 t4.Mul(t4, t5) 994 995 // Step 337: t4 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabf00 996 for s := 0; s < 8; s++ { 997 t4.Square(t4) 998 } 999 1000 // Step 338: t4 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfff 1001 t4.Mul(t0, t4) 1002 1003 // Step 346: t4 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfff00 1004 for s := 0; s < 8; s++ { 1005 t4.Square(t4) 1006 } 1007 1008 // Step 347: t3 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb 1009 t3.Mul(t3, t4) 1010 1011 // Step 358: t3 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff5800 1012 for s := 0; s < 11; s++ { 1013 t3.Square(t3) 1014 } 1015 1016 // Step 359: t2 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9 1017 t2.Mul(t2, t3) 1018 1019 // Step 367: t2 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a900 1020 for s := 0; s < 8; s++ { 1021 t2.Square(t2) 1022 } 1023 1024 // Step 368: t2 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ff 1025 t2.Mul(t0, t2) 1026 1027 // Step 376: t2 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ff00 1028 for s := 0; s < 8; s++ { 1029 t2.Square(t2) 1030 } 1031 1032 // Step 377: t2 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffff 1033 t2.Mul(t0, t2) 1034 1035 // Step 383: t2 = x^0x340223d472ffcd3496374f6c869759aec8ee9709e70a257ece61a541ed61ec483d57fffd62a7fffc0 1036 for s := 0; s < 6; s++ { 1037 t2.Square(t2) 1038 } 1039 1040 // Step 384: t1 = x^0x340223d472ffcd3496374f6c869759aec8ee9709e70a257ece61a541ed61ec483d57fffd62a7ffff7 1041 t1.Mul(t1, t2) 1042 1043 // Step 394: t1 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffffdc00 1044 for s := 0; s < 10; s++ { 1045 t1.Square(t1) 1046 } 1047 1048 // Step 395: t1 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffffdcff 1049 t1.Mul(t0, t1) 1050 1051 // Step 404: t1 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9fe00 1052 for s := 0; s < 9; s++ { 1053 t1.Square(t1) 1054 } 1055 1056 // Step 405: t1 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feff 1057 t1.Mul(t0, t1) 1058 1059 // Step 413: t1 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feff00 1060 for s := 0; s < 8; s++ { 1061 t1.Square(t1) 1062 } 1063 1064 // Step 414: t1 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffff 1065 t1.Mul(t0, t1) 1066 1067 // Step 422: t1 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffff00 1068 for s := 0; s < 8; s++ { 1069 t1.Square(t1) 1070 } 1071 1072 // Step 423: t1 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffff 1073 t1.Mul(t0, t1) 1074 1075 // Step 431: t1 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffff00 1076 for s := 0; s < 8; s++ { 1077 t1.Square(t1) 1078 } 1079 1080 // Step 432: t0 = x^0x1a0111ea397fe69a4b1ba7b6434bacd764774b84f38512bf6730d2a0f6b0f6241eabfffeb153ffffb9feffffffff 1081 t0.Mul(t0, t1) 1082 1083 // Step 439: t0 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffffdcff7fffffff80 1084 for s := 0; s < 7; s++ { 1085 t0.Square(t0) 1086 } 1087 1088 // Step 440: t0 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffffdcff7fffffffd5 1089 t0.Mul(z, t0) 1090 1091 // Step 448: t0 = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffffdcff7fffffffd500 1092 for s := 0; s < 8; s++ { 1093 t0.Square(t0) 1094 } 1095 1096 // Step 449: z = x^0xd0088f51cbff34d258dd3db21a5d66bb23ba5c279c2895fb39869507b587b120f55ffff58a9ffffdcff7fffffffd555 1097 z.Mul(z, t0) 1098 1099 return z 1100 }