// Copyright 2024 The BoringSSL Authors
//
// 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
//
//     https://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 <openssl/mldsa.h>

#include <memory>
#include <vector>

#include <gtest/gtest.h>

#include <openssl/bytestring.h>
#include <openssl/mem.h>
#include <openssl/span.h>

#include "../fipsmodule/bcm_interface.h"
#include "../internal.h"
#include "../test/file_test.h"
#include "../test/test_util.h"


namespace {

template <typename T>
std::vector<uint8_t> Marshal(bcm_status (*marshal_func)(CBB *, const T *),
                             const T *t) {
  bssl::ScopedCBB cbb;
  uint8_t *encoded;
  size_t encoded_len;
  if (!CBB_init(cbb.get(), 1) ||                             //
      marshal_func(cbb.get(), t) != bcm_status::approved ||  //
      !CBB_finish(cbb.get(), &encoded, &encoded_len)) {
    abort();
  }

  std::vector<uint8_t> ret(encoded, encoded + encoded_len);
  OPENSSL_free(encoded);
  return ret;
}

// This test is very slow, so it is disabled by default.
TEST(MLDSATest, DISABLED_BitFlips) {
  std::vector<uint8_t> encoded_public_key(MLDSA65_PUBLIC_KEY_BYTES);
  auto priv = std::make_unique<MLDSA65_private_key>();
  uint8_t seed[MLDSA_SEED_BYTES];
  EXPECT_TRUE(
      MLDSA65_generate_key(encoded_public_key.data(), seed, priv.get()));

  std::vector<uint8_t> encoded_signature(MLDSA65_SIGNATURE_BYTES);
  static const uint8_t kMessage[] = {'H', 'e', 'l', 'l', 'o', ' ',
                                     'w', 'o', 'r', 'l', 'd'};
  EXPECT_TRUE(MLDSA65_sign(encoded_signature.data(), priv.get(), kMessage,
                           sizeof(kMessage), nullptr, 0));

  auto pub = std::make_unique<MLDSA65_public_key>();
  CBS cbs = CBS(encoded_public_key);
  ASSERT_TRUE(MLDSA65_parse_public_key(pub.get(), &cbs));

  EXPECT_EQ(MLDSA65_verify(pub.get(), encoded_signature.data(),
                           encoded_signature.size(), kMessage, sizeof(kMessage),
                           nullptr, 0),
            1);

  for (size_t i = 0; i < MLDSA65_SIGNATURE_BYTES; i++) {
    for (int j = 0; j < 8; j++) {
      encoded_signature[i] ^= 1 << j;
      EXPECT_EQ(MLDSA65_verify(pub.get(), encoded_signature.data(),
                               encoded_signature.size(), kMessage,
                               sizeof(kMessage), nullptr, 0),
                0)
          << "Bit flip in signature at byte " << i << " bit " << j
          << " didn't cause a verification failure";
      encoded_signature[i] ^= 1 << j;
    }
  }
}

template <typename PrivateKey, typename PublicKey, size_t PublicKeyBytes,
          size_t SignatureBytes,
          int (*Generate)(uint8_t *, uint8_t *, PrivateKey *),
          int (*Sign)(uint8_t *, const PrivateKey *, const uint8_t *, size_t,
                      const uint8_t *, size_t),
          int (*ParsePublicKey)(PublicKey *, CBS *),
          int (*Verify)(const PublicKey *, const uint8_t *, size_t,
                        const uint8_t *, size_t, const uint8_t *, size_t),
          int (*PrivateKeyFromSeed)(PrivateKey *, const uint8_t *, size_t),
          bcm_status (*ParsePrivate)(PrivateKey *, CBS *),
          bcm_status (*MarshalPrivate)(CBB *, const PrivateKey *)>
static void MLDSABasicTest() {
  std::vector<uint8_t> encoded_public_key(PublicKeyBytes);
  auto priv = std::make_unique<PrivateKey>();
  uint8_t seed[MLDSA_SEED_BYTES];
  EXPECT_TRUE(Generate(encoded_public_key.data(), seed, priv.get()));

  const std::vector<uint8_t> encoded_private_key =
      Marshal(MarshalPrivate, priv.get());
  CBS cbs = CBS(encoded_private_key);
  EXPECT_TRUE(bcm_success(ParsePrivate(priv.get(), &cbs)));

  std::vector<uint8_t> encoded_signature(SignatureBytes);
  static const uint8_t kMessage[] = {'H', 'e', 'l', 'l', 'o', ' ',
                                     'w', 'o', 'r', 'l', 'd'};
  static const uint8_t kContext[] = {'c', 't', 'x'};
  EXPECT_TRUE(Sign(encoded_signature.data(), priv.get(), kMessage,
                   sizeof(kMessage), kContext, sizeof(kContext)));

  auto pub = std::make_unique<PublicKey>();
  cbs = CBS(encoded_public_key);
  ASSERT_TRUE(ParsePublicKey(pub.get(), &cbs));

  EXPECT_EQ(
      Verify(pub.get(), encoded_signature.data(), encoded_signature.size(),
             kMessage, sizeof(kMessage), kContext, sizeof(kContext)),
      1);

  auto priv2 = std::make_unique<PrivateKey>();
  EXPECT_TRUE(PrivateKeyFromSeed(priv2.get(), seed, sizeof(seed)));

  EXPECT_EQ(Bytes(Declassified(Marshal(MarshalPrivate, priv.get()))),
            Bytes(Declassified(Marshal(MarshalPrivate, priv2.get()))));
}

TEST(MLDSATest, Basic65) {
  MLDSABasicTest<
      MLDSA65_private_key, MLDSA65_public_key, MLDSA65_PUBLIC_KEY_BYTES,
      MLDSA65_SIGNATURE_BYTES, MLDSA65_generate_key, MLDSA65_sign,
      MLDSA65_parse_public_key, MLDSA65_verify, MLDSA65_private_key_from_seed,
      BCM_mldsa65_parse_private_key, BCM_mldsa65_marshal_private_key>();
}

TEST(MLDSATest, Basic87) {
  MLDSABasicTest<
      MLDSA87_private_key, MLDSA87_public_key, MLDSA87_PUBLIC_KEY_BYTES,
      MLDSA87_SIGNATURE_BYTES, MLDSA87_generate_key, MLDSA87_sign,
      MLDSA87_parse_public_key, MLDSA87_verify, MLDSA87_private_key_from_seed,
      BCM_mldsa87_parse_private_key, BCM_mldsa87_marshal_private_key>();
}

TEST(MLDSATest, Basic44) {
  MLDSABasicTest<
      MLDSA44_private_key, MLDSA44_public_key, MLDSA44_PUBLIC_KEY_BYTES,
      MLDSA44_SIGNATURE_BYTES, MLDSA44_generate_key, MLDSA44_sign,
      MLDSA44_parse_public_key, MLDSA44_verify, MLDSA44_private_key_from_seed,
      BCM_mldsa44_parse_private_key, BCM_mldsa44_marshal_private_key>();
}

TEST(MLDSATest, SignatureIsRandomized) {
  std::vector<uint8_t> encoded_public_key(MLDSA65_PUBLIC_KEY_BYTES);
  auto priv = std::make_unique<MLDSA65_private_key>();
  uint8_t seed[MLDSA_SEED_BYTES];
  EXPECT_TRUE(
      MLDSA65_generate_key(encoded_public_key.data(), seed, priv.get()));

  auto pub = std::make_unique<MLDSA65_public_key>();
  CBS cbs = CBS(encoded_public_key);
  ASSERT_TRUE(MLDSA65_parse_public_key(pub.get(), &cbs));

  std::vector<uint8_t> encoded_signature1(MLDSA65_SIGNATURE_BYTES);
  std::vector<uint8_t> encoded_signature2(MLDSA65_SIGNATURE_BYTES);
  static const uint8_t kMessage[] = {'H', 'e', 'l', 'l', 'o', ' ',
                                     'w', 'o', 'r', 'l', 'd'};
  EXPECT_TRUE(MLDSA65_sign(encoded_signature1.data(), priv.get(), kMessage,
                           sizeof(kMessage), nullptr, 0));
  EXPECT_TRUE(MLDSA65_sign(encoded_signature2.data(), priv.get(), kMessage,
                           sizeof(kMessage), nullptr, 0));

  EXPECT_NE(Bytes(encoded_signature1), Bytes(encoded_signature2));

  // Even though the signatures are different, they both verify.
  EXPECT_EQ(MLDSA65_verify(pub.get(), encoded_signature1.data(),
                           encoded_signature1.size(), kMessage,
                           sizeof(kMessage), nullptr, 0),
            1);
  EXPECT_EQ(MLDSA65_verify(pub.get(), encoded_signature2.data(),
                           encoded_signature2.size(), kMessage,
                           sizeof(kMessage), nullptr, 0),
            1);
}

TEST(MLDSATest, PrehashedSignatureVerifies) {
  std::vector<uint8_t> encoded_public_key(MLDSA65_PUBLIC_KEY_BYTES);
  auto priv = std::make_unique<MLDSA65_private_key>();
  uint8_t seed[MLDSA_SEED_BYTES];
  EXPECT_TRUE(
      MLDSA65_generate_key(encoded_public_key.data(), seed, priv.get()));

  auto pub = std::make_unique<MLDSA65_public_key>();
  CBS cbs = CBS(encoded_public_key);
  ASSERT_TRUE(MLDSA65_parse_public_key(pub.get(), &cbs));

  std::vector<uint8_t> encoded_signature(MLDSA65_SIGNATURE_BYTES);
  static const uint8_t kMessage[] = {'H', 'e', 'l', 'l', 'o', ' ',
                                     'w', 'o', 'r', 'l', 'd'};

  MLDSA65_prehash prehash_state;
  EXPECT_TRUE(MLDSA65_prehash_init(&prehash_state, pub.get(), nullptr, 0));
  MLDSA65_prehash_update(&prehash_state, kMessage, sizeof(kMessage));
  uint8_t representative[MLDSA_MU_BYTES];
  MLDSA65_prehash_finalize(representative, &prehash_state);
  EXPECT_TRUE(MLDSA65_sign_message_representative(encoded_signature.data(),
                                                  priv.get(), representative));

  EXPECT_EQ(MLDSA65_verify(pub.get(), encoded_signature.data(),
                           encoded_signature.size(), kMessage, sizeof(kMessage),
                           nullptr, 0),
            1);

  // Updating in multiple chunks also works.
  for (size_t i = 0; i <= sizeof(kMessage); ++i) {
    for (size_t j = i; j <= sizeof(kMessage); ++j) {
      EXPECT_TRUE(MLDSA65_prehash_init(&prehash_state, pub.get(), nullptr, 0));
      MLDSA65_prehash_update(&prehash_state, kMessage, i);
      MLDSA65_prehash_update(&prehash_state, kMessage + i, j - i);
      MLDSA65_prehash_update(&prehash_state, kMessage + j,
                             sizeof(kMessage) - j);
      MLDSA65_prehash_finalize(representative, &prehash_state);
      EXPECT_TRUE(MLDSA65_sign_message_representative(
          encoded_signature.data(), priv.get(), representative));

      EXPECT_EQ(MLDSA65_verify(pub.get(), encoded_signature.data(),
                               encoded_signature.size(), kMessage,
                               sizeof(kMessage), nullptr, 0),
                1);
    }
  }
}

TEST(MLDSATest, PublicFromPrivateIsConsistent) {
  std::vector<uint8_t> encoded_public_key(MLDSA65_PUBLIC_KEY_BYTES);
  auto priv = std::make_unique<MLDSA65_private_key>();
  uint8_t seed[MLDSA_SEED_BYTES];
  EXPECT_TRUE(
      MLDSA65_generate_key(encoded_public_key.data(), seed, priv.get()));

  auto pub = std::make_unique<MLDSA65_public_key>();
  EXPECT_TRUE(MLDSA65_public_from_private(pub.get(), priv.get()));

  std::vector<uint8_t> encoded_public_key2(MLDSA65_PUBLIC_KEY_BYTES);

  CBB cbb;
  CBB_init_fixed(&cbb, encoded_public_key2.data(), encoded_public_key2.size());
  ASSERT_TRUE(MLDSA65_marshal_public_key(&cbb, pub.get()));

  EXPECT_EQ(Bytes(encoded_public_key2), Bytes(encoded_public_key));
}

TEST(MLDSATest, InvalidPublicKeyEncodingLength) {
  // Encode a public key with a trailing 0 at the end.
  std::vector<uint8_t> encoded_public_key(MLDSA65_PUBLIC_KEY_BYTES + 1);
  auto priv = std::make_unique<MLDSA65_private_key>();
  uint8_t seed[MLDSA_SEED_BYTES];
  EXPECT_TRUE(
      MLDSA65_generate_key(encoded_public_key.data(), seed, priv.get()));

  // Public key is 1 byte too short.
  CBS cbs =
      CBS(bssl::Span(encoded_public_key).first(MLDSA65_PUBLIC_KEY_BYTES - 1));
  auto parsed_pub = std::make_unique<MLDSA65_public_key>();
  EXPECT_FALSE(MLDSA65_parse_public_key(parsed_pub.get(), &cbs));

  // Public key has the correct length.
  cbs = CBS(bssl::Span(encoded_public_key).first(MLDSA65_PUBLIC_KEY_BYTES));
  EXPECT_TRUE(MLDSA65_parse_public_key(parsed_pub.get(), &cbs));

  // Public key is 1 byte too long.
  cbs = CBS(encoded_public_key);
  EXPECT_FALSE(MLDSA65_parse_public_key(parsed_pub.get(), &cbs));
}

TEST(MLDSATest, InvalidPrivateKeyEncodingLength) {
  std::vector<uint8_t> encoded_public_key(MLDSA65_PUBLIC_KEY_BYTES);
  auto priv = std::make_unique<MLDSA65_private_key>();
  uint8_t seed[MLDSA_SEED_BYTES];
  EXPECT_TRUE(bcm_success(
      BCM_mldsa65_generate_key(encoded_public_key.data(), seed, priv.get())));

  CBB cbb;
  std::vector<uint8_t> malformed_private_key(BCM_MLDSA65_PRIVATE_KEY_BYTES + 1,
                                             0);
  CBB_init_fixed(&cbb, malformed_private_key.data(),
                 BCM_MLDSA65_PRIVATE_KEY_BYTES);
  ASSERT_TRUE(bcm_success(BCM_mldsa65_marshal_private_key(&cbb, priv.get())));

  CBS cbs;
  auto parsed_priv = std::make_unique<MLDSA65_private_key>();

  // Private key is 1 byte too short.
  CBS_init(&cbs, malformed_private_key.data(),
           BCM_MLDSA65_PRIVATE_KEY_BYTES - 1);
  EXPECT_FALSE(
      bcm_success(BCM_mldsa65_parse_private_key(parsed_priv.get(), &cbs)));

  // Private key has the correct length.
  CBS_init(&cbs, malformed_private_key.data(), BCM_MLDSA65_PRIVATE_KEY_BYTES);
  EXPECT_TRUE(
      bcm_success(BCM_mldsa65_parse_private_key(parsed_priv.get(), &cbs)));

  // Private key is 1 byte too long.
  CBS_init(&cbs, malformed_private_key.data(),
           BCM_MLDSA65_PRIVATE_KEY_BYTES + 1);
  EXPECT_FALSE(
      bcm_success(BCM_mldsa65_parse_private_key(parsed_priv.get(), &cbs)));
}

template <typename PrivateKey, typename PublicKey, size_t SignatureBytes,
          bcm_status (*ParsePrivateKey)(PrivateKey *, CBS *),
          bcm_status (*SignInternal)(uint8_t *, const PrivateKey *,
                                     const uint8_t *, size_t, const uint8_t *,
                                     size_t, const uint8_t *, size_t,
                                     const uint8_t *),
          int (*PublicFromPrivate)(PublicKey *, const PrivateKey *),
          bcm_status (*VerifyInternal)(const PublicKey *, const uint8_t *,
                                       const uint8_t *, size_t, const uint8_t *,
                                       size_t, const uint8_t *, size_t)>
static void MLDSASigGenTest(FileTest *t) {
  std::vector<uint8_t> private_key_bytes, msg, expected_signature;
  ASSERT_TRUE(t->GetBytes(&private_key_bytes, "sk"));
  ASSERT_TRUE(t->GetBytes(&msg, "message"));
  ASSERT_TRUE(t->GetBytes(&expected_signature, "signature"));

  auto priv = std::make_unique<PrivateKey>();
  CBS cbs;
  CBS_init(&cbs, private_key_bytes.data(), private_key_bytes.size());
  EXPECT_TRUE(bcm_success(ParsePrivateKey(priv.get(), &cbs)));

  const uint8_t zero_randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES] = {0};
  std::vector<uint8_t> signature(SignatureBytes);
  EXPECT_TRUE(bcm_success(SignInternal(signature.data(), priv.get(), msg.data(),
                                       msg.size(), nullptr, 0, nullptr, 0,
                                       zero_randomizer)));

  EXPECT_EQ(Bytes(signature), Bytes(expected_signature));

  auto pub = std::make_unique<PublicKey>();
  ASSERT_TRUE(PublicFromPrivate(pub.get(), priv.get()));
  EXPECT_TRUE(
      bcm_success(VerifyInternal(pub.get(), signature.data(), msg.data(),
                                 msg.size(), nullptr, 0, nullptr, 0)));
}

TEST(MLDSATest, SigGenTests65) {
  FileTestGTest(
      "crypto/mldsa/mldsa_nist_siggen_65_tests.txt",
      MLDSASigGenTest<MLDSA65_private_key, MLDSA65_public_key,
                      MLDSA65_SIGNATURE_BYTES, BCM_mldsa65_parse_private_key,
                      BCM_mldsa65_sign_internal, MLDSA65_public_from_private,
                      BCM_mldsa65_verify_internal>);
}

TEST(MLDSATest, SigGenTests87) {
  FileTestGTest(
      "crypto/mldsa/mldsa_nist_siggen_87_tests.txt",
      MLDSASigGenTest<MLDSA87_private_key, MLDSA87_public_key,
                      MLDSA87_SIGNATURE_BYTES, BCM_mldsa87_parse_private_key,
                      BCM_mldsa87_sign_internal, MLDSA87_public_from_private,
                      BCM_mldsa87_verify_internal>);
}

TEST(MLDSATest, SigGenTests44) {
  FileTestGTest(
      "crypto/mldsa/mldsa_nist_siggen_44_tests.txt",
      MLDSASigGenTest<MLDSA44_private_key, MLDSA44_public_key,
                      MLDSA44_SIGNATURE_BYTES, BCM_mldsa44_parse_private_key,
                      BCM_mldsa44_sign_internal, MLDSA44_public_from_private,
                      BCM_mldsa44_verify_internal>);
}

template <typename PrivateKey, size_t PublicKeyBytes,
          bcm_status (*Generate)(uint8_t *, PrivateKey *, const uint8_t *),
          bcm_status (*MarshalPrivate)(CBB *, const PrivateKey *)>
static void MLDSAKeyGenTest(FileTest *t) {
  std::vector<uint8_t> seed, expected_public_key, expected_private_key;
  ASSERT_TRUE(t->GetBytes(&seed, "seed"));
  CONSTTIME_SECRET(seed.data(), seed.size());
  ASSERT_TRUE(t->GetBytes(&expected_public_key, "pub"));
  ASSERT_TRUE(t->GetBytes(&expected_private_key, "priv"));

  std::vector<uint8_t> encoded_public_key(PublicKeyBytes);
  auto priv = std::make_unique<PrivateKey>();
  ASSERT_TRUE(bcm_success(
      Generate(encoded_public_key.data(), priv.get(), seed.data())));

  const std::vector<uint8_t> encoded_private_key =
      Marshal(MarshalPrivate, priv.get());

  EXPECT_EQ(Bytes(encoded_public_key), Bytes(expected_public_key));
  EXPECT_EQ(Bytes(Declassified(encoded_private_key)),
            Bytes(expected_private_key));
}

TEST(MLDSATest, KeyGenTests65) {
  FileTestGTest("crypto/mldsa/mldsa_nist_keygen_65_tests.txt",
                MLDSAKeyGenTest<MLDSA65_private_key, MLDSA65_PUBLIC_KEY_BYTES,
                                BCM_mldsa65_generate_key_external_entropy,
                                BCM_mldsa65_marshal_private_key>);
}

TEST(MLDSATest, KeyGenTests87) {
  FileTestGTest(
      "crypto/mldsa/mldsa_nist_keygen_87_tests.txt",
      MLDSAKeyGenTest<MLDSA87_private_key, MLDSA87_PUBLIC_KEY_BYTES,
                      BCM_mldsa87_generate_key_external_entropy,
                      BCM_mldsa87_marshal_private_key>);
}

TEST(MLDSATest, KeyGenTests44) {
  FileTestGTest("crypto/mldsa/mldsa_nist_keygen_44_tests.txt",
                MLDSAKeyGenTest<MLDSA44_private_key, MLDSA44_PUBLIC_KEY_BYTES,
                                BCM_mldsa44_generate_key_external_entropy,
                                BCM_mldsa44_marshal_private_key>);
}

template <
    typename PrivateKey, bcm_status_t (*ParsePrivateKey)(PrivateKey *, CBS *),
    size_t SignatureBytes,
    bcm_status_t (*SignInternal)(uint8_t *, const PrivateKey *, const uint8_t *,
                                 size_t, const uint8_t *, size_t,
                                 const uint8_t *, size_t, const uint8_t *)>
static void MLDSAWycheproofSignTest(FileTest *t) {
  std::vector<uint8_t> private_key_bytes, msg, expected_signature, context;
  ASSERT_TRUE(t->GetInstructionBytes(&private_key_bytes, "privateKey"));
  ASSERT_TRUE(t->GetBytes(&msg, "msg"));
  ASSERT_TRUE(t->GetBytes(&expected_signature, "sig"));
  if (t->HasAttribute("ctx")) {
    t->GetBytes(&context, "ctx");
  }
  std::string result;
  ASSERT_TRUE(t->GetAttribute(&result, "result"));
  t->IgnoreAttribute("flags");

  CBS cbs;
  CBS_init(&cbs, private_key_bytes.data(), private_key_bytes.size());
  auto priv = std::make_unique<PrivateKey>();
  const int priv_ok = bcm_success(ParsePrivateKey(priv.get(), &cbs));

  if (!priv_ok) {
    ASSERT_TRUE(result != "valid");
    return;
  }

  // Unfortunately we need to reimplement the context length check here because
  // we are using the internal function in order to pass in an all-zero
  // randomizer.
  if (context.size() > 255) {
    ASSERT_TRUE(result != "valid");
    return;
  }

  const uint8_t zero_randomizer[BCM_MLDSA_SIGNATURE_RANDOMIZER_BYTES] = {0};
  std::vector<uint8_t> signature(SignatureBytes);
  const uint8_t context_prefix[2] = {0, static_cast<uint8_t>(context.size())};
  EXPECT_TRUE(bcm_success(SignInternal(signature.data(), priv.get(), msg.data(),
                                       msg.size(), context_prefix,
                                       sizeof(context_prefix), context.data(),
                                       context.size(), zero_randomizer)));

  EXPECT_EQ(Bytes(signature), Bytes(expected_signature));
}

TEST(MLDSATest, WycheproofSignTests65) {
  FileTestGTest(
      "third_party/wycheproof_testvectors/mldsa_65_standard_sign_test.txt",
      MLDSAWycheproofSignTest<
          MLDSA65_private_key, BCM_mldsa65_parse_private_key,
          MLDSA65_SIGNATURE_BYTES, BCM_mldsa65_sign_internal>);
}

TEST(MLDSATest, WycheproofSignTests87) {
  FileTestGTest(
      "third_party/wycheproof_testvectors/mldsa_87_standard_sign_test.txt",
      MLDSAWycheproofSignTest<
          MLDSA87_private_key, BCM_mldsa87_parse_private_key,
          MLDSA87_SIGNATURE_BYTES, BCM_mldsa87_sign_internal>);
}

TEST(MLDSATest, WycheproofSignTests44) {
  FileTestGTest(
      "third_party/wycheproof_testvectors/mldsa_44_standard_sign_test.txt",
      MLDSAWycheproofSignTest<
          MLDSA44_private_key, BCM_mldsa44_parse_private_key,
          MLDSA44_SIGNATURE_BYTES, BCM_mldsa44_sign_internal>);
}

template <typename PublicKey, size_t SignatureLength,
          int (*ParsePublicKey)(PublicKey *, CBS *),
          int (*Verify)(const PublicKey *, const uint8_t *, size_t,
                        const uint8_t *, size_t, const uint8_t *, size_t)>
static void MLDSAWycheproofVerifyTest(FileTest *t) {
  std::vector<uint8_t> public_key_bytes, msg, signature, context;
  ASSERT_TRUE(t->GetInstructionBytes(&public_key_bytes, "publicKey"));
  ASSERT_TRUE(t->GetBytes(&msg, "msg"));
  ASSERT_TRUE(t->GetBytes(&signature, "sig"));
  if (t->HasAttribute("ctx")) {
    t->GetBytes(&context, "ctx");
  }
  std::string result, flags;
  ASSERT_TRUE(t->GetAttribute(&result, "result"));
  ASSERT_TRUE(t->GetAttribute(&flags, "flags"));

  CBS cbs;
  CBS_init(&cbs, public_key_bytes.data(), public_key_bytes.size());
  auto pub = std::make_unique<PublicKey>();
  const int pub_ok = ParsePublicKey(pub.get(), &cbs);

  if (!pub_ok) {
    EXPECT_EQ(flags, "IncorrectPublicKeyLength");
    return;
  }

  const int sig_ok =
      Verify(pub.get(), signature.data(), signature.size(), msg.data(),
             msg.size(), context.data(), context.size());
  if (!sig_ok) {
    EXPECT_EQ(result, "invalid");
  } else {
    EXPECT_EQ(result, "valid");
  }
}

TEST(MLDSATest, WycheproofVerifyTests65) {
  FileTestGTest(
      "third_party/wycheproof_testvectors/mldsa_65_standard_verify_test.txt",
      MLDSAWycheproofVerifyTest<MLDSA65_public_key, MLDSA65_SIGNATURE_BYTES,
                                MLDSA65_parse_public_key, MLDSA65_verify>);
}

TEST(MLDSATest, WycheproofVerifyTests87) {
  FileTestGTest(
      "third_party/wycheproof_testvectors/mldsa_87_standard_verify_test.txt",
      MLDSAWycheproofVerifyTest<MLDSA87_public_key, MLDSA87_SIGNATURE_BYTES,
                                MLDSA87_parse_public_key, MLDSA87_verify>);
}

TEST(MLDSATest, WycheproofVerifyTests44) {
  FileTestGTest(
      "third_party/wycheproof_testvectors/mldsa_44_standard_verify_test.txt",
      MLDSAWycheproofVerifyTest<MLDSA44_public_key, MLDSA44_SIGNATURE_BYTES,
                                MLDSA44_parse_public_key, MLDSA44_verify>);
}

TEST(MLDSATest, Self) { ASSERT_TRUE(boringssl_self_test_mldsa()); }

TEST(MLDSATest, PWCT) {
  uint8_t seed[MLDSA_SEED_BYTES];

  auto pub65 = std::make_unique<uint8_t[]>(MLDSA65_PUBLIC_KEY_BYTES);
  auto priv65 = std::make_unique<MLDSA65_private_key>();
  ASSERT_EQ(BCM_mldsa65_generate_key_fips(pub65.get(), seed, priv65.get()),
            bcm_status::approved);

  auto pub87 = std::make_unique<uint8_t[]>(MLDSA87_PUBLIC_KEY_BYTES);
  auto priv87 = std::make_unique<MLDSA87_private_key>();
  ASSERT_EQ(BCM_mldsa87_generate_key_fips(pub87.get(), seed, priv87.get()),
            bcm_status::approved);

  auto pub44 = std::make_unique<uint8_t[]>(MLDSA44_PUBLIC_KEY_BYTES);
  auto priv44 = std::make_unique<MLDSA44_private_key>();
  ASSERT_EQ(BCM_mldsa44_generate_key_fips(pub44.get(), seed, priv44.get()),
            bcm_status::approved);
}

TEST(MLDSATest, NullptrArgumentsToCreate) {
  // For FIPS reasons, this should fail rather than crash.
  ASSERT_EQ(BCM_mldsa65_generate_key_fips(nullptr, nullptr, nullptr),
            bcm_status::failure);
  ASSERT_EQ(BCM_mldsa87_generate_key_fips(nullptr, nullptr, nullptr),
            bcm_status::failure);
  ASSERT_EQ(BCM_mldsa44_generate_key_fips(nullptr, nullptr, nullptr),
            bcm_status::failure);
  ASSERT_EQ(
      BCM_mldsa65_generate_key_external_entropy_fips(nullptr, nullptr, nullptr),
      bcm_status::failure);
  ASSERT_EQ(
      BCM_mldsa87_generate_key_external_entropy_fips(nullptr, nullptr, nullptr),
      bcm_status::failure);
  ASSERT_EQ(
      BCM_mldsa44_generate_key_external_entropy_fips(nullptr, nullptr, nullptr),
      bcm_status::failure);
}

}  // namespace
