xref: /aosp_15_r20/external/tink/go/signature/ed25519_signer_key_manager_test.go (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1// Copyright 2018 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 signature_test
18
19import (
20	"bytes"
21	"crypto/ed25519"
22	"encoding/hex"
23	"fmt"
24	"testing"
25
26	"github.com/google/go-cmp/cmp"
27	"google.golang.org/protobuf/proto"
28	"github.com/google/tink/go/core/registry"
29	"github.com/google/tink/go/internal/internalregistry"
30	"github.com/google/tink/go/signature/subtle"
31	"github.com/google/tink/go/subtle/random"
32	"github.com/google/tink/go/testutil"
33	ed25519pb "github.com/google/tink/go/proto/ed25519_go_proto"
34	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
35)
36
37func TestED25519SignerGetPrimitiveBasic(t *testing.T) {
38	km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL)
39	if err != nil {
40		t.Errorf("cannot obtain ED25519Signer key manager: %s", err)
41	}
42	pvtKey := testutil.NewED25519PrivateKey()
43	serializedKey, _ := proto.Marshal(pvtKey)
44	tmp, err := km.Primitive(serializedKey)
45	if err != nil {
46		t.Errorf("unexpect error in test case: %s ", err)
47	}
48	var s = tmp.(*subtle.ED25519Signer)
49
50	kmPub, err := registry.GetKeyManager(testutil.ED25519VerifierTypeURL)
51	if err != nil {
52		t.Errorf("cannot obtain ED25519Signer key manager: %s", err)
53	}
54	pubKey := pvtKey.PublicKey
55	serializedKey, _ = proto.Marshal(pubKey)
56	tmp, err = kmPub.Primitive(serializedKey)
57	if err != nil {
58		t.Errorf("unexpect error in test case: %s ", err)
59	}
60	var v = tmp.(*subtle.ED25519Verifier)
61
62	data := random.GetRandomBytes(1281)
63	signature, err := s.Sign(data)
64	if err != nil {
65		t.Errorf("unexpected error when signing: %s", err)
66	}
67
68	if err := v.Verify(signature, data); err != nil {
69		t.Errorf("unexpected error when verifying signature: %s", err)
70	}
71
72}
73
74func TestED25519SignGetPrimitiveWithInvalidInput(t *testing.T) {
75	// invalid params
76	km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL)
77	if err != nil {
78		t.Errorf("cannot obtain ED25519Signer key manager: %s", err)
79	}
80
81	// invalid version
82	key := testutil.NewED25519PrivateKey()
83	key.Version = testutil.ED25519SignerKeyVersion + 1
84	serializedKey, _ := proto.Marshal(key)
85	if _, err := km.Primitive(serializedKey); err == nil {
86		t.Errorf("expect an error when version is invalid")
87	}
88	// nil input
89	if _, err := km.Primitive(nil); err == nil {
90		t.Errorf("expect an error when input is nil")
91	}
92	if _, err := km.Primitive([]byte{}); err == nil {
93		t.Errorf("expect an error when input is empty slice")
94	}
95}
96
97func TestED25519SignNewKeyBasic(t *testing.T) {
98	km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL)
99	if err != nil {
100		t.Errorf("cannot obtain ED25519Signer key manager: %s", err)
101	}
102	serializedFormat, _ := proto.Marshal(testutil.NewED25519PrivateKey())
103	tmp, err := km.NewKey(serializedFormat)
104	if err != nil {
105		t.Errorf("unexpected error: %s", err)
106	}
107	key := tmp.(*ed25519pb.Ed25519PrivateKey)
108	if err := validateED25519PrivateKey(key); err != nil {
109		t.Errorf("invalid private key in test case: %s", err)
110	}
111}
112
113func TestED25519PublicKeyDataBasic(t *testing.T) {
114	km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL)
115	if err != nil {
116		t.Errorf("cannot obtain ED25519Signer key manager: %s", err)
117	}
118	pkm, ok := km.(registry.PrivateKeyManager)
119	if !ok {
120		t.Errorf("cannot obtain private key manager")
121	}
122
123	key := testutil.NewED25519PrivateKey()
124	serializedKey, _ := proto.Marshal(key)
125
126	pubKeyData, err := pkm.PublicKeyData(serializedKey)
127	if err != nil {
128		t.Errorf("unexpect error in test case: %s ", err)
129	}
130	if pubKeyData.TypeUrl != testutil.ED25519VerifierTypeURL {
131		t.Errorf("incorrect type url: %s", pubKeyData.TypeUrl)
132	}
133	if pubKeyData.KeyMaterialType != tinkpb.KeyData_ASYMMETRIC_PUBLIC {
134		t.Errorf("incorrect key material type: %d", pubKeyData.KeyMaterialType)
135	}
136	pubKey := new(ed25519pb.Ed25519PublicKey)
137	if err = proto.Unmarshal(pubKeyData.Value, pubKey); err != nil {
138		t.Errorf("invalid public key: %s", err)
139	}
140}
141
142func TestED25519PublicKeyDataWithInvalidInput(t *testing.T) {
143	km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL)
144	if err != nil {
145		t.Errorf("cannot obtain ED25519Signer key manager: %s", err)
146	}
147	pkm, ok := km.(registry.PrivateKeyManager)
148	if !ok {
149		t.Errorf("cannot obtain private key manager")
150	}
151	// modified key
152	key := testutil.NewED25519PrivateKey()
153	serializedKey, _ := proto.Marshal(key)
154	serializedKey[0] = 0
155	if _, err := pkm.PublicKeyData(serializedKey); err == nil {
156		t.Errorf("expect an error when input is a modified serialized key")
157	}
158	// invalid with a single byte
159	if _, err := pkm.PublicKeyData([]byte{42}); err == nil {
160		t.Errorf("expect an error when input is an empty slice")
161	}
162}
163
164func TestED25519KeyMaterialType(t *testing.T) {
165	km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL)
166	if err != nil {
167		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ED25519SignerTypeURL, err)
168	}
169	keyManager, ok := km.(internalregistry.DerivableKeyManager)
170	if !ok {
171		t.Fatalf("key manager is not DerivableKeyManager")
172	}
173	if got, want := keyManager.KeyMaterialType(), tinkpb.KeyData_ASYMMETRIC_PRIVATE; got != want {
174		t.Errorf("KeyMaterialType() = %v, want %v", got, want)
175	}
176}
177
178func TestED25519DeriveKey(t *testing.T) {
179	km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL)
180	if err != nil {
181		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ED25519SignerTypeURL, err)
182	}
183	keyManager, ok := km.(internalregistry.DerivableKeyManager)
184	if !ok {
185		t.Fatalf("key manager is not DerivableKeyManager")
186	}
187	keyFormat, err := proto.Marshal(&ed25519pb.Ed25519KeyFormat{Version: testutil.ED25519SignerKeyVersion})
188	if err != nil {
189		t.Fatalf("proto.Marshal() err = %v, want nil", err)
190	}
191	for _, test := range []struct {
192		name      string
193		keyFormat []byte
194	}{
195		{
196			// nil unmarshals to an empty proto, which implies version = 0.
197			name:      "nil",
198			keyFormat: nil,
199		},
200		{
201			// An empty proto implies version = 0.
202			name:      "empty",
203			keyFormat: []byte{},
204		},
205		{
206			name:      "specified",
207			keyFormat: keyFormat,
208		},
209	} {
210		t.Run(test.name, func(t *testing.T) {
211			rand := random.GetRandomBytes(ed25519.SeedSize)
212			buf := &bytes.Buffer{}
213			buf.Write(rand) // never returns a non-nil error
214			k, err := keyManager.DeriveKey(test.keyFormat, buf)
215			if err != nil {
216				t.Fatalf("keyManager.DeriveKey() err = %v, want nil", err)
217			}
218			key := k.(*ed25519pb.Ed25519PrivateKey)
219			if got, want := len(key.KeyValue), ed25519.SeedSize; got != want {
220				t.Errorf("private key length = %d, want %d", got, want)
221			}
222			if diff := cmp.Diff(key.KeyValue, rand[:ed25519.SeedSize]); diff != "" {
223				t.Errorf("incorrect derived private key: diff = %v", diff)
224			}
225			if got, want := len(key.PublicKey.KeyValue), ed25519.PublicKeySize; got != want {
226				t.Errorf("public key length = %d, want %d", got, want)
227			}
228			if diff := cmp.Diff(key.PublicKey.KeyValue, []byte(ed25519.NewKeyFromSeed(rand))[32:]); diff != "" {
229				t.Errorf("incorrect derived public key: diff = %v", diff)
230			}
231		})
232	}
233}
234
235func TestED25519DeriveKeyFailsWithInvalidKeyFormats(t *testing.T) {
236	km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL)
237	if err != nil {
238		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ED25519SignerTypeURL, err)
239	}
240	keyManager, ok := km.(internalregistry.DerivableKeyManager)
241	if !ok {
242		t.Fatalf("key manager is not DerivableKeyManager")
243	}
244	invalidVersion, err := proto.Marshal(&ed25519pb.Ed25519KeyFormat{Version: 10})
245	if err != nil {
246		t.Fatalf("proto.Marshal() err = %v, want nil", err)
247	}
248	// Proto messages start with a VarInt, which always ends with a byte with the
249	// MSB unset, so 0x80 is invalid.
250	invalidSerialization, err := hex.DecodeString("80")
251	if err != nil {
252		t.Errorf("hex.DecodeString() err = %v, want nil", err)
253	}
254	for _, test := range []struct {
255		name      string
256		keyFormat []byte
257	}{
258		{
259			name:      "invalid version",
260			keyFormat: invalidVersion,
261		},
262		{
263			name:      "invalid serialization",
264			keyFormat: invalidSerialization,
265		},
266	} {
267		t.Run(test.name, func(t *testing.T) {
268			buf := bytes.NewBuffer(random.GetRandomBytes(ed25519.SeedSize))
269			if _, err := keyManager.DeriveKey(test.keyFormat, buf); err == nil {
270				t.Errorf("keyManager.DeriveKey() err = nil, want non-nil")
271			}
272		})
273	}
274}
275
276func TestED25519DeriveKeyFailsWithInsufficientRandomness(t *testing.T) {
277	km, err := registry.GetKeyManager(testutil.ED25519SignerTypeURL)
278	if err != nil {
279		t.Fatalf("registry.GetKeyManager(%q) err = %v, want nil", testutil.ED25519SignerTypeURL, err)
280	}
281	keyManager, ok := km.(internalregistry.DerivableKeyManager)
282	if !ok {
283		t.Fatalf("key manager is not DerivableKeyManager")
284	}
285	keyFormat, err := proto.Marshal(&ed25519pb.Ed25519KeyFormat{Version: 0})
286	if err != nil {
287		t.Fatalf("proto.Marshal() err = %v, want nil", err)
288	}
289	{
290		buf := bytes.NewBuffer(random.GetRandomBytes(ed25519.SeedSize))
291		if _, err := keyManager.DeriveKey(keyFormat, buf); err != nil {
292			t.Errorf("keyManager.DeriveKey() err = %v, want nil", err)
293		}
294	}
295	{
296		insufficientBuf := bytes.NewBuffer(random.GetRandomBytes(ed25519.SeedSize - 1))
297		if _, err := keyManager.DeriveKey(keyFormat, insufficientBuf); err == nil {
298			t.Errorf("keyManager.DeriveKey() err = nil, want non-nil")
299		}
300	}
301}
302
303func validateED25519PrivateKey(key *ed25519pb.Ed25519PrivateKey) error {
304	if key.Version != testutil.ED25519SignerKeyVersion {
305		return fmt.Errorf("incorrect private key's version: expect %d, got %d",
306			testutil.ED25519SignerKeyVersion, key.Version)
307	}
308	publicKey := key.PublicKey
309	if publicKey.Version != testutil.ED25519SignerKeyVersion {
310		return fmt.Errorf("incorrect public key's version: expect %d, got %d",
311			testutil.ED25519SignerKeyVersion, key.Version)
312	}
313
314	signer, err := subtle.NewED25519Signer(key.KeyValue)
315	if err != nil {
316		return fmt.Errorf("unexpected error when creating ED25519Sign: %s", err)
317	}
318
319	verifier, err := subtle.NewED25519Verifier(publicKey.KeyValue)
320	if err != nil {
321		return fmt.Errorf("unexpected error when creating ED25519Verify: %s", err)
322	}
323	for i := 0; i < 100; i++ {
324		data := random.GetRandomBytes(1281)
325		signature, err := signer.Sign(data)
326		if err != nil {
327			return fmt.Errorf("unexpected error when signing: %s", err)
328		}
329
330		if err := verifier.Verify(signature, data); err != nil {
331			return fmt.Errorf("unexpected error when verifying signature: %s", err)
332		}
333	}
334	return nil
335}
336