// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//      http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
//
////////////////////////////////////////////////////////////////////////////////

// Package testutil provides common methods needed in test code.
package testutil

import (
	"crypto/ecdsa"
	"crypto/rand"
	"fmt"
	"log"
	"math"
	"strconv"
	"strings"

	"golang.org/x/crypto/ed25519"
	"github.com/golang/protobuf/proto"
	"github.com/google/tink/go/core/registry"
	subtledaead "github.com/google/tink/go/daead/subtle"
	subtlehybrid "github.com/google/tink/go/hybrid/subtle"
	"github.com/google/tink/go/keyset"
	"github.com/google/tink/go/mac"
	"github.com/google/tink/go/subtle/random"
	"github.com/google/tink/go/subtle"
	"github.com/google/tink/go/tink"

	cmacpb "github.com/google/tink/go/proto/aes_cmac_go_proto"
	aescmacprfpb "github.com/google/tink/go/proto/aes_cmac_prf_go_proto"
	ctrhmacpb "github.com/google/tink/go/proto/aes_ctr_hmac_streaming_go_proto"
	gcmpb "github.com/google/tink/go/proto/aes_gcm_go_proto"
	gcmhkdfpb "github.com/google/tink/go/proto/aes_gcm_hkdf_streaming_go_proto"
	aspb "github.com/google/tink/go/proto/aes_siv_go_proto"
	commonpb "github.com/google/tink/go/proto/common_go_proto"
	ecdsapb "github.com/google/tink/go/proto/ecdsa_go_proto"
	eciespb "github.com/google/tink/go/proto/ecies_aead_hkdf_go_proto"
	ed25519pb "github.com/google/tink/go/proto/ed25519_go_proto"
	hkdfprfpb "github.com/google/tink/go/proto/hkdf_prf_go_proto"
	hmacpb "github.com/google/tink/go/proto/hmac_go_proto"
	hmacprfpb "github.com/google/tink/go/proto/hmac_prf_go_proto"
	tinkpb "github.com/google/tink/go/proto/tink_go_proto"
)

// DummyAEADKeyManager is a dummy implementation of the KeyManager interface.
// It returns DummyAEAD when GetPrimitive() functions are called.
type DummyAEADKeyManager struct{}

var _ registry.KeyManager = (*DummyAEADKeyManager)(nil)

// Primitive constructs a primitive instance for the key given in
// serializedKey, which must be a serialized key protocol buffer handled by this manager.
func (km *DummyAEADKeyManager) Primitive(serializedKey []byte) (interface{}, error) {
	return new(DummyAEAD), nil
}

// NewKey generates a new key according to specification in serializedKeyFormat.
func (km *DummyAEADKeyManager) NewKey(serializedKeyFormat []byte) (proto.Message, error) {
	return nil, fmt.Errorf("not implemented")
}

// NewKeyData generates a new KeyData according to specification in serializedkeyFormat.
func (km *DummyAEADKeyManager) NewKeyData(serializedKeyFormat []byte) (*tinkpb.KeyData, error) {
	return nil, fmt.Errorf("not implemented")
}

// DoesSupport returns true iff this KeyManager supports key type identified by typeURL.
func (km *DummyAEADKeyManager) DoesSupport(typeURL string) bool {
	return typeURL == AESGCMTypeURL
}

// TypeURL returns the type URL.
func (km *DummyAEADKeyManager) TypeURL() string {
	return AESGCMTypeURL
}

// DummyAEAD is a dummy implementation of AEAD interface.
type DummyAEAD struct{}

// Encrypt encrypts the plaintext.
func (a *DummyAEAD) Encrypt(plaintext []byte, additionalData []byte) ([]byte, error) {
	return nil, fmt.Errorf("dummy aead encrypt")
}

// Decrypt decrypts the ciphertext.
func (a *DummyAEAD) Decrypt(ciphertext []byte, additionalData []byte) ([]byte, error) {
	return nil, fmt.Errorf("dummy aead decrypt")
}

// DummyMAC is a dummy implementation of Mac interface.
type DummyMAC struct {
	Name string
}

// ComputeMAC computes message authentication code (MAC) for {@code data}.
func (h *DummyMAC) ComputeMAC(data []byte) ([]byte, error) {
	var m []byte
	m = append(m, data...)
	m = append(m, h.Name...)
	return m, nil
}

// VerifyMAC verifies whether {@code mac} is a correct authentication code (MAC) for {@code data}.
func (h *DummyMAC) VerifyMAC(mac []byte, data []byte) error {
	return nil
}

// DummyKMSClient is a dummy implementation of a KMS Client.
type DummyKMSClient struct{}

var _ registry.KMSClient = (*DummyKMSClient)(nil)

// Supported true if this client does support keyURI
func (d *DummyKMSClient) Supported(keyURI string) bool {
	return keyURI == "dummy"
}

// LoadCredentials loads the credentials in credentialPath. If credentialPath is null, loads the
// default credentials.
func (d *DummyKMSClient) LoadCredentials(credentialPath string) (interface{}, error) {
	return d, nil
}

// LoadDefaultCredentials loads with the default credentials.
func (d *DummyKMSClient) LoadDefaultCredentials() (interface{}, error) {
	return d, nil
}

// GetAEAD gets an Aead backend by keyURI.
func (d *DummyKMSClient) GetAEAD(keyURI string) (tink.AEAD, error) {
	return &DummyAEAD{}, nil
}

// NewTestAESGCMKeyset creates a new Keyset containing an AESGCMKey.
func NewTestAESGCMKeyset(primaryOutputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset {
	keyData := NewAESGCMKeyData(16)
	return NewTestKeyset(keyData, primaryOutputPrefixType)
}

// NewTestAESSIVKeyset creates a new Keyset containing an AesSivKey.
func NewTestAESSIVKeyset(primaryOutputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset {
	keyValue := random.GetRandomBytes(subtledaead.AESSIVKeySize)
	key := &aspb.AesSivKey{
		Version:  AESSIVKeyVersion,
		KeyValue: keyValue,
	}
	serializedKey, err := proto.Marshal(key)
	if err != nil {
		log.Fatalf("failed serializing proto: %v", err)
	}
	keyData := NewKeyData(AESSIVTypeURL, serializedKey, tinkpb.KeyData_SYMMETRIC)
	return NewTestKeyset(keyData, primaryOutputPrefixType)
}

// NewTestHMACKeyset creates a new Keyset containing a HMACKey.
func NewTestHMACKeyset(tagSize uint32,
	primaryOutputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset {
	keyData := NewHMACKeyData(commonpb.HashType_SHA256, tagSize)
	return NewTestKeyset(keyData, primaryOutputPrefixType)
}

// NewTestAESGCMHKDFKeyset creates a new Keyset containing an AESGCMHKDFKey.
func NewTestAESGCMHKDFKeyset() *tinkpb.Keyset {
	const (
		keySize               = 16
		derivedKeySize        = 16
		ciphertextSegmentSize = 4096
	)
	keyData := NewAESGCMHKDFKeyData(keySize, derivedKeySize, commonpb.HashType_SHA256, ciphertextSegmentSize)
	return NewTestKeyset(keyData, tinkpb.OutputPrefixType_RAW)
}

// NewTestKeyset creates a new test Keyset.
func NewTestKeyset(keyData *tinkpb.KeyData,
	primaryOutputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset {
	primaryKey := NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 42, primaryOutputPrefixType)
	rawKey := NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 43, tinkpb.OutputPrefixType_RAW)
	legacyKey := NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 44, tinkpb.OutputPrefixType_LEGACY)
	tinkKey := NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 45, tinkpb.OutputPrefixType_TINK)
	crunchyKey := NewKey(keyData, tinkpb.KeyStatusType_ENABLED, 46, tinkpb.OutputPrefixType_CRUNCHY)
	keys := []*tinkpb.Keyset_Key{primaryKey, rawKey, legacyKey, tinkKey, crunchyKey}
	return NewKeyset(primaryKey.KeyId, keys)
}

// NewDummyKey returns a dummy key that doesn't contain actual key material.
func NewDummyKey(keyID int, status tinkpb.KeyStatusType, outputPrefixType tinkpb.OutputPrefixType) *tinkpb.Keyset_Key {
	return &tinkpb.Keyset_Key{
		KeyData:          new(tinkpb.KeyData),
		Status:           status,
		KeyId:            uint32(keyID),
		OutputPrefixType: outputPrefixType,
	}
}

// NewECDSAParams creates a ECDSAParams with the specified parameters.
func NewECDSAParams(hashType commonpb.HashType,
	curve commonpb.EllipticCurveType,
	encoding ecdsapb.EcdsaSignatureEncoding) *ecdsapb.EcdsaParams {
	return &ecdsapb.EcdsaParams{
		HashType: hashType,
		Curve:    curve,
		Encoding: encoding,
	}
}

// NewECDSAKeyFormat creates a ECDSAKeyFormat with the specified parameters.
func NewECDSAKeyFormat(params *ecdsapb.EcdsaParams) *ecdsapb.EcdsaKeyFormat {
	return &ecdsapb.EcdsaKeyFormat{Params: params}
}

// NewECDSAPrivateKey creates a ECDSAPrivateKey with the specified paramaters.
func NewECDSAPrivateKey(version uint32,
	publicKey *ecdsapb.EcdsaPublicKey,
	keyValue []byte) *ecdsapb.EcdsaPrivateKey {
	return &ecdsapb.EcdsaPrivateKey{
		Version:   version,
		PublicKey: publicKey,
		KeyValue:  keyValue,
	}
}

// NewECDSAPublicKey creates a ECDSAPublicKey with the specified paramaters.
func NewECDSAPublicKey(version uint32,
	params *ecdsapb.EcdsaParams,
	x []byte, y []byte) *ecdsapb.EcdsaPublicKey {
	return &ecdsapb.EcdsaPublicKey{
		Version: version,
		Params:  params,
		X:       x,
		Y:       y,
	}
}

// NewRandomECDSAPrivateKey creates an ECDSAPrivateKey with randomly generated key material.
func NewRandomECDSAPrivateKey(hashType commonpb.HashType, curve commonpb.EllipticCurveType) *ecdsapb.EcdsaPrivateKey {
	curveName := commonpb.EllipticCurveType_name[int32(curve)]
	priv, _ := ecdsa.GenerateKey(subtle.GetCurve(curveName), rand.Reader)
	params := NewECDSAParams(hashType, curve, ecdsapb.EcdsaSignatureEncoding_DER)
	publicKey := NewECDSAPublicKey(ECDSAVerifierKeyVersion, params, priv.X.Bytes(), priv.Y.Bytes())
	return NewECDSAPrivateKey(ECDSASignerKeyVersion, publicKey, priv.D.Bytes())
}

// NewRandomECDSAPrivateKeyData creates a KeyData containing an ECDSAPrivateKey with randomly generated key material.
func NewRandomECDSAPrivateKeyData(hashType commonpb.HashType, curve commonpb.EllipticCurveType) *tinkpb.KeyData {
	serializedKey, err := proto.Marshal(NewRandomECDSAPrivateKey(hashType, curve))
	if err != nil {
		log.Fatalf("failed serializing proto: %v", err)
	}
	return &tinkpb.KeyData{
		TypeUrl:         ECDSASignerTypeURL,
		Value:           serializedKey,
		KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PRIVATE,
	}
}

// NewRandomECDSAPublicKey creates an ECDSAPublicKey with randomly generated key material.
func NewRandomECDSAPublicKey(hashType commonpb.HashType, curve commonpb.EllipticCurveType) *ecdsapb.EcdsaPublicKey {
	return NewRandomECDSAPrivateKey(hashType, curve).PublicKey
}

// GetECDSAParamNames returns the string representations of each parameter in
// the given ECDSAParams.
func GetECDSAParamNames(params *ecdsapb.EcdsaParams) (string, string, string) {
	hashName := commonpb.HashType_name[int32(params.HashType)]
	curveName := commonpb.EllipticCurveType_name[int32(params.Curve)]
	encodingName := ecdsapb.EcdsaSignatureEncoding_name[int32(params.Encoding)]
	return hashName, curveName, encodingName
}

// NewED25519PrivateKey creates an ED25519PrivateKey with randomly generated key material.
func NewED25519PrivateKey() *ed25519pb.Ed25519PrivateKey {
	public, private, _ := ed25519.GenerateKey(rand.Reader)
	publicProto := &ed25519pb.Ed25519PublicKey{
		Version:  ED25519SignerKeyVersion,
		KeyValue: public,
	}
	return &ed25519pb.Ed25519PrivateKey{
		Version:   ED25519SignerKeyVersion,
		PublicKey: publicProto,
		KeyValue:  private.Seed(),
	}
}

// NewED25519PrivateKeyData creates a KeyData containing an ED25519PrivateKey with randomly generated key material.
func NewED25519PrivateKeyData() *tinkpb.KeyData {
	serializedKey, err := proto.Marshal(NewED25519PrivateKey())
	if err != nil {
		log.Fatalf("failed serializing proto: %v", err)
	}
	return &tinkpb.KeyData{
		TypeUrl:         ED25519SignerTypeURL,
		Value:           serializedKey,
		KeyMaterialType: tinkpb.KeyData_ASYMMETRIC_PRIVATE,
	}
}

// NewED25519PublicKey creates an ED25519PublicKey with randomly generated key material.
func NewED25519PublicKey() *ed25519pb.Ed25519PublicKey {
	return NewED25519PrivateKey().PublicKey
}

// NewAESGCMKey creates a randomly generated AESGCMKey.
func NewAESGCMKey(keyVersion uint32, keySize uint32) *gcmpb.AesGcmKey {
	keyValue := random.GetRandomBytes(keySize)
	return &gcmpb.AesGcmKey{
		Version:  keyVersion,
		KeyValue: keyValue,
	}
}

// NewAESGCMKeyData creates a KeyData containing a randomly generated AESGCMKey.
func NewAESGCMKeyData(keySize uint32) *tinkpb.KeyData {
	serializedKey, err := proto.Marshal(NewAESGCMKey(AESGCMKeyVersion, keySize))
	if err != nil {
		log.Fatalf("failed serializing proto: %v", err)
	}
	return NewKeyData(AESGCMTypeURL, serializedKey, tinkpb.KeyData_SYMMETRIC)
}

// NewSerializedAESGCMKey creates a AESGCMKey with randomly generated key material.
func NewSerializedAESGCMKey(keySize uint32) []byte {
	serializedKey, err := proto.Marshal(NewAESGCMKey(AESGCMKeyVersion, keySize))
	if err != nil {
		panic(fmt.Sprintf("cannot marshal AESGCMKey: %s", err))
	}
	return serializedKey
}

// NewAESGCMKeyFormat returns a new AESGCMKeyFormat.
func NewAESGCMKeyFormat(keySize uint32) *gcmpb.AesGcmKeyFormat {
	return &gcmpb.AesGcmKeyFormat{
		KeySize: keySize,
	}
}

// NewAESGCMHKDFKey creates a randomly generated AESGCMHKDFKey.
func NewAESGCMHKDFKey(
	keyVersion uint32,
	keySize uint32,
	derivedKeySize uint32,
	hkdfHashType commonpb.HashType,
	ciphertextSegmentSize uint32,
) *gcmhkdfpb.AesGcmHkdfStreamingKey {
	keyValue := random.GetRandomBytes(keySize)
	return &gcmhkdfpb.AesGcmHkdfStreamingKey{
		Version:  keyVersion,
		KeyValue: keyValue,
		Params: &gcmhkdfpb.AesGcmHkdfStreamingParams{
			CiphertextSegmentSize: ciphertextSegmentSize,
			DerivedKeySize:        derivedKeySize,
			HkdfHashType:          hkdfHashType,
		},
	}
}

// NewAESGCMHKDFKeyData creates a KeyData containing a randomly generated AESGCMHKDFKey.
func NewAESGCMHKDFKeyData(
	keySize uint32,
	derivedKeySize uint32,
	hkdfHashType commonpb.HashType,
	ciphertextSegmentSize uint32,
) *tinkpb.KeyData {
	serializedKey, err := proto.Marshal(NewAESGCMHKDFKey(AESGCMHKDFKeyVersion, keySize, derivedKeySize, hkdfHashType, ciphertextSegmentSize))
	if err != nil {
		log.Fatalf("failed serializing proto: %v", err)
	}
	return NewKeyData(AESGCMHKDFTypeURL, serializedKey, tinkpb.KeyData_SYMMETRIC)
}

// NewAESGCMHKDFKeyFormat returns a new AESGCMHKDFKeyFormat.
func NewAESGCMHKDFKeyFormat(
	keySize uint32,
	derivedKeySize uint32,
	hkdfHashType commonpb.HashType,
	ciphertextSegmentSize uint32,
) *gcmhkdfpb.AesGcmHkdfStreamingKeyFormat {
	return &gcmhkdfpb.AesGcmHkdfStreamingKeyFormat{
		KeySize: keySize,
		Params: &gcmhkdfpb.AesGcmHkdfStreamingParams{
			CiphertextSegmentSize: ciphertextSegmentSize,
			DerivedKeySize:        derivedKeySize,
			HkdfHashType:          hkdfHashType,
		},
	}
}

// NewAESCTRHMACKey creates a randomly generated AESCTRHMACKey.
func NewAESCTRHMACKey(
	keyVersion uint32,
	keySize uint32,
	hkdfHashType commonpb.HashType,
	derivedKeySize uint32,
	hashType commonpb.HashType,
	tagSize uint32,
	ciphertextSegmentSize uint32,
) *ctrhmacpb.AesCtrHmacStreamingKey {
	keyValue := random.GetRandomBytes(keySize)
	return &ctrhmacpb.AesCtrHmacStreamingKey{
		Version:  keyVersion,
		KeyValue: keyValue,
		Params: &ctrhmacpb.AesCtrHmacStreamingParams{
			CiphertextSegmentSize: ciphertextSegmentSize,
			DerivedKeySize:        derivedKeySize,
			HkdfHashType:          hkdfHashType,
			HmacParams: &hmacpb.HmacParams{
				Hash:    hashType,
				TagSize: tagSize,
			},
		},
	}
}

// NewAESCTRHMACKeyData creates a KeyData containing a randomly generated AESCTRHMACKey.
func NewAESCTRHMACKeyData(
	keySize uint32,
	hkdfHashType commonpb.HashType,
	derivedKeySize uint32,
	hashType commonpb.HashType,
	tagSize uint32,
	ciphertextSegmentSize uint32,
) *tinkpb.KeyData {
	key := NewAESCTRHMACKey(AESCTRHMACKeyVersion, keySize, hkdfHashType, derivedKeySize, hashType, tagSize, ciphertextSegmentSize)
	serializedKey, err := proto.Marshal(key)
	if err != nil {
		log.Fatalf("failed serializing proto: %v", err)
	}
	return NewKeyData(AESCTRHMACTypeURL, serializedKey, tinkpb.KeyData_SYMMETRIC)
}

// NewAESCTRHMACKeyFormat returns a new AESCTRHMACKeyFormat.
func NewAESCTRHMACKeyFormat(
	keySize uint32,
	hkdfHashType commonpb.HashType,
	derivedKeySize uint32,
	hashType commonpb.HashType,
	tagSize uint32,
	ciphertextSegmentSize uint32,
) *ctrhmacpb.AesCtrHmacStreamingKeyFormat {
	return &ctrhmacpb.AesCtrHmacStreamingKeyFormat{
		KeySize: keySize,
		Params: &ctrhmacpb.AesCtrHmacStreamingParams{
			CiphertextSegmentSize: ciphertextSegmentSize,
			DerivedKeySize:        derivedKeySize,
			HkdfHashType:          hkdfHashType,
			HmacParams: &hmacpb.HmacParams{
				Hash:    hashType,
				TagSize: tagSize,
			},
		},
	}
}

// NewHMACParams returns a new HMACParams.
func NewHMACParams(hashType commonpb.HashType, tagSize uint32) *hmacpb.HmacParams {
	return &hmacpb.HmacParams{
		Hash:    hashType,
		TagSize: tagSize,
	}
}

// NewHMACKey creates a new HMACKey with the specified parameters.
func NewHMACKey(hashType commonpb.HashType, tagSize uint32) *hmacpb.HmacKey {
	params := NewHMACParams(hashType, tagSize)
	keyValue := random.GetRandomBytes(20)
	return &hmacpb.HmacKey{
		Version:  HMACKeyVersion,
		Params:   params,
		KeyValue: keyValue,
	}
}

// NewHMACKeyFormat creates a new HMACKeyFormat with the specified parameters.
func NewHMACKeyFormat(hashType commonpb.HashType, tagSize uint32) *hmacpb.HmacKeyFormat {
	params := NewHMACParams(hashType, tagSize)
	keySize := uint32(20)
	return &hmacpb.HmacKeyFormat{
		Params:  params,
		KeySize: keySize,
	}
}

// NewAESCMACParams returns a new AESCMACParams.
func NewAESCMACParams(tagSize uint32) *cmacpb.AesCmacParams {
	return &cmacpb.AesCmacParams{
		TagSize: tagSize,
	}
}

// NewAESCMACKey creates a new AESCMACKey with the specified parameters.
func NewAESCMACKey(tagSize uint32) *cmacpb.AesCmacKey {
	params := NewAESCMACParams(tagSize)
	keyValue := random.GetRandomBytes(32)
	return &cmacpb.AesCmacKey{
		Version:  AESCMACKeyVersion,
		Params:   params,
		KeyValue: keyValue,
	}
}

// NewAESCMACKeyFormat creates a new AESCMACKeyFormat with the specified parameters.
func NewAESCMACKeyFormat(tagSize uint32) *cmacpb.AesCmacKeyFormat {
	params := NewAESCMACParams(tagSize)
	keySize := uint32(32)
	return &cmacpb.AesCmacKeyFormat{
		Params:  params,
		KeySize: keySize,
	}
}

// NewHMACKeysetManager returns a new KeysetManager that contains a HMACKey.
func NewHMACKeysetManager() *keyset.Manager {
	ksm := keyset.NewManager()
	kt := mac.HMACSHA256Tag128KeyTemplate()
	err := ksm.Rotate(kt)
	if err != nil {
		panic(fmt.Sprintf("cannot rotate keyset manager: %s", err))
	}
	return ksm
}

// NewHMACKeyData returns a new KeyData that contains a HMACKey.
func NewHMACKeyData(hashType commonpb.HashType, tagSize uint32) *tinkpb.KeyData {
	key := NewHMACKey(hashType, tagSize)
	serializedKey, err := proto.Marshal(key)
	if err != nil {
		log.Fatalf("failed serializing proto: %v", err)
	}
	return &tinkpb.KeyData{
		TypeUrl:         HMACTypeURL,
		Value:           serializedKey,
		KeyMaterialType: tinkpb.KeyData_SYMMETRIC,
	}
}

// NewHMACPRFParams returns a new HMACPRFParams.
func NewHMACPRFParams(hashType commonpb.HashType) *hmacprfpb.HmacPrfParams {
	return &hmacprfpb.HmacPrfParams{
		Hash: hashType,
	}
}

// NewHMACPRFKey creates a new HMACPRFKey with the specified parameters.
func NewHMACPRFKey(hashType commonpb.HashType) *hmacprfpb.HmacPrfKey {
	params := NewHMACPRFParams(hashType)
	keyValue := random.GetRandomBytes(32)
	return &hmacprfpb.HmacPrfKey{
		Version:  HMACPRFKeyVersion,
		Params:   params,
		KeyValue: keyValue,
	}
}

// NewHMACPRFKeyFormat creates a new HMACPRFKeyFormat with the specified parameters.
func NewHMACPRFKeyFormat(hashType commonpb.HashType) *hmacprfpb.HmacPrfKeyFormat {
	params := NewHMACPRFParams(hashType)
	keySize := uint32(32)
	return &hmacprfpb.HmacPrfKeyFormat{
		Params:  params,
		KeySize: keySize,
	}
}

// NewHKDFPRFParams returns a new HKDFPRFParams.
func NewHKDFPRFParams(hashType commonpb.HashType, salt []byte) *hkdfprfpb.HkdfPrfParams {
	return &hkdfprfpb.HkdfPrfParams{
		Hash: hashType,
		Salt: salt,
	}
}

// NewHKDFPRFKey creates a new HKDFPRFKey with the specified parameters.
func NewHKDFPRFKey(hashType commonpb.HashType, salt []byte) *hkdfprfpb.HkdfPrfKey {
	params := NewHKDFPRFParams(hashType, salt)
	keyValue := random.GetRandomBytes(32)
	return &hkdfprfpb.HkdfPrfKey{
		Version:  HKDFPRFKeyVersion,
		Params:   params,
		KeyValue: keyValue,
	}
}

// NewHKDFPRFKeyFormat creates a new HKDFPRFKeyFormat with the specified parameters.
func NewHKDFPRFKeyFormat(hashType commonpb.HashType, salt []byte) *hkdfprfpb.HkdfPrfKeyFormat {
	params := NewHKDFPRFParams(hashType, salt)
	keySize := uint32(32)
	return &hkdfprfpb.HkdfPrfKeyFormat{
		Params:  params,
		KeySize: keySize,
	}
}

// NewAESCMACPRFKey creates a new AESCMACPRFKey with the specified parameters.
func NewAESCMACPRFKey() *aescmacprfpb.AesCmacPrfKey {
	keyValue := random.GetRandomBytes(32)
	return &aescmacprfpb.AesCmacPrfKey{
		Version:  AESCMACPRFKeyVersion,
		KeyValue: keyValue,
	}
}

// NewAESCMACPRFKeyFormat creates a new AESCMACPRFKeyFormat with the specified parameters.
func NewAESCMACPRFKeyFormat() *aescmacprfpb.AesCmacPrfKeyFormat {
	keySize := uint32(32)
	return &aescmacprfpb.AesCmacPrfKeyFormat{
		KeySize: keySize,
	}
}

// NewKeyData creates a new KeyData with the specified parameters.
func NewKeyData(typeURL string,
	value []byte,
	materialType tinkpb.KeyData_KeyMaterialType) *tinkpb.KeyData {
	return &tinkpb.KeyData{
		TypeUrl:         typeURL,
		Value:           value,
		KeyMaterialType: materialType,
	}
}

// NewKey creates a new Key with the specified parameters.
func NewKey(keyData *tinkpb.KeyData,
	status tinkpb.KeyStatusType,
	keyID uint32,
	prefixType tinkpb.OutputPrefixType) *tinkpb.Keyset_Key {
	return &tinkpb.Keyset_Key{
		KeyData:          keyData,
		Status:           status,
		KeyId:            keyID,
		OutputPrefixType: prefixType,
	}
}

// NewKeyset creates a new Keyset with the specified parameters.
func NewKeyset(primaryKeyID uint32,
	keys []*tinkpb.Keyset_Key) *tinkpb.Keyset {
	return &tinkpb.Keyset{
		PrimaryKeyId: primaryKeyID,
		Key:          keys,
	}
}

// NewEncryptedKeyset creates a new EncryptedKeyset with a specified parameters.
func NewEncryptedKeyset(encryptedKeySet []byte, info *tinkpb.KeysetInfo) *tinkpb.EncryptedKeyset {
	return &tinkpb.EncryptedKeyset{
		EncryptedKeyset: encryptedKeySet,
		KeysetInfo:      info,
	}
}

// GenerateMutations generates different byte mutations for a given byte array.
func GenerateMutations(src []byte) (all [][]byte) {
	n := make([]byte, len(src))

	// Flip bits
	for i := 0; i < len(src); i++ {
		for j := 0; j < 8; j++ {
			copy(n, src)
			n[i] = n[i] ^ (1 << uint8(j))
			all = append(all, n)
		}
	}

	//truncate bytes
	for i := 0; i < len(src); i++ {
		copy(n, src[i:])
		all = append(all, n)
	}

	//append extra byte
	m := make([]byte, len(src)+1)
	copy(m, src)
	all = append(all, m)
	return
}

// ZTestUniformString uses a z test on the given byte string, expecting all
// bits to be uniformly set with probability 1/2. Returns non ok status if the
// z test fails by more than 10 standard deviations.
//
// With less statistics jargon: This counts the number of bits set and expects
// the number to be roughly half of the length of the string. The law of large
// numbers suggests that we can assume that the longer the string is, the more
// accurate that estimate becomes for a random string. This test is useful to
// detect things like strings that are entirely zero.
//
// Note: By itself, this is a very weak test for randomness.
func ZTestUniformString(bytes []byte) error {
	expected := float64(len(bytes)) * 8.0 / 2.0
	stddev := math.Sqrt(float64(len(bytes)) * 8.0 / 4.0)
	numSetBits := int64(0)
	for _, b := range bytes {
		// Counting the number of bits set in byte:
		for b != 0 {
			numSetBits++
			b = b & (b - 1)
		}
	}
	// Check that the number of bits is within 10 stddevs.
	if math.Abs(float64(numSetBits)-expected) < 10.0*stddev {
		return nil
	}
	return fmt.Errorf("Z test for uniformly distributed variable out of bounds; "+
		"Actual number of set bits was %d expected was %0.00f, 10 * standard deviation is 10 * %0.00f = %0.00f",
		numSetBits, expected, stddev, 10.0*stddev)
}

func rotate(bytes []byte) []byte {
	result := make([]byte, len(bytes))
	for i := 0; i < len(bytes); i++ {
		prev := i
		if i == 0 {
			prev = len(bytes)
		}
		result[i] = (bytes[i] >> 1) |
			(bytes[prev-1] << 7)
	}
	return result
}

// ZTestCrosscorrelationUniformStrings tests that the crosscorrelation of two
// strings of equal length points to independent and uniformly distributed
// strings. Returns non ok status if the z test fails by more than 10 standard
// deviations.
//
// With less statistics jargon: This xors two strings and then performs the
// ZTestUniformString on the result. If the two strings are independent and
// uniformly distributed, the xor'ed string is as well. A cross correlation test
// will find whether two strings overlap more or less than it would be expected.
//
// Note: Having a correlation of zero is only a necessary but not sufficient
// condition for independence.
func ZTestCrosscorrelationUniformStrings(bytes1,
	bytes2 []byte) error {
	if len(bytes1) != len(bytes2) {
		return fmt.Errorf(
			"Strings are not of equal length")
	}
	crossed := make([]byte, len(bytes1))
	for i := 0; i < len(bytes1); i++ {
		crossed[i] = bytes1[i] ^ bytes2[i]
	}
	return ZTestUniformString(crossed)
}

// ZTestAutocorrelationUniformString tests that the autocorrelation of a string
// points to the bits being independent and uniformly distributed.
// Rotates the string in a cyclic fashion. Returns non ok status if the z test
// fails by more than 10 standard deviations.
//
// With less statistics jargon: This rotates the string bit by bit and performs
// ZTestCrosscorrelationUniformStrings on each of the rotated strings and the
// original. This will find self similarity of the input string, especially
// periodic self similarity. For example, it is a decent test to find English
// text (needs about 180 characters with the current settings).
//
// Note: Having a correlation of zero is only a necessary but not sufficient
// condition for independence.
func ZTestAutocorrelationUniformString(bytes []byte) error {
	rotated := make([]byte, len(bytes))
	copy(rotated, bytes)
	violations := []string{}
	for i := 1; i < len(bytes)*8; i++ {
		rotated = rotate(rotated)
		err := ZTestCrosscorrelationUniformStrings(bytes, rotated)
		if err != nil {
			violations = append(violations, strconv.Itoa(i))
		}
	}
	if len(violations) == 0 {
		return nil
	}
	return fmt.Errorf("Autocorrelation exceeded 10 standard deviation at %d indices: %s", len(violations), strings.Join(violations, ", "))
}

// eciesAEADHKDFPublicKey returns a EciesAeadHkdfPublicKey with specified parameters.
func eciesAEADHKDFPublicKey(c commonpb.EllipticCurveType, ht commonpb.HashType, ptfmt commonpb.EcPointFormat, dekT *tinkpb.KeyTemplate, x, y, salt []byte) *eciespb.EciesAeadHkdfPublicKey {
	return &eciespb.EciesAeadHkdfPublicKey{
		Version: 0,
		Params: &eciespb.EciesAeadHkdfParams{
			KemParams: &eciespb.EciesHkdfKemParams{
				CurveType:    c,
				HkdfHashType: ht,
				HkdfSalt:     salt,
			},
			DemParams: &eciespb.EciesAeadDemParams{
				AeadDem: dekT,
			},
			EcPointFormat: ptfmt,
		},
		X: x,
		Y: y,
	}
}

// eciesAEADHKDFPrivateKey returns a EciesAeadHkdfPrivateKey with specified parameters
func eciesAEADHKDFPrivateKey(p *eciespb.EciesAeadHkdfPublicKey, d []byte) *eciespb.EciesAeadHkdfPrivateKey {
	return &eciespb.EciesAeadHkdfPrivateKey{
		Version:   0,
		PublicKey: p,
		KeyValue:  d,
	}
}

// GenerateECIESAEADHKDFPrivateKey generates a new EC key pair and returns the private key proto.
func GenerateECIESAEADHKDFPrivateKey(c commonpb.EllipticCurveType, ht commonpb.HashType, ptfmt commonpb.EcPointFormat, dekT *tinkpb.KeyTemplate, salt []byte) (*eciespb.EciesAeadHkdfPrivateKey, error) {
	curve, err := subtlehybrid.GetCurve(c.String())
	if err != nil {
		return nil, err
	}
	pvt, err := subtlehybrid.GenerateECDHKeyPair(curve)
	if err != nil {
		return nil, err
	}
	pubKey := eciesAEADHKDFPublicKey(c, ht, ptfmt, dekT, pvt.PublicKey.Point.X.Bytes(), pvt.PublicKey.Point.Y.Bytes(), salt)
	//fmt.Println(proto.MarshalTextString(pubKey))
	return eciesAEADHKDFPrivateKey(pubKey, pvt.D.Bytes()), nil
}
