1// Copyright 2020 Google LLC 2// 3// Licensed under the Apache License, Version 2.0 (the "License"); 4// you may not use this file except in compliance with the License. 5// You may obtain a copy of the License at 6// 7// http://www.apache.org/licenses/LICENSE-2.0 8// 9// Unless required by applicable law or agreed to in writing, software 10// distributed under the License is distributed on an "AS IS" BASIS, 11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12// See the License for the specific language governing permissions and 13// limitations under the License. 14// 15//////////////////////////////////////////////////////////////////////////////// 16 17package subtle_test 18 19import ( 20 "bytes" 21 "crypto/ed25519" 22 "crypto/rand" 23 "encoding/hex" 24 "fmt" 25 "testing" 26 27 subtleSignature "github.com/google/tink/go/signature/subtle" 28 "github.com/google/tink/go/subtle/random" 29 "github.com/google/tink/go/testutil" 30) 31 32func TestED25519Deterministic(t *testing.T) { 33 data := random.GetRandomBytes(20) 34 public, priv, err := ed25519.GenerateKey(rand.Reader) 35 if err != nil { 36 t.Errorf("key generation error: %s", err) 37 } 38 39 // Use the private key and public key directly to create new instances 40 signer, verifier, err := newSignerVerifier(t, &priv, &public) 41 if err != nil { 42 t.Errorf("unexpected error when creating ED25519 Signer and Verifier: %s", err) 43 } 44 sign1, err := signer.Sign(data) 45 if err != nil { 46 t.Errorf("unexpected error when signing: %s", err) 47 } 48 if err := verifier.Verify(sign1, data); err != nil { 49 t.Errorf("unexpected error when verifying: %s", err) 50 } 51 52 sign2, err := signer.Sign(data) 53 if err != nil { 54 t.Errorf("unexpected error when signing: %s", err) 55 } 56 if err := verifier.Verify(sign2, data); err != nil { 57 t.Errorf("unexpected error when verifying: %s", err) 58 } 59 if !bytes.Equal(sign1, sign2) { 60 t.Error("deterministic signature check failure") 61 } 62 63} 64 65func TestEd25519VerifyModifiedSignature(t *testing.T) { 66 data := random.GetRandomBytes(20) 67 public, priv, err := ed25519.GenerateKey(rand.Reader) 68 if err != nil { 69 t.Errorf("key generation error: %s", err) 70 } 71 // Use the private key and public key directly to create new instances 72 signer, verifier, err := newSignerVerifier(t, &priv, &public) 73 if err != nil { 74 t.Fatalf("failed to create new signer verifier: %v", err) 75 } 76 77 sign, err := signer.Sign(data) 78 if err != nil { 79 t.Errorf("unexpected error when signing: %s", err) 80 } 81 82 for i := 0; i < len(sign); i++ { 83 for j := 0; j < 8; j++ { 84 sign[i] = byte(sign[i] ^ (1 << uint32(j))) 85 if err := verifier.Verify(sign, data); err == nil { 86 t.Errorf("unexpected error when verifying: %s", err) 87 } 88 } 89 } 90} 91func TestEd25519VerifyModifiedMessage(t *testing.T) { 92 data := random.GetRandomBytes(20) 93 public, priv, err := ed25519.GenerateKey(rand.Reader) 94 if err != nil { 95 t.Errorf("key generation error: %s", err) 96 } 97 98 // Use the private key and public key directly to create new instances 99 signer, verifier, err := newSignerVerifier(t, &priv, &public) 100 if err != nil { 101 t.Fatalf("failed to create new signer verifier: %v", err) 102 } 103 104 sign, err := signer.Sign(data) 105 if err != nil { 106 t.Errorf("unexpected error when signing: %s", err) 107 } 108 109 for i := 0; i < len(data); i++ { 110 for j := 0; j < 8; j++ { 111 data[i] = byte(data[i] ^ (1 << uint32(j))) 112 if err := verifier.Verify(sign, data); err == nil { 113 t.Errorf("unexpected error when verifying: %s", err) 114 } 115 } 116 } 117} 118func TestED25519SignVerify(t *testing.T) { 119 public, priv, err := ed25519.GenerateKey(rand.Reader) 120 if err != nil { 121 t.Errorf("key generation error: %s", err) 122 } 123 124 // Use the private key and public key directly to create new instances 125 signer, verifier, err := newSignerVerifier(t, &priv, &public) 126 if err != nil { 127 t.Errorf("unexpected error when creating ED25519 Signer and Verifier: %s", err) 128 } 129 for i := 0; i < 100; i++ { 130 data := random.GetRandomBytes(20) 131 signature, err := signer.Sign(data) 132 if err != nil { 133 t.Errorf("unexpected error when signing: %s", err) 134 } 135 if err := verifier.Verify(signature, data); err != nil { 136 t.Errorf("unexpected error when verifying: %s", err) 137 } 138 139 // Use byte slices to create new instances 140 signer, err = subtleSignature.NewED25519Signer(priv[:ed25519.SeedSize]) 141 if err != nil { 142 t.Errorf("unexpected error when creating ED25519 Signer: %s", err) 143 } 144 145 signature, err = signer.Sign(data) 146 if err != nil { 147 t.Errorf("unexpected error when signing: %s", err) 148 } 149 if err = verifier.Verify(signature, data); err != nil { 150 t.Errorf("unexpected error when verifying: %s", err) 151 } 152 } 153 154} 155 156func TestED25519WycheproofCases(t *testing.T) { 157 testutil.SkipTestIfTestSrcDirIsNotSet(t) 158 159 suite := new(ed25519Suite) 160 if err := testutil.PopulateSuite(suite, "eddsa_test.json"); err != nil { 161 t.Fatalf("failed populating suite: %s", err) 162 } 163 for _, group := range suite.TestGroups { 164 private := ed25519.PrivateKey(group.Key.SK) 165 public := ed25519.PrivateKey(group.Key.PK) 166 signer, err := subtleSignature.NewED25519Signer(private) 167 if err != nil { 168 continue 169 } 170 verifier, err := subtleSignature.NewED25519Verifier(public) 171 if err != nil { 172 continue 173 } 174 for _, test := range group.Tests { 175 caseName := fmt.Sprintf("Sign-%s-%s:Case-%d", suite.Algorithm, group.Type, test.CaseID) 176 t.Run(caseName, func(t *testing.T) { 177 got, err := signer.Sign(test.Message) 178 switch test.Result { 179 case "valid": 180 if err != nil { 181 t.Fatalf("ED25519Signer.Sign() failed in a valid test case: %s", err) 182 } 183 if !bytes.Equal(got, test.Signature) { 184 // Ed25519 is deterministic. 185 // Getting an alternative signature may leak the private key. 186 // This is especially the case if an attacker can also learn the valid signature. 187 t.Fatalf("ED25519Signer.Sign() = %s, want = %s", hex.EncodeToString(got), hex.EncodeToString(test.Signature)) 188 } 189 case "invalid": 190 if err == nil && bytes.Equal(got, test.Signature) { 191 t.Fatalf("ED25519Signer.Sign() produced a matching signature in an invalid test case.") 192 } 193 default: 194 t.Fatalf("unrecognized result: %q", test.Result) 195 } 196 }) 197 198 caseName = fmt.Sprintf("Verify-%s-%s:Case-%d", suite.Algorithm, group.Type, test.CaseID) 199 t.Run(caseName, func(t *testing.T) { 200 err := verifier.Verify(test.Signature, test.Message) 201 switch test.Result { 202 case "valid": 203 if err != nil { 204 t.Fatalf("ED25519Verifier.Verify() failed in a valid test case: %s", err) 205 } 206 case "invalid": 207 if err == nil { 208 t.Fatal("ED25519Verifier.Verify() succeeded in an invalid test case.") 209 } 210 default: 211 t.Fatalf("unsupported test result: %q", test.Result) 212 } 213 }) 214 } 215 } 216} 217 218func newSignerVerifier(t *testing.T, pvtKey *ed25519.PrivateKey, pubKey *ed25519.PublicKey) (*subtleSignature.ED25519Signer, *subtleSignature.ED25519Verifier, error) { 219 t.Helper() 220 signer, err := subtleSignature.NewED25519SignerFromPrivateKey(pvtKey) 221 if err != nil { 222 return nil, nil, err 223 } 224 verifier, err := subtleSignature.NewED25519VerifierFromPublicKey(pubKey) 225 if err != nil { 226 return nil, nil, err 227 } 228 return signer, verifier, nil 229} 230