// Copyright 2020 Google LLC
//
// 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 prf contains utilities to calculate pseudo random function families.
package prf

import (
	"fmt"

	"github.com/google/tink/go/core/registry"
	"github.com/google/tink/go/internal/internalregistry"
	"github.com/google/tink/go/monitoring"
)

// The PRF interface is an abstraction for an element of a pseudo random
// function family, selected by a key. It has the following property:
//   - It is deterministic. PRF.compute(input, length) will always return the
//     same output if the same key is used. PRF.compute(input, length1) will be
//     a prefix of PRF.compute(input, length2) if length1 < length2 and the same
//     key is used.
//   - It is indistinguishable from a random function:
//     Given the evaluation of n different inputs, an attacker cannot
//     distinguish between the PRF and random bytes on an input different from
//     the n that are known.
//
// Use cases for PRF are deterministic redaction of PII, keyed hash functions,
// creating sub IDs that do not allow joining with the original dataset without
// knowing the key.
// While PRFs can be used in order to prove authenticity of a message, using the
// MAC interface is recommended for that use case, as it has support for
// verification, avoiding the security problems that often happen during
// verification, and having automatic support for key rotation. It also allows
// for non-deterministic MAC algorithms.
type PRF interface {
	// Computes the PRF selected by the underlying key on input and
	// returns the first outputLength bytes.
	// When choosing this parameter keep the birthday paradox in mind.
	// If you have 2^n different inputs that your system has to handle
	// set the output length (in bytes) to at least
	// ceil(n/4 + 4)
	// This corresponds to 2*n + 32 bits, meaning a collision will occur with
	// a probability less than 1:2^32. When in doubt, request a security review.
	// Returns a non ok status if the algorithm fails or if the output of
	// algorithm is less than outputLength.
	ComputePRF(input []byte, outputLength uint32) ([]byte, error)
}

type monitoredPRF struct {
	prf    PRF
	keyID  uint32
	logger monitoring.Logger
}

var _ PRF = (*monitoredPRF)(nil)

func (w *monitoredPRF) ComputePRF(input []byte, outputLength uint32) ([]byte, error) {
	p, err := w.prf.ComputePRF(input, outputLength)
	if err != nil {
		w.logger.LogFailure()
		return nil, err
	}
	w.logger.Log(w.keyID, len(input))
	return p, nil
}

// Set is a set of PRFs. A Tink Keyset can be converted into a set of PRFs using this primitive. Every
// key in the keyset corresponds to a PRF in the prf.Set.
// Every PRF in the set is given an ID, which is the same ID as the key id in
// the Keyset.
type Set struct {
	// PrimaryID is the key ID marked as primary in the corresponding Keyset.
	PrimaryID uint32
	// PRFs maps key IDs to their corresponding PRF.
	PRFs map[uint32]PRF
}

// ComputePrimaryPRF is equivalent to set.PRFs[set.PrimaryID].ComputePRF(input, outputLength).
func (s Set) ComputePrimaryPRF(input []byte, outputLength uint32) ([]byte, error) {
	prf, ok := s.PRFs[s.PrimaryID]
	if !ok {
		return nil, fmt.Errorf("Could not find primary ID %d in prf.Set", s.PrimaryID)
	}
	return prf.ComputePRF(input, outputLength)
}

func init() {
	if err := registry.RegisterKeyManager(new(hmacprfKeyManager)); err != nil {
		panic(fmt.Sprintf("prf.init() failed: %v", err))
	}
	if err := internalregistry.AllowKeyDerivation(hmacprfTypeURL); err != nil {
		panic(fmt.Sprintf("prf.init() failed: %v", err))
	}
	if err := registry.RegisterKeyManager(new(hkdfprfKeyManager)); err != nil {
		panic(fmt.Sprintf("prf.init() failed: %v", err))
	}
	if err := internalregistry.AllowKeyDerivation(hkdfprfTypeURL); err != nil {
		panic(fmt.Sprintf("prf.init() failed: %v", err))
	}
	if err := registry.RegisterKeyManager(new(aescmacprfKeyManager)); err != nil {
		panic(fmt.Sprintf("prf.init() failed: %v", err))
	}
}
