aboutsummaryrefslogtreecommitdiff
path: root/cc/experimental
diff options
context:
space:
mode:
authorTink Team <tink-dev@google.com>2021-08-30 22:18:13 -0700
committerCopybara-Service <copybara-worker@google.com>2021-08-30 22:18:46 -0700
commita47628f01875b3f826484e0cdacb41f48f72c578 (patch)
tree5bdcad232de9df1e19d73979f75b3b31dc8144b2 /cc/experimental
parent506d990a06fc632d6efe72468944a96c6c882cee (diff)
downloadtink-a47628f01875b3f826484e0cdacb41f48f72c578.tar.gz
Create util structures and functions for sphincs key generation and validation.
PiperOrigin-RevId: 393921707
Diffstat (limited to 'cc/experimental')
-rw-r--r--cc/experimental/pqcrypto/signature/subtle/sphincs_helper_pqclean.cc1104
-rw-r--r--cc/experimental/pqcrypto/signature/subtle/sphincs_helper_pqclean.h81
-rw-r--r--cc/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils.cc105
-rw-r--r--cc/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils.h129
-rw-r--r--cc/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils_test.cc295
5 files changed, 1714 insertions, 0 deletions
diff --git a/cc/experimental/pqcrypto/signature/subtle/sphincs_helper_pqclean.cc b/cc/experimental/pqcrypto/signature/subtle/sphincs_helper_pqclean.cc
new file mode 100644
index 000000000..52b20e5c4
--- /dev/null
+++ b/cc/experimental/pqcrypto/signature/subtle/sphincs_helper_pqclean.cc
@@ -0,0 +1,1104 @@
+// 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/subtle/sphincs_helper_pqclean.h"
+
+#include <cstddef>
+#include <memory>
+#include <vector>
+
+#include "absl/memory/memory.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"
+}
+
+#define NUM_VARIANTS 2
+#define NUM_KEY_SIZES 3
+#define NUM_SIG_LENGTHS 2
+
+namespace crypto {
+namespace tink {
+namespace subtle {
+
+class SphincsHaraka128FRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsHaraka128FRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSHARAKA128FROBUST_AESNI_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128FROBUST_AESNI_CRYPTO_BYTES) {}
+
+ ~SphincsHaraka128FRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA128FROBUST_AESNI_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSHARAKA128FROBUST_AESNI_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA128FROBUST_AESNI_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsHaraka128SRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsHaraka128SRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSHARAKA128SROBUST_AESNI_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128SROBUST_AESNI_CRYPTO_BYTES) {}
+
+ ~SphincsHaraka128SRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA128SROBUST_AESNI_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSHARAKA128SROBUST_AESNI_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA128SROBUST_AESNI_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsHaraka128FSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsHaraka128FSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSHARAKA128FSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128FSIMPLE_AESNI_CRYPTO_BYTES) {}
+
+ ~SphincsHaraka128FSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA128FSIMPLE_AESNI_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSHARAKA128FSIMPLE_AESNI_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA128FSIMPLE_AESNI_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsHaraka128SSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsHaraka128SSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSHARAKA128SSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128SSIMPLE_AESNI_CRYPTO_BYTES) {}
+
+ ~SphincsHaraka128SSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA128SSIMPLE_AESNI_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSHARAKA128SSIMPLE_AESNI_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA128SSIMPLE_AESNI_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsHaraka192FRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsHaraka192FRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSHARAKA192FROBUST_AESNI_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192FROBUST_AESNI_CRYPTO_BYTES) {}
+
+ ~SphincsHaraka192FRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA192FROBUST_AESNI_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSHARAKA192FROBUST_AESNI_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA192FROBUST_AESNI_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsHaraka192SRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsHaraka192SRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSHARAKA192SROBUST_AESNI_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192SROBUST_AESNI_CRYPTO_BYTES) {}
+
+ ~SphincsHaraka192SRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA192SROBUST_AESNI_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSHARAKA192SROBUST_AESNI_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA192SROBUST_AESNI_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsHaraka192FSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsHaraka192FSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSHARAKA192FSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192FSIMPLE_AESNI_CRYPTO_BYTES) {}
+
+ ~SphincsHaraka192FSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA192FSIMPLE_AESNI_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSHARAKA192FSIMPLE_AESNI_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA192FSIMPLE_AESNI_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsHaraka192SSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsHaraka192SSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSHARAKA192SSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192SSIMPLE_AESNI_CRYPTO_BYTES) {}
+
+ ~SphincsHaraka192SSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA192SSIMPLE_AESNI_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSHARAKA192SSIMPLE_AESNI_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA192SSIMPLE_AESNI_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsHaraka256FRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsHaraka256FRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSHARAKA256FROBUST_AESNI_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256FROBUST_AESNI_CRYPTO_BYTES) {}
+
+ ~SphincsHaraka256FRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA256FROBUST_AESNI_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSHARAKA256FROBUST_AESNI_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA256FROBUST_AESNI_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsHaraka256SRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsHaraka256SRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSHARAKA256SROBUST_AESNI_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256SROBUST_AESNI_CRYPTO_BYTES) {}
+
+ ~SphincsHaraka256SRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA256SROBUST_AESNI_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSHARAKA256SROBUST_AESNI_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA256SROBUST_AESNI_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsHaraka256FSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsHaraka256FSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSHARAKA256FSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256FSIMPLE_AESNI_CRYPTO_BYTES) {}
+
+ ~SphincsHaraka256FSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA256FSIMPLE_AESNI_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSHARAKA256FSIMPLE_AESNI_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA256FSIMPLE_AESNI_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsHaraka256SSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsHaraka256SSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSHARAKA256SSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256SSIMPLE_AESNI_CRYPTO_BYTES) {}
+
+ ~SphincsHaraka256SSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA256SSIMPLE_AESNI_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSHARAKA256SSIMPLE_AESNI_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSHARAKA256SSIMPLE_AESNI_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHA256128FRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHA256128FRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHA256128FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128FROBUST_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHA256128FRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256128FROBUST_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHA256128FROBUST_AVX2_crypto_sign_verify(sig, siglen,
+ m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256128FROBUST_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHA256128SRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHA256128SRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHA256128SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128SROBUST_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHA256128SRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256128SROBUST_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHA256128SROBUST_AVX2_crypto_sign_verify(sig, siglen,
+ m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256128SROBUST_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHA256128FSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHA256128FSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHA256128FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128FSIMPLE_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHA256128FSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256128FSIMPLE_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHA256128FSIMPLE_AVX2_crypto_sign_verify(sig, siglen,
+ m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256128FSIMPLE_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHA256128SSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHA256128SSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHA256128SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128SSIMPLE_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHA256128SSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256128SSIMPLE_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHA256128SSIMPLE_AVX2_crypto_sign_verify(sig, siglen,
+ m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256128SSIMPLE_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHA256192FRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHA256192FRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHA256192FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192FROBUST_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHA256192FRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256192FROBUST_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHA256192FROBUST_AVX2_crypto_sign_verify(sig, siglen,
+ m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256192FROBUST_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHA256192SRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHA256192SRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHA256192SRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_crypto_sign_verify(sig, siglen,
+ m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHA256192FSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHA256192FSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHA256192FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192FSIMPLE_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHA256192FSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256192FSIMPLE_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHA256192FSIMPLE_AVX2_crypto_sign_verify(sig, siglen,
+ m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256192FSIMPLE_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHA256192SSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHA256192SSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHA256192SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192SSIMPLE_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHA256192SSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256192SSIMPLE_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHA256192SSIMPLE_AVX2_crypto_sign_verify(sig, siglen,
+ m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256192SSIMPLE_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHA256256FRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHA256256FRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHA256256FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256FROBUST_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHA256256FRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256256FROBUST_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHA256256FROBUST_AVX2_crypto_sign_verify(sig, siglen,
+ m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256256FROBUST_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHA256256SRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHA256256SRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHA256256SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256SROBUST_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHA256256SRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256256SROBUST_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHA256256SROBUST_AVX2_crypto_sign_verify(sig, siglen,
+ m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256256SROBUST_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHA256256FSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHA256256FSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHA256256FSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_crypto_sign_verify(sig, siglen,
+ m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHA256256SSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHA256256SSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHA256256SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256SSIMPLE_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHA256256SSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256256SSIMPLE_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHA256256SSIMPLE_AVX2_crypto_sign_verify(sig, siglen,
+ m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHA256256SSIMPLE_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHAKE256128FRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHAKE256128FRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHAKE256128FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128FROBUST_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHAKE256128FRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256128FROBUST_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHAKE256128FROBUST_AVX2_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256128FROBUST_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHAKE256128SRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHAKE256128SRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHAKE256128SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128SROBUST_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHAKE256128SRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256128SROBUST_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHAKE256128SROBUST_AVX2_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256128SROBUST_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHAKE256128FSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHAKE256128FSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHAKE256128FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128FSIMPLE_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHAKE256128FSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256128FSIMPLE_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHAKE256128FSIMPLE_AVX2_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256128FSIMPLE_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHAKE256128SSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHAKE256128SSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHAKE256128SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128SSIMPLE_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHAKE256128SSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256128SSIMPLE_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHAKE256128SSIMPLE_AVX2_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256128SSIMPLE_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHAKE256192FRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHAKE256192FRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHAKE256192FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192FROBUST_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHAKE256192FRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256192FROBUST_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHAKE256192FROBUST_AVX2_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256192FROBUST_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHAKE256192SRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHAKE256192SRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHAKE256192SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192SROBUST_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHAKE256192SRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256192SROBUST_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHAKE256192SROBUST_AVX2_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256192SROBUST_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHAKE256192FSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHAKE256192FSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHAKE256192FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192FSIMPLE_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHAKE256192FSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256192FSIMPLE_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHAKE256192FSIMPLE_AVX2_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256192FSIMPLE_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHAKE256192SSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHAKE256192SSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHAKE256192SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192SSIMPLE_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHAKE256192SSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256192SSIMPLE_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHAKE256192SSIMPLE_AVX2_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256192SSIMPLE_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHAKE256256FRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHAKE256256FRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHAKE256256FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256FROBUST_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHAKE256256FRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256256FROBUST_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHAKE256256FROBUST_AVX2_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256256FROBUST_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHAKE256256SRobustPqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHAKE256256SRobustPqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHAKE256256SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256SROBUST_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHAKE256256SRobustPqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256256SROBUST_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHAKE256256SROBUST_AVX2_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256256SROBUST_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHAKE256256FSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHAKE256256FSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHAKE256256FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256FSIMPLE_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHAKE256256FSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256256FSIMPLE_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHAKE256256FSIMPLE_AVX2_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256256FSIMPLE_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+class SphincsSHAKE256256SSimplePqclean : public SphincsHelperPqclean {
+ public:
+ SphincsSHAKE256256SSimplePqclean()
+ : SphincsHelperPqclean(
+ PQCLEAN_SPHINCSSHAKE256256SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256SSIMPLE_AVX2_CRYPTO_BYTES) {}
+
+ ~SphincsSHAKE256256SSimplePqclean() override = default;
+
+ int Sign(uint8_t *sig, size_t *siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256256SSIMPLE_AVX2_crypto_sign_signature(
+ sig, siglen, m, mlen, sk);
+ }
+
+ int Verify(const uint8_t *sig, size_t siglen, const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const override {
+ return PQCLEAN_SPHINCSSHAKE256256SSIMPLE_AVX2_crypto_sign_verify(
+ sig, siglen, m, mlen, pk);
+ }
+
+ int Keygen(uint8_t *pk, uint8_t *sk) const override {
+ return PQCLEAN_SPHINCSSHAKE256256SSIMPLE_AVX2_crypto_sign_keypair(pk, sk);
+ }
+};
+
+std::vector<std::unique_ptr<SphincsHelperPqclean>>
+GetSphincsPqcleanHelperArray() {
+ std::vector<std::unique_ptr<SphincsHelperPqclean>> sphincs_helper_pqclean;
+
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsHaraka128FRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsHaraka128SRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsHaraka128FSimplePqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsHaraka128SSimplePqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsHaraka192FRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsHaraka192SRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsHaraka192FSimplePqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsHaraka192SSimplePqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsHaraka256FRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsHaraka256SRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsHaraka256FSimplePqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsHaraka256SSimplePqclean>());
+
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHA256128FRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHA256128SRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHA256128FSimplePqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHA256128SSimplePqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHA256192FRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHA256192SRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHA256192FSimplePqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHA256192SSimplePqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHA256256FRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHA256256SRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHA256256FSimplePqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHA256256SSimplePqclean>());
+
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHAKE256128FRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHAKE256128SRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHAKE256128FSimplePqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHAKE256128SSimplePqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHAKE256192FRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHAKE256192SRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHAKE256192FSimplePqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHAKE256192SSimplePqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHAKE256256FRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHAKE256256SRobustPqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHAKE256256FSimplePqclean>());
+ sphincs_helper_pqclean.push_back(
+ absl::make_unique<SphincsSHAKE256256SSimplePqclean>());
+
+ return sphincs_helper_pqclean;
+}
+
+const SphincsHelperPqclean &GetSphincsHelperPqclean(int hash_type, int variant,
+ int key_size,
+ int signature_length) {
+ static std::vector<std::unique_ptr<SphincsHelperPqclean>>
+ *sphincs_helper_pqclean = new std::vector(GetSphincsPqcleanHelperArray());
+
+ return *sphincs_helper_pqclean->at(
+ hash_type * NUM_VARIANTS * NUM_KEY_SIZES * NUM_SIG_LENGTHS +
+ key_size * NUM_VARIANTS * NUM_SIG_LENGTHS + variant * NUM_SIG_LENGTHS +
+ signature_length);
+}
+
+} // namespace subtle
+} // namespace tink
+} // namespace crypto
diff --git a/cc/experimental/pqcrypto/signature/subtle/sphincs_helper_pqclean.h b/cc/experimental/pqcrypto/signature/subtle/sphincs_helper_pqclean.h
new file mode 100644
index 000000000..4e8c99e1e
--- /dev/null
+++ b/cc/experimental/pqcrypto/signature/subtle/sphincs_helper_pqclean.h
@@ -0,0 +1,81 @@
+// 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_SUBTLE_SPHINCS_HELPER_PQCLEAN_H_
+#define TINK_EXPERIMENTAL_PQCRYPTO_SIGNATURE_SUBTLE_SPHINCS_HELPER_PQCLEAN_H_
+
+#include <memory>
+#include <vector>
+
+#include "absl/base/attributes.h"
+
+namespace crypto {
+namespace tink {
+namespace subtle {
+
+class SphincsHelperPqclean {
+ public:
+ SphincsHelperPqclean(int public_key_size, int signature_length)
+ : public_key_size_(public_key_size),
+ signature_length_(signature_length) {}
+
+ SphincsHelperPqclean(const SphincsHelperPqclean &other) = delete;
+ SphincsHelperPqclean &operator=(const SphincsHelperPqclean &other) = delete;
+ virtual ~SphincsHelperPqclean() {}
+
+ // Arguments:
+ // sig - output signature (allocated buffer of size at least
+ // GetSignatureLength()); siglen - output length of signature; m - message
+ // to be signed; mlen - length of message; sk - bit-packed secret key.
+ // Computes signature. Returns 0 (success).
+ virtual ABSL_MUST_USE_RESULT int Sign(uint8_t *sig, size_t *siglen,
+ const uint8_t *m, size_t mlen,
+ const uint8_t *sk) const = 0;
+
+ // Arguments:
+ // sig - input signature; siglen - length of signature;
+ // m - input message; mlen - length of message; pk - bit-packed public key.
+ // Verifies the signature. Returns 0 (success).
+ virtual ABSL_MUST_USE_RESULT int Verify(const uint8_t *sig, size_t siglen,
+ const uint8_t *m, size_t mlen,
+ const uint8_t *pk) const = 0;
+
+ // Arguments:
+ // pk - output public key (allocated buffer of the corresponding public key
+ // size); sk - output private key (allocated buffer of the corresponding
+ // private key size)
+ // Gnerates the key pair. Returns 0 (success).
+ virtual ABSL_MUST_USE_RESULT int Keygen(uint8_t *pk, uint8_t *sk) const = 0;
+
+ int GetPublicKeySize() const { return public_key_size_; }
+ int GetSignatureLength() const { return signature_length_; }
+
+ private:
+ int public_key_size_;
+ int signature_length_;
+};
+
+// Returns a pointer to the corresponding SphincsHelperPqclean derived class.
+// Will be used for the key generation, signing and verifing.
+const SphincsHelperPqclean &GetSphincsHelperPqclean(int hash_type, int variant,
+ int key_size,
+ int signature_length);
+
+} // namespace subtle
+} // namespace tink
+} // namespace crypto
+
+#endif // TINK_EXPERIMENTAL_PQCRYPTO_SIGNATURE_SUBTLE_SPHINCS_HELPER_PQCLEAN_H_
diff --git a/cc/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils.cc b/cc/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils.cc
new file mode 100644
index 000000000..52bc84128
--- /dev/null
+++ b/cc/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils.cc
@@ -0,0 +1,105 @@
+// 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/subtle/sphincs_subtle_utils.h"
+
+#include <string>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/str_format.h"
+#include "tink/experimental/pqcrypto/signature/subtle/sphincs_helper_pqclean.h"
+#include "tink/util/secret_data.h"
+#include "tink/util/statusor.h"
+
+// Definitions of the three possible sphincs key sizes.
+#define SPHINCSKEYSIZE64 64
+#define SPHINCSKEYSIZE96 96
+#define SPHINCSKEYSIZE128 128
+
+namespace crypto {
+namespace tink {
+namespace subtle {
+
+crypto::tink::util::StatusOr<SphincsKeyPair> GenerateSphincsKeyPair(
+ SphincsParams params) {
+ util::Status key_size_status = ValidateKeySize(params.private_key_size);
+ if (!key_size_status.ok()) {
+ return key_size_status;
+ }
+
+ util::StatusOr<int32> key_size_index_or =
+ SphincsKeySizeToIndex(params.private_key_size);
+ if (!key_size_index_or.ok()) {
+ return key_size_index_or.status();
+ }
+
+ std::string public_key;
+ std::string private_key;
+ private_key.resize(params.private_key_size);
+
+ const SphincsHelperPqclean &sphincs_helper_pqclean =
+ GetSphincsHelperPqclean(params.hash_type, params.variant,
+ *key_size_index_or, params.sig_length_type);
+ public_key.resize(sphincs_helper_pqclean.GetPublicKeySize());
+
+ if (0 != sphincs_helper_pqclean.Keygen(
+ reinterpret_cast<uint8_t *>(public_key.data()),
+ reinterpret_cast<uint8_t *>(private_key.data()))) {
+ return util::Status(util::error::INTERNAL, "Key generation failed.");
+ }
+
+ util::SecretData private_key_data =
+ util::SecretDataFromStringView(private_key);
+
+ SphincsKeyPair key_pair(SphincsPrivateKeyPqclean{private_key_data},
+ SphincsPublicKeyPqclean{public_key});
+
+ return key_pair;
+}
+
+crypto::tink::util::Status ValidateKeySize(int32 key_size) {
+ switch (key_size) {
+ case SPHINCSKEYSIZE64:
+ case SPHINCSKEYSIZE96:
+ case SPHINCSKEYSIZE128:
+ return util::Status::OK;
+ default:
+ return util::Status(
+ util::error::INVALID_ARGUMENT,
+ absl::StrFormat("Invalid private key size (%d). "
+ "The only valid sizes are %d, %d, %d.",
+ key_size, SPHINCSKEYSIZE64, SPHINCSKEYSIZE96,
+ SPHINCSKEYSIZE128));
+ }
+}
+
+crypto::tink::util::StatusOr<int32> SphincsKeySizeToIndex(int32 key_size) {
+ switch (key_size) {
+ case SPHINCSKEYSIZE64:
+ return 0;
+ case SPHINCSKEYSIZE96:
+ return 1;
+ case SPHINCSKEYSIZE128:
+ return 2;
+ default:
+ return util::Status(util::error::INVALID_ARGUMENT, "Invalid key size");
+ }
+}
+
+} // namespace subtle
+} // namespace tink
+} // namespace crypto
diff --git a/cc/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils.h b/cc/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils.h
new file mode 100644
index 000000000..fef40401b
--- /dev/null
+++ b/cc/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils.h
@@ -0,0 +1,129 @@
+// 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_SUBTLE_SPHINCS_SUBTLE_UTILS_H_
+#define TINK_EXPERIMENTAL_PQCRYPTO_SIGNATURE_SUBTLE_SPHINCS_SUBTLE_UTILS_H_
+
+#include <string>
+#include <utility>
+
+#include "absl/memory/memory.h"
+#include "absl/strings/str_format.h"
+#include "tink/util/secret_data.h"
+#include "tink/util/statusor.h"
+
+namespace crypto {
+namespace tink {
+namespace subtle {
+
+enum SphincsHashType {
+ HARAKA = 0,
+ SHA256 = 1,
+ SHAKE256 = 2,
+};
+
+enum SphincsVariant {
+ ROBUST = 0,
+ SIMPLE = 1,
+};
+
+enum SphincsSignatureLengthType {
+ F = 0,
+ S = 1,
+};
+
+class SphincsPrivateKeyPqclean {
+ public:
+ explicit SphincsPrivateKeyPqclean(util::SecretData key_data)
+ : private_key_data_(std::move(key_data)) {}
+
+ SphincsPrivateKeyPqclean(const SphincsPrivateKeyPqclean& other) = default;
+ SphincsPrivateKeyPqclean& operator=(const SphincsPrivateKeyPqclean& other) =
+ default;
+
+ const util::SecretData& Get() const { return private_key_data_; }
+
+ private:
+ const util::SecretData private_key_data_;
+};
+
+class SphincsPublicKeyPqclean {
+ public:
+ explicit SphincsPublicKeyPqclean(std::string key_data)
+ : public_key_data_(std::move(key_data)) {}
+
+ SphincsPublicKeyPqclean(const SphincsPublicKeyPqclean& other) = default;
+ SphincsPublicKeyPqclean& operator=(const SphincsPublicKeyPqclean& other) =
+ default;
+
+ const std::string& Get() const { return public_key_data_; }
+
+ private:
+ const std::string public_key_data_;
+};
+
+class SphincsKeyPair {
+ public:
+ SphincsKeyPair(SphincsPrivateKeyPqclean private_key,
+ SphincsPublicKeyPqclean public_key)
+ : private_key_(private_key), public_key_(public_key) {}
+
+ SphincsKeyPair(const SphincsKeyPair& other) = default;
+ SphincsKeyPair& operator=(const SphincsKeyPair& other) =
+ default;
+
+ const SphincsPrivateKeyPqclean& GetPrivateKey() const { return private_key_; }
+ const SphincsPublicKeyPqclean& GetPublicKey() const { return public_key_; }
+
+ private:
+ SphincsPrivateKeyPqclean private_key_;
+ SphincsPublicKeyPqclean public_key_;
+};
+
+struct SphincsParams {
+ SphincsHashType hash_type;
+ SphincsVariant variant;
+ SphincsSignatureLengthType sig_length_type;
+ int32 private_key_size;
+
+ SphincsParams(SphincsHashType hash_type_, SphincsVariant variant_,
+ int32 private_key_size_,
+ SphincsSignatureLengthType sig_length_type_) {
+ hash_type = hash_type_;
+ variant = variant_;
+ private_key_size = private_key_size_;
+ sig_length_type = sig_length_type_;
+ }
+};
+
+// This is an utility function that generates a new Sphincs key pair based on
+// Sphincs specific parameters. This function is expected to be called from
+// a key manager class.
+crypto::tink::util::StatusOr<SphincsKeyPair> GenerateSphincsKeyPair(
+ SphincsParams params);
+
+// Validates whether 'key_size' is safe to use for sphincs signature.
+crypto::tink::util::Status ValidateKeySize(int32 key_size);
+
+// Convert the sphincs private key size to the appropiate index in the
+// pqclean functions array.
+crypto::tink::util::StatusOr<int32> SphincsKeySizeToIndex(int32 key_size);
+
+} // namespace subtle
+} // namespace tink
+} // namespace crypto
+
+#endif // TINK_EXPERIMENTAL_PQCRYPTO_SIGNATURE_SUBTLE_SPHINCS_SUBTLE_UTILS_H_
diff --git a/cc/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils_test.cc b/cc/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils_test.cc
new file mode 100644
index 000000000..c5ee6a9dd
--- /dev/null
+++ b/cc/experimental/pqcrypto/signature/subtle/sphincs_subtle_utils_test.cc
@@ -0,0 +1,295 @@
+// 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/subtle/sphincs_subtle_utils.h"
+
+#include <string>
+#include <utility>
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "absl/strings/str_cat.h"
+#include "tink/experimental/pqcrypto/signature/subtle/sphincs_helper_pqclean.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"
+}
+
+// Definitions of the three possible sphincs key sizes.
+#define SPHINCSKEYSIZE64 64
+#define SPHINCSKEYSIZE96 96
+#define SPHINCSKEYSIZE128 128
+
+namespace crypto {
+namespace tink {
+namespace subtle {
+namespace {
+
+using ::crypto::tink::test::IsOk;
+
+struct SphincsUtilsTestCase {
+ std::string test_name;
+ SphincsHashType hash_type;
+ SphincsVariant variant;
+ SphincsSignatureLengthType sig_length_type;
+ int32_t private_key_size;
+ int32_t public_key_size;
+};
+
+using SphincsUtilsTest = testing::TestWithParam<SphincsUtilsTestCase>;
+
+TEST_P(SphincsUtilsTest, SphincsKeysLength) {
+ const SphincsUtilsTestCase& test_case = GetParam();
+
+ SphincsParams params(test_case.hash_type, test_case.variant,
+ test_case.private_key_size, test_case.sig_length_type);
+
+ // Generate sphincs key pair.
+ util::StatusOr<SphincsKeyPair> key_pair = GenerateSphincsKeyPair(params);
+ ASSERT_THAT(key_pair.status(), IsOk());
+
+ // Check keys size.
+ EXPECT_EQ(key_pair->GetPrivateKey().Get().size(), test_case.private_key_size);
+ EXPECT_EQ(key_pair->GetPublicKey().Get().size(), test_case.public_key_size);
+}
+
+TEST_P(SphincsUtilsTest, DifferentContent) {
+ const SphincsUtilsTestCase& test_case = GetParam();
+
+ SphincsParams params(test_case.hash_type, test_case.variant,
+ test_case.private_key_size, test_case.sig_length_type);
+
+ // Generate sphincs key pair.
+ util::StatusOr<SphincsKeyPair> key_pair = GenerateSphincsKeyPair(params);
+ ASSERT_THAT(key_pair.status(), IsOk());
+
+ // Check keys content is different.
+ EXPECT_NE(util::SecretDataAsStringView(key_pair->GetPrivateKey().Get()),
+ key_pair->GetPublicKey().Get());
+}
+
+TEST(SphincsUtilsTest, InvalidKeySize) {
+ for (int keysize = 0; keysize <= SPHINCSKEYSIZE128; keysize++) {
+ if (keysize == SPHINCSKEYSIZE64 || keysize == SPHINCSKEYSIZE96 ||
+ keysize == SPHINCSKEYSIZE128) {
+ // Valid key size.
+ continue;
+ }
+ EXPECT_FALSE(ValidateKeySize(keysize).ok());
+ }
+}
+
+INSTANTIATE_TEST_SUITE_P(
+ SphincsUtilsTests, SphincsUtilsTest,
+ testing::ValuesIn<SphincsUtilsTestCase>(
+ {{"SPHINCSHARAKA128FROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSHARAKA128FROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128FROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA128SROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSHARAKA128SROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128SROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA128FSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSHARAKA128FSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128FSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA128SSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSHARAKA128SSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA128SSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSHARAKA192FROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSHARAKA192FROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192FROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA192SROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSHARAKA192SROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192SROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA192FSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSHARAKA192FSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192FSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA192SSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSHARAKA192SSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA192SSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSHARAKA256FROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSHARAKA256FROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256FROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA256SROBUST", SphincsHashType::HARAKA,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSHARAKA256SROBUST_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256SROBUST_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA256FSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSHARAKA256FSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256FSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSHARAKA256SSIMPLE", SphincsHashType::HARAKA,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSHARAKA256SSIMPLE_AESNI_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSHARAKA256SSIMPLE_AESNI_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHA256128FROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSSHA256128FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256128SROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSSHA256128SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256128FSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSSHA256128FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256128SSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSSHA256128SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256128SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHA256192FROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSSHA256192FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256192SROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256192FSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSSHA256192FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256192SSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSSHA256192SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256192SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHA256256FROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSSHA256256FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256256SROBUST", SphincsHashType::SHA256,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSSHA256256SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256256FSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHA256256SSIMPLE", SphincsHashType::SHA256,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSSHA256256SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHA256256SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHAKE256128FROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSSHAKE256128FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256128SROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSSHAKE256128SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256128FSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSSHAKE256128FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256128SSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSSHAKE256128SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256128SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHAKE256192FROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSSHAKE256192FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256192SROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSSHAKE256192SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256192FSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSSHAKE256192FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256192SSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSSHAKE256192SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256192SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+
+ {"SPHINCSSHAKE256256FROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSSHAKE256256FROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256FROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256256SROBUST", SphincsHashType::SHAKE256,
+ SphincsVariant::ROBUST, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSSHAKE256256SROBUST_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256SROBUST_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256256FSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::F,
+ PQCLEAN_SPHINCSSHAKE256256FSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256FSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES},
+ {"SPHINCSSHAKE256256SSIMPLE", SphincsHashType::SHAKE256,
+ SphincsVariant::SIMPLE, SphincsSignatureLengthType::S,
+ PQCLEAN_SPHINCSSHAKE256256SSIMPLE_AVX2_CRYPTO_SECRETKEYBYTES,
+ PQCLEAN_SPHINCSSHAKE256256SSIMPLE_AVX2_CRYPTO_PUBLICKEYBYTES}}),
+ [](const testing::TestParamInfo<SphincsUtilsTest::ParamType>& info) {
+ return info.param.test_name;
+ });
+
+} // namespace
+} // namespace subtle
+} // namespace tink
+} // namespace crypto