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

     1  /*
     2  Copyright IBM Corp. 2017 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  
    17  package sw
    18  
    19  import (
    20  	"crypto/ecdsa"
    21  	"crypto/elliptic"
    22  	"crypto/rand"
    23  	"crypto/sha256"
    24  	"crypto/x509"
    25  	"math/big"
    26  	"testing"
    27  
    28  	"github.com/stretchr/testify/assert"
    29  )
    30  
    31  func TestUnmarshalECDSASignature(t *testing.T) {
    32  	_, _, err := UnmarshalECDSASignature(nil)
    33  	assert.Error(t, err)
    34  	assert.Contains(t, err.Error(), "Failed unmashalling signature [")
    35  
    36  	_, _, err = UnmarshalECDSASignature([]byte{})
    37  	assert.Error(t, err)
    38  	assert.Contains(t, err.Error(), "Failed unmashalling signature [")
    39  
    40  	_, _, err = UnmarshalECDSASignature([]byte{0})
    41  	assert.Error(t, err)
    42  	assert.Contains(t, err.Error(), "Failed unmashalling signature [")
    43  
    44  	sigma, err := MarshalECDSASignature(big.NewInt(-1), big.NewInt(1))
    45  	assert.NoError(t, err)
    46  	_, _, err = UnmarshalECDSASignature(sigma)
    47  	assert.Error(t, err)
    48  	assert.Contains(t, err.Error(), "Invalid signature. R must be larger than zero")
    49  
    50  	sigma, err = MarshalECDSASignature(big.NewInt(0), big.NewInt(1))
    51  	assert.NoError(t, err)
    52  	_, _, err = UnmarshalECDSASignature(sigma)
    53  	assert.Error(t, err)
    54  	assert.Contains(t, err.Error(), "Invalid signature. R must be larger than zero")
    55  
    56  	sigma, err = MarshalECDSASignature(big.NewInt(1), big.NewInt(0))
    57  	assert.NoError(t, err)
    58  	_, _, err = UnmarshalECDSASignature(sigma)
    59  	assert.Error(t, err)
    60  	assert.Contains(t, err.Error(), "Invalid signature. S must be larger than zero")
    61  
    62  	sigma, err = MarshalECDSASignature(big.NewInt(1), big.NewInt(-1))
    63  	assert.NoError(t, err)
    64  	_, _, err = UnmarshalECDSASignature(sigma)
    65  	assert.Error(t, err)
    66  	assert.Contains(t, err.Error(), "Invalid signature. S must be larger than zero")
    67  
    68  	sigma, err = MarshalECDSASignature(big.NewInt(1), big.NewInt(1))
    69  	assert.NoError(t, err)
    70  	R, S, err := UnmarshalECDSASignature(sigma)
    71  	assert.NoError(t, err)
    72  	assert.Equal(t, big.NewInt(1), R)
    73  	assert.Equal(t, big.NewInt(1), S)
    74  }
    75  
    76  func TestSignECDSA(t *testing.T) {
    77  	// Generate a key
    78  	lowLevelKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
    79  	assert.NoError(t, err)
    80  
    81  	// Induce an error on the underlying ecdsa algorithm
    82  	msg := []byte("hello world")
    83  	oldN := lowLevelKey.Params().N
    84  	defer func() { lowLevelKey.Params().N = oldN }()
    85  	lowLevelKey.Params().N = big.NewInt(0)
    86  	_, err = signECDSA(lowLevelKey, msg, nil)
    87  	assert.Error(t, err)
    88  	assert.Contains(t, err.Error(), "zero parameter")
    89  	lowLevelKey.Params().N = oldN
    90  
    91  	oldCurveHalfOrders := curveHalfOrders
    92  	curveHalfOrders = nil
    93  	defer func() { curveHalfOrders = oldCurveHalfOrders }()
    94  	_, err = signECDSA(lowLevelKey, msg, nil)
    95  	assert.Error(t, err)
    96  	assert.Contains(t, err.Error(), "Curve not recognized [")
    97  	curveHalfOrders = oldCurveHalfOrders
    98  }
    99  
   100  func TestVerifyECDSA(t *testing.T) {
   101  	// Generate a key
   102  	lowLevelKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   103  	assert.NoError(t, err)
   104  
   105  	msg := []byte("hello world")
   106  	sigma, err := signECDSA(lowLevelKey, msg, nil)
   107  	assert.NoError(t, err)
   108  
   109  	valid, err := verifyECDSA(&lowLevelKey.PublicKey, sigma, msg, nil)
   110  	assert.NoError(t, err)
   111  	assert.True(t, valid)
   112  
   113  	_, err = verifyECDSA(&lowLevelKey.PublicKey, nil, msg, nil)
   114  	assert.Error(t, err)
   115  	assert.Contains(t, err.Error(), "Failed unmashalling signature [")
   116  
   117  	oldCurveHalfOrders := curveHalfOrders
   118  	curveHalfOrders = nil
   119  	defer func() { curveHalfOrders = oldCurveHalfOrders }()
   120  	_, err = verifyECDSA(&lowLevelKey.PublicKey, sigma, msg, nil)
   121  	assert.Error(t, err)
   122  	assert.Contains(t, err.Error(), "Curve not recognized [")
   123  	curveHalfOrders = oldCurveHalfOrders
   124  
   125  	_, err = verifyECDSA(&lowLevelKey.PublicKey, nil, msg, nil)
   126  	assert.Error(t, err)
   127  	assert.Contains(t, err.Error(), "Failed unmashalling signature [")
   128  
   129  	R, S, err := UnmarshalECDSASignature(sigma)
   130  	assert.NoError(t, err)
   131  	S.Add(curveHalfOrders[elliptic.P256()], big.NewInt(1))
   132  	sigmaWrongS, err := MarshalECDSASignature(R, S)
   133  	assert.NoError(t, err)
   134  	_, err = verifyECDSA(&lowLevelKey.PublicKey, sigmaWrongS, msg, nil)
   135  	assert.Error(t, err)
   136  	assert.Contains(t, err.Error(), "Invalid S. Must be smaller than half the order [")
   137  }
   138  
   139  func TestEcdsaSignerSign(t *testing.T) {
   140  	signer := &ecdsaSigner{}
   141  	verifierPrivateKey := &ecdsaPrivateKeyVerifier{}
   142  	verifierPublicKey := &ecdsaPublicKeyKeyVerifier{}
   143  
   144  	// Generate a key
   145  	lowLevelKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   146  	assert.NoError(t, err)
   147  	k := &ecdsaPrivateKey{lowLevelKey}
   148  	pk, err := k.PublicKey()
   149  	assert.NoError(t, err)
   150  
   151  	// Sign
   152  	msg := []byte("Hello World")
   153  	sigma, err := signer.Sign(k, msg, nil)
   154  	assert.NoError(t, err)
   155  	assert.NotNil(t, sigma)
   156  
   157  	// Verify
   158  	valid, err := verifyECDSA(&lowLevelKey.PublicKey, sigma, msg, nil)
   159  	assert.NoError(t, err)
   160  	assert.True(t, valid)
   161  
   162  	valid, err = verifierPrivateKey.Verify(k, sigma, msg, nil)
   163  	assert.NoError(t, err)
   164  	assert.True(t, valid)
   165  
   166  	valid, err = verifierPublicKey.Verify(pk, sigma, msg, nil)
   167  	assert.NoError(t, err)
   168  	assert.True(t, valid)
   169  }
   170  
   171  func TestEcdsaPrivateKey(t *testing.T) {
   172  	lowLevelKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   173  	assert.NoError(t, err)
   174  	k := &ecdsaPrivateKey{lowLevelKey}
   175  
   176  	assert.False(t, k.Symmetric())
   177  	assert.True(t, k.Private())
   178  
   179  	_, err = k.Bytes()
   180  	assert.Error(t, err)
   181  	assert.Contains(t, err.Error(), "Not supported.")
   182  
   183  	k.privKey = nil
   184  	ski := k.SKI()
   185  	assert.Nil(t, ski)
   186  
   187  	k.privKey = lowLevelKey
   188  	ski = k.SKI()
   189  	raw := elliptic.Marshal(k.privKey.Curve, k.privKey.PublicKey.X, k.privKey.PublicKey.Y)
   190  	hash := sha256.New()
   191  	hash.Write(raw)
   192  	ski2 := hash.Sum(nil)
   193  	assert.Equal(t, ski2, ski, "SKI is not computed in the right way.")
   194  
   195  	pk, err := k.PublicKey()
   196  	assert.NoError(t, err)
   197  	assert.NotNil(t, pk)
   198  	ecdsaPK, ok := pk.(*ecdsaPublicKey)
   199  	assert.True(t, ok)
   200  	assert.Equal(t, &lowLevelKey.PublicKey, ecdsaPK.pubKey)
   201  }
   202  
   203  func TestEcdsaPublicKey(t *testing.T) {
   204  	lowLevelKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   205  	assert.NoError(t, err)
   206  	k := &ecdsaPublicKey{&lowLevelKey.PublicKey}
   207  
   208  	assert.False(t, k.Symmetric())
   209  	assert.False(t, k.Private())
   210  
   211  	k.pubKey = nil
   212  	ski := k.SKI()
   213  	assert.Nil(t, ski)
   214  
   215  	k.pubKey = &lowLevelKey.PublicKey
   216  	ski = k.SKI()
   217  	raw := elliptic.Marshal(k.pubKey.Curve, k.pubKey.X, k.pubKey.Y)
   218  	hash := sha256.New()
   219  	hash.Write(raw)
   220  	ski2 := hash.Sum(nil)
   221  	assert.Equal(t, ski, ski2, "SKI is not computed in the right way.")
   222  
   223  	pk, err := k.PublicKey()
   224  	assert.NoError(t, err)
   225  	assert.Equal(t, k, pk)
   226  
   227  	bytes, err := k.Bytes()
   228  	assert.NoError(t, err)
   229  	bytes2, err := x509.MarshalPKIXPublicKey(k.pubKey)
   230  	assert.Equal(t, bytes2, bytes, "bytes are not computed in the right way.")
   231  
   232  	invalidCurve := &elliptic.CurveParams{Name: "P-Invalid"}
   233  	invalidCurve.BitSize = 1024
   234  	k.pubKey = &ecdsa.PublicKey{Curve: invalidCurve, X: big.NewInt(1), Y: big.NewInt(1)}
   235  	_, err = k.Bytes()
   236  	assert.Error(t, err)
   237  	assert.Contains(t, err.Error(), "Failed marshalling key [")
   238  }
   239  
   240  func TestIsLowS(t *testing.T) {
   241  	lowLevelKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   242  	assert.NoError(t, err)
   243  
   244  	lowS, err := IsLowS(&lowLevelKey.PublicKey, big.NewInt(0))
   245  	assert.NoError(t, err)
   246  	assert.True(t, lowS)
   247  
   248  	s := new(big.Int)
   249  	s = s.Set(curveHalfOrders[elliptic.P256()])
   250  
   251  	lowS, err = IsLowS(&lowLevelKey.PublicKey, s)
   252  	assert.NoError(t, err)
   253  	assert.True(t, lowS)
   254  
   255  	s = s.Add(s, big.NewInt(1))
   256  	lowS, err = IsLowS(&lowLevelKey.PublicKey, s)
   257  	assert.NoError(t, err)
   258  	assert.False(t, lowS)
   259  	s, modified, err := ToLowS(&lowLevelKey.PublicKey, s)
   260  	assert.NoError(t, err)
   261  	assert.True(t, modified)
   262  	lowS, err = IsLowS(&lowLevelKey.PublicKey, s)
   263  	assert.NoError(t, err)
   264  	assert.True(t, lowS)
   265  }
   266  
   267  func TestSignatureToLowS(t *testing.T) {
   268  	lowLevelKey, err := ecdsa.GenerateKey(elliptic.P256(), rand.Reader)
   269  	assert.NoError(t, err)
   270  
   271  	s := new(big.Int)
   272  	s = s.Set(curveHalfOrders[elliptic.P256()])
   273  	s = s.Add(s, big.NewInt(1))
   274  
   275  	lowS, err := IsLowS(&lowLevelKey.PublicKey, s)
   276  	assert.NoError(t, err)
   277  	assert.False(t, lowS)
   278  	sigma, err := MarshalECDSASignature(big.NewInt(1), s)
   279  	assert.NoError(t, err)
   280  	sigma2, err := SignatureToLowS(&lowLevelKey.PublicKey, sigma)
   281  	assert.NoError(t, err)
   282  	_, s, err = UnmarshalECDSASignature(sigma2)
   283  	assert.NoError(t, err)
   284  	lowS, err = IsLowS(&lowLevelKey.PublicKey, s)
   285  	assert.NoError(t, err)
   286  	assert.True(t, lowS)
   287  }