xref: /aosp_15_r20/external/tink/go/signature/subtle/ed25519_signer_verifier_test.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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