gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/sm2soft/p256.go (about)

     1  // Copyright (c) 2022 zhaochun
     2  // core-gm 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  //
   777  //	0xffffffff for 0 < x <= 2**31
   778  //	0 for x == 0 or x > 2**31.
   779  func nonZeroToAllOnes(x uint32) uint32 {
   780  	return ((x - 1) >> 31) - 1
   781  }
   782  
   783  var sm2P256Carry = [8 * 9]uint32{
   784  	0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0,
   785  	0x2, 0x0, 0x1FFFFF00, 0x7FF, 0x0, 0x0, 0x0, 0x2000000, 0x0,
   786  	0x4, 0x0, 0x1FFFFE00, 0xFFF, 0x0, 0x0, 0x0, 0x4000000, 0x0,
   787  	0x6, 0x0, 0x1FFFFD00, 0x17FF, 0x0, 0x0, 0x0, 0x6000000, 0x0,
   788  	0x8, 0x0, 0x1FFFFC00, 0x1FFF, 0x0, 0x0, 0x0, 0x8000000, 0x0,
   789  	0xA, 0x0, 0x1FFFFB00, 0x27FF, 0x0, 0x0, 0x0, 0xA000000, 0x0,
   790  	0xC, 0x0, 0x1FFFFA00, 0x2FFF, 0x0, 0x0, 0x0, 0xC000000, 0x0,
   791  	0xE, 0x0, 0x1FFFF900, 0x37FF, 0x0, 0x0, 0x0, 0xE000000, 0x0,
   792  }
   793  
   794  // carry < 2 ^ 3
   795  func sm2P256ReduceCarry(a *sm2P256FieldElement, carry uint32) {
   796  	a[0] += sm2P256Carry[carry*9+0]
   797  	a[2] += sm2P256Carry[carry*9+2]
   798  	a[3] += sm2P256Carry[carry*9+3]
   799  	a[7] += sm2P256Carry[carry*9+7]
   800  }
   801  
   802  func sm2P256ReduceDegree(a *sm2P256FieldElement, b *sm2P256LargeFieldElement) {
   803  	var tmp [18]uint32
   804  	var carry, x, xMask uint32
   805  
   806  	// tmp
   807  	// 0  | 1  | 2  | 3  | 4  | 5  | 6  | 7  | 8  |  9 | 10 ...
   808  	// 29 | 28 | 29 | 28 | 29 | 28 | 29 | 28 | 29 | 28 | 29 ...
   809  	tmp[0] = uint32(b[0]) & bottom29Bits
   810  	tmp[1] = uint32(b[0]) >> 29
   811  	tmp[1] |= (uint32(b[0]>>32) << 3) & bottom28Bits
   812  	tmp[1] += uint32(b[1]) & bottom28Bits
   813  	carry = tmp[1] >> 28
   814  	tmp[1] &= bottom28Bits
   815  	for i := 2; i < 17; i++ {
   816  		tmp[i] = (uint32(b[i-2] >> 32)) >> 25
   817  		tmp[i] += (uint32(b[i-1])) >> 28
   818  		tmp[i] += (uint32(b[i-1]>>32) << 4) & bottom29Bits
   819  		tmp[i] += uint32(b[i]) & bottom29Bits
   820  		tmp[i] += carry
   821  		carry = tmp[i] >> 29
   822  		tmp[i] &= bottom29Bits
   823  
   824  		i++
   825  		if i == 17 {
   826  			break
   827  		}
   828  		tmp[i] = uint32(b[i-2]>>32) >> 25
   829  		tmp[i] += uint32(b[i-1]) >> 29
   830  		tmp[i] += ((uint32(b[i-1] >> 32)) << 3) & bottom28Bits
   831  		tmp[i] += uint32(b[i]) & bottom28Bits
   832  		tmp[i] += carry
   833  		carry = tmp[i] >> 28
   834  		tmp[i] &= bottom28Bits
   835  	}
   836  	tmp[17] = uint32(b[15]>>32) >> 25
   837  	tmp[17] += uint32(b[16]) >> 29
   838  	tmp[17] += uint32(b[16]>>32) << 3
   839  	tmp[17] += carry
   840  
   841  	for i := 0; ; i += 2 {
   842  
   843  		tmp[i+1] += tmp[i] >> 29
   844  		x = tmp[i] & bottom29Bits
   845  		tmp[i] = 0
   846  		if x > 0 {
   847  			set4 := uint32(0)
   848  			set7 := uint32(0)
   849  			xMask = nonZeroToAllOnes(x)
   850  			tmp[i+2] += (x << 7) & bottom29Bits
   851  			tmp[i+3] += x >> 22
   852  			if tmp[i+3] < 0x10000000 {
   853  				set4 = 1
   854  				tmp[i+3] += 0x10000000 & xMask
   855  				tmp[i+3] -= (x << 10) & bottom28Bits
   856  			} else {
   857  				tmp[i+3] -= (x << 10) & bottom28Bits
   858  			}
   859  			if tmp[i+4] < 0x20000000 {
   860  				tmp[i+4] += 0x20000000 & xMask
   861  				tmp[i+4] -= set4 // 借位
   862  				tmp[i+4] -= x >> 18
   863  				if tmp[i+5] < 0x10000000 {
   864  					tmp[i+5] += 0x10000000 & xMask
   865  					tmp[i+5] -= 1 // 借位
   866  					if tmp[i+6] < 0x20000000 {
   867  						set7 = 1
   868  						tmp[i+6] += 0x20000000 & xMask
   869  						tmp[i+6] -= 1 // 借位
   870  					} else {
   871  						tmp[i+6] -= 1 // 借位
   872  					}
   873  				} else {
   874  					tmp[i+5] -= 1
   875  				}
   876  			} else {
   877  				tmp[i+4] -= set4 // 借位
   878  				tmp[i+4] -= x >> 18
   879  			}
   880  			if tmp[i+7] < 0x10000000 {
   881  				tmp[i+7] += 0x10000000 & xMask
   882  				tmp[i+7] -= set7
   883  				tmp[i+7] -= (x << 24) & bottom28Bits
   884  				tmp[i+8] += (x << 28) & bottom29Bits
   885  				if tmp[i+8] < 0x20000000 {
   886  					tmp[i+8] += 0x20000000 & xMask
   887  					tmp[i+8] -= 1
   888  					tmp[i+8] -= x >> 4
   889  					tmp[i+9] += ((x >> 1) - 1) & xMask
   890  				} else {
   891  					tmp[i+8] -= 1
   892  					tmp[i+8] -= x >> 4
   893  					tmp[i+9] += (x >> 1) & xMask
   894  				}
   895  			} else {
   896  				tmp[i+7] -= set7 // 借位
   897  				tmp[i+7] -= (x << 24) & bottom28Bits
   898  				tmp[i+8] += (x << 28) & bottom29Bits
   899  				if tmp[i+8] < 0x20000000 {
   900  					tmp[i+8] += 0x20000000 & xMask
   901  					tmp[i+8] -= x >> 4
   902  					tmp[i+9] += ((x >> 1) - 1) & xMask
   903  				} else {
   904  					tmp[i+8] -= x >> 4
   905  					tmp[i+9] += (x >> 1) & xMask
   906  				}
   907  			}
   908  
   909  		}
   910  
   911  		if i+1 == 9 {
   912  			break
   913  		}
   914  
   915  		tmp[i+2] += tmp[i+1] >> 28
   916  		x = tmp[i+1] & bottom28Bits
   917  		tmp[i+1] = 0
   918  		if x > 0 {
   919  			set5 := uint32(0)
   920  			set8 := uint32(0)
   921  			set9 := uint32(0)
   922  			xMask = nonZeroToAllOnes(x)
   923  			tmp[i+3] += (x << 7) & bottom28Bits
   924  			tmp[i+4] += x >> 21
   925  			if tmp[i+4] < 0x20000000 {
   926  				set5 = 1
   927  				tmp[i+4] += 0x20000000 & xMask
   928  				tmp[i+4] -= (x << 11) & bottom29Bits
   929  			} else {
   930  				tmp[i+4] -= (x << 11) & bottom29Bits
   931  			}
   932  			if tmp[i+5] < 0x10000000 {
   933  				tmp[i+5] += 0x10000000 & xMask
   934  				tmp[i+5] -= set5 // 借位
   935  				tmp[i+5] -= x >> 18
   936  				if tmp[i+6] < 0x20000000 {
   937  					tmp[i+6] += 0x20000000 & xMask
   938  					tmp[i+6] -= 1 // 借位
   939  					if tmp[i+7] < 0x10000000 {
   940  						set8 = 1
   941  						tmp[i+7] += 0x10000000 & xMask
   942  						tmp[i+7] -= 1 // 借位
   943  					} else {
   944  						tmp[i+7] -= 1 // 借位
   945  					}
   946  				} else {
   947  					tmp[i+6] -= 1 // 借位
   948  				}
   949  			} else {
   950  				tmp[i+5] -= set5 // 借位
   951  				tmp[i+5] -= x >> 18
   952  			}
   953  			if tmp[i+8] < 0x20000000 {
   954  				set9 = 1
   955  				tmp[i+8] += 0x20000000 & xMask
   956  				tmp[i+8] -= set8
   957  				tmp[i+8] -= (x << 25) & bottom29Bits
   958  			} else {
   959  				tmp[i+8] -= set8
   960  				tmp[i+8] -= (x << 25) & bottom29Bits
   961  			}
   962  			if tmp[i+9] < 0x10000000 {
   963  				tmp[i+9] += 0x10000000 & xMask
   964  				tmp[i+9] -= set9 // 借位
   965  				tmp[i+9] -= x >> 4
   966  				tmp[i+10] += (x - 1) & xMask
   967  			} else {
   968  				tmp[i+9] -= set9 // 借位
   969  				tmp[i+9] -= x >> 4
   970  				tmp[i+10] += x & xMask
   971  			}
   972  		}
   973  	}
   974  
   975  	carry = uint32(0)
   976  	for i := 0; i < 8; i++ {
   977  		a[i] = tmp[i+9]
   978  		a[i] += carry
   979  		a[i] += (tmp[i+10] << 28) & bottom29Bits
   980  		carry = a[i] >> 29
   981  		a[i] &= bottom29Bits
   982  
   983  		i++
   984  		a[i] = tmp[i+9] >> 1
   985  		a[i] += carry
   986  		carry = a[i] >> 28
   987  		a[i] &= bottom28Bits
   988  	}
   989  	a[8] = tmp[17]
   990  	a[8] += carry
   991  	carry = a[8] >> 29
   992  	a[8] &= bottom29Bits
   993  	sm2P256ReduceCarry(a, carry)
   994  }
   995  
   996  // b = a
   997  func sm2P256Dup(b, a *sm2P256FieldElement) {
   998  	*b = *a
   999  }
  1000  
  1001  // X = a * R mod P
  1002  func sm2P256FromBig(X *sm2P256FieldElement, a *big.Int) {
  1003  	x := new(big.Int).Lsh(a, 257)
  1004  	x.Mod(x, sm2P256.P)
  1005  	for i := 0; i < 9; i++ {
  1006  		if bits := x.Bits(); len(bits) > 0 {
  1007  			X[i] = uint32(bits[0]) & bottom29Bits
  1008  		} else {
  1009  			X[i] = 0
  1010  		}
  1011  		x.Rsh(x, 29)
  1012  		i++
  1013  		if i == 9 {
  1014  			break
  1015  		}
  1016  		if bits := x.Bits(); len(bits) > 0 {
  1017  			X[i] = uint32(bits[0]) & bottom28Bits
  1018  		} else {
  1019  			X[i] = 0
  1020  		}
  1021  		x.Rsh(x, 28)
  1022  	}
  1023  }
  1024  
  1025  // X = r * R mod P
  1026  // r = X * R' mod P
  1027  func sm2P256ToBig(X *sm2P256FieldElement) *big.Int {
  1028  	r, tm := new(big.Int), new(big.Int)
  1029  	r.SetInt64(int64(X[8]))
  1030  	for i := 7; i >= 0; i-- {
  1031  		if (i & 1) == 0 {
  1032  			r.Lsh(r, 29)
  1033  		} else {
  1034  			r.Lsh(r, 28)
  1035  		}
  1036  		tm.SetInt64(int64(X[i]))
  1037  		r.Add(r, tm)
  1038  	}
  1039  	r.Mul(r, sm2P256.RInverse)
  1040  	r.Mod(r, sm2P256.P)
  1041  	return r
  1042  }
  1043  func WNafReversed(wnaf []int8) []int8 {
  1044  	// wnafRev := make([]int8, len(wnaf), len(wnaf))
  1045  	wnafRev := make([]int8, len(wnaf))
  1046  	for i, v := range wnaf {
  1047  		wnafRev[len(wnaf)-(1+i)] = v
  1048  	}
  1049  	return wnafRev
  1050  }
  1051  func sm2GenrateWNaf(b []byte) []int8 {
  1052  	n := new(big.Int).SetBytes(b)
  1053  	var k *big.Int
  1054  	if n.Cmp(sm2P256.N) >= 0 {
  1055  		n.Mod(n, sm2P256.N)
  1056  		k = n
  1057  	} else {
  1058  		k = n
  1059  	}
  1060  	// wnaf := make([]int8, k.BitLen()+1, k.BitLen()+1)
  1061  	wnaf := make([]int8, k.BitLen()+1)
  1062  	if k.Sign() == 0 {
  1063  		return wnaf
  1064  	}
  1065  	var width, pow2, sign int
  1066  	width, pow2, sign = 4, 16, 8
  1067  	var mask int64 = 15
  1068  	var carry bool
  1069  	var length, pos int
  1070  	for pos <= k.BitLen() {
  1071  		if k.Bit(pos) == boolToUint(carry) {
  1072  			pos++
  1073  			continue
  1074  		}
  1075  		k.Rsh(k, uint(pos))
  1076  		var digit int
  1077  		digit = int(k.Int64() & mask)
  1078  		if carry {
  1079  			digit++
  1080  		}
  1081  		carry = (digit & sign) != 0
  1082  		if carry {
  1083  			digit -= pow2
  1084  		}
  1085  		length += pos
  1086  		wnaf[length] = int8(digit)
  1087  		pos = width
  1088  	}
  1089  	if len(wnaf) > length+1 {
  1090  		// t := make([]int8, length+1, length+1)
  1091  		t := make([]int8, length+1)
  1092  		copy(t, wnaf[0:length+1])
  1093  		wnaf = t
  1094  	}
  1095  	return wnaf
  1096  }
  1097  func boolToUint(b bool) uint {
  1098  	if b {
  1099  		return 1
  1100  	}
  1101  	return 0
  1102  }
  1103  func abs(a int8) uint32 {
  1104  	if a < 0 {
  1105  		return uint32(-a)
  1106  	}
  1107  	return uint32(a)
  1108  }
  1109  
  1110  func sm2P256ScalarMult(xOut, yOut, zOut, x, y *sm2P256FieldElement, scalar []int8) {
  1111  	var precomp [16][3]sm2P256FieldElement
  1112  	var px, py, pz, tx, ty, tz sm2P256FieldElement
  1113  	var nIsInfinityMask, index, pIsNoninfiniteMask, mask uint32
  1114  
  1115  	// We precompute 0,1,2,... times {x,y}.
  1116  	precomp[1][0] = *x
  1117  	precomp[1][1] = *y
  1118  	precomp[1][2] = sm2P256Factor[1]
  1119  
  1120  	for i := 2; i < 8; i += 2 {
  1121  		sm2P256PointDouble(&precomp[i][0], &precomp[i][1], &precomp[i][2], &precomp[i/2][0], &precomp[i/2][1], &precomp[i/2][2])
  1122  		sm2P256PointAddMixed(&precomp[i+1][0], &precomp[i+1][1], &precomp[i+1][2], &precomp[i][0], &precomp[i][1], &precomp[i][2], x, y)
  1123  	}
  1124  
  1125  	for i := range xOut {
  1126  		xOut[i] = 0
  1127  	}
  1128  	for i := range yOut {
  1129  		yOut[i] = 0
  1130  	}
  1131  	for i := range zOut {
  1132  		zOut[i] = 0
  1133  	}
  1134  	nIsInfinityMask = ^uint32(0)
  1135  	var zeroes int16
  1136  	for i := 0; i < len(scalar); i++ {
  1137  		if scalar[i] == 0 {
  1138  			zeroes++
  1139  			continue
  1140  		}
  1141  		if zeroes > 0 {
  1142  			for ; zeroes > 0; zeroes-- {
  1143  				sm2P256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut)
  1144  			}
  1145  		}
  1146  		index = abs(scalar[i])
  1147  		sm2P256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut)
  1148  		sm2P256SelectJacobianPoint(&px, &py, &pz, &precomp, index)
  1149  		if scalar[i] > 0 {
  1150  			sm2P256PointAdd(xOut, yOut, zOut, &px, &py, &pz, &tx, &ty, &tz)
  1151  		} else {
  1152  			sm2P256PointSub(xOut, yOut, zOut, &px, &py, &pz, &tx, &ty, &tz)
  1153  		}
  1154  		sm2P256CopyConditional(xOut, &px, nIsInfinityMask)
  1155  		sm2P256CopyConditional(yOut, &py, nIsInfinityMask)
  1156  		sm2P256CopyConditional(zOut, &pz, nIsInfinityMask)
  1157  		pIsNoninfiniteMask = nonZeroToAllOnes(index)
  1158  		mask = pIsNoninfiniteMask & ^nIsInfinityMask
  1159  		sm2P256CopyConditional(xOut, &tx, mask)
  1160  		sm2P256CopyConditional(yOut, &ty, mask)
  1161  		sm2P256CopyConditional(zOut, &tz, mask)
  1162  		nIsInfinityMask &^= pIsNoninfiniteMask
  1163  	}
  1164  	if zeroes > 0 {
  1165  		for ; zeroes > 0; zeroes-- {
  1166  			sm2P256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut)
  1167  		}
  1168  	}
  1169  }