diff options
author | Tink Team <tink-dev@google.com> | 2021-09-07 17:31:06 -0700 |
---|---|---|
committer | Copybara-Service <copybara-worker@google.com> | 2021-09-07 17:31:51 -0700 |
commit | de6901a410a08e90ea63882c4348082cd6a566b9 (patch) | |
tree | 1606af0e5dd27796ccd3eb0f65aded14b637b74c /cc/experimental | |
parent | dfdf4b24cbc36bb4761cb474f086226593ed17b3 (diff) | |
download | tink-de6901a410a08e90ea63882c4348082cd6a566b9.tar.gz |
Add Sphincs Digital Signature Schemes to the key manager.
PiperOrigin-RevId: 395365169
Diffstat (limited to 'cc/experimental')
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 |