//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") } } }) }