xref: /aosp_15_r20/external/tink/go/testutil/testutil.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
17// Package testutil provides common methods needed in test code.
18package testutil
19
20import (
21	"bytes"
22	"crypto/ecdsa"
23	"crypto/ed25519"
24	"crypto/rand"
25	"encoding/gob"
26	"errors"
27	"fmt"
28	"log"
29	"math"
30	"strconv"
31	"strings"
32
33	"google.golang.org/protobuf/proto"
34	"github.com/google/tink/go/core/registry"
35	subtledaead "github.com/google/tink/go/daead/subtle"
36	subtlehybrid "github.com/google/tink/go/hybrid/subtle"
37	"github.com/google/tink/go/keyset"
38	"github.com/google/tink/go/mac"
39	"github.com/google/tink/go/subtle/random"
40	"github.com/google/tink/go/subtle"
41	"github.com/google/tink/go/tink"
42
43	cmacpb "github.com/google/tink/go/proto/aes_cmac_go_proto"
44	aescmacprfpb "github.com/google/tink/go/proto/aes_cmac_prf_go_proto"
45	ctrhmacpb "github.com/google/tink/go/proto/aes_ctr_hmac_streaming_go_proto"
46	gcmpb "github.com/google/tink/go/proto/aes_gcm_go_proto"
47	gcmhkdfpb "github.com/google/tink/go/proto/aes_gcm_hkdf_streaming_go_proto"
48	gcmsivpb "github.com/google/tink/go/proto/aes_gcm_siv_go_proto"
49	aspb "github.com/google/tink/go/proto/aes_siv_go_proto"
50	commonpb "github.com/google/tink/go/proto/common_go_proto"
51	ecdsapb "github.com/google/tink/go/proto/ecdsa_go_proto"
52	eciespb "github.com/google/tink/go/proto/ecies_aead_hkdf_go_proto"
53	ed25519pb "github.com/google/tink/go/proto/ed25519_go_proto"
54	hkdfprfpb "github.com/google/tink/go/proto/hkdf_prf_go_proto"
55	hmacpb "github.com/google/tink/go/proto/hmac_go_proto"
56	hmacprfpb "github.com/google/tink/go/proto/hmac_prf_go_proto"
57	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
58)
59
60// DummyAEADKeyManager is a dummy implementation of the KeyManager interface.
61// It returns DummyAEAD when GetPrimitive() functions are called.
62type DummyAEADKeyManager struct{}
63
64var _ registry.KeyManager = (*DummyAEADKeyManager)(nil)
65
66// Primitive constructs a primitive instance for the key given in
67// serializedKey, which must be a serialized key protocol buffer handled by this manager.
68func (km *DummyAEADKeyManager) Primitive(serializedKey []byte) (interface{}, error) {
69	return new(DummyAEAD), nil
70}
71
72// NewKey generates a new key according to specification in serializedKeyFormat.
73func (km *DummyAEADKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) {
74	return nil, fmt.Errorf("not implemented")
75}
76
77// NewKeyData generates a new KeyData according to specification in serializedkeyFormat.
78func (km *DummyAEADKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) {
79	return nil, fmt.Errorf("not implemented")
80}
81
82// DoesSupport returns true iff this KeyManager supports key type identified by typeURL.
83func (km *DummyAEADKeyManager) DoesSupport(typeURL string) bool {
84	return typeURL == AESGCMTypeURL
85}
86
87// TypeURL returns the type URL.
88func (km *DummyAEADKeyManager) TypeURL() string {
89	return AESGCMTypeURL
90}
91
92// DummyAEAD is a dummy implementation of AEAD interface. It "encrypts" data
93// with a simple serialization capturing the dummy name, plaintext, and
94// associated data, and "decrypts" it by reversing this and checking that the
95// name and associated data match.
96type DummyAEAD struct {
97	Name string
98}
99
100type dummyAEADData struct {
101	Name           string
102	Plaintext      []byte
103	AssociatedData []byte
104}
105
106// Encrypt encrypts the plaintext.
107func (a *DummyAEAD) Encrypt(plaintext []byte, associatedData []byte) ([]byte, error) {
108	buf := new(bytes.Buffer)
109	encoder := gob.NewEncoder(buf)
110	err := encoder.Encode(dummyAEADData{
111		Name:           a.Name,
112		Plaintext:      plaintext,
113		AssociatedData: associatedData,
114	})
115	if err != nil {
116		return nil, fmt.Errorf("dummy aead encrypt: %v", err)
117	}
118	return buf.Bytes(), nil
119}
120
121// Decrypt decrypts the ciphertext.
122func (a *DummyAEAD) Decrypt(ciphertext []byte, associatedData []byte) ([]byte, error) {
123	data := dummyAEADData{}
124	decoder := gob.NewDecoder(bytes.NewBuffer(ciphertext))
125	if err := decoder.Decode(&data); err != nil {
126		return nil, fmt.Errorf("dummy aead decrypt: invalid data: %v", err)
127	}
128	if data.Name != a.Name || !bytes.Equal(data.AssociatedData, associatedData) {
129		return nil, errors.New("dummy aead encrypt: name/associated data mismatch")
130	}
131	return data.Plaintext, nil
132}
133
134// AlwaysFailingAead fails encryption and decryption operations.
135type AlwaysFailingAead struct {
136	Error error
137}
138
139var _ (tink.AEAD) = (*AlwaysFailingAead)(nil)
140
141// NewAlwaysFailingAead creates a new always failing AEAD.
142func NewAlwaysFailingAead(err error) tink.AEAD {
143	return &AlwaysFailingAead{Error: err}
144}
145
146// Encrypt returns an error on encryption.
147func (a *AlwaysFailingAead) Encrypt(plaintext []byte, associatedData []byte) ([]byte, error) {
148	return nil, fmt.Errorf("AlwaysFailingAead will always fail on encryption: %v", a.Error)
149}
150
151// Decrypt returns an error on decryption.
152func (a *AlwaysFailingAead) Decrypt(ciphertext []byte, associatedData []byte) ([]byte, error) {
153	return nil, fmt.Errorf("AlwaysFailingAead will always fail on decryption: %v", a.Error)
154}
155
156// AlwaysFailingDeterministicAead fails encryption and decryption operations.
157type AlwaysFailingDeterministicAead struct {
158	Error error
159}
160
161var _ (tink.DeterministicAEAD) = (*AlwaysFailingDeterministicAead)(nil)
162
163// NewAlwaysFailingDeterministicAead creates a new always failing AEAD.
164func NewAlwaysFailingDeterministicAead(err error) tink.DeterministicAEAD {
165	return &AlwaysFailingDeterministicAead{Error: err}
166}
167
168// EncryptDeterministically returns an error on encryption.
169func (a *AlwaysFailingDeterministicAead) EncryptDeterministically(plaintext []byte, associatedData []byte) ([]byte, error) {
170	return nil, fmt.Errorf("AlwaysFailingDeterministicAead will always fail on encryption: %v", a.Error)
171}
172
173// DecryptDeterministically returns an error on decryption.
174func (a *AlwaysFailingDeterministicAead) DecryptDeterministically(ciphertext []byte, associatedData []byte) ([]byte, error) {
175	return nil, fmt.Errorf("AlwaysFailingDeterministicAead will always fail on decryption: %v", a.Error)
176}
177
178// TestKeyManager is key manager which can be setup to return an arbitrary primitive for a type URL
179// useful for testing.
180type TestKeyManager struct {
181	primitive interface{}
182	typeURL   string
183}
184
185var _ registry.KeyManager = (*TestKeyManager)(nil)
186
187// NewTestKeyManager creates a new key manager that returns a specific primitive for a typeURL.
188func NewTestKeyManager(primitive interface{}, typeURL string) registry.KeyManager {
189	return &TestKeyManager{
190		primitive: primitive,
191		typeURL:   typeURL,
192	}
193}
194
195// Primitive constructs a primitive instance for the key given input key.
196func (km *TestKeyManager) Primitive(serializedKey []byte) (interface{}, error) {
197	return km.primitive, nil
198}
199
200// NewKey generates a new key according to specification in serializedKeyFormat.
201func (km *TestKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) {
202	return nil, fmt.Errorf("TestKeyManager: not implemented")
203}
204
205// NewKeyData generates a new KeyData according to specification in serializedkeyFormat.
206func (km *TestKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) {
207	return nil, fmt.Errorf("TestKeyManager: not implemented")
208}
209
210// DoesSupport returns true if this KeyManager supports key type identified by typeURL.
211func (km *TestKeyManager) DoesSupport(typeURL string) bool {
212	return typeURL == km.typeURL
213}
214
215// TypeURL returns the type URL.
216func (km *TestKeyManager) TypeURL() string {
217	return km.typeURL
218}
219
220// DummySigner is a dummy implementation of the Signer interface.
221type DummySigner struct {
222	aead DummyAEAD
223}
224
225// NewDummySigner creates a new dummy signer with the specified name. The name
226// is used to pair with the DummyVerifier.
227func NewDummySigner(name string) *DummySigner {
228	return &DummySigner{DummyAEAD{Name: "dummy public key:" + name}}
229}
230
231// Sign signs data.
232func (s *DummySigner) Sign(data []byte) ([]byte, error) {
233	return s.aead.Encrypt(nil, data)
234}
235
236// DummyVerifier is a dummy implementation of the Signer interface.
237type DummyVerifier struct {
238	aead DummyAEAD
239}
240
241// Verify verifies data.
242func (v *DummyVerifier) Verify(sig, data []byte) error {
243	_, err := v.aead.Decrypt(sig, data)
244	return err
245}
246
247// NewDummyVerifier creates a new dummy verifier with the specified name. The
248// name is used to pair with the DummySigner.
249func NewDummyVerifier(name string) *DummyVerifier {
250	return &DummyVerifier{DummyAEAD{Name: "dummy public key:" + name}}
251}
252
253// DummyMAC is a dummy implementation of Mac interface.
254type DummyMAC struct {
255	Name string
256}
257
258// ComputeMAC computes a message authentication code (MAC) for data.
259func (h *DummyMAC) ComputeMAC(data []byte) ([]byte, error) {
260	var m []byte
261	m = append(m, data...)
262	m = append(m, h.Name...)
263	return m, nil
264}
265
266// VerifyMAC verifies whether mac is a correct message authentication code
267// (MAC) for data.
268func (h *DummyMAC) VerifyMAC(mac []byte, data []byte) error {
269	return nil
270}
271
272// DummyKMSClient is a dummy implementation of a KMS Client.
273type DummyKMSClient struct{}
274
275var _ registry.KMSClient = (*DummyKMSClient)(nil)
276
277// Supported true if this client does support keyURI
278func (d *DummyKMSClient) Supported(keyURI string) bool {
279	return keyURI == "dummy"
280}
281
282// GetAEAD gets an Aead backend by keyURI.
283func (d *DummyKMSClient) GetAEAD(keyURI string) (tink.AEAD, error) {
284	return &DummyAEAD{}, nil
285}
286
287// NewTestAESGCMKeyset creates a new Keyset containing an AESGCMKey.
288func NewTestAESGCMKeyset(primaryOutputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset {
289	keyData := NewAESGCMKeyData(16)
290	return NewTestKeyset(keyData, primaryOutputPrefixType)
291}
292
293// NewTestAESGCMSIVKeyset creates a new Keyset containing an AESGCMSIVKey.
294func NewTestAESGCMSIVKeyset(primaryOutputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset {
295	keyData := NewAESGCMSIVKeyData(16)
296	return NewTestKeyset(keyData, primaryOutputPrefixType)
297}
298
299// NewTestAESSIVKeyset creates a new Keyset containing an AesSivKey.
300func NewTestAESSIVKeyset(primaryOutputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset {
301	keyValue := random.GetRandomBytes(subtledaead.AESSIVKeySize)
302	key := &aspb.AesSivKey{
303		Version:  AESSIVKeyVersion,
304		KeyValue: keyValue,
305	}
306	serializedKey, err := proto.Marshal(key)
307	if err != nil {
308		log.Fatalf("failed serializing proto: %v", err)
309	}
310	keyData := NewKeyData(AESSIVTypeURL, serializedKey, tinkpb.KeyData_SYMMETRIC)
311	return NewTestKeyset(keyData, primaryOutputPrefixType)
312}
313
314// NewTestHMACKeyset creates a new Keyset containing a HMACKey.
315func NewTestHMACKeyset(tagSize uint32, primaryOutputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset {
316	keyData := NewHMACKeyData(commonpb.HashType_SHA256, tagSize)
317	return NewTestKeyset(keyData, primaryOutputPrefixType)
318}
319
320// NewTestAESGCMHKDFKeyset creates a new Keyset containing an AESGCMHKDFKey.
321func NewTestAESGCMHKDFKeyset() *tinkpb.Keyset {
322	const (
323		keySize               = 16
324		derivedKeySize        = 16
325		ciphertextSegmentSize = 4096
326	)
327	keyData := NewAESGCMHKDFKeyData(keySize, derivedKeySize, commonpb.HashType_SHA256, ciphertextSegmentSize)
328	return NewTestKeyset(keyData, tinkpb.OutputPrefixType_RAW)
329}
330
331// NewTestKeyset creates a new test Keyset.
332func NewTestKeyset(keyData *tinkpb.KeyData, primaryOutputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset {
333	primaryKey := NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 42, primaryOutputPrefixType)
334	rawKey := NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 43, tinkpb.OutputPrefixType_RAW)
335	legacyKey := NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 44, tinkpb.OutputPrefixType_LEGACY)
336	tinkKey := NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 45, tinkpb.OutputPrefixType_TINK)
337	crunchyKey := NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 46, tinkpb.OutputPrefixType_CRUNCHY)
338	keys := []*tinkpb.Keyset_Key{primaryKey, rawKey, legacyKey, tinkKey, crunchyKey}
339	return NewKeyset(primaryKey.KeyId, keys)
340}
341
342// NewDummyKey returns a dummy key that doesn't contain actual key material.
343func NewDummyKey(keyID int, status tinkpb.KeyStatusType, outputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset_Key {
344	return &tinkpb.Keyset_Key{
345		KeyData:          new(tinkpb.KeyData),
346		Status:           status,
347		KeyId:            uint32(keyID),
348		OutputPrefixType: outputPrefixType,
349	}
350}
351
352// NewECDSAParams creates a ECDSAParams with the specified parameters.
353func NewECDSAParams(hashType commonpb.HashType, curve commonpb.EllipticCurveType, encoding ecdsapb.EcdsaSignatureEncoding) *ecdsapb.EcdsaParams {
354	return &ecdsapb.EcdsaParams{
355		HashType: hashType,
356		Curve:    curve,
357		Encoding: encoding,
358	}
359}
360
361// NewECDSAKeyFormat creates a ECDSAKeyFormat with the specified parameters.
362func NewECDSAKeyFormat(params *ecdsapb.EcdsaParams) *ecdsapb.EcdsaKeyFormat {
363	return &ecdsapb.EcdsaKeyFormat{Params: params}
364}
365
366// NewECDSAPrivateKey creates a ECDSAPrivateKey with the specified paramaters.
367func NewECDSAPrivateKey(version uint32, publicKey *ecdsapb.EcdsaPublicKey, keyValue []byte) *ecdsapb.EcdsaPrivateKey {
368	return &ecdsapb.EcdsaPrivateKey{
369		Version:   version,
370		PublicKey: publicKey,
371		KeyValue:  keyValue,
372	}
373}
374
375// NewECDSAPublicKey creates a ECDSAPublicKey with the specified paramaters.
376func NewECDSAPublicKey(version uint32, params *ecdsapb.EcdsaParams, x, y []byte) *ecdsapb.EcdsaPublicKey {
377	return &ecdsapb.EcdsaPublicKey{
378		Version: version,
379		Params:  params,
380		X:       x,
381		Y:       y,
382	}
383}
384
385// NewRandomECDSAPrivateKey creates an ECDSAPrivateKey with randomly generated key material.
386func NewRandomECDSAPrivateKey(hashType commonpb.HashType, curve commonpb.EllipticCurveType) *ecdsapb.EcdsaPrivateKey {
387	curveName := commonpb.EllipticCurveType_name[int32(curve)]
388	priv, _ := ecdsa.GenerateKey(subtle.GetCurve(curveName), rand.Reader)
389	params := NewECDSAParams(hashType, curve, ecdsapb.EcdsaSignatureEncoding_DER)
390	publicKey := NewECDSAPublicKey(ECDSAVerifierKeyVersion, params, priv.X.Bytes(), priv.Y.Bytes())
391	return NewECDSAPrivateKey(ECDSASignerKeyVersion, publicKey, priv.D.Bytes())
392}
393
394// NewRandomECDSAPublicKey creates an ECDSAPublicKey with randomly generated key material.
395func NewRandomECDSAPublicKey(hashType commonpb.HashType, curve commonpb.EllipticCurveType) *ecdsapb.EcdsaPublicKey {
396	return NewRandomECDSAPrivateKey(hashType, curve).PublicKey
397}
398
399// GetECDSAParamNames returns the string representations of each parameter in
400// the given ECDSAParams.
401func GetECDSAParamNames(params *ecdsapb.EcdsaParams) (string, string, string) {
402	hashName := commonpb.HashType_name[int32(params.HashType)]
403	curveName := commonpb.EllipticCurveType_name[int32(params.Curve)]
404	encodingName := ecdsapb.EcdsaSignatureEncoding_name[int32(params.Encoding)]
405	return hashName, curveName, encodingName
406}
407
408// NewED25519PrivateKey creates an ED25519PrivateKey with randomly generated key material.
409func NewED25519PrivateKey() *ed25519pb.Ed25519PrivateKey {
410	public, private, _ := ed25519.GenerateKey(rand.Reader)
411	publicProto := &ed25519pb.Ed25519PublicKey{
412		Version:  ED25519SignerKeyVersion,
413		KeyValue: public,
414	}
415	return &ed25519pb.Ed25519PrivateKey{
416		Version:   ED25519SignerKeyVersion,
417		PublicKey: publicProto,
418		KeyValue:  private.Seed(),
419	}
420}
421
422// NewED25519PublicKey creates an ED25519PublicKey with randomly generated key material.
423func NewED25519PublicKey() *ed25519pb.Ed25519PublicKey {
424	return NewED25519PrivateKey().PublicKey
425}
426
427// NewAESGCMKey creates a randomly generated AESGCMKey.
428func NewAESGCMKey(keyVersion uint32, keySize uint32) *gcmpb.AesGcmKey {
429	keyValue := random.GetRandomBytes(keySize)
430	return &gcmpb.AesGcmKey{
431		Version:  keyVersion,
432		KeyValue: keyValue,
433	}
434}
435
436// NewAESGCMKeyData creates a KeyData containing a randomly generated AESGCMKey.
437func NewAESGCMKeyData(keySize uint32) *tinkpb.KeyData {
438	serializedKey, err := proto.Marshal(NewAESGCMKey(AESGCMKeyVersion, keySize))
439	if err != nil {
440		log.Fatalf("failed serializing proto: %v", err)
441	}
442	return NewKeyData(AESGCMTypeURL, serializedKey, tinkpb.KeyData_SYMMETRIC)
443}
444
445// NewAESGCMKeyFormat returns a new AESGCMKeyFormat.
446func NewAESGCMKeyFormat(keySize uint32) *gcmpb.AesGcmKeyFormat {
447	return &gcmpb.AesGcmKeyFormat{
448		KeySize: keySize,
449	}
450}
451
452// NewAESGCMSIVKey creates a randomly generated AESGCMSIVKey.
453func NewAESGCMSIVKey(keyVersion, keySize uint32) *gcmsivpb.AesGcmSivKey {
454	keyValue := random.GetRandomBytes(keySize)
455	return &gcmsivpb.AesGcmSivKey{
456		Version:  keyVersion,
457		KeyValue: keyValue,
458	}
459}
460
461// NewAESGCMSIVKeyData creates a KeyData containing a randomly generated AESGCMSIVKey.
462func NewAESGCMSIVKeyData(keySize uint32) *tinkpb.KeyData {
463	serializedKey, err := proto.Marshal(NewAESGCMSIVKey(AESGCMKeyVersion, keySize))
464	if err != nil {
465		log.Fatalf("NewAESGCMSIVKeyData(keySize=%d): Failed serializing proto; err=%v", keySize, err)
466	}
467	return NewKeyData(AESGCMTypeURL, serializedKey, tinkpb.KeyData_SYMMETRIC)
468}
469
470// NewAESGCMSIVKeyFormat returns a new AESGCMKeyFormat.
471func NewAESGCMSIVKeyFormat(keySize uint32) *gcmsivpb.AesGcmSivKeyFormat {
472	return &gcmsivpb.AesGcmSivKeyFormat{
473		KeySize: keySize,
474	}
475}
476
477// NewAESGCMHKDFKey creates a randomly generated AESGCMHKDFKey.
478func NewAESGCMHKDFKey(keyVersion, keySize, derivedKeySize uint32, hkdfHashType commonpb.HashType, ciphertextSegmentSize uint32) *gcmhkdfpb.AesGcmHkdfStreamingKey {
479	keyValue := random.GetRandomBytes(keySize)
480	return &gcmhkdfpb.AesGcmHkdfStreamingKey{
481		Version:  keyVersion,
482		KeyValue: keyValue,
483		Params: &gcmhkdfpb.AesGcmHkdfStreamingParams{
484			CiphertextSegmentSize: ciphertextSegmentSize,
485			DerivedKeySize:        derivedKeySize,
486			HkdfHashType:          hkdfHashType,
487		},
488	}
489}
490
491// NewAESGCMHKDFKeyData creates a KeyData containing a randomly generated AESGCMHKDFKey.
492func NewAESGCMHKDFKeyData(keySize, derivedKeySize uint32, hkdfHashType commonpb.HashType, ciphertextSegmentSize uint32) *tinkpb.KeyData {
493	serializedKey, err := proto.Marshal(NewAESGCMHKDFKey(AESGCMHKDFKeyVersion, keySize, derivedKeySize, hkdfHashType, ciphertextSegmentSize))
494	if err != nil {
495		log.Fatalf("failed serializing proto: %v", err)
496	}
497	return NewKeyData(AESGCMHKDFTypeURL, serializedKey, tinkpb.KeyData_SYMMETRIC)
498}
499
500// NewAESGCMHKDFKeyFormat returns a new AESGCMHKDFKeyFormat.
501func NewAESGCMHKDFKeyFormat(keySize, derivedKeySize uint32, hkdfHashType commonpb.HashType, ciphertextSegmentSize uint32) *gcmhkdfpb.AesGcmHkdfStreamingKeyFormat {
502	return &gcmhkdfpb.AesGcmHkdfStreamingKeyFormat{
503		KeySize: keySize,
504		Params: &gcmhkdfpb.AesGcmHkdfStreamingParams{
505			CiphertextSegmentSize: ciphertextSegmentSize,
506			DerivedKeySize:        derivedKeySize,
507			HkdfHashType:          hkdfHashType,
508		},
509	}
510}
511
512// NewAESCTRHMACKey creates a randomly generated AESCTRHMACKey.
513func NewAESCTRHMACKey(keyVersion, keySize uint32, hkdfHashType commonpb.HashType, derivedKeySize uint32, hashType commonpb.HashType, tagSize, ciphertextSegmentSize uint32) *ctrhmacpb.AesCtrHmacStreamingKey {
514	keyValue := random.GetRandomBytes(keySize)
515	return &ctrhmacpb.AesCtrHmacStreamingKey{
516		Version:  keyVersion,
517		KeyValue: keyValue,
518		Params: &ctrhmacpb.AesCtrHmacStreamingParams{
519			CiphertextSegmentSize: ciphertextSegmentSize,
520			DerivedKeySize:        derivedKeySize,
521			HkdfHashType:          hkdfHashType,
522			HmacParams: &hmacpb.HmacParams{
523				Hash:    hashType,
524				TagSize: tagSize,
525			},
526		},
527	}
528}
529
530// NewAESCTRHMACKeyFormat returns a new AESCTRHMACKeyFormat.
531func NewAESCTRHMACKeyFormat(keySize uint32, hkdfHashType commonpb.HashType, derivedKeySize uint32, hashType commonpb.HashType, tagSize, ciphertextSegmentSize uint32) *ctrhmacpb.AesCtrHmacStreamingKeyFormat {
532	return &ctrhmacpb.AesCtrHmacStreamingKeyFormat{
533		KeySize: keySize,
534		Params: &ctrhmacpb.AesCtrHmacStreamingParams{
535			CiphertextSegmentSize: ciphertextSegmentSize,
536			DerivedKeySize:        derivedKeySize,
537			HkdfHashType:          hkdfHashType,
538			HmacParams: &hmacpb.HmacParams{
539				Hash:    hashType,
540				TagSize: tagSize,
541			},
542		},
543	}
544}
545
546// NewHMACParams returns a new HMACParams.
547func NewHMACParams(hashType commonpb.HashType, tagSize uint32) *hmacpb.HmacParams {
548	return &hmacpb.HmacParams{
549		Hash:    hashType,
550		TagSize: tagSize,
551	}
552}
553
554// NewHMACKey creates a new HMACKey with the specified parameters.
555func NewHMACKey(hashType commonpb.HashType, tagSize uint32) *hmacpb.HmacKey {
556	params := NewHMACParams(hashType, tagSize)
557	keyValue := random.GetRandomBytes(20)
558	return &hmacpb.HmacKey{
559		Version:  HMACKeyVersion,
560		Params:   params,
561		KeyValue: keyValue,
562	}
563}
564
565// NewHMACKeyFormat creates a new HMACKeyFormat with the specified parameters.
566func NewHMACKeyFormat(hashType commonpb.HashType, tagSize uint32) *hmacpb.HmacKeyFormat {
567	params := NewHMACParams(hashType, tagSize)
568	keySize := uint32(20)
569	return &hmacpb.HmacKeyFormat{
570		Params:  params,
571		KeySize: keySize,
572	}
573}
574
575// NewAESCMACParams returns a new AESCMACParams.
576func NewAESCMACParams(tagSize uint32) *cmacpb.AesCmacParams {
577	return &cmacpb.AesCmacParams{
578		TagSize: tagSize,
579	}
580}
581
582// NewAESCMACKey creates a new AESCMACKey with the specified parameters.
583func NewAESCMACKey(tagSize uint32) *cmacpb.AesCmacKey {
584	params := NewAESCMACParams(tagSize)
585	keyValue := random.GetRandomBytes(32)
586	return &cmacpb.AesCmacKey{
587		Version:  AESCMACKeyVersion,
588		Params:   params,
589		KeyValue: keyValue,
590	}
591}
592
593// NewAESCMACKeyFormat creates a new AESCMACKeyFormat with the specified parameters.
594func NewAESCMACKeyFormat(tagSize uint32) *cmacpb.AesCmacKeyFormat {
595	params := NewAESCMACParams(tagSize)
596	keySize := uint32(32)
597	return &cmacpb.AesCmacKeyFormat{
598		Params:  params,
599		KeySize: keySize,
600	}
601}
602
603// NewHMACKeysetManager returns a new KeysetManager that contains a HMACKey.
604func NewHMACKeysetManager() *keyset.Manager {
605	ksm := keyset.NewManager()
606	kt := mac.HMACSHA256Tag128KeyTemplate()
607	keyID, err := ksm.Add(kt)
608	if err != nil {
609		panic(fmt.Sprintf("cannot add key: %v", err))
610	}
611	err = ksm.SetPrimary(keyID)
612	if err != nil {
613		panic(fmt.Sprintf("cannot set primary key: %v", err))
614	}
615	return ksm
616}
617
618// NewHMACKeyData returns a new KeyData that contains a HMACKey.
619func NewHMACKeyData(hashType commonpb.HashType, tagSize uint32) *tinkpb.KeyData {
620	key := NewHMACKey(hashType, tagSize)
621	serializedKey, err := proto.Marshal(key)
622	if err != nil {
623		log.Fatalf("failed serializing proto: %v", err)
624	}
625	return &tinkpb.KeyData{
626		TypeUrl:         HMACTypeURL,
627		Value:           serializedKey,
628		KeyMaterialType: tinkpb.KeyData_SYMMETRIC,
629	}
630}
631
632// NewHMACPRFParams returns a new HMACPRFParams.
633func NewHMACPRFParams(hashType commonpb.HashType) *hmacprfpb.HmacPrfParams {
634	return &hmacprfpb.HmacPrfParams{
635		Hash: hashType,
636	}
637}
638
639// NewHMACPRFKey creates a new HMACPRFKey with the specified parameters.
640func NewHMACPRFKey(hashType commonpb.HashType) *hmacprfpb.HmacPrfKey {
641	params := NewHMACPRFParams(hashType)
642	keyValue := random.GetRandomBytes(32)
643	return &hmacprfpb.HmacPrfKey{
644		Version:  HMACPRFKeyVersion,
645		Params:   params,
646		KeyValue: keyValue,
647	}
648}
649
650// NewHMACPRFKeyFormat creates a new HMACPRFKeyFormat with the specified parameters.
651func NewHMACPRFKeyFormat(hashType commonpb.HashType) *hmacprfpb.HmacPrfKeyFormat {
652	params := NewHMACPRFParams(hashType)
653	keySize := uint32(32)
654	return &hmacprfpb.HmacPrfKeyFormat{
655		Params:  params,
656		KeySize: keySize,
657	}
658}
659
660// NewHKDFPRFParams returns a new HKDFPRFParams.
661func NewHKDFPRFParams(hashType commonpb.HashType, salt []byte) *hkdfprfpb.HkdfPrfParams {
662	return &hkdfprfpb.HkdfPrfParams{
663		Hash: hashType,
664		Salt: salt,
665	}
666}
667
668// NewHKDFPRFKey creates a new HKDFPRFKey with the specified parameters.
669func NewHKDFPRFKey(hashType commonpb.HashType, salt []byte) *hkdfprfpb.HkdfPrfKey {
670	params := NewHKDFPRFParams(hashType, salt)
671	keyValue := random.GetRandomBytes(32)
672	return &hkdfprfpb.HkdfPrfKey{
673		Version:  HKDFPRFKeyVersion,
674		Params:   params,
675		KeyValue: keyValue,
676	}
677}
678
679// NewHKDFPRFKeyFormat creates a new HKDFPRFKeyFormat with the specified parameters.
680func NewHKDFPRFKeyFormat(hashType commonpb.HashType, salt []byte) *hkdfprfpb.HkdfPrfKeyFormat {
681	params := NewHKDFPRFParams(hashType, salt)
682	keySize := uint32(32)
683	return &hkdfprfpb.HkdfPrfKeyFormat{
684		Params:  params,
685		KeySize: keySize,
686	}
687}
688
689// NewAESCMACPRFKey creates a new AESCMACPRFKey with the specified parameters.
690func NewAESCMACPRFKey() *aescmacprfpb.AesCmacPrfKey {
691	keyValue := random.GetRandomBytes(32)
692	return &aescmacprfpb.AesCmacPrfKey{
693		Version:  AESCMACPRFKeyVersion,
694		KeyValue: keyValue,
695	}
696}
697
698// NewAESCMACPRFKeyFormat creates a new AESCMACPRFKeyFormat with the specified parameters.
699func NewAESCMACPRFKeyFormat() *aescmacprfpb.AesCmacPrfKeyFormat {
700	keySize := uint32(32)
701	return &aescmacprfpb.AesCmacPrfKeyFormat{
702		KeySize: keySize,
703	}
704}
705
706// NewKeyData creates a new KeyData with the specified parameters.
707func NewKeyData(typeURL string, value []byte, materialType tinkpb.KeyData_KeyMaterialType) *tinkpb.KeyData {
708	return &tinkpb.KeyData{
709		TypeUrl:         typeURL,
710		Value:           value,
711		KeyMaterialType: materialType,
712	}
713}
714
715// NewKey creates a new Key with the specified parameters.
716func NewKey(keyData *tinkpb.KeyData, status tinkpb.KeyStatusType, keyID uint32, prefixType tinkpb.OutputPrefixType) *tinkpb.Keyset_Key {
717	return &tinkpb.Keyset_Key{
718		KeyData:          keyData,
719		Status:           status,
720		KeyId:            keyID,
721		OutputPrefixType: prefixType,
722	}
723}
724
725// NewKeyset creates a new Keyset with the specified parameters.
726func NewKeyset(primaryKeyID uint32, keys []*tinkpb.Keyset_Key) *tinkpb.Keyset {
727	return &tinkpb.Keyset{
728		PrimaryKeyId: primaryKeyID,
729		Key:          keys,
730	}
731}
732
733// GenerateMutations generates different byte mutations for a given byte array.
734func GenerateMutations(src []byte) (all [][]byte) {
735	// Flip bits
736	for i := 0; i < len(src); i++ {
737		for j := 0; j < 8; j++ {
738			n := make([]byte, len(src))
739			copy(n, src)
740			n[i] = n[i] ^ (1 << uint8(j))
741			all = append(all, n)
742		}
743	}
744
745	//truncate bytes
746	for i := 1; i < len(src); i++ {
747		n := make([]byte, len(src[i:]))
748		copy(n, src[i:])
749		all = append(all, n)
750	}
751
752	//append extra byte
753	m := make([]byte, len(src)+1)
754	copy(m, src)
755	all = append(all, m)
756	return
757}
758
759// ZTestUniformString uses a z test on the given byte string, expecting all
760// bits to be uniformly set with probability 1/2. Returns non ok status if the
761// z test fails by more than 10 standard deviations.
762//
763// With less statistics jargon: This counts the number of bits set and expects
764// the number to be roughly half of the length of the string. The law of large
765// numbers suggests that we can assume that the longer the string is, the more
766// accurate that estimate becomes for a random string. This test is useful to
767// detect things like strings that are entirely zero.
768//
769// Note: By itself, this is a very weak test for randomness.
770func ZTestUniformString(bytes []byte) error {
771	expected := float64(len(bytes)) * 8.0 / 2.0
772	stddev := math.Sqrt(float64(len(bytes)) * 8.0 / 4.0)
773	numSetBits := int64(0)
774	for _, b := range bytes {
775		// Counting the number of bits set in byte:
776		for b != 0 {
777			numSetBits++
778			b = b & (b - 1)
779		}
780	}
781	// Check that the number of bits is within 10 stddevs.
782	if math.Abs(float64(numSetBits)-expected) < 10.0*stddev {
783		return nil
784	}
785	return fmt.Errorf("Z test for uniformly distributed variable out of bounds; "+
786		"Actual number of set bits was %d expected was %0.00f, 10 * standard deviation is 10 * %0.00f = %0.00f",
787		numSetBits, expected, stddev, 10.0*stddev)
788}
789
790func rotate(bytes []byte) []byte {
791	result := make([]byte, len(bytes))
792	for i := 0; i < len(bytes); i++ {
793		prev := i
794		if i == 0 {
795			prev = len(bytes)
796		}
797		result[i] = (bytes[i] >> 1) |
798			(bytes[prev-1] << 7)
799	}
800	return result
801}
802
803// ZTestCrosscorrelationUniformStrings tests that the crosscorrelation of two
804// strings of equal length points to independent and uniformly distributed
805// strings. Returns non ok status if the z test fails by more than 10 standard
806// deviations.
807//
808// With less statistics jargon: This xors two strings and then performs the
809// ZTestUniformString on the result. If the two strings are independent and
810// uniformly distributed, the xor'ed string is as well. A cross correlation test
811// will find whether two strings overlap more or less than it would be expected.
812//
813// Note: Having a correlation of zero is only a necessary but not sufficient
814// condition for independence.
815func ZTestCrosscorrelationUniformStrings(bytes1, bytes2 []byte) error {
816	if len(bytes1) != len(bytes2) {
817		return fmt.Errorf(
818			"Strings are not of equal length")
819	}
820	crossed := make([]byte, len(bytes1))
821	for i := 0; i < len(bytes1); i++ {
822		crossed[i] = bytes1[i] ^ bytes2[i]
823	}
824	return ZTestUniformString(crossed)
825}
826
827// ZTestAutocorrelationUniformString tests that the autocorrelation of a string
828// points to the bits being independent and uniformly distributed.
829// Rotates the string in a cyclic fashion. Returns non ok status if the z test
830// fails by more than 10 standard deviations.
831//
832// With less statistics jargon: This rotates the string bit by bit and performs
833// ZTestCrosscorrelationUniformStrings on each of the rotated strings and the
834// original. This will find self similarity of the input string, especially
835// periodic self similarity. For example, it is a decent test to find English
836// text (needs about 180 characters with the current settings).
837//
838// Note: Having a correlation of zero is only a necessary but not sufficient
839// condition for independence.
840func ZTestAutocorrelationUniformString(bytes []byte) error {
841	rotated := make([]byte, len(bytes))
842	copy(rotated, bytes)
843	violations := []string{}
844	for i := 1; i < len(bytes)*8; i++ {
845		rotated = rotate(rotated)
846		err := ZTestCrosscorrelationUniformStrings(bytes, rotated)
847		if err != nil {
848			violations = append(violations, strconv.Itoa(i))
849		}
850	}
851	if len(violations) == 0 {
852		return nil
853	}
854	return fmt.Errorf("Autocorrelation exceeded 10 standard deviation at %d indices: %s", len(violations), strings.Join(violations, ", "))
855}
856
857// eciesAEADHKDFPublicKey returns a EciesAeadHkdfPublicKey with specified parameters.
858func eciesAEADHKDFPublicKey(c commonpb.EllipticCurveType, ht commonpb.HashType, ptfmt commonpb.EcPointFormat, dekT *tinkpb.KeyTemplate, x, y, salt []byte) *eciespb.EciesAeadHkdfPublicKey {
859	return &eciespb.EciesAeadHkdfPublicKey{
860		Version: 0,
861		Params: &eciespb.EciesAeadHkdfParams{
862			KemParams: &eciespb.EciesHkdfKemParams{
863				CurveType:    c,
864				HkdfHashType: ht,
865				HkdfSalt:     salt,
866			},
867			DemParams: &eciespb.EciesAeadDemParams{
868				AeadDem: dekT,
869			},
870			EcPointFormat: ptfmt,
871		},
872		X: x,
873		Y: y,
874	}
875}
876
877// eciesAEADHKDFPrivateKey returns a EciesAeadHkdfPrivateKey with specified parameters
878func eciesAEADHKDFPrivateKey(p *eciespb.EciesAeadHkdfPublicKey, d []byte) *eciespb.EciesAeadHkdfPrivateKey {
879	return &eciespb.EciesAeadHkdfPrivateKey{
880		Version:   0,
881		PublicKey: p,
882		KeyValue:  d,
883	}
884}
885
886// GenerateECIESAEADHKDFPrivateKey generates a new EC key pair and returns the private key proto.
887func GenerateECIESAEADHKDFPrivateKey(c commonpb.EllipticCurveType, ht commonpb.HashType, ptfmt commonpb.EcPointFormat, dekT *tinkpb.KeyTemplate, salt []byte) (*eciespb.EciesAeadHkdfPrivateKey, error) {
888	curve, err := subtlehybrid.GetCurve(c.String())
889	if err != nil {
890		return nil, err
891	}
892	pvt, err := subtlehybrid.GenerateECDHKeyPair(curve)
893	if err != nil {
894		return nil, err
895	}
896	pubKey := eciesAEADHKDFPublicKey(c, ht, ptfmt, dekT, pvt.PublicKey.Point.X.Bytes(), pvt.PublicKey.Point.Y.Bytes(), salt)
897	//fmt.Println(proto.MarshalTextString(pubKey))
898	return eciesAEADHKDFPrivateKey(pubKey, pvt.D.Bytes()), nil
899}
900