...

Source file src/golang.org/x/crypto/internal/wycheproof/ecdsa_test.go

Documentation: golang.org/x/crypto/internal/wycheproof

     1  // Copyright 2019 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 wycheproof
     6  
     7  import (
     8  	"crypto/ecdsa"
     9  	"math/big"
    10  	"testing"
    11  
    12  	"golang.org/x/crypto/cryptobyte"
    13  	"golang.org/x/crypto/cryptobyte/asn1"
    14  )
    15  
    16  func TestECDSA(t *testing.T) {
    17  	type ASNSignatureTestVector struct {
    18  		// A brief description of the test case
    19  		Comment string `json:"comment"`
    20  		// A list of flags
    21  		Flags []string `json:"flags"`
    22  		// The message to sign
    23  		Msg string `json:"msg"`
    24  		// Test result
    25  		Result string `json:"result"`
    26  		// An ASN.1 encoded signature for msg
    27  		Sig string `json:"sig"`
    28  		// Identifier of the test case
    29  		TcID int `json:"tcId"`
    30  	}
    31  
    32  	type ECPublicKey struct {
    33  		// The EC group used by this public key
    34  		Curve interface{} `json:"curve"`
    35  	}
    36  
    37  	type ECDSATestGroup struct {
    38  		// Unencoded EC public key
    39  		Key *ECPublicKey `json:"key"`
    40  		// DER encoded public key
    41  		KeyDER string `json:"keyDer"`
    42  		// the hash function used for ECDSA
    43  		SHA   string                    `json:"sha"`
    44  		Tests []*ASNSignatureTestVector `json:"tests"`
    45  	}
    46  
    47  	type Root struct {
    48  		TestGroups []*ECDSATestGroup `json:"testGroups"`
    49  	}
    50  
    51  	flagsShouldPass := map[string]bool{
    52  		// An encoded ASN.1 integer missing a leading zero is invalid, but
    53  		// accepted by some implementations.
    54  		"MissingZero": false,
    55  		// A signature using a weaker hash than the EC params is not a security
    56  		// risk, as long as the hash is secure.
    57  		// https://www.imperialviolet.org/2014/05/25/strengthmatching.html
    58  		"WeakHash": true,
    59  	}
    60  
    61  	// supportedCurves is a map of all elliptic curves supported
    62  	// by crypto/elliptic, which can subsequently be parsed and tested.
    63  	supportedCurves := map[string]bool{
    64  		"secp224r1": true,
    65  		"secp256r1": true,
    66  		"secp384r1": true,
    67  		"secp521r1": true,
    68  	}
    69  
    70  	var root Root
    71  	readTestVector(t, "ecdsa_test.json", &root)
    72  	for _, tg := range root.TestGroups {
    73  		curve := tg.Key.Curve.(string)
    74  		if !supportedCurves[curve] {
    75  			continue
    76  		}
    77  		pub := decodePublicKey(tg.KeyDER).(*ecdsa.PublicKey)
    78  		h := parseHash(tg.SHA).New()
    79  		for _, sig := range tg.Tests {
    80  			h.Reset()
    81  			h.Write(decodeHex(sig.Msg))
    82  			hashed := h.Sum(nil)
    83  			sigBytes := decodeHex(sig.Sig)
    84  			got := ecdsa.VerifyASN1(pub, hashed, sigBytes)
    85  			if want := shouldPass(sig.Result, sig.Flags, flagsShouldPass); got != want {
    86  				t.Errorf("tcid: %d, type: %s, comment: %q, VerifyASN1 wanted success: %t", sig.TcID, sig.Result, sig.Comment, want)
    87  			}
    88  
    89  			var r, s big.Int
    90  			var inner cryptobyte.String
    91  			input := cryptobyte.String(sigBytes)
    92  			if !input.ReadASN1(&inner, asn1.SEQUENCE) ||
    93  				!input.Empty() ||
    94  				!inner.ReadASN1Integer(&r) ||
    95  				!inner.ReadASN1Integer(&s) ||
    96  				!inner.Empty() {
    97  				continue
    98  			}
    99  			got = ecdsa.Verify(pub, hashed, &r, &s)
   100  			if want := shouldPass(sig.Result, sig.Flags, flagsShouldPass); got != want {
   101  				t.Errorf("tcid: %d, type: %s, comment: %q, Verify wanted success: %t", sig.TcID, sig.Result, sig.Comment, want)
   102  			}
   103  		}
   104  	}
   105  }
   106  

View as plain text