gmsm/sm9/sm9_test.go

495 lines
11 KiB
Go
Raw Normal View History

2025-03-13 16:50:28 +08:00
package sm9_test
2022-07-15 16:42:39 +08:00
import (
"bytes"
2022-07-15 16:42:39 +08:00
"crypto/rand"
"encoding/hex"
"testing"
2025-03-13 16:50:28 +08:00
"github.com/emmansun/gmsm/sm9"
2022-07-15 16:42:39 +08:00
)
func TestSignASN1(t *testing.T) {
2025-03-13 16:50:28 +08:00
masterKey, err := sm9.GenerateSignMasterKey(rand.Reader)
2022-07-15 16:42:39 +08:00
hashed := []byte("Chinese IBS standard")
uid := []byte("emmansun")
hid := byte(0x01)
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
2022-11-28 10:55:23 +08:00
sig, err := userKey.Sign(rand.Reader, hashed, nil)
2022-07-15 16:42:39 +08:00
if err != nil {
t.Fatal(err)
}
2025-03-25 11:10:53 +08:00
if !masterKey.PublicKey().Verify(uid, hid, hashed, sig) {
2022-07-15 16:42:39 +08:00
t.Errorf("Verify failed")
}
2022-12-02 15:49:48 +08:00
sig[0] = 0xff
2025-03-25 11:10:53 +08:00
if masterKey.PublicKey().Verify(uid, hid, hashed, sig) {
2022-12-02 15:49:48 +08:00
t.Errorf("Verify with invalid asn1 format successed")
}
}
func TestWrapKey(t *testing.T) {
2025-03-13 16:50:28 +08:00
masterKey, err := sm9.GenerateEncryptMasterKey(rand.Reader)
2022-07-15 16:42:39 +08:00
hid := byte(0x01)
uid := []byte("emmansun")
2022-11-25 10:11:46 +08:00
if err != nil {
t.Fatal(err)
}
2022-07-15 16:42:39 +08:00
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
2025-03-25 11:10:53 +08:00
key, cipher, err := masterKey.PublicKey().WrapKey(rand.Reader, uid, hid, 16)
2022-11-25 10:11:46 +08:00
if err != nil {
t.Fatal(err)
}
2022-07-15 16:42:39 +08:00
key2, err := userKey.UnwrapKey(uid, cipher, 16)
2022-11-25 10:11:46 +08:00
if err != nil {
t.Fatal(err)
}
2022-07-15 16:42:39 +08:00
if !bytes.Equal(key, key2) {
t.Errorf("expected %x, got %x", key, key2)
2022-07-15 16:42:39 +08:00
}
}
func TestWrapKeyASN1(t *testing.T) {
2025-03-13 16:50:28 +08:00
masterKey, err := sm9.GenerateEncryptMasterKey(rand.Reader)
hid := byte(0x01)
uid := []byte("emmansun")
2022-08-03 16:31:02 +08:00
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
2022-08-03 16:31:02 +08:00
if err != nil {
t.Fatal(err)
}
2025-03-25 11:10:53 +08:00
keyPackage, err := masterKey.PublicKey().WrapKeyASN1(rand.Reader, uid, hid, 16)
2022-08-03 16:31:02 +08:00
if err != nil {
t.Fatal(err)
}
2025-03-13 16:50:28 +08:00
key1, cipher, err := sm9.UnmarshalSM9KeyPackage(keyPackage)
2022-08-03 16:31:02 +08:00
if err != nil {
t.Fatal(err)
}
2025-03-13 16:50:28 +08:00
key2, err := sm9.UnwrapKey(userKey, uid, cipher, 16)
2022-08-03 16:31:02 +08:00
if err != nil {
t.Fatal(err)
}
if !bytes.Equal(key1, key2) {
t.Errorf("expected %x, got %x", key1, key2)
2022-08-03 16:31:02 +08:00
}
}
func TestEncryptDecrypt(t *testing.T) {
plaintext := []byte("Chinese IBE standard")
2025-03-13 16:50:28 +08:00
masterKey, err := sm9.GenerateEncryptMasterKey(rand.Reader)
hid := byte(0x01)
uid := []byte("emmansun")
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
2025-03-13 16:50:28 +08:00
encTypes := []sm9.EncrypterOpts{
sm9.DefaultEncrypterOpts, sm9.SM4ECBEncrypterOpts, sm9.SM4CBCEncrypterOpts, sm9.SM4CFBEncrypterOpts, sm9.SM4OFBEncrypterOpts,
}
for _, opts := range encTypes {
2025-03-25 11:10:53 +08:00
cipher, err := sm9.Encrypt(rand.Reader, masterKey.PublicKey(), uid, hid, plaintext, opts)
if err != nil {
t.Fatal(err)
}
2025-03-13 16:50:28 +08:00
got, err := sm9.Decrypt(userKey, uid, cipher, opts)
if err != nil {
t.Fatal(err)
}
if string(got) != string(plaintext) {
t.Errorf("expected %v, got %v\n", string(plaintext), string(got))
}
opts1, err := sm9.NewDecrypterOptsWithUID(opts, uid)
if err != nil {
t.Fatal(err)
}
got, err = userKey.Decrypt(rand.Reader, cipher, opts1)
if err != nil {
t.Fatalf("encType %v, first byte %x, %v", opts.GetEncryptType(), cipher[0], err)
}
if string(got) != string(plaintext) {
t.Errorf("expected %v, got %v\n", string(plaintext), string(got))
}
opts1.EncrypterOpts = nil
_, err = userKey.Decrypt(rand.Reader, cipher, opts1)
if err == nil || err.Error() != "sm9: invalid ciphertext asn.1 data" {
t.Fatalf("sm9: invalid ciphertext asn.1 data")
}
}
}
func TestEncryptEmptyPlaintext(t *testing.T) {
2025-03-13 16:50:28 +08:00
masterKey, err := sm9.GenerateEncryptMasterKey(rand.Reader)
2022-07-15 16:42:39 +08:00
hid := byte(0x01)
uid := []byte("emmansun")
if err != nil {
t.Fatal(err)
}
2025-03-13 16:50:28 +08:00
encTypes := []sm9.EncrypterOpts{
sm9.DefaultEncrypterOpts, sm9.SM4ECBEncrypterOpts, sm9.SM4CBCEncrypterOpts, sm9.SM4CFBEncrypterOpts, sm9.SM4OFBEncrypterOpts,
2022-07-15 16:42:39 +08:00
}
for _, opts := range encTypes {
2025-03-25 11:10:53 +08:00
_, err := sm9.Encrypt(rand.Reader, masterKey.PublicKey(), uid, hid, nil, opts)
2025-03-13 16:50:28 +08:00
if err != sm9.ErrEmptyPlaintext {
t.Fatalf("should be ErrEmptyPlaintext")
}
2022-07-15 16:42:39 +08:00
}
}
func TestEncryptDecryptASN1(t *testing.T) {
plaintext := []byte("Chinese IBE standard")
2025-03-13 16:50:28 +08:00
masterKey, err := sm9.GenerateEncryptMasterKey(rand.Reader)
2022-07-15 16:42:39 +08:00
hid := byte(0x01)
uid := []byte("emmansun")
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
2025-03-13 16:50:28 +08:00
encTypes := []sm9.EncrypterOpts{
sm9.DefaultEncrypterOpts, sm9.SM4ECBEncrypterOpts, sm9.SM4CBCEncrypterOpts, sm9.SM4CFBEncrypterOpts, sm9.SM4OFBEncrypterOpts,
2022-07-15 16:42:39 +08:00
}
for _, opts := range encTypes {
2025-03-25 11:10:53 +08:00
cipher, err := sm9.EncryptASN1(rand.Reader, masterKey.PublicKey(), uid, hid, plaintext, opts)
if err != nil {
t.Fatal(err)
}
2022-07-15 16:42:39 +08:00
2025-03-13 16:50:28 +08:00
got, err := sm9.DecryptASN1(userKey, uid, cipher)
if err != nil {
t.Fatal(err)
}
2022-07-15 16:42:39 +08:00
if string(got) != string(plaintext) {
t.Errorf("expected %v, got %v\n", string(plaintext), string(got))
}
2023-02-03 15:13:02 +08:00
got, err = userKey.DecryptASN1(uid, cipher)
if err != nil {
t.Fatal(err)
}
if string(got) != string(plaintext) {
t.Errorf("expected %v, got %v\n", string(plaintext), string(got))
}
got, err = userKey.Decrypt(rand.Reader, cipher, uid)
if err != nil {
t.Fatal(err)
}
if string(got) != string(plaintext) {
t.Errorf("expected %v, got %v\n", string(plaintext), string(got))
}
opts, err := sm9.NewDecrypterOptsWithUID(nil, uid)
if err != nil {
t.Fatal(err)
}
got, err = userKey.Decrypt(rand.Reader, cipher, opts)
if err != nil {
t.Fatal(err)
}
if string(got) != string(plaintext) {
t.Errorf("expected %v, got %v\n", string(plaintext), string(got))
}
2022-07-15 16:42:39 +08:00
}
}
func TestUnmarshalSM9KeyPackage(t *testing.T) {
2025-03-13 16:50:28 +08:00
masterKey, err := sm9.GenerateEncryptMasterKey(rand.Reader)
2022-07-15 16:42:39 +08:00
hid := byte(0x01)
uid := []byte("emmansun")
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
t.Fatal(err)
}
2025-03-25 11:10:53 +08:00
p, err := masterKey.PublicKey().WrapKeyASN1(rand.Reader, uid, hid, 16)
2022-07-15 16:42:39 +08:00
if err != nil {
t.Fatal(err)
}
2025-03-13 16:50:28 +08:00
key, cipher, err := sm9.UnmarshalSM9KeyPackage(p)
2022-07-15 16:42:39 +08:00
if err != nil {
t.Fatal(err)
}
2025-03-13 16:50:28 +08:00
key2, err := sm9.UnwrapKey(userKey, uid, cipher, 16)
2022-07-15 16:42:39 +08:00
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key) != hex.EncodeToString(key2) {
t.Errorf("expected %v, got %v\n", hex.EncodeToString(key), hex.EncodeToString(key2))
}
}
func TestKeyExchange(t *testing.T) {
hid := byte(0x02)
userA := []byte("Alice")
userB := []byte("Bob")
2025-03-13 16:50:28 +08:00
masterKey, err := sm9.GenerateEncryptMasterKey(rand.Reader)
2022-11-25 10:11:46 +08:00
if err != nil {
t.Fatal(err)
}
2022-07-15 16:42:39 +08:00
userKey, err := masterKey.GenerateUserKey(userA, hid)
2022-07-15 16:42:39 +08:00
if err != nil {
t.Fatal(err)
}
initiator := userKey.NewKeyExchange(userA, userB, 16, true)
2022-07-15 16:42:39 +08:00
userKey, err = masterKey.GenerateUserKey(userB, hid)
2022-11-25 10:11:46 +08:00
if err != nil {
t.Fatal(err)
}
responder := userKey.NewKeyExchange(userB, userA, 16, true)
defer func() {
initiator.Destroy()
responder.Destroy()
}()
// A1-A4
rA, err := initiator.InitKeyExchange(rand.Reader, hid)
2022-07-15 16:42:39 +08:00
if err != nil {
t.Fatal(err)
}
// B1 - B7
rB, sigB, err := responder.RespondKeyExchange(rand.Reader, hid, rA)
2022-11-25 10:11:46 +08:00
if err != nil {
t.Fatal(err)
}
2022-07-15 16:42:39 +08:00
// A5 -A8
key1, sigA, err := initiator.ConfirmResponder(rB, sigB)
2022-07-15 16:42:39 +08:00
if err != nil {
t.Fatal(err)
}
// B8
key2, err := responder.ConfirmInitiator(sigA)
2022-11-25 10:11:46 +08:00
if err != nil {
t.Fatal(err)
}
2022-07-15 16:42:39 +08:00
if hex.EncodeToString(key1) != hex.EncodeToString(key2) {
t.Errorf("got different key")
2022-07-15 16:42:39 +08:00
}
}
func TestKeyExchangeWithoutSignature(t *testing.T) {
hid := byte(0x02)
userA := []byte("Alice")
userB := []byte("Bob")
2025-03-13 16:50:28 +08:00
masterKey, err := sm9.GenerateEncryptMasterKey(rand.Reader)
2023-02-13 14:36:34 +08:00
if err != nil {
t.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(userA, hid)
2023-02-13 14:36:34 +08:00
if err != nil {
t.Fatal(err)
}
initiator := userKey.NewKeyExchange(userA, userB, 16, false)
2023-02-13 14:36:34 +08:00
userKey, err = masterKey.GenerateUserKey(userB, hid)
2023-02-13 14:36:34 +08:00
if err != nil {
t.Fatal(err)
}
responder := userKey.NewKeyExchange(userB, userA, 16, false)
defer func() {
initiator.Destroy()
responder.Destroy()
}()
// A1-A4
rA, err := initiator.InitKeyExchange(rand.Reader, hid)
2023-02-13 14:36:34 +08:00
if err != nil {
t.Fatal(err)
}
// B1 - B7
rB, sigB, err := responder.RespondKeyExchange(rand.Reader, hid, rA)
2022-07-15 16:42:39 +08:00
if err != nil {
t.Fatal(err)
}
if len(sigB) != 0 {
t.Errorf("should no signature")
2022-07-15 16:42:39 +08:00
}
// A5 -A8
key1, sigA, err := initiator.ConfirmResponder(rB, sigB)
if err != nil {
t.Fatal(err)
}
if len(sigA) != 0 {
t.Errorf("should no signature")
}
key2, err := responder.ConfirmInitiator(nil)
2022-07-15 16:42:39 +08:00
if err != nil {
t.Fatal(err)
}
if hex.EncodeToString(key1) != hex.EncodeToString(key2) {
t.Errorf("got different key")
2022-07-15 16:42:39 +08:00
}
}
func BenchmarkSign(b *testing.B) {
hashed := []byte("Chinese IBS standard")
uid := []byte("emmansun")
hid := byte(0x01)
2025-03-13 16:50:28 +08:00
masterKey, err := sm9.GenerateSignMasterKey(rand.Reader)
2022-07-15 16:42:39 +08:00
if err != nil {
b.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
b.Fatal(err)
}
2025-03-13 16:50:28 +08:00
sm9.SignASN1(rand.Reader, userKey, hashed) // fire precompute
2022-07-15 16:42:39 +08:00
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
2025-03-13 16:50:28 +08:00
sig, err := sm9.SignASN1(rand.Reader, userKey, hashed)
2022-07-15 16:42:39 +08:00
if err != nil {
b.Fatal(err)
}
// Prevent the compiler from optimizing out the operation.
hashed[0] = sig[0]
}
}
func BenchmarkVerify(b *testing.B) {
hashed := []byte("Chinese IBS standard")
uid := []byte("emmansun")
hid := byte(0x01)
2025-03-13 16:50:28 +08:00
masterKey, err := sm9.GenerateSignMasterKey(rand.Reader)
2022-07-15 16:42:39 +08:00
if err != nil {
b.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
b.Fatal(err)
}
2025-03-13 16:50:28 +08:00
sig, err := sm9.SignASN1(rand.Reader, userKey, hashed)
2022-07-15 16:42:39 +08:00
if err != nil {
b.Fatal(err)
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
2025-03-25 11:10:53 +08:00
if !sm9.VerifyASN1(masterKey.PublicKey(), uid, hid, hashed, sig) {
2022-07-15 16:42:39 +08:00
b.Fatal("verify failed")
}
}
}
func BenchmarkEncrypt(b *testing.B) {
plaintext := []byte("Chinese IBE standard")
2025-03-13 16:50:28 +08:00
masterKey, err := sm9.GenerateEncryptMasterKey(rand.Reader)
2022-07-15 16:42:39 +08:00
hid := byte(0x01)
uid := []byte("emmansun")
if err != nil {
b.Fatal(err)
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
2025-03-25 11:10:53 +08:00
cipher, err := sm9.Encrypt(rand.Reader, masterKey.PublicKey(), uid, hid, plaintext, nil)
2022-07-15 16:42:39 +08:00
if err != nil {
b.Fatal(err)
}
// Prevent the compiler from optimizing out the operation.
plaintext[0] = cipher[0]
}
}
func BenchmarkDecrypt(b *testing.B) {
plaintext := []byte("Chinese IBE standard")
2025-03-13 16:50:28 +08:00
masterKey, err := sm9.GenerateEncryptMasterKey(rand.Reader)
2022-07-15 16:42:39 +08:00
hid := byte(0x01)
uid := []byte("emmansun")
if err != nil {
b.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
b.Fatal(err)
}
2025-03-25 11:10:53 +08:00
cipher, err := sm9.Encrypt(rand.Reader, masterKey.PublicKey(), uid, hid, plaintext, nil)
2022-07-15 16:42:39 +08:00
if err != nil {
b.Fatal(err)
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
2025-03-13 16:50:28 +08:00
got, err := sm9.Decrypt(userKey, uid, cipher, nil)
2022-07-15 16:42:39 +08:00
if err != nil {
b.Fatal(err)
}
if string(got) != string(plaintext) {
b.Errorf("expected %v, got %v\n", string(plaintext), string(got))
}
}
}
func BenchmarkDecryptASN1(b *testing.B) {
plaintext := []byte("Chinese IBE standard")
2025-03-13 16:50:28 +08:00
masterKey, err := sm9.GenerateEncryptMasterKey(rand.Reader)
2022-07-15 16:42:39 +08:00
hid := byte(0x01)
uid := []byte("emmansun")
if err != nil {
b.Fatal(err)
}
userKey, err := masterKey.GenerateUserKey(uid, hid)
if err != nil {
b.Fatal(err)
}
2025-03-25 11:10:53 +08:00
cipher, err := sm9.EncryptASN1(rand.Reader, masterKey.PublicKey(), uid, hid, plaintext, nil)
2022-07-15 16:42:39 +08:00
if err != nil {
b.Fatal(err)
}
b.ReportAllocs()
b.ResetTimer()
for i := 0; i < b.N; i++ {
2025-03-13 16:50:28 +08:00
got, err := sm9.DecryptASN1(userKey, uid, cipher)
2022-07-15 16:42:39 +08:00
if err != nil {
b.Fatal(err)
}
if string(got) != string(plaintext) {
b.Errorf("expected %v, got %v\n", string(plaintext), string(got))
}
}
}