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  }