Source file src/crypto/ecdsa/ecdsa_test.go

     1  // Copyright 2011 The Go Authors. 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_test
     6  
     7  import (
     8  	"bufio"
     9  	"bytes"
    10  	"compress/bzip2"
    11  	"crypto"
    12  	. "crypto/ecdsa"
    13  	"crypto/elliptic"
    14  	"crypto/internal/cryptotest"
    15  	"crypto/internal/fips140/ecdsa"
    16  	"crypto/rand"
    17  	"crypto/sha1"
    18  	"crypto/sha256"
    19  	"crypto/sha512"
    20  	"crypto/x509"
    21  	"encoding/hex"
    22  	"encoding/json"
    23  	"fmt"
    24  	"hash"
    25  	"io"
    26  	"math/big"
    27  	"os"
    28  	"strings"
    29  	"testing"
    30  
    31  	"golang.org/x/crypto/cryptobyte"
    32  	"golang.org/x/crypto/cryptobyte/asn1"
    33  )
    34  
    35  func testAllCurves(t *testing.T, f func(*testing.T, elliptic.Curve)) {
    36  	tests := []struct {
    37  		name  string
    38  		curve elliptic.Curve
    39  	}{
    40  		{"P256", elliptic.P256()},
    41  		{"P224", elliptic.P224()},
    42  		{"P384", elliptic.P384()},
    43  		{"P521", elliptic.P521()},
    44  		{"P256/Generic", genericParamsForCurve(elliptic.P256())},
    45  	}
    46  	if testing.Short() {
    47  		tests = tests[:1]
    48  	}
    49  	for _, test := range tests {
    50  		curve := test.curve
    51  		cryptotest.TestAllImplementations(t, "ecdsa", func(t *testing.T) {
    52  			t.Run(test.name, func(t *testing.T) {
    53  				t.Parallel()
    54  				f(t, curve)
    55  			})
    56  		})
    57  	}
    58  }
    59  
    60  // genericParamsForCurve returns the dereferenced CurveParams for
    61  // the specified curve. This is used to avoid the logic for
    62  // upgrading a curve to its specific implementation, forcing
    63  // usage of the generic implementation.
    64  func genericParamsForCurve(c elliptic.Curve) *elliptic.CurveParams {
    65  	d := *(c.Params())
    66  	return &d
    67  }
    68  
    69  func TestKeyGeneration(t *testing.T) {
    70  	testAllCurves(t, testKeyGeneration)
    71  }
    72  
    73  func testKeyGeneration(t *testing.T, c elliptic.Curve) {
    74  	priv, err := GenerateKey(c, rand.Reader)
    75  	if err != nil {
    76  		t.Fatal(err)
    77  	}
    78  	if !c.IsOnCurve(priv.PublicKey.X, priv.PublicKey.Y) {
    79  		t.Errorf("public key invalid: %s", err)
    80  	}
    81  }
    82  
    83  func TestSignAndVerify(t *testing.T) {
    84  	testAllCurves(t, testSignAndVerify)
    85  }
    86  
    87  func testSignAndVerify(t *testing.T, c elliptic.Curve) {
    88  	priv, _ := GenerateKey(c, rand.Reader)
    89  
    90  	hashed := []byte("testing")
    91  	r, s, err := Sign(rand.Reader, priv, hashed)
    92  	if err != nil {
    93  		t.Errorf("error signing: %s", err)
    94  		return
    95  	}
    96  
    97  	if !Verify(&priv.PublicKey, hashed, r, s) {
    98  		t.Errorf("Verify failed")
    99  	}
   100  
   101  	hashed[0] ^= 0xff
   102  	if Verify(&priv.PublicKey, hashed, r, s) {
   103  		t.Errorf("Verify always works!")
   104  	}
   105  }
   106  
   107  func TestSignAndVerifyASN1(t *testing.T) {
   108  	testAllCurves(t, testSignAndVerifyASN1)
   109  }
   110  
   111  func TestEmptyHashRejection(t *testing.T) {
   112  	testAllCurves(t, testEmptyHashRejection)
   113  }
   114  
   115  func testEmptyHashRejection(t *testing.T, c elliptic.Curve) {
   116  	priv, err := GenerateKey(c, rand.Reader)
   117  	if err != nil {
   118  		t.Fatal(err)
   119  	}
   120  
   121  	t.Run("SignASN1", func(t *testing.T) {
   122  		_, err := SignASN1(rand.Reader, priv, nil)
   123  		if err == nil {
   124  			t.Fatal("SignASN1 with nil hash should fail")
   125  		}
   126  		if !strings.Contains(err.Error(), "cannot be empty") {
   127  			t.Errorf("unexpected error: %v", err)
   128  		}
   129  
   130  		_, err = SignASN1(rand.Reader, priv, []byte{})
   131  		if err == nil {
   132  			t.Fatal("SignASN1 with empty hash should fail")
   133  		}
   134  		if !strings.Contains(err.Error(), "cannot be empty") {
   135  			t.Errorf("unexpected error: %v", err)
   136  		}
   137  	})
   138  
   139  	t.Run("Sign", func(t *testing.T) {
   140  		_, err := priv.Sign(rand.Reader, nil, nil)
   141  		if err == nil {
   142  			t.Fatal("Sign with nil hash should fail")
   143  		}
   144  		if !strings.Contains(err.Error(), "cannot be empty") {
   145  			t.Errorf("unexpected error: %v", err)
   146  		}
   147  
   148  		_, err = priv.Sign(rand.Reader, []byte{}, nil)
   149  		if err == nil {
   150  			t.Fatal("Sign with empty hash should fail")
   151  		}
   152  		if !strings.Contains(err.Error(), "cannot be empty") {
   153  			t.Errorf("unexpected error: %v", err)
   154  		}
   155  	})
   156  
   157  	t.Run("SignDeterministic", func(t *testing.T) {
   158  		if _, err := priv.Sign(nil, nil, nil); err == nil {
   159  			t.Error("deterministic Sign with nil hash should fail")
   160  		}
   161  		if _, err := priv.Sign(nil, []byte{}, nil); err == nil {
   162  			t.Error("deterministic Sign with empty hash should fail")
   163  		}
   164  	})
   165  
   166  	t.Run("VerifyASN1", func(t *testing.T) {
   167  		// Create a valid signature first
   168  		hash := []byte("test hash")
   169  		sig, err := SignASN1(rand.Reader, priv, hash)
   170  		if err != nil {
   171  			t.Fatal(err)
   172  		}
   173  
   174  		// Verify with nil hash should return false
   175  		if VerifyASN1(&priv.PublicKey, nil, sig) {
   176  			t.Error("VerifyASN1 with nil hash should return false")
   177  		}
   178  
   179  		// Verify with empty hash should return false
   180  		if VerifyASN1(&priv.PublicKey, []byte{}, sig) {
   181  			t.Error("VerifyASN1 with empty hash should return false")
   182  		}
   183  	})
   184  }
   185  
   186  func testSignAndVerifyASN1(t *testing.T, c elliptic.Curve) {
   187  	priv, _ := GenerateKey(c, rand.Reader)
   188  
   189  	hashed := []byte("testing")
   190  	sig, err := SignASN1(rand.Reader, priv, hashed)
   191  	if err != nil {
   192  		t.Errorf("error signing: %s", err)
   193  		return
   194  	}
   195  
   196  	if !VerifyASN1(&priv.PublicKey, hashed, sig) {
   197  		t.Errorf("VerifyASN1 failed")
   198  	}
   199  
   200  	hashed[0] ^= 0xff
   201  	if VerifyASN1(&priv.PublicKey, hashed, sig) {
   202  		t.Errorf("VerifyASN1 always works!")
   203  	}
   204  }
   205  
   206  func TestSignHashLength(t *testing.T) {
   207  	testAllCurves(t, testSignHashLength)
   208  }
   209  
   210  func testSignHashLength(t *testing.T, c elliptic.Curve) {
   211  	priv, err := GenerateKey(c, rand.Reader)
   212  	if err != nil {
   213  		t.Fatal(err)
   214  	}
   215  
   216  	digest := sha256.Sum256([]byte("message"))
   217  
   218  	// opts == nil is allowed and skips the length check.
   219  	if _, err := priv.Sign(rand.Reader, digest[:], nil); err != nil {
   220  		t.Errorf("Sign with nil opts: %v", err)
   221  	}
   222  
   223  	// opts != nil with matching hash length succeeds.
   224  	if _, err := priv.Sign(rand.Reader, digest[:], crypto.SHA256); err != nil {
   225  		t.Errorf("Sign with matching hash: %v", err)
   226  	}
   227  
   228  	// opts != nil with mismatched hash length fails.
   229  	if _, err := priv.Sign(rand.Reader, digest[:], crypto.SHA384); err == nil {
   230  		t.Error("Sign with mismatched hash length should fail")
   231  	}
   232  	if _, err := priv.Sign(rand.Reader, digest[:len(digest)-1], crypto.SHA256); err == nil {
   233  		t.Error("Sign with short digest should fail")
   234  	}
   235  	if _, err := priv.Sign(rand.Reader, nil, crypto.SHA256); err == nil {
   236  		t.Error("Sign with empty digest should fail")
   237  	}
   238  
   239  	// opts.HashFunc() == 0 errors cleanly.
   240  	if _, err := priv.Sign(rand.Reader, digest[:], crypto.Hash(0)); err == nil {
   241  		t.Error("Sign with crypto.Hash(0) should fail")
   242  	}
   243  }
   244  
   245  func TestNonceSafety(t *testing.T) {
   246  	testAllCurves(t, testNonceSafety)
   247  }
   248  
   249  func testNonceSafety(t *testing.T, c elliptic.Curve) {
   250  	priv, _ := GenerateKey(c, rand.Reader)
   251  
   252  	hashed := []byte("testing")
   253  	r0, s0, err := Sign(zeroReader, priv, hashed)
   254  	if err != nil {
   255  		t.Errorf("error signing: %s", err)
   256  		return
   257  	}
   258  
   259  	hashed = []byte("testing...")
   260  	r1, s1, err := Sign(zeroReader, priv, hashed)
   261  	if err != nil {
   262  		t.Errorf("error signing: %s", err)
   263  		return
   264  	}
   265  
   266  	if s0.Cmp(s1) == 0 {
   267  		// This should never happen.
   268  		t.Errorf("the signatures on two different messages were the same")
   269  	}
   270  
   271  	if r0.Cmp(r1) == 0 {
   272  		t.Errorf("the nonce used for two different messages was the same")
   273  	}
   274  }
   275  
   276  type readerFunc func([]byte) (int, error)
   277  
   278  func (f readerFunc) Read(b []byte) (int, error) { return f(b) }
   279  
   280  var zeroReader = readerFunc(func(b []byte) (int, error) {
   281  	clear(b)
   282  	return len(b), nil
   283  })
   284  
   285  func TestINDCCA(t *testing.T) {
   286  	testAllCurves(t, testINDCCA)
   287  }
   288  
   289  func testINDCCA(t *testing.T, c elliptic.Curve) {
   290  	priv, _ := GenerateKey(c, rand.Reader)
   291  
   292  	hashed := []byte("testing")
   293  	r0, s0, err := Sign(rand.Reader, priv, hashed)
   294  	if err != nil {
   295  		t.Errorf("error signing: %s", err)
   296  		return
   297  	}
   298  
   299  	r1, s1, err := Sign(rand.Reader, priv, hashed)
   300  	if err != nil {
   301  		t.Errorf("error signing: %s", err)
   302  		return
   303  	}
   304  
   305  	if s0.Cmp(s1) == 0 {
   306  		t.Errorf("two signatures of the same message produced the same result")
   307  	}
   308  
   309  	if r0.Cmp(r1) == 0 {
   310  		t.Errorf("two signatures of the same message produced the same nonce")
   311  	}
   312  }
   313  
   314  func fromHex(s string) *big.Int {
   315  	r, ok := new(big.Int).SetString(s, 16)
   316  	if !ok {
   317  		panic("bad hex")
   318  	}
   319  	return r
   320  }
   321  
   322  func TestVectors(t *testing.T) {
   323  	cryptotest.TestAllImplementations(t, "ecdsa", testVectors)
   324  }
   325  
   326  func testVectors(t *testing.T) {
   327  	// This test runs the full set of NIST test vectors from
   328  	// https://csrc.nist.gov/groups/STM/cavp/documents/dss/186-3ecdsatestvectors.zip
   329  	//
   330  	// The SigVer.rsp file has been edited to remove test vectors for
   331  	// unsupported algorithms and has been compressed.
   332  
   333  	if testing.Short() {
   334  		return
   335  	}
   336  
   337  	f, err := os.Open("testdata/SigVer.rsp.bz2")
   338  	if err != nil {
   339  		t.Fatal(err)
   340  	}
   341  
   342  	buf := bufio.NewReader(bzip2.NewReader(f))
   343  
   344  	lineNo := 1
   345  	var h hash.Hash
   346  	var msg []byte
   347  	var hashed []byte
   348  	var r, s *big.Int
   349  	pub := new(PublicKey)
   350  
   351  	for {
   352  		line, err := buf.ReadString('\n')
   353  		if len(line) == 0 {
   354  			if err == io.EOF {
   355  				break
   356  			}
   357  			t.Fatalf("error reading from input: %s", err)
   358  		}
   359  		lineNo++
   360  		// Need to remove \r\n from the end of the line.
   361  		if !strings.HasSuffix(line, "\r\n") {
   362  			t.Fatalf("bad line ending (expected \\r\\n) on line %d", lineNo)
   363  		}
   364  		line = line[:len(line)-2]
   365  
   366  		if len(line) == 0 || line[0] == '#' {
   367  			continue
   368  		}
   369  
   370  		if line[0] == '[' {
   371  			line = line[1 : len(line)-1]
   372  			curve, hash, _ := strings.Cut(line, ",")
   373  
   374  			switch curve {
   375  			case "P-224":
   376  				pub.Curve = elliptic.P224()
   377  			case "P-256":
   378  				pub.Curve = elliptic.P256()
   379  			case "P-384":
   380  				pub.Curve = elliptic.P384()
   381  			case "P-521":
   382  				pub.Curve = elliptic.P521()
   383  			default:
   384  				pub.Curve = nil
   385  			}
   386  
   387  			switch hash {
   388  			case "SHA-1":
   389  				h = sha1.New()
   390  			case "SHA-224":
   391  				h = sha256.New224()
   392  			case "SHA-256":
   393  				h = sha256.New()
   394  			case "SHA-384":
   395  				h = sha512.New384()
   396  			case "SHA-512":
   397  				h = sha512.New()
   398  			default:
   399  				h = nil
   400  			}
   401  
   402  			continue
   403  		}
   404  
   405  		if h == nil || pub.Curve == nil {
   406  			continue
   407  		}
   408  
   409  		switch {
   410  		case strings.HasPrefix(line, "Msg = "):
   411  			if msg, err = hex.DecodeString(line[6:]); err != nil {
   412  				t.Fatalf("failed to decode message on line %d: %s", lineNo, err)
   413  			}
   414  		case strings.HasPrefix(line, "Qx = "):
   415  			pub.X = fromHex(line[5:])
   416  		case strings.HasPrefix(line, "Qy = "):
   417  			pub.Y = fromHex(line[5:])
   418  		case strings.HasPrefix(line, "R = "):
   419  			r = fromHex(line[4:])
   420  		case strings.HasPrefix(line, "S = "):
   421  			s = fromHex(line[4:])
   422  		case strings.HasPrefix(line, "Result = "):
   423  			expected := line[9] == 'P'
   424  			h.Reset()
   425  			h.Write(msg)
   426  			hashed := h.Sum(hashed[:0])
   427  			if Verify(pub, hashed, r, s) != expected {
   428  				t.Fatalf("incorrect result on line %d", lineNo)
   429  			}
   430  		default:
   431  			t.Fatalf("unknown variable on line %d: %s", lineNo, line)
   432  		}
   433  	}
   434  }
   435  
   436  func TestNegativeInputs(t *testing.T) {
   437  	testAllCurves(t, testNegativeInputs)
   438  }
   439  
   440  func testNegativeInputs(t *testing.T, curve elliptic.Curve) {
   441  	key, err := GenerateKey(curve, rand.Reader)
   442  	if err != nil {
   443  		t.Errorf("failed to generate key")
   444  	}
   445  
   446  	var hash [32]byte
   447  	r := new(big.Int).SetInt64(1)
   448  	r.Lsh(r, 550 /* larger than any supported curve */)
   449  	r.Neg(r)
   450  
   451  	if Verify(&key.PublicKey, hash[:], r, r) {
   452  		t.Errorf("bogus signature accepted")
   453  	}
   454  }
   455  
   456  func TestZeroHashSignature(t *testing.T) {
   457  	testAllCurves(t, testZeroHashSignature)
   458  }
   459  
   460  func testZeroHashSignature(t *testing.T, curve elliptic.Curve) {
   461  	zeroHash := make([]byte, 64)
   462  
   463  	privKey, err := GenerateKey(curve, rand.Reader)
   464  	if err != nil {
   465  		panic(err)
   466  	}
   467  
   468  	// Sign a hash consisting of all zeros.
   469  	r, s, err := Sign(rand.Reader, privKey, zeroHash)
   470  	if err != nil {
   471  		panic(err)
   472  	}
   473  
   474  	// Confirm that it can be verified.
   475  	if !Verify(&privKey.PublicKey, zeroHash, r, s) {
   476  		t.Errorf("zero hash signature verify failed for %T", curve)
   477  	}
   478  }
   479  
   480  func TestZeroSignature(t *testing.T) {
   481  	testAllCurves(t, testZeroSignature)
   482  }
   483  
   484  func testZeroSignature(t *testing.T, curve elliptic.Curve) {
   485  	privKey, err := GenerateKey(curve, rand.Reader)
   486  	if err != nil {
   487  		panic(err)
   488  	}
   489  
   490  	if Verify(&privKey.PublicKey, make([]byte, 64), big.NewInt(0), big.NewInt(0)) {
   491  		t.Errorf("Verify with r,s=0 succeeded: %T", curve)
   492  	}
   493  }
   494  
   495  func TestNegativeSignature(t *testing.T) {
   496  	testAllCurves(t, testNegativeSignature)
   497  }
   498  
   499  func testNegativeSignature(t *testing.T, curve elliptic.Curve) {
   500  	zeroHash := make([]byte, 64)
   501  
   502  	privKey, err := GenerateKey(curve, rand.Reader)
   503  	if err != nil {
   504  		panic(err)
   505  	}
   506  	r, s, err := Sign(rand.Reader, privKey, zeroHash)
   507  	if err != nil {
   508  		panic(err)
   509  	}
   510  
   511  	r = r.Neg(r)
   512  	if Verify(&privKey.PublicKey, zeroHash, r, s) {
   513  		t.Errorf("Verify with r=-r succeeded: %T", curve)
   514  	}
   515  }
   516  
   517  func TestRPlusNSignature(t *testing.T) {
   518  	testAllCurves(t, testRPlusNSignature)
   519  }
   520  
   521  func testRPlusNSignature(t *testing.T, curve elliptic.Curve) {
   522  	zeroHash := make([]byte, 64)
   523  
   524  	privKey, err := GenerateKey(curve, rand.Reader)
   525  	if err != nil {
   526  		panic(err)
   527  	}
   528  	r, s, err := Sign(rand.Reader, privKey, zeroHash)
   529  	if err != nil {
   530  		panic(err)
   531  	}
   532  
   533  	r = r.Add(r, curve.Params().N)
   534  	if Verify(&privKey.PublicKey, zeroHash, r, s) {
   535  		t.Errorf("Verify with r=r+n succeeded: %T", curve)
   536  	}
   537  }
   538  
   539  func TestRMinusNSignature(t *testing.T) {
   540  	testAllCurves(t, testRMinusNSignature)
   541  }
   542  
   543  func testRMinusNSignature(t *testing.T, curve elliptic.Curve) {
   544  	zeroHash := make([]byte, 64)
   545  
   546  	privKey, err := GenerateKey(curve, rand.Reader)
   547  	if err != nil {
   548  		panic(err)
   549  	}
   550  	r, s, err := Sign(rand.Reader, privKey, zeroHash)
   551  	if err != nil {
   552  		panic(err)
   553  	}
   554  
   555  	r = r.Sub(r, curve.Params().N)
   556  	if Verify(&privKey.PublicKey, zeroHash, r, s) {
   557  		t.Errorf("Verify with r=r-n succeeded: %T", curve)
   558  	}
   559  }
   560  
   561  func TestRFC6979(t *testing.T) {
   562  	t.Run("P-224", func(t *testing.T) {
   563  		testRFC6979(t, elliptic.P224(),
   564  			"F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1",
   565  			"00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
   566  			"EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
   567  			"sample",
   568  			"61AA3DA010E8E8406C656BC477A7A7189895E7E840CDFE8FF42307BA",
   569  			"BC814050DAB5D23770879494F9E0A680DC1AF7161991BDE692B10101")
   570  		testRFC6979(t, elliptic.P224(),
   571  			"F220266E1105BFE3083E03EC7A3A654651F45E37167E88600BF257C1",
   572  			"00CF08DA5AD719E42707FA431292DEA11244D64FC51610D94B130D6C",
   573  			"EEAB6F3DEBE455E3DBF85416F7030CBD94F34F2D6F232C69F3C1385A",
   574  			"test",
   575  			"AD04DDE87B84747A243A631EA47A1BA6D1FAA059149AD2440DE6FBA6",
   576  			"178D49B1AE90E3D8B629BE3DB5683915F4E8C99FDF6E666CF37ADCFD")
   577  	})
   578  	t.Run("P-256", func(t *testing.T) {
   579  		// This vector was bruteforced to find a message that causes the
   580  		// generation of k to loop. It was checked against
   581  		// github.com/codahale/rfc6979 (https://go.dev/play/p/FK5-fmKf7eK),
   582  		// OpenSSL 3.2.0 (https://github.com/openssl/openssl/pull/23130),
   583  		// and python-ecdsa:
   584  		//
   585  		//    ecdsa.keys.SigningKey.from_secret_exponent(
   586  		//        0xC9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721,
   587  		//        ecdsa.curves.curve_by_name("NIST256p"), hashlib.sha256).sign_deterministic(
   588  		//        b"wv[vnX", hashlib.sha256, lambda r, s, order: print(hex(r), hex(s)))
   589  		//
   590  		testRFC6979(t, elliptic.P256(),
   591  			"C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721",
   592  			"60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
   593  			"7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
   594  			"wv[vnX",
   595  			"EFD9073B652E76DA1B5A019C0E4A2E3FA529B035A6ABB91EF67F0ED7A1F21234",
   596  			"3DB4706C9D9F4A4FE13BB5E08EF0FAB53A57DBAB2061C83A35FA411C68D2BA33")
   597  
   598  		// The remaining vectors are from RFC 6979.
   599  		testRFC6979(t, elliptic.P256(),
   600  			"C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721",
   601  			"60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
   602  			"7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
   603  			"sample",
   604  			"EFD48B2AACB6A8FD1140DD9CD45E81D69D2C877B56AAF991C34D0EA84EAF3716",
   605  			"F7CB1C942D657C41D436C7A1B6E29F65F3E900DBB9AFF4064DC4AB2F843ACDA8")
   606  		testRFC6979(t, elliptic.P256(),
   607  			"C9AFA9D845BA75166B5C215767B1D6934E50C3DB36E89B127B8A622B120F6721",
   608  			"60FED4BA255A9D31C961EB74C6356D68C049B8923B61FA6CE669622E60F29FB6",
   609  			"7903FE1008B8BC99A41AE9E95628BC64F2F1B20C2D7E9F5177A3C294D4462299",
   610  			"test",
   611  			"F1ABB023518351CD71D881567B1EA663ED3EFCF6C5132B354F28D3B0B7D38367",
   612  			"019F4113742A2B14BD25926B49C649155F267E60D3814B4C0CC84250E46F0083")
   613  	})
   614  	t.Run("P-384", func(t *testing.T) {
   615  		testRFC6979(t, elliptic.P384(),
   616  			"6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5",
   617  			"EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
   618  			"8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
   619  			"sample",
   620  			"21B13D1E013C7FA1392D03C5F99AF8B30C570C6F98D4EA8E354B63A21D3DAA33BDE1E888E63355D92FA2B3C36D8FB2CD",
   621  			"F3AA443FB107745BF4BD77CB3891674632068A10CA67E3D45DB2266FA7D1FEEBEFDC63ECCD1AC42EC0CB8668A4FA0AB0")
   622  		testRFC6979(t, elliptic.P384(),
   623  			"6B9D3DAD2E1B8C1C05B19875B6659F4DE23C3B667BF297BA9AA47740787137D896D5724E4C70A825F872C9EA60D2EDF5",
   624  			"EC3A4E415B4E19A4568618029F427FA5DA9A8BC4AE92E02E06AAE5286B300C64DEF8F0EA9055866064A254515480BC13",
   625  			"8015D9B72D7D57244EA8EF9AC0C621896708A59367F9DFB9F54CA84B3F1C9DB1288B231C3AE0D4FE7344FD2533264720",
   626  			"test",
   627  			"6D6DEFAC9AB64DABAFE36C6BF510352A4CC27001263638E5B16D9BB51D451559F918EEDAF2293BE5B475CC8F0188636B",
   628  			"2D46F3BECBCC523D5F1A1256BF0C9B024D879BA9E838144C8BA6BAEB4B53B47D51AB373F9845C0514EEFB14024787265")
   629  	})
   630  	t.Run("P-521", func(t *testing.T) {
   631  		testRFC6979(t, elliptic.P521(),
   632  			"0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538",
   633  			"1894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
   634  			"0493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
   635  			"sample",
   636  			"1511BB4D675114FE266FC4372B87682BAECC01D3CC62CF2303C92B3526012659D16876E25C7C1E57648F23B73564D67F61C6F14D527D54972810421E7D87589E1A7",
   637  			"04A171143A83163D6DF460AAF61522695F207A58B95C0644D87E52AA1A347916E4F7A72930B1BC06DBE22CE3F58264AFD23704CBB63B29B931F7DE6C9D949A7ECFC")
   638  		testRFC6979(t, elliptic.P521(),
   639  			"0FAD06DAA62BA3B25D2FB40133DA757205DE67F5BB0018FEE8C86E1B68C7E75CAA896EB32F1F47C70855836A6D16FCC1466F6D8FBEC67DB89EC0C08B0E996B83538",
   640  			"1894550D0785932E00EAA23B694F213F8C3121F86DC97A04E5A7167DB4E5BCD371123D46E45DB6B5D5370A7F20FB633155D38FFA16D2BD761DCAC474B9A2F5023A4",
   641  			"0493101C962CD4D2FDDF782285E64584139C2F91B47F87FF82354D6630F746A28A0DB25741B5B34A828008B22ACC23F924FAAFBD4D33F81EA66956DFEAA2BFDFCF5",
   642  			"test",
   643  			"00E871C4A14F993C6C7369501900C4BC1E9C7B0B4BA44E04868B30B41D8071042EB28C4C250411D0CE08CD197E4188EA4876F279F90B3D8D74A3C76E6F1E4656AA8",
   644  			"0CD52DBAA33B063C3A6CD8058A1FB0A46A4754B034FCC644766CA14DA8CA5CA9FDE00E88C1AD60CCBA759025299079D7A427EC3CC5B619BFBC828E7769BCD694E86")
   645  	})
   646  }
   647  
   648  func testRFC6979(t *testing.T, curve elliptic.Curve, D, X, Y, msg, r, s string) {
   649  	priv := &PrivateKey{
   650  		D: fromHex(D),
   651  		PublicKey: PublicKey{
   652  			Curve: curve,
   653  			X:     fromHex(X),
   654  			Y:     fromHex(Y),
   655  		},
   656  	}
   657  	h := sha256.Sum256([]byte(msg))
   658  	sig, err := priv.Sign(nil, h[:], crypto.SHA256)
   659  	if err != nil {
   660  		t.Fatal(err)
   661  	}
   662  	expected, err := encodeSignature(fromHex(r).Bytes(), fromHex(s).Bytes())
   663  	if err != nil {
   664  		t.Fatal(err)
   665  	}
   666  	if !bytes.Equal(sig, expected) {
   667  		t.Errorf("signature mismatch:\n got: %x\nwant: %x", sig, expected)
   668  	}
   669  }
   670  
   671  func encodeSignature(r, s []byte) ([]byte, error) {
   672  	var b cryptobyte.Builder
   673  	b.AddASN1(asn1.SEQUENCE, func(b *cryptobyte.Builder) {
   674  		addASN1IntBytes(b, r)
   675  		addASN1IntBytes(b, s)
   676  	})
   677  	return b.Bytes()
   678  }
   679  
   680  func addASN1IntBytes(b *cryptobyte.Builder, bytes []byte) {
   681  	for len(bytes) > 0 && bytes[0] == 0 {
   682  		bytes = bytes[1:]
   683  	}
   684  	b.AddASN1(asn1.INTEGER, func(c *cryptobyte.Builder) {
   685  		if bytes[0]&0x80 != 0 {
   686  			c.AddUint8(0)
   687  		}
   688  		c.AddBytes(bytes)
   689  	})
   690  }
   691  
   692  func TestParseAndBytesRoundTrip(t *testing.T) {
   693  	testAllCurves(t, testParseAndBytesRoundTrip)
   694  }
   695  
   696  func testParseAndBytesRoundTrip(t *testing.T, curve elliptic.Curve) {
   697  	if strings.HasSuffix(t.Name(), "/Generic") {
   698  		t.Skip("these methods don't support generic curves")
   699  	}
   700  	priv, _ := GenerateKey(curve, rand.Reader)
   701  
   702  	b, err := priv.PublicKey.Bytes()
   703  	if err != nil {
   704  		t.Fatalf("failed to serialize private key's public key: %v", err)
   705  	}
   706  	if b[0] != 4 {
   707  		t.Fatalf("public key bytes doesn't start with 0x04 (uncompressed format)")
   708  	}
   709  	p, err := ParseUncompressedPublicKey(curve, b)
   710  	if err != nil {
   711  		t.Fatalf("failed to parse private key's public key: %v", err)
   712  	}
   713  	if !priv.PublicKey.Equal(p) {
   714  		t.Errorf("parsed private key's public key doesn't match original")
   715  	}
   716  
   717  	bk, err := priv.Bytes()
   718  	if err != nil {
   719  		t.Fatalf("failed to serialize private key: %v", err)
   720  	}
   721  	k, err := ParseRawPrivateKey(curve, bk)
   722  	if err != nil {
   723  		t.Fatalf("failed to parse private key: %v", err)
   724  	}
   725  	if !priv.Equal(k) {
   726  		t.Errorf("parsed private key doesn't match original")
   727  	}
   728  
   729  	if curve != elliptic.P224() {
   730  		privECDH, err := priv.ECDH()
   731  		if err != nil {
   732  			t.Fatalf("failed to convert private key to ECDH: %v", err)
   733  		}
   734  
   735  		pp, err := privECDH.Curve().NewPublicKey(b)
   736  		if err != nil {
   737  			t.Fatalf("failed to parse with ECDH: %v", err)
   738  		}
   739  		if !privECDH.PublicKey().Equal(pp) {
   740  			t.Errorf("parsed ECDH public key doesn't match original")
   741  		}
   742  		if !bytes.Equal(b, pp.Bytes()) {
   743  			t.Errorf("encoded ECDH public key doesn't match Bytes")
   744  		}
   745  
   746  		kk, err := privECDH.Curve().NewPrivateKey(bk)
   747  		if err != nil {
   748  			t.Fatalf("failed to parse with ECDH: %v", err)
   749  		}
   750  		if !privECDH.Equal(kk) {
   751  			t.Errorf("parsed ECDH private key doesn't match original")
   752  		}
   753  		if !bytes.Equal(bk, kk.Bytes()) {
   754  			t.Errorf("encoded ECDH private key doesn't match Bytes")
   755  		}
   756  	}
   757  }
   758  
   759  func TestInvalidPublicKeys(t *testing.T) {
   760  	testAllCurves(t, testInvalidPublicKeys)
   761  }
   762  
   763  func testInvalidPublicKeys(t *testing.T, curve elliptic.Curve) {
   764  	t.Run("Infinity", func(t *testing.T) {
   765  		k := &PublicKey{Curve: curve, X: big.NewInt(0), Y: big.NewInt(0)}
   766  		if _, err := k.Bytes(); err == nil {
   767  			t.Errorf("PublicKey.Bytes accepted infinity")
   768  		}
   769  
   770  		b := []byte{0}
   771  		if _, err := ParseUncompressedPublicKey(curve, b); err == nil {
   772  			t.Errorf("ParseUncompressedPublicKey accepted infinity")
   773  		}
   774  		b = make([]byte, 1+2*(curve.Params().BitSize+7)/8)
   775  		b[0] = 4
   776  		if _, err := ParseUncompressedPublicKey(curve, b); err == nil {
   777  			t.Errorf("ParseUncompressedPublicKey accepted infinity")
   778  		}
   779  	})
   780  	t.Run("NotOnCurve", func(t *testing.T) {
   781  		k, _ := GenerateKey(curve, rand.Reader)
   782  		k.X = k.X.Add(k.X, big.NewInt(1))
   783  		if _, err := k.Bytes(); err == nil {
   784  			t.Errorf("PublicKey.Bytes accepted not on curve")
   785  		}
   786  
   787  		b := make([]byte, 1+2*(curve.Params().BitSize+7)/8)
   788  		b[0] = 4
   789  		k.X.FillBytes(b[1 : 1+len(b)/2])
   790  		k.Y.FillBytes(b[1+len(b)/2:])
   791  		if _, err := ParseUncompressedPublicKey(curve, b); err == nil {
   792  			t.Errorf("ParseUncompressedPublicKey accepted not on curve")
   793  		}
   794  	})
   795  	t.Run("Compressed", func(t *testing.T) {
   796  		k, _ := GenerateKey(curve, rand.Reader)
   797  		b := elliptic.MarshalCompressed(curve, k.X, k.Y)
   798  		if _, err := ParseUncompressedPublicKey(curve, b); err == nil {
   799  			t.Errorf("ParseUncompressedPublicKey accepted compressed key")
   800  		}
   801  	})
   802  }
   803  
   804  func TestInvalidPrivateKeys(t *testing.T) {
   805  	testAllCurves(t, testInvalidPrivateKeys)
   806  }
   807  
   808  func testInvalidPrivateKeys(t *testing.T, curve elliptic.Curve) {
   809  	t.Run("Zero", func(t *testing.T) {
   810  		k := &PrivateKey{PublicKey{curve, big.NewInt(0), big.NewInt(0)}, big.NewInt(0)}
   811  		if _, err := k.Bytes(); err == nil {
   812  			t.Errorf("PrivateKey.Bytes accepted zero key")
   813  		}
   814  
   815  		b := make([]byte, (curve.Params().BitSize+7)/8)
   816  		if _, err := ParseRawPrivateKey(curve, b); err == nil {
   817  			t.Errorf("ParseRawPrivateKey accepted zero key")
   818  		}
   819  	})
   820  	t.Run("Overflow", func(t *testing.T) {
   821  		d := new(big.Int).Add(curve.Params().N, big.NewInt(5))
   822  		x, y := curve.ScalarBaseMult(d.Bytes())
   823  		k := &PrivateKey{PublicKey{curve, x, y}, d}
   824  		if _, err := k.Bytes(); err == nil {
   825  			t.Errorf("PrivateKey.Bytes accepted overflow key")
   826  		}
   827  
   828  		b := make([]byte, (curve.Params().BitSize+7)/8)
   829  		k.D.FillBytes(b)
   830  		if _, err := ParseRawPrivateKey(curve, b); err == nil {
   831  			t.Errorf("ParseRawPrivateKey accepted overflow key")
   832  		}
   833  	})
   834  	t.Run("Length", func(t *testing.T) {
   835  		b := []byte{1, 2, 3}
   836  		if _, err := ParseRawPrivateKey(curve, b); err == nil {
   837  			t.Errorf("ParseRawPrivateKey accepted short key")
   838  		}
   839  
   840  		b = make([]byte, (curve.Params().BitSize+7)/8)
   841  		b = append(b, []byte{1, 2, 3}...)
   842  		if _, err := ParseRawPrivateKey(curve, b); err == nil {
   843  			t.Errorf("ParseRawPrivateKey accepted long key")
   844  		}
   845  	})
   846  }
   847  
   848  // TestKeyGenerationVectors tests GenerateKey with the deterministic keygen
   849  // vectors of c2sp.org/det-keygen by replacing the default random source with
   850  // the specified DRBG.
   851  func TestKeyGenerationVectors(t *testing.T) {
   852  	var vectors []struct {
   853  		Curve string
   854  		Seed  []byte
   855  		PKCS8 []byte `json:"private_key_pkcs8"`
   856  	}
   857  	f, err := os.Open("testdata/det-keygen.json")
   858  	if err != nil {
   859  		t.Fatalf("failed to open det-keygen.json: %v", err)
   860  	}
   861  	defer f.Close()
   862  	if err := json.NewDecoder(f).Decode(&vectors); err != nil {
   863  		t.Fatalf("failed to decode keygen.json: %v", err)
   864  	}
   865  	for i, v := range vectors {
   866  		t.Run(fmt.Sprintf("%s-%d", v.Curve, i), func(t *testing.T) {
   867  			t.Setenv("GODEBUG", "cryptocustomrand=1")
   868  			var pers []byte
   869  			var curve elliptic.Curve
   870  			switch v.Curve {
   871  			case "secp224r1":
   872  				curve = elliptic.P224()
   873  				pers = []byte("det ECDSA key gen P-224")
   874  			case "secp256r1":
   875  				curve = elliptic.P256()
   876  				pers = []byte("det ECDSA key gen P-256")
   877  			case "secp384r1":
   878  				curve = elliptic.P384()
   879  				pers = []byte("det ECDSA key gen P-384")
   880  			case "secp521r1":
   881  				curve = elliptic.P521()
   882  				pers = []byte("det ECDSA key gen P-521")
   883  			default:
   884  				t.Fatalf("unknown curve: %q", v.Curve)
   885  			}
   886  			drbg := ecdsa.TestingOnlyNewDRBG(sha256.New, v.Seed, nil, pers)
   887  			rng := &keyGenTestReader{next: func(p []byte) error {
   888  				drbg.Generate(p)
   889  				return nil
   890  			}}
   891  			priv, err := GenerateKey(curve, rng)
   892  			if err != nil {
   893  				t.Fatalf("GenerateKey: %v", err)
   894  			}
   895  			der, err := x509.MarshalPKCS8PrivateKey(priv)
   896  			if err != nil {
   897  				t.Fatalf("MarshalPKCS8PrivateKey: %v", err)
   898  			}
   899  			if !bytes.Equal(der, v.PKCS8) {
   900  				t.Errorf("PKCS8 mismatch:\n%s\nvs\n\n%s", hex.Dump(der), hex.Dump(v.PKCS8))
   901  			}
   902  		})
   903  	}
   904  }
   905  
   906  type keyGenTestReader struct {
   907  	next func([]byte) error
   908  }
   909  
   910  func (r *keyGenTestReader) Read(p []byte) (n int, err error) {
   911  	// Neutralize randutil.MaybeReadByte.
   912  	//
   913  	// DO NOT COPY this. We *will* break you. We can do this because we're
   914  	// in the standard library, and can update this along with the
   915  	// GenerateKey implementation if necessary.
   916  	//
   917  	// You have been warned.
   918  	if len(p) == 1 {
   919  		return 1, nil
   920  	}
   921  
   922  	if err := r.next(p); err != nil {
   923  		return 0, err
   924  	}
   925  	return len(p), nil
   926  }
   927  
   928  func benchmarkAllCurves(b *testing.B, f func(*testing.B, elliptic.Curve)) {
   929  	tests := []struct {
   930  		name  string
   931  		curve elliptic.Curve
   932  	}{
   933  		{"P256", elliptic.P256()},
   934  		{"P384", elliptic.P384()},
   935  		{"P521", elliptic.P521()},
   936  	}
   937  	for _, test := range tests {
   938  		curve := test.curve
   939  		b.Run(test.name, func(b *testing.B) {
   940  			f(b, curve)
   941  		})
   942  	}
   943  }
   944  
   945  func BenchmarkSign(b *testing.B) {
   946  	benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
   947  		r := bufio.NewReaderSize(rand.Reader, 1<<15)
   948  		priv, err := GenerateKey(curve, r)
   949  		if err != nil {
   950  			b.Fatal(err)
   951  		}
   952  		hashed := []byte("testing")
   953  
   954  		b.ReportAllocs()
   955  		b.ResetTimer()
   956  		for i := 0; i < b.N; i++ {
   957  			sig, err := SignASN1(r, priv, hashed)
   958  			if err != nil {
   959  				b.Fatal(err)
   960  			}
   961  			// Prevent the compiler from optimizing out the operation.
   962  			hashed[0] = sig[0]
   963  		}
   964  	})
   965  }
   966  
   967  func BenchmarkVerify(b *testing.B) {
   968  	benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
   969  		r := bufio.NewReaderSize(rand.Reader, 1<<15)
   970  		priv, err := GenerateKey(curve, r)
   971  		if err != nil {
   972  			b.Fatal(err)
   973  		}
   974  		hashed := []byte("testing")
   975  		sig, err := SignASN1(r, priv, hashed)
   976  		if err != nil {
   977  			b.Fatal(err)
   978  		}
   979  
   980  		b.ReportAllocs()
   981  		b.ResetTimer()
   982  		for i := 0; i < b.N; i++ {
   983  			if !VerifyASN1(&priv.PublicKey, hashed, sig) {
   984  				b.Fatal("verify failed")
   985  			}
   986  		}
   987  	})
   988  }
   989  
   990  func BenchmarkGenerateKey(b *testing.B) {
   991  	benchmarkAllCurves(b, func(b *testing.B, curve elliptic.Curve) {
   992  		r := bufio.NewReaderSize(rand.Reader, 1<<15)
   993  		b.ReportAllocs()
   994  		b.ResetTimer()
   995  		for i := 0; i < b.N; i++ {
   996  			if _, err := GenerateKey(curve, r); err != nil {
   997  				b.Fatal(err)
   998  			}
   999  		}
  1000  	})
  1001  }
  1002  

View as plain text