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 }