Documentation ¶
Overview ¶
Package sm2 implements ShangMi(SM) sm2 digital signature, public key encryption and key exchange algorithms.
Example (ParseCipherASN1EndsWithInvalidBytes) ¶
This method provide a sample to handle ASN1 ciphertext ends with extra bytes.
package main import ( "encoding/hex" "errors" "log" "math/big" "golang.org/x/crypto/cryptobyte" "golang.org/x/crypto/cryptobyte/asn1" ) func main() { // a sample method to get frist ASN1 SEQUENCE data getFirstASN1Sequence := func(ciphertext []byte) ([]byte, []byte, error) { input := cryptobyte.String(ciphertext) var inner cryptobyte.String if !input.ReadASN1(&inner, asn1.SEQUENCE) { return nil, nil, errors.New("there are no sequence tag") } if len(input) == 0 { return ciphertext, nil, nil } return ciphertext[:len(ciphertext)-len(input)], input, nil } ciphertext, _ := hex.DecodeString("3081980220298ED52AE2A0EBA8B7567D54DF41C5F9B310EDFA4A8E15ECCB44EDA94F9F1FC20220116BE33B0833C95D8E5FF9483CD2D7EFF7033C92FE5DEAB6197D809FF1EEE05F042097A90979A6FCEBDE883C2E07E9C286818E694EDE37C3CDAA70E4CD481BE883E00430D62160BB179CB20CE3B5ECA0F5A535BEB6E221566C78FEA92105F71BD37F3F850AD2F86F2D1E35F15E9356557DAC026A") _, rest, err := getFirstASN1Sequence(ciphertext) if err != nil || len(rest) != 0 { log.Fatalf("can't get a complete ASN1 sequence") } ciphertext, _ = hex.DecodeString("3081980220298ED52AE2A0EBA8B7567D54DF41C5F9B310EDFA4A8E15ECCB44EDA94F9F1FC20220116BE33B0833C95D8E5FF9483CD2D7EFF7033C92FE5DEAB6197D809FF1EEE05F042097A90979A6FCEBDE883C2E07E9C286818E694EDE37C3CDAA70E4CD481BE883E00430D62160BB179CB20CE3B5ECA0F5A535BEB6E221566C78FEA92105F71BD37F3F850AD2F86F2D1E35F15E9356557DAC026A0000") seq, rest, err := getFirstASN1Sequence(ciphertext) if err != nil || len(rest) != 2 { log.Fatalf("can't get a complete ASN1 sequence") } var ( x1, y1 = &big.Int{}, &big.Int{} c2, c3 []byte inner cryptobyte.String ) input := cryptobyte.String(seq) if !input.ReadASN1(&inner, asn1.SEQUENCE) || !input.Empty() || !inner.ReadASN1Integer(x1) || !inner.ReadASN1Integer(y1) || !inner.ReadASN1Bytes(&c3, asn1.OCTET_STRING) || !inner.ReadASN1Bytes(&c2, asn1.OCTET_STRING) || !inner.Empty() { log.Fatalf("invalid cipher text") } }
Output:
Index ¶
- Constants
- Variables
- func ASN1Ciphertext2Plain(ciphertext []byte, opts *EncrypterOpts) ([]byte, error)
- func AdjustCiphertextSplicingOrder(ciphertext []byte, from, to ciphertextSplicingOrder) ([]byte, error)
- func CalculateSM2Hash(pub *ecdsa.PublicKey, data, uid []byte) ([]byte, error)
- func CalculateZA(pub *ecdsa.PublicKey, uid []byte) ([]byte, error)
- func Decrypt(priv *PrivateKey, ciphertext []byte) ([]byte, error)
- func Encrypt(random io.Reader, pub *ecdsa.PublicKey, msg []byte, opts *EncrypterOpts) ([]byte, error)
- func EncryptASN1(random io.Reader, pub *ecdsa.PublicKey, msg []byte) ([]byte, error)
- func IsSM2PublicKey(publicKey any) bool
- func MarshalEnvelopedPrivateKey(rand io.Reader, pub *ecdsa.PublicKey, tobeEnveloped *PrivateKey) ([]byte, error)
- func NewPublicKey(key []byte) (*ecdsa.PublicKey, error)
- func P256() elliptic.Curve
- func PlainCiphertext2ASN1(ciphertext []byte, from ciphertextSplicingOrder) ([]byte, error)
- func PublicKeyToECDH(k *ecdsa.PublicKey) (*ecdh.PublicKey, error)
- func RecoverPublicKeysFromSM2Signature(hash, sig []byte) ([]*ecdsa.PublicKey, error)
- func Sign(rand io.Reader, priv *ecdsa.PrivateKey, hash []byte) (r, s *big.Int, err error)
- func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte, opts crypto.SignerOpts) ([]byte, error)
- func SignWithSM2(rand io.Reader, priv *ecdsa.PrivateKey, uid, msg []byte) (r, s *big.Int, err error)
- func Verify(pub *ecdsa.PublicKey, hash []byte, r, s *big.Int) bool
- func VerifyASN1(pub *ecdsa.PublicKey, hash, sig []byte) bool
- func VerifyASN1WithSM2(pub *ecdsa.PublicKey, uid, msg, sig []byte) bool
- func VerifyWithSM2(pub *ecdsa.PublicKey, uid, msg []byte, r, s *big.Int) bool
- type DecrypterOpts
- type EncrypterOpts
- type KeyExchange
- func (ke *KeyExchange) ConfirmInitiator(s1 []byte) ([]byte, error)
- func (ke *KeyExchange) ConfirmResponder(rB *ecdsa.PublicKey, sB []byte) ([]byte, []byte, error)
- func (ke *KeyExchange) Destroy()
- func (ke *KeyExchange) InitKeyExchange(rand io.Reader) (*ecdsa.PublicKey, error)
- func (ke *KeyExchange) RepondKeyExchange(rand io.Reader, rA *ecdsa.PublicKey) (*ecdsa.PublicKey, []byte, error)
- func (ke *KeyExchange) SetPeerParameters(peerPub *ecdsa.PublicKey, peerUID []byte) error
- type PrivateKey
- func (priv *PrivateKey) Decrypt(rand io.Reader, msg []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error)
- func (k *PrivateKey) ECDH() (*ecdh.PrivateKey, error)
- func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool
- func (priv *PrivateKey) FromECPrivateKey(key *ecdsa.PrivateKey) (*PrivateKey, error)
- func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error)
- func (priv *PrivateKey) SignWithSM2(rand io.Reader, uid, msg []byte) ([]byte, error)
- type SM2SignerOption
- type Signer
Examples ¶
Constants ¶
const ( //MarshalUncompressed uncompressed mashal mode MarshalUncompressed pointMarshalMode = iota //MarshalCompressed compressed mashal mode MarshalCompressed //MarshalHybrid hybrid mashal mode MarshalHybrid )
const ( C1C3C2 ciphertextSplicingOrder = iota C1C2C3 )
const ( ENCODING_PLAIN ciphertextEncoding = iota ENCODING_ASN1 )
Variables ¶
var ASN1DecrypterOpts = &DecrypterOpts{ENCODING_ASN1, C1C3C2}
var ASN1EncrypterOpts = &EncrypterOpts{ENCODING_ASN1, MarshalUncompressed, C1C3C2}
var DefaultSM2SignerOpts = NewSM2SignerOption(true, nil)
DefaultSM2SignerOpts uses default UID and forceGMSign is true.
var ErrDecryption = errors.New("sm2: decryption error")
ErrDecryption represents a failure to decrypt a message. It is deliberately vague to avoid adaptive attacks.
var ErrInvalidSignature = errors.New("sm2: invalid signature")
Functions ¶
func ASN1Ciphertext2Plain ¶ added in v0.7.0
func ASN1Ciphertext2Plain(ciphertext []byte, opts *EncrypterOpts) ([]byte, error)
ASN1Ciphertext2Plain utility method to convert ASN.1 encoding ciphertext to plain encoding format
func AdjustCiphertextSplicingOrder ¶ added in v0.7.0
func AdjustCiphertextSplicingOrder(ciphertext []byte, from, to ciphertextSplicingOrder) ([]byte, error)
AdjustCiphertextSplicingOrder utility method to change c2 c3 order
func CalculateSM2Hash ¶ added in v0.24.0
CalculateSM2Hash calculates hash value for data including uid and public key parameters according standards.
uid can be nil, then it will use default uid (1234567812345678)
func CalculateZA ¶ added in v0.1.2
CalculateZA ZA = H256(ENTLA || IDA || a || b || xG || yG || xA || yA). Compliance with GB/T 32918.2-2016 5.5.
This function will not use default UID even the uid argument is empty.
func Decrypt ¶
func Decrypt(priv *PrivateKey, ciphertext []byte) ([]byte, error)
Decrypt sm2 decrypt implementation by default DecrypterOpts{C1C3C2}. Compliance with GB/T 32918.4-2016.
func Encrypt ¶
func Encrypt(random io.Reader, pub *ecdsa.PublicKey, msg []byte, opts *EncrypterOpts) ([]byte, error)
Encrypt sm2 encrypt implementation, compliance with GB/T 32918.4-2016.
The random parameter is used as a source of entropy to ensure that encrypting the same message twice doesn't result in the same ciphertext. Most applications should use crypto/rand.Reader as random.
func EncryptASN1 ¶ added in v0.7.0
EncryptASN1 sm2 encrypt and output ASN.1 result, compliance with GB/T 32918.4-2016.
The random parameter is used as a source of entropy to ensure that encrypting the same message twice doesn't result in the same ciphertext. Most applications should use crypto/rand.Reader as random.
Example ¶
package main import ( "crypto/rand" "encoding/hex" "fmt" "log" "os" "github.com/emmansun/gmsm/sm2" ) func main() { // real public key should be from cert or public key pem file keypoints, _ := hex.DecodeString("048356e642a40ebd18d29ba3532fbd9f3bbee8f027c3f6f39a5ba2f870369f9988981f5efe55d1c5cdf6c0ef2b070847a14f7fdf4272a8df09c442f3058af94ba1") testkey, err := sm2.NewPublicKey(keypoints) if err != nil { log.Fatalf("fail to new public key %v", err) } secretMessage := []byte("send reinforcements, we're going to advance") // crypto/rand.Reader is a good source of entropy for randomizing the // encryption function. rng := rand.Reader ciphertext, err := sm2.EncryptASN1(rng, testkey, secretMessage) if err != nil { fmt.Fprintf(os.Stderr, "Error from encryption: %s\n", err) return } // Since encryption is a randomized function, ciphertext will be // different each time. fmt.Printf("Ciphertext: %x\n", ciphertext) }
Output:
func IsSM2PublicKey ¶ added in v0.4.8
IsSM2PublicKey check if given public key is a SM2 public key or not
func MarshalEnvelopedPrivateKey ¶ added in v0.16.0
func MarshalEnvelopedPrivateKey(rand io.Reader, pub *ecdsa.PublicKey, tobeEnveloped *PrivateKey) ([]byte, error)
MarshalEnvelopedPrivateKey, returns sm2 key pair protected data with ASN.1 format:
SM2EnvelopedKey ::= SEQUENCE { symAlgID AlgorithmIdentifier, symEncryptedKey SM2Cipher, sm2PublicKey SM2PublicKey, sm2EncryptedPrivateKey BIT STRING, }
This implementation follows GB/T 35276-2017, uses SM4 cipher to encrypt sm2 private key. Please note the standard did NOT clarify if the ECB mode requires padding or not.
func NewPublicKey ¶ added in v0.24.1
NewPublicKey checks that key is valid and returns a PublicKey.
Example ¶
package main import ( "crypto/elliptic" "encoding/hex" "fmt" "log" "github.com/emmansun/gmsm/sm2" ) func main() { keypoints, _ := hex.DecodeString("048356e642a40ebd18d29ba3532fbd9f3bbee8f027c3f6f39a5ba2f870369f9988981f5efe55d1c5cdf6c0ef2b070847a14f7fdf4272a8df09c442f3058af94ba1") pub, err := sm2.NewPublicKey(keypoints) if err != nil { log.Fatalf("fail to new public key %v", err) } fmt.Printf("%x\n", elliptic.Marshal(sm2.P256(), pub.X, pub.Y)) }
Output: 048356e642a40ebd18d29ba3532fbd9f3bbee8f027c3f6f39a5ba2f870369f9988981f5efe55d1c5cdf6c0ef2b070847a14f7fdf4272a8df09c442f3058af94ba1
func PlainCiphertext2ASN1 ¶ added in v0.7.0
PlainCiphertext2ASN1 utility method to convert plain encoding ciphertext to ASN.1 encoding format
func PublicKeyToECDH ¶ added in v0.15.4
PublicKeyToECDH returns k as a ecdh.PublicKey. It returns an error if the key is invalid according to the definition of ecdh.Curve.NewPublicKey, or if the Curve is not supported by ecdh.
func RecoverPublicKeysFromSM2Signature ¶ added in v0.27.1
RecoverPublicKeysFromSM2Signature recovers two or four SM2 public keys from a given signature and hash. It takes the hash and signature as input and returns the recovered public keys as []*ecdsa.PublicKey. If the signature or hash is invalid, it returns an error. The function follows the SM2 algorithm to recover the public keys.
func Sign ¶ added in v0.1.2
Sign signs a hash (which should be the result of hashing a larger message) using the private key, priv. If the hash is longer than the bit-length of the private key's curve order, the hash will be truncated to that length. It returns the signature as a pair of integers. Most applications should use SignASN1 instead of dealing directly with r, s.
Compliance with GB/T 32918.2-2016 regardless it's SM2 curve or not.
func SignASN1 ¶ added in v0.4.8
func SignASN1(rand io.Reader, priv *PrivateKey, hash []byte, opts crypto.SignerOpts) ([]byte, error)
SignASN1 signs a hash (which should be the result of hashing a larger message) using the private key, priv. If the hash is longer than the bit-length of the private key's curve order, the hash will be truncated to that length. It returns the ASN.1 encoded signature.
The signature is randomized. Most applications should use crypto/rand.Reader as rand. Note that the returned signature does not depend deterministically on the bytes read from rand, and may change between calls and/or between versions.
If the opts argument is instance of *SM2SignerOption, and its ForceGMSign is true, then the hash will be treated as raw message.
func SignWithSM2 ¶ added in v0.1.2
func SignWithSM2(rand io.Reader, priv *ecdsa.PrivateKey, uid, msg []byte) (r, s *big.Int, err error)
SignWithSM2 follow sm2 dsa standards for hash part, compliance with GB/T 32918.2-2016.
func Verify ¶ added in v0.1.2
Verify verifies the signature in r, s of hash using the public key, pub. Its return value records whether the signature is valid. Most applications should use VerifyASN1 instead of dealing directly with r, s.
Compliance with GB/T 32918.2-2016 regardless it's SM2 curve or not. Caller should make sure the hash's correctness.
func VerifyASN1 ¶ added in v0.4.8
VerifyASN1 verifies the ASN.1 encoded signature, sig, of hash using the public key, pub. Its return value records whether the signature is valid.
Compliance with GB/T 32918.2-2016 regardless it's SM2 curve or not. Caller should make sure the hash's correctness, in other words, the caller must pre-calculate the hash value.
func VerifyASN1WithSM2 ¶ added in v0.4.8
VerifyASN1WithSM2 verifies the signature in ASN.1 encoding format sig of raw msg and uid using the public key, pub. The uid can be empty, meaning to use the default value.
It returns value records whether the signature is valid. Compliance with GB/T 32918.2-2016.
Example ¶
package main import ( "encoding/hex" "fmt" "log" "github.com/emmansun/gmsm/sm2" ) func main() { // real public key should be from cert or public key pem file keypoints, _ := hex.DecodeString("048356e642a40ebd18d29ba3532fbd9f3bbee8f027c3f6f39a5ba2f870369f9988981f5efe55d1c5cdf6c0ef2b070847a14f7fdf4272a8df09c442f3058af94ba1") testkey, err := sm2.NewPublicKey(keypoints) if err != nil { log.Fatalf("fail to new public key %v", err) } toSign := []byte("ShangMi SM2 Sign Standard") signature, _ := hex.DecodeString("304402205b3a799bd94c9063120d7286769220af6b0fa127009af3e873c0e8742edc5f890220097968a4c8b040fd548d1456b33f470cabd8456bfea53e8a828f92f6d4bdcd77") ok := sm2.VerifyASN1WithSM2(testkey, nil, toSign, signature) fmt.Printf("%v\n", ok) }
Output: true
Types ¶
type DecrypterOpts ¶ added in v0.6.0
type DecrypterOpts struct {
// contains filtered or unexported fields
}
DecrypterOpts decryption options
func NewPlainDecrypterOpts ¶ added in v0.7.0
func NewPlainDecrypterOpts(splicingOrder ciphertextSplicingOrder) *DecrypterOpts
NewPlainDecrypterOpts creates a SM2 non-ASN1 decrypter options.
type EncrypterOpts ¶ added in v0.3.0
type EncrypterOpts struct {
// contains filtered or unexported fields
}
EncrypterOpts encryption options
func NewPlainEncrypterOpts ¶ added in v0.7.0
func NewPlainEncrypterOpts(marhsalMode pointMarshalMode, splicingOrder ciphertextSplicingOrder) *EncrypterOpts
NewPlainEncrypterOpts creates a SM2 non-ASN1 encrypter options.
type KeyExchange ¶ added in v0.13.3
type KeyExchange struct {
// contains filtered or unexported fields
}
KeyExchange key exchange struct, include internal stat in whole key exchange flow. Initiator's flow will be: NewKeyExchange -> InitKeyExchange -> transmission -> ConfirmResponder Responder's flow will be: NewKeyExchange -> waiting ... -> RepondKeyExchange -> transmission -> ConfirmInitiator
func NewKeyExchange ¶ added in v0.13.3
func NewKeyExchange(priv *PrivateKey, peerPub *ecdsa.PublicKey, uid, peerUID []byte, keyLen int, genSignature bool) (ke *KeyExchange, err error)
NewKeyExchange create one new KeyExchange object
在部分场景中,在初始 KeyExchange 时暂时没有对端的公开信息(如公钥、UID),这些信息可能需要在后续的交换中得到。 这种情况下,可设置 peerPub、peerUID 参数为 nil,并在合适的时候通过 KeyExchange.SetPeerParameters 方法配置相关参数。 注意 KeyExchange.SetPeerParameters 方法必须要在 KeyExchange.RepondKeyExchange 或 KeyExchange.RepondKeyExchange 方法之前调用。
func (*KeyExchange) ConfirmInitiator ¶ added in v0.13.3
func (ke *KeyExchange) ConfirmInitiator(s1 []byte) ([]byte, error)
ConfirmInitiator for responder's step B10
func (*KeyExchange) ConfirmResponder ¶ added in v0.13.3
ConfirmResponder for initiator's step A4-A10, returns keying data and optional signature.
It will check if there are peer's public key and validate the peer's Ephemeral Public Key.
If the peer's signature is not empty, then it will also validate the peer's signature and return generated signature depends on KeyExchange.genSignature value.
func (*KeyExchange) Destroy ¶ added in v0.14.0
func (ke *KeyExchange) Destroy()
Destroy clear all internal state and Ephemeral private/public keys.
func (*KeyExchange) InitKeyExchange ¶ added in v0.13.3
InitKeyExchange is for initiator's step A1-A3, returns generated Ephemeral Public Key which will be passed to Reponder.
func (*KeyExchange) RepondKeyExchange ¶ added in v0.13.3
func (ke *KeyExchange) RepondKeyExchange(rand io.Reader, rA *ecdsa.PublicKey) (*ecdsa.PublicKey, []byte, error)
RepondKeyExchange is for responder's step B1-B8, returns generated Ephemeral Public Key and optional signature depends on KeyExchange.genSignature value.
It will check if there are peer's public key and validate the peer's Ephemeral Public Key.
func (*KeyExchange) SetPeerParameters ¶ added in v0.13.7
func (ke *KeyExchange) SetPeerParameters(peerPub *ecdsa.PublicKey, peerUID []byte) error
SetPeerParameters 设置对端公开信息,该方法用于某些初期状态无法取得对端公开参数的场景。 例如:在TLCP协议中,基于SM2算法ECDHE过程。
注意该方法仅在 NewKeyExchange 没有提供 peerPub、peerUID参数时允许被调用, 且该方法只能调用一次不可重复调用,若多次调用或peerPub、peerUID已经存在则会发生错误。
type PrivateKey ¶ added in v0.1.2
type PrivateKey struct { ecdsa.PrivateKey // contains filtered or unexported fields }
PrivateKey represents an ECDSA SM2 private key. It implemented both crypto.Decrypter and crypto.Signer interfaces.
func GenerateKey ¶ added in v0.1.2
func GenerateKey(rand io.Reader) (*PrivateKey, error)
GenerateKey generates a new SM2 private key.
Most applications should use crypto/rand.Reader as rand. Note that the returned key does not depend deterministically on the bytes read from rand, and may change between calls and/or between versions.
func NewPrivateKey ¶ added in v0.24.1
func NewPrivateKey(key []byte) (*PrivateKey, error)
NewPrivateKey checks that key is valid and returns a SM2 PrivateKey.
key - the private key byte slice, the length must be 32 for SM2.
Example ¶
package main import ( "encoding/hex" "fmt" "log" "github.com/emmansun/gmsm/sm2" ) func main() { keyBytes, _ := hex.DecodeString("6c5a0a0b2eed3cbec3e4f1252bfe0e28c504a1c6bf1999eebb0af9ef0f8e6c85") priv, err := sm2.NewPrivateKey(keyBytes) if err != nil { log.Fatalf("fail to new private key %v", err) } fmt.Printf("%x\n", priv.D.Bytes()) }
Output: 6c5a0a0b2eed3cbec3e4f1252bfe0e28c504a1c6bf1999eebb0af9ef0f8e6c85
func NewPrivateKeyFromInt ¶ added in v0.24.1
func NewPrivateKeyFromInt(key *big.Int) (*PrivateKey, error)
NewPrivateKeyFromInt checks that key is valid and returns a SM2 PrivateKey.
Example ¶
package main import ( "fmt" "log" "math/big" "github.com/emmansun/gmsm/sm2" ) func main() { key := big.NewInt(0x123456) priv, err := sm2.NewPrivateKeyFromInt(key) if err != nil { log.Fatalf("fail to new private key %v", err) } fmt.Printf("%x\n", priv.D.Bytes()) }
Output: 123456
func ParseEnvelopedPrivateKey ¶ added in v0.16.0
func ParseEnvelopedPrivateKey(priv *PrivateKey, enveloped []byte) (*PrivateKey, error)
ParseEnvelopedPrivateKey, parses and decrypts the enveloped SM2 private key. This methed just supports SM4 cipher now.
func (*PrivateKey) Decrypt ¶ added in v0.3.0
func (priv *PrivateKey) Decrypt(rand io.Reader, msg []byte, opts crypto.DecrypterOpts) (plaintext []byte, err error)
Decrypt decrypts ciphertext msg to plaintext. The opts argument should be appropriate for the primitive used. Compliance with GB/T 32918.4-2016 chapter 7.
Example ¶
package main import ( "encoding/hex" "fmt" "log" "os" "github.com/emmansun/gmsm/sm2" ) func main() { ciphertext, _ := hex.DecodeString("308194022100bd31001ce8d39a4a0119ff96d71334cd12d8b75bbc780f5bfc6e1efab535e85a02201839c075ff8bf761dcbe185c9750816410517001d6a130f6ab97fb23337cce150420ea82bd58d6a5394eb468a769ab48b6a26870ca075377eb06663780c920ea5ee0042be22abcf48e56ae9d29ac770d9de0d6b7094a874a2f8d26c26e0b1daaf4ff50a484b88163d04785b04585bb") // real private key should be from secret storage privKey, _ := hex.DecodeString("6c5a0a0b2eed3cbec3e4f1252bfe0e28c504a1c6bf1999eebb0af9ef0f8e6c85") testkey, err := sm2.NewPrivateKey(privKey) if err != nil { log.Fatalf("fail to new private key %v", err) } plaintext, err := testkey.Decrypt(nil, ciphertext, nil) if err != nil { fmt.Fprintf(os.Stderr, "Error from decryption: %s\n", err) return } fmt.Printf("Plaintext: %s\n", string(plaintext)) }
Output: Plaintext: send reinforcements, we're going to advance
func (*PrivateKey) ECDH ¶ added in v0.15.4
func (k *PrivateKey) ECDH() (*ecdh.PrivateKey, error)
ECDH returns k as a ecdh.PrivateKey. It returns an error if the key is invalid according to the definition of ecdh.Curve.NewPrivateKey, or if the Curve is not supported by ecdh.
func (*PrivateKey) Equal ¶ added in v0.11.1
func (priv *PrivateKey) Equal(x crypto.PrivateKey) bool
func (*PrivateKey) FromECPrivateKey ¶ added in v0.3.0
func (priv *PrivateKey) FromECPrivateKey(key *ecdsa.PrivateKey) (*PrivateKey, error)
FromECPrivateKey convert an ecdsa private key to SM2 private key.
func (*PrivateKey) Sign ¶ added in v0.1.2
func (priv *PrivateKey) Sign(rand io.Reader, digest []byte, opts crypto.SignerOpts) ([]byte, error)
Sign signs digest with priv, reading randomness from rand. Compliance with GB/T 32918.2-2016. The opts argument is currently used for SM2SignerOption checking only. If the opts argument is SM2SignerOption and its ForceGMSign is true, digest argument will be treated as raw data and UID will be taken from opts.
This method implements crypto.Signer, which is an interface to support keys where the private part is kept in, for example, a hardware module.
Example (ForceSM2) ¶
This is a reference method to force SM2 standard with SDK crypto.Signer.
package main import ( "crypto/rand" "encoding/hex" "fmt" "log" "os" "github.com/emmansun/gmsm/sm2" ) func main() { toSign := []byte("ShangMi SM2 Sign Standard") // real private key should be from secret storage privKey, _ := hex.DecodeString("6c5a0a0b2eed3cbec3e4f1252bfe0e28c504a1c6bf1999eebb0af9ef0f8e6c85") testkey, err := sm2.NewPrivateKey(privKey) if err != nil { log.Fatalf("fail to new private key %v", err) } // force SM2 sign standard and use default UID sig, err := testkey.Sign(rand.Reader, toSign, sm2.DefaultSM2SignerOpts) if err != nil { fmt.Fprintf(os.Stderr, "Error from sign: %s\n", err) return } // Since sign is a randomized function, signature will be // different each time. fmt.Printf("%x\n", sig) }
Output:
func (*PrivateKey) SignWithSM2 ¶ added in v0.2.2
SignWithSM2 signs uid, msg with priv, reading randomness from rand. Compliance with GB/T 32918.2-2016. Deprecated: please use Sign method directly.
type SM2SignerOption ¶ added in v0.4.8
type SM2SignerOption struct {
// contains filtered or unexported fields
}
SM2SignerOption implements crypto.SignerOpts interface. It is specific for SM2, used in private key's Sign method.
func NewSM2SignerOption ¶ added in v0.4.8
func NewSM2SignerOption(forceGMSign bool, uid []byte) *SM2SignerOption
NewSM2SignerOption creates a SM2 specific signer option. forceGMSign - if use GM specific sign logic, if yes, should pass raw message to sign. uid - if forceGMSign is true, then you can pass uid, if no uid is provided, system will use default one.
func (*SM2SignerOption) HashFunc ¶ added in v0.4.8
func (*SM2SignerOption) HashFunc() crypto.Hash