Files
xgcl/sm/sm2/sm2_fuzz_test.go
2026-05-27 23:03:00 +08:00

242 lines
4.7 KiB
Go

//go:build go1.18
// +build go1.18
package sm2
import (
"bytes"
"crypto/rand"
"fmt"
"sync"
"testing"
"time"
"xdx.jelly/xgcl/grand"
"xdx.jelly/xgcl/sm/sm3"
)
var m sync.Mutex
var waittingIcons = string("|/-\\")
var i = 0
var begin time.Time
var last time.Time
func waitting() {
m.Lock()
defer m.Unlock()
if time.Since(last).Milliseconds() > 200 {
elaspe := time.Since(begin)
hours := int64(elaspe.Hours())
elaspe -= time.Duration(hours) * time.Hour
minutes := int64(elaspe.Minutes())
elaspe -= time.Duration(minutes) * time.Minute
seconds := int64(elaspe.Seconds())
fmt.Printf("\rTest is running for %02dh %02dm %02ds ", hours, minutes, seconds)
fmt.Print(string(waittingIcons[i]))
last = time.Now()
i++
if i >= len(waittingIcons) {
i = 0
}
}
}
func TestFuzz(t *testing.T) {
wg := new(sync.WaitGroup)
count := 1000
begin = time.Now()
last = begin
// test key generation
wg.Add(1)
go func(k int) {
for i := 0; i < k; i++ {
k := NewPrivateKey().Random(grand.Reader)
pk := (&PublicKey{}).Generate(k)
b, _ := pk.MarshalBinary()
pk1 := &PublicKey{}
pk1.UnmarshalBinary(b)
if !pk1.Equals(pk) || !pk.IsValid() || !pk1.IsValid() {
t.Log()
t.Fail()
break
}
if i%100 == 0 {
waitting()
}
}
wg.Done()
}(count)
wg.Add(1)
go func(k int) {
for i := 0; i < k; i++ {
e := grand.GetRandom(ByteSize())
k := grand.GetRandom(ByteSize())
d := (&PrivateKey{}).Random(grand.Reader)
pk := (&PublicKey{}).Generate(d)
sig, err := Sign(e, k, d)
if err != nil {
t.Log()
t.Fail()
break
}
data, err := sig.MarshalBinary()
if err != nil {
t.Log()
t.Fail()
}
sig1 := NewSignature()
if err := sig1.UnmarshalBinary(data); err != nil {
t.Log()
t.Fail()
}
ret := Verify(e, pk, sig1)
if !ret {
t.Log()
t.Fail()
break
}
if i%100 == 0 {
waitting()
}
}
wg.Done()
}(count)
wg.Add(1)
go func(k int) {
for i := 0; i < k; i++ {
k := grand.GetRandom(ByteSize())
d := (&PrivateKey{}).Random(grand.Reader)
pk := (&PublicKey{}).Generate(d)
msg := grand.GetRandom(i&0xff + 1)
cipher, err := Encrypt(pk, msg, k)
if err != nil {
t.Logf("pk=%v,msg=%v", pk, msg)
t.Log(err)
t.Fail()
break
}
data, _ := cipher.MarshalBinary()
cipher1 := NewCipher()
if err := cipher1.UnmarshalBinary(data); err != nil {
t.Log("unmarshal failed")
t.Fail()
break
}
//Decrypt
decryptedMsg, err := Decrypt(d, cipher)
if err != nil || bytes.Compare(decryptedMsg, msg) != 0 {
t.Log(err)
t.Fail()
break
}
if i%100 == 0 {
waitting()
}
}
wg.Done()
}(count)
// TODO generic32 and 64 panic
// wg.Add(1)
// go func(k int) {
// for i := 0; i < k; i++ {
// sponsorID := []byte("Sponsor")
// responsorID := []byte("Responsor")
// ska := (&PrivateKey{}).Random(grand.Reader)
// skb := (&PrivateKey{}).Random(grand.Reader)
// // 使用默认id传入nil或GetDefaultID
// s := NewSponsor(sponsorID, ska)
// rs := NewResponsor(responsorID, skb)
// keylen := i%128 + 1
// tempKeyOfSponsor, err := s.GenerateAgreementData(nil)
// if err != nil {
// t.Log()
// t.Fail()
// }
// keyOfResponsor, tempKeyOfResponsor, err := rs.GenerateAgreementDataAndKey(sponsorID, GenPublicKey(ska), tempKeyOfSponsor, keylen, nil)
// if err != nil {
// t.Log()
// t.Fail()
// }
// keyOfSponsor, err := s.GenerateKey(responsorID, GenPublicKey(skb), tempKeyOfResponsor, keylen)
// if err != nil {
// t.Log()
// t.Fail()
// }
// if bytes.Compare(keyOfResponsor, keyOfSponsor) != 0 {
// t.Log()
// t.Fail()
// break
// }
// ska.Clear()
// skb.Clear()
// s.Clear()
// rs.Clear()
// if i%100 == 0 {
// waitting()
// }
// }
// wg.Done()
// }(count)
// wait for all routine finish
wg.Wait()
}
func FuzzSign(f *testing.F) {
f.Add([]byte{}, []byte{})
f.Fuzz(func(t *testing.T, k, msg []byte) {
d := sm3.Sum(k)
sk := &PrivateKey{}
sk.SetBytes(d[:])
e := PreComputeWithIdAndPubkeyAndMessage(GetDefaultID(), msg, &sk.PublicKey)
r, s, err := SignWithReader(rand.Reader, sk, e)
if err != nil {
t.Errorf("%v", err)
}
if !VerifyWithRS(&sk.PublicKey, e, r, s) {
t.Error("verify failed")
}
})
}
func FuzzEnc(f *testing.F) {
f.Add([]byte{}, []byte{}, []byte{})
f.Fuzz(func(t *testing.T, r1, r2, msg []byte) {
buf := sm3.Sum(r1)
d := &PrivateKey{}
d.SetBytes(buf[:])
pk := &d.PublicKey
buf = sm3.Sum(r2)
k := buf[:]
cipher, err := Encrypt(pk, msg, k)
if err != nil {
t.Error("Encrypt failed")
}
//Decrypt
decryptedMsg, err := Decrypt(d, cipher)
if err != nil || bytes.Compare(decryptedMsg, msg) != 0 {
if err != nil {
t.Error("Dencrypt failed")
}
}
})
}