From da0d651197dee82dda267c84e85d1f2b89318804 Mon Sep 17 00:00:00 2001 From: Sun Yimin Date: Mon, 26 May 2025 15:10:48 +0800 Subject: [PATCH] sm2: provide SignMessage method to comply with the [crypto.MessageSigner] interface --- sm2/sm2_dsa.go | 11 +++++++++++ sm2/sm2_dsa_test.go | 33 +++++++++++++++++++++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/sm2/sm2_dsa.go b/sm2/sm2_dsa.go index 614b6f2..a400b06 100644 --- a/sm2/sm2_dsa.go +++ b/sm2/sm2_dsa.go @@ -118,6 +118,17 @@ func (priv *PrivateKey) SignWithSM2(rand io.Reader, uid, msg []byte) ([]byte, er return priv.Sign(rand, msg, NewSM2SignerOption(true, uid)) } +// SignMessage signs a message with the private key, reading randomness from rand. +// If opts is an instance of SM2SignerOption, it will use the UID from opts. +// This method is used to comply with the [crypto.MessageSigner] interface. +func (priv *PrivateKey) SignMessage(rand io.Reader, msg []byte, opts crypto.SignerOpts) ([]byte, error) { + var uid []byte + if sm2Opts, ok := opts.(*SM2SignerOption); ok { + uid = sm2Opts.uid + } + return priv.SignWithSM2(rand, uid, msg) +} + // GenerateKey generates a new SM2 private key. // // Most applications should use [crypto/rand.Reader] as rand. Note that the diff --git a/sm2/sm2_dsa_test.go b/sm2/sm2_dsa_test.go index 50a85f3..cdf2a5b 100644 --- a/sm2/sm2_dsa_test.go +++ b/sm2/sm2_dsa_test.go @@ -424,6 +424,39 @@ func TestSignVerify(t *testing.T) { } } +func TestSignMessage(t *testing.T) { + priv, _ := GenerateKey(rand.Reader) + tests := []struct { + name string + plainText string + }{ + // TODO: Add test cases. + {"less than 32", "encryption standard"}, + {"equals 32", "encryption standard encryption "}, + {"long than 32", "encryption standard encryption standard"}, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + signature, err := priv.SignMessage(rand.Reader, []byte(tt.plainText), nil) + if err != nil { + t.Fatalf("SignMessage failed %v", err) + } + result := VerifyASN1WithSM2(&priv.PublicKey, nil, []byte(tt.plainText), signature) + if !result { + t.Fatal("verify failed") + } + signature, err = priv.SignMessage(rand.Reader, []byte(tt.plainText), NewSM2SignerOption(true, []byte("testid"))) + if err != nil { + t.Fatalf("SignMessage failed %v", err) + } + result = VerifyASN1WithSM2(&priv.PublicKey, []byte("testid"), []byte(tt.plainText), signature) + if !result { + t.Fatal("verify failed") + } + }) + } +} + func TestSM2Hasher(t *testing.T) { tobeHashed := []byte("hello world") keypoints, _ := hex.DecodeString("048356e642a40ebd18d29ba3532fbd9f3bbee8f027c3f6f39a5ba2f870369f9988981f5efe55d1c5cdf6c0ef2b070847a14f7fdf4272a8df09c442f3058af94ba1")