aboutsummaryrefslogtreecommitdiff
path: root/cc/prf
diff options
context:
space:
mode:
authorsschmieg <sschmieg@google.com>2020-04-01 16:33:28 -0700
committerCopybara-Service <copybara-worker@google.com>2020-04-01 16:34:02 -0700
commita389e601043a61d129264a66d0487c04d84a207a (patch)
tree85ea7b63c452d06be5aaa6e9ce9746c5fd1f6799 /cc/prf
parent61442e6cb557c2adfee4e1ea33500c73bccda8c2 (diff)
downloadtink-a389e601043a61d129264a66d0487c04d84a207a.tar.gz
PrfSet implementation last CL: Registering the key managers and wrappers in the config and adding an end to end test.
Also adds a statistical test to find obvious non randomness. PiperOrigin-RevId: 304286550
Diffstat (limited to 'cc/prf')
-rw-r--r--cc/prf/BUILD.bazel9
-rw-r--r--cc/prf/CMakeLists.txt9
-rw-r--r--cc/prf/prf_config.cc19
-rw-r--r--cc/prf/prf_set_test.cc93
4 files changed, 129 insertions, 1 deletions
diff --git a/cc/prf/BUILD.bazel b/cc/prf/BUILD.bazel
index b110db907..b0bc6abcc 100644
--- a/cc/prf/BUILD.bazel
+++ b/cc/prf/BUILD.bazel
@@ -38,7 +38,10 @@ cc_library(
include_prefix = "tink/prf",
visibility = ["//visibility:public"],
deps = [
+ ":aes_cmac_prf_key_manager",
":hkdf_prf_key_manager",
+ ":hmac_prf_key_manager",
+ ":prf_set_wrapper",
"//:registry",
"//proto:tink_cc_proto",
"//util:status",
@@ -195,8 +198,14 @@ cc_test(
name = "prf_set_test",
srcs = ["prf_set_test.cc"],
deps = [
+ ":prf_config",
+ ":prf_key_templates",
":prf_set",
+ "//:keyset_handle",
+ "//:keyset_manager",
"//util:statusor",
+ "//util:test_matchers",
+ "//util:test_util",
"@com_google_absl//absl/memory",
"@com_google_absl//absl/strings",
"@com_google_googletest//:gtest_main",
diff --git a/cc/prf/CMakeLists.txt b/cc/prf/CMakeLists.txt
index f3114300b..4c61a97ba 100644
--- a/cc/prf/CMakeLists.txt
+++ b/cc/prf/CMakeLists.txt
@@ -32,7 +32,10 @@ tink_cc_library(
prf_config.cc
prf_config.h
DEPS
+ tink::prf::aes_cmac_prf_key_manager
tink::prf::hkdf_prf_key_manager
+ tink::prf::hmac_prf_key_manager
+ tink::prf::prf_set_wrapper
tink::core::registry
tink::util::status
tink::proto::tink_cc_proto
@@ -180,7 +183,13 @@ tink_cc_test(
SRCS prf_set_test.cc
DEPS
tink::prf::prf_set
+ tink::prf::prf_config
+ tink::prf::prf_key_templates
+ tink::core::keyset_handle
+ tink::core::keyset_manager
tink::util::statusor
+ tink::util::test_matchers
+ tink::util::test_util
absl::memory
absl::strings
gmock
diff --git a/cc/prf/prf_config.cc b/cc/prf/prf_config.cc
index 17498513d..1a3861407 100644
--- a/cc/prf/prf_config.cc
+++ b/cc/prf/prf_config.cc
@@ -13,15 +13,32 @@
////////////////////////////////////////////////////////////////////////////////
#include "tink/prf/prf_config.h"
+#include "tink/prf/aes_cmac_prf_key_manager.h"
#include "tink/prf/hkdf_prf_key_manager.h"
+#include "tink/prf/hmac_prf_key_manager.h"
+#include "tink/prf/prf_set_wrapper.h"
#include "tink/registry.h"
namespace crypto {
namespace tink {
crypto::tink::util::Status PrfConfig::Register() {
- return Registry::RegisterKeyTypeManager(
+ auto status = Registry::RegisterKeyTypeManager(
absl::make_unique<HkdfPrfKeyManager>(), true);
+ if (!status.ok()) {
+ return status;
+ }
+ status = Registry::RegisterKeyTypeManager(
+ absl::make_unique<HmacPrfKeyManager>(), true);
+ if (!status.ok()) {
+ return status;
+ }
+ status = Registry::RegisterKeyTypeManager(
+ absl::make_unique<AesCmacPrfKeyManager>(), true);
+ if (!status.ok()) {
+ return status;
+ }
+ return Registry::RegisterPrimitiveWrapper(absl::make_unique<PrfSetWrapper>());
}
} // namespace tink
diff --git a/cc/prf/prf_set_test.cc b/cc/prf/prf_set_test.cc
index e7ee43981..20c592673 100644
--- a/cc/prf/prf_set_test.cc
+++ b/cc/prf/prf_set_test.cc
@@ -19,13 +19,28 @@
#include "gmock/gmock.h"
#include "gtest/gtest.h"
#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"
+#include "tink/keyset_handle.h"
+#include "tink/keyset_manager.h"
+#include "tink/prf/prf_config.h"
+#include "tink/prf/prf_key_templates.h"
#include "tink/util/statusor.h"
+#include "tink/util/test_matchers.h"
+#include "tink/util/test_util.h"
namespace crypto {
namespace tink {
namespace {
+using ::crypto::tink::test::IsOk;
+using ::testing::_;
+using ::testing::Eq;
+using ::testing::Pair;
+using ::testing::SizeIs;
+using ::testing::StrEq;
+using ::testing::UnorderedElementsAre;
+
class DummyPrf : public Prf {
util::StatusOr<std::string> Compute(absl::string_view input,
size_t output_length) const override {
@@ -66,6 +81,84 @@ TEST(PrfSetTest, ComputePrimary) {
<< "Expected broken PrfSet to not be able to compute the primary PRF";
}
+TEST(PrfSetWrapperTest, TestPrimitivesEndToEnd) {
+ auto status = PrfConfig::Register();
+ ASSERT_TRUE(status.ok()) << status;
+ auto keyset_manager_result =
+ KeysetManager::New(PrfKeyTemplates::HkdfSha256());
+ ASSERT_TRUE(keyset_manager_result.ok()) << keyset_manager_result.status();
+ auto keyset_manager = std::move(keyset_manager_result.ValueOrDie());
+ auto id_result = keyset_manager->Add(PrfKeyTemplates::HmacSha256());
+ ASSERT_TRUE(id_result.ok()) << id_result.status();
+ uint32_t hmac_sha256_id = id_result.ValueOrDie();
+ id_result = keyset_manager->Add(PrfKeyTemplates::HmacSha512());
+ ASSERT_TRUE(id_result.ok()) << id_result.status();
+ uint32_t hmac_sha512_id = id_result.ValueOrDie();
+ id_result = keyset_manager->Add(PrfKeyTemplates::AesCmac());
+ ASSERT_TRUE(id_result.ok()) << id_result.status();
+ uint32_t aes_cmac_id = id_result.ValueOrDie();
+ auto keyset_handle = keyset_manager->GetKeysetHandle();
+ uint32_t hkdf_id = keyset_handle->GetKeysetInfo().primary_key_id();
+ auto prf_set_result = keyset_handle->GetPrimitive<PrfSet>();
+ ASSERT_TRUE(prf_set_result.ok()) << prf_set_result.status();
+ auto prf_set = std::move(prf_set_result.ValueOrDie());
+ EXPECT_THAT(prf_set->GetPrimaryId(), Eq(hkdf_id));
+ auto prf_map = prf_set->GetPrfs();
+ EXPECT_THAT(prf_map, UnorderedElementsAre(Pair(Eq(hkdf_id), _),
+ Pair(Eq(hmac_sha256_id), _),
+ Pair(Eq(hmac_sha512_id), _),
+ Pair(Eq(aes_cmac_id), _)));
+ std::string input = "This is an input string";
+ std::string input2 = "This is a second input string";
+ std::vector<size_t> output_lengths = {15, 16, 17, 31, 32,
+ 33, 63, 64, 65, 100};
+ for (size_t output_length : output_lengths) {
+ bool aes_cmac_ok = output_length <= 16;
+ bool hmac_sha256_ok = output_length <= 32;
+ bool hmac_sha512_ok = output_length <= 64;
+ bool hkdf_sha256_ok = output_length <= 8192;
+ std::vector<std::string> results;
+ for (auto prf : prf_map) {
+ SCOPED_TRACE(absl::StrCat("Computing prf ", prf.first,
+ " with output_length ", output_length));
+ bool ok = (prf.first == aes_cmac_id && aes_cmac_ok) ||
+ (prf.first == hmac_sha256_id && hmac_sha256_ok) ||
+ (prf.first == hmac_sha512_id && hmac_sha512_ok) ||
+ (prf.first == hkdf_id && hkdf_sha256_ok);
+ auto output_result = prf.second->Compute(input, output_length);
+ EXPECT_THAT(output_result.ok(), Eq(ok)) << output_result.status();
+ if (!ok) {
+ continue;
+ }
+ std::string output;
+ if (output_result.ok()) {
+ output = output_result.ValueOrDie();
+ results.push_back(output);
+ }
+ output_result = prf.second->Compute(input2, output_length);
+ EXPECT_TRUE(output_result.ok()) << output_result.status();
+ if (output_result.ok()) {
+ results.push_back(output_result.ValueOrDie());
+ }
+ output_result = prf.second->Compute(input, output_length);
+ EXPECT_TRUE(output_result.ok()) << output_result.status();
+ if (output_result.ok()) {
+ EXPECT_THAT(output_result.ValueOrDie(), StrEq(output));
+ }
+ }
+ for (int i = 0; i < results.size(); i++) {
+ EXPECT_THAT(results[i], SizeIs(output_length));
+ EXPECT_THAT(test::ZTestUniformString(results[i]), IsOk());
+ EXPECT_THAT(test::ZTestAutocorrelationUniformString(results[i]), IsOk());
+ for (int j = i + 1; j < results.size(); j++) {
+ EXPECT_THAT(
+ test::ZTestCrosscorrelationUniformStrings(results[i], results[j]),
+ IsOk());
+ }
+ }
+ }
+}
+
} // namespace
} // namespace tink
} // namespace crypto