github.com/kchristidis/fabric@v1.0.4-0.20171028114726-837acd08cde1/bccsp/sw/ecdsa.go (about)

     1  /*
     2  Copyright IBM Corp. 2016 All Rights Reserved.
     3  
     4  Licensed under the Apache License, Version 2.0 (the "License");
     5  you may not use this file except in compliance with the License.
     6  You may obtain a copy of the License at
     7  
     8  		 http://www.apache.org/licenses/LICENSE-2.0
     9  
    10  Unless required by applicable law or agreed to in writing, software
    11  distributed under the License is distributed on an "AS IS" BASIS,
    12  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
    13  See the License for the specific language governing permissions and
    14  limitations under the License.
    15  */
    16  package sw
    17  
    18  import (
    19  	"crypto/ecdsa"
    20  	"crypto/elliptic"
    21  	"crypto/rand"
    22  	"encoding/asn1"
    23  	"errors"
    24  	"fmt"
    25  	"math/big"
    26  
    27  	"github.com/hyperledger/fabric/bccsp"
    28  )
    29  
    30  type ECDSASignature struct {
    31  	R, S *big.Int
    32  }
    33  
    34  var (
    35  	// curveHalfOrders contains the precomputed curve group orders halved.
    36  	// It is used to ensure that signature' S value is lower or equal to the
    37  	// curve group order halved. We accept only low-S signatures.
    38  	// They are precomputed for efficiency reasons.
    39  	curveHalfOrders map[elliptic.Curve]*big.Int = map[elliptic.Curve]*big.Int{
    40  		elliptic.P224(): new(big.Int).Rsh(elliptic.P224().Params().N, 1),
    41  		elliptic.P256(): new(big.Int).Rsh(elliptic.P256().Params().N, 1),
    42  		elliptic.P384(): new(big.Int).Rsh(elliptic.P384().Params().N, 1),
    43  		elliptic.P521(): new(big.Int).Rsh(elliptic.P521().Params().N, 1),
    44  	}
    45  )
    46  
    47  func MarshalECDSASignature(r, s *big.Int) ([]byte, error) {
    48  	return asn1.Marshal(ECDSASignature{r, s})
    49  }
    50  
    51  func UnmarshalECDSASignature(raw []byte) (*big.Int, *big.Int, error) {
    52  	// Unmarshal
    53  	sig := new(ECDSASignature)
    54  	_, err := asn1.Unmarshal(raw, sig)
    55  	if err != nil {
    56  		return nil, nil, fmt.Errorf("Failed unmashalling signature [%s]", err)
    57  	}
    58  
    59  	// Validate sig
    60  	if sig.R == nil {
    61  		return nil, nil, errors.New("Invalid signature. R must be different from nil.")
    62  	}
    63  	if sig.S == nil {
    64  		return nil, nil, errors.New("Invalid signature. S must be different from nil.")
    65  	}
    66  
    67  	if sig.R.Sign() != 1 {
    68  		return nil, nil, errors.New("Invalid signature. R must be larger than zero")
    69  	}
    70  	if sig.S.Sign() != 1 {
    71  		return nil, nil, errors.New("Invalid signature. S must be larger than zero")
    72  	}
    73  
    74  	return sig.R, sig.S, nil
    75  }
    76  
    77  func signECDSA(k *ecdsa.PrivateKey, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) {
    78  	r, s, err := ecdsa.Sign(rand.Reader, k, digest)
    79  	if err != nil {
    80  		return nil, err
    81  	}
    82  
    83  	s, _, err = ToLowS(&k.PublicKey, s)
    84  	if err != nil {
    85  		return nil, err
    86  	}
    87  
    88  	return MarshalECDSASignature(r, s)
    89  }
    90  
    91  func verifyECDSA(k *ecdsa.PublicKey, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) {
    92  	r, s, err := UnmarshalECDSASignature(signature)
    93  	if err != nil {
    94  		return false, fmt.Errorf("Failed unmashalling signature [%s]", err)
    95  	}
    96  
    97  	lowS, err := IsLowS(k, s)
    98  	if err != nil {
    99  		return false, err
   100  	}
   101  
   102  	if !lowS {
   103  		return false, fmt.Errorf("Invalid S. Must be smaller than half the order [%s][%s].", s, curveHalfOrders[k.Curve])
   104  	}
   105  
   106  	return ecdsa.Verify(k, digest, r, s), nil
   107  }
   108  
   109  func SignatureToLowS(k *ecdsa.PublicKey, signature []byte) ([]byte, error) {
   110  	r, s, err := UnmarshalECDSASignature(signature)
   111  	if err != nil {
   112  		return nil, err
   113  	}
   114  
   115  	s, modified, err := ToLowS(k, s)
   116  	if err != nil {
   117  		return nil, err
   118  	}
   119  
   120  	if modified {
   121  		return MarshalECDSASignature(r, s)
   122  	}
   123  
   124  	return signature, nil
   125  }
   126  
   127  // IsLow checks that s is a low-S
   128  func IsLowS(k *ecdsa.PublicKey, s *big.Int) (bool, error) {
   129  	halfOrder, ok := curveHalfOrders[k.Curve]
   130  	if !ok {
   131  		return false, fmt.Errorf("Curve not recognized [%s]", k.Curve)
   132  	}
   133  
   134  	return s.Cmp(halfOrder) != 1, nil
   135  
   136  }
   137  
   138  func ToLowS(k *ecdsa.PublicKey, s *big.Int) (*big.Int, bool, error) {
   139  	lowS, err := IsLowS(k, s)
   140  	if err != nil {
   141  		return nil, false, err
   142  	}
   143  
   144  	if !lowS {
   145  		// Set s to N - s that will be then in the lower part of signature space
   146  		// less or equal to half order
   147  		s.Sub(k.Params().N, s)
   148  
   149  		return s, true, nil
   150  	}
   151  
   152  	return s, false, nil
   153  }
   154  
   155  type ecdsaSigner struct{}
   156  
   157  func (s *ecdsaSigner) Sign(k bccsp.Key, digest []byte, opts bccsp.SignerOpts) (signature []byte, err error) {
   158  	return signECDSA(k.(*ecdsaPrivateKey).privKey, digest, opts)
   159  }
   160  
   161  type ecdsaPrivateKeyVerifier struct{}
   162  
   163  func (v *ecdsaPrivateKeyVerifier) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) {
   164  	return verifyECDSA(&(k.(*ecdsaPrivateKey).privKey.PublicKey), signature, digest, opts)
   165  }
   166  
   167  type ecdsaPublicKeyKeyVerifier struct{}
   168  
   169  func (v *ecdsaPublicKeyKeyVerifier) Verify(k bccsp.Key, signature, digest []byte, opts bccsp.SignerOpts) (valid bool, err error) {
   170  	return verifyECDSA(k.(*ecdsaPublicKey).pubKey, signature, digest, opts)
   171  }