github.com/hxx258456/ccgo@v0.0.5-0.20230213014102-48b35f46f66f/sm2/p256_asm_test.go (about) 1 //go:build amd64 || arm64 2 // +build amd64 arm64 3 4 package sm2 5 6 import ( 7 "crypto/rand" 8 "encoding/hex" 9 "fmt" 10 "io" 11 "math/big" 12 "testing" 13 "time" 14 ) 15 16 func toBigInt(in []uint64) *big.Int { 17 var valBytes = make([]byte, 32) 18 p256LittleToBig(valBytes, in) 19 return new(big.Int).SetBytes(valBytes) 20 } 21 22 // ordk0 = -n^(-1) mod 2^64 23 func Test_p256ordk0(t *testing.T) { 24 n, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", 16) 25 p, _ := new(big.Int).SetString("10000000000000000", 16) // 2^64 26 n = n.ModInverse(n, p) 27 n = n.Neg(n) 28 n = n.Mod(n, p) 29 if hex.EncodeToString(n.Bytes()) != "327f9e8872350975" { 30 t.Failed() 31 } 32 } 33 34 func Test_p256NegCond(t *testing.T) { 35 p, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) 36 var val = []uint64{0x61328990f418029e, 0x3e7981eddca6c050, 0xd6a1ed99ac24c3c3, 0x91167a5ee1c13b05} 37 bigVal := toBigInt(val) 38 39 p256NegCond(val, 0) 40 bigVal1 := toBigInt(val) 41 if bigVal.Cmp(bigVal1) != 0 { 42 t.Fatal("should be same") 43 } 44 p256NegCond(val, 1) 45 bigVal1 = toBigInt(val) 46 if bigVal.Cmp(bigVal1) == 0 { 47 t.Fatal("should be different") 48 } 49 bigVal2 := new(big.Int).Sub(p, bigVal) 50 if bigVal2.Cmp(bigVal1) != 0 { 51 t.Fatal("should be same") 52 } 53 } 54 55 func Test_p256FromMont(t *testing.T) { 56 res := make([]uint64, 4) 57 p256FromMont(res, []uint64{0x0000000000000001, 0x00000000ffffffff, 0x0000000000000000, 0x0000000100000000}) 58 res1 := (res[0] ^ 0x0000000000000001) | res[1] | res[2] | res[3] 59 if res1 != 0 { 60 t.FailNow() 61 } 62 x, _ := new(big.Int).SetString("32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16) 63 x1 := make([]uint64, 4) 64 p256BigToLittle(x1, x.Bytes()) 65 66 p256FromMont(res, []uint64{0x61328990f418029e, 0x3e7981eddca6c050, 0xd6a1ed99ac24c3c3, 0x91167a5ee1c13b05}) 67 if (res[0]^x1[0])|(res[1]^x1[1])|(res[2]^x1[2])|(res[3]^x1[3]) != 0 { 68 t.FailNow() 69 } 70 } 71 72 func Test_p256Sqr(t *testing.T) { 73 r, _ := new(big.Int).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) 74 p, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) 75 x, _ := new(big.Int).SetString("32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16) 76 one := []uint64{0x0000000000000001, 0x00000000ffffffff, 0x0000000000000000, 0x0000000100000000} 77 res := make([]uint64, 4) 78 p256Sqr(res, one, 2) 79 if (res[0]^one[0])|(res[1]^one[1])|(res[2]^one[2])|(res[3]^one[3]) != 0 { 80 t.FailNow() 81 } 82 gx := []uint64{0x61328990f418029e, 0x3e7981eddca6c050, 0xd6a1ed99ac24c3c3, 0x91167a5ee1c13b05} 83 p256Sqr(res, gx, 2) 84 resInt := toBigInt(res) 85 fmt.Printf("1=%s\n", hex.EncodeToString(resInt.Bytes())) 86 gxsqr := new(big.Int).Mul(x, x) 87 gxsqr = new(big.Int).Mod(gxsqr, p) 88 gxsqr = new(big.Int).Mul(gxsqr, gxsqr) 89 gxsqr = new(big.Int).Mod(gxsqr, p) 90 gxsqr = new(big.Int).Mul(gxsqr, r) 91 gxsqr = new(big.Int).Mod(gxsqr, p) 92 fmt.Printf("2=%s\n", hex.EncodeToString(gxsqr.Bytes())) 93 if resInt.Cmp(gxsqr) != 0 { 94 t.FailNow() 95 } 96 } 97 98 func Test_p256Mul(t *testing.T) { 99 r, _ := new(big.Int).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) 100 p, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) 101 x, _ := new(big.Int).SetString("32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16) 102 y, _ := new(big.Int).SetString("BC3736A2F4F6779C59BDCEE36B692153D0A9877CC62A474002DF32E52139F0A0", 16) 103 res := make([]uint64, 4) 104 gx := []uint64{0x61328990f418029e, 0x3e7981eddca6c050, 0xd6a1ed99ac24c3c3, 0x91167a5ee1c13b05} 105 gy := []uint64{0xc1354e593c2d0ddd, 0xc1f5e5788d3295fa, 0x8d4cfb066e2a48f8, 0x63cd65d481d735bd} 106 107 p256Mul(res, gx, gy) 108 resInt := toBigInt(res) 109 fmt.Printf("1=%s\n", hex.EncodeToString(resInt.Bytes())) 110 xmy := new(big.Int).Mul(x, y) 111 xmy = new(big.Int).Mod(xmy, p) 112 xmy = new(big.Int).Mul(xmy, r) 113 xmy = new(big.Int).Mod(xmy, p) 114 fmt.Printf("2=%s\n", hex.EncodeToString(xmy.Bytes())) 115 if resInt.Cmp(xmy) != 0 { 116 t.FailNow() 117 } 118 } 119 120 func p256SqrTest(t *testing.T, x, p, r *big.Int) { 121 x1 := new(big.Int).Mul(x, r) 122 x1 = x1.Mod(x1, p) 123 ax := make([]uint64, 4) 124 res := make([]uint64, 4) 125 res2 := make([]uint64, 4) 126 fromBig(ax, x1) 127 p256Sqr(res2, ax, 1) 128 p256FromMont(res, res2) 129 resInt := toBigInt(res) 130 131 expected := new(big.Int).Mul(x, x) 132 expected = expected.Mod(expected, p) 133 if resInt.Cmp(expected) != 0 { 134 t.FailNow() 135 } 136 } 137 138 func TestFuzzyP256Sqr(t *testing.T) { 139 p, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) 140 r, _ := new(big.Int).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) 141 var scalar1 [32]byte 142 var timeout *time.Timer 143 144 if testing.Short() { 145 timeout = time.NewTimer(10 * time.Millisecond) 146 } else { 147 timeout = time.NewTimer(2 * time.Second) 148 } 149 for { 150 select { 151 case <-timeout.C: 152 return 153 default: 154 } 155 _, err := io.ReadFull(rand.Reader, scalar1[:]) 156 if err != nil { 157 t.Fatal(err) 158 } 159 x := new(big.Int).SetBytes(scalar1[:]) 160 p256SqrTest(t, x, p, r) 161 } 162 } 163 164 func p256MulTest(t *testing.T, x, y, p, r *big.Int) { 165 x1 := new(big.Int).Mul(x, r) 166 x1 = x1.Mod(x1, p) 167 y1 := new(big.Int).Mul(y, r) 168 y1 = y1.Mod(y1, p) 169 ax := make([]uint64, 4) 170 ay := make([]uint64, 4) 171 res := make([]uint64, 4) 172 res2 := make([]uint64, 4) 173 fromBig(ax, x1) 174 fromBig(ay, y1) 175 p256Mul(res2, ax, ay) 176 p256FromMont(res, res2) 177 resInt := toBigInt(res) 178 179 expected := new(big.Int).Mul(x, y) 180 expected = expected.Mod(expected, p) 181 if resInt.Cmp(expected) != 0 { 182 t.FailNow() 183 } 184 } 185 186 func TestFuzzyP256Mul(t *testing.T) { 187 p, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) 188 r, _ := new(big.Int).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) 189 var scalar1 [32]byte 190 var scalar2 [32]byte 191 var timeout *time.Timer 192 193 if testing.Short() { 194 timeout = time.NewTimer(10 * time.Millisecond) 195 } else { 196 timeout = time.NewTimer(2 * time.Second) 197 } 198 for { 199 select { 200 case <-timeout.C: 201 return 202 default: 203 } 204 _, err := io.ReadFull(rand.Reader, scalar1[:]) 205 if err != nil { 206 t.Fatal(err) 207 } 208 _, err = io.ReadFull(rand.Reader, scalar2[:]) 209 if err != nil { 210 t.Fatal(err) 211 } 212 x := new(big.Int).SetBytes(scalar1[:]) 213 y := new(big.Int).SetBytes(scalar2[:]) 214 p256MulTest(t, x, y, p, r) 215 } 216 } 217 218 func Test_p256MulSqr(t *testing.T) { 219 r, _ := new(big.Int).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) 220 p, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) 221 x, _ := new(big.Int).SetString("32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16) 222 res := make([]uint64, 4) 223 gx := []uint64{0x61328990f418029e, 0x3e7981eddca6c050, 0xd6a1ed99ac24c3c3, 0x91167a5ee1c13b05} 224 225 p256Sqr(res, gx, 32) 226 resInt := toBigInt(res) 227 fmt.Printf("0=%s\n", hex.EncodeToString(resInt.Bytes())) 228 229 p256Mul(res, gx, gx) 230 for i := 0; i < 31; i++ { 231 p256Mul(res, res, res) 232 } 233 resInt1 := toBigInt(res) 234 fmt.Printf("1=%s\n", hex.EncodeToString(resInt1.Bytes())) 235 236 resInt2 := new(big.Int).Mod(x, p) 237 238 for i := 0; i < 32; i++ { 239 resInt2 = new(big.Int).Mul(resInt2, resInt2) 240 resInt2 = new(big.Int).Mod(resInt2, p) 241 } 242 resInt2 = new(big.Int).Mul(resInt2, r) 243 resInt2 = new(big.Int).Mod(resInt2, p) 244 fmt.Printf("2=%s\n", hex.EncodeToString(resInt2.Bytes())) 245 246 if resInt.Cmp(resInt2) != 0 || resInt1.Cmp(resInt2) != 0 { 247 t.FailNow() 248 } 249 } 250 251 func Test_p256OrdSqr(t *testing.T) { 252 r, _ := new(big.Int).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) 253 n, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", 16) 254 x, _ := new(big.Int).SetString("32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16) 255 gx := make([]uint64, 4) 256 res := make([]uint64, 4) 257 xm := new(big.Int).Mul(x, r) 258 xm = new(big.Int).Mod(xm, n) 259 p256BigToLittle(gx, xm.Bytes()) 260 p256OrdMul(res, gx, gx) 261 resInt := toBigInt(res) 262 fmt.Printf("p256OrdMul=%s\n", hex.EncodeToString(resInt.Bytes())) 263 gxsqr := new(big.Int).Mul(x, x) 264 gxsqr = new(big.Int).Mod(gxsqr, n) 265 gxsqr = new(big.Int).Mul(gxsqr, r) 266 gxsqr = new(big.Int).Mod(gxsqr, n) 267 fmt.Printf("2=%s\n", hex.EncodeToString(gxsqr.Bytes())) 268 if resInt.Cmp(gxsqr) != 0 { 269 t.FailNow() 270 } 271 p256OrdSqr(res, gx, 1) 272 resInt = toBigInt(res) 273 fmt.Printf("p256OrdSqr=%s\n", hex.EncodeToString(resInt.Bytes())) 274 if resInt.Cmp(gxsqr) != 0 { 275 t.FailNow() 276 } 277 } 278 279 func Test_p256Inverse(t *testing.T) { 280 r, _ := new(big.Int).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) 281 p, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) 282 x, _ := new(big.Int).SetString("32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16) 283 gx := []uint64{0x61328990f418029e, 0x3e7981eddca6c050, 0xd6a1ed99ac24c3c3, 0x91167a5ee1c13b05} 284 res := make([]uint64, 4) 285 p256Inverse(res, gx) 286 resInt := toBigInt(res) 287 fmt.Printf("p256Inverse=%s\n", hex.EncodeToString(resInt.Bytes())) 288 xInv := new(big.Int).ModInverse(x, p) 289 xInv = new(big.Int).Mul(xInv, r) 290 xInv = new(big.Int).Mod(xInv, p) 291 fmt.Printf("expected=%s\n", hex.EncodeToString(xInv.Bytes())) 292 if resInt.Cmp(xInv) != 0 { 293 t.FailNow() 294 } 295 } 296 297 func Test_p256PointAddAsm_basepoint(t *testing.T) { 298 curve1 := P256Sm2() 299 params := curve1.Params() 300 basePoint := []uint64{ 301 0x61328990f418029e, 0x3e7981eddca6c050, 0xd6a1ed99ac24c3c3, 0x91167a5ee1c13b05, 302 0xc1354e593c2d0ddd, 0xc1f5e5788d3295fa, 0x8d4cfb066e2a48f8, 0x63cd65d481d735bd, 303 0x0000000000000001, 0x00000000ffffffff, 0x0000000000000000, 0x0000000100000000, 304 } 305 in := make([]uint64, 12) 306 res := make([]uint64, 12) 307 copy(in, basePoint) 308 p256PointDoubleAsm(res, in) 309 n := p256PointAddAsm(res, res, in) 310 fmt.Printf("n=%d\n", n) 311 var r p256Point 312 copy(r.xyz[:], res) 313 x1, y1 := r.p256PointToAffine() 314 fmt.Printf("x1=%s, y1=%s\n", hex.EncodeToString(x1.Bytes()), hex.EncodeToString(y1.Bytes())) 315 316 x2, y2 := params.Double(params.Gx, params.Gy) 317 x2, y2 = params.Add(params.Gx, params.Gy, x2, y2) 318 fmt.Printf("x2=%s, y2=%s\n", hex.EncodeToString(x2.Bytes()), hex.EncodeToString(y2.Bytes())) 319 if x1.Cmp(x2) != 0 || y1.Cmp(y2) != 0 { 320 t.FailNow() 321 } 322 } 323 324 func Test_p256PointDoubleAsm(t *testing.T) { 325 basePoint := []uint64{ 326 0x61328990f418029e, 0x3e7981eddca6c050, 0xd6a1ed99ac24c3c3, 0x91167a5ee1c13b05, 327 0xc1354e593c2d0ddd, 0xc1f5e5788d3295fa, 0x8d4cfb066e2a48f8, 0x63cd65d481d735bd, 328 0x0000000000000001, 0x00000000ffffffff, 0x0000000000000000, 0x0000000100000000, 329 } 330 t1 := make([]uint64, 12) 331 copy(t1, basePoint) 332 for i := 0; i < 16; i++ { 333 p256PointDoubleAsm(t1, t1) 334 } 335 var r p256Point 336 copy(r.xyz[:], t1) 337 x1, y1 := r.p256PointToAffine() 338 fmt.Printf("x1=%s, y1=%s\n", hex.EncodeToString(x1.Bytes()), hex.EncodeToString(y1.Bytes())) 339 curve1 := P256Sm2() 340 params := curve1.Params() 341 x2, y2 := params.Double(params.Gx, params.Gy) 342 for i := 0; i < 15; i++ { 343 x2, y2 = params.Double(x2, y2) 344 } 345 fmt.Printf("x2=%s, y2=%s\n", hex.EncodeToString(x2.Bytes()), hex.EncodeToString(y2.Bytes())) 346 if x1.Cmp(x2) != 0 || y1.Cmp(y2) != 0 { 347 t.FailNow() 348 } 349 } 350 351 func Test_ScalarBaseMult(t *testing.T) { 352 scalar := big.NewInt(0xffffffff) 353 curve1 := P256Sm2() 354 x1, y1 := curve1.ScalarBaseMult(scalar.Bytes()) 355 fmt.Printf("x1=%s, y1=%s\n", hex.EncodeToString(x1.Bytes()), hex.EncodeToString(y1.Bytes())) 356 params := curve1.Params() 357 x2, y2 := params.ScalarBaseMult(scalar.Bytes()) 358 fmt.Printf("x2=%s, y2=%s\n", hex.EncodeToString(x2.Bytes()), hex.EncodeToString(y2.Bytes())) 359 if x1.Cmp(x2) != 0 || y1.Cmp(y2) != 0 { 360 t.FailNow() 361 } 362 } 363 364 func Test_p256PointAddAsm(t *testing.T) { 365 curve1 := P256Sm2() 366 params := curve1.Params() 367 k1, _ := randFieldElement(params, rand.Reader) 368 x1, y1 := params.ScalarBaseMult(k1.Bytes()) 369 k2, _ := randFieldElement(params, rand.Reader) 370 x2, y2 := params.ScalarBaseMult(k2.Bytes()) 371 x3, y3 := params.Add(x1, y1, x2, y2) 372 fmt.Printf("x1=%s, y1=%s\n", hex.EncodeToString(x3.Bytes()), hex.EncodeToString(y3.Bytes())) 373 var in1, in2, rp p256Point 374 fromBig(in1.xyz[0:4], maybeReduceModP(x1)) 375 fromBig(in1.xyz[4:8], maybeReduceModP(y1)) 376 fromBig(in2.xyz[0:4], maybeReduceModP(x2)) 377 fromBig(in2.xyz[4:8], maybeReduceModP(y2)) 378 in1.xyz[8] = 0x0000000000000001 379 in1.xyz[9] = 0x00000000ffffffff 380 in1.xyz[10] = 0x0000000000000000 381 in1.xyz[11] = 0x0000000100000000 382 in2.xyz[8] = 0x0000000000000001 383 in2.xyz[9] = 0x00000000ffffffff 384 in2.xyz[10] = 0x0000000000000000 385 in2.xyz[11] = 0x0000000100000000 386 p256Mul(in1.xyz[0:4], in1.xyz[0:4], rr[:]) 387 p256Mul(in1.xyz[4:8], in1.xyz[4:8], rr[:]) 388 p256Mul(in2.xyz[0:4], in2.xyz[0:4], rr[:]) 389 p256Mul(in2.xyz[4:8], in2.xyz[4:8], rr[:]) 390 res := make([]uint64, 12) 391 n := p256PointAddAsm(res, in1.xyz[:], in2.xyz[:]) 392 fmt.Printf("n=%d\n", n) 393 copy(rp.xyz[:], res) 394 x4, y4 := rp.p256PointToAffine() 395 fmt.Printf("x1=%s, y1=%s\n", hex.EncodeToString(x4.Bytes()), hex.EncodeToString(y4.Bytes())) 396 if n == 0 && (x3.Cmp(x4) != 0 || y3.Cmp(y4) != 0) { 397 t.FailNow() 398 } 399 } 400 401 func Test_ScalarMult_basepoint(t *testing.T) { 402 scalar := big.NewInt(0xffffffff) 403 curve1 := P256Sm2() 404 x1, y1 := curve1.ScalarMult(curve1.Params().Gx, curve1.Params().Gy, scalar.Bytes()) 405 fmt.Printf("x1=%s, y1=%s\n", hex.EncodeToString(x1.Bytes()), hex.EncodeToString(y1.Bytes())) 406 params := curve1.Params() 407 x2, y2 := params.ScalarMult(curve1.Params().Gx, curve1.Params().Gy, scalar.Bytes()) 408 fmt.Printf("x2=%s, y2=%s\n", hex.EncodeToString(x2.Bytes()), hex.EncodeToString(y2.Bytes())) 409 if x1.Cmp(x2) != 0 || y1.Cmp(y2) != 0 { 410 t.FailNow() 411 } 412 } 413 414 func Test_Inverse(t *testing.T) { 415 n, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFF7203DF6B21C6052B53BBF40939D54123", 16) 416 x, _ := new(big.Int).SetString("32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16) 417 nm2 := new(big.Int).Sub(n, big.NewInt(2)) 418 nm2a := make([]uint64, 4) 419 fromBig(nm2a, nm2) 420 fmt.Printf("%0b, %0b, %b, %b\n", nm2a[0], nm2a[1], nm2a[2], nm2a[3]) 421 xInv1 := fermatInverse(x, n) 422 fmt.Printf("expect=%s\n", hex.EncodeToString(xInv1.Bytes())) 423 _ = P256Sm2() 424 xInv2 := p256.Inverse(x) 425 fmt.Printf("result=%s\n", hex.EncodeToString(xInv2.Bytes())) 426 427 if xInv1.Cmp(xInv2) != 0 { 428 t.FailNow() 429 } 430 }