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 }