Make it plainly obvious this is experimental code.

Since we are saying this will die when standardized, let us
ensure users of this code from this location take notice
and action before using it.

We then selectively allow it in the speed tool and in our tests.

If we like this approach, I'll go back and apply it to kyber
(which will have some other fallout consequences to fix) but this
one should be painless right now.

This can also be applied to Dilithium when it comes back.

Future experimentals could be added in this manner.

Change-Id: Ie3b41cf16278868562ef1c8b28f2caed5e0e2dd1
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/66887
Commit-Queue: Bob Beck <bbe@google.com>
Reviewed-by: David Benjamin <davidben@google.com>
diff --git a/crypto/spx/spx.c b/crypto/spx/spx.c
index b5bec6e..372001a 100644
--- a/crypto/spx/spx.c
+++ b/crypto/spx/spx.c
@@ -16,6 +16,7 @@
 
 #include <string.h>
 
+#define OPENSSL_UNSTABLE_EXPERIMENTAL_SPX
 #include <openssl/experimental/spx.h>
 #include <openssl/rand.h>
 
@@ -26,14 +27,14 @@
 #include "./spx_util.h"
 #include "./thash.h"
 
-void spx_generate_key(uint8_t out_public_key[SPX_PUBLIC_KEY_BYTES],
+void SPX_generate_key(uint8_t out_public_key[SPX_PUBLIC_KEY_BYTES],
                       uint8_t out_secret_key[SPX_SECRET_KEY_BYTES]) {
   uint8_t seed[3 * SPX_N];
   RAND_bytes(seed, 3 * SPX_N);
-  spx_generate_key_from_seed(out_public_key, out_secret_key, seed);
+  SPX_generate_key_from_seed(out_public_key, out_secret_key, seed);
 }
 
-void spx_generate_key_from_seed(uint8_t out_public_key[SPX_PUBLIC_KEY_BYTES],
+void SPX_generate_key_from_seed(uint8_t out_public_key[SPX_PUBLIC_KEY_BYTES],
                                 uint8_t out_secret_key[SPX_SECRET_KEY_BYTES],
                                 const uint8_t seed[3 * SPX_N]) {
   // Initialize SK.seed || SK.prf || PK.seed from seed.
@@ -51,7 +52,7 @@
   memcpy(out_secret_key + 3 * SPX_N, out_public_key + SPX_N, SPX_N);
 }
 
-void spx_sign(uint8_t out_signature[SPX_SIGNATURE_BYTES],
+void SPX_sign(uint8_t out_signature[SPX_SIGNATURE_BYTES],
               const uint8_t secret_key[SPX_SECRET_KEY_BYTES],
               const uint8_t *msg, size_t msg_len, int randomized) {
   uint8_t addr[32] = {0};
@@ -102,7 +103,7 @@
               idx_leaf, sk_seed, pk_seed);
 }
 
-int spx_verify(const uint8_t signature[SPX_SIGNATURE_BYTES],
+int SPX_verify(const uint8_t signature[SPX_SIGNATURE_BYTES],
                const uint8_t public_key[SPX_SECRET_KEY_BYTES],
                const uint8_t *msg, size_t msg_len) {
   uint8_t addr[32] = {0};
diff --git a/crypto/spx/spx_test.cc b/crypto/spx/spx_test.cc
index 313f47d..e17dce8 100644
--- a/crypto/spx/spx_test.cc
+++ b/crypto/spx/spx_test.cc
@@ -21,12 +21,13 @@
 
 #include <gtest/gtest.h>
 #include <openssl/bytestring.h>
+#define OPENSSL_UNSTABLE_EXPERIMENTAL_SPX
 #include <openssl/experimental/spx.h>
 
 #include "../test/file_test.h"
 #include "../test/test_util.h"
 
-
+// suppress warnings for experimental spx api
 namespace {
 
 TEST(SpxTest, KeyGeneration) {
@@ -47,7 +48,7 @@
 
   uint8_t pk[2 * SPX_N];
   uint8_t sk[4 * SPX_N];
-  spx_generate_key_from_seed(pk, sk, seed);
+  SPX_generate_key_from_seed(pk, sk, seed);
   EXPECT_EQ(Bytes(pk), Bytes(expected_pk));
   EXPECT_EQ(Bytes(sk), Bytes(expected_sk));
 }
@@ -75,7 +76,7 @@
 
   uint8_t pk[2 * SPX_N];
   uint8_t sk[4 * SPX_N];
-  spx_generate_key_from_seed(pk, sk, seed);
+  SPX_generate_key_from_seed(pk, sk, seed);
   EXPECT_EQ(Bytes(pk), Bytes(expected_pk));
   EXPECT_EQ(Bytes(sk), Bytes(expected_sk));
 }
@@ -83,12 +84,12 @@
 TEST(SpxTest, BasicSignVerify) {
   uint8_t pk[2 * SPX_N];
   uint8_t sk[4 * SPX_N];
-  spx_generate_key(pk, sk);
+  SPX_generate_key(pk, sk);
 
   uint8_t message[] = {0x42};
   uint8_t signature[SPX_SIGNATURE_BYTES];
-  spx_sign(signature, sk, message, sizeof(message), true);
-  EXPECT_EQ(spx_verify(signature, pk, message, sizeof(message)), 1);
+  SPX_sign(signature, sk, message, sizeof(message), true);
+  EXPECT_EQ(SPX_verify(signature, pk, message, sizeof(message)), 1);
 }
 
 static void SpxFileTest(FileTest *t) {
@@ -102,13 +103,13 @@
   t->IgnoreAttribute("smlen");
   ASSERT_TRUE(t->GetBytes(&signature, "sm"));
 
-  EXPECT_EQ(spx_verify(signature.data(), public_key.data(), message.data(),
+  EXPECT_EQ(SPX_verify(signature.data(), public_key.data(), message.data(),
                        message.size()),
             1);
 
   message[0] ^= 1;
 
-  EXPECT_EQ(spx_verify(signature.data(), public_key.data(), message.data(),
+  EXPECT_EQ(SPX_verify(signature.data(), public_key.data(), message.data(),
                        message.size()),
             0);
 }
@@ -126,7 +127,7 @@
   expected_signature.resize(SPX_SIGNATURE_BYTES);
 
   uint8_t signature[SPX_SIGNATURE_BYTES];
-  spx_sign(signature, sk.data(), message.data(), message.size(), false);
+  SPX_sign(signature, sk.data(), message.data(), message.size(), false);
 
   EXPECT_EQ(Bytes(signature), Bytes(expected_signature));
 }
diff --git a/include/openssl/experimental/spx.h b/include/openssl/experimental/spx.h
index 713322a..58dd472 100644
--- a/include/openssl/experimental/spx.h
+++ b/include/openssl/experimental/spx.h
@@ -22,6 +22,14 @@
 #endif
 
 
+#if defined(OPENSSL_UNSTABLE_EXPERIMENTAL_SPX)
+// This header implements experimental, draft versions of not-yet-standardized
+// primitives. When the standard is complete, these functions will be removed
+// and replaced with the final, incompatible standard version. They are
+// available now for short-lived experiments, but must not be deployed anywhere
+// durable, such as a long-lived key store. To use these functions define
+// OPENSSL_UNSTABLE_EXPERIMENTAL_SPX
+
 // SPX_N is the number of bytes in the hash output
 #define SPX_N 16
 
@@ -37,39 +45,42 @@
 // SPHINCS+-SHA2-128s
 #define SPX_SIGNATURE_BYTES 7856
 
-// spx_generate_key generates a SPHINCS+-SHA2-128s key pair and writes the
+// SPX_generate_key generates a SPHINCS+-SHA2-128s key pair and writes the
 // result to |out_public_key| and |out_secret_key|.
 // Private key: SK.seed || SK.prf || PK.seed || PK.root
 // Public key: PK.seed || PK.root
-OPENSSL_EXPORT void spx_generate_key(
+OPENSSL_EXPORT void SPX_generate_key(
     uint8_t out_public_key[SPX_PUBLIC_KEY_BYTES],
     uint8_t out_secret_key[SPX_SECRET_KEY_BYTES]);
 
-// spx_generate_key_from_seed generates a SPHINCS+-SHA2-128s key pair from a
+// SPX_generate_key_from_seed generates a SPHINCS+-SHA2-128s key pair from a
 // 48-byte seed and writes the result to |out_public_key| and |out_secret_key|.
 // Secret key: SK.seed || SK.prf || PK.seed || PK.root
 // Public key: PK.seed || PK.root
-OPENSSL_EXPORT void spx_generate_key_from_seed(
+OPENSSL_EXPORT void SPX_generate_key_from_seed(
     uint8_t out_public_key[SPX_PUBLIC_KEY_BYTES],
     uint8_t out_secret_key[SPX_SECRET_KEY_BYTES],
     const uint8_t seed[3 * SPX_N]);
 
-// spx_sign generates a SPHINCS+-SHA2-128s signature over |msg| or length
+// SPX_sign generates a SPHINCS+-SHA2-128s signature over |msg| or length
 // |msg_len| using |secret_key| and writes the output to |out_signature|.
 //
 // if |randomized| is 0, deterministic signing is performed, otherwise,
 // non-deterministic signing is performed.
-OPENSSL_EXPORT void spx_sign(uint8_t out_snignature[SPX_SIGNATURE_BYTES],
-                             const uint8_t secret_key[SPX_SECRET_KEY_BYTES],
-                             const uint8_t *msg, size_t msg_len,
-                             int randomized);
+OPENSSL_EXPORT void SPX_sign(
+    uint8_t out_snignature[SPX_SIGNATURE_BYTES],
+    const uint8_t secret_key[SPX_SECRET_KEY_BYTES], const uint8_t *msg,
+    size_t msg_len, int randomized);
 
-// spx_verify verifies a SPHINCS+-SHA2-128s signature in |signature| over |msg|
+// SPX_verify verifies a SPHINCS+-SHA2-128s signature in |signature| over |msg|
 // or length |msg_len| using |public_key|. 1 is returned if the signature
 // matches, 0 otherwise.
-OPENSSL_EXPORT int spx_verify(const uint8_t signature[SPX_SIGNATURE_BYTES],
-                              const uint8_t public_key[SPX_SECRET_KEY_BYTES],
-                              const uint8_t *msg, size_t msg_len);
+OPENSSL_EXPORT int SPX_verify(
+    const uint8_t signature[SPX_SIGNATURE_BYTES],
+    const uint8_t public_key[SPX_SECRET_KEY_BYTES], const uint8_t *msg,
+    size_t msg_len);
+
+#endif //OPENSSL_UNSTABLE_EXPERIMENTAL_SPX
 
 
 #if defined(__cplusplus)
diff --git a/tool/speed.cc b/tool/speed.cc
index d524455..d3cc87e 100644
--- a/tool/speed.cc
+++ b/tool/speed.cc
@@ -25,6 +25,8 @@
 #include <stdlib.h>
 #include <string.h>
 
+#define OPENSSL_I_UNDERSTAND_EXPERIMENTAL_FUNCTION_RISK
+
 #include <openssl/aead.h>
 #include <openssl/aes.h>
 #include <openssl/base64.h>
@@ -38,6 +40,7 @@
 #include <openssl/ecdsa.h>
 #include <openssl/err.h>
 #include <openssl/evp.h>
+#define OPENSSL_UNSTABLE_EXPERIMENTAL_SPX
 #include <openssl/experimental/kyber.h>
 #include <openssl/experimental/spx.h>
 #include <openssl/hrss.h>
@@ -1136,7 +1139,7 @@
   TimeResults results;
   if (!TimeFunctionParallel(&results, []() -> bool {
         uint8_t public_key[32], private_key[64];
-        spx_generate_key(public_key, private_key);
+        SPX_generate_key(public_key, private_key);
         return true;
       })) {
     return false;
@@ -1145,12 +1148,12 @@
   results.Print("SPHINCS+-SHA2-128s key generation");
 
   uint8_t public_key[32], private_key[64];
-  spx_generate_key(public_key, private_key);
+  SPX_generate_key(public_key, private_key);
   static const uint8_t kMessage[] = {0, 1, 2, 3, 4, 5};
 
   if (!TimeFunctionParallel(&results, [&private_key]() -> bool {
         uint8_t out[SPX_SIGNATURE_BYTES];
-        spx_sign(out, private_key, kMessage, sizeof(kMessage), true);
+        SPX_sign(out, private_key, kMessage, sizeof(kMessage), true);
         return true;
       })) {
     return false;
@@ -1159,10 +1162,10 @@
   results.Print("SPHINCS+-SHA2-128s signing");
 
   uint8_t signature[SPX_SIGNATURE_BYTES];
-  spx_sign(signature, private_key, kMessage, sizeof(kMessage), true);
+  SPX_sign(signature, private_key, kMessage, sizeof(kMessage), true);
 
   if (!TimeFunctionParallel(&results, [&public_key, &signature]() -> bool {
-        return spx_verify(signature, public_key, kMessage, sizeof(kMessage)) ==
+        return SPX_verify(signature, public_key, kMessage, sizeof(kMessage)) ==
                1;
       })) {
     fprintf(stderr, "SPHINCS+-SHA2-128s verify failed.\n");