gitee.com/zhaochuninhefei/gmgo@v0.0.31-0.20240209061119-069254a02979/sm2soft/p256.go (about)

     1  // Copyright (c) 2022 zhaochun
     2  // gmgo is licensed under Mulan PSL v2.
     3  // You can use this software according to the terms and conditions of the Mulan PSL v2.
     4  // You may obtain a copy of Mulan PSL v2 at:
     5  //          http://license.coscl.org.cn/MulanPSL2
     6  // THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT, MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
     7  // See the Mulan PSL v2 for more details.
     8  
     9  /*
    10  sm2soft 是sm2的纯软实现,基于tjfoc国密算法库`tjfoc/gmsm`做了少量修改。
    11  对应版权声明: thrid_licenses/github.com/tjfoc/gmsm/版权声明
    12  */
    13  
    14  package sm2soft
    15  
    16  /*
    17  sm2/p256.go 定义sm2P256椭圆曲线
    18  */
    19  
    20  import (
    21  	"crypto/elliptic"
    22  	"math/big"
    23  	"sync"
    24  )
    25  
    26  // SM2P256椭圆曲线
    27  type sm2P256Curve struct {
    28  	RInverse *big.Int
    29  	*elliptic.CurveParams
    30  	a, b, gx, gy sm2P256FieldElement
    31  }
    32  
    33  var initonce sync.Once
    34  var sm2P256 sm2P256Curve
    35  
    36  type sm2P256FieldElement [9]uint32
    37  type sm2P256LargeFieldElement [17]uint64
    38  
    39  const (
    40  	bottom28Bits = 0xFFFFFFF
    41  	bottom29Bits = 0x1FFFFFFF
    42  )
    43  
    44  // 初始化sm2椭圆曲线 sm2P256
    45  func initP256Sm2() {
    46  	sm2P256.CurveParams = &elliptic.CurveParams{Name: "SM2-P-256"} // sm2
    47  	A, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFC", 16)
    48  	//SM2椭圆曲线公钥密码算法推荐曲线参数
    49  	sm2P256.P, _ = new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16)
    50  	sm2P256.N, _ = new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", 16)
    51  	sm2P256.B, _ = new(big.Int).SetString("28E9FA9E9D9F5E344D5A9E4BCF6509A7F39789F515AB8F92DDBCBD414D940E93", 16)
    52  	sm2P256.Gx, _ = new(big.Int).SetString("32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16)
    53  	sm2P256.Gy, _ = new(big.Int).SetString("BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", 16)
    54  	sm2P256.RInverse, _ = new(big.Int).SetString("7ffffffd80000002fffffffe000000017ffffffe800000037ffffffc80000002", 16)
    55  	sm2P256.BitSize = 256
    56  	sm2P256FromBig(&sm2P256.a, A)
    57  	sm2P256FromBig(&sm2P256.gx, sm2P256.Gx)
    58  	sm2P256FromBig(&sm2P256.gy, sm2P256.Gy)
    59  	sm2P256FromBig(&sm2P256.b, sm2P256.B)
    60  }
    61  
    62  // P256Sm2 获取SM2P256椭圆曲线
    63  // 该曲线是一个单例
    64  func P256Sm2() elliptic.Curve {
    65  	// 为确保sm2P256是一个单例,这里只初始化一次sm2P256
    66  	initonce.Do(initP256Sm2)
    67  	return sm2P256
    68  }
    69  
    70  // Params 获取SM2P256椭圆曲线的曲线参数
    71  func (curve sm2P256Curve) Params() *elliptic.CurveParams {
    72  	return sm2P256.CurveParams
    73  }
    74  
    75  // IsOnCurve y^2 = x^3 + ax + b
    76  // 判断给定的X,Y座标是否在sm2P256Curve曲线上
    77  func (curve sm2P256Curve) IsOnCurve(X, Y *big.Int) bool {
    78  	var a, x, y, y2, x3 sm2P256FieldElement
    79  
    80  	sm2P256FromBig(&x, X)
    81  	sm2P256FromBig(&y, Y)
    82  
    83  	sm2P256Square(&x3, &x)       // x3 = x ^ 2
    84  	sm2P256Mul(&x3, &x3, &x)     // x3 = x ^ 2 * x
    85  	sm2P256Mul(&a, &curve.a, &x) // a = a * x
    86  	sm2P256Add(&x3, &x3, &a)
    87  	sm2P256Add(&x3, &x3, &curve.b)
    88  
    89  	sm2P256Square(&y2, &y) // y2 = y ^ 2
    90  	return sm2P256ToBig(&x3).Cmp(sm2P256ToBig(&y2)) == 0
    91  }
    92  
    93  func zForAffine(x, y *big.Int) *big.Int {
    94  	z := new(big.Int)
    95  	if x.Sign() != 0 || y.Sign() != 0 {
    96  		z.SetInt64(1)
    97  	}
    98  	return z
    99  }
   100  
   101  func (curve sm2P256Curve) Add(x1, y1, x2, y2 *big.Int) (*big.Int, *big.Int) {
   102  	var X1, Y1, Z1, X2, Y2, Z2, X3, Y3, Z3 sm2P256FieldElement
   103  
   104  	z1 := zForAffine(x1, y1)
   105  	z2 := zForAffine(x2, y2)
   106  	sm2P256FromBig(&X1, x1)
   107  	sm2P256FromBig(&Y1, y1)
   108  	sm2P256FromBig(&Z1, z1)
   109  	sm2P256FromBig(&X2, x2)
   110  	sm2P256FromBig(&Y2, y2)
   111  	sm2P256FromBig(&Z2, z2)
   112  	sm2P256PointAdd(&X1, &Y1, &Z1, &X2, &Y2, &Z2, &X3, &Y3, &Z3)
   113  	return sm2P256ToAffine(&X3, &Y3, &Z3)
   114  }
   115  
   116  func (curve sm2P256Curve) Double(x1, y1 *big.Int) (*big.Int, *big.Int) {
   117  	var X1, Y1, Z1 sm2P256FieldElement
   118  
   119  	z1 := zForAffine(x1, y1)
   120  	sm2P256FromBig(&X1, x1)
   121  	sm2P256FromBig(&Y1, y1)
   122  	sm2P256FromBig(&Z1, z1)
   123  	sm2P256PointDouble(&X1, &Y1, &Z1, &X1, &Y1, &Z1)
   124  	return sm2P256ToAffine(&X1, &Y1, &Z1)
   125  }
   126  
   127  func (curve sm2P256Curve) ScalarMult(x1, y1 *big.Int, k []byte) (*big.Int, *big.Int) {
   128  	var X, Y, Z, X1, Y1 sm2P256FieldElement
   129  	sm2P256FromBig(&X1, x1)
   130  	sm2P256FromBig(&Y1, y1)
   131  	scalar := sm2GenrateWNaf(k)
   132  	scalarReversed := WNafReversed(scalar)
   133  	sm2P256ScalarMult(&X, &Y, &Z, &X1, &Y1, scalarReversed)
   134  	return sm2P256ToAffine(&X, &Y, &Z)
   135  }
   136  
   137  func (curve sm2P256Curve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) {
   138  	var scalarReversed [32]byte
   139  	var X, Y, Z sm2P256FieldElement
   140  
   141  	sm2P256GetScalar(&scalarReversed, k)
   142  	sm2P256ScalarBaseMult(&X, &Y, &Z, &scalarReversed)
   143  	return sm2P256ToAffine(&X, &Y, &Z)
   144  }
   145  
   146  var sm2P256Precomputed = [9 * 2 * 15 * 2]uint32{
   147  	0x830053d, 0x328990f, 0x6c04fe1, 0xc0f72e5, 0x1e19f3c, 0x666b093, 0x175a87b, 0xec38276, 0x222cf4b,
   148  	0x185a1bba, 0x354e593, 0x1295fac1, 0xf2bc469, 0x47c60fa, 0xc19b8a9, 0xf63533e, 0x903ae6b, 0xc79acba,
   149  	0x15b061a4, 0x33e020b, 0xdffb34b, 0xfcf2c8, 0x16582e08, 0x262f203, 0xfb34381, 0xa55452, 0x604f0ff,
   150  	0x41f1f90, 0xd64ced2, 0xee377bf, 0x75f05f0, 0x189467ae, 0xe2244e, 0x1e7700e8, 0x3fbc464, 0x9612d2e,
   151  	0x1341b3b8, 0xee84e23, 0x1edfa5b4, 0x14e6030, 0x19e87be9, 0x92f533c, 0x1665d96c, 0x226653e, 0xa238d3e,
   152  	0xf5c62c, 0x95bb7a, 0x1f0e5a41, 0x28789c3, 0x1f251d23, 0x8726609, 0xe918910, 0x8096848, 0xf63d028,
   153  	0x152296a1, 0x9f561a8, 0x14d376fb, 0x898788a, 0x61a95fb, 0xa59466d, 0x159a003d, 0x1ad1698, 0x93cca08,
   154  	0x1b314662, 0x706e006, 0x11ce1e30, 0x97b710, 0x172fbc0d, 0x8f50158, 0x11c7ffe7, 0xd182cce, 0xc6ad9e8,
   155  	0x12ea31b2, 0xc4e4f38, 0x175b0d96, 0xec06337, 0x75a9c12, 0xb001fdf, 0x93e82f5, 0x34607de, 0xb8035ed,
   156  	0x17f97924, 0x75cf9e6, 0xdceaedd, 0x2529924, 0x1a10c5ff, 0xb1a54dc, 0x19464d8, 0x2d1997, 0xde6a110,
   157  	0x1e276ee5, 0x95c510c, 0x1aca7c7a, 0xfe48aca, 0x121ad4d9, 0xe4132c6, 0x8239b9d, 0x40ea9cd, 0x816c7b,
   158  	0x632d7a4, 0xa679813, 0x5911fcf, 0x82b0f7c, 0x57b0ad5, 0xbef65, 0xd541365, 0x7f9921f, 0xc62e7a,
   159  	0x3f4b32d, 0x58e50e1, 0x6427aed, 0xdcdda67, 0xe8c2d3e, 0x6aa54a4, 0x18df4c35, 0x49a6a8e, 0x3cd3d0c,
   160  	0xd7adf2, 0xcbca97, 0x1bda5f2d, 0x3258579, 0x606b1e6, 0x6fc1b5b, 0x1ac27317, 0x503ca16, 0xa677435,
   161  	0x57bc73, 0x3992a42, 0xbab987b, 0xfab25eb, 0x128912a4, 0x90a1dc4, 0x1402d591, 0x9ffbcfc, 0xaa48856,
   162  	0x7a7c2dc, 0xcefd08a, 0x1b29bda6, 0xa785641, 0x16462d8c, 0x76241b7, 0x79b6c3b, 0x204ae18, 0xf41212b,
   163  	0x1f567a4d, 0xd6ce6db, 0xedf1784, 0x111df34, 0x85d7955, 0x55fc189, 0x1b7ae265, 0xf9281ac, 0xded7740,
   164  	0xf19468b, 0x83763bb, 0x8ff7234, 0x3da7df8, 0x9590ac3, 0xdc96f2a, 0x16e44896, 0x7931009, 0x99d5acc,
   165  	0x10f7b842, 0xaef5e84, 0xc0310d7, 0xdebac2c, 0x2a7b137, 0x4342344, 0x19633649, 0x3a10624, 0x4b4cb56,
   166  	0x1d809c59, 0xac007f, 0x1f0f4bcd, 0xa1ab06e, 0xc5042cf, 0x82c0c77, 0x76c7563, 0x22c30f3, 0x3bf1568,
   167  	0x7a895be, 0xfcca554, 0x12e90e4c, 0x7b4ab5f, 0x13aeb76b, 0x5887e2c, 0x1d7fe1e3, 0x908c8e3, 0x95800ee,
   168  	0xb36bd54, 0xf08905d, 0x4e73ae8, 0xf5a7e48, 0xa67cb0, 0x50e1067, 0x1b944a0a, 0xf29c83a, 0xb23cfb9,
   169  	0xbe1db1, 0x54de6e8, 0xd4707f2, 0x8ebcc2d, 0x2c77056, 0x1568ce4, 0x15fcc849, 0x4069712, 0xe2ed85f,
   170  	0x2c5ff09, 0x42a6929, 0x628e7ea, 0xbd5b355, 0xaf0bd79, 0xaa03699, 0xdb99816, 0x4379cef, 0x81d57b,
   171  	0x11237f01, 0xe2a820b, 0xfd53b95, 0x6beb5ee, 0x1aeb790c, 0xe470d53, 0x2c2cfee, 0x1c1d8d8, 0xa520fc4,
   172  	0x1518e034, 0xa584dd4, 0x29e572b, 0xd4594fc, 0x141a8f6f, 0x8dfccf3, 0x5d20ba3, 0x2eb60c3, 0x9f16eb0,
   173  	0x11cec356, 0xf039f84, 0x1b0990c1, 0xc91e526, 0x10b65bae, 0xf0616e8, 0x173fa3ff, 0xec8ccf9, 0xbe32790,
   174  	0x11da3e79, 0xe2f35c7, 0x908875c, 0xdacf7bd, 0x538c165, 0x8d1487f, 0x7c31aed, 0x21af228, 0x7e1689d,
   175  	0xdfc23ca, 0x24f15dc, 0x25ef3c4, 0x35248cd, 0x99a0f43, 0xa4b6ecc, 0xd066b3, 0x2481152, 0x37a7688,
   176  	0x15a444b6, 0xb62300c, 0x4b841b, 0xa655e79, 0xd53226d, 0xbeb348a, 0x127f3c2, 0xb989247, 0x71a277d,
   177  	0x19e9dfcb, 0xb8f92d0, 0xe2d226c, 0x390a8b0, 0x183cc462, 0x7bd8167, 0x1f32a552, 0x5e02db4, 0xa146ee9,
   178  	0x1a003957, 0x1c95f61, 0x1eeec155, 0x26f811f, 0xf9596ba, 0x3082bfb, 0x96df083, 0x3e3a289, 0x7e2d8be,
   179  	0x157a63e0, 0x99b8941, 0x1da7d345, 0xcc6cd0, 0x10beed9a, 0x48e83c0, 0x13aa2e25, 0x7cad710, 0x4029988,
   180  	0x13dfa9dd, 0xb94f884, 0x1f4adfef, 0xb88543, 0x16f5f8dc, 0xa6a67f4, 0x14e274e2, 0x5e56cf4, 0x2f24ef,
   181  	0x1e9ef967, 0xfe09bad, 0xfe079b3, 0xcc0ae9e, 0xb3edf6d, 0x3e961bc, 0x130d7831, 0x31043d6, 0xba986f9,
   182  	0x1d28055, 0x65240ca, 0x4971fa3, 0x81b17f8, 0x11ec34a5, 0x8366ddc, 0x1471809, 0xfa5f1c6, 0xc911e15,
   183  	0x8849491, 0xcf4c2e2, 0x14471b91, 0x39f75be, 0x445c21e, 0xf1585e9, 0x72cc11f, 0x4c79f0c, 0xe5522e1,
   184  	0x1874c1ee, 0x4444211, 0x7914884, 0x3d1b133, 0x25ba3c, 0x4194f65, 0x1c0457ef, 0xac4899d, 0xe1fa66c,
   185  	0x130a7918, 0x9b8d312, 0x4b1c5c8, 0x61ccac3, 0x18c8aa6f, 0xe93cb0a, 0xdccb12c, 0xde10825, 0x969737d,
   186  	0xf58c0c3, 0x7cee6a9, 0xc2c329a, 0xc7f9ed9, 0x107b3981, 0x696a40e, 0x152847ff, 0x4d88754, 0xb141f47,
   187  	0x5a16ffe, 0x3a7870a, 0x18667659, 0x3b72b03, 0xb1c9435, 0x9285394, 0xa00005a, 0x37506c, 0x2edc0bb,
   188  	0x19afe392, 0xeb39cac, 0x177ef286, 0xdf87197, 0x19f844ed, 0x31fe8, 0x15f9bfd, 0x80dbec, 0x342e96e,
   189  	0x497aced, 0xe88e909, 0x1f5fa9ba, 0x530a6ee, 0x1ef4e3f1, 0x69ffd12, 0x583006d, 0x2ecc9b1, 0x362db70,
   190  	0x18c7bdc5, 0xf4bb3c5, 0x1c90b957, 0xf067c09, 0x9768f2b, 0xf73566a, 0x1939a900, 0x198c38a, 0x202a2a1,
   191  	0x4bbf5a6, 0x4e265bc, 0x1f44b6e7, 0x185ca49, 0xa39e81b, 0x24aff5b, 0x4acc9c2, 0x638bdd3, 0xb65b2a8,
   192  	0x6def8be, 0xb94537a, 0x10b81dee, 0xe00ec55, 0x2f2cdf7, 0xc20622d, 0x2d20f36, 0xe03c8c9, 0x898ea76,
   193  	0x8e3921b, 0x8905bff, 0x1e94b6c8, 0xee7ad86, 0x154797f2, 0xa620863, 0x3fbd0d9, 0x1f3caab, 0x30c24bd,
   194  	0x19d3892f, 0x59c17a2, 0x1ab4b0ae, 0xf8714ee, 0x90c4098, 0xa9c800d, 0x1910236b, 0xea808d3, 0x9ae2f31,
   195  	0x1a15ad64, 0xa48c8d1, 0x184635a4, 0xb725ef1, 0x11921dcc, 0x3f866df, 0x16c27568, 0xbdf580a, 0xb08f55c,
   196  	0x186ee1c, 0xb1627fa, 0x34e82f6, 0x933837e, 0xf311be5, 0xfedb03b, 0x167f72cd, 0xa5469c0, 0x9c82531,
   197  	0xb92a24b, 0x14fdc8b, 0x141980d1, 0xbdc3a49, 0x7e02bb1, 0xaf4e6dd, 0x106d99e1, 0xd4616fc, 0x93c2717,
   198  	0x1c0a0507, 0xc6d5fed, 0x9a03d8b, 0xa1d22b0, 0x127853e3, 0xc4ac6b8, 0x1a048cf7, 0x9afb72c, 0x65d485d,
   199  	0x72d5998, 0xe9fa744, 0xe49e82c, 0x253cf80, 0x5f777ce, 0xa3799a5, 0x17270cbb, 0xc1d1ef0, 0xdf74977,
   200  	0x114cb859, 0xfa8e037, 0xb8f3fe5, 0xc734cc6, 0x70d3d61, 0xeadac62, 0x12093dd0, 0x9add67d, 0x87200d6,
   201  	0x175bcbb, 0xb29b49f, 0x1806b79c, 0x12fb61f, 0x170b3a10, 0x3aaf1cf, 0xa224085, 0x79d26af, 0x97759e2,
   202  	0x92e19f1, 0xb32714d, 0x1f00d9f1, 0xc728619, 0x9e6f627, 0xe745e24, 0x18ea4ace, 0xfc60a41, 0x125f5b2,
   203  	0xc3cf512, 0x39ed486, 0xf4d15fa, 0xf9167fd, 0x1c1f5dd5, 0xc21a53e, 0x1897930, 0x957a112, 0x21059a0,
   204  	0x1f9e3ddc, 0xa4dfced, 0x8427f6f, 0x726fbe7, 0x1ea658f8, 0x2fdcd4c, 0x17e9b66f, 0xb2e7c2e, 0x39923bf,
   205  	0x1bae104, 0x3973ce5, 0xc6f264c, 0x3511b84, 0x124195d7, 0x11996bd, 0x20be23d, 0xdc437c4, 0x4b4f16b,
   206  	0x11902a0, 0x6c29cc9, 0x1d5ffbe6, 0xdb0b4c7, 0x10144c14, 0x2f2b719, 0x301189, 0x2343336, 0xa0bf2ac,
   207  }
   208  
   209  func sm2P256GetScalar(b *[32]byte, a []byte) {
   210  	var scalarBytes []byte
   211  
   212  	n := new(big.Int).SetBytes(a)
   213  	if n.Cmp(sm2P256.N) >= 0 {
   214  		n.Mod(n, sm2P256.N)
   215  		scalarBytes = n.Bytes()
   216  	} else {
   217  		scalarBytes = a
   218  	}
   219  	for i, v := range scalarBytes {
   220  		b[len(scalarBytes)-(1+i)] = v
   221  	}
   222  }
   223  
   224  func sm2P256PointAddMixed(xOut, yOut, zOut, x1, y1, z1, x2, y2 *sm2P256FieldElement) {
   225  	var z1z1, z1z1z1, s2, u2, h, i, j, r, rr, v, tmp sm2P256FieldElement
   226  
   227  	sm2P256Square(&z1z1, z1)
   228  	sm2P256Add(&tmp, z1, z1)
   229  
   230  	sm2P256Mul(&u2, x2, &z1z1)
   231  	sm2P256Mul(&z1z1z1, z1, &z1z1)
   232  	sm2P256Mul(&s2, y2, &z1z1z1)
   233  	sm2P256Sub(&h, &u2, x1)
   234  	sm2P256Add(&i, &h, &h)
   235  	sm2P256Square(&i, &i)
   236  	sm2P256Mul(&j, &h, &i)
   237  	sm2P256Sub(&r, &s2, y1)
   238  	sm2P256Add(&r, &r, &r)
   239  	sm2P256Mul(&v, x1, &i)
   240  
   241  	sm2P256Mul(zOut, &tmp, &h)
   242  	sm2P256Square(&rr, &r)
   243  	sm2P256Sub(xOut, &rr, &j)
   244  	sm2P256Sub(xOut, xOut, &v)
   245  	sm2P256Sub(xOut, xOut, &v)
   246  
   247  	sm2P256Sub(&tmp, &v, xOut)
   248  	sm2P256Mul(yOut, &tmp, &r)
   249  	sm2P256Mul(&tmp, y1, &j)
   250  	sm2P256Sub(yOut, yOut, &tmp)
   251  	sm2P256Sub(yOut, yOut, &tmp)
   252  }
   253  
   254  // sm2P256CopyConditional sets out=in if mask = 0xffffffff in constant time.
   255  //
   256  // On entry: mask is either 0 or 0xffffffff.
   257  func sm2P256CopyConditional(out, in *sm2P256FieldElement, mask uint32) {
   258  	for i := 0; i < 9; i++ {
   259  		tmp := mask & (in[i] ^ out[i])
   260  		out[i] ^= tmp
   261  	}
   262  }
   263  
   264  // sm2P256SelectAffinePoint sets {out_x,out_y} to the index'th entry of table.
   265  // On entry: index < 16, table[0] must be zero.
   266  func sm2P256SelectAffinePoint(xOut, yOut *sm2P256FieldElement, table []uint32, index uint32) {
   267  	for i := range xOut {
   268  		xOut[i] = 0
   269  	}
   270  	for i := range yOut {
   271  		yOut[i] = 0
   272  	}
   273  
   274  	for i := uint32(1); i < 16; i++ {
   275  		mask := i ^ index
   276  		mask |= mask >> 2
   277  		mask |= mask >> 1
   278  		mask &= 1
   279  		mask--
   280  		for j := range xOut {
   281  			xOut[j] |= table[0] & mask
   282  			table = table[1:]
   283  		}
   284  		for j := range yOut {
   285  			yOut[j] |= table[0] & mask
   286  			table = table[1:]
   287  		}
   288  	}
   289  }
   290  
   291  // sm2P256SelectJacobianPoint sets {out_x,out_y,out_z} to the index'th entry of
   292  // table.
   293  // On entry: index < 16, table[0] must be zero.
   294  func sm2P256SelectJacobianPoint(xOut, yOut, zOut *sm2P256FieldElement, table *[16][3]sm2P256FieldElement, index uint32) {
   295  	for i := range xOut {
   296  		xOut[i] = 0
   297  	}
   298  	for i := range yOut {
   299  		yOut[i] = 0
   300  	}
   301  	for i := range zOut {
   302  		zOut[i] = 0
   303  	}
   304  
   305  	// The implicit value at index 0 is all zero. We don't need to perform that
   306  	// iteration of the loop because we already set out_* to zero.
   307  	for i := uint32(1); i < 16; i++ {
   308  		mask := i ^ index
   309  		mask |= mask >> 2
   310  		mask |= mask >> 1
   311  		mask &= 1
   312  		mask--
   313  		for j := range xOut {
   314  			xOut[j] |= table[i][0][j] & mask
   315  		}
   316  		for j := range yOut {
   317  			yOut[j] |= table[i][1][j] & mask
   318  		}
   319  		for j := range zOut {
   320  			zOut[j] |= table[i][2][j] & mask
   321  		}
   322  	}
   323  }
   324  
   325  // sm2P256GetBit returns the bit'th bit of scalar.
   326  func sm2P256GetBit(scalar *[32]uint8, bit uint) uint32 {
   327  	return uint32(((scalar[bit>>3]) >> (bit & 7)) & 1)
   328  }
   329  
   330  // sm2P256ScalarBaseMult sets {xOut,yOut,zOut} = scalar*G where scalar is a
   331  // little-endian number. Note that the value of scalar must be less than the
   332  // order of the group.
   333  func sm2P256ScalarBaseMult(xOut, yOut, zOut *sm2P256FieldElement, scalar *[32]uint8) {
   334  	nIsInfinityMask := ^uint32(0)
   335  	var px, py, tx, ty, tz sm2P256FieldElement
   336  	var pIsNoninfiniteMask, mask, tableOffset uint32
   337  
   338  	for i := range xOut {
   339  		xOut[i] = 0
   340  	}
   341  	for i := range yOut {
   342  		yOut[i] = 0
   343  	}
   344  	for i := range zOut {
   345  		zOut[i] = 0
   346  	}
   347  
   348  	// The loop adds bits at positions 0, 64, 128 and 192, followed by
   349  	// positions 32,96,160 and 224 and does this 32 times.
   350  	for i := uint(0); i < 32; i++ {
   351  		if i != 0 {
   352  			sm2P256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut)
   353  		}
   354  		tableOffset = 0
   355  		for j := uint(0); j <= 32; j += 32 {
   356  			bit0 := sm2P256GetBit(scalar, 31-i+j)
   357  			bit1 := sm2P256GetBit(scalar, 95-i+j)
   358  			bit2 := sm2P256GetBit(scalar, 159-i+j)
   359  			bit3 := sm2P256GetBit(scalar, 223-i+j)
   360  			index := bit0 | (bit1 << 1) | (bit2 << 2) | (bit3 << 3)
   361  
   362  			sm2P256SelectAffinePoint(&px, &py, sm2P256Precomputed[tableOffset:], index)
   363  			tableOffset += 30 * 9
   364  
   365  			// Since scalar is less than the order of the group, we know that
   366  			// {xOut,yOut,zOut} != {px,py,1}, unless both are zero, which we handle
   367  			// below.
   368  			sm2P256PointAddMixed(&tx, &ty, &tz, xOut, yOut, zOut, &px, &py)
   369  			// The result of pointAddMixed is incorrect if {xOut,yOut,zOut} is zero
   370  			// (a.k.a.  the point at infinity). We handle that situation by
   371  			// copying the point from the table.
   372  			sm2P256CopyConditional(xOut, &px, nIsInfinityMask)
   373  			sm2P256CopyConditional(yOut, &py, nIsInfinityMask)
   374  			sm2P256CopyConditional(zOut, &sm2P256Factor[1], nIsInfinityMask)
   375  
   376  			// Equally, the result is also wrong if the point from the table is
   377  			// zero, which happens when the index is zero. We handle that by
   378  			// only copying from {tx,ty,tz} to {xOut,yOut,zOut} if index != 0.
   379  			pIsNoninfiniteMask = nonZeroToAllOnes(index)
   380  			mask = pIsNoninfiniteMask & ^nIsInfinityMask
   381  			sm2P256CopyConditional(xOut, &tx, mask)
   382  			sm2P256CopyConditional(yOut, &ty, mask)
   383  			sm2P256CopyConditional(zOut, &tz, mask)
   384  			// If p was not zero, then n is now non-zero.
   385  			nIsInfinityMask &^= pIsNoninfiniteMask
   386  		}
   387  	}
   388  }
   389  
   390  func sm2P256PointToAffine(xOut, yOut, x, y, z *sm2P256FieldElement) {
   391  	var zInv, zInvSq sm2P256FieldElement
   392  
   393  	zz := sm2P256ToBig(z)
   394  	zz.ModInverse(zz, sm2P256.P)
   395  	sm2P256FromBig(&zInv, zz)
   396  
   397  	sm2P256Square(&zInvSq, &zInv)
   398  	sm2P256Mul(xOut, x, &zInvSq)
   399  	sm2P256Mul(&zInv, &zInv, &zInvSq)
   400  	sm2P256Mul(yOut, y, &zInv)
   401  }
   402  
   403  func sm2P256ToAffine(x, y, z *sm2P256FieldElement) (xOut, yOut *big.Int) {
   404  	var xx, yy sm2P256FieldElement
   405  
   406  	sm2P256PointToAffine(&xx, &yy, x, y, z)
   407  	return sm2P256ToBig(&xx), sm2P256ToBig(&yy)
   408  }
   409  
   410  var sm2P256Factor = []sm2P256FieldElement{
   411  	{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0},
   412  	{0x2, 0x0, 0x1FFFFF00, 0x7FF, 0x0, 0x0, 0x0, 0x2000000, 0x0},
   413  	{0x4, 0x0, 0x1FFFFE00, 0xFFF, 0x0, 0x0, 0x0, 0x4000000, 0x0},
   414  	{0x6, 0x0, 0x1FFFFD00, 0x17FF, 0x0, 0x0, 0x0, 0x6000000, 0x0},
   415  	{0x8, 0x0, 0x1FFFFC00, 0x1FFF, 0x0, 0x0, 0x0, 0x8000000, 0x0},
   416  	{0xA, 0x0, 0x1FFFFB00, 0x27FF, 0x0, 0x0, 0x0, 0xA000000, 0x0},
   417  	{0xC, 0x0, 0x1FFFFA00, 0x2FFF, 0x0, 0x0, 0x0, 0xC000000, 0x0},
   418  	{0xE, 0x0, 0x1FFFF900, 0x37FF, 0x0, 0x0, 0x0, 0xE000000, 0x0},
   419  	{0x10, 0x0, 0x1FFFF800, 0x3FFF, 0x0, 0x0, 0x0, 0x0, 0x01},
   420  }
   421  
   422  func sm2P256Scalar(b *sm2P256FieldElement, a int) {
   423  	sm2P256Mul(b, b, &sm2P256Factor[a])
   424  }
   425  
   426  // (x3, y3, z3) = (x1, y1, z1) + (x2, y2, z2)
   427  func sm2P256PointAdd(x1, y1, z1, x2, y2, z2, x3, y3, z3 *sm2P256FieldElement) {
   428  	var u1, u2, z22, z12, z23, z13, s1, s2, h, h2, r, r2, tm sm2P256FieldElement
   429  
   430  	if sm2P256ToBig(z1).Sign() == 0 {
   431  		sm2P256Dup(x3, x2)
   432  		sm2P256Dup(y3, y2)
   433  		sm2P256Dup(z3, z2)
   434  		return
   435  	}
   436  
   437  	if sm2P256ToBig(z2).Sign() == 0 {
   438  		sm2P256Dup(x3, x1)
   439  		sm2P256Dup(y3, y1)
   440  		sm2P256Dup(z3, z1)
   441  		return
   442  	}
   443  
   444  	sm2P256Square(&z12, z1) // z12 = z1 ^ 2
   445  	sm2P256Square(&z22, z2) // z22 = z2 ^ 2
   446  
   447  	sm2P256Mul(&z13, &z12, z1) // z13 = z1 ^ 3
   448  	sm2P256Mul(&z23, &z22, z2) // z23 = z2 ^ 3
   449  
   450  	sm2P256Mul(&u1, x1, &z22) // u1 = x1 * z2 ^ 2
   451  	sm2P256Mul(&u2, x2, &z12) // u2 = x2 * z1 ^ 2
   452  
   453  	sm2P256Mul(&s1, y1, &z23) // s1 = y1 * z2 ^ 3
   454  	sm2P256Mul(&s2, y2, &z13) // s2 = y2 * z1 ^ 3
   455  
   456  	if sm2P256ToBig(&u1).Cmp(sm2P256ToBig(&u2)) == 0 &&
   457  		sm2P256ToBig(&s1).Cmp(sm2P256ToBig(&s2)) == 0 {
   458  		sm2P256PointDouble(x1, y1, z1, x1, y1, z1)
   459  	}
   460  
   461  	sm2P256Sub(&h, &u2, &u1) // h = u2 - u1
   462  	sm2P256Sub(&r, &s2, &s1) // r = s2 - s1
   463  
   464  	sm2P256Square(&r2, &r) // r2 = r ^ 2
   465  	sm2P256Square(&h2, &h) // h2 = h ^ 2
   466  
   467  	sm2P256Mul(&tm, &h2, &h) // tm = h ^ 3
   468  	sm2P256Sub(x3, &r2, &tm)
   469  	sm2P256Mul(&tm, &u1, &h2)
   470  	sm2P256Scalar(&tm, 2)   // tm = 2 * (u1 * h ^ 2)
   471  	sm2P256Sub(x3, x3, &tm) // x3 = r ^ 2 - h ^ 3 - 2 * u1 * h ^ 2
   472  
   473  	sm2P256Mul(&tm, &u1, &h2) // tm = u1 * h ^ 2
   474  	sm2P256Sub(&tm, &tm, x3)  // tm = u1 * h ^ 2 - x3
   475  	sm2P256Mul(y3, &r, &tm)
   476  	sm2P256Mul(&tm, &h2, &h)  // tm = h ^ 3
   477  	sm2P256Mul(&tm, &tm, &s1) // tm = s1 * h ^ 3
   478  	sm2P256Sub(y3, y3, &tm)   // y3 = r * (u1 * h ^ 2 - x3) - s1 * h ^ 3
   479  
   480  	sm2P256Mul(z3, z1, z2)
   481  	sm2P256Mul(z3, z3, &h) // z3 = z1 * z3 * h
   482  }
   483  
   484  // (x3, y3, z3) = (x1, y1, z1)- (x2, y2, z2)
   485  func sm2P256PointSub(x1, y1, z1, x2, y2, z2, x3, y3, z3 *sm2P256FieldElement) {
   486  	var u1, u2, z22, z12, z23, z13, s1, s2, h, h2, r, r2, tm sm2P256FieldElement
   487  	y := sm2P256ToBig(y2)
   488  	zero := new(big.Int).SetInt64(0)
   489  	y.Sub(zero, y)
   490  	sm2P256FromBig(y2, y)
   491  
   492  	if sm2P256ToBig(z1).Sign() == 0 {
   493  		sm2P256Dup(x3, x2)
   494  		sm2P256Dup(y3, y2)
   495  		sm2P256Dup(z3, z2)
   496  		return
   497  	}
   498  
   499  	if sm2P256ToBig(z2).Sign() == 0 {
   500  		sm2P256Dup(x3, x1)
   501  		sm2P256Dup(y3, y1)
   502  		sm2P256Dup(z3, z1)
   503  		return
   504  	}
   505  
   506  	sm2P256Square(&z12, z1) // z12 = z1 ^ 2
   507  	sm2P256Square(&z22, z2) // z22 = z2 ^ 2
   508  
   509  	sm2P256Mul(&z13, &z12, z1) // z13 = z1 ^ 3
   510  	sm2P256Mul(&z23, &z22, z2) // z23 = z2 ^ 3
   511  
   512  	sm2P256Mul(&u1, x1, &z22) // u1 = x1 * z2 ^ 2
   513  	sm2P256Mul(&u2, x2, &z12) // u2 = x2 * z1 ^ 2
   514  
   515  	sm2P256Mul(&s1, y1, &z23) // s1 = y1 * z2 ^ 3
   516  	sm2P256Mul(&s2, y2, &z13) // s2 = y2 * z1 ^ 3
   517  
   518  	if sm2P256ToBig(&u1).Cmp(sm2P256ToBig(&u2)) == 0 &&
   519  		sm2P256ToBig(&s1).Cmp(sm2P256ToBig(&s2)) == 0 {
   520  		sm2P256PointDouble(x1, y1, z1, x1, y1, z1)
   521  	}
   522  
   523  	sm2P256Sub(&h, &u2, &u1) // h = u2 - u1
   524  	sm2P256Sub(&r, &s2, &s1) // r = s2 - s1
   525  
   526  	sm2P256Square(&r2, &r) // r2 = r ^ 2
   527  	sm2P256Square(&h2, &h) // h2 = h ^ 2
   528  
   529  	sm2P256Mul(&tm, &h2, &h) // tm = h ^ 3
   530  	sm2P256Sub(x3, &r2, &tm)
   531  	sm2P256Mul(&tm, &u1, &h2)
   532  	sm2P256Scalar(&tm, 2)   // tm = 2 * (u1 * h ^ 2)
   533  	sm2P256Sub(x3, x3, &tm) // x3 = r ^ 2 - h ^ 3 - 2 * u1 * h ^ 2
   534  
   535  	sm2P256Mul(&tm, &u1, &h2) // tm = u1 * h ^ 2
   536  	sm2P256Sub(&tm, &tm, x3)  // tm = u1 * h ^ 2 - x3
   537  	sm2P256Mul(y3, &r, &tm)
   538  	sm2P256Mul(&tm, &h2, &h)  // tm = h ^ 3
   539  	sm2P256Mul(&tm, &tm, &s1) // tm = s1 * h ^ 3
   540  	sm2P256Sub(y3, y3, &tm)   // y3 = r * (u1 * h ^ 2 - x3) - s1 * h ^ 3
   541  
   542  	sm2P256Mul(z3, z1, z2)
   543  	sm2P256Mul(z3, z3, &h) // z3 = z1 * z3 * h
   544  }
   545  
   546  func sm2P256PointDouble(x3, y3, z3, x, y, z *sm2P256FieldElement) {
   547  	var s, m, m2, x2, y2, z2, z4, y4, az4 sm2P256FieldElement
   548  
   549  	sm2P256Square(&x2, x) // x2 = x ^ 2
   550  	sm2P256Square(&y2, y) // y2 = y ^ 2
   551  	sm2P256Square(&z2, z) // z2 = z ^ 2
   552  
   553  	sm2P256Square(&z4, z)   // z4 = z ^ 2
   554  	sm2P256Mul(&z4, &z4, z) // z4 = z ^ 3
   555  	sm2P256Mul(&z4, &z4, z) // z4 = z ^ 4
   556  
   557  	sm2P256Square(&y4, y)   // y4 = y ^ 2
   558  	sm2P256Mul(&y4, &y4, y) // y4 = y ^ 3
   559  	sm2P256Mul(&y4, &y4, y) // y4 = y ^ 4
   560  	sm2P256Scalar(&y4, 8)   // y4 = 8 * y ^ 4
   561  
   562  	sm2P256Mul(&s, x, &y2)
   563  	sm2P256Scalar(&s, 4) // s = 4 * x * y ^ 2
   564  
   565  	sm2P256Dup(&m, &x2)
   566  	sm2P256Scalar(&m, 3)
   567  	sm2P256Mul(&az4, &sm2P256.a, &z4)
   568  	sm2P256Add(&m, &m, &az4) // m = 3 * x ^ 2 + a * z ^ 4
   569  
   570  	sm2P256Square(&m2, &m) // m2 = m ^ 2
   571  
   572  	sm2P256Add(z3, y, z)
   573  	sm2P256Square(z3, z3)
   574  	sm2P256Sub(z3, z3, &z2)
   575  	sm2P256Sub(z3, z3, &y2) // z' = (y + z) ^2 - z ^ 2 - y ^ 2
   576  
   577  	sm2P256Sub(x3, &m2, &s)
   578  	sm2P256Sub(x3, x3, &s) // x' = m2 - 2 * s
   579  
   580  	sm2P256Sub(y3, &s, x3)
   581  	sm2P256Mul(y3, y3, &m)
   582  	sm2P256Sub(y3, y3, &y4) // y' = m * (s - x') - 8 * y ^ 4
   583  }
   584  
   585  // p256Zero31 is 0 mod p.
   586  var sm2P256Zero31 = sm2P256FieldElement{0x7FFFFFF8, 0x3FFFFFFC, 0x800003FC, 0x3FFFDFFC, 0x7FFFFFFC, 0x3FFFFFFC, 0x7FFFFFFC, 0x37FFFFFC, 0x7FFFFFFC}
   587  
   588  // c = a + b
   589  func sm2P256Add(c, a, b *sm2P256FieldElement) {
   590  	carry := uint32(0)
   591  	for i := 0; ; i++ {
   592  		c[i] = a[i] + b[i]
   593  		c[i] += carry
   594  		carry = c[i] >> 29
   595  		c[i] &= bottom29Bits
   596  		i++
   597  		if i == 9 {
   598  			break
   599  		}
   600  		c[i] = a[i] + b[i]
   601  		c[i] += carry
   602  		carry = c[i] >> 28
   603  		c[i] &= bottom28Bits
   604  	}
   605  	sm2P256ReduceCarry(c, carry)
   606  }
   607  
   608  // c = a - b
   609  func sm2P256Sub(c, a, b *sm2P256FieldElement) {
   610  	var carry uint32
   611  
   612  	for i := 0; ; i++ {
   613  		c[i] = a[i] - b[i]
   614  		c[i] += sm2P256Zero31[i]
   615  		c[i] += carry
   616  		carry = c[i] >> 29
   617  		c[i] &= bottom29Bits
   618  		i++
   619  		if i == 9 {
   620  			break
   621  		}
   622  		c[i] = a[i] - b[i]
   623  		c[i] += sm2P256Zero31[i]
   624  		c[i] += carry
   625  		carry = c[i] >> 28
   626  		c[i] &= bottom28Bits
   627  	}
   628  	sm2P256ReduceCarry(c, carry)
   629  }
   630  
   631  // c = a * b
   632  func sm2P256Mul(c, a, b *sm2P256FieldElement) {
   633  	var tmp sm2P256LargeFieldElement
   634  
   635  	tmp[0] = uint64(a[0]) * uint64(b[0])
   636  	tmp[1] = uint64(a[0])*(uint64(b[1])<<0) +
   637  		uint64(a[1])*(uint64(b[0])<<0)
   638  	tmp[2] = uint64(a[0])*(uint64(b[2])<<0) +
   639  		uint64(a[1])*(uint64(b[1])<<1) +
   640  		uint64(a[2])*(uint64(b[0])<<0)
   641  	tmp[3] = uint64(a[0])*(uint64(b[3])<<0) +
   642  		uint64(a[1])*(uint64(b[2])<<0) +
   643  		uint64(a[2])*(uint64(b[1])<<0) +
   644  		uint64(a[3])*(uint64(b[0])<<0)
   645  	tmp[4] = uint64(a[0])*(uint64(b[4])<<0) +
   646  		uint64(a[1])*(uint64(b[3])<<1) +
   647  		uint64(a[2])*(uint64(b[2])<<0) +
   648  		uint64(a[3])*(uint64(b[1])<<1) +
   649  		uint64(a[4])*(uint64(b[0])<<0)
   650  	tmp[5] = uint64(a[0])*(uint64(b[5])<<0) +
   651  		uint64(a[1])*(uint64(b[4])<<0) +
   652  		uint64(a[2])*(uint64(b[3])<<0) +
   653  		uint64(a[3])*(uint64(b[2])<<0) +
   654  		uint64(a[4])*(uint64(b[1])<<0) +
   655  		uint64(a[5])*(uint64(b[0])<<0)
   656  	tmp[6] = uint64(a[0])*(uint64(b[6])<<0) +
   657  		uint64(a[1])*(uint64(b[5])<<1) +
   658  		uint64(a[2])*(uint64(b[4])<<0) +
   659  		uint64(a[3])*(uint64(b[3])<<1) +
   660  		uint64(a[4])*(uint64(b[2])<<0) +
   661  		uint64(a[5])*(uint64(b[1])<<1) +
   662  		uint64(a[6])*(uint64(b[0])<<0)
   663  	tmp[7] = uint64(a[0])*(uint64(b[7])<<0) +
   664  		uint64(a[1])*(uint64(b[6])<<0) +
   665  		uint64(a[2])*(uint64(b[5])<<0) +
   666  		uint64(a[3])*(uint64(b[4])<<0) +
   667  		uint64(a[4])*(uint64(b[3])<<0) +
   668  		uint64(a[5])*(uint64(b[2])<<0) +
   669  		uint64(a[6])*(uint64(b[1])<<0) +
   670  		uint64(a[7])*(uint64(b[0])<<0)
   671  	// tmp[8] has the greatest value but doesn't overflow. See logic in
   672  	// p256Square.
   673  	tmp[8] = uint64(a[0])*(uint64(b[8])<<0) +
   674  		uint64(a[1])*(uint64(b[7])<<1) +
   675  		uint64(a[2])*(uint64(b[6])<<0) +
   676  		uint64(a[3])*(uint64(b[5])<<1) +
   677  		uint64(a[4])*(uint64(b[4])<<0) +
   678  		uint64(a[5])*(uint64(b[3])<<1) +
   679  		uint64(a[6])*(uint64(b[2])<<0) +
   680  		uint64(a[7])*(uint64(b[1])<<1) +
   681  		uint64(a[8])*(uint64(b[0])<<0)
   682  	tmp[9] = uint64(a[1])*(uint64(b[8])<<0) +
   683  		uint64(a[2])*(uint64(b[7])<<0) +
   684  		uint64(a[3])*(uint64(b[6])<<0) +
   685  		uint64(a[4])*(uint64(b[5])<<0) +
   686  		uint64(a[5])*(uint64(b[4])<<0) +
   687  		uint64(a[6])*(uint64(b[3])<<0) +
   688  		uint64(a[7])*(uint64(b[2])<<0) +
   689  		uint64(a[8])*(uint64(b[1])<<0)
   690  	tmp[10] = uint64(a[2])*(uint64(b[8])<<0) +
   691  		uint64(a[3])*(uint64(b[7])<<1) +
   692  		uint64(a[4])*(uint64(b[6])<<0) +
   693  		uint64(a[5])*(uint64(b[5])<<1) +
   694  		uint64(a[6])*(uint64(b[4])<<0) +
   695  		uint64(a[7])*(uint64(b[3])<<1) +
   696  		uint64(a[8])*(uint64(b[2])<<0)
   697  	tmp[11] = uint64(a[3])*(uint64(b[8])<<0) +
   698  		uint64(a[4])*(uint64(b[7])<<0) +
   699  		uint64(a[5])*(uint64(b[6])<<0) +
   700  		uint64(a[6])*(uint64(b[5])<<0) +
   701  		uint64(a[7])*(uint64(b[4])<<0) +
   702  		uint64(a[8])*(uint64(b[3])<<0)
   703  	tmp[12] = uint64(a[4])*(uint64(b[8])<<0) +
   704  		uint64(a[5])*(uint64(b[7])<<1) +
   705  		uint64(a[6])*(uint64(b[6])<<0) +
   706  		uint64(a[7])*(uint64(b[5])<<1) +
   707  		uint64(a[8])*(uint64(b[4])<<0)
   708  	tmp[13] = uint64(a[5])*(uint64(b[8])<<0) +
   709  		uint64(a[6])*(uint64(b[7])<<0) +
   710  		uint64(a[7])*(uint64(b[6])<<0) +
   711  		uint64(a[8])*(uint64(b[5])<<0)
   712  	tmp[14] = uint64(a[6])*(uint64(b[8])<<0) +
   713  		uint64(a[7])*(uint64(b[7])<<1) +
   714  		uint64(a[8])*(uint64(b[6])<<0)
   715  	tmp[15] = uint64(a[7])*(uint64(b[8])<<0) +
   716  		uint64(a[8])*(uint64(b[7])<<0)
   717  	tmp[16] = uint64(a[8]) * (uint64(b[8]) << 0)
   718  	sm2P256ReduceDegree(c, &tmp)
   719  }
   720  
   721  // b = a * a
   722  func sm2P256Square(b, a *sm2P256FieldElement) {
   723  	var tmp sm2P256LargeFieldElement
   724  
   725  	tmp[0] = uint64(a[0]) * uint64(a[0])
   726  	tmp[1] = uint64(a[0]) * (uint64(a[1]) << 1)
   727  	tmp[2] = uint64(a[0])*(uint64(a[2])<<1) +
   728  		uint64(a[1])*(uint64(a[1])<<1)
   729  	tmp[3] = uint64(a[0])*(uint64(a[3])<<1) +
   730  		uint64(a[1])*(uint64(a[2])<<1)
   731  	tmp[4] = uint64(a[0])*(uint64(a[4])<<1) +
   732  		uint64(a[1])*(uint64(a[3])<<2) +
   733  		uint64(a[2])*uint64(a[2])
   734  	tmp[5] = uint64(a[0])*(uint64(a[5])<<1) +
   735  		uint64(a[1])*(uint64(a[4])<<1) +
   736  		uint64(a[2])*(uint64(a[3])<<1)
   737  	tmp[6] = uint64(a[0])*(uint64(a[6])<<1) +
   738  		uint64(a[1])*(uint64(a[5])<<2) +
   739  		uint64(a[2])*(uint64(a[4])<<1) +
   740  		uint64(a[3])*(uint64(a[3])<<1)
   741  	tmp[7] = uint64(a[0])*(uint64(a[7])<<1) +
   742  		uint64(a[1])*(uint64(a[6])<<1) +
   743  		uint64(a[2])*(uint64(a[5])<<1) +
   744  		uint64(a[3])*(uint64(a[4])<<1)
   745  	// tmp[8] has the greatest value of 2**61 + 2**60 + 2**61 + 2**60 + 2**60,
   746  	// which is < 2**64 as required.
   747  	tmp[8] = uint64(a[0])*(uint64(a[8])<<1) +
   748  		uint64(a[1])*(uint64(a[7])<<2) +
   749  		uint64(a[2])*(uint64(a[6])<<1) +
   750  		uint64(a[3])*(uint64(a[5])<<2) +
   751  		uint64(a[4])*uint64(a[4])
   752  	tmp[9] = uint64(a[1])*(uint64(a[8])<<1) +
   753  		uint64(a[2])*(uint64(a[7])<<1) +
   754  		uint64(a[3])*(uint64(a[6])<<1) +
   755  		uint64(a[4])*(uint64(a[5])<<1)
   756  	tmp[10] = uint64(a[2])*(uint64(a[8])<<1) +
   757  		uint64(a[3])*(uint64(a[7])<<2) +
   758  		uint64(a[4])*(uint64(a[6])<<1) +
   759  		uint64(a[5])*(uint64(a[5])<<1)
   760  	tmp[11] = uint64(a[3])*(uint64(a[8])<<1) +
   761  		uint64(a[4])*(uint64(a[7])<<1) +
   762  		uint64(a[5])*(uint64(a[6])<<1)
   763  	tmp[12] = uint64(a[4])*(uint64(a[8])<<1) +
   764  		uint64(a[5])*(uint64(a[7])<<2) +
   765  		uint64(a[6])*uint64(a[6])
   766  	tmp[13] = uint64(a[5])*(uint64(a[8])<<1) +
   767  		uint64(a[6])*(uint64(a[7])<<1)
   768  	tmp[14] = uint64(a[6])*(uint64(a[8])<<1) +
   769  		uint64(a[7])*(uint64(a[7])<<1)
   770  	tmp[15] = uint64(a[7]) * (uint64(a[8]) << 1)
   771  	tmp[16] = uint64(a[8]) * uint64(a[8])
   772  	sm2P256ReduceDegree(b, &tmp)
   773  }
   774  
   775  // nonZeroToAllOnes returns:
   776  //   0xffffffff for 0 < x <= 2**31
   777  //   0 for x == 0 or x > 2**31.
   778  func nonZeroToAllOnes(x uint32) uint32 {
   779  	return ((x - 1) >> 31) - 1
   780  }
   781  
   782  var sm2P256Carry = [8 * 9]uint32{
   783  	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   784  	0x2, 0x0, 0x1FFFFF00, 0x7FF, 0x0, 0x0, 0x0, 0x2000000, 0x0,
   785  	0x4, 0x0, 0x1FFFFE00, 0xFFF, 0x0, 0x0, 0x0, 0x4000000, 0x0,
   786  	0x6, 0x0, 0x1FFFFD00, 0x17FF, 0x0, 0x0, 0x0, 0x6000000, 0x0,
   787  	0x8, 0x0, 0x1FFFFC00, 0x1FFF, 0x0, 0x0, 0x0, 0x8000000, 0x0,
   788  	0xA, 0x0, 0x1FFFFB00, 0x27FF, 0x0, 0x0, 0x0, 0xA000000, 0x0,
   789  	0xC, 0x0, 0x1FFFFA00, 0x2FFF, 0x0, 0x0, 0x0, 0xC000000, 0x0,
   790  	0xE, 0x0, 0x1FFFF900, 0x37FF, 0x0, 0x0, 0x0, 0xE000000, 0x0,
   791  }
   792  
   793  // carry < 2 ^ 3
   794  func sm2P256ReduceCarry(a *sm2P256FieldElement, carry uint32) {
   795  	a[0] += sm2P256Carry[carry*9+0]
   796  	a[2] += sm2P256Carry[carry*9+2]
   797  	a[3] += sm2P256Carry[carry*9+3]
   798  	a[7] += sm2P256Carry[carry*9+7]
   799  }
   800  
   801  func sm2P256ReduceDegree(a *sm2P256FieldElement, b *sm2P256LargeFieldElement) {
   802  	var tmp [18]uint32
   803  	var carry, x, xMask uint32
   804  
   805  	// tmp
   806  	// 0  | 1  | 2  | 3  | 4  | 5  | 6  | 7  | 8  |  9 | 10 ...
   807  	// 29 | 28 | 29 | 28 | 29 | 28 | 29 | 28 | 29 | 28 | 29 ...
   808  	tmp[0] = uint32(b[0]) & bottom29Bits
   809  	tmp[1] = uint32(b[0]) >> 29
   810  	tmp[1] |= (uint32(b[0]>>32) << 3) & bottom28Bits
   811  	tmp[1] += uint32(b[1]) & bottom28Bits
   812  	carry = tmp[1] >> 28
   813  	tmp[1] &= bottom28Bits
   814  	for i := 2; i < 17; i++ {
   815  		tmp[i] = (uint32(b[i-2] >> 32)) >> 25
   816  		tmp[i] += (uint32(b[i-1])) >> 28
   817  		tmp[i] += (uint32(b[i-1]>>32) << 4) & bottom29Bits
   818  		tmp[i] += uint32(b[i]) & bottom29Bits
   819  		tmp[i] += carry
   820  		carry = tmp[i] >> 29
   821  		tmp[i] &= bottom29Bits
   822  
   823  		i++
   824  		if i == 17 {
   825  			break
   826  		}
   827  		tmp[i] = uint32(b[i-2]>>32) >> 25
   828  		tmp[i] += uint32(b[i-1]) >> 29
   829  		tmp[i] += ((uint32(b[i-1] >> 32)) << 3) & bottom28Bits
   830  		tmp[i] += uint32(b[i]) & bottom28Bits
   831  		tmp[i] += carry
   832  		carry = tmp[i] >> 28
   833  		tmp[i] &= bottom28Bits
   834  	}
   835  	tmp[17] = uint32(b[15]>>32) >> 25
   836  	tmp[17] += uint32(b[16]) >> 29
   837  	tmp[17] += uint32(b[16]>>32) << 3
   838  	tmp[17] += carry
   839  
   840  	for i := 0; ; i += 2 {
   841  
   842  		tmp[i+1] += tmp[i] >> 29
   843  		x = tmp[i] & bottom29Bits
   844  		tmp[i] = 0
   845  		if x > 0 {
   846  			set4 := uint32(0)
   847  			set7 := uint32(0)
   848  			xMask = nonZeroToAllOnes(x)
   849  			tmp[i+2] += (x << 7) & bottom29Bits
   850  			tmp[i+3] += x >> 22
   851  			if tmp[i+3] < 0x10000000 {
   852  				set4 = 1
   853  				tmp[i+3] += 0x10000000 & xMask
   854  				tmp[i+3] -= (x << 10) & bottom28Bits
   855  			} else {
   856  				tmp[i+3] -= (x << 10) & bottom28Bits
   857  			}
   858  			if tmp[i+4] < 0x20000000 {
   859  				tmp[i+4] += 0x20000000 & xMask
   860  				tmp[i+4] -= set4 // 借位
   861  				tmp[i+4] -= x >> 18
   862  				if tmp[i+5] < 0x10000000 {
   863  					tmp[i+5] += 0x10000000 & xMask
   864  					tmp[i+5] -= 1 // 借位
   865  					if tmp[i+6] < 0x20000000 {
   866  						set7 = 1
   867  						tmp[i+6] += 0x20000000 & xMask
   868  						tmp[i+6] -= 1 // 借位
   869  					} else {
   870  						tmp[i+6] -= 1 // 借位
   871  					}
   872  				} else {
   873  					tmp[i+5] -= 1
   874  				}
   875  			} else {
   876  				tmp[i+4] -= set4 // 借位
   877  				tmp[i+4] -= x >> 18
   878  			}
   879  			if tmp[i+7] < 0x10000000 {
   880  				tmp[i+7] += 0x10000000 & xMask
   881  				tmp[i+7] -= set7
   882  				tmp[i+7] -= (x << 24) & bottom28Bits
   883  				tmp[i+8] += (x << 28) & bottom29Bits
   884  				if tmp[i+8] < 0x20000000 {
   885  					tmp[i+8] += 0x20000000 & xMask
   886  					tmp[i+8] -= 1
   887  					tmp[i+8] -= x >> 4
   888  					tmp[i+9] += ((x >> 1) - 1) & xMask
   889  				} else {
   890  					tmp[i+8] -= 1
   891  					tmp[i+8] -= x >> 4
   892  					tmp[i+9] += (x >> 1) & xMask
   893  				}
   894  			} else {
   895  				tmp[i+7] -= set7 // 借位
   896  				tmp[i+7] -= (x << 24) & bottom28Bits
   897  				tmp[i+8] += (x << 28) & bottom29Bits
   898  				if tmp[i+8] < 0x20000000 {
   899  					tmp[i+8] += 0x20000000 & xMask
   900  					tmp[i+8] -= x >> 4
   901  					tmp[i+9] += ((x >> 1) - 1) & xMask
   902  				} else {
   903  					tmp[i+8] -= x >> 4
   904  					tmp[i+9] += (x >> 1) & xMask
   905  				}
   906  			}
   907  
   908  		}
   909  
   910  		if i+1 == 9 {
   911  			break
   912  		}
   913  
   914  		tmp[i+2] += tmp[i+1] >> 28
   915  		x = tmp[i+1] & bottom28Bits
   916  		tmp[i+1] = 0
   917  		if x > 0 {
   918  			set5 := uint32(0)
   919  			set8 := uint32(0)
   920  			set9 := uint32(0)
   921  			xMask = nonZeroToAllOnes(x)
   922  			tmp[i+3] += (x << 7) & bottom28Bits
   923  			tmp[i+4] += x >> 21
   924  			if tmp[i+4] < 0x20000000 {
   925  				set5 = 1
   926  				tmp[i+4] += 0x20000000 & xMask
   927  				tmp[i+4] -= (x << 11) & bottom29Bits
   928  			} else {
   929  				tmp[i+4] -= (x << 11) & bottom29Bits
   930  			}
   931  			if tmp[i+5] < 0x10000000 {
   932  				tmp[i+5] += 0x10000000 & xMask
   933  				tmp[i+5] -= set5 // 借位
   934  				tmp[i+5] -= x >> 18
   935  				if tmp[i+6] < 0x20000000 {
   936  					tmp[i+6] += 0x20000000 & xMask
   937  					tmp[i+6] -= 1 // 借位
   938  					if tmp[i+7] < 0x10000000 {
   939  						set8 = 1
   940  						tmp[i+7] += 0x10000000 & xMask
   941  						tmp[i+7] -= 1 // 借位
   942  					} else {
   943  						tmp[i+7] -= 1 // 借位
   944  					}
   945  				} else {
   946  					tmp[i+6] -= 1 // 借位
   947  				}
   948  			} else {
   949  				tmp[i+5] -= set5 // 借位
   950  				tmp[i+5] -= x >> 18
   951  			}
   952  			if tmp[i+8] < 0x20000000 {
   953  				set9 = 1
   954  				tmp[i+8] += 0x20000000 & xMask
   955  				tmp[i+8] -= set8
   956  				tmp[i+8] -= (x << 25) & bottom29Bits
   957  			} else {
   958  				tmp[i+8] -= set8
   959  				tmp[i+8] -= (x << 25) & bottom29Bits
   960  			}
   961  			if tmp[i+9] < 0x10000000 {
   962  				tmp[i+9] += 0x10000000 & xMask
   963  				tmp[i+9] -= set9 // 借位
   964  				tmp[i+9] -= x >> 4
   965  				tmp[i+10] += (x - 1) & xMask
   966  			} else {
   967  				tmp[i+9] -= set9 // 借位
   968  				tmp[i+9] -= x >> 4
   969  				tmp[i+10] += x & xMask
   970  			}
   971  		}
   972  	}
   973  
   974  	carry = uint32(0)
   975  	for i := 0; i < 8; i++ {
   976  		a[i] = tmp[i+9]
   977  		a[i] += carry
   978  		a[i] += (tmp[i+10] << 28) & bottom29Bits
   979  		carry = a[i] >> 29
   980  		a[i] &= bottom29Bits
   981  
   982  		i++
   983  		a[i] = tmp[i+9] >> 1
   984  		a[i] += carry
   985  		carry = a[i] >> 28
   986  		a[i] &= bottom28Bits
   987  	}
   988  	a[8] = tmp[17]
   989  	a[8] += carry
   990  	carry = a[8] >> 29
   991  	a[8] &= bottom29Bits
   992  	sm2P256ReduceCarry(a, carry)
   993  }
   994  
   995  // b = a
   996  func sm2P256Dup(b, a *sm2P256FieldElement) {
   997  	*b = *a
   998  }
   999  
  1000  // X = a * R mod P
  1001  func sm2P256FromBig(X *sm2P256FieldElement, a *big.Int) {
  1002  	x := new(big.Int).Lsh(a, 257)
  1003  	x.Mod(x, sm2P256.P)
  1004  	for i := 0; i < 9; i++ {
  1005  		if bits := x.Bits(); len(bits) > 0 {
  1006  			X[i] = uint32(bits[0]) & bottom29Bits
  1007  		} else {
  1008  			X[i] = 0
  1009  		}
  1010  		x.Rsh(x, 29)
  1011  		i++
  1012  		if i == 9 {
  1013  			break
  1014  		}
  1015  		if bits := x.Bits(); len(bits) > 0 {
  1016  			X[i] = uint32(bits[0]) & bottom28Bits
  1017  		} else {
  1018  			X[i] = 0
  1019  		}
  1020  		x.Rsh(x, 28)
  1021  	}
  1022  }
  1023  
  1024  // X = r * R mod P
  1025  // r = X * R' mod P
  1026  func sm2P256ToBig(X *sm2P256FieldElement) *big.Int {
  1027  	r, tm := new(big.Int), new(big.Int)
  1028  	r.SetInt64(int64(X[8]))
  1029  	for i := 7; i >= 0; i-- {
  1030  		if (i & 1) == 0 {
  1031  			r.Lsh(r, 29)
  1032  		} else {
  1033  			r.Lsh(r, 28)
  1034  		}
  1035  		tm.SetInt64(int64(X[i]))
  1036  		r.Add(r, tm)
  1037  	}
  1038  	r.Mul(r, sm2P256.RInverse)
  1039  	r.Mod(r, sm2P256.P)
  1040  	return r
  1041  }
  1042  func WNafReversed(wnaf []int8) []int8 {
  1043  	// wnafRev := make([]int8, len(wnaf), len(wnaf))
  1044  	wnafRev := make([]int8, len(wnaf))
  1045  	for i, v := range wnaf {
  1046  		wnafRev[len(wnaf)-(1+i)] = v
  1047  	}
  1048  	return wnafRev
  1049  }
  1050  func sm2GenrateWNaf(b []byte) []int8 {
  1051  	n := new(big.Int).SetBytes(b)
  1052  	var k *big.Int
  1053  	if n.Cmp(sm2P256.N) >= 0 {
  1054  		n.Mod(n, sm2P256.N)
  1055  		k = n
  1056  	} else {
  1057  		k = n
  1058  	}
  1059  	// wnaf := make([]int8, k.BitLen()+1, k.BitLen()+1)
  1060  	wnaf := make([]int8, k.BitLen()+1)
  1061  	if k.Sign() == 0 {
  1062  		return wnaf
  1063  	}
  1064  	var width, pow2, sign int
  1065  	width, pow2, sign = 4, 16, 8
  1066  	var mask int64 = 15
  1067  	var carry bool
  1068  	var length, pos int
  1069  	for pos <= k.BitLen() {
  1070  		if k.Bit(pos) == boolToUint(carry) {
  1071  			pos++
  1072  			continue
  1073  		}
  1074  		k.Rsh(k, uint(pos))
  1075  		var digit int
  1076  		digit = int(k.Int64() & mask)
  1077  		if carry {
  1078  			digit++
  1079  		}
  1080  		carry = (digit & sign) != 0
  1081  		if carry {
  1082  			digit -= pow2
  1083  		}
  1084  		length += pos
  1085  		wnaf[length] = int8(digit)
  1086  		pos = width
  1087  	}
  1088  	if len(wnaf) > length+1 {
  1089  		// t := make([]int8, length+1, length+1)
  1090  		t := make([]int8, length+1)
  1091  		copy(t, wnaf[0:length+1])
  1092  		wnaf = t
  1093  	}
  1094  	return wnaf
  1095  }
  1096  func boolToUint(b bool) uint {
  1097  	if b {
  1098  		return 1
  1099  	}
  1100  	return 0
  1101  }
  1102  func abs(a int8) uint32 {
  1103  	if a < 0 {
  1104  		return uint32(-a)
  1105  	}
  1106  	return uint32(a)
  1107  }
  1108  
  1109  func sm2P256ScalarMult(xOut, yOut, zOut, x, y *sm2P256FieldElement, scalar []int8) {
  1110  	var precomp [16][3]sm2P256FieldElement
  1111  	var px, py, pz, tx, ty, tz sm2P256FieldElement
  1112  	var nIsInfinityMask, index, pIsNoninfiniteMask, mask uint32
  1113  
  1114  	// We precompute 0,1,2,... times {x,y}.
  1115  	precomp[1][0] = *x
  1116  	precomp[1][1] = *y
  1117  	precomp[1][2] = sm2P256Factor[1]
  1118  
  1119  	for i := 2; i < 8; i += 2 {
  1120  		sm2P256PointDouble(&precomp[i][0], &precomp[i][1], &precomp[i][2], &precomp[i/2][0], &precomp[i/2][1], &precomp[i/2][2])
  1121  		sm2P256PointAddMixed(&precomp[i+1][0], &precomp[i+1][1], &precomp[i+1][2], &precomp[i][0], &precomp[i][1], &precomp[i][2], x, y)
  1122  	}
  1123  
  1124  	for i := range xOut {
  1125  		xOut[i] = 0
  1126  	}
  1127  	for i := range yOut {
  1128  		yOut[i] = 0
  1129  	}
  1130  	for i := range zOut {
  1131  		zOut[i] = 0
  1132  	}
  1133  	nIsInfinityMask = ^uint32(0)
  1134  	var zeroes int16
  1135  	for i := 0; i < len(scalar); i++ {
  1136  		if scalar[i] == 0 {
  1137  			zeroes++
  1138  			continue
  1139  		}
  1140  		if zeroes > 0 {
  1141  			for ; zeroes > 0; zeroes-- {
  1142  				sm2P256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut)
  1143  			}
  1144  		}
  1145  		index = abs(scalar[i])
  1146  		sm2P256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut)
  1147  		sm2P256SelectJacobianPoint(&px, &py, &pz, &precomp, index)
  1148  		if scalar[i] > 0 {
  1149  			sm2P256PointAdd(xOut, yOut, zOut, &px, &py, &pz, &tx, &ty, &tz)
  1150  		} else {
  1151  			sm2P256PointSub(xOut, yOut, zOut, &px, &py, &pz, &tx, &ty, &tz)
  1152  		}
  1153  		sm2P256CopyConditional(xOut, &px, nIsInfinityMask)
  1154  		sm2P256CopyConditional(yOut, &py, nIsInfinityMask)
  1155  		sm2P256CopyConditional(zOut, &pz, nIsInfinityMask)
  1156  		pIsNoninfiniteMask = nonZeroToAllOnes(index)
  1157  		mask = pIsNoninfiniteMask & ^nIsInfinityMask
  1158  		sm2P256CopyConditional(xOut, &tx, mask)
  1159  		sm2P256CopyConditional(yOut, &ty, mask)
  1160  		sm2P256CopyConditional(zOut, &tz, mask)
  1161  		nIsInfinityMask &^= pIsNoninfiniteMask
  1162  	}
  1163  	if zeroes > 0 {
  1164  		for ; zeroes > 0; zeroes-- {
  1165  			sm2P256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut)
  1166  		}
  1167  	}
  1168  }