From 05aeed5c3464c58c68c3fef0e0a1dd92f42c9e42 Mon Sep 17 00:00:00 2001 From: Sun Yimin Date: Tue, 9 Aug 2022 10:01:34 +0800 Subject: [PATCH] sm9: marshal compressed --- sm2/sm2.go | 1 + sm9/sm9_key.go | 32 +++++++++++++++++ sm9/sm9_key_test.go | 88 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 121 insertions(+) diff --git a/sm2/sm2.go b/sm2/sm2.go index 3ecf77e..bedc13e 100644 --- a/sm2/sm2.go +++ b/sm2/sm2.go @@ -51,6 +51,7 @@ type combinedMult interface { } // PrivateKey represents an ECDSA SM2 private key. +// It implemented both crypto.Decrypter and crypto.Signer interfaces. type PrivateKey struct { ecdsa.PrivateKey } diff --git a/sm9/sm9_key.go b/sm9/sm9_key.go index 19c3c96..6691545 100644 --- a/sm9/sm9_key.go +++ b/sm9/sm9_key.go @@ -153,6 +153,14 @@ func (pub *SignMasterPublicKey) MarshalASN1() ([]byte, error) { return b.Bytes() } +// MarshalCompressedASN1 marshal sign master public key to asn.1 format data according +// SM9 cryptographic algorithm application specification, the curve point is in compressed form. +func (pub *SignMasterPublicKey) MarshalCompressedASN1() ([]byte, error) { + var b cryptobyte.Builder + b.AddASN1BitString(pub.MasterPublicKey.MarshalCompressed()) + return b.Bytes() +} + func unmarshalG2(bytes []byte) (*bn256.G2, error) { g2 := new(bn256.G2) switch bytes[0] { @@ -207,6 +215,14 @@ func (priv *SignPrivateKey) MarshalASN1() ([]byte, error) { return b.Bytes() } +// MarshalCompressedASN1 marshal sign user private key to asn.1 format data according +// SM9 cryptographic algorithm application specification, the curve point is in compressed form. +func (priv *SignPrivateKey) MarshalCompressedASN1() ([]byte, error) { + var b cryptobyte.Builder + b.AddASN1BitString(priv.PrivateKey.MarshalCompressed()) + return b.Bytes() +} + func unmarshalG1(bytes []byte) (*bn256.G1, error) { g := new(bn256.G1) switch bytes[0] { @@ -343,6 +359,14 @@ func (pub *EncryptMasterPublicKey) MarshalASN1() ([]byte, error) { return b.Bytes() } +// MarshalCompressedASN1 marshal encrypt master public key to asn.1 format data according +// SM9 cryptographic algorithm application specification, the curve point is in compressed form. +func (pub *EncryptMasterPublicKey) MarshalCompressedASN1() ([]byte, error) { + var b cryptobyte.Builder + b.AddASN1BitString(pub.MasterPublicKey.MarshalCompressed()) + return b.Bytes() +} + // UnmarshalASN1 unmarsal der data to encrypt master public key func (pub *EncryptMasterPublicKey) UnmarshalASN1(der []byte) error { var bytes []byte @@ -378,6 +402,14 @@ func (priv *EncryptPrivateKey) MarshalASN1() ([]byte, error) { return b.Bytes() } +// MarshalCompressedASN1 marshal encrypt user private key to asn.1 format data according +// SM9 cryptographic algorithm application specification, the curve point is in compressed form. +func (priv *EncryptPrivateKey) MarshalCompressedASN1() ([]byte, error) { + var b cryptobyte.Builder + b.AddASN1BitString(priv.PrivateKey.MarshalCompressed()) + return b.Bytes() +} + // UnmarshalASN1 unmarsal der data to encrypt user private key // Note, priv's EncryptMasterPublicKey should be handled separately. func (priv *EncryptPrivateKey) UnmarshalASN1(der []byte) error { diff --git a/sm9/sm9_key_test.go b/sm9/sm9_key_test.go index 2b54d1e..929c4c9 100644 --- a/sm9/sm9_key_test.go +++ b/sm9/sm9_key_test.go @@ -44,6 +44,25 @@ func TestSignMasterPublicKeyMarshalASN1(t *testing.T) { } } +func TestSignMasterPublicKeyMarshalCompressedASN1(t *testing.T) { + masterKey, err := GenerateSignMasterKey(rand.Reader) + if err != nil { + t.Fatal(err) + } + der, err := masterKey.Public().MarshalCompressedASN1() + if err != nil { + t.Fatal(err) + } + pub2 := new(SignMasterPublicKey) + err = pub2.UnmarshalASN1(der) + if err != nil { + t.Fatal(err) + } + if !masterKey.MasterPublicKey.Equal(pub2.MasterPublicKey) { + t.Errorf("not same") + } +} + func TestSignUserPrivateKeyMarshalASN1(t *testing.T) { masterKey, err := GenerateSignMasterKey(rand.Reader) uid := []byte("emmansun") @@ -69,6 +88,31 @@ func TestSignUserPrivateKeyMarshalASN1(t *testing.T) { } } +func TestSignUserPrivateKeyMarshalCompressedASN1(t *testing.T) { + masterKey, err := GenerateSignMasterKey(rand.Reader) + uid := []byte("emmansun") + hid := byte(0x01) + if err != nil { + t.Fatal(err) + } + userKey, err := masterKey.GenerateUserKey(uid, hid) + if err != nil { + t.Fatal(err) + } + der, err := userKey.MarshalCompressedASN1() + if err != nil { + t.Fatal(err) + } + userKey2 := new(SignPrivateKey) + err = userKey2.UnmarshalASN1(der) + if err != nil { + t.Fatal(err) + } + if !userKey.PrivateKey.Equal(userKey2.PrivateKey) { + t.Errorf("not same") + } +} + func TestEncryptMasterPrivateKeyMarshalASN1(t *testing.T) { masterKey, err := GenerateEncryptMasterKey(rand.Reader) if err != nil { @@ -107,6 +151,25 @@ func TestEncryptMasterPublicKeyMarshalASN1(t *testing.T) { } } +func TestEncryptMasterPublicKeyMarshalCompressedASN1(t *testing.T) { + masterKey, err := GenerateEncryptMasterKey(rand.Reader) + if err != nil { + t.Fatal(err) + } + der, err := masterKey.Public().MarshalCompressedASN1() + if err != nil { + t.Fatal(err) + } + pub2 := new(EncryptMasterPublicKey) + err = pub2.UnmarshalASN1(der) + if err != nil { + t.Fatal(err) + } + if !masterKey.MasterPublicKey.Equal(pub2.MasterPublicKey) { + t.Errorf("not same") + } +} + func TestEncryptUserPrivateKeyMarshalASN1(t *testing.T) { masterKey, err := GenerateEncryptMasterKey(rand.Reader) uid := []byte("emmansun") @@ -132,6 +195,31 @@ func TestEncryptUserPrivateKeyMarshalASN1(t *testing.T) { } } +func TestEncryptUserPrivateKeyMarshalCompressedASN1(t *testing.T) { + masterKey, err := GenerateEncryptMasterKey(rand.Reader) + uid := []byte("emmansun") + hid := byte(0x01) + if err != nil { + t.Fatal(err) + } + userKey, err := masterKey.GenerateUserKey(uid, hid) + if err != nil { + t.Fatal(err) + } + der, err := userKey.MarshalCompressedASN1() + if err != nil { + t.Fatal(err) + } + userKey2 := new(EncryptPrivateKey) + err = userKey2.UnmarshalASN1(der) + if err != nil { + t.Fatal(err) + } + if !userKey.PrivateKey.Equal(userKey2.PrivateKey) { + t.Errorf("not same") + } +} + func BenchmarkGenerateSignPrivKey(b *testing.B) { masterKey, err := GenerateSignMasterKey(rand.Reader) uid := []byte("emmansun")