github.com/mangodowner/go-gm@v0.0.0-20180818020936-8baa2bd4408c/src/crypto/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 scalarReversed [32]byte 145 var X, Y, Z, X1, Y1 sm2P256FieldElement 146 147 sm2P256FromBig(&X1, x1) 148 sm2P256FromBig(&Y1, y1) 149 sm2P256GetScalar(&scalarReversed, k) 150 sm2P256ScalarMult(&X, &Y, &Z, &X1, &Y1, &scalarReversed) 151 return sm2P256ToAffine(&X, &Y, &Z) 152 } 153 154 func (curve sm2P256Curve) ScalarBaseMult(k []byte) (*big.Int, *big.Int) { 155 var scalarReversed [32]byte 156 var X, Y, Z sm2P256FieldElement 157 158 sm2P256GetScalar(&scalarReversed, k) 159 sm2P256ScalarBaseMult(&X, &Y, &Z, &scalarReversed) 160 return sm2P256ToAffine(&X, &Y, &Z) 161 } 162 163 var sm2P256Precomputed = [9 * 2 * 15 * 2]uint32{ 164 0x830053d, 0x328990f, 0x6c04fe1, 0xc0f72e5, 0x1e19f3c, 0x666b093, 0x175a87b, 0xec38276, 0x222cf4b, 165 0x185a1bba, 0x354e593, 0x1295fac1, 0xf2bc469, 0x47c60fa, 0xc19b8a9, 0xf63533e, 0x903ae6b, 0xc79acba, 166 0x15b061a4, 0x33e020b, 0xdffb34b, 0xfcf2c8, 0x16582e08, 0x262f203, 0xfb34381, 0xa55452, 0x604f0ff, 167 0x41f1f90, 0xd64ced2, 0xee377bf, 0x75f05f0, 0x189467ae, 0xe2244e, 0x1e7700e8, 0x3fbc464, 0x9612d2e, 168 0x1341b3b8, 0xee84e23, 0x1edfa5b4, 0x14e6030, 0x19e87be9, 0x92f533c, 0x1665d96c, 0x226653e, 0xa238d3e, 169 0xf5c62c, 0x95bb7a, 0x1f0e5a41, 0x28789c3, 0x1f251d23, 0x8726609, 0xe918910, 0x8096848, 0xf63d028, 170 0x152296a1, 0x9f561a8, 0x14d376fb, 0x898788a, 0x61a95fb, 0xa59466d, 0x159a003d, 0x1ad1698, 0x93cca08, 171 0x1b314662, 0x706e006, 0x11ce1e30, 0x97b710, 0x172fbc0d, 0x8f50158, 0x11c7ffe7, 0xd182cce, 0xc6ad9e8, 172 0x12ea31b2, 0xc4e4f38, 0x175b0d96, 0xec06337, 0x75a9c12, 0xb001fdf, 0x93e82f5, 0x34607de, 0xb8035ed, 173 0x17f97924, 0x75cf9e6, 0xdceaedd, 0x2529924, 0x1a10c5ff, 0xb1a54dc, 0x19464d8, 0x2d1997, 0xde6a110, 174 0x1e276ee5, 0x95c510c, 0x1aca7c7a, 0xfe48aca, 0x121ad4d9, 0xe4132c6, 0x8239b9d, 0x40ea9cd, 0x816c7b, 175 0x632d7a4, 0xa679813, 0x5911fcf, 0x82b0f7c, 0x57b0ad5, 0xbef65, 0xd541365, 0x7f9921f, 0xc62e7a, 176 0x3f4b32d, 0x58e50e1, 0x6427aed, 0xdcdda67, 0xe8c2d3e, 0x6aa54a4, 0x18df4c35, 0x49a6a8e, 0x3cd3d0c, 177 0xd7adf2, 0xcbca97, 0x1bda5f2d, 0x3258579, 0x606b1e6, 0x6fc1b5b, 0x1ac27317, 0x503ca16, 0xa677435, 178 0x57bc73, 0x3992a42, 0xbab987b, 0xfab25eb, 0x128912a4, 0x90a1dc4, 0x1402d591, 0x9ffbcfc, 0xaa48856, 179 0x7a7c2dc, 0xcefd08a, 0x1b29bda6, 0xa785641, 0x16462d8c, 0x76241b7, 0x79b6c3b, 0x204ae18, 0xf41212b, 180 0x1f567a4d, 0xd6ce6db, 0xedf1784, 0x111df34, 0x85d7955, 0x55fc189, 0x1b7ae265, 0xf9281ac, 0xded7740, 181 0xf19468b, 0x83763bb, 0x8ff7234, 0x3da7df8, 0x9590ac3, 0xdc96f2a, 0x16e44896, 0x7931009, 0x99d5acc, 182 0x10f7b842, 0xaef5e84, 0xc0310d7, 0xdebac2c, 0x2a7b137, 0x4342344, 0x19633649, 0x3a10624, 0x4b4cb56, 183 0x1d809c59, 0xac007f, 0x1f0f4bcd, 0xa1ab06e, 0xc5042cf, 0x82c0c77, 0x76c7563, 0x22c30f3, 0x3bf1568, 184 0x7a895be, 0xfcca554, 0x12e90e4c, 0x7b4ab5f, 0x13aeb76b, 0x5887e2c, 0x1d7fe1e3, 0x908c8e3, 0x95800ee, 185 0xb36bd54, 0xf08905d, 0x4e73ae8, 0xf5a7e48, 0xa67cb0, 0x50e1067, 0x1b944a0a, 0xf29c83a, 0xb23cfb9, 186 0xbe1db1, 0x54de6e8, 0xd4707f2, 0x8ebcc2d, 0x2c77056, 0x1568ce4, 0x15fcc849, 0x4069712, 0xe2ed85f, 187 0x2c5ff09, 0x42a6929, 0x628e7ea, 0xbd5b355, 0xaf0bd79, 0xaa03699, 0xdb99816, 0x4379cef, 0x81d57b, 188 0x11237f01, 0xe2a820b, 0xfd53b95, 0x6beb5ee, 0x1aeb790c, 0xe470d53, 0x2c2cfee, 0x1c1d8d8, 0xa520fc4, 189 0x1518e034, 0xa584dd4, 0x29e572b, 0xd4594fc, 0x141a8f6f, 0x8dfccf3, 0x5d20ba3, 0x2eb60c3, 0x9f16eb0, 190 0x11cec356, 0xf039f84, 0x1b0990c1, 0xc91e526, 0x10b65bae, 0xf0616e8, 0x173fa3ff, 0xec8ccf9, 0xbe32790, 191 0x11da3e79, 0xe2f35c7, 0x908875c, 0xdacf7bd, 0x538c165, 0x8d1487f, 0x7c31aed, 0x21af228, 0x7e1689d, 192 0xdfc23ca, 0x24f15dc, 0x25ef3c4, 0x35248cd, 0x99a0f43, 0xa4b6ecc, 0xd066b3, 0x2481152, 0x37a7688, 193 0x15a444b6, 0xb62300c, 0x4b841b, 0xa655e79, 0xd53226d, 0xbeb348a, 0x127f3c2, 0xb989247, 0x71a277d, 194 0x19e9dfcb, 0xb8f92d0, 0xe2d226c, 0x390a8b0, 0x183cc462, 0x7bd8167, 0x1f32a552, 0x5e02db4, 0xa146ee9, 195 0x1a003957, 0x1c95f61, 0x1eeec155, 0x26f811f, 0xf9596ba, 0x3082bfb, 0x96df083, 0x3e3a289, 0x7e2d8be, 196 0x157a63e0, 0x99b8941, 0x1da7d345, 0xcc6cd0, 0x10beed9a, 0x48e83c0, 0x13aa2e25, 0x7cad710, 0x4029988, 197 0x13dfa9dd, 0xb94f884, 0x1f4adfef, 0xb88543, 0x16f5f8dc, 0xa6a67f4, 0x14e274e2, 0x5e56cf4, 0x2f24ef, 198 0x1e9ef967, 0xfe09bad, 0xfe079b3, 0xcc0ae9e, 0xb3edf6d, 0x3e961bc, 0x130d7831, 0x31043d6, 0xba986f9, 199 0x1d28055, 0x65240ca, 0x4971fa3, 0x81b17f8, 0x11ec34a5, 0x8366ddc, 0x1471809, 0xfa5f1c6, 0xc911e15, 200 0x8849491, 0xcf4c2e2, 0x14471b91, 0x39f75be, 0x445c21e, 0xf1585e9, 0x72cc11f, 0x4c79f0c, 0xe5522e1, 201 0x1874c1ee, 0x4444211, 0x7914884, 0x3d1b133, 0x25ba3c, 0x4194f65, 0x1c0457ef, 0xac4899d, 0xe1fa66c, 202 0x130a7918, 0x9b8d312, 0x4b1c5c8, 0x61ccac3, 0x18c8aa6f, 0xe93cb0a, 0xdccb12c, 0xde10825, 0x969737d, 203 0xf58c0c3, 0x7cee6a9, 0xc2c329a, 0xc7f9ed9, 0x107b3981, 0x696a40e, 0x152847ff, 0x4d88754, 0xb141f47, 204 0x5a16ffe, 0x3a7870a, 0x18667659, 0x3b72b03, 0xb1c9435, 0x9285394, 0xa00005a, 0x37506c, 0x2edc0bb, 205 0x19afe392, 0xeb39cac, 0x177ef286, 0xdf87197, 0x19f844ed, 0x31fe8, 0x15f9bfd, 0x80dbec, 0x342e96e, 206 0x497aced, 0xe88e909, 0x1f5fa9ba, 0x530a6ee, 0x1ef4e3f1, 0x69ffd12, 0x583006d, 0x2ecc9b1, 0x362db70, 207 0x18c7bdc5, 0xf4bb3c5, 0x1c90b957, 0xf067c09, 0x9768f2b, 0xf73566a, 0x1939a900, 0x198c38a, 0x202a2a1, 208 0x4bbf5a6, 0x4e265bc, 0x1f44b6e7, 0x185ca49, 0xa39e81b, 0x24aff5b, 0x4acc9c2, 0x638bdd3, 0xb65b2a8, 209 0x6def8be, 0xb94537a, 0x10b81dee, 0xe00ec55, 0x2f2cdf7, 0xc20622d, 0x2d20f36, 0xe03c8c9, 0x898ea76, 210 0x8e3921b, 0x8905bff, 0x1e94b6c8, 0xee7ad86, 0x154797f2, 0xa620863, 0x3fbd0d9, 0x1f3caab, 0x30c24bd, 211 0x19d3892f, 0x59c17a2, 0x1ab4b0ae, 0xf8714ee, 0x90c4098, 0xa9c800d, 0x1910236b, 0xea808d3, 0x9ae2f31, 212 0x1a15ad64, 0xa48c8d1, 0x184635a4, 0xb725ef1, 0x11921dcc, 0x3f866df, 0x16c27568, 0xbdf580a, 0xb08f55c, 213 0x186ee1c, 0xb1627fa, 0x34e82f6, 0x933837e, 0xf311be5, 0xfedb03b, 0x167f72cd, 0xa5469c0, 0x9c82531, 214 0xb92a24b, 0x14fdc8b, 0x141980d1, 0xbdc3a49, 0x7e02bb1, 0xaf4e6dd, 0x106d99e1, 0xd4616fc, 0x93c2717, 215 0x1c0a0507, 0xc6d5fed, 0x9a03d8b, 0xa1d22b0, 0x127853e3, 0xc4ac6b8, 0x1a048cf7, 0x9afb72c, 0x65d485d, 216 0x72d5998, 0xe9fa744, 0xe49e82c, 0x253cf80, 0x5f777ce, 0xa3799a5, 0x17270cbb, 0xc1d1ef0, 0xdf74977, 217 0x114cb859, 0xfa8e037, 0xb8f3fe5, 0xc734cc6, 0x70d3d61, 0xeadac62, 0x12093dd0, 0x9add67d, 0x87200d6, 218 0x175bcbb, 0xb29b49f, 0x1806b79c, 0x12fb61f, 0x170b3a10, 0x3aaf1cf, 0xa224085, 0x79d26af, 0x97759e2, 219 0x92e19f1, 0xb32714d, 0x1f00d9f1, 0xc728619, 0x9e6f627, 0xe745e24, 0x18ea4ace, 0xfc60a41, 0x125f5b2, 220 0xc3cf512, 0x39ed486, 0xf4d15fa, 0xf9167fd, 0x1c1f5dd5, 0xc21a53e, 0x1897930, 0x957a112, 0x21059a0, 221 0x1f9e3ddc, 0xa4dfced, 0x8427f6f, 0x726fbe7, 0x1ea658f8, 0x2fdcd4c, 0x17e9b66f, 0xb2e7c2e, 0x39923bf, 222 0x1bae104, 0x3973ce5, 0xc6f264c, 0x3511b84, 0x124195d7, 0x11996bd, 0x20be23d, 0xdc437c4, 0x4b4f16b, 223 0x11902a0, 0x6c29cc9, 0x1d5ffbe6, 0xdb0b4c7, 0x10144c14, 0x2f2b719, 0x301189, 0x2343336, 0xa0bf2ac, 224 } 225 226 func sm2P256GetScalar(b *[32]byte, a []byte) { 227 var scalarBytes []byte 228 229 n := new(big.Int).SetBytes(a) 230 if n.Cmp(sm2P256.N) >= 0 { 231 n.Mod(n, sm2P256.N) 232 scalarBytes = n.Bytes() 233 } else { 234 scalarBytes = a 235 } 236 for i, v := range scalarBytes { 237 b[len(scalarBytes)-(1+i)] = v 238 } 239 } 240 241 func sm2P256PointAddMixed(xOut, yOut, zOut, x1, y1, z1, x2, y2 *sm2P256FieldElement) { 242 var z1z1, z1z1z1, s2, u2, h, i, j, r, rr, v, tmp sm2P256FieldElement 243 244 sm2P256Square(&z1z1, z1) 245 sm2P256Add(&tmp, z1, z1) 246 247 sm2P256Mul(&u2, x2, &z1z1) 248 sm2P256Mul(&z1z1z1, z1, &z1z1) 249 sm2P256Mul(&s2, y2, &z1z1z1) 250 sm2P256Sub(&h, &u2, x1) 251 sm2P256Add(&i, &h, &h) 252 sm2P256Square(&i, &i) 253 sm2P256Mul(&j, &h, &i) 254 sm2P256Sub(&r, &s2, y1) 255 sm2P256Add(&r, &r, &r) 256 sm2P256Mul(&v, x1, &i) 257 258 sm2P256Mul(zOut, &tmp, &h) 259 sm2P256Square(&rr, &r) 260 sm2P256Sub(xOut, &rr, &j) 261 sm2P256Sub(xOut, xOut, &v) 262 sm2P256Sub(xOut, xOut, &v) 263 264 sm2P256Sub(&tmp, &v, xOut) 265 sm2P256Mul(yOut, &tmp, &r) 266 sm2P256Mul(&tmp, y1, &j) 267 sm2P256Sub(yOut, yOut, &tmp) 268 sm2P256Sub(yOut, yOut, &tmp) 269 } 270 271 // sm2P256CopyConditional sets out=in if mask = 0xffffffff in constant time. 272 // 273 // On entry: mask is either 0 or 0xffffffff. 274 func sm2P256CopyConditional(out, in *sm2P256FieldElement, mask uint32) { 275 for i := 0; i < 9; i++ { 276 tmp := mask & (in[i] ^ out[i]) 277 out[i] ^= tmp 278 } 279 } 280 281 // sm2P256SelectAffinePoint sets {out_x,out_y} to the index'th entry of table. 282 // On entry: index < 16, table[0] must be zero. 283 func sm2P256SelectAffinePoint(xOut, yOut *sm2P256FieldElement, table []uint32, index uint32) { 284 for i := range xOut { 285 xOut[i] = 0 286 } 287 for i := range yOut { 288 yOut[i] = 0 289 } 290 291 for i := uint32(1); i < 16; i++ { 292 mask := i ^ index 293 mask |= mask >> 2 294 mask |= mask >> 1 295 mask &= 1 296 mask-- 297 for j := range xOut { 298 xOut[j] |= table[0] & mask 299 table = table[1:] 300 } 301 for j := range yOut { 302 yOut[j] |= table[0] & mask 303 table = table[1:] 304 } 305 } 306 } 307 308 // sm2P256SelectJacobianPoint sets {out_x,out_y,out_z} to the index'th entry of 309 // table. 310 // On entry: index < 16, table[0] must be zero. 311 func sm2P256SelectJacobianPoint(xOut, yOut, zOut *sm2P256FieldElement, table *[16][3]sm2P256FieldElement, index uint32) { 312 for i := range xOut { 313 xOut[i] = 0 314 } 315 for i := range yOut { 316 yOut[i] = 0 317 } 318 for i := range zOut { 319 zOut[i] = 0 320 } 321 322 // The implicit value at index 0 is all zero. We don't need to perform that 323 // iteration of the loop because we already set out_* to zero. 324 for i := uint32(1); i < 16; i++ { 325 mask := i ^ index 326 mask |= mask >> 2 327 mask |= mask >> 1 328 mask &= 1 329 mask-- 330 for j := range xOut { 331 xOut[j] |= table[i][0][j] & mask 332 } 333 for j := range yOut { 334 yOut[j] |= table[i][1][j] & mask 335 } 336 for j := range zOut { 337 zOut[j] |= table[i][2][j] & mask 338 } 339 } 340 } 341 342 // sm2P256GetBit returns the bit'th bit of scalar. 343 func sm2P256GetBit(scalar *[32]uint8, bit uint) uint32 { 344 return uint32(((scalar[bit>>3]) >> (bit & 7)) & 1) 345 } 346 347 // sm2P256ScalarBaseMult sets {xOut,yOut,zOut} = scalar*G where scalar is a 348 // little-endian number. Note that the value of scalar must be less than the 349 // order of the group. 350 func sm2P256ScalarBaseMult(xOut, yOut, zOut *sm2P256FieldElement, scalar *[32]uint8) { 351 nIsInfinityMask := ^uint32(0) 352 var px, py, tx, ty, tz sm2P256FieldElement 353 var pIsNoninfiniteMask, mask, tableOffset uint32 354 355 for i := range xOut { 356 xOut[i] = 0 357 } 358 for i := range yOut { 359 yOut[i] = 0 360 } 361 for i := range zOut { 362 zOut[i] = 0 363 } 364 365 // The loop adds bits at positions 0, 64, 128 and 192, followed by 366 // positions 32,96,160 and 224 and does this 32 times. 367 for i := uint(0); i < 32; i++ { 368 if i != 0 { 369 sm2P256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut) 370 } 371 tableOffset = 0 372 for j := uint(0); j <= 32; j += 32 { 373 bit0 := sm2P256GetBit(scalar, 31-i+j) 374 bit1 := sm2P256GetBit(scalar, 95-i+j) 375 bit2 := sm2P256GetBit(scalar, 159-i+j) 376 bit3 := sm2P256GetBit(scalar, 223-i+j) 377 index := bit0 | (bit1 << 1) | (bit2 << 2) | (bit3 << 3) 378 379 sm2P256SelectAffinePoint(&px, &py, sm2P256Precomputed[tableOffset:], index) 380 tableOffset += 30 * 9 381 382 // Since scalar is less than the order of the group, we know that 383 // {xOut,yOut,zOut} != {px,py,1}, unless both are zero, which we handle 384 // below. 385 sm2P256PointAddMixed(&tx, &ty, &tz, xOut, yOut, zOut, &px, &py) 386 // The result of pointAddMixed is incorrect if {xOut,yOut,zOut} is zero 387 // (a.k.a. the point at infinity). We handle that situation by 388 // copying the point from the table. 389 sm2P256CopyConditional(xOut, &px, nIsInfinityMask) 390 sm2P256CopyConditional(yOut, &py, nIsInfinityMask) 391 sm2P256CopyConditional(zOut, &sm2P256Factor[1], nIsInfinityMask) 392 393 // Equally, the result is also wrong if the point from the table is 394 // zero, which happens when the index is zero. We handle that by 395 // only copying from {tx,ty,tz} to {xOut,yOut,zOut} if index != 0. 396 pIsNoninfiniteMask = nonZeroToAllOnes(index) 397 mask = pIsNoninfiniteMask & ^nIsInfinityMask 398 sm2P256CopyConditional(xOut, &tx, mask) 399 sm2P256CopyConditional(yOut, &ty, mask) 400 sm2P256CopyConditional(zOut, &tz, mask) 401 // If p was not zero, then n is now non-zero. 402 nIsInfinityMask &^= pIsNoninfiniteMask 403 } 404 } 405 } 406 407 func sm2P256ScalarMult(xOut, yOut, zOut, x, y *sm2P256FieldElement, scalar *[32]uint8) { 408 var precomp [16][3]sm2P256FieldElement 409 var px, py, pz, tx, ty, tz sm2P256FieldElement 410 var nIsInfinityMask, index, pIsNoninfiniteMask, mask uint32 411 412 // We precompute 0,1,2,... times {x,y}. 413 precomp[1][0] = *x 414 precomp[1][1] = *y 415 precomp[1][2] = sm2P256Factor[1] 416 417 for i := 2; i < 16; i += 2 { 418 sm2P256PointDouble(&precomp[i][0], &precomp[i][1], &precomp[i][2], &precomp[i/2][0], &precomp[i/2][1], &precomp[i/2][2]) 419 sm2P256PointAddMixed(&precomp[i+1][0], &precomp[i+1][1], &precomp[i+1][2], &precomp[i][0], &precomp[i][1], &precomp[i][2], x, y) 420 } 421 422 for i := range xOut { 423 xOut[i] = 0 424 } 425 for i := range yOut { 426 yOut[i] = 0 427 } 428 for i := range zOut { 429 zOut[i] = 0 430 } 431 nIsInfinityMask = ^uint32(0) 432 433 // We add in a window of four bits each iteration and do this 64 times. 434 for i := 0; i < 64; i++ { 435 if i != 0 { 436 sm2P256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut) 437 sm2P256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut) 438 sm2P256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut) 439 sm2P256PointDouble(xOut, yOut, zOut, xOut, yOut, zOut) 440 } 441 442 index = uint32(scalar[31-i/2]) 443 if (i & 1) == 1 { 444 index &= 15 445 } else { 446 index >>= 4 447 } 448 449 // See the comments in scalarBaseMult about handling infinities. 450 sm2P256SelectJacobianPoint(&px, &py, &pz, &precomp, index) 451 sm2P256PointAdd(xOut, yOut, zOut, &px, &py, &pz, &tx, &ty, &tz) 452 sm2P256CopyConditional(xOut, &px, nIsInfinityMask) 453 sm2P256CopyConditional(yOut, &py, nIsInfinityMask) 454 sm2P256CopyConditional(zOut, &pz, nIsInfinityMask) 455 456 pIsNoninfiniteMask = nonZeroToAllOnes(index) 457 mask = pIsNoninfiniteMask & ^nIsInfinityMask 458 sm2P256CopyConditional(xOut, &tx, mask) 459 sm2P256CopyConditional(yOut, &ty, mask) 460 sm2P256CopyConditional(zOut, &tz, mask) 461 nIsInfinityMask &^= pIsNoninfiniteMask 462 } 463 } 464 465 func sm2P256PointToAffine(xOut, yOut, x, y, z *sm2P256FieldElement) { 466 var zInv, zInvSq sm2P256FieldElement 467 468 zz := sm2P256ToBig(z) 469 zz.ModInverse(zz, sm2P256.P) 470 sm2P256FromBig(&zInv, zz) 471 472 sm2P256Square(&zInvSq, &zInv) 473 sm2P256Mul(xOut, x, &zInvSq) 474 sm2P256Mul(&zInv, &zInv, &zInvSq) 475 sm2P256Mul(yOut, y, &zInv) 476 } 477 478 func sm2P256ToAffine(x, y, z *sm2P256FieldElement) (xOut, yOut *big.Int) { 479 var xx, yy sm2P256FieldElement 480 481 sm2P256PointToAffine(&xx, &yy, x, y, z) 482 return sm2P256ToBig(&xx), sm2P256ToBig(&yy) 483 } 484 485 var sm2P256Factor = []sm2P256FieldElement{ 486 sm2P256FieldElement{0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0}, 487 sm2P256FieldElement{0x2, 0x0, 0x1FFFFF00, 0x7FF, 0x0, 0x0, 0x0, 0x2000000, 0x0}, 488 sm2P256FieldElement{0x4, 0x0, 0x1FFFFE00, 0xFFF, 0x0, 0x0, 0x0, 0x4000000, 0x0}, 489 sm2P256FieldElement{0x6, 0x0, 0x1FFFFD00, 0x17FF, 0x0, 0x0, 0x0, 0x6000000, 0x0}, 490 sm2P256FieldElement{0x8, 0x0, 0x1FFFFC00, 0x1FFF, 0x0, 0x0, 0x0, 0x8000000, 0x0}, 491 sm2P256FieldElement{0xA, 0x0, 0x1FFFFB00, 0x27FF, 0x0, 0x0, 0x0, 0xA000000, 0x0}, 492 sm2P256FieldElement{0xC, 0x0, 0x1FFFFA00, 0x2FFF, 0x0, 0x0, 0x0, 0xC000000, 0x0}, 493 sm2P256FieldElement{0xE, 0x0, 0x1FFFF900, 0x37FF, 0x0, 0x0, 0x0, 0xE000000, 0x0}, 494 sm2P256FieldElement{0x10, 0x0, 0x1FFFF800, 0x3FFF, 0x0, 0x0, 0x0, 0x0, 0x01}, 495 } 496 497 func sm2P256Scalar(b *sm2P256FieldElement, a int) { 498 sm2P256Mul(b, b, &sm2P256Factor[a]) 499 } 500 501 // (x3, y3, z3) = (x1, y1, z1) + (x2, y2, z2) 502 func sm2P256PointAdd(x1, y1, z1, x2, y2, z2, x3, y3, z3 *sm2P256FieldElement) { 503 var u1, u2, z22, z12, z23, z13, s1, s2, h, h2, r, r2, tm sm2P256FieldElement 504 505 if sm2P256ToBig(z1).Sign() == 0 { 506 sm2P256Dup(x3, x2) 507 sm2P256Dup(y3, y2) 508 sm2P256Dup(z3, z2) 509 return 510 } 511 512 if sm2P256ToBig(z2).Sign() == 0 { 513 sm2P256Dup(x3, x1) 514 sm2P256Dup(y3, y1) 515 sm2P256Dup(z3, z1) 516 return 517 } 518 519 sm2P256Square(&z12, z1) // z12 = z1 ^ 2 520 sm2P256Square(&z22, z2) // z22 = z2 ^ 2 521 522 sm2P256Mul(&z13, &z12, z1) // z13 = z1 ^ 3 523 sm2P256Mul(&z23, &z22, z2) // z23 = z2 ^ 3 524 525 sm2P256Mul(&u1, x1, &z22) // u1 = x1 * z2 ^ 2 526 sm2P256Mul(&u2, x2, &z12) // u2 = x2 * z1 ^ 2 527 528 sm2P256Mul(&s1, y1, &z23) // s1 = y1 * z2 ^ 3 529 sm2P256Mul(&s2, y2, &z13) // s2 = y2 * z1 ^ 3 530 531 if sm2P256ToBig(&u1).Cmp(sm2P256ToBig(&u2)) == 0 && 532 sm2P256ToBig(&s1).Cmp(sm2P256ToBig(&s2)) == 0 { 533 sm2P256PointDouble(x1, y1, z1, x1, y1, z1) 534 } 535 536 sm2P256Sub(&h, &u2, &u1) // h = u2 - u1 537 sm2P256Sub(&r, &s2, &s1) // r = s2 - s1 538 539 sm2P256Square(&r2, &r) // r2 = r ^ 2 540 sm2P256Square(&h2, &h) // h2 = h ^ 2 541 542 sm2P256Mul(&tm, &h2, &h) // tm = h ^ 3 543 sm2P256Sub(x3, &r2, &tm) 544 sm2P256Mul(&tm, &u1, &h2) 545 sm2P256Scalar(&tm, 2) // tm = 2 * (u1 * h ^ 2) 546 sm2P256Sub(x3, x3, &tm) // x3 = r ^ 2 - h ^ 3 - 2 * u1 * h ^ 2 547 548 sm2P256Mul(&tm, &u1, &h2) // tm = u1 * h ^ 2 549 sm2P256Sub(&tm, &tm, x3) // tm = u1 * h ^ 2 - x3 550 sm2P256Mul(y3, &r, &tm) 551 sm2P256Mul(&tm, &h2, &h) // tm = h ^ 3 552 sm2P256Mul(&tm, &tm, &s1) // tm = s1 * h ^ 3 553 sm2P256Sub(y3, y3, &tm) // y3 = r * (u1 * h ^ 2 - x3) - s1 * h ^ 3 554 555 sm2P256Mul(z3, z1, z2) 556 sm2P256Mul(z3, z3, &h) // z3 = z1 * z3 * h 557 } 558 559 func sm2P256PointDouble(x3, y3, z3, x, y, z *sm2P256FieldElement) { 560 var s, m, m2, x2, y2, z2, z4, y4, az4 sm2P256FieldElement 561 562 sm2P256Square(&x2, x) // x2 = x ^ 2 563 sm2P256Square(&y2, y) // y2 = y ^ 2 564 sm2P256Square(&z2, z) // z2 = z ^ 2 565 566 sm2P256Square(&z4, z) // z4 = z ^ 2 567 sm2P256Mul(&z4, &z4, z) // z4 = z ^ 3 568 sm2P256Mul(&z4, &z4, z) // z4 = z ^ 4 569 570 sm2P256Square(&y4, y) // y4 = y ^ 2 571 sm2P256Mul(&y4, &y4, y) // y4 = y ^ 3 572 sm2P256Mul(&y4, &y4, y) // y4 = y ^ 4 573 sm2P256Scalar(&y4, 8) // y4 = 8 * y ^ 4 574 575 sm2P256Mul(&s, x, &y2) 576 sm2P256Scalar(&s, 4) // s = 4 * x * y ^ 2 577 578 sm2P256Dup(&m, &x2) 579 sm2P256Scalar(&m, 3) 580 sm2P256Mul(&az4, &sm2P256.a, &z4) 581 sm2P256Add(&m, &m, &az4) // m = 3 * x ^ 2 + a * z ^ 4 582 583 sm2P256Square(&m2, &m) // m2 = m ^ 2 584 585 sm2P256Add(z3, y, z) 586 sm2P256Square(z3, z3) 587 sm2P256Sub(z3, z3, &z2) 588 sm2P256Sub(z3, z3, &y2) // z' = (y + z) ^2 - z ^ 2 - y ^ 2 589 590 sm2P256Sub(x3, &m2, &s) 591 sm2P256Sub(x3, x3, &s) // x' = m2 - 2 * s 592 593 sm2P256Sub(y3, &s, x3) 594 sm2P256Mul(y3, y3, &m) 595 sm2P256Sub(y3, y3, &y4) // y' = m * (s - x') - 8 * y ^ 4 596 } 597 598 // p256Zero31 is 0 mod p. 599 var sm2P256Zero31 = sm2P256FieldElement{0x7FFFFFF8, 0x3FFFFFFC, 0x800003FC, 0x3FFFDFFC, 0x7FFFFFFC, 0x3FFFFFFC, 0x7FFFFFFC, 0x37FFFFFC, 0x7FFFFFFC} 600 601 // c = a + b 602 func sm2P256Add(c, a, b *sm2P256FieldElement) { 603 carry := uint32(0) 604 for i := 0; ; i++ { 605 c[i] = a[i] + b[i] 606 c[i] += carry 607 carry = c[i] >> 29 608 c[i] &= bottom29Bits 609 i++ 610 if i == 9 { 611 break 612 } 613 c[i] = a[i] + b[i] 614 c[i] += carry 615 carry = c[i] >> 28 616 c[i] &= bottom28Bits 617 } 618 sm2P256ReduceCarry(c, carry) 619 } 620 621 // c = a - b 622 func sm2P256Sub(c, a, b *sm2P256FieldElement) { 623 var carry uint32 624 625 for i := 0; ; i++ { 626 c[i] = a[i] - b[i] 627 c[i] += sm2P256Zero31[i] 628 c[i] += carry 629 carry = c[i] >> 29 630 c[i] &= bottom29Bits 631 i++ 632 if i == 9 { 633 break 634 } 635 c[i] = a[i] - b[i] 636 c[i] += sm2P256Zero31[i] 637 c[i] += carry 638 carry = c[i] >> 28 639 c[i] &= bottom28Bits 640 } 641 sm2P256ReduceCarry(c, carry) 642 } 643 644 // c = a * b 645 func sm2P256Mul(c, a, b *sm2P256FieldElement) { 646 var tmp sm2P256LargeFieldElement 647 648 tmp[0] = uint64(a[0]) * uint64(b[0]) 649 tmp[1] = uint64(a[0])*(uint64(b[1])<<0) + 650 uint64(a[1])*(uint64(b[0])<<0) 651 tmp[2] = uint64(a[0])*(uint64(b[2])<<0) + 652 uint64(a[1])*(uint64(b[1])<<1) + 653 uint64(a[2])*(uint64(b[0])<<0) 654 tmp[3] = uint64(a[0])*(uint64(b[3])<<0) + 655 uint64(a[1])*(uint64(b[2])<<0) + 656 uint64(a[2])*(uint64(b[1])<<0) + 657 uint64(a[3])*(uint64(b[0])<<0) 658 tmp[4] = uint64(a[0])*(uint64(b[4])<<0) + 659 uint64(a[1])*(uint64(b[3])<<1) + 660 uint64(a[2])*(uint64(b[2])<<0) + 661 uint64(a[3])*(uint64(b[1])<<1) + 662 uint64(a[4])*(uint64(b[0])<<0) 663 tmp[5] = uint64(a[0])*(uint64(b[5])<<0) + 664 uint64(a[1])*(uint64(b[4])<<0) + 665 uint64(a[2])*(uint64(b[3])<<0) + 666 uint64(a[3])*(uint64(b[2])<<0) + 667 uint64(a[4])*(uint64(b[1])<<0) + 668 uint64(a[5])*(uint64(b[0])<<0) 669 tmp[6] = uint64(a[0])*(uint64(b[6])<<0) + 670 uint64(a[1])*(uint64(b[5])<<1) + 671 uint64(a[2])*(uint64(b[4])<<0) + 672 uint64(a[3])*(uint64(b[3])<<1) + 673 uint64(a[4])*(uint64(b[2])<<0) + 674 uint64(a[5])*(uint64(b[1])<<1) + 675 uint64(a[6])*(uint64(b[0])<<0) 676 tmp[7] = uint64(a[0])*(uint64(b[7])<<0) + 677 uint64(a[1])*(uint64(b[6])<<0) + 678 uint64(a[2])*(uint64(b[5])<<0) + 679 uint64(a[3])*(uint64(b[4])<<0) + 680 uint64(a[4])*(uint64(b[3])<<0) + 681 uint64(a[5])*(uint64(b[2])<<0) + 682 uint64(a[6])*(uint64(b[1])<<0) + 683 uint64(a[7])*(uint64(b[0])<<0) 684 // tmp[8] has the greatest value but doesn't overflow. See logic in 685 // p256Square. 686 tmp[8] = uint64(a[0])*(uint64(b[8])<<0) + 687 uint64(a[1])*(uint64(b[7])<<1) + 688 uint64(a[2])*(uint64(b[6])<<0) + 689 uint64(a[3])*(uint64(b[5])<<1) + 690 uint64(a[4])*(uint64(b[4])<<0) + 691 uint64(a[5])*(uint64(b[3])<<1) + 692 uint64(a[6])*(uint64(b[2])<<0) + 693 uint64(a[7])*(uint64(b[1])<<1) + 694 uint64(a[8])*(uint64(b[0])<<0) 695 tmp[9] = uint64(a[1])*(uint64(b[8])<<0) + 696 uint64(a[2])*(uint64(b[7])<<0) + 697 uint64(a[3])*(uint64(b[6])<<0) + 698 uint64(a[4])*(uint64(b[5])<<0) + 699 uint64(a[5])*(uint64(b[4])<<0) + 700 uint64(a[6])*(uint64(b[3])<<0) + 701 uint64(a[7])*(uint64(b[2])<<0) + 702 uint64(a[8])*(uint64(b[1])<<0) 703 tmp[10] = uint64(a[2])*(uint64(b[8])<<0) + 704 uint64(a[3])*(uint64(b[7])<<1) + 705 uint64(a[4])*(uint64(b[6])<<0) + 706 uint64(a[5])*(uint64(b[5])<<1) + 707 uint64(a[6])*(uint64(b[4])<<0) + 708 uint64(a[7])*(uint64(b[3])<<1) + 709 uint64(a[8])*(uint64(b[2])<<0) 710 tmp[11] = uint64(a[3])*(uint64(b[8])<<0) + 711 uint64(a[4])*(uint64(b[7])<<0) + 712 uint64(a[5])*(uint64(b[6])<<0) + 713 uint64(a[6])*(uint64(b[5])<<0) + 714 uint64(a[7])*(uint64(b[4])<<0) + 715 uint64(a[8])*(uint64(b[3])<<0) 716 tmp[12] = uint64(a[4])*(uint64(b[8])<<0) + 717 uint64(a[5])*(uint64(b[7])<<1) + 718 uint64(a[6])*(uint64(b[6])<<0) + 719 uint64(a[7])*(uint64(b[5])<<1) + 720 uint64(a[8])*(uint64(b[4])<<0) 721 tmp[13] = uint64(a[5])*(uint64(b[8])<<0) + 722 uint64(a[6])*(uint64(b[7])<<0) + 723 uint64(a[7])*(uint64(b[6])<<0) + 724 uint64(a[8])*(uint64(b[5])<<0) 725 tmp[14] = uint64(a[6])*(uint64(b[8])<<0) + 726 uint64(a[7])*(uint64(b[7])<<1) + 727 uint64(a[8])*(uint64(b[6])<<0) 728 tmp[15] = uint64(a[7])*(uint64(b[8])<<0) + 729 uint64(a[8])*(uint64(b[7])<<0) 730 tmp[16] = uint64(a[8]) * (uint64(b[8]) << 0) 731 sm2P256ReduceDegree(c, &tmp) 732 } 733 734 // b = a * a 735 func sm2P256Square(b, a *sm2P256FieldElement) { 736 var tmp sm2P256LargeFieldElement 737 738 tmp[0] = uint64(a[0]) * uint64(a[0]) 739 tmp[1] = uint64(a[0]) * (uint64(a[1]) << 1) 740 tmp[2] = uint64(a[0])*(uint64(a[2])<<1) + 741 uint64(a[1])*(uint64(a[1])<<1) 742 tmp[3] = uint64(a[0])*(uint64(a[3])<<1) + 743 uint64(a[1])*(uint64(a[2])<<1) 744 tmp[4] = uint64(a[0])*(uint64(a[4])<<1) + 745 uint64(a[1])*(uint64(a[3])<<2) + 746 uint64(a[2])*uint64(a[2]) 747 tmp[5] = uint64(a[0])*(uint64(a[5])<<1) + 748 uint64(a[1])*(uint64(a[4])<<1) + 749 uint64(a[2])*(uint64(a[3])<<1) 750 tmp[6] = uint64(a[0])*(uint64(a[6])<<1) + 751 uint64(a[1])*(uint64(a[5])<<2) + 752 uint64(a[2])*(uint64(a[4])<<1) + 753 uint64(a[3])*(uint64(a[3])<<1) 754 tmp[7] = uint64(a[0])*(uint64(a[7])<<1) + 755 uint64(a[1])*(uint64(a[6])<<1) + 756 uint64(a[2])*(uint64(a[5])<<1) + 757 uint64(a[3])*(uint64(a[4])<<1) 758 // tmp[8] has the greatest value of 2**61 + 2**60 + 2**61 + 2**60 + 2**60, 759 // which is < 2**64 as required. 760 tmp[8] = uint64(a[0])*(uint64(a[8])<<1) + 761 uint64(a[1])*(uint64(a[7])<<2) + 762 uint64(a[2])*(uint64(a[6])<<1) + 763 uint64(a[3])*(uint64(a[5])<<2) + 764 uint64(a[4])*uint64(a[4]) 765 tmp[9] = uint64(a[1])*(uint64(a[8])<<1) + 766 uint64(a[2])*(uint64(a[7])<<1) + 767 uint64(a[3])*(uint64(a[6])<<1) + 768 uint64(a[4])*(uint64(a[5])<<1) 769 tmp[10] = uint64(a[2])*(uint64(a[8])<<1) + 770 uint64(a[3])*(uint64(a[7])<<2) + 771 uint64(a[4])*(uint64(a[6])<<1) + 772 uint64(a[5])*(uint64(a[5])<<1) 773 tmp[11] = uint64(a[3])*(uint64(a[8])<<1) + 774 uint64(a[4])*(uint64(a[7])<<1) + 775 uint64(a[5])*(uint64(a[6])<<1) 776 tmp[12] = uint64(a[4])*(uint64(a[8])<<1) + 777 uint64(a[5])*(uint64(a[7])<<2) + 778 uint64(a[6])*uint64(a[6]) 779 tmp[13] = uint64(a[5])*(uint64(a[8])<<1) + 780 uint64(a[6])*(uint64(a[7])<<1) 781 tmp[14] = uint64(a[6])*(uint64(a[8])<<1) + 782 uint64(a[7])*(uint64(a[7])<<1) 783 tmp[15] = uint64(a[7]) * (uint64(a[8]) << 1) 784 tmp[16] = uint64(a[8]) * uint64(a[8]) 785 sm2P256ReduceDegree(b, &tmp) 786 } 787 788 // nonZeroToAllOnes returns: 789 // 0xffffffff for 0 < x <= 2**31 790 // 0 for x == 0 or x > 2**31. 791 func nonZeroToAllOnes(x uint32) uint32 { 792 return ((x - 1) >> 31) - 1 793 } 794 795 var sm2P256Carry = [8 * 9]uint32{ 796 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 0x0, 797 0x2, 0x0, 0x1FFFFF00, 0x7FF, 0x0, 0x0, 0x0, 0x2000000, 0x0, 798 0x4, 0x0, 0x1FFFFE00, 0xFFF, 0x0, 0x0, 0x0, 0x4000000, 0x0, 799 0x6, 0x0, 0x1FFFFD00, 0x17FF, 0x0, 0x0, 0x0, 0x6000000, 0x0, 800 0x8, 0x0, 0x1FFFFC00, 0x1FFF, 0x0, 0x0, 0x0, 0x8000000, 0x0, 801 0xA, 0x0, 0x1FFFFB00, 0x27FF, 0x0, 0x0, 0x0, 0xA000000, 0x0, 802 0xC, 0x0, 0x1FFFFA00, 0x2FFF, 0x0, 0x0, 0x0, 0xC000000, 0x0, 803 0xE, 0x0, 0x1FFFF900, 0x37FF, 0x0, 0x0, 0x0, 0xE000000, 0x0, 804 } 805 806 // carry < 2 ^ 3 807 func sm2P256ReduceCarry(a *sm2P256FieldElement, carry uint32) { 808 a[0] += sm2P256Carry[carry*9+0] 809 a[2] += sm2P256Carry[carry*9+2] 810 a[3] += sm2P256Carry[carry*9+3] 811 a[7] += sm2P256Carry[carry*9+7] 812 } 813 814 // 这代码真是丑比了,我也是对自己醉了。。。 815 // 你最好别改这个代码,不然你会死的很惨。。 816 func sm2P256ReduceDegree(a *sm2P256FieldElement, b *sm2P256LargeFieldElement) { 817 var tmp [18]uint32 818 var carry, x, xMask uint32 819 820 // tmp 821 // 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 ... 822 // 29 | 28 | 29 | 28 | 29 | 28 | 29 | 28 | 29 | 28 | 29 ... 823 tmp[0] = uint32(b[0]) & bottom29Bits 824 tmp[1] = uint32(b[0]) >> 29 825 tmp[1] |= (uint32(b[0]>>32) << 3) & bottom28Bits 826 tmp[1] += uint32(b[1]) & bottom28Bits 827 carry = tmp[1] >> 28 828 tmp[1] &= bottom28Bits 829 for i := 2; i < 17; i++ { 830 tmp[i] = (uint32(b[i-2] >> 32)) >> 25 831 tmp[i] += (uint32(b[i-1])) >> 28 832 tmp[i] += (uint32(b[i-1]>>32) << 4) & bottom29Bits 833 tmp[i] += uint32(b[i]) & bottom29Bits 834 tmp[i] += carry 835 carry = tmp[i] >> 29 836 tmp[i] &= bottom29Bits 837 838 i++ 839 if i == 17 { 840 break 841 } 842 tmp[i] = uint32(b[i-2]>>32) >> 25 843 tmp[i] += uint32(b[i-1]) >> 29 844 tmp[i] += ((uint32(b[i-1] >> 32)) << 3) & bottom28Bits 845 tmp[i] += uint32(b[i]) & bottom28Bits 846 tmp[i] += carry 847 carry = tmp[i] >> 28 848 tmp[i] &= bottom28Bits 849 } 850 tmp[17] = uint32(b[15]>>32) >> 25 851 tmp[17] += uint32(b[16]) >> 29 852 tmp[17] += uint32(b[16]>>32) << 3 853 tmp[17] += carry 854 855 for i := 0; ; i += 2 { 856 857 tmp[i+1] += tmp[i] >> 29 858 x = tmp[i] & bottom29Bits 859 tmp[i] = 0 860 if x > 0 { 861 set4 := uint32(0) 862 set7 := uint32(0) 863 xMask = nonZeroToAllOnes(x) 864 tmp[i+2] += (x << 7) & bottom29Bits 865 tmp[i+3] += x >> 22 866 if tmp[i+3] < 0x10000000 { 867 set4 = 1 868 tmp[i+3] += 0x10000000 & xMask 869 tmp[i+3] -= (x << 10) & bottom28Bits 870 } else { 871 tmp[i+3] -= (x << 10) & bottom28Bits 872 } 873 if tmp[i+4] < 0x20000000 { 874 tmp[i+4] += 0x20000000 & xMask 875 tmp[i+4] -= set4 // 借位 876 tmp[i+4] -= x >> 18 877 if tmp[i+5] < 0x10000000 { 878 tmp[i+5] += 0x10000000 & xMask 879 tmp[i+5] -= 1 // 借位 880 if tmp[i+6] < 0x20000000 { 881 set7 = 1 882 tmp[i+6] += 0x20000000 & xMask 883 tmp[i+6] -= 1 // 借位 884 } else { 885 tmp[i+6] -= 1 // 借位 886 } 887 } else { 888 tmp[i+5] -= 1 889 } 890 } else { 891 tmp[i+4] -= set4 // 借位 892 tmp[i+4] -= x >> 18 893 } 894 if tmp[i+7] < 0x10000000 { 895 tmp[i+7] += 0x10000000 & xMask 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] -= 1 902 tmp[i+8] -= x >> 4 903 tmp[i+9] += ((x >> 1) - 1) & xMask 904 } else { 905 tmp[i+8] -= 1 906 tmp[i+8] -= x >> 4 907 tmp[i+9] += (x >> 1) & xMask 908 } 909 } else { 910 tmp[i+7] -= set7 // 借位 911 tmp[i+7] -= (x << 24) & bottom28Bits 912 tmp[i+8] += (x << 28) & bottom29Bits 913 if tmp[i+8] < 0x20000000 { 914 tmp[i+8] += 0x20000000 & xMask 915 tmp[i+8] -= x >> 4 916 tmp[i+9] += ((x >> 1) - 1) & xMask 917 } else { 918 tmp[i+8] -= x >> 4 919 tmp[i+9] += (x >> 1) & xMask 920 } 921 } 922 923 } 924 925 if i+1 == 9 { 926 break 927 } 928 929 tmp[i+2] += tmp[i+1] >> 28 930 x = tmp[i+1] & bottom28Bits 931 tmp[i+1] = 0 932 if x > 0 { 933 set5 := uint32(0) 934 set8 := uint32(0) 935 set9 := uint32(0) 936 xMask = nonZeroToAllOnes(x) 937 tmp[i+3] += (x << 7) & bottom28Bits 938 tmp[i+4] += x >> 21 939 if tmp[i+4] < 0x20000000 { 940 set5 = 1 941 tmp[i+4] += 0x20000000 & xMask 942 tmp[i+4] -= (x << 11) & bottom29Bits 943 } else { 944 tmp[i+4] -= (x << 11) & bottom29Bits 945 } 946 if tmp[i+5] < 0x10000000 { 947 tmp[i+5] += 0x10000000 & xMask 948 tmp[i+5] -= set5 // 借位 949 tmp[i+5] -= x >> 18 950 if tmp[i+6] < 0x20000000 { 951 tmp[i+6] += 0x20000000 & xMask 952 tmp[i+6] -= 1 // 借位 953 if tmp[i+7] < 0x10000000 { 954 set8 = 1 955 tmp[i+7] += 0x10000000 & xMask 956 tmp[i+7] -= 1 // 借位 957 } else { 958 tmp[i+7] -= 1 // 借位 959 } 960 } else { 961 tmp[i+6] -= 1 // 借位 962 } 963 } else { 964 tmp[i+5] -= set5 // 借位 965 tmp[i+5] -= x >> 18 966 } 967 if tmp[i+8] < 0x20000000 { 968 set9 = 1 969 tmp[i+8] += 0x20000000 & xMask 970 tmp[i+8] -= set8 971 tmp[i+8] -= (x << 25) & bottom29Bits 972 } else { 973 tmp[i+8] -= set8 974 tmp[i+8] -= (x << 25) & bottom29Bits 975 } 976 if tmp[i+9] < 0x10000000 { 977 tmp[i+9] += 0x10000000 & xMask 978 tmp[i+9] -= set9 // 借位 979 tmp[i+9] -= x >> 4 980 tmp[i+10] += (x - 1) & xMask 981 } else { 982 tmp[i+9] -= set9 // 借位 983 tmp[i+9] -= x >> 4 984 tmp[i+10] += x & xMask 985 } 986 } 987 } 988 989 carry = uint32(0) 990 for i := 0; i < 8; i++ { 991 a[i] = tmp[i+9] 992 a[i] += carry 993 a[i] += (tmp[i+10] << 28) & bottom29Bits 994 carry = a[i] >> 29 995 a[i] &= bottom29Bits 996 997 i++ 998 a[i] = tmp[i+9] >> 1 999 a[i] += carry 1000 carry = a[i] >> 28 1001 a[i] &= bottom28Bits 1002 } 1003 a[8] = tmp[17] 1004 a[8] += carry 1005 carry = a[8] >> 29 1006 a[8] &= bottom29Bits 1007 sm2P256ReduceCarry(a, carry) 1008 } 1009 1010 // b = a 1011 func sm2P256Dup(b, a *sm2P256FieldElement) { 1012 *b = *a 1013 } 1014 1015 // X = a * R mod P 1016 func sm2P256FromBig(X *sm2P256FieldElement, a *big.Int) { 1017 x := new(big.Int).Lsh(a, 257) 1018 x.Mod(x, sm2P256.P) 1019 for i := 0; i < 9; i++ { 1020 if bits := x.Bits(); len(bits) > 0 { 1021 X[i] = uint32(bits[0]) & bottom29Bits 1022 } else { 1023 X[i] = 0 1024 } 1025 x.Rsh(x, 29) 1026 i++ 1027 if i == 9 { 1028 break 1029 } 1030 if bits := x.Bits(); len(bits) > 0 { 1031 X[i] = uint32(bits[0]) & bottom28Bits 1032 } else { 1033 X[i] = 0 1034 } 1035 x.Rsh(x, 28) 1036 } 1037 } 1038 1039 // X = r * R mod P 1040 // r = X * R' mod P 1041 func sm2P256ToBig(X *sm2P256FieldElement) *big.Int { 1042 r, tm := new(big.Int), new(big.Int) 1043 r.SetInt64(int64(X[8])) 1044 for i := 7; i >= 0; i-- { 1045 if (i & 1) == 0 { 1046 r.Lsh(r, 29) 1047 } else { 1048 r.Lsh(r, 28) 1049 } 1050 tm.SetInt64(int64(X[i])) 1051 r.Add(r, tm) 1052 } 1053 r.Mul(r, sm2P256.RInverse) 1054 r.Mod(r, sm2P256.P) 1055 return r 1056 }