sm2

package
v0.27.2 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 10, 2024 License: MIT Imports: 24 Imported by: 28

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

Examples

Constants

View Source
const (
	//MarshalUncompressed uncompressed mashal mode
	MarshalUncompressed pointMarshalMode = iota
	//MarshalCompressed compressed mashal mode
	MarshalCompressed
	//MarshalHybrid hybrid mashal mode
	MarshalHybrid
)
View Source
const (
	C1C3C2 ciphertextSplicingOrder = iota
	C1C2C3
)
View Source
const (
	ENCODING_PLAIN ciphertextEncoding = iota
	ENCODING_ASN1
)

Variables

View Source
var ASN1DecrypterOpts = &DecrypterOpts{ENCODING_ASN1, C1C3C2}
View Source
var DefaultSM2SignerOpts = NewSM2SignerOption(true, nil)

DefaultSM2SignerOpts uses default UID and forceGMSign is true.

View Source
var ErrDecryption = errors.New("sm2: decryption error")

ErrDecryption represents a failure to decrypt a message. It is deliberately vague to avoid adaptive attacks.

View Source
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

func CalculateSM2Hash(pub *ecdsa.PublicKey, data, uid []byte) ([]byte, error)

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

func CalculateZA(pub *ecdsa.PublicKey, uid []byte) ([]byte, error)

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

func EncryptASN1(random io.Reader, pub *ecdsa.PublicKey, msg []byte) ([]byte, error)

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

func IsSM2PublicKey(publicKey any) bool

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

func NewPublicKey(key []byte) (*ecdsa.PublicKey, error)

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 P256

func P256() elliptic.Curve

P256 returns sm2 curve signleton, this function is for backward compatibility.

func PlainCiphertext2ASN1 added in v0.7.0

func PlainCiphertext2ASN1(ciphertext []byte, from ciphertextSplicingOrder) ([]byte, error)

PlainCiphertext2ASN1 utility method to convert plain encoding ciphertext to ASN.1 encoding format

func PublicKeyToECDH added in v0.15.4

func PublicKeyToECDH(k *ecdsa.PublicKey) (*ecdh.PublicKey, error)

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

func RecoverPublicKeysFromSM2Signature(hash, sig []byte) ([]*ecdsa.PublicKey, error)

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

func Sign(rand io.Reader, priv *ecdsa.PrivateKey, hash []byte) (r, s *big.Int, err error)

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

func Verify(pub *ecdsa.PublicKey, hash []byte, r, s *big.Int) bool

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

func VerifyASN1(pub *ecdsa.PublicKey, hash, sig []byte) bool

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

func VerifyASN1WithSM2(pub *ecdsa.PublicKey, uid, msg, sig []byte) bool

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

func VerifyWithSM2 added in v0.1.2

func VerifyWithSM2(pub *ecdsa.PublicKey, uid, msg []byte, r, s *big.Int) bool

VerifyWithSM2 verifies the signature in r, s of raw msg and uid using the public key, pub. It returns value records whether the signature is valid. Compliance with GB/T 32918.2-2016.

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

func (ke *KeyExchange) ConfirmResponder(rB *ecdsa.PublicKey, sB []byte) ([]byte, []byte, error)

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

func (ke *KeyExchange) InitKeyExchange(rand io.Reader) (*ecdsa.PublicKey, error)

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

func (priv *PrivateKey) SignWithSM2(rand io.Reader, uid, msg []byte) ([]byte, error)

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

type Signer added in v0.3.0

type Signer interface {
	SignWithSM2(rand io.Reader, uid, msg []byte) ([]byte, error)
}

Signer SM2 special signer

Directories

Path Synopsis
Package sm2ec defines/implements SM2 curve structure.
Package sm2ec defines/implements SM2 curve structure.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL