github.com/turingchain2020/turingchain@v1.1.21/system/crypto/sm2/sm2.go (about)

     1  // Copyright Turing Corp. 2018 All Rights Reserved.
     2  // Use of this source code is governed by a BSD-style
     3  // license that can be found in the LICENSE file.
     4  
     5  // Package sm2 带证书交易的签名
     6  package sm2
     7  
     8  import (
     9  	"bytes"
    10  	"crypto/elliptic"
    11  	"errors"
    12  	"fmt"
    13  	"math/big"
    14  
    15  	cert "github.com/turingchain2020/turingchain/system/crypto/common"
    16  	"github.com/golang/protobuf/proto"
    17  
    18  	"github.com/turingchain2020/turingchain/common/crypto"
    19  	"github.com/tjfoc/gmsm/sm2"
    20  )
    21  
    22  //const
    23  const (
    24  	SM2PrivateKeyLength    = 32
    25  	SM2PublicKeyLength     = 65
    26  	SM2PublicKeyCompressed = 33
    27  	SM2SignatureMinLength  = 72
    28  )
    29  
    30  //Driver 驱动
    31  type Driver struct{}
    32  
    33  //GenKey 生成私钥
    34  func (d Driver) GenKey() (crypto.PrivKey, error) {
    35  	privKeyBytes := [SM2PrivateKeyLength]byte{}
    36  	copy(privKeyBytes[:], crypto.CRandBytes(SM2PrivateKeyLength))
    37  	priv, _ := privKeyFromBytes(sm2.P256Sm2(), privKeyBytes[:])
    38  	copy(privKeyBytes[:], SerializePrivateKey(priv))
    39  	return PrivKeySM2(privKeyBytes), nil
    40  }
    41  
    42  //PrivKeyFromBytes 字节转为私钥
    43  func (d Driver) PrivKeyFromBytes(b []byte) (privKey crypto.PrivKey, err error) {
    44  	if len(b) != SM2PrivateKeyLength {
    45  		return nil, errors.New("invalid priv key byte")
    46  	}
    47  	privKeyBytes := new([SM2PrivateKeyLength]byte)
    48  	copy(privKeyBytes[:], b[:SM2PrivateKeyLength])
    49  
    50  	priv, _ := privKeyFromBytes(sm2.P256Sm2(), privKeyBytes[:])
    51  
    52  	copy(privKeyBytes[:], SerializePrivateKey(priv))
    53  	return PrivKeySM2(*privKeyBytes), nil
    54  }
    55  
    56  //PubKeyFromBytes 字节转为公钥
    57  func (d Driver) PubKeyFromBytes(b []byte) (pubKey crypto.PubKey, err error) {
    58  	if len(b) != SM2PublicKeyLength && len(b) != SM2PublicKeyCompressed {
    59  		return nil, errors.New("invalid pub key byte")
    60  	}
    61  	pubKeyBytes := new([SM2PublicKeyLength]byte)
    62  	copy(pubKeyBytes[:], b[:])
    63  	return PubKeySM2(*pubKeyBytes), nil
    64  }
    65  
    66  //SignatureFromBytes 字节转为签名
    67  func (d Driver) SignatureFromBytes(b []byte) (sig crypto.Signature, err error) {
    68  	var certSignature cert.CertSignature
    69  	err = proto.Unmarshal(b, &certSignature)
    70  	if err != nil {
    71  		return SignatureSM2(b), nil
    72  	}
    73  
    74  	return &SignatureS{
    75  		Signature: SignatureSM2(certSignature.Signature),
    76  		uid:       certSignature.Uid,
    77  	}, nil
    78  }
    79  
    80  // Validate validate msg and signature TODO:目前只做了公私钥签名验证,需要根据框架整合证书验证
    81  func (d Driver) Validate(msg, pub, sig []byte) error {
    82  	return crypto.BasicValidation(d, msg, pub, sig)
    83  }
    84  
    85  //PrivKeySM2 私钥
    86  type PrivKeySM2 [SM2PrivateKeyLength]byte
    87  
    88  //Bytes 字节格式
    89  func (privKey PrivKeySM2) Bytes() []byte {
    90  	s := make([]byte, SM2PrivateKeyLength)
    91  	copy(s, privKey[:])
    92  	return s
    93  }
    94  
    95  //Sign 签名
    96  func (privKey PrivKeySM2) Sign(msg []byte) crypto.Signature {
    97  	priv, _ := privKeyFromBytes(sm2.P256Sm2(), privKey[:])
    98  	r, s, err := sm2.Sm2Sign(priv, msg, nil)
    99  	if err != nil {
   100  		return nil
   101  	}
   102  	//sm2不需要LowS转换
   103  	//s = ToLowS(pub, s)
   104  	return SignatureSM2(Serialize(r, s))
   105  }
   106  
   107  //PubKey 私钥生成公钥
   108  func (privKey PrivKeySM2) PubKey() crypto.PubKey {
   109  	_, pub := privKeyFromBytes(sm2.P256Sm2(), privKey[:])
   110  	var pubSM2 PubKeySM2
   111  	copy(pubSM2[:], sm2.Compress(pub))
   112  	return pubSM2
   113  }
   114  
   115  //Equals 公钥
   116  func (privKey PrivKeySM2) Equals(other crypto.PrivKey) bool {
   117  	if otherSecp, ok := other.(PrivKeySM2); ok {
   118  		return bytes.Equal(privKey[:], otherSecp[:])
   119  	}
   120  
   121  	return false
   122  }
   123  
   124  func (privKey PrivKeySM2) String() string {
   125  	return fmt.Sprintf("PrivKeySM2{*****}")
   126  }
   127  
   128  //PubKeySM2 公钥
   129  type PubKeySM2 [SM2PublicKeyLength]byte
   130  
   131  //Bytes 字节格式
   132  func (pubKey PubKeySM2) Bytes() []byte {
   133  	length := SM2PublicKeyLength
   134  	if pubKey.isCompressed() {
   135  		length = SM2PublicKeyCompressed
   136  	}
   137  	s := make([]byte, length)
   138  	copy(s, pubKey[0:length])
   139  	return s
   140  }
   141  
   142  func (pubKey PubKeySM2) isCompressed() bool {
   143  	return pubKey[0] != pubkeyUncompressed
   144  }
   145  
   146  //VerifyBytes 验证字节
   147  func (pubKey PubKeySM2) VerifyBytes(msg []byte, sig crypto.Signature) bool {
   148  	var uid []byte
   149  	if wrap, ok := sig.(*SignatureS); ok {
   150  		sig = wrap.Signature
   151  		uid = wrap.uid
   152  	}
   153  	sigSM2, ok := sig.(SignatureSM2)
   154  	if !ok {
   155  		return false
   156  	}
   157  
   158  	if !pubKey.isCompressed() {
   159  		return false
   160  	}
   161  
   162  	pub := sm2.Decompress(pubKey[0:SM2PublicKeyCompressed])
   163  	r, s, err := Deserialize(sigSM2)
   164  	if err != nil {
   165  		fmt.Printf("unmarshal sign failed")
   166  		return false
   167  	}
   168  
   169  	return sm2.Sm2Verify(pub, msg, uid, r, s)
   170  }
   171  
   172  func (pubKey PubKeySM2) String() string {
   173  	return fmt.Sprintf("PubKeySM2{%X}", pubKey[:])
   174  }
   175  
   176  //KeyString Must return the full bytes in hex.
   177  // Used for map keying, etc.
   178  func (pubKey PubKeySM2) KeyString() string {
   179  	return fmt.Sprintf("%X", pubKey[:])
   180  }
   181  
   182  //Equals 相等
   183  func (pubKey PubKeySM2) Equals(other crypto.PubKey) bool {
   184  	if otherSecp, ok := other.(PubKeySM2); ok {
   185  		return bytes.Equal(pubKey[:], otherSecp[:])
   186  	}
   187  	return false
   188  }
   189  
   190  //SignatureSM2 签名
   191  type SignatureSM2 []byte
   192  
   193  //SignatureS 签名
   194  type SignatureS struct {
   195  	crypto.Signature
   196  	uid []byte
   197  }
   198  
   199  //Bytes 字节格式
   200  func (sig SignatureSM2) Bytes() []byte {
   201  	s := make([]byte, len(sig))
   202  	copy(s, sig[:])
   203  	return s
   204  }
   205  
   206  //IsZero 是否为0
   207  func (sig SignatureSM2) IsZero() bool { return len(sig) == 0 }
   208  
   209  func (sig SignatureSM2) String() string {
   210  	fingerprint := make([]byte, len(sig[:]))
   211  	copy(fingerprint, sig[:])
   212  	return fmt.Sprintf("/%X.../", fingerprint)
   213  
   214  }
   215  
   216  //Equals 相等
   217  func (sig SignatureSM2) Equals(other crypto.Signature) bool {
   218  	if otherEd, ok := other.(SignatureSM2); ok {
   219  		return bytes.Equal(sig[:], otherEd[:])
   220  	}
   221  	return false
   222  }
   223  
   224  //const
   225  const (
   226  	Name = "auth_sm2"
   227  	ID   = 258
   228  )
   229  
   230  func init() {
   231  	// TODO: 注册时需要初始化证书,WithOptionInitFunc
   232  	crypto.Register(Name, &Driver{}, crypto.WithOptionTypeID(ID))
   233  }
   234  
   235  func privKeyFromBytes(curve elliptic.Curve, pk []byte) (*sm2.PrivateKey, *sm2.PublicKey) {
   236  	x, y := curve.ScalarBaseMult(pk)
   237  
   238  	priv := &sm2.PrivateKey{
   239  		PublicKey: sm2.PublicKey{
   240  			Curve: curve,
   241  			X:     x,
   242  			Y:     y,
   243  		},
   244  		D: new(big.Int).SetBytes(pk),
   245  	}
   246  
   247  	return priv, &priv.PublicKey
   248  }