1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154
|
// Copyright 2012 The Go Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package ed25519
import (
"bufio"
"bytes"
"compress/gzip"
"crypto/rand"
"encoding/hex"
"io"
"os"
"strings"
"testing"
)
func TestSignVerify(t *testing.T) {
secretKey, publicKey := GenerateKey([32]byte{})
message := []byte("test message")
sig := Sign(secretKey, message)
if !Verify(publicKey, message, sig) {
t.Errorf("valid signature rejected")
}
wrongMessage := []byte("wrong message")
if Verify(publicKey, wrongMessage, sig) {
t.Errorf("signature of different message accepted")
}
}
func TestGolden(t *testing.T) {
// sign.input.gz is a selection of test cases from
// http://ed25519.cr.yp.to/python/sign.input
testDataZ, err := os.Open("testdata.gz")
if err != nil {
t.Fatal(err)
}
defer testDataZ.Close()
testData, err := gzip.NewReader(testDataZ)
if err != nil {
t.Fatal(err)
}
defer testData.Close()
in := bufio.NewReaderSize(testData, 1<<12)
lineNo := 0
for {
lineNo++
lineBytes, isPrefix, err := in.ReadLine()
if isPrefix {
t.Fatal("bufio buffer too small")
}
if err != nil {
if err == io.EOF {
break
}
t.Fatalf("error reading test data: %s", err)
}
line := string(lineBytes)
parts := strings.Split(line, ":")
if len(parts) != 5 {
t.Fatalf("bad number of parts on line %d", lineNo)
}
privBytes, _ := hex.DecodeString(parts[0])
pubKeyBytes, _ := hex.DecodeString(parts[1])
msg, _ := hex.DecodeString(parts[2])
sig, _ := hex.DecodeString(parts[3])
// The signatures in the test vectors also include the message
// at the end, but we just want R and S.
sig = sig[:SignatureSize]
if l := len(pubKeyBytes); l != PublicKeySize {
t.Fatalf("bad public key length on line %d: got %d bytes", lineNo, l)
}
priv := new([SecretKeySize]byte)
pub := new([PublicKeySize]byte)
copy(priv[:], privBytes)
copy(priv[32:], pubKeyBytes)
copy(pub[:], pubKeyBytes)
sig2 := Sign(priv, msg)
if !bytes.Equal(sig, sig2[:]) {
t.Errorf("different signature result on line %d: %x vs %x", lineNo, sig, sig2)
}
if !Verify(pub, msg, sig2) {
t.Errorf("signature failed to verify on line %d", lineNo)
}
}
}
func BenchmarkGenerateKeys(b *testing.B) {
var entropy [32]byte
for i := 0; i < b.N; i++ {
_, err := rand.Read(entropy[:])
if err != nil {
panic(err)
}
_, _ = GenerateKey(entropy)
}
}
func BenchmarkSign(b *testing.B) {
var entropy [32]byte
_, err := rand.Read(entropy[:])
if err != nil {
panic(err)
}
sk, _ := GenerateKey(entropy)
var secret [64]byte
copy(secret[:], sk[:])
b.ResetTimer()
message := make([]byte, 64)
for i := 0; i < b.N; i++ {
_, err := rand.Read(message)
if err != nil {
panic(err)
}
_ = Sign(sk, message)
}
}
func BenchmarkVerify(b *testing.B) {
var entropy [32]byte
_, err := rand.Read(entropy[:])
if err != nil {
panic(err)
}
sk, pk := GenerateKey(entropy)
b.ResetTimer()
message := make([]byte, 64)
for i := 0; i < b.N; i++ {
b.StopTimer()
_, err := rand.Read(message)
if err != nil {
panic(err)
}
sig := Sign(sk, message)
b.StartTimer()
ver := Verify(pk, message, sig)
if !ver {
panic(err)
}
}
}
|