github.com/gidoBOSSftw5731/go/src@v0.0.0-20210226122457-d24b0edbf019/crypto/ed25519/ed25519_test.go (about)

     1  // Copyright 2016 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 ed25519
     6  
     7  import (
     8  	"bufio"
     9  	"bytes"
    10  	"compress/gzip"
    11  	"crypto"
    12  	"crypto/ed25519/internal/edwards25519"
    13  	"crypto/rand"
    14  	"encoding/hex"
    15  	"os"
    16  	"strings"
    17  	"testing"
    18  )
    19  
    20  type zeroReader struct{}
    21  
    22  func (zeroReader) Read(buf []byte) (int, error) {
    23  	for i := range buf {
    24  		buf[i] = 0
    25  	}
    26  	return len(buf), nil
    27  }
    28  
    29  func TestUnmarshalMarshal(t *testing.T) {
    30  	pub, _, _ := GenerateKey(rand.Reader)
    31  
    32  	var A edwards25519.ExtendedGroupElement
    33  	var pubBytes [32]byte
    34  	copy(pubBytes[:], pub)
    35  	if !A.FromBytes(&pubBytes) {
    36  		t.Fatalf("ExtendedGroupElement.FromBytes failed")
    37  	}
    38  
    39  	var pub2 [32]byte
    40  	A.ToBytes(&pub2)
    41  
    42  	if pubBytes != pub2 {
    43  		t.Errorf("FromBytes(%v)->ToBytes does not round-trip, got %x\n", pubBytes, pub2)
    44  	}
    45  }
    46  
    47  func TestSignVerify(t *testing.T) {
    48  	var zero zeroReader
    49  	public, private, _ := GenerateKey(zero)
    50  
    51  	message := []byte("test message")
    52  	sig := Sign(private, message)
    53  	if !Verify(public, message, sig) {
    54  		t.Errorf("valid signature rejected")
    55  	}
    56  
    57  	wrongMessage := []byte("wrong message")
    58  	if Verify(public, wrongMessage, sig) {
    59  		t.Errorf("signature of different message accepted")
    60  	}
    61  }
    62  
    63  func TestCryptoSigner(t *testing.T) {
    64  	var zero zeroReader
    65  	public, private, _ := GenerateKey(zero)
    66  
    67  	signer := crypto.Signer(private)
    68  
    69  	publicInterface := signer.Public()
    70  	public2, ok := publicInterface.(PublicKey)
    71  	if !ok {
    72  		t.Fatalf("expected PublicKey from Public() but got %T", publicInterface)
    73  	}
    74  
    75  	if !bytes.Equal(public, public2) {
    76  		t.Errorf("public keys do not match: original:%x vs Public():%x", public, public2)
    77  	}
    78  
    79  	message := []byte("message")
    80  	var noHash crypto.Hash
    81  	signature, err := signer.Sign(zero, message, noHash)
    82  	if err != nil {
    83  		t.Fatalf("error from Sign(): %s", err)
    84  	}
    85  
    86  	if !Verify(public, message, signature) {
    87  		t.Errorf("Verify failed on signature from Sign()")
    88  	}
    89  }
    90  
    91  func TestEqual(t *testing.T) {
    92  	public, private, _ := GenerateKey(rand.Reader)
    93  
    94  	if !public.Equal(public) {
    95  		t.Errorf("public key is not equal to itself: %q", public)
    96  	}
    97  	if !public.Equal(crypto.Signer(private).Public()) {
    98  		t.Errorf("private.Public() is not Equal to public: %q", public)
    99  	}
   100  	if !private.Equal(private) {
   101  		t.Errorf("private key is not equal to itself: %q", private)
   102  	}
   103  
   104  	otherPub, otherPriv, _ := GenerateKey(rand.Reader)
   105  	if public.Equal(otherPub) {
   106  		t.Errorf("different public keys are Equal")
   107  	}
   108  	if private.Equal(otherPriv) {
   109  		t.Errorf("different private keys are Equal")
   110  	}
   111  }
   112  
   113  func TestGolden(t *testing.T) {
   114  	// sign.input.gz is a selection of test cases from
   115  	// https://ed25519.cr.yp.to/python/sign.input
   116  	testDataZ, err := os.Open("testdata/sign.input.gz")
   117  	if err != nil {
   118  		t.Fatal(err)
   119  	}
   120  	defer testDataZ.Close()
   121  	testData, err := gzip.NewReader(testDataZ)
   122  	if err != nil {
   123  		t.Fatal(err)
   124  	}
   125  	defer testData.Close()
   126  
   127  	scanner := bufio.NewScanner(testData)
   128  	lineNo := 0
   129  
   130  	for scanner.Scan() {
   131  		lineNo++
   132  
   133  		line := scanner.Text()
   134  		parts := strings.Split(line, ":")
   135  		if len(parts) != 5 {
   136  			t.Fatalf("bad number of parts on line %d", lineNo)
   137  		}
   138  
   139  		privBytes, _ := hex.DecodeString(parts[0])
   140  		pubKey, _ := hex.DecodeString(parts[1])
   141  		msg, _ := hex.DecodeString(parts[2])
   142  		sig, _ := hex.DecodeString(parts[3])
   143  		// The signatures in the test vectors also include the message
   144  		// at the end, but we just want R and S.
   145  		sig = sig[:SignatureSize]
   146  
   147  		if l := len(pubKey); l != PublicKeySize {
   148  			t.Fatalf("bad public key length on line %d: got %d bytes", lineNo, l)
   149  		}
   150  
   151  		var priv [PrivateKeySize]byte
   152  		copy(priv[:], privBytes)
   153  		copy(priv[32:], pubKey)
   154  
   155  		sig2 := Sign(priv[:], msg)
   156  		if !bytes.Equal(sig, sig2[:]) {
   157  			t.Errorf("different signature result on line %d: %x vs %x", lineNo, sig, sig2)
   158  		}
   159  
   160  		if !Verify(pubKey, msg, sig2) {
   161  			t.Errorf("signature failed to verify on line %d", lineNo)
   162  		}
   163  
   164  		priv2 := NewKeyFromSeed(priv[:32])
   165  		if !bytes.Equal(priv[:], priv2) {
   166  			t.Errorf("recreating key pair gave different private key on line %d: %x vs %x", lineNo, priv[:], priv2)
   167  		}
   168  
   169  		if pubKey2 := priv2.Public().(PublicKey); !bytes.Equal(pubKey, pubKey2) {
   170  			t.Errorf("recreating key pair gave different public key on line %d: %x vs %x", lineNo, pubKey, pubKey2)
   171  		}
   172  
   173  		if seed := priv2.Seed(); !bytes.Equal(priv[:32], seed) {
   174  			t.Errorf("recreating key pair gave different seed on line %d: %x vs %x", lineNo, priv[:32], seed)
   175  		}
   176  	}
   177  
   178  	if err := scanner.Err(); err != nil {
   179  		t.Fatalf("error reading test data: %s", err)
   180  	}
   181  }
   182  
   183  func TestMalleability(t *testing.T) {
   184  	// https://tools.ietf.org/html/rfc8032#section-5.1.7 adds an additional test
   185  	// that s be in [0, order). This prevents someone from adding a multiple of
   186  	// order to s and obtaining a second valid signature for the same message.
   187  	msg := []byte{0x54, 0x65, 0x73, 0x74}
   188  	sig := []byte{
   189  		0x7c, 0x38, 0xe0, 0x26, 0xf2, 0x9e, 0x14, 0xaa, 0xbd, 0x05, 0x9a,
   190  		0x0f, 0x2d, 0xb8, 0xb0, 0xcd, 0x78, 0x30, 0x40, 0x60, 0x9a, 0x8b,
   191  		0xe6, 0x84, 0xdb, 0x12, 0xf8, 0x2a, 0x27, 0x77, 0x4a, 0xb0, 0x67,
   192  		0x65, 0x4b, 0xce, 0x38, 0x32, 0xc2, 0xd7, 0x6f, 0x8f, 0x6f, 0x5d,
   193  		0xaf, 0xc0, 0x8d, 0x93, 0x39, 0xd4, 0xee, 0xf6, 0x76, 0x57, 0x33,
   194  		0x36, 0xa5, 0xc5, 0x1e, 0xb6, 0xf9, 0x46, 0xb3, 0x1d,
   195  	}
   196  	publicKey := []byte{
   197  		0x7d, 0x4d, 0x0e, 0x7f, 0x61, 0x53, 0xa6, 0x9b, 0x62, 0x42, 0xb5,
   198  		0x22, 0xab, 0xbe, 0xe6, 0x85, 0xfd, 0xa4, 0x42, 0x0f, 0x88, 0x34,
   199  		0xb1, 0x08, 0xc3, 0xbd, 0xae, 0x36, 0x9e, 0xf5, 0x49, 0xfa,
   200  	}
   201  
   202  	if Verify(publicKey, msg, sig) {
   203  		t.Fatal("non-canonical signature accepted")
   204  	}
   205  }
   206  
   207  func BenchmarkKeyGeneration(b *testing.B) {
   208  	var zero zeroReader
   209  	for i := 0; i < b.N; i++ {
   210  		if _, _, err := GenerateKey(zero); err != nil {
   211  			b.Fatal(err)
   212  		}
   213  	}
   214  }
   215  
   216  func BenchmarkNewKeyFromSeed(b *testing.B) {
   217  	seed := make([]byte, SeedSize)
   218  	b.ReportAllocs()
   219  	for i := 0; i < b.N; i++ {
   220  		_ = NewKeyFromSeed(seed)
   221  	}
   222  }
   223  
   224  func BenchmarkSigning(b *testing.B) {
   225  	var zero zeroReader
   226  	_, priv, err := GenerateKey(zero)
   227  	if err != nil {
   228  		b.Fatal(err)
   229  	}
   230  	message := []byte("Hello, world!")
   231  	b.ReportAllocs()
   232  	b.ResetTimer()
   233  	for i := 0; i < b.N; i++ {
   234  		Sign(priv, message)
   235  	}
   236  }
   237  
   238  func BenchmarkVerification(b *testing.B) {
   239  	var zero zeroReader
   240  	pub, priv, err := GenerateKey(zero)
   241  	if err != nil {
   242  		b.Fatal(err)
   243  	}
   244  	message := []byte("Hello, world!")
   245  	signature := Sign(priv, message)
   246  	b.ResetTimer()
   247  	for i := 0; i < b.N; i++ {
   248  		Verify(pub, message, signature)
   249  	}
   250  }