aboutsummaryrefslogtreecommitdiff
path: root/cc/experimental
diff options
context:
space:
mode:
authorTink Team <tink-dev@google.com>2021-09-07 17:31:06 -0700
committerCopybara-Service <copybara-worker@google.com>2021-09-07 17:31:51 -0700
commitde6901a410a08e90ea63882c4348082cd6a566b9 (patch)
tree1606af0e5dd27796ccd3eb0f65aded14b637b74c /cc/experimental
parentdfdf4b24cbc36bb4761cb474f086226593ed17b3 (diff)
downloadtink-de6901a410a08e90ea63882c4348082cd6a566b9.tar.gz
Add Sphincs Digital Signature Schemes to the key manager.
PiperOrigin-RevId: 395365169
Diffstat (limited to 'cc/experimental')
-rw-r--r--cc/experimental/pqcrypto/signature/sphincs_sign_key_manager.cc123
-rw-r--r--cc/experimental/pqcrypto/signature/sphincs_sign_key_manager.h87
-rw-r--r--cc/experimental/pqcrypto/signature/sphincs_sign_key_manager_test.cc468
-rw-r--r--cc/experimental/pqcrypto/signature/sphincs_verify_key_manager.cc93
-rw-r--r--cc/experimental/pqcrypto/signature/sphincs_verify_key_manager.h74
-rw-r--r--cc/experimental/pqcrypto/signature/sphincs_verify_key_manager_test.cc443
6 files changed, 1288 insertions, 0 deletions
diff --git a/cc/experimental/pqcrypto/signature/sphincs_sign_key_manager.cc b/cc/experimental/pqcrypto/signature/sphincs_sign_key_manager.cc
new file mode 100644
index 000000000..b20ef6a99
--- /dev/null
+++ b/cc/experimental/pqcrypto/signature/sphincs_sign_key_manager.cc
@@ -0,0 +1,123 @@
+// Copyright 2021 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.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "tink/experimental/pqcrypto/signature/sphincs_sign_key_manager.h"
+
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "tink/experimental/pqcrypto/signature/sphincs_verify_key_manager.h"
+#include "tink/experimental/pqcrypto/signature/subtle/sphincs_sign.h"
+#include "tink/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils.h"
+#include "tink/experimental/pqcrypto/signature/util/enums.h"
+#include "tink/public_key_sign.h"
+#include "tink/util/errors.h"
+#include "tink/util/input_stream_util.h"
+#include "tink/util/protobuf_helper.h"
+#include "tink/util/secret_data.h"
+#include "tink/util/status.h"
+#include "tink/util/statusor.h"
+#include "tink/util/validation.h"
+
+namespace crypto {
+namespace tink {
+
+using ::crypto::tink::subtle::SphincsKeyPair;
+using ::crypto::tink::subtle::SphincsParamsPqclean;
+using ::crypto::tink::subtle::SphincsPrivateKeyPqclean;
+using ::crypto::tink::util::EnumsPqcrypto;
+using ::crypto::tink::util::Status;
+using ::crypto::tink::util::StatusOr;
+using ::google::crypto::tink::SphincsKeyFormat;
+using ::google::crypto::tink::SphincsPrivateKey;
+using ::google::crypto::tink::SphincsPublicKey;
+
+StatusOr<SphincsPrivateKey> SphincsSignKeyManager::CreateKey(
+ const SphincsKeyFormat& key_format) const {
+ SphincsParamsPqclean sphincs_params_pqclean = {
+ .hash_type =
+ EnumsPqcrypto::ProtoToSubtle(key_format.params().hash_type()),
+ .variant = EnumsPqcrypto::ProtoToSubtle(key_format.params().variant()),
+ .sig_length_type =
+ EnumsPqcrypto::ProtoToSubtle(key_format.params().sig_length_type()),
+ .private_key_size = key_format.params().key_size()};
+
+ util::StatusOr<SphincsKeyPair> key_pair =
+ GenerateSphincsKeyPair(sphincs_params_pqclean);
+
+ if (!key_pair.status().ok()) {
+ return key_pair.status();
+ }
+
+ SphincsPrivateKey sphincs_private_key;
+ sphincs_private_key.set_version(get_version());
+ sphincs_private_key.set_key_value(
+ util::SecretDataAsStringView(key_pair->GetPrivateKey().GetKey()));
+
+ SphincsPublicKey* sphincs_public_key =
+ sphincs_private_key.mutable_public_key();
+ sphincs_public_key->set_version(get_version());
+ sphincs_public_key->set_key_value(key_pair->GetPublicKey().GetKey());
+ *(sphincs_public_key->mutable_params()) = key_format.params();
+
+ return sphincs_private_key;
+}
+
+StatusOr<std::unique_ptr<PublicKeySign>>
+SphincsSignKeyManager::PublicKeySignFactory::Create(
+ const SphincsPrivateKey& private_key) const {
+ util::SecretData sk_data =
+ util::SecretDataFromStringView(private_key.key_value());
+ SphincsParamsPqclean sphincs_params_pqclean = {
+ .hash_type = EnumsPqcrypto::ProtoToSubtle(
+ private_key.public_key().params().hash_type()),
+ .variant = EnumsPqcrypto::ProtoToSubtle(
+ private_key.public_key().params().variant()),
+ .sig_length_type = EnumsPqcrypto::ProtoToSubtle(
+ private_key.public_key().params().sig_length_type()),
+ .private_key_size = private_key.public_key().params().key_size()};
+
+ SphincsPrivateKeyPqclean sphincs_private_key_pqclean(sk_data,
+ sphincs_params_pqclean);
+
+ return subtle::SphincsSign::New(sphincs_private_key_pqclean);
+}
+
+Status SphincsSignKeyManager::ValidateKey(const SphincsPrivateKey& key) const {
+ Status status = ValidateVersion(key.version(), get_version());
+ if (!status.ok()) {
+ return status;
+ }
+
+ status = subtle::ValidatePrivateKeySize(key.key_value().length());
+ if (!status.ok()) {
+ return status;
+ }
+
+ return SphincsVerifyKeyManager().ValidateKey(key.public_key());
+}
+
+Status SphincsSignKeyManager::ValidateKeyFormat(
+ const SphincsKeyFormat& key_format) const {
+ if (!key_format.has_params()) {
+ return Status(util::error::INVALID_ARGUMENT, "Missing params.");
+ }
+
+ return SphincsVerifyKeyManager().ValidateParams(key_format.params());
+}
+
+} // namespace tink
+} // namespace crypto
diff --git a/cc/experimental/pqcrypto/signature/sphincs_sign_key_manager.h b/cc/experimental/pqcrypto/signature/sphincs_sign_key_manager.h
new file mode 100644
index 000000000..03655e7a8
--- /dev/null
+++ b/cc/experimental/pqcrypto/signature/sphincs_sign_key_manager.h
@@ -0,0 +1,87 @@
+// Copyright 2021 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.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef TINK_EXPERIMENTAL_PQCRYPTO_SIGNATURE_SPHINCS_SIGN_KEY_MANAGER_H_
+#define TINK_EXPERIMENTAL_PQCRYPTO_SIGNATURE_SPHINCS_SIGN_KEY_MANAGER_H_
+
+#include <string>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "tink/core/private_key_type_manager.h"
+#include "tink/public_key_sign.h"
+#include "tink/util/constants.h"
+#include "tink/util/errors.h"
+#include "tink/util/input_stream_util.h"
+#include "tink/util/protobuf_helper.h"
+#include "tink/util/status.h"
+#include "tink/util/statusor.h"
+#include "proto/experimental/pqcrypto/sphincs.pb.h"
+
+namespace crypto {
+namespace tink {
+
+class SphincsSignKeyManager
+ : public PrivateKeyTypeManager<google::crypto::tink::SphincsPrivateKey,
+ google::crypto::tink::SphincsKeyFormat,
+ google::crypto::tink::SphincsPublicKey,
+ List<PublicKeySign>> {
+ public:
+ class PublicKeySignFactory : public PrimitiveFactory<PublicKeySign> {
+ crypto::tink::util::StatusOr<std::unique_ptr<PublicKeySign>> Create(
+ const google::crypto::tink::SphincsPrivateKey& private_key)
+ const override;
+ };
+
+ SphincsSignKeyManager()
+ : PrivateKeyTypeManager(absl::make_unique<PublicKeySignFactory>()) {}
+
+ uint32_t get_version() const override { return 0; }
+
+ google::crypto::tink::KeyData::KeyMaterialType key_material_type()
+ const override {
+ return google::crypto::tink::KeyData::ASYMMETRIC_PRIVATE;
+ }
+
+ const std::string& get_key_type() const override { return key_type_; }
+
+ crypto::tink::util::Status ValidateKey(
+ const google::crypto::tink::SphincsPrivateKey& key) const override;
+
+ crypto::tink::util::Status ValidateKeyFormat(
+ const google::crypto::tink::SphincsKeyFormat& key_format)
+ const override;
+
+ crypto::tink::util::StatusOr<google::crypto::tink::SphincsPrivateKey>
+ CreateKey(const google::crypto::tink::SphincsKeyFormat& key_format)
+ const override;
+
+ crypto::tink::util::StatusOr<google::crypto::tink::SphincsPublicKey>
+ GetPublicKey(const google::crypto::tink::SphincsPrivateKey& private_key)
+ const override {
+ return private_key.public_key();
+ }
+
+ private:
+ const std::string key_type_ =
+ absl::StrCat(kTypeGoogleapisCom,
+ google::crypto::tink::SphincsPrivateKey().GetTypeName());
+};
+
+} // namespace tink
+} // namespace crypto
+
+#endif // TINK_EXPERIMENTAL_PQCRYPTO_SIGNATURE_SPHINCS_SIGN_KEY_MANAGER_H_
diff --git a/cc/experimental/pqcrypto/signature/sphincs_sign_key_manager_test.cc b/cc/experimental/pqcrypto/signature/sphincs_sign_key_manager_test.cc
new file mode 100644
index 000000000..261cf74ba
--- /dev/null
+++ b/cc/experimental/pqcrypto/signature/sphincs_sign_key_manager_test.cc
@@ -0,0 +1,468 @@
+// Copyright 2021 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.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "tink/experimental/pqcrypto/signature/sphincs_sign_key_manager.h"
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "absl/container/flat_hash_set.h"
+#include "absl/strings/str_cat.h"
+#include "tink/experimental/pqcrypto/signature/sphincs_verify_key_manager.h"
+#include "tink/experimental/pqcrypto/signature/subtle/sphincs_sign.h"
+#include "tink/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils.h"
+#include "tink/experimental/pqcrypto/signature/subtle/sphincs_verify.h"
+#include "tink/experimental/pqcrypto/signature/util/enums.h"
+#include "tink/public_key_verify.h"
+#include "tink/util/secret_data.h"
+#include "tink/util/status.h"
+#include "tink/util/statusor.h"
+#include "tink/util/test_matchers.h"
+
+extern "C" {
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-128f-robust/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-128f-simple/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-128s-robust/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-128s-simple/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-192f-robust/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-192f-simple/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-192s-robust/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-192s-simple/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-256f-robust/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-256f-simple/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-256s-robust/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-256s-simple/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-128f-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-128f-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-128s-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-128s-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-192f-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-192f-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-192s-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-192s-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-256f-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-256f-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-256s-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-256s-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-128f-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-128f-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-128s-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-128s-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-192f-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-192f-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-192s-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-192s-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-256f-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-256f-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-256s-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-256s-simple/avx2/api.h"
+}
+
+namespace crypto {
+namespace tink {
+namespace {
+
+using ::crypto::tink::subtle::SphincsPublicKeyPqclean;
+using ::crypto::tink::test::IsOk;
+using ::crypto::tink::util::EnumsPqcrypto;
+using ::crypto::tink::util::StatusOr;
+using ::google::crypto::tink::KeyData;
+using ::google::crypto::tink::SphincsHashType;
+using ::google::crypto::tink::SphincsKeyFormat;
+using ::google::crypto::tink::SphincsParams;
+using ::google::crypto::tink::SphincsPrivateKey;
+using ::google::crypto::tink::SphincsPublicKey;
+using ::google::crypto::tink::SphincsSignatureType;
+using ::google::crypto::tink::SphincsVariant;
+using ::testing::Eq;
+using ::testing::Not;
+using ::testing::SizeIs;
+
+struct SphincsTestCase {
+ std::string test_name;
+ SphincsHashType hash_type;
+ SphincsVariant variant;
+ SphincsSignatureType sig_length_type;
+ int32_t private_key_size;
+ int32_t public_key_size;
+};
+
+using SphincsSignKeyManagerTest = testing::TestWithParam<SphincsTestCase>;
+
+// Helper function that returns a valid sphincs key format.
+StatusOr<SphincsKeyFormat> CreateValidKeyFormat(int32 private_key_size,
+ SphincsHashType hash_type,
+ SphincsVariant variant,
+ SphincsSignatureType type) {
+ SphincsKeyFormat key_format;
+ SphincsParams* params = key_format.mutable_params();
+ params->set_key_size(private_key_size);
+ params->set_hash_type(hash_type);
+ params->set_variant(variant);
+ params->set_sig_length_type(type);
+
+ return key_format;
+}
+
+TEST(SphincsSignKeyManagerTest, Basic) {
+ EXPECT_THAT(SphincsSignKeyManager().get_version(), Eq(0));
+ EXPECT_THAT(SphincsSignKeyManager().key_material_type(),
+ Eq(KeyData::ASYMMETRIC_PRIVATE));
+ EXPECT_THAT(SphincsSignKeyManager().get_key_type(),
+ Eq("type.googleapis.com/google.crypto.tink.SphincsPrivateKey"));
+}
+
+TEST_P(SphincsSignKeyManagerTest, ValidKeyFormat) {
+ const SphincsTestCase& test_case = GetParam();
+
+ StatusOr<SphincsKeyFormat> key_format =
+ CreateValidKeyFormat(test_case.private_key_size, test_case.hash_type,
+ test_case.variant, test_case.sig_length_type);
+ ASSERT_THAT(key_format.status(), IsOk());
+
+ EXPECT_THAT(SphincsSignKeyManager().ValidateKeyFormat(*key_format), IsOk());
+}
+
+TEST(SphincsSignKeyManagerTest, InvalidKeyFormat) {
+ StatusOr<SphincsKeyFormat> key_format = CreateValidKeyFormat(
+ subtle::kSphincsPrivateKeySize64, SphincsHashType::UNKNOWN_HASH_TYPE,
+ SphincsVariant::UNKNOWN_VARIANT, SphincsSignatureType::UNKNOWN_SIG_TYPE);
+ ASSERT_THAT(key_format.status(), IsOk());
+
+ EXPECT_THAT(SphincsSignKeyManager().ValidateKeyFormat(*key_format),
+ Not(IsOk()));
+}
+
+TEST_P(SphincsSignKeyManagerTest, CreateKeyValid) {
+ const SphincsTestCase& test_case = GetParam();
+
+ StatusOr<SphincsKeyFormat> key_format =
+ CreateValidKeyFormat(test_case.private_key_size, test_case.hash_type,
+ test_case.variant, test_case.sig_length_type);
+ ASSERT_THAT(key_format.status(), IsOk());
+
+ StatusOr<SphincsPrivateKey> private_key =
+ SphincsSignKeyManager().CreateKey(*key_format);
+ ASSERT_THAT(private_key.status(), IsOk());
+
+ EXPECT_THAT(SphincsSignKeyManager().ValidateKey(*private_key), IsOk());
+ EXPECT_THAT(private_key->version(), Eq(0));
+ EXPECT_THAT(private_key->public_key().version(), Eq(private_key->version()));
+ EXPECT_THAT(private_key->key_value(), SizeIs(test_case.private_key_size));
+}
+
+TEST_P(SphincsSignKeyManagerTest, PrivateKeyWrongVersion) {
+ const SphincsTestCase& test_case = GetParam();
+
+ StatusOr<SphincsKeyFormat> key_format =
+ CreateValidKeyFormat(test_case.private_key_size, test_case.hash_type,
+ test_case.variant, test_case.sig_length_type);
+ ASSERT_THAT(key_format.status(), IsOk());
+
+ StatusOr<SphincsPrivateKey> private_key =
+ SphincsSignKeyManager().CreateKey(*key_format);
+ ASSERT_THAT(private_key.status(), IsOk());
+
+ private_key->set_version(1);
+ EXPECT_THAT(SphincsSignKeyManager().ValidateKey(*private_key), Not(IsOk()));
+}
+
+TEST(SphincsSignKeyManagerTest, CreateKeyInvalidParams) {
+ StatusOr<SphincsKeyFormat> key_format = CreateValidKeyFormat(
+ subtle::kSphincsPrivateKeySize64, SphincsHashType::UNKNOWN_HASH_TYPE,
+ SphincsVariant::UNKNOWN_VARIANT, SphincsSignatureType::UNKNOWN_SIG_TYPE);
+ ASSERT_THAT(key_format.status(), IsOk());
+
+ StatusOr<SphincsPrivateKey> private_key =
+ SphincsSignKeyManager().CreateKey(*key_format);
+ EXPECT_THAT(private_key.status(), Not(IsOk()));
+}
+
+TEST_P(SphincsSignKeyManagerTest, CreateKeyAlwaysNew) {
+ const SphincsTestCase& test_case = GetParam();
+
+ StatusOr<SphincsKeyFormat> key_format =
+ CreateValidKeyFormat(test_case.private_key_size, test_case.hash_type,
+ test_case.variant, test_case.sig_length_type);
+ ASSERT_THAT(key_format.status(), IsOk());
+
+ absl::flat_hash_set<std::string> keys;
+ int num_tests = 5;
+ for (int i = 0; i < num_tests; ++i) {
+ StatusOr<SphincsPrivateKey> private_key =
+ SphincsSignKeyManager().CreateKey(*key_format);
+ ASSERT_THAT(private_key.status(), IsOk());
+ keys.insert(private_key->key_value());
+ }
+ EXPECT_THAT(keys, SizeIs(num_tests));
+}
+
+TEST_P(SphincsSignKeyManagerTest, GetPublicKey) {
+ const SphincsTestCase& test_case = GetParam();
+
+ StatusOr<SphincsKeyFormat> key_format =
+ CreateValidKeyFormat(test_case.private_key_size, test_case.hash_type,
+ test_case.variant, test_case.sig_length_type);
+ ASSERT_THAT(key_format.status(), IsOk());
+
+ StatusOr<SphincsPrivateKey> private_key =
+ SphincsSignKeyManager().CreateKey(*key_format);
+ ASSERT_THAT(private_key.status(), IsOk());
+
+ StatusOr<SphincsPublicKey> public_key_or =
+ SphincsSignKeyManager().GetPublicKey(*private_key);
+ ASSERT_THAT(public_key_or.status(), IsOk());
+
+ EXPECT_THAT(public_key_or->version(),
+ Eq(private_key->public_key().version()));
+ EXPECT_THAT(public_key_or->key_value(),
+ Eq(private_key->public_key().key_value()));
+}
+
+TEST_P(SphincsSignKeyManagerTest, CreateValid) {
+ const SphincsTestCase& test_case = GetParam();
+
+ StatusOr<SphincsKeyFormat> key_format =
+ CreateValidKeyFormat(test_case.private_key_size, test_case.hash_type,
+ test_case.variant, test_case.sig_length_type);
+ ASSERT_THAT(key_format.status(), IsOk());
+
+ util::StatusOr<SphincsPrivateKey> private_key =
+ SphincsSignKeyManager().CreateKey(*key_format);
+ ASSERT_THAT(private_key.status(), IsOk());
+
+ util::StatusOr<std::unique_ptr<PublicKeySign>> signer =
+ SphincsSignKeyManager().GetPrimitive<PublicKeySign>(*private_key);
+ ASSERT_THAT(signer.status(), IsOk());
+
+ subtle::SphincsParamsPqclean sphincs_params_pqclean = {
+ .hash_type = EnumsPqcrypto::ProtoToSubtle(test_case.hash_type),
+ .variant = EnumsPqcrypto::ProtoToSubtle(test_case.variant),
+ .sig_length_type =
+ EnumsPqcrypto::ProtoToSubtle(test_case.sig_length_type),
+ .private_key_size = test_case.private_key_size};
+
+ SphincsPublicKeyPqclean sphincs_public_key_pqclean(
+ private_key->public_key().key_value(), sphincs_params_pqclean);
+
+ util::StatusOr<std::unique_ptr<PublicKeyVerify>> verifier =
+ subtle::SphincsVerify::New(sphincs_public_key_pqclean);
+ ASSERT_THAT(verifier.status(), IsOk());
+
+ std::string message = "Some message";
+ util::StatusOr<std::string> signature = (*signer)->Sign(message);
+ ASSERT_THAT(signature.status(), IsOk());
+ EXPECT_THAT((*verifier)->Verify(*signature, message), IsOk());
+}
+
+TEST_P(SphincsSignKeyManagerTest, CreateBadPublicKey) {
+ const SphincsTestCase& test_case = GetParam();
+
+ StatusOr<SphincsKeyFormat> key_format =
+ CreateValidKeyFormat(test_case.private_key_size, test_case.hash_type,
+ test_case.variant, test_case.sig_length_type);
+ ASSERT_THAT(key_format.status(), IsOk());
+
+ util::StatusOr<SphincsPrivateKey> private_key =
+ SphincsSignKeyManager().CreateKey(*key_format);
+ ASSERT_THAT(private_key.status(), IsOk());
+
+ util::StatusOr<std::unique_ptr<PublicKeySign>> signer =
+ SphincsSignKeyManager().GetPrimitive<PublicKeySign>(*private_key);
+ ASSERT_THAT(signer.status(), IsOk());
+
+ std::string bad_public_key_data(test_case.public_key_size, '@');
+
+ subtle::SphincsParamsPqclean sphincs_params_pqclean = {
+ .hash_type = EnumsPqcrypto::ProtoToSubtle(test_case.hash_type),
+ .variant = EnumsPqcrypto::ProtoToSubtle(test_case.variant),
+ .sig_length_type =
+ EnumsPqcrypto::ProtoToSubtle(test_case.sig_length_type),
+ .private_key_size = test_case.private_key_size};
+
+ SphincsPublicKeyPqclean sphincs_public_key_pqclean(bad_public_key_data,
+ sphincs_params_pqclean);
+ util::StatusOr<std::unique_ptr<PublicKeyVerify>> direct_verifier =
+ subtle::SphincsVerify::New(sphincs_public_key_pqclean);
+ ASSERT_THAT(direct_verifier.status(), IsOk());
+
+ std::string message = "Some message";
+ util::StatusOr<std::string> signature = (*signer)->Sign(message);
+ ASSERT_THAT(signature.status(), IsOk());
+ EXPECT_THAT((*direct_verifier)->Verify(*signature, message), Not(IsOk()));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ SphincsSignKeyManagerTests, SphincsSignKeyManagerTest,
+ testing::ValuesIn<SphincsTestCase>(
+ {{"SPHINCSHARAKA128FROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSHARAKA128FROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128FROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA128SROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSHARAKA128SROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128SROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA128FSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSHARAKA128FSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128FSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA128SSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSHARAKA128SSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128SSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSHARAKA192FROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSHARAKA192FROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192FROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA192SROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSHARAKA192SROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192SROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA192FSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSHARAKA192FSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192FSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA192SSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSHARAKA192SSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192SSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSHARAKA256FROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSHARAKA256FROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256FROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA256SROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSHARAKA256SROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256SROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA256FSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSHARAKA256FSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256FSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA256SSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSHARAKA256SSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256SSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHA256128FROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHA256128FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256128SROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHA256128SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256128FSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHA256128FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256128SSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHA256128SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHA256192FROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHA256192FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256192SROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256192FSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHA256192FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256192SSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHA256192SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHA256256FROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHA256256FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256256SROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHA256256SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256256FSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256256SSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHA256256SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHAKE256128FROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHAKE256128FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256128SROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHAKE256128SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256128FSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHAKE256128FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256128SSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHAKE256128SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHAKE256192FROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHAKE256192FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256192SROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHAKE256192SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256192FSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHAKE256192FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256192SSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHAKE256192SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHAKE256256FROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHAKE256256FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256256SROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHAKE256256SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256256FSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHAKE256256FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256256SSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHAKE256256SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES}}),
+ [](const testing::TestParamInfo<SphincsSignKeyManagerTest::ParamType>&
+ info) { return info.param.test_name; });
+
+} // namespace
+
+} // namespace tink
+} // namespace crypto
diff --git a/cc/experimental/pqcrypto/signature/sphincs_verify_key_manager.cc b/cc/experimental/pqcrypto/signature/sphincs_verify_key_manager.cc
new file mode 100644
index 000000000..266a8f302
--- /dev/null
+++ b/cc/experimental/pqcrypto/signature/sphincs_verify_key_manager.cc
@@ -0,0 +1,93 @@
+// Copyright 2021 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.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "tink/experimental/pqcrypto/signature/sphincs_verify_key_manager.h"
+
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "absl/strings/string_view.h"
+#include "tink/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils.h"
+#include "tink/experimental/pqcrypto/signature/subtle/sphincs_verify.h"
+#include "tink/experimental/pqcrypto/signature/util/enums.h"
+#include "tink/public_key_verify.h"
+#include "tink/util/errors.h"
+#include "tink/util/input_stream_util.h"
+#include "tink/util/protobuf_helper.h"
+#include "tink/util/secret_data.h"
+#include "tink/util/status.h"
+#include "tink/util/statusor.h"
+#include "tink/util/validation.h"
+
+namespace crypto {
+namespace tink {
+
+using ::crypto::tink::subtle::SphincsParamsPqclean;
+using ::crypto::tink::subtle::SphincsPublicKeyPqclean;
+using ::crypto::tink::util::EnumsPqcrypto;
+using ::crypto::tink::util::Status;
+using ::crypto::tink::util::StatusOr;
+using ::google::crypto::tink::SphincsParams;
+using ::google::crypto::tink::SphincsPublicKey;
+
+StatusOr<std::unique_ptr<PublicKeyVerify>>
+SphincsVerifyKeyManager::PublicKeyVerifyFactory::Create(
+ const SphincsPublicKey& public_key) const {
+ SphincsParamsPqclean sphincs_params_pqclean = {
+ .hash_type =
+ EnumsPqcrypto::ProtoToSubtle(public_key.params().hash_type()),
+ .variant = EnumsPqcrypto::ProtoToSubtle(public_key.params().variant()),
+ .sig_length_type =
+ EnumsPqcrypto::ProtoToSubtle(public_key.params().sig_length_type()),
+ .private_key_size = public_key.params().key_size()};
+
+ SphincsPublicKeyPqclean sphincs_public_key_pqclean(public_key.key_value(),
+ sphincs_params_pqclean);
+
+ return subtle::SphincsVerify::New(sphincs_public_key_pqclean);
+}
+
+Status SphincsVerifyKeyManager::ValidateKey(const SphincsPublicKey& key) const {
+ Status status = ValidateVersion(key.version(), get_version());
+ if (!status.ok()) {
+ return status;
+ }
+
+ status = subtle::ValidatePublicKeySize(key.key_value().length());
+ if (!status.ok()) {
+ return status;
+ }
+
+ return Status::OK;
+}
+
+Status SphincsVerifyKeyManager::ValidateParams(
+ const SphincsParams& params) const {
+ SphincsParamsPqclean sphincs_params_pqclean = {
+ .hash_type = EnumsPqcrypto::ProtoToSubtle(params.hash_type()),
+ .variant = EnumsPqcrypto::ProtoToSubtle(params.variant()),
+ .sig_length_type = EnumsPqcrypto::ProtoToSubtle(params.sig_length_type()),
+ .private_key_size = params.key_size()};
+
+ Status status = subtle::ValidateParams(sphincs_params_pqclean);
+ if (!status.ok()) {
+ return status;
+ }
+
+ return Status::OK;
+}
+
+} // namespace tink
+} // namespace crypto
diff --git a/cc/experimental/pqcrypto/signature/sphincs_verify_key_manager.h b/cc/experimental/pqcrypto/signature/sphincs_verify_key_manager.h
new file mode 100644
index 000000000..d0d228300
--- /dev/null
+++ b/cc/experimental/pqcrypto/signature/sphincs_verify_key_manager.h
@@ -0,0 +1,74 @@
+// Copyright 2021 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.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#ifndef TINK_EXPERIMENTAL_PQCRYPTO_SIGNATURE_SPHINCS_VERIFY_KEY_MANAGER_H_
+#define TINK_EXPERIMENTAL_PQCRYPTO_SIGNATURE_SPHINCS_VERIFY_KEY_MANAGER_H_
+
+#include <string>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/str_cat.h"
+#include "tink/core/private_key_type_manager.h"
+#include "tink/public_key_verify.h"
+#include "tink/util/constants.h"
+#include "tink/util/errors.h"
+#include "tink/util/input_stream_util.h"
+#include "tink/util/protobuf_helper.h"
+#include "tink/util/status.h"
+#include "tink/util/statusor.h"
+#include "proto/experimental/pqcrypto/sphincs.pb.h"
+
+namespace crypto {
+namespace tink {
+
+class SphincsVerifyKeyManager
+ : public KeyTypeManager<google::crypto::tink::SphincsPublicKey, void,
+ List<PublicKeyVerify>> {
+ public:
+ class PublicKeyVerifyFactory : public PrimitiveFactory<PublicKeyVerify> {
+ crypto::tink::util::StatusOr<std::unique_ptr<PublicKeyVerify>> Create(
+ const google::crypto::tink::SphincsPublicKey& public_key)
+ const override;
+ };
+
+ SphincsVerifyKeyManager()
+ : KeyTypeManager(absl::make_unique<PublicKeyVerifyFactory>()) {}
+
+ uint32_t get_version() const override { return 0; }
+
+ google::crypto::tink::KeyData::KeyMaterialType key_material_type()
+ const override {
+ return google::crypto::tink::KeyData::ASYMMETRIC_PUBLIC;
+ }
+
+ const std::string& get_key_type() const override { return key_type_; }
+
+ crypto::tink::util::Status ValidateKey(
+ const google::crypto::tink::SphincsPublicKey& key) const override;
+
+ crypto::tink::util::Status ValidateParams(
+ const google::crypto::tink::SphincsParams& params) const;
+
+ private:
+ const std::string key_type_ =
+ absl::StrCat(kTypeGoogleapisCom,
+ google::crypto::tink::SphincsPublicKey().GetTypeName());
+};
+
+} // namespace tink
+} // namespace crypto
+
+#endif // TINK_EXPERIMENTAL_PQCRYPTO_SIGNATURE_SPHINCS_VERIFY_KEY_MANAGER_H_
diff --git a/cc/experimental/pqcrypto/signature/sphincs_verify_key_manager_test.cc b/cc/experimental/pqcrypto/signature/sphincs_verify_key_manager_test.cc
new file mode 100644
index 000000000..5fc6f3db0
--- /dev/null
+++ b/cc/experimental/pqcrypto/signature/sphincs_verify_key_manager_test.cc
@@ -0,0 +1,443 @@
+// Copyright 2021 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.
+//
+///////////////////////////////////////////////////////////////////////////////
+
+#include "tink/experimental/pqcrypto/signature/sphincs_verify_key_manager.h"
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "absl/container/flat_hash_set.h"
+#include "absl/strings/str_cat.h"
+#include "tink/experimental/pqcrypto/signature/sphincs_sign_key_manager.h"
+#include "tink/experimental/pqcrypto/signature/subtle/sphincs_sign.h"
+#include "tink/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils.h"
+#include "tink/experimental/pqcrypto/signature/subtle/sphincs_verify.h"
+#include "tink/experimental/pqcrypto/signature/util/enums.h"
+#include "tink/public_key_verify.h"
+#include "tink/util/secret_data.h"
+#include "tink/util/status.h"
+#include "tink/util/statusor.h"
+#include "tink/util/test_matchers.h"
+
+extern "C" {
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-128f-robust/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-128f-simple/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-128s-robust/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-128s-simple/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-192f-robust/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-192f-simple/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-192s-robust/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-192s-simple/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-256f-robust/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-256f-simple/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-256s-robust/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-haraka-256s-simple/aesni/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-128f-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-128f-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-128s-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-128s-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-192f-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-192f-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-192s-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-192s-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-256f-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-256f-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-256s-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-sha256-256s-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-128f-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-128f-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-128s-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-128s-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-192f-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-192f-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-192s-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-192s-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-256f-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-256f-simple/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-256s-robust/avx2/api.h"
+#include "third_party/pqclean/crypto_sign/sphincs-shake256-256s-simple/avx2/api.h"
+}
+
+namespace crypto {
+namespace tink {
+namespace {
+
+using ::crypto::tink::test::IsOk;
+using ::crypto::tink::util::EnumsPqcrypto;
+using ::crypto::tink::util::StatusOr;
+using ::google::crypto::tink::KeyData;
+using ::google::crypto::tink::SphincsHashType;
+using ::google::crypto::tink::SphincsKeyFormat;
+using ::google::crypto::tink::SphincsParams;
+using ::google::crypto::tink::SphincsPrivateKey;
+using ::google::crypto::tink::SphincsPublicKey;
+using ::google::crypto::tink::SphincsSignatureType;
+using ::google::crypto::tink::SphincsVariant;
+using ::testing::Eq;
+using ::testing::Not;
+
+struct SphincsTestCase {
+ std::string test_name;
+ SphincsHashType hash_type;
+ SphincsVariant variant;
+ SphincsSignatureType sig_length_type;
+ int32_t private_key_size;
+ int32_t public_key_size;
+};
+
+using SphincsVerifyKeyManagerTest = testing::TestWithParam<SphincsTestCase>;
+
+// Helper function that returns a valid sphincs private key.
+StatusOr<SphincsPrivateKey> CreateValidPrivateKey(int32 private_key_size,
+ SphincsHashType hash_type,
+ SphincsVariant variant,
+ SphincsSignatureType type) {
+ SphincsKeyFormat key_format;
+ SphincsParams* params = key_format.mutable_params();
+ params->set_key_size(private_key_size);
+ params->set_hash_type(hash_type);
+ params->set_variant(variant);
+ params->set_sig_length_type(type);
+
+ return SphincsSignKeyManager().CreateKey(key_format);
+}
+
+// Helper function that returns a valid sphincs public key.
+StatusOr<SphincsPublicKey> CreateValidPublicKey(int32 private_key_size,
+ SphincsHashType hash_type,
+ SphincsVariant variant,
+ SphincsSignatureType type) {
+ StatusOr<SphincsPrivateKey> private_key =
+ CreateValidPrivateKey(private_key_size, hash_type, variant, type);
+
+ if (!private_key.ok()) return private_key.status();
+ return SphincsSignKeyManager().GetPublicKey(*private_key);
+}
+
+TEST(SphincsVerifyKeyManagerTest, Basics) {
+ EXPECT_THAT(SphincsVerifyKeyManager().get_version(), Eq(0));
+ EXPECT_THAT(SphincsVerifyKeyManager().key_material_type(),
+ Eq(KeyData::ASYMMETRIC_PUBLIC));
+ EXPECT_THAT(SphincsVerifyKeyManager().get_key_type(),
+ Eq("type.googleapis.com/google.crypto.tink.SphincsPublicKey"));
+}
+
+TEST(SphincsVerifyKeyManagerTest, ValidateEmptyKey) {
+ EXPECT_THAT(SphincsVerifyKeyManager().ValidateKey(SphincsPublicKey()),
+ Not(IsOk()));
+}
+
+TEST_P(SphincsVerifyKeyManagerTest, InvalidParam) {
+ const SphincsTestCase& test_case = GetParam();
+
+ SphincsKeyFormat key_format;
+ SphincsParams* params = key_format.mutable_params();
+ params->set_key_size(test_case.private_key_size);
+ params->set_hash_type(test_case.hash_type);
+ params->set_variant(test_case.variant);
+ params->set_sig_length_type(SphincsSignatureType::UNKNOWN_SIG_TYPE);
+
+ EXPECT_THAT(SphincsVerifyKeyManager().ValidateParams(*params), Not(IsOk()));
+}
+
+TEST_P(SphincsVerifyKeyManagerTest, PublicKeyValid) {
+ const SphincsTestCase& test_case = GetParam();
+
+ StatusOr<SphincsPublicKey> public_key =
+ CreateValidPublicKey(test_case.private_key_size, test_case.hash_type,
+ test_case.variant, test_case.sig_length_type);
+ ASSERT_THAT(public_key.status(), IsOk());
+
+ EXPECT_THAT(SphincsVerifyKeyManager().ValidateKey(*public_key), IsOk());
+}
+
+TEST(SphincsVerifyKeyManagerTest, PublicKeyInvalidParams) {
+ StatusOr<SphincsPublicKey> public_key = CreateValidPublicKey(
+ subtle::kSphincsPrivateKeySize64, SphincsHashType::UNKNOWN_HASH_TYPE,
+ SphincsVariant::UNKNOWN_VARIANT, SphincsSignatureType::UNKNOWN_SIG_TYPE);
+ EXPECT_THAT(public_key.status(), Not(IsOk()));
+}
+
+TEST_P(SphincsVerifyKeyManagerTest, PublicKeyWrongVersion) {
+ const SphincsTestCase& test_case = GetParam();
+
+ StatusOr<SphincsPublicKey> public_key =
+ CreateValidPublicKey(test_case.private_key_size, test_case.hash_type,
+ test_case.variant, test_case.sig_length_type);
+ ASSERT_THAT(public_key.status(), IsOk());
+
+ public_key->set_version(1);
+ EXPECT_THAT(SphincsVerifyKeyManager().ValidateKey(*public_key), Not(IsOk()));
+}
+
+TEST_P(SphincsVerifyKeyManagerTest, Create) {
+ const SphincsTestCase& test_case = GetParam();
+
+ StatusOr<SphincsPrivateKey> private_key =
+ CreateValidPrivateKey(test_case.private_key_size, test_case.hash_type,
+ test_case.variant, test_case.sig_length_type);
+ ASSERT_THAT(private_key.status(), IsOk());
+
+ StatusOr<SphincsPublicKey> public_key =
+ SphincsSignKeyManager().GetPublicKey(*private_key);
+ ASSERT_THAT(public_key.status(), IsOk());
+
+ subtle::SphincsParamsPqclean sphincs_params_pqclean = {
+ .hash_type = EnumsPqcrypto::ProtoToSubtle(test_case.hash_type),
+ .variant = EnumsPqcrypto::ProtoToSubtle(test_case.variant),
+ .sig_length_type =
+ EnumsPqcrypto::ProtoToSubtle(test_case.sig_length_type),
+ .private_key_size = test_case.private_key_size};
+ subtle::SphincsPrivateKeyPqclean sphincs_private_key_pqclean(
+ util::SecretDataFromStringView(private_key->key_value()),
+ sphincs_params_pqclean);
+
+ util::StatusOr<std::unique_ptr<PublicKeySign>> direct_signer =
+ subtle::SphincsSign::New(sphincs_private_key_pqclean);
+ ASSERT_THAT(direct_signer.status(), IsOk());
+
+ util::StatusOr<std::unique_ptr<PublicKeyVerify>> verifier =
+ SphincsVerifyKeyManager().GetPrimitive<PublicKeyVerify>(*public_key);
+ ASSERT_THAT(verifier.status(), IsOk());
+
+ std::string message = "Some message";
+ util::StatusOr<std::string> signature = (*direct_signer)->Sign(message);
+ ASSERT_THAT(signature.status(), IsOk());
+ EXPECT_THAT((*verifier)->Verify(*signature, message), IsOk());
+}
+
+TEST_P(SphincsVerifyKeyManagerTest, CreateInvalidPublicKey) {
+ const SphincsTestCase& test_case = GetParam();
+
+ StatusOr<SphincsPrivateKey> private_key =
+ CreateValidPrivateKey(test_case.private_key_size, test_case.hash_type,
+ test_case.variant, test_case.sig_length_type);
+ ASSERT_THAT(private_key.status(), IsOk());
+
+ StatusOr<SphincsPublicKey> public_key =
+ SphincsSignKeyManager().GetPublicKey(*private_key);
+ ASSERT_THAT(public_key.status(), IsOk());
+
+ std::string bad_public_key_data = "bad_public_key";
+ public_key->set_key_value(bad_public_key_data);
+
+ util::StatusOr<std::unique_ptr<PublicKeyVerify>> verifier =
+ SphincsVerifyKeyManager().GetPrimitive<PublicKeyVerify>(*public_key);
+ EXPECT_THAT(verifier.status(), Not(IsOk()));
+}
+
+TEST_P(SphincsVerifyKeyManagerTest, CreateDifferentPublicKey) {
+ const SphincsTestCase& test_case = GetParam();
+
+ StatusOr<SphincsPrivateKey> private_key =
+ CreateValidPrivateKey(test_case.private_key_size, test_case.hash_type,
+ test_case.variant, test_case.sig_length_type);
+ ASSERT_THAT(private_key.status(), IsOk());
+
+ // Create a new public key derived from a diffferent private key.
+ StatusOr<SphincsPrivateKey> new_private_key =
+ CreateValidPrivateKey(test_case.private_key_size, test_case.hash_type,
+ test_case.variant, test_case.sig_length_type);
+ ASSERT_THAT(new_private_key.status(), IsOk());
+ StatusOr<SphincsPublicKey> public_key =
+ SphincsSignKeyManager().GetPublicKey(*new_private_key);
+ ASSERT_THAT(public_key.status(), IsOk());
+
+ subtle::SphincsParamsPqclean sphincs_params_pqclean = {
+ .hash_type = EnumsPqcrypto::ProtoToSubtle(test_case.hash_type),
+ .variant = EnumsPqcrypto::ProtoToSubtle(test_case.variant),
+ .sig_length_type =
+ EnumsPqcrypto::ProtoToSubtle(test_case.sig_length_type),
+ .private_key_size = test_case.private_key_size};
+ subtle::SphincsPrivateKeyPqclean sphincs_private_key_pqclean(
+ util::SecretDataFromStringView(private_key->key_value()),
+ sphincs_params_pqclean);
+
+ util::StatusOr<std::unique_ptr<PublicKeySign>> direct_signer =
+ subtle::SphincsSign::New(sphincs_private_key_pqclean);
+ ASSERT_THAT(direct_signer.status(), IsOk());
+
+ util::StatusOr<std::unique_ptr<PublicKeyVerify>> verifier =
+ SphincsVerifyKeyManager().GetPrimitive<PublicKeyVerify>(*public_key);
+ ASSERT_THAT(verifier.status(), IsOk());
+
+ std::string message = "Some message";
+ util::StatusOr<std::string> signature = (*direct_signer)->Sign(message);
+ ASSERT_THAT(signature.status(), IsOk());
+ EXPECT_THAT((*verifier)->Verify(*signature, message), Not(IsOk()));
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ SphincsVerifyKeyManagerTests, SphincsVerifyKeyManagerTest,
+ testing::ValuesIn<SphincsTestCase>(
+ {{"SPHINCSHARAKA128FROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSHARAKA128FROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128FROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA128SROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSHARAKA128SROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128SROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA128FSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSHARAKA128FSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128FSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA128SSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSHARAKA128SSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128SSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSHARAKA192FROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSHARAKA192FROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192FROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA192SROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSHARAKA192SROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192SROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA192FSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSHARAKA192FSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192FSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA192SSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSHARAKA192SSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192SSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSHARAKA256FROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSHARAKA256FROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256FROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA256SROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSHARAKA256SROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256SROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA256FSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSHARAKA256FSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256FSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA256SSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSHARAKA256SSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256SSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHA256128FROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHA256128FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256128SROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHA256128SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256128FSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHA256128FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256128SSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHA256128SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHA256192FROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHA256192FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256192SROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256192FSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHA256192FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256192SSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHA256192SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHA256256FROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHA256256FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256256SROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHA256256SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256256FSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256256SSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHA256256SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHAKE256128FROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHAKE256128FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256128SROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHAKE256128SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256128FSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHAKE256128FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256128SSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHAKE256128SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHAKE256192FROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHAKE256192FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256192SROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHAKE256192SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256192FSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHAKE256192FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256192SSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHAKE256192SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHAKE256256FROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHAKE256256FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256256SROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHAKE256256SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256256FSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::FAST_SIGNING,
+ PQCLEAN_SPHINCSSHAKE256256FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256256SSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureType::SMALL_SIGNATURE,
+ PQCLEAN_SPHINCSSHAKE256256SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES}}),
+ [](const testing::TestParamInfo<SphincsVerifyKeyManagerTest::ParamType>&
+ info) { return info.param.test_name; });
+
+} // namespace
+
+} // namespace tink
+} // namespace crypto