github.com/turingchain2020/turingchain@v1.1.21/system/crypto/secp256r1/secp256r1.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 ecdsa 6 7 import ( 8 "bytes" 9 "errors" 10 "fmt" 11 12 cert "github.com/turingchain2020/turingchain/system/crypto/common" 13 "github.com/golang/protobuf/proto" 14 15 "crypto/ecdsa" 16 "crypto/elliptic" 17 "crypto/rand" 18 "math/big" 19 20 "github.com/turingchain2020/turingchain/common/crypto" 21 ) 22 23 const ( 24 privateKeyECDSALength = 32 25 publicKeyECDSALength = 65 26 publicKeyECDSALengthCompressed = 33 27 ) 28 29 // Driver driver 30 type Driver struct{} 31 32 // GenKey create private key 33 func (d Driver) GenKey() (crypto.PrivKey, error) { 34 privKeyBytes := [privateKeyECDSALength]byte{} 35 copy(privKeyBytes[:], crypto.CRandBytes(privateKeyECDSALength)) 36 priv, _ := privKeyFromBytes(elliptic.P256(), privKeyBytes[:]) 37 copy(privKeyBytes[:], SerializePrivateKey(priv)) 38 return PrivKeyECDSA(privKeyBytes), nil 39 } 40 41 // PrivKeyFromBytes create private key from bytes 42 func (d Driver) PrivKeyFromBytes(b []byte) (privKey crypto.PrivKey, err error) { 43 if len(b) != privateKeyECDSALength { 44 return nil, errors.New("invalid priv key byte") 45 } 46 47 privKeyBytes := new([privateKeyECDSALength]byte) 48 copy(privKeyBytes[:], b[:privateKeyECDSALength]) 49 priv, _ := privKeyFromBytes(elliptic.P256(), privKeyBytes[:]) 50 51 copy(privKeyBytes[:], SerializePrivateKey(priv)) 52 return PrivKeyECDSA(*privKeyBytes), nil 53 } 54 55 // PubKeyFromBytes create public key from bytes 56 func (d Driver) PubKeyFromBytes(b []byte) (pubKey crypto.PubKey, err error) { 57 if len(b) != publicKeyECDSALength && len(b) != publicKeyECDSALengthCompressed { 58 return nil, errors.New("invalid pub key byte") 59 } 60 pubKeyBytes := new([publicKeyECDSALengthCompressed]byte) 61 copy(pubKeyBytes[:], b[:]) 62 return PubKeyECDSA(*pubKeyBytes), nil 63 } 64 65 // SignatureFromBytes create signature from bytes 66 func (d Driver) SignatureFromBytes(b []byte) (sig crypto.Signature, err error) { 67 var certSignature cert.CertSignature 68 err = proto.Unmarshal(b, &certSignature) 69 if err != nil { 70 return SignatureECDSA(b), nil 71 } 72 73 if len(certSignature.Cert) == 0 { 74 return SignatureECDSA(b), nil 75 } 76 77 return SignatureECDSA(certSignature.Signature), 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 // PrivKeyECDSA PrivKey 86 type PrivKeyECDSA [privateKeyECDSALength]byte 87 88 // Bytes convert to bytes 89 func (privKey PrivKeyECDSA) Bytes() []byte { 90 s := make([]byte, privateKeyECDSALength) 91 copy(s, privKey[:]) 92 return s 93 } 94 95 // Sign create signature 96 func (privKey PrivKeyECDSA) Sign(msg []byte) crypto.Signature { 97 priv, pub := privKeyFromBytes(elliptic.P256(), privKey[:]) 98 r, s, err := ecdsa.Sign(rand.Reader, priv, crypto.Sha256(msg)) 99 if err != nil { 100 return nil 101 } 102 103 s = ToLowS(pub, s) 104 ecdsaSigByte, _ := MarshalECDSASignature(r, s) 105 return SignatureECDSA(ecdsaSigByte) 106 } 107 108 // PubKey convert to public key 109 func (privKey PrivKeyECDSA) PubKey() crypto.PubKey { 110 _, pub := privKeyFromBytes(elliptic.P256(), privKey[:]) 111 var pubECDSA PubKeyECDSA 112 copy(pubECDSA[:], SerializePublicKeyCompressed(pub)) 113 return pubECDSA 114 } 115 116 // Equals check privkey is equal 117 func (privKey PrivKeyECDSA) Equals(other crypto.PrivKey) bool { 118 if otherSecp, ok := other.(PrivKeyECDSA); ok { 119 return bytes.Equal(privKey[:], otherSecp[:]) 120 } 121 122 return false 123 } 124 125 // String convert to string 126 func (privKey PrivKeyECDSA) String() string { 127 return fmt.Sprintf("PrivKeyECDSA{*****}") 128 } 129 130 // PubKeyECDSA PubKey 131 // prefixed with 0x02 or 0x03, depending on the y-cord. 132 type PubKeyECDSA [publicKeyECDSALengthCompressed]byte 133 134 // Bytes convert to bytes 135 func (pubKey PubKeyECDSA) Bytes() []byte { 136 length := publicKeyECDSALengthCompressed 137 s := make([]byte, length) 138 copy(s, pubKey[:]) 139 return s 140 } 141 142 // VerifyBytes verify signature 143 func (pubKey PubKeyECDSA) VerifyBytes(msg []byte, sig crypto.Signature) bool { 144 // unwrap if needed 145 if wrap, ok := sig.(SignatureS); ok { 146 sig = wrap.Signature 147 } 148 // and assert same algorithm to sign and verify 149 sigECDSA, ok := sig.(SignatureECDSA) 150 if !ok { 151 return false 152 } 153 154 if !pubKey.isCompressed() { 155 return false 156 } 157 158 pub, err := parsePubKeyCompressed(pubKey[0:publicKeyECDSALengthCompressed]) 159 if err != nil { 160 return false 161 } 162 163 r, s, err := UnmarshalECDSASignature(sigECDSA) 164 if err != nil { 165 return false 166 } 167 168 lowS := IsLowS(s) 169 if !lowS { 170 return false 171 } 172 return ecdsa.Verify(pub, crypto.Sha256(msg), r, s) 173 } 174 175 // String convert to string 176 func (pubKey PubKeyECDSA) String() string { 177 return fmt.Sprintf("PubKeyECDSA{%X}", pubKey[:]) 178 } 179 180 // KeyString Must return the full bytes in hex. 181 // Used for map keying, etc. 182 func (pubKey PubKeyECDSA) KeyString() string { 183 return fmt.Sprintf("%X", pubKey[:]) 184 } 185 186 // Equals check public key is equal 187 func (pubKey PubKeyECDSA) Equals(other crypto.PubKey) bool { 188 if otherSecp, ok := other.(PubKeyECDSA); ok { 189 return bytes.Equal(pubKey[:], otherSecp[:]) 190 } 191 return false 192 } 193 194 func (pubKey PubKeyECDSA) isCompressed() bool { 195 return pubKey[0] != pubkeyUncompressed 196 } 197 198 type signatureECDSA struct { 199 R, S *big.Int 200 } 201 202 // SignatureECDSA Signature 203 type SignatureECDSA []byte 204 205 // SignatureS signature struct 206 type SignatureS struct { 207 crypto.Signature 208 } 209 210 // Bytes convert signature to bytes 211 func (sig SignatureECDSA) Bytes() []byte { 212 s := make([]byte, len(sig)) 213 copy(s, sig[:]) 214 return s 215 } 216 217 // IsZero check signature is zero 218 func (sig SignatureECDSA) IsZero() bool { return len(sig) == 0 } 219 220 // String convert signature to string 221 func (sig SignatureECDSA) String() string { 222 fingerprint := make([]byte, len(sig[:])) 223 copy(fingerprint, sig[:]) 224 return fmt.Sprintf("/%X.../", fingerprint) 225 226 } 227 228 // Equals check signature equals 229 func (sig SignatureECDSA) Equals(other crypto.Signature) bool { 230 if otherEd, ok := other.(SignatureECDSA); ok { 231 return bytes.Equal(sig[:], otherEd[:]) 232 } 233 return false 234 } 235 236 // Name name 237 const Name = "auth_ecdsa" 238 239 // ID id 240 const ID = 257 241 242 func init() { 243 // TODO: 注册时需要初始化证书,WithOptionInitFunc 244 crypto.Register(Name, &Driver{}, crypto.WithOptionTypeID(ID)) 245 } 246 247 func privKeyFromBytes(curve elliptic.Curve, pk []byte) (*ecdsa.PrivateKey, *ecdsa.PublicKey) { 248 x, y := curve.ScalarBaseMult(pk) 249 250 priv := &ecdsa.PrivateKey{ 251 PublicKey: ecdsa.PublicKey{ 252 Curve: curve, 253 X: x, 254 Y: y, 255 }, 256 D: new(big.Int).SetBytes(pk), 257 } 258 259 return priv, &priv.PublicKey 260 }