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