439 lines
12 KiB
Go
439 lines
12 KiB
Go
package sm2
|
|
|
|
import (
|
|
"bytes"
|
|
"crypto/elliptic"
|
|
"crypto/rand"
|
|
"encoding/hex"
|
|
"fmt"
|
|
"io"
|
|
"log"
|
|
"math/big"
|
|
"testing"
|
|
|
|
"github.com/stretchr/testify/assert"
|
|
"xdx.jelly/xgcl/grand"
|
|
"xdx.jelly/xgcl/internal"
|
|
)
|
|
|
|
func hexDecode(s string) []byte {
|
|
b, err := hex.DecodeString(s)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
return b
|
|
}
|
|
|
|
func TestAudit(t *testing.T) {
|
|
if !(Auditor{}).Correctness() {
|
|
t.Fatal("Correctness check failed")
|
|
}
|
|
}
|
|
|
|
// TestCurve test speed of sm2 curve on ScalarMult and ScalarBaseMult.
|
|
// A litter slower than P256 curve.
|
|
func TestCurve(t *testing.T) {
|
|
gx, gy := Curve().Params().Gx, Curve().Params().Gy
|
|
k := make([]byte, 32)
|
|
grand.GenerateRandom(k)
|
|
|
|
count, duation := internal.SingleThreadTester(func() {
|
|
sm2Curve.ScalarMult(gx, gy, k)
|
|
})
|
|
fmt.Printf("SM2Curve ScalarMult: %d times/Sec\n", int(internal.Rate(count, duation)))
|
|
|
|
count, duation = internal.SingleThreadTester(func() {
|
|
sm2Curve.ScalarBaseMult(k)
|
|
})
|
|
fmt.Printf("SM2Curve ScalarBaseMult: %d times/Sec\n", int(internal.Rate(count, duation)))
|
|
}
|
|
|
|
// TestP256Curve test speed of P256 curve on ScalarMult and ScalarBaseMult.
|
|
func TestP256Curve(t *testing.T) {
|
|
c := elliptic.P256()
|
|
gx, gy := c.Params().Gx, c.Params().Gy
|
|
k := make([]byte, 32)
|
|
grand.GenerateRandom(k)
|
|
|
|
count, duation := internal.SingleThreadTester(func() {
|
|
c.ScalarMult(gx, gy, k)
|
|
})
|
|
fmt.Printf("P256 ScalarMult: %d times/Sec\n", int(internal.Rate(count, duation)))
|
|
|
|
count, duation = internal.SingleThreadTester(func() {
|
|
c.ScalarBaseMult(k)
|
|
})
|
|
fmt.Printf("P256 ScalarBaseMult: %d times/Sec\n", int(internal.Rate(count, duation)))
|
|
}
|
|
|
|
// func TestKeyGen(t *testing.T) {
|
|
// sk, _ := GenPrivateKey(grand.GetRandom(32))
|
|
// pk := GenPublicKey(sk)
|
|
|
|
// sm4Key := make([]byte, 16)
|
|
// buf := make([]byte, 0)
|
|
// fp, err := os.OpenFile("/Users/fengwd/Codes/go/src/xdx.jelly/xgcl/sm/sm2/key", os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666)
|
|
// if err != nil {
|
|
// panic("openfile failed")
|
|
// }
|
|
// for i := 0; i < 1000; i++ {
|
|
// buf = buf[:0]
|
|
// if i%1000 == 0 {
|
|
// fmt.Printf("%d\n", i)
|
|
// }
|
|
// usk, _ := GenPrivateKey(grand.GetRandom(32))
|
|
// upk := GenPublicKey(sk)
|
|
// grand.GenerateRandom(sm4Key)
|
|
// tmp, _ := usk.MarshalBinary()
|
|
// buf = append(buf, tmp...)
|
|
// tmp, _ = upk.MarshalBinary()
|
|
// buf = append(buf, tmp...)
|
|
// buf = padding.P7.Pad(buf, 16)
|
|
// buf, _ = sm4.EncryptECB(buf, sm4Key, buf)
|
|
// cipher, _ := Encrypt(pk, sm4Key, nil)
|
|
// tmp, _ = cipher.MarshalBinary()
|
|
// buf = append(buf, tmp...)
|
|
// fp.Write(buf)
|
|
|
|
// }
|
|
|
|
// fp.Close()
|
|
// }
|
|
|
|
func TestKeyValid(t *testing.T) {
|
|
{
|
|
k, _ := hex.DecodeString("000001000000000000000000000000000000000000000000000000000000000000000000972b80815e2c29e837fd006dc05534373950b221a090ad8dbeaa6e787bbbc85b00000000000000000000000000000000000000000000000000000000000000009ec521bc8fe61d2cfbc3bb8d4748ee6eb56e33d5955dba236f21085264095fa8")
|
|
// pk := NewPublicKey()
|
|
pk := &PublicKey{}
|
|
pk.UnmarshalBinary(k)
|
|
b, _ := pk.MarshalBinary()
|
|
assert.Equal(t, k, b)
|
|
}
|
|
{
|
|
k := NewPrivateKey().Random(grand.Reader)
|
|
pk := (&PublicKey{}).Generate(k)
|
|
b, _ := pk.MarshalBinary()
|
|
pk1 := &PublicKey{}
|
|
pk1.UnmarshalBinary(b)
|
|
assert.True(t, pk1.Equal(pk))
|
|
assert.True(t, pk.IsValid())
|
|
assert.True(t, pk1.IsValid())
|
|
}
|
|
}
|
|
func TestPreComputeWithIdAndPubkey(t *testing.T) {
|
|
var r [32]byte
|
|
r[31] = 1
|
|
sk, _ := GenPrivateKey(r[:])
|
|
pk := GenPublicKey(sk)
|
|
e := PreComputeWithIdAndPubkey(nil, pk)
|
|
assert.Equal(t, e, hexDecode("5b32bfe35482899b195d72c09d33ccdb465b2ded883240ff91f120a68bc91de8"))
|
|
}
|
|
|
|
func TestSignStd(t *testing.T) {
|
|
m := []byte("message digest")
|
|
buf, _ := hex.DecodeString("3945208F7B2144B13F36E38AC6D39F95889393692860B51A42FB81EF4DF7C5B8")
|
|
d, _ := GenPrivateKey(buf)
|
|
pk := GenPublicKey(d)
|
|
e := PreComputeWithIdAndPubkeyAndMessage(nil, m, pk)
|
|
k, err := hex.DecodeString("59276E27D506861A16680F3AD9C02DCCEF3CC1FA3CDBE4CE6D54B80DEAC1BC21")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
fmt.Printf("%x\n", e)
|
|
fmt.Println(pk.X.Text(16))
|
|
fmt.Println(pk.Y.Text(16))
|
|
|
|
sig, err := Sign(e, k, d)
|
|
if err != nil {
|
|
t.Log()
|
|
t.Fail()
|
|
}
|
|
|
|
data, err := sig.MarshalBinary()
|
|
if err != nil {
|
|
t.Log()
|
|
t.Fail()
|
|
}
|
|
if hex.EncodeToString(data) != "0000000000000000000000000000000000000000000000000000000000000000f5a03b0648d2c4630eeac513e1bb81a15944da3827d5b74143ac7eaceee720b30000000000000000000000000000000000000000000000000000000000000000b1b6aa29df212fd8763182bc0d421ca1bb9038fd1f7f42d4840b69c485bbc1aa" {
|
|
t.Log()
|
|
t.Fail()
|
|
}
|
|
assert.True(t, Verify(e, pk, sig))
|
|
}
|
|
|
|
func TestSign(t *testing.T) {
|
|
e := hexDecode("3854C463FA3F73783621B1CE4EF83F7C78048AAC79B221FCDD290866CC131174")
|
|
k := hexDecode("F026AD9A7EB94401A800C8D8C3277E69972C7F3778ACE4D537012023EDFB69FF")
|
|
d, err := GenPrivateKey(hexDecode("C242939DDAB6FCC07B6676C07D2DC117EC68A09142C25C008630B9756786162D"))
|
|
assert.Nil(t, err)
|
|
|
|
sig, err := Sign(e, k, d)
|
|
assert.Nil(t, err)
|
|
|
|
data, err := sig.MarshalBinary()
|
|
assert.Nil(t, err)
|
|
assert.Equal(t, data, hexDecode("00000000000000000000000000000000000000000000000000000000000000006e5db49dbd0992b97040080a96003c721cdb9cf64c88d74321fc2f630adf377400000000000000000000000000000000000000000000000000000000000000002f6dff453dfc8d7a506d3f52301bee529e62fddd38948f0d5d2cbcbc55900cfa"))
|
|
|
|
sig1 := NewSignature()
|
|
assert.Nil(t, sig1.UnmarshalBinary(data))
|
|
assert.Equal(t, sig1.R.Cmp(sig.R), 0)
|
|
assert.Equal(t, sig1.S.Cmp(sig.S), 0)
|
|
|
|
pk := GenPublicKey(d)
|
|
fmt.Println(pk)
|
|
data, err = pk.MarshalBinary()
|
|
assert.Nil(t, err)
|
|
|
|
pk1 := NewPublicKey()
|
|
assert.Nil(t, pk1.UnmarshalBinary(data))
|
|
assert.Equal(t, fmt.Sprintf("%#v", pk), fmt.Sprintf("%#v", pk1))
|
|
|
|
assert.True(t, Verify(e, pk, sig))
|
|
}
|
|
|
|
// (r,s)是e,pk的签名,则(r, -(s + 2rd/(1+d))也是e,pk的签名
|
|
func TestSignDual(t *testing.T) {
|
|
e := hexDecode("3854C463FA3F73783621B1CE4EF83F7C78048AAC79B221FCDD290866CC131174")
|
|
k := hexDecode("F026AD9A7EB94401A800C8D8C3277E69972C7F3778ACE4D537012023EDFB69FF")
|
|
sk, _ := GenPrivateKey(hexDecode("C242939DDAB6FCC07B6676C07D2DC117EC68A09142C25C008630B9756786162D"))
|
|
pk := GenPublicKey(sk)
|
|
|
|
var sig *Signature
|
|
sig, err := Sign(e, k, sk)
|
|
assert.Nil(t, err)
|
|
|
|
assert.True(t, Verify(e, pk, sig))
|
|
|
|
// s' = -(s + 2rd(1+d)^-1)
|
|
tmp := big.NewInt(1)
|
|
tmp.Add(tmp, sk.D)
|
|
tmp.ModInverse(tmp, OrderN())
|
|
tmp.Mul(tmp, sk.D)
|
|
tmp.Mul(tmp, sig.R)
|
|
tmp.Lsh(tmp, 1)
|
|
tmp.Add(tmp, sig.S)
|
|
tmp.Mod(tmp, OrderN())
|
|
tmp.Sub(OrderN(), tmp)
|
|
sig.S.Set(tmp)
|
|
|
|
assert.True(t, Verify(e, pk, sig))
|
|
}
|
|
|
|
// 已知公钥P, 则可任意取r,s,并构造e = r-X(sG+(r+s)P)
|
|
// verify(r,s,P,e) = true
|
|
func TestSignForge(t *testing.T) {
|
|
|
|
d, err := hex.DecodeString("C242939DDAB6FCC07B6676C07D2DC117EC68A09142C25C008630B9756786162D")
|
|
if err != nil {
|
|
log.Fatal(err)
|
|
}
|
|
sk, _ := GenPrivateKey(d)
|
|
pk := GenPublicKey(sk)
|
|
|
|
r, _ := rand.Int(grand.Reader, OrderN())
|
|
s, _ := rand.Int(grand.Reader, OrderN())
|
|
|
|
u := big.NewInt(0)
|
|
u.Add(r, s)
|
|
u.Mod(u, OrderN())
|
|
x1, y1 := Curve().ScalarMult(pk.X, pk.Y, u.Bytes())
|
|
x2, y2 := Curve().ScalarBaseMult(s.Bytes())
|
|
x1, _ = Curve().Add(x1, y1, x2, y2)
|
|
e := new(big.Int)
|
|
e = e.Sub(r, x1)
|
|
e.Mod(e, OrderN())
|
|
|
|
sig := new(Signature)
|
|
sig.S = s
|
|
sig.R = r
|
|
|
|
assert.True(t, Verify(e.Bytes(), pk, sig))
|
|
|
|
}
|
|
|
|
func TestEncrypt(t *testing.T) {
|
|
sk, _ := GenPrivateKey([]byte{
|
|
0x81, 0x98, 0x7C, 0xC9, 0x0C, 0xF5, 0x05, 0x7C,
|
|
0x2D, 0xCA, 0xA7, 0x5D, 0x1F, 0xDD, 0xCA, 0x84,
|
|
0xB2, 0x48, 0x62, 0xF0, 0xCA, 0xD7, 0x3C, 0x7F,
|
|
0x67, 0x34, 0x9A, 0xE6, 0x99, 0xB9, 0x29, 0x83},
|
|
)
|
|
|
|
rnd := []byte{
|
|
0x26, 0xD6, 0x16, 0x3F, 0xA1, 0x86, 0x03, 0xEE,
|
|
0x2F, 0x3D, 0xE8, 0x93, 0x65, 0x44, 0xD5, 0xDF,
|
|
0x12, 0x55, 0xA2, 0xDB, 0xEB, 0xA6, 0x3A, 0xFC,
|
|
0x0D, 0x83, 0x3E, 0xC4, 0x49, 0xD2, 0xCB, 0x45,
|
|
}
|
|
|
|
msg := []byte{
|
|
0xC3, 0x53, 0xC6, 0x8E, 0xF0, 0x5C, 0x4B, 0x34,
|
|
0x2B, 0x37, 0x7D, 0xA0, 0x55, 0xD9, 0x09, 0xFB,
|
|
0x1F, 0xAA, 0x42, 0x55, 0x66, 0x2F, 0x3B, 0xAB,
|
|
0x8D, 0xDB, 0x35, 0x35, 0xE4, 0x0B, 0xC9, 0x3B,
|
|
}
|
|
|
|
wantCipher := "bf6cfcb8e6295dc22777376f8385c5d6aadd5e430d11e004246d6bebf99ec5249cb9ab2f9af688c77a1bdf9f3b0816a4eab7f5da22e5dacdc1c8f6e45499874e1fc32e35744161aa0ffa6c70fc811d3b66d4cacda3c0996b54768c603c6b24e0c85cdde8ad71a258b89ddb42da900bcf4f18ab52d7841134cac581d3cf7f58f7"
|
|
pk := GenPublicKey(sk)
|
|
|
|
// pk.X.Add(pk.X, gmath.BigInt1)
|
|
// fmt.Println(hex.EncodeToString(pk.x[:]) + hex.EncodeToString(pk.y[:]))
|
|
cipher, err := Encrypt(pk, msg, rnd)
|
|
if err != nil {
|
|
t.Log(err)
|
|
t.Fail()
|
|
return
|
|
}
|
|
|
|
if hex.EncodeToString(cipher.Bytes()) != wantCipher {
|
|
t.Log("Encrypt Failed")
|
|
t.Log("cipher :", hex.EncodeToString(cipher.Bytes()))
|
|
t.Log("WantCipher:", wantCipher)
|
|
t.Fail()
|
|
return
|
|
}
|
|
|
|
// marshal test
|
|
// t.Log(cipher)
|
|
data, _ := cipher.MarshalBinary()
|
|
// t.Log(hex.EncodeToString(data))
|
|
cipher1 := NewCipher()
|
|
if err := cipher1.UnmarshalBinary(data); err != nil {
|
|
t.Log("unmarshal failed")
|
|
}
|
|
if fmt.Sprintf("%#v", cipher) != fmt.Sprintf("%#v", cipher1) {
|
|
t.Log("Marshal Test failed")
|
|
t.Fail()
|
|
}
|
|
|
|
//Decrypt
|
|
decryptedMsg, err := Decrypt(sk, cipher)
|
|
if err != nil || bytes.Compare(decryptedMsg, msg) != 0 {
|
|
t.Log(err)
|
|
t.Log("decryptedMsg :", hex.EncodeToString(decryptedMsg))
|
|
t.Log("msg :", hex.EncodeToString(msg))
|
|
t.Fail()
|
|
}
|
|
|
|
}
|
|
|
|
// func TestErrors(t *testing.T) {
|
|
// errors.PrintErrorInfos(os.Stdout)
|
|
// }
|
|
|
|
func TestZeroHashSign(t *testing.T) {
|
|
zeroHash := make([]byte, 32)
|
|
|
|
for _, curve := range []elliptic.Curve{Curve()} {
|
|
privKey, err := GenerateKey(curve, rand.Reader)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Sign a hash consisting of all zeros.
|
|
// r, s, err := Sign(rand.Reader, privKey, zeroHash)
|
|
k := make([]byte, 32)
|
|
grand.GenerateRandom(k)
|
|
sig, err := Sign(zeroHash, k, privKey)
|
|
if err != nil {
|
|
panic(err)
|
|
}
|
|
|
|
// Confirm that it can be verified.
|
|
if !Verify(zeroHash, privKey.Public().(*PublicKey), sig) {
|
|
t.Errorf("zero hash signature verify failed for %T", curve)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestEncEmpty(t *testing.T) {
|
|
sk, _ := GenPrivateKey([]byte{
|
|
0x81, 0x98, 0x7C, 0xC9, 0x0C, 0xF5, 0x05, 0x7C,
|
|
0x2D, 0xCA, 0xA7, 0x5D, 0x1F, 0xDD, 0xCA, 0x84,
|
|
0xB2, 0x48, 0x62, 0xF0, 0xCA, 0xD7, 0x3C, 0x7F,
|
|
0x67, 0x34, 0x9A, 0xE6, 0x99, 0xB9, 0x29, 0x83},
|
|
)
|
|
|
|
rnd := []byte{
|
|
0x26, 0xD6, 0x16, 0x3F, 0xA1, 0x86, 0x03, 0xEE,
|
|
0x2F, 0x3D, 0xE8, 0x93, 0x65, 0x44, 0xD5, 0xDF,
|
|
0x12, 0x55, 0xA2, 0xDB, 0xEB, 0xA6, 0x3A, 0xFC,
|
|
0x0D, 0x83, 0x3E, 0xC4, 0x49, 0xD2, 0xCB, 0x45,
|
|
}
|
|
|
|
msg := []byte{}
|
|
|
|
pk := &sk.PublicKey
|
|
cipher, err := Encrypt(pk, msg, rnd)
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
decryptedMsg, err := Decrypt(sk, cipher)
|
|
if err != nil || bytes.Compare(decryptedMsg, msg) != 0 {
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestEncLong(t *testing.T) {
|
|
sk, err := GenerateKey(Curve(), grand.Reader)
|
|
pk := &sk.PublicKey
|
|
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
data := make([]byte, 409600)
|
|
if _, err := io.ReadFull(grand.Reader, data); err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
|
|
cipher, err := Encrypt(pk, data, grand.GetRandom(32))
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
decryptedData, err := Decrypt(sk, cipher)
|
|
if err != nil || bytes.Compare(decryptedData, data) != 0 {
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
}
|
|
}
|
|
|
|
func TestSM2Point(t *testing.T) {
|
|
x, _ := new(big.Int).SetString("54cb2e421e7119ddbba44ff0db131e9907ed90a1b0b9a23b9d3eb890519d5cae", 16)
|
|
y, _ := new(big.Int).SetString("389646ab568a3bd7a566e1e49b98a4d41041b2fa2cf0af74fceef65ef1e986c6", 16)
|
|
|
|
pk := &PublicKey{
|
|
Curve: Curve(),
|
|
X: x,
|
|
Y: y,
|
|
}
|
|
assert.True(t, pk.IsValid())
|
|
}
|
|
|
|
// func TestSM2Verify(t *testing.T) {
|
|
// r, _ := new(big.Int).SetString("d3233fe6b680f1fc26bb4932b894af1e9e73c700554c39f407ac91c4d4d74347", 16)
|
|
// s, _ := new(big.Int).SetString("08bc7476b0fd496287d162dfab5a68a340515b3f8647ed03f75c4d1b50aeb957", 16)
|
|
// x, _ := new(big.Int).SetString("6a3f992330c0857eda4b914ebef614bf401266fb6168e3f90475ed1fcd3c2625", 16)
|
|
// y, _ := new(big.Int).SetString("36341b6383d996205996aa164480bad952aa07a0db942858d103bf8f2f4b460a", 16)
|
|
// pk := &PublicKey{
|
|
// Curve: Curve(),
|
|
// X: x,
|
|
// Y: y,
|
|
// }
|
|
// sig := &Signature{
|
|
// R: r,
|
|
// S: s,
|
|
// }
|
|
// assert.True(t, pk.IsValid())
|
|
// e, _ := hex.DecodeString("c3e283e5ad232e04b29d2422a88fb251cd08cad4f0e8b77cdcdd7859eb6fabd7")
|
|
// // e = PreComputeWithIdAndPubkeyAndMessage(GetDefaultID(), e, pk)
|
|
|
|
// assert.True(t, Verify(e, pk, sig))
|
|
// e, _ = hex.DecodeString("8d3eef66a23e3118a7b32a386cd1db41bc4e7a803098ee92c6b5cda43829ad96")
|
|
// // e = PreComputeWithIdAndPubkeyAndMessage(GetDefaultID(), e, pk)
|
|
// assert.True(t, Verify(e, pk, sig))
|
|
// }
|