github.com/guyezi/gofrontend@v0.0.0-20200228202240-7a62a49e62c0/libgo/go/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 TestGolden(t *testing.T) {
    92  	// sign.input.gz is a selection of test cases from
    93  	// https://ed25519.cr.yp.to/python/sign.input
    94  	testDataZ, err := os.Open("testdata/sign.input.gz")
    95  	if err != nil {
    96  		t.Fatal(err)
    97  	}
    98  	defer testDataZ.Close()
    99  	testData, err := gzip.NewReader(testDataZ)
   100  	if err != nil {
   101  		t.Fatal(err)
   102  	}
   103  	defer testData.Close()
   104  
   105  	scanner := bufio.NewScanner(testData)
   106  	lineNo := 0
   107  
   108  	for scanner.Scan() {
   109  		lineNo++
   110  
   111  		line := scanner.Text()
   112  		parts := strings.Split(line, ":")
   113  		if len(parts) != 5 {
   114  			t.Fatalf("bad number of parts on line %d", lineNo)
   115  		}
   116  
   117  		privBytes, _ := hex.DecodeString(parts[0])
   118  		pubKey, _ := hex.DecodeString(parts[1])
   119  		msg, _ := hex.DecodeString(parts[2])
   120  		sig, _ := hex.DecodeString(parts[3])
   121  		// The signatures in the test vectors also include the message
   122  		// at the end, but we just want R and S.
   123  		sig = sig[:SignatureSize]
   124  
   125  		if l := len(pubKey); l != PublicKeySize {
   126  			t.Fatalf("bad public key length on line %d: got %d bytes", lineNo, l)
   127  		}
   128  
   129  		var priv [PrivateKeySize]byte
   130  		copy(priv[:], privBytes)
   131  		copy(priv[32:], pubKey)
   132  
   133  		sig2 := Sign(priv[:], msg)
   134  		if !bytes.Equal(sig, sig2[:]) {
   135  			t.Errorf("different signature result on line %d: %x vs %x", lineNo, sig, sig2)
   136  		}
   137  
   138  		if !Verify(pubKey, msg, sig2) {
   139  			t.Errorf("signature failed to verify on line %d", lineNo)
   140  		}
   141  
   142  		priv2 := NewKeyFromSeed(priv[:32])
   143  		if !bytes.Equal(priv[:], priv2) {
   144  			t.Errorf("recreating key pair gave different private key on line %d: %x vs %x", lineNo, priv[:], priv2)
   145  		}
   146  
   147  		if pubKey2 := priv2.Public().(PublicKey); !bytes.Equal(pubKey, pubKey2) {
   148  			t.Errorf("recreating key pair gave different public key on line %d: %x vs %x", lineNo, pubKey, pubKey2)
   149  		}
   150  
   151  		if seed := priv2.Seed(); !bytes.Equal(priv[:32], seed) {
   152  			t.Errorf("recreating key pair gave different seed on line %d: %x vs %x", lineNo, priv[:32], seed)
   153  		}
   154  	}
   155  
   156  	if err := scanner.Err(); err != nil {
   157  		t.Fatalf("error reading test data: %s", err)
   158  	}
   159  }
   160  
   161  func TestMalleability(t *testing.T) {
   162  	// https://tools.ietf.org/html/rfc8032#section-5.1.7 adds an additional test
   163  	// that s be in [0, order). This prevents someone from adding a multiple of
   164  	// order to s and obtaining a second valid signature for the same message.
   165  	msg := []byte{0x54, 0x65, 0x73, 0x74}
   166  	sig := []byte{
   167  		0x7c, 0x38, 0xe0, 0x26, 0xf2, 0x9e, 0x14, 0xaa, 0xbd, 0x05, 0x9a,
   168  		0x0f, 0x2d, 0xb8, 0xb0, 0xcd, 0x78, 0x30, 0x40, 0x60, 0x9a, 0x8b,
   169  		0xe6, 0x84, 0xdb, 0x12, 0xf8, 0x2a, 0x27, 0x77, 0x4a, 0xb0, 0x67,
   170  		0x65, 0x4b, 0xce, 0x38, 0x32, 0xc2, 0xd7, 0x6f, 0x8f, 0x6f, 0x5d,
   171  		0xaf, 0xc0, 0x8d, 0x93, 0x39, 0xd4, 0xee, 0xf6, 0x76, 0x57, 0x33,
   172  		0x36, 0xa5, 0xc5, 0x1e, 0xb6, 0xf9, 0x46, 0xb3, 0x1d,
   173  	}
   174  	publicKey := []byte{
   175  		0x7d, 0x4d, 0x0e, 0x7f, 0x61, 0x53, 0xa6, 0x9b, 0x62, 0x42, 0xb5,
   176  		0x22, 0xab, 0xbe, 0xe6, 0x85, 0xfd, 0xa4, 0x42, 0x0f, 0x88, 0x34,
   177  		0xb1, 0x08, 0xc3, 0xbd, 0xae, 0x36, 0x9e, 0xf5, 0x49, 0xfa,
   178  	}
   179  
   180  	if Verify(publicKey, msg, sig) {
   181  		t.Fatal("non-canonical signature accepted")
   182  	}
   183  }
   184  
   185  func BenchmarkKeyGeneration(b *testing.B) {
   186  	var zero zeroReader
   187  	for i := 0; i < b.N; i++ {
   188  		if _, _, err := GenerateKey(zero); err != nil {
   189  			b.Fatal(err)
   190  		}
   191  	}
   192  }
   193  
   194  func BenchmarkNewKeyFromSeed(b *testing.B) {
   195  	seed := make([]byte, SeedSize)
   196  	b.ReportAllocs()
   197  	for i := 0; i < b.N; i++ {
   198  		_ = NewKeyFromSeed(seed)
   199  	}
   200  }
   201  
   202  func BenchmarkSigning(b *testing.B) {
   203  	var zero zeroReader
   204  	_, priv, err := GenerateKey(zero)
   205  	if err != nil {
   206  		b.Fatal(err)
   207  	}
   208  	message := []byte("Hello, world!")
   209  	b.ReportAllocs()
   210  	b.ResetTimer()
   211  	for i := 0; i < b.N; i++ {
   212  		Sign(priv, message)
   213  	}
   214  }
   215  
   216  func BenchmarkVerification(b *testing.B) {
   217  	var zero zeroReader
   218  	pub, priv, err := GenerateKey(zero)
   219  	if err != nil {
   220  		b.Fatal(err)
   221  	}
   222  	message := []byte("Hello, world!")
   223  	signature := Sign(priv, message)
   224  	b.ResetTimer()
   225  	for i := 0; i < b.N; i++ {
   226  		Verify(pub, message, signature)
   227  	}
   228  }