github.com/emmansun/gmsm@v0.29.1/internal/sm2ec/sm2p256_asm_test.go (about) 1 //go:build (amd64 || arm64 || s390x || ppc64le) && !purego 2 3 package sm2ec 4 5 import ( 6 "bytes" 7 "crypto/rand" 8 "encoding/hex" 9 "io" 10 "math/big" 11 "testing" 12 "time" 13 ) 14 15 // fromBig converts a *big.Int into a format used by this code. 16 func fromBig(out *p256Element, big *big.Int) { 17 for i := range out { 18 out[i] = 0 19 } 20 21 for i, v := range big.Bits() { 22 out[i] = uint64(v) 23 } 24 } 25 26 func toBigInt(in *p256Element) *big.Int { 27 var valBytes [32]byte 28 p256LittleToBig(&valBytes, in) 29 return new(big.Int).SetBytes(valBytes[:]) 30 } 31 32 func p256MulTest(t *testing.T, x, y, p, r *big.Int) { 33 x1 := new(big.Int).Mul(x, r) 34 x1 = x1.Mod(x1, p) 35 y1 := new(big.Int).Mul(y, r) 36 y1 = y1.Mod(y1, p) 37 ax := new(p256Element) 38 ay := new(p256Element) 39 res := new(p256Element) 40 res2 := new(p256Element) 41 fromBig(ax, x1) 42 fromBig(ay, y1) 43 p256Mul(res2, ax, ay) 44 p256FromMont(res, res2) 45 resInt := toBigInt(res) 46 47 expected := new(big.Int).Mul(x, y) 48 expected = expected.Mod(expected, p) 49 if resInt.Cmp(expected) != 0 { 50 t.FailNow() 51 } 52 } 53 54 func TestP256MulPMinus1(t *testing.T) { 55 p, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) 56 r, _ := new(big.Int).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) 57 pMinus1 := new(big.Int).Sub(p, big.NewInt(1)) 58 p256MulTest(t, pMinus1, pMinus1, p, r) 59 } 60 61 func TestFuzzyP256Mul(t *testing.T) { 62 p, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) 63 r, _ := new(big.Int).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) 64 var scalar1 [32]byte 65 var scalar2 [32]byte 66 var timeout *time.Timer 67 68 if testing.Short() { 69 timeout = time.NewTimer(10 * time.Millisecond) 70 } else { 71 timeout = time.NewTimer(2 * time.Second) 72 } 73 for { 74 select { 75 case <-timeout.C: 76 return 77 default: 78 } 79 io.ReadFull(rand.Reader, scalar1[:]) 80 io.ReadFull(rand.Reader, scalar2[:]) 81 x := new(big.Int).SetBytes(scalar1[:]) 82 y := new(big.Int).SetBytes(scalar2[:]) 83 p256MulTest(t, x, y, p, r) 84 } 85 } 86 87 func BenchmarkP256Mul(b *testing.B) { 88 p, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) 89 r, _ := new(big.Int).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) 90 var scalar1 [32]byte 91 io.ReadFull(rand.Reader, scalar1[:]) 92 x := new(big.Int).SetBytes(scalar1[:]) 93 x1 := new(big.Int).Mul(x, r) 94 x1 = x1.Mod(x1, p) 95 ax := new(p256Element) 96 res := new(p256Element) 97 fromBig(ax, x1) 98 b.ResetTimer() 99 for i := 0; i < b.N; i++ { 100 p256Mul(res, ax, ax) 101 } 102 } 103 104 func p256SqrTest(t *testing.T, x, p, r *big.Int) { 105 x1 := new(big.Int).Mul(x, r) 106 x1 = x1.Mod(x1, p) 107 ax := new(p256Element) 108 res := new(p256Element) 109 res2 := new(p256Element) 110 fromBig(ax, x1) 111 p256Sqr(res2, ax, 1) 112 p256FromMont(res, res2) 113 resInt := toBigInt(res) 114 115 expected := new(big.Int).Mul(x, x) 116 expected = expected.Mod(expected, p) 117 if resInt.Cmp(expected) != 0 { 118 t.FailNow() 119 } 120 } 121 122 func TestP256SqrPMinus1(t *testing.T) { 123 p, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) 124 r, _ := new(big.Int).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) 125 pMinus1 := new(big.Int).Sub(p, big.NewInt(1)) 126 p256SqrTest(t, pMinus1, p, r) 127 } 128 129 func TestFuzzyP256Sqr(t *testing.T) { 130 p, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) 131 r, _ := new(big.Int).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) 132 var scalar1 [32]byte 133 var timeout *time.Timer 134 135 if testing.Short() { 136 timeout = time.NewTimer(10 * time.Millisecond) 137 } else { 138 timeout = time.NewTimer(2 * time.Second) 139 } 140 for { 141 select { 142 case <-timeout.C: 143 return 144 default: 145 } 146 io.ReadFull(rand.Reader, scalar1[:]) 147 x := new(big.Int).SetBytes(scalar1[:]) 148 p256SqrTest(t, x, p, r) 149 } 150 } 151 152 func BenchmarkP256Sqr(b *testing.B) { 153 p, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) 154 r, _ := new(big.Int).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) 155 var scalar1 [32]byte 156 io.ReadFull(rand.Reader, scalar1[:]) 157 x := new(big.Int).SetBytes(scalar1[:]) 158 x1 := new(big.Int).Mul(x, r) 159 x1 = x1.Mod(x1, p) 160 ax := new(p256Element) 161 res := new(p256Element) 162 fromBig(ax, x1) 163 b.ResetTimer() 164 for i := 0; i < b.N; i++ { 165 p256Sqr(res, ax, 20) 166 } 167 } 168 169 func Test_p256Inverse(t *testing.T) { 170 r, _ := new(big.Int).SetString("10000000000000000000000000000000000000000000000000000000000000000", 16) 171 p, _ := new(big.Int).SetString("FFFFFFFEFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFF00000000FFFFFFFFFFFFFFFF", 16) 172 x, _ := new(big.Int).SetString("32C4AE2C1F1981195F9904466A39C9948FE30BBFF2660BE1715A4589334C74C7", 16) 173 gx := &p256Element{0x61328990f418029e, 0x3e7981eddca6c050, 0xd6a1ed99ac24c3c3, 0x91167a5ee1c13b05} 174 res := new(p256Element) 175 p256Inverse(res, gx) 176 resInt := toBigInt(res) 177 xInv := new(big.Int).ModInverse(x, p) 178 xInv = new(big.Int).Mul(xInv, r) 179 xInv = new(big.Int).Mod(xInv, p) 180 if resInt.Cmp(xInv) != 0 { 181 t.Errorf("expected %v, got %v", hex.EncodeToString(xInv.Bytes()), hex.EncodeToString(resInt.Bytes())) 182 } 183 } 184 185 func BenchmarkP256SelectAffine(b *testing.B) { 186 var t0 p256AffinePoint 187 for i := 0; i < b.N; i++ { 188 p256SelectAffine(&t0, &p256Precomputed[20], 20) 189 } 190 } 191 192 func TestPointDouble(t *testing.T) { 193 var double1, double2 SM2P256Point 194 p := NewSM2P256Point().SetGenerator() 195 p256PointDoubleAsm(&double1, p) 196 p256PointDoubleAsm(&double1, &double1) 197 p256PointDoubleAsm(&double1, &double1) 198 p256PointDoubleAsm(&double1, &double1) 199 p256PointDoubleAsm(&double1, &double1) 200 p256PointDoubleAsm(&double1, &double1) 201 202 p256PointDouble6TimesAsm(&double2, p) 203 if !bytes.Equal(double1.Bytes(), double2.Bytes()) { 204 t.Error("PointDouble6Times is incorrect") 205 } 206 207 if hex.EncodeToString(double1.Bytes()) != "0497662389f36ce643a47dcf644f700651e988794843797b0c4a69c806e78615c2cd4d9449aea5cac5328b8d67d4ae956f5eb06c4515ff01bd17eef58bf866b33f" { 208 t.Errorf("PointDouble6Times is incorrect %x", double1.Bytes()) 209 } 210 } 211 212 func TestPointAdd(t *testing.T) { 213 p := NewSM2P256Point().SetGenerator() 214 var p1, p2, sum1, sum2 SM2P256Point 215 p256PointDoubleAsm(&p1, p) 216 p256PointAddAsm(&sum1, p, &p1) 217 218 p256PointDouble6TimesAsm(&p2, p) 219 p256PointAddAsm(&sum2, p, &p2) 220 221 if hex.EncodeToString(sum1.Bytes()) != "04a97f7cd4b3c993b4be2daa8cdb41e24ca13f6bd945302244e26918f1d0509ebf530b5dd88c688ef5ccc5cec08a72150f7c400ee5cd045292aaacdd037458f6e6" { 222 t.Errorf("G + [2]G is incorrect %x", sum1.Bytes()) 223 } 224 if hex.EncodeToString(sum2.Bytes()) != "04403b18162679c05515a8ecd063d726ba7b1eb83b8306ace5cd382e53ed23ae1feb42ebf496a7bd698d61a1c805ef7074df882dfcffcc84bcd0a5d4ebea56f425" { 225 t.Errorf("G + [64]G is incorrect %x", sum2.Bytes()) 226 } 227 }