1*e7b1675dSTing-Kang Chang // Copyright 2020 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 #ifndef TINK_PRF_PRF_SET_H_ 18*e7b1675dSTing-Kang Chang #define TINK_PRF_PRF_SET_H_ 19*e7b1675dSTing-Kang Chang 20*e7b1675dSTing-Kang Chang #include <map> 21*e7b1675dSTing-Kang Chang #include <string> 22*e7b1675dSTing-Kang Chang 23*e7b1675dSTing-Kang Chang #include "absl/strings/string_view.h" 24*e7b1675dSTing-Kang Chang #include "tink/util/statusor.h" 25*e7b1675dSTing-Kang Chang 26*e7b1675dSTing-Kang Chang namespace crypto { 27*e7b1675dSTing-Kang Chang namespace tink { 28*e7b1675dSTing-Kang Chang 29*e7b1675dSTing-Kang Chang // The PRF interface is an abstraction for an element of a pseudo random 30*e7b1675dSTing-Kang Chang // function family, selected by a key. It has the following property: 31*e7b1675dSTing-Kang Chang // * It is deterministic. PRF.compute(input, length) will always return the 32*e7b1675dSTing-Kang Chang // same output if the same key is used. PRF.compute(input, length1) will be 33*e7b1675dSTing-Kang Chang // a prefix of PRF.compute(input, length2) if length1 < length2 and the same 34*e7b1675dSTing-Kang Chang // key is used. 35*e7b1675dSTing-Kang Chang // * It is indistinguishable from a random function: 36*e7b1675dSTing-Kang Chang // Given the evaluation of n different inputs, an attacker cannot 37*e7b1675dSTing-Kang Chang // distinguish between the PRF and random bytes on an input different from 38*e7b1675dSTing-Kang Chang // the n that are known. 39*e7b1675dSTing-Kang Chang // Use cases for PRF are deterministic redaction of PII, keyed hash functions, 40*e7b1675dSTing-Kang Chang // creating sub IDs that do not allow joining with the original dataset without 41*e7b1675dSTing-Kang Chang // knowing the key. 42*e7b1675dSTing-Kang Chang // While PRFs can be used in order to prove authenticity of a message, using the 43*e7b1675dSTing-Kang Chang // MAC interface is recommended for that use case, as it has support for 44*e7b1675dSTing-Kang Chang // verification, avoiding the security problems that often happen during 45*e7b1675dSTing-Kang Chang // verification, and having automatic support for key rotation. It also allows 46*e7b1675dSTing-Kang Chang // for non-deterministic MAC algorithms. 47*e7b1675dSTing-Kang Chang class Prf { 48*e7b1675dSTing-Kang Chang public: 49*e7b1675dSTing-Kang Chang virtual ~Prf() = default; 50*e7b1675dSTing-Kang Chang // Computes the PRF selected by the underlying key on input and 51*e7b1675dSTing-Kang Chang // returns the first outputLength bytes. 52*e7b1675dSTing-Kang Chang // When choosing this parameter keep the birthday paradox in mind. 53*e7b1675dSTing-Kang Chang // If you have 2^n different inputs that your system has to handle 54*e7b1675dSTing-Kang Chang // set the output length (in bytes) to at least 55*e7b1675dSTing-Kang Chang // ceil(n/4 + 4) 56*e7b1675dSTing-Kang Chang // This corresponds to 2*n + 32 bits, meaning a collision will occur with 57*e7b1675dSTing-Kang Chang // a probability less than 1:2^32. When in doubt, request a security review. 58*e7b1675dSTing-Kang Chang // Returns a non ok status if the algorithm fails or if the output of 59*e7b1675dSTing-Kang Chang // algorithm is less than outputLength. 60*e7b1675dSTing-Kang Chang virtual util::StatusOr<std::string> Compute(absl::string_view input, 61*e7b1675dSTing-Kang Chang size_t output_length) const = 0; 62*e7b1675dSTing-Kang Chang }; 63*e7b1675dSTing-Kang Chang 64*e7b1675dSTing-Kang Chang // A Tink Keyset can be converted into a set of PRFs using this primitive. Every 65*e7b1675dSTing-Kang Chang // key in the keyset corresponds to a PRF in the PRFSet. 66*e7b1675dSTing-Kang Chang // Every PRF in the set is given an ID, which is the same ID as the key id in 67*e7b1675dSTing-Kang Chang // the Keyset. 68*e7b1675dSTing-Kang Chang class PrfSet { 69*e7b1675dSTing-Kang Chang public: 70*e7b1675dSTing-Kang Chang virtual ~PrfSet() = default; 71*e7b1675dSTing-Kang Chang // The primary ID of the keyset. 72*e7b1675dSTing-Kang Chang virtual uint32_t GetPrimaryId() const = 0; 73*e7b1675dSTing-Kang Chang // A map of the PRFs represented by the keys in this keyset. 74*e7b1675dSTing-Kang Chang // The map is guaranteed to contain getPrimaryId() as a key. 75*e7b1675dSTing-Kang Chang virtual const std::map<uint32_t, Prf*>& GetPrfs() const = 0; 76*e7b1675dSTing-Kang Chang // Convenience method to compute the primary PRF on a given input. 77*e7b1675dSTing-Kang Chang // See PRF.compute for details of the parameters. 78*e7b1675dSTing-Kang Chang util::StatusOr<std::string> ComputePrimary(absl::string_view input, 79*e7b1675dSTing-Kang Chang size_t output_length) const; 80*e7b1675dSTing-Kang Chang }; 81*e7b1675dSTing-Kang Chang 82*e7b1675dSTing-Kang Chang } // namespace tink 83*e7b1675dSTing-Kang Chang } // namespace crypto 84*e7b1675dSTing-Kang Chang 85*e7b1675dSTing-Kang Chang #endif // TINK_PRF_PRF_SET_H_ 86