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  }