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