...

Source file src/crypto/ed25519/ed25519_test.go

Documentation: crypto/ed25519

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

View as plain text