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 }