//go:build go1.18 // +build go1.18 package sm9 // Fuzz Test use random data and run for a long time import ( "bytes" "crypto/rand" "testing" "xdx.jelly/xgcl/sm/sm3" "xdx.jelly/xgcl/sm/sm4" "xdx.jelly/xgcl/utils/padding" ) func FuzzSign(f *testing.F) { ks, pubs, err := GenerateMastSignPrivateKey(rand.Reader) if err != nil { f.Fatal(err) } f.Add([]byte{}, []byte{}, []byte{}) f.Fuzz(func(t *testing.T, uid, msg, seed []byte) { ds, err := GenerateUserSignKey(uid, ks) if err != nil { t.Fatal(err) } dig := sm3.Sum(seed) signature, err := Sign(msg, ds, pubs, dig[:]) if err != nil { t.Fatal(err) } if !Verify(signature, uid, msg, pubs) { t.Fatal("verify failed") } }) } func FuzzKeyExchange(f *testing.F) { ke, pube, err := GenerateMastEncPrivateKey(rand.Reader) if err != nil { f.Fatal(err) } f.Add([]byte{}, []byte{}, []byte{}, uint(1)) f.Fuzz(func(t *testing.T, idA, idB, seed []byte, kLen uint) { kLen += 1 deA, _ := GenerateUserEncKey(idA, ke) deB, _ := GenerateUserEncKey(idB, ke) alice := NewSponsor(idA, deA) bob := NewResponsor(idB, deB) rnd := sm3.Sum(seed) tempKeyOfSponsor, _ := alice.GenerateAgreementData(idB, pube, rnd[:]) rnd = sm3.Sum(seed) keyOfResponsor, tempKeyOfResponsor, _ := bob.GenerateAgreementDataAndKey(idA, pube, tempKeyOfSponsor, int(kLen), rnd[:]) keyOfSponsor, _ := alice.GenerateKey(tempKeyOfResponsor, int(kLen)) if !bytes.Equal(keyOfResponsor, keyOfSponsor) { t.Fatal() } alice.Clear() bob.Clear() }) } func FuzzEnc(f *testing.F) { ke, pube, err := GenerateMastEncPrivateKey(rand.Reader) if err != nil { f.Fatal(err) } f.Add([]byte{}, []byte{}, []byte{}) f.Fuzz(func(t *testing.T, id, msg, seed []byte) { de, err := GenerateUserEncKey(id, ke) if err != nil { t.Fatal(err) } // msg,id可能共享内存,因此不能直接在msg上padding。先复制一份 paddedMsg := append([]byte{}, msg...) paddedMsg = padding.P7.Pad(paddedMsg, sm4.BlockSize) for _, encType := range []EncType{EncTypeKDF} { c, err := Encrypt(encType, pube, id, msg, rand.Reader, nil) if err != nil { t.Fatal(err) } plain, err := Decrypt(id, c, de) if err != nil { t.Fatal(err) } if !bytes.Equal(plain, msg) { t.Fatal(err) } } for _, encType := range []EncType{EncTypeSM4ECB, EncTypeSM4CBC, EncTypeSM4CFB, EncTypeSM4OFB} { c, err := Encrypt(encType, pube, id, paddedMsg, rand.Reader, nil) if err != nil { t.Fatal(err) } plain, err := Decrypt(id, c, de) if !bytes.Equal(plain, paddedMsg) || err != nil { t.Fatal() } } }) }