gmsm/internal/sm9/bn256/gfp_invert_sqrt.go

340 lines
8.3 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

// Code generated by addchain. DO NOT EDIT.
package bn256
// Invert sets e = 1/x, and returns e.
//
// If x == 0, Invert returns e = 0.
func (e *gfP) Invert(x *gfP) *gfP {
// Inversion is implemented as exponentiation with exponent p 2.
// The sequence of 56 multiplications and 250 squarings is derived from the
// following addition chain generated with github.com/mmcloughlin/addchain v0.4.0.
//
// _10 = 2*1
// _100 = 2*_10
// _110 = _10 + _100
// _1010 = _100 + _110
// _1011 = 1 + _1010
// _1101 = _10 + _1011
// _10000 = _110 + _1010
// _10101 = _1010 + _1011
// _11011 = _110 + _10101
// _11101 = _10 + _11011
// _11111 = _10 + _11101
// _101001 = _1010 + _11111
// _101011 = _10 + _101001
// _111011 = _10000 + _101011
// _1000101 = _1010 + _111011
// _1001111 = _1010 + _1000101
// _1010001 = _10 + _1001111
// _1011011 = _1010 + _1010001
// _1011101 = _10 + _1011011
// _1011111 = _10 + _1011101
// _1100011 = _100 + _1011111
// _1101001 = _110 + _1100011
// _1101101 = _100 + _1101001
// _1101111 = _10 + _1101101
// _1110101 = _110 + _1101111
// _1111011 = _110 + _1110101
// _10110110 = _111011 + _1111011
// i72 = ((_10110110 << 2 + 1) << 33 + _10101) << 8
// i94 = ((_11101 + i72) << 9 + _1101111) << 10 + _1110101
// i116 = ((2*i94 + 1) << 14 + _1110101) << 5
// i129 = 2*((_1101 + i116) << 9 + _1111011 + _100)
// i146 = ((1 + i129) << 5 + _1011) << 9 + _111011
// i174 = ((i146 << 8 + _11101) << 9 + _101001) << 9
// i194 = ((_11111 + i174) << 8 + _101001) << 9 + _1101001
// i220 = ((i194 << 8 + _1100011) << 8 + _1001111) << 8
// i237 = ((_1011101 + i220) << 7 + _1101101) << 7 + _1011111
// i260 = ((i237 << 8 + _101011) << 6 + _11111) << 7
// i279 = ((_11011 + i260) << 9 + _1001111) << 7 + _1100011
// i305 = ((i279 << 8 + _1010001) << 8 + _1000101) << 8
// return _1111011 + i305
//
var z = new(gfP).Set(e)
var t0 = new(gfP)
var t1 = new(gfP)
var t2 = new(gfP)
var t3 = new(gfP)
var t4 = new(gfP)
var t5 = new(gfP)
var t6 = new(gfP)
var t7 = new(gfP)
var t8 = new(gfP)
var t9 = new(gfP)
var t10 = new(gfP)
var t11 = new(gfP)
var t12 = new(gfP)
var t13 = new(gfP)
var t14 = new(gfP)
var t15 = new(gfP)
var t16 = new(gfP)
var t17 = new(gfP)
var t18 = new(gfP)
var t19 = new(gfP)
var t20 = new(gfP)
t17.Square(x, 1)
t15.Square(t17, 1)
z.Mul(t17, t15)
t2.Mul(t15, z)
t14.Mul(x, t2)
t16.Mul(t17, t14)
t0.Mul(z, t2)
t19.Mul(t2, t14)
t4.Mul(z, t19)
t12.Mul(t17, t4)
t5.Mul(t17, t12)
t11.Mul(t2, t5)
t6.Mul(t17, t11)
t13.Mul(t0, t6)
t0.Mul(t2, t13)
t3.Mul(t2, t0)
t1.Mul(t17, t3)
t2.Mul(t2, t1)
t9.Mul(t17, t2)
t7.Mul(t17, t9)
t2.Mul(t15, t7)
t10.Mul(z, t2)
t8.Mul(t15, t10)
t18.Mul(t17, t8)
t17.Mul(z, t18)
z.Mul(z, t17)
t20.Mul(t13, z)
t20.Square(t20, 2)
t20.Mul(x, t20)
t20.Square(t20, 33)
t19.Mul(t19, t20)
t19.Square(t19, 8)
t19.Mul(t12, t19)
t19.Square(t19, 9)
t18.Mul(t18, t19)
t18.Square(t18, 10)
t18.Mul(t17, t18)
t18.Square(t18, 1)
t18.Mul(x, t18)
t18.Square(t18, 14)
t17.Mul(t17, t18)
t17.Square(t17, 5)
t16.Mul(t16, t17)
t16.Square(t16, 9)
t16.Mul(z, t16)
t15.Mul(t15, t16)
t15.Square(t15, 1)
t15.Mul(x, t15)
t15.Square(t15, 5)
t14.Mul(t14, t15)
t14.Square(t14, 9)
t13.Mul(t13, t14)
t13.Square(t13, 8)
t12.Mul(t12, t13)
t12.Square(t12, 9)
t12.Mul(t11, t12)
t12.Square(t12, 9)
t12.Mul(t5, t12)
t12.Square(t12, 8)
t11.Mul(t11, t12)
t11.Square(t11, 9)
t10.Mul(t10, t11)
t10.Square(t10, 8)
t10.Mul(t2, t10)
t10.Square(t10, 8)
t10.Mul(t3, t10)
t10.Square(t10, 8)
t9.Mul(t9, t10)
t9.Square(t9, 7)
t8.Mul(t8, t9)
t8.Square(t8, 7)
t7.Mul(t7, t8)
t7.Square(t7, 8)
t6.Mul(t6, t7)
t6.Square(t6, 6)
t5.Mul(t5, t6)
t5.Square(t5, 7)
t4.Mul(t4, t5)
t4.Square(t4, 9)
t3.Mul(t3, t4)
t3.Square(t3, 7)
t2.Mul(t2, t3)
t2.Square(t2, 8)
t1.Mul(t1, t2)
t1.Square(t1, 8)
t0.Mul(t0, t1)
t0.Square(t0, 8)
z.Mul(z, t0)
return e.Set(z)
}
// Sqrt sets e to a square root of x. If x is not a square, Sqrt returns
// false and e is unchanged. e and x can overlap.
func Sqrt(e, x *gfP) (isSquare bool) {
candidate, b, i := &gfP{}, &gfP{}, &gfP{}
sqrtCandidate(candidate, x)
gfpMul(b, twoExpPMinus5Over8, candidate) // b=ta1
gfpMul(candidate, x, b) // a1=fb
gfpMul(i, two, candidate) // i=2(fb)
gfpMul(i, i, b) // i=2(fb)b
gfpSub(i, i, one) // i=2(fb)b-1
gfpMul(i, candidate, i) // i=(fb)(2(fb)b-1)
square := new(gfP).Square(i, 1)
if square.Equal(x) != 1 {
return false
}
e.Set(i)
return true
}
// sqrtCandidate sets z to a square root candidate for x. z and x must not overlap.
func sqrtCandidate(z, x *gfP) {
// Since p = 8k+5, exponentiation by (p - 5) / 8 yields a square root candidate.
//
// The sequence of 54 multiplications and 248 squarings is derived from the
// following addition chain generated with github.com/mmcloughlin/addchain v0.4.0.
//
// _10 = 2*1
// _100 = 2*_10
// _110 = _10 + _100
// _1010 = _100 + _110
// _1011 = 1 + _1010
// _1101 = _10 + _1011
// _1111 = _10 + _1101
// _10000 = 1 + _1111
// _10101 = _110 + _1111
// _11011 = _110 + _10101
// _11101 = _10 + _11011
// _11111 = _10 + _11101
// _101001 = _1010 + _11111
// _101011 = _10 + _101001
// _111011 = _10000 + _101011
// _1000101 = _1010 + _111011
// _1001111 = _1010 + _1000101
// _1010001 = _10 + _1001111
// _1011011 = _1010 + _1010001
// _1011101 = _10 + _1011011
// _1011111 = _10 + _1011101
// _1100011 = _100 + _1011111
// _1101001 = _110 + _1100011
// _1101101 = _100 + _1101001
// _1101111 = _10 + _1101101
// _1110101 = _110 + _1101111
// i72 = ((_1011011 << 3 + 1) << 33 + _10101) << 8
// i94 = ((_11101 + i72) << 9 + _1101111) << 10 + _1110101
// i116 = ((2*i94 + 1) << 14 + _1110101) << 5
// i129 = 2*((_1101 + i116) << 9 + _1110101) + _10101
// i153 = ((i129 << 5 + _1011) << 9 + _111011) << 8
// i174 = ((_11101 + i153) << 9 + _101001) << 9 + _11111
// i201 = ((i174 << 8 + _101001) << 9 + _1101001) << 8
// i220 = ((_1100011 + i201) << 8 + _1001111) << 8 + _1011101
// i244 = ((i220 << 7 + _1101101) << 7 + _1011111) << 8
// i260 = ((_101011 + i244) << 6 + _11111) << 7 + _11011
// i286 = ((i260 << 9 + _1001111) << 7 + _1100011) << 8
// return ((_1010001 + i286) << 8 + _1000101) << 5 + _1111
//
var t0 = new(gfP)
var t1 = new(gfP)
var t2 = new(gfP)
var t3 = new(gfP)
var t4 = new(gfP)
var t5 = new(gfP)
var t6 = new(gfP)
var t7 = new(gfP)
var t8 = new(gfP)
var t9 = new(gfP)
var t10 = new(gfP)
var t11 = new(gfP)
var t12 = new(gfP)
var t13 = new(gfP)
var t14 = new(gfP)
var t15 = new(gfP)
var t16 = new(gfP)
var t17 = new(gfP)
var t18 = new(gfP)
var t19 = new(gfP)
t18.Square(x, 1)
t8.Square(t18, 1)
t16.Mul(t18, t8)
t2.Mul(t8, t16)
t14.Mul(x, t2)
t17.Mul(t18, t14)
z.Mul(t18, t17)
t0.Mul(x, z)
t15.Mul(t16, z)
t4.Mul(t16, t15)
t12.Mul(t18, t4)
t5.Mul(t18, t12)
t11.Mul(t2, t5)
t6.Mul(t18, t11)
t13.Mul(t0, t6)
t0.Mul(t2, t13)
t3.Mul(t2, t0)
t1.Mul(t18, t3)
t19.Mul(t2, t1)
t9.Mul(t18, t19)
t7.Mul(t18, t9)
t2.Mul(t8, t7)
t10.Mul(t16, t2)
t8.Mul(t8, t10)
t18.Mul(t18, t8)
t16.Mul(t16, t18)
t19.Square(t19, 3)
t19.Mul(x, t19)
t19.Square(t19, 33)
t19.Mul(t15, t19)
t19.Square(t19, 8)
t19.Mul(t12, t19)
t19.Square(t19, 9)
t18.Mul(t18, t19)
t18.Square(t18, 10)
t18.Mul(t16, t18)
t18.Square(t18, 1)
t18.Mul(x, t18)
t18.Square(t18, 14)
t18.Mul(t16, t18)
t18.Square(t18, 5)
t17.Mul(t17, t18)
t17.Square(t17, 9)
t16.Mul(t16, t17)
t16.Square(t16, 1)
t15.Mul(t15, t16)
t15.Square(t15, 5)
t14.Mul(t14, t15)
t14.Square(t14, 9)
t13.Mul(t13, t14)
t13.Square(t13, 8)
t12.Mul(t12, t13)
t12.Square(t12, 9)
t12.Mul(t11, t12)
t12.Square(t12, 9)
t12.Mul(t5, t12)
t12.Square(t12, 8)
t11.Mul(t11, t12)
t11.Square(t11, 9)
t10.Mul(t10, t11)
t10.Square(t10, 8)
t10.Mul(t2, t10)
t10.Square(t10, 8)
t10.Mul(t3, t10)
t10.Square(t10, 8)
t9.Mul(t9, t10)
t9.Square(t9, 7)
t8.Mul(t8, t9)
t8.Square(t8, 7)
t7.Mul(t7, t8)
t7.Square(t7, 8)
t6.Mul(t6, t7)
t6.Square(t6, 6)
t5.Mul(t5, t6)
t5.Square(t5, 7)
t4.Mul(t4, t5)
t4.Square(t4, 9)
t3.Mul(t3, t4)
t3.Square(t3, 7)
t2.Mul(t2, t3)
t2.Square(t2, 8)
t1.Mul(t1, t2)
t1.Square(t1, 8)
t0.Mul(t0, t1)
t0.Square(t0, 5)
z.Mul(z, t0)
}