github.com/emmansun/gmsm@v0.29.1/sm9/bn256/gfp_invert_sqrt.go (about) 1 // Code generated by addchain. DO NOT EDIT. 2 package bn256 3 4 // Invert sets e = 1/x, and returns e. 5 // 6 // If x == 0, Invert returns e = 0. 7 func (e *gfP) Invert(x *gfP) *gfP { 8 // Inversion is implemented as exponentiation with exponent p − 2. 9 // The sequence of 56 multiplications and 250 squarings is derived from the 10 // following addition chain generated with github.com/mmcloughlin/addchain v0.4.0. 11 // 12 // _10 = 2*1 13 // _100 = 2*_10 14 // _110 = _10 + _100 15 // _1010 = _100 + _110 16 // _1011 = 1 + _1010 17 // _1101 = _10 + _1011 18 // _10000 = _110 + _1010 19 // _10101 = _1010 + _1011 20 // _11011 = _110 + _10101 21 // _11101 = _10 + _11011 22 // _11111 = _10 + _11101 23 // _101001 = _1010 + _11111 24 // _101011 = _10 + _101001 25 // _111011 = _10000 + _101011 26 // _1000101 = _1010 + _111011 27 // _1001111 = _1010 + _1000101 28 // _1010001 = _10 + _1001111 29 // _1011011 = _1010 + _1010001 30 // _1011101 = _10 + _1011011 31 // _1011111 = _10 + _1011101 32 // _1100011 = _100 + _1011111 33 // _1101001 = _110 + _1100011 34 // _1101101 = _100 + _1101001 35 // _1101111 = _10 + _1101101 36 // _1110101 = _110 + _1101111 37 // _1111011 = _110 + _1110101 38 // _10110110 = _111011 + _1111011 39 // i72 = ((_10110110 << 2 + 1) << 33 + _10101) << 8 40 // i94 = ((_11101 + i72) << 9 + _1101111) << 10 + _1110101 41 // i116 = ((2*i94 + 1) << 14 + _1110101) << 5 42 // i129 = 2*((_1101 + i116) << 9 + _1111011 + _100) 43 // i146 = ((1 + i129) << 5 + _1011) << 9 + _111011 44 // i174 = ((i146 << 8 + _11101) << 9 + _101001) << 9 45 // i194 = ((_11111 + i174) << 8 + _101001) << 9 + _1101001 46 // i220 = ((i194 << 8 + _1100011) << 8 + _1001111) << 8 47 // i237 = ((_1011101 + i220) << 7 + _1101101) << 7 + _1011111 48 // i260 = ((i237 << 8 + _101011) << 6 + _11111) << 7 49 // i279 = ((_11011 + i260) << 9 + _1001111) << 7 + _1100011 50 // i305 = ((i279 << 8 + _1010001) << 8 + _1000101) << 8 51 // return _1111011 + i305 52 // 53 var z = new(gfP).Set(e) 54 var t0 = new(gfP) 55 var t1 = new(gfP) 56 var t2 = new(gfP) 57 var t3 = new(gfP) 58 var t4 = new(gfP) 59 var t5 = new(gfP) 60 var t6 = new(gfP) 61 var t7 = new(gfP) 62 var t8 = new(gfP) 63 var t9 = new(gfP) 64 var t10 = new(gfP) 65 var t11 = new(gfP) 66 var t12 = new(gfP) 67 var t13 = new(gfP) 68 var t14 = new(gfP) 69 var t15 = new(gfP) 70 var t16 = new(gfP) 71 var t17 = new(gfP) 72 var t18 = new(gfP) 73 var t19 = new(gfP) 74 var t20 = new(gfP) 75 76 t17.Square(x, 1) 77 t15.Square(t17, 1) 78 z.Mul(t17, t15) 79 t2.Mul(t15, z) 80 t14.Mul(x, t2) 81 t16.Mul(t17, t14) 82 t0.Mul(z, t2) 83 t19.Mul(t2, t14) 84 t4.Mul(z, t19) 85 t12.Mul(t17, t4) 86 t5.Mul(t17, t12) 87 t11.Mul(t2, t5) 88 t6.Mul(t17, t11) 89 t13.Mul(t0, t6) 90 t0.Mul(t2, t13) 91 t3.Mul(t2, t0) 92 t1.Mul(t17, t3) 93 t2.Mul(t2, t1) 94 t9.Mul(t17, t2) 95 t7.Mul(t17, t9) 96 t2.Mul(t15, t7) 97 t10.Mul(z, t2) 98 t8.Mul(t15, t10) 99 t18.Mul(t17, t8) 100 t17.Mul(z, t18) 101 z.Mul(z, t17) 102 t20.Mul(t13, z) 103 t20.Square(t20, 2) 104 t20.Mul(x, t20) 105 t20.Square(t20, 33) 106 t19.Mul(t19, t20) 107 t19.Square(t19, 8) 108 t19.Mul(t12, t19) 109 t19.Square(t19, 9) 110 t18.Mul(t18, t19) 111 t18.Square(t18, 10) 112 t18.Mul(t17, t18) 113 t18.Square(t18, 1) 114 t18.Mul(x, t18) 115 t18.Square(t18, 14) 116 t17.Mul(t17, t18) 117 t17.Square(t17, 5) 118 t16.Mul(t16, t17) 119 t16.Square(t16, 9) 120 t16.Mul(z, t16) 121 t15.Mul(t15, t16) 122 t15.Square(t15, 1) 123 t15.Mul(x, t15) 124 t15.Square(t15, 5) 125 t14.Mul(t14, t15) 126 t14.Square(t14, 9) 127 t13.Mul(t13, t14) 128 t13.Square(t13, 8) 129 t12.Mul(t12, t13) 130 t12.Square(t12, 9) 131 t12.Mul(t11, t12) 132 t12.Square(t12, 9) 133 t12.Mul(t5, t12) 134 t12.Square(t12, 8) 135 t11.Mul(t11, t12) 136 t11.Square(t11, 9) 137 t10.Mul(t10, t11) 138 t10.Square(t10, 8) 139 t10.Mul(t2, t10) 140 t10.Square(t10, 8) 141 t10.Mul(t3, t10) 142 t10.Square(t10, 8) 143 t9.Mul(t9, t10) 144 t9.Square(t9, 7) 145 t8.Mul(t8, t9) 146 t8.Square(t8, 7) 147 t7.Mul(t7, t8) 148 t7.Square(t7, 8) 149 t6.Mul(t6, t7) 150 t6.Square(t6, 6) 151 t5.Mul(t5, t6) 152 t5.Square(t5, 7) 153 t4.Mul(t4, t5) 154 t4.Square(t4, 9) 155 t3.Mul(t3, t4) 156 t3.Square(t3, 7) 157 t2.Mul(t2, t3) 158 t2.Square(t2, 8) 159 t1.Mul(t1, t2) 160 t1.Square(t1, 8) 161 t0.Mul(t0, t1) 162 t0.Square(t0, 8) 163 z.Mul(z, t0) 164 return e.Set(z) 165 } 166 167 // Sqrt sets e to a square root of x. If x is not a square, Sqrt returns 168 // false and e is unchanged. e and x can overlap. 169 func Sqrt(e, x *gfP) (isSquare bool) { 170 candidate, b, i := &gfP{}, &gfP{}, &gfP{} 171 sqrtCandidate(candidate, x) 172 gfpMul(b, twoExpPMinus5Over8, candidate) // b=ta1 173 gfpMul(candidate, x, b) // a1=fb 174 gfpMul(i, two, candidate) // i=2(fb) 175 gfpMul(i, i, b) // i=2(fb)b 176 gfpSub(i, i, one) // i=2(fb)b-1 177 gfpMul(i, candidate, i) // i=(fb)(2(fb)b-1) 178 square := new(gfP).Square(i, 1) 179 if square.Equal(x) != 1 { 180 return false 181 } 182 e.Set(i) 183 return true 184 } 185 186 // sqrtCandidate sets z to a square root candidate for x. z and x must not overlap. 187 func sqrtCandidate(z, x *gfP) { 188 // Since p = 8k+5, exponentiation by (p - 5) / 8 yields a square root candidate. 189 // 190 // The sequence of 54 multiplications and 248 squarings is derived from the 191 // following addition chain generated with github.com/mmcloughlin/addchain v0.4.0. 192 // 193 // _10 = 2*1 194 // _100 = 2*_10 195 // _110 = _10 + _100 196 // _1010 = _100 + _110 197 // _1011 = 1 + _1010 198 // _1101 = _10 + _1011 199 // _1111 = _10 + _1101 200 // _10000 = 1 + _1111 201 // _10101 = _110 + _1111 202 // _11011 = _110 + _10101 203 // _11101 = _10 + _11011 204 // _11111 = _10 + _11101 205 // _101001 = _1010 + _11111 206 // _101011 = _10 + _101001 207 // _111011 = _10000 + _101011 208 // _1000101 = _1010 + _111011 209 // _1001111 = _1010 + _1000101 210 // _1010001 = _10 + _1001111 211 // _1011011 = _1010 + _1010001 212 // _1011101 = _10 + _1011011 213 // _1011111 = _10 + _1011101 214 // _1100011 = _100 + _1011111 215 // _1101001 = _110 + _1100011 216 // _1101101 = _100 + _1101001 217 // _1101111 = _10 + _1101101 218 // _1110101 = _110 + _1101111 219 // i72 = ((_1011011 << 3 + 1) << 33 + _10101) << 8 220 // i94 = ((_11101 + i72) << 9 + _1101111) << 10 + _1110101 221 // i116 = ((2*i94 + 1) << 14 + _1110101) << 5 222 // i129 = 2*((_1101 + i116) << 9 + _1110101) + _10101 223 // i153 = ((i129 << 5 + _1011) << 9 + _111011) << 8 224 // i174 = ((_11101 + i153) << 9 + _101001) << 9 + _11111 225 // i201 = ((i174 << 8 + _101001) << 9 + _1101001) << 8 226 // i220 = ((_1100011 + i201) << 8 + _1001111) << 8 + _1011101 227 // i244 = ((i220 << 7 + _1101101) << 7 + _1011111) << 8 228 // i260 = ((_101011 + i244) << 6 + _11111) << 7 + _11011 229 // i286 = ((i260 << 9 + _1001111) << 7 + _1100011) << 8 230 // return ((_1010001 + i286) << 8 + _1000101) << 5 + _1111 231 // 232 var t0 = new(gfP) 233 var t1 = new(gfP) 234 var t2 = new(gfP) 235 var t3 = new(gfP) 236 var t4 = new(gfP) 237 var t5 = new(gfP) 238 var t6 = new(gfP) 239 var t7 = new(gfP) 240 var t8 = new(gfP) 241 var t9 = new(gfP) 242 var t10 = new(gfP) 243 var t11 = new(gfP) 244 var t12 = new(gfP) 245 var t13 = new(gfP) 246 var t14 = new(gfP) 247 var t15 = new(gfP) 248 var t16 = new(gfP) 249 var t17 = new(gfP) 250 var t18 = new(gfP) 251 var t19 = new(gfP) 252 253 t18.Square(x, 1) 254 t8.Square(t18, 1) 255 t16.Mul(t18, t8) 256 t2.Mul(t8, t16) 257 t14.Mul(x, t2) 258 t17.Mul(t18, t14) 259 z.Mul(t18, t17) 260 t0.Mul(x, z) 261 t15.Mul(t16, z) 262 t4.Mul(t16, t15) 263 t12.Mul(t18, t4) 264 t5.Mul(t18, t12) 265 t11.Mul(t2, t5) 266 t6.Mul(t18, t11) 267 t13.Mul(t0, t6) 268 t0.Mul(t2, t13) 269 t3.Mul(t2, t0) 270 t1.Mul(t18, t3) 271 t19.Mul(t2, t1) 272 t9.Mul(t18, t19) 273 t7.Mul(t18, t9) 274 t2.Mul(t8, t7) 275 t10.Mul(t16, t2) 276 t8.Mul(t8, t10) 277 t18.Mul(t18, t8) 278 t16.Mul(t16, t18) 279 t19.Square(t19, 3) 280 t19.Mul(x, t19) 281 t19.Square(t19, 33) 282 t19.Mul(t15, t19) 283 t19.Square(t19, 8) 284 t19.Mul(t12, t19) 285 t19.Square(t19, 9) 286 t18.Mul(t18, t19) 287 t18.Square(t18, 10) 288 t18.Mul(t16, t18) 289 t18.Square(t18, 1) 290 t18.Mul(x, t18) 291 t18.Square(t18, 14) 292 t18.Mul(t16, t18) 293 t18.Square(t18, 5) 294 t17.Mul(t17, t18) 295 t17.Square(t17, 9) 296 t16.Mul(t16, t17) 297 t16.Square(t16, 1) 298 t15.Mul(t15, t16) 299 t15.Square(t15, 5) 300 t14.Mul(t14, t15) 301 t14.Square(t14, 9) 302 t13.Mul(t13, t14) 303 t13.Square(t13, 8) 304 t12.Mul(t12, t13) 305 t12.Square(t12, 9) 306 t12.Mul(t11, t12) 307 t12.Square(t12, 9) 308 t12.Mul(t5, t12) 309 t12.Square(t12, 8) 310 t11.Mul(t11, t12) 311 t11.Square(t11, 9) 312 t10.Mul(t10, t11) 313 t10.Square(t10, 8) 314 t10.Mul(t2, t10) 315 t10.Square(t10, 8) 316 t10.Mul(t3, t10) 317 t10.Square(t10, 8) 318 t9.Mul(t9, t10) 319 t9.Square(t9, 7) 320 t8.Mul(t8, t9) 321 t8.Square(t8, 7) 322 t7.Mul(t7, t8) 323 t7.Square(t7, 8) 324 t6.Mul(t6, t7) 325 t6.Square(t6, 6) 326 t5.Mul(t5, t6) 327 t5.Square(t5, 7) 328 t4.Mul(t4, t5) 329 t4.Square(t4, 9) 330 t3.Mul(t3, t4) 331 t3.Square(t3, 7) 332 t2.Mul(t2, t3) 333 t2.Square(t2, 8) 334 t1.Mul(t1, t2) 335 t1.Square(t1, 8) 336 t0.Mul(t0, t1) 337 t0.Square(t0, 5) 338 z.Mul(z, t0) 339 }