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