// Copyright 2023 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
//
//    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 "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h"

#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "quiche/common/platform/api/quiche_test.h"
#include "quiche/common/test_tools/quiche_test_utils.h"
#include "absl/strings/escaping.h"
#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h"
#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h"
#include "openssl/base.h"
#include "openssl/rsa.h"

namespace private_membership {
namespace anonymous_tokens {
namespace {

struct IetfNewPublicExponentWithPublicMetadataTestVector {
  RSAPublicKey public_key;
  std::string public_metadata;
  std::string new_e;
};

TEST(AnonymousTokensCryptoUtilsTest, BignumToStringAndBack) {
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx());

  // Create a new BIGNUM using the context and set it
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> bn_1, NewBigNum());
  ASSERT_EQ(BN_set_u64(bn_1.get(), 0x124435435), 1);
  EXPECT_NE(bn_1, nullptr);
  EXPECT_EQ(BN_is_zero(bn_1.get()), 0);
  EXPECT_EQ(BN_is_one(bn_1.get()), 0);

  // Convert bn_1 to string from BIGNUM
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
      const std::string converted_str,
      BignumToString(*bn_1, BN_num_bytes(bn_1.get())));
  // Convert the string version of bn_1 back to BIGNUM
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> bn_2,
                                   StringToBignum(converted_str));
  // Check whether the conversion back worked
  EXPECT_EQ(BN_cmp(bn_1.get(), bn_2.get()), 0);
}

TEST(AnonymousTokensCryptoUtilsTest, PowerOfTwoAndRsaSqrtTwo) {
  // Compute 2^(10-1/2).
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> sqrt2,
                                   GetRsaSqrtTwo(10));
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> small_pow2,
                                   ComputePowerOfTwo(9));
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> large_pow2,
                                   ComputePowerOfTwo(10));
  EXPECT_GT(BN_cmp(sqrt2.get(), small_pow2.get()), 0);
  EXPECT_LT(BN_cmp(sqrt2.get(), large_pow2.get()), 0);
}

TEST(AnonymousTokensCryptoUtilsTest, ComputeHashAcceptsNullStringView) {
  absl::StatusOr<std::string> null_hash =
      ComputeHash(absl::string_view(nullptr, 0), *EVP_sha512());
  absl::StatusOr<std::string> empty_hash = ComputeHash("", *EVP_sha512());
  std::string str;
  absl::StatusOr<std::string> empty_str_hash = ComputeHash(str, *EVP_sha512());

  QUICHE_EXPECT_OK(null_hash);
  QUICHE_EXPECT_OK(empty_hash);
  QUICHE_EXPECT_OK(empty_str_hash);

  EXPECT_EQ(*null_hash, *empty_hash);
  EXPECT_EQ(*null_hash, *empty_str_hash);
}

TEST(AnonymousTokensCryptoUtilsTest, ComputeCarmichaelLcm) {
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx());

  // Suppose that N = 1019 * 1187.
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> phi_p, NewBigNum());
  ASSERT_TRUE(BN_set_word(phi_p.get(), 1019 - 1));
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> phi_q, NewBigNum());
  ASSERT_TRUE(BN_set_word(phi_q.get(), 1187 - 1));
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> expected_lcm,
                                   NewBigNum());
  ASSERT_TRUE(BN_set_word(expected_lcm.get(), (1019 - 1) * (1187 - 1) / 2));

  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> lcm,
                                   ComputeCarmichaelLcm(*phi_p, *phi_q, *ctx));
  EXPECT_EQ(BN_cmp(lcm.get(), expected_lcm.get()), 0);
}

struct ComputeHashTestParam {
  const EVP_MD* hasher;
  absl::string_view input_hex;
  absl::string_view expected_digest_hex;
};

using ComputeHashTest = testing::TestWithParam<ComputeHashTestParam>;

// Returns the test parameters for ComputeHashTestParam from NIST's
// samples.
std::vector<ComputeHashTestParam> GetComputeHashTestParams() {
  std::vector<ComputeHashTestParam> params;
  params.push_back({
      EVP_sha256(),
      "af397a8b8dd73ab702ce8e53aa9f",
      "d189498a3463b18e846b8ab1b41583b0b7efc789dad8a7fb885bbf8fb5b45c5c",
  });
  params.push_back({
      EVP_sha256(),
      "59eb45bbbeb054b0b97334d53580ce03f699",
      "32c38c54189f2357e96bd77eb00c2b9c341ebebacc2945f97804f59a93238288",
  });
  params.push_back({
      EVP_sha512(),
      "16b17074d3e3d97557f9ed77d920b4b1bff4e845b345a922",
      "6884134582a760046433abcbd53db8ff1a89995862f305b887020f6da6c7b903a314721e"
      "972bf438483f452a8b09596298a576c903c91df4a414c7bd20fd1d07",
  });
  params.push_back({
      EVP_sha512(),
      "7651ab491b8fa86f969d42977d09df5f8bee3e5899180b52c968b0db057a6f02a886ad61"
      "7a84915a",
      "f35e50e2e02b8781345f8ceb2198f068ba103476f715cfb487a452882c9f0de0c720b2a0"
      "88a39d06a8a6b64ce4d6470dfeadc4f65ae06672c057e29f14c4daf9",
  });
  return params;
}

TEST_P(ComputeHashTest, ComputesHash) {
  const ComputeHashTestParam& params = GetParam();
  ASSERT_NE(params.hasher, nullptr);
  std::string data = absl::HexStringToBytes(params.input_hex);
  std::string expected_digest =
      absl::HexStringToBytes(params.expected_digest_hex);
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto computed_hash,
                                   ComputeHash(data, *params.hasher));
  EXPECT_EQ(computed_hash, expected_digest);
}

INSTANTIATE_TEST_SUITE_P(ComputeHashTests, ComputeHashTest,
                         testing::ValuesIn(GetComputeHashTestParams()));

TEST(PublicMetadataCryptoUtilsInternalTest, PublicMetadataHashWithHKDF) {
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx());
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> max_value,
                                   NewBigNum());
  ASSERT_TRUE(BN_set_word(max_value.get(), 4294967295));
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto key_pair, GetStrongRsaKeys2048());
  std::string input1 = "ro1";
  std::string input2 = "ro2";
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
      bssl::UniquePtr<BIGNUM> output1,
      internal::PublicMetadataHashWithHKDF(input1, key_pair.first.n(),
                                           1 + input1.size()));
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
      bssl::UniquePtr<BIGNUM> another_output1,
      internal::PublicMetadataHashWithHKDF(input1, key_pair.first.n(),
                                           1 + input1.size()));
  EXPECT_EQ(BN_cmp(output1.get(), another_output1.get()), 0);

  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
      bssl::UniquePtr<BIGNUM> output2,
      internal::PublicMetadataHashWithHKDF(input2, key_pair.first.n(),
                                           1 + input2.size()));
  EXPECT_NE(BN_cmp(output1.get(), output2.get()), 0);

  EXPECT_LE(BN_cmp(output1.get(), max_value.get()), 0);
  EXPECT_LE(BN_cmp(output2.get(), max_value.get()), 0);
}

TEST(PublicMetadataCryptoUtilsTest, PublicExponentHashDifferentModulus) {
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto key_pair_1, GetStrongRsaKeys2048());
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto key_pair_2,
                                   GetAnotherStrongRsaKeys2048());
  std::string metadata = "md";
  // Check that same metadata and different modulus result in different
  // hashes.
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> rsa_modulus_1,
                                   StringToBignum(key_pair_1.first.n()));
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
      bssl::UniquePtr<BIGNUM> exp1,
      PublicMetadataExponent(*rsa_modulus_1.get(), metadata));
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto rsa_modulus_2,
                                   StringToBignum(key_pair_2.first.n()));
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
      bssl::UniquePtr<BIGNUM> exp2,
      PublicMetadataExponent(*rsa_modulus_2.get(), metadata));
  EXPECT_NE(BN_cmp(exp1.get(), exp2.get()), 0);
}

std::vector<IetfNewPublicExponentWithPublicMetadataTestVector>
GetIetfNewPublicExponentWithPublicMetadataTestVectors() {
  std::vector<IetfNewPublicExponentWithPublicMetadataTestVector> test_vectors;

  RSAPublicKey public_key;
  public_key.set_n(absl::HexStringToBytes(
      "d6930820f71fe517bf3259d14d40209b02a5c0d3d61991c731dd7da39f8d69821552e231"
      "8d6c9ad897e603887a476ea3162c1205da9ac96f02edf31df049bd55f142134c17d4382a"
      "0e78e275345f165fbe8e49cdca6cf5c726c599dd39e09e75e0f330a33121e73976e4facb"
      "a9cfa001c28b7c96f8134f9981db6750b43a41710f51da4240fe03106c12acb1e7bb53d7"
      "5ec7256da3fddd0718b89c365410fce61bc7c99b115fb4c3c318081fa7e1b65a37774e8e"
      "50c96e8ce2b2cc6b3b367982366a2bf9924c4bafdb3ff5e722258ab705c76d43e5f1f121"
      "b984814e98ea2b2b8725cd9bc905c0bc3d75c2a8db70a7153213c39ae371b2b5dc1dafcb"
      "19d6fae9"));
  public_key.set_e(absl::HexStringToBytes("010001"));

  // Test vector 1
  test_vectors.push_back(
      {.public_key = public_key,
       .public_metadata = absl::HexStringToBytes("6d65746164617461"),
       .new_e = absl::HexStringToBytes(
           "30584b72f5cb557085106232f051d039e23358feee9204cf30ea567620e90d79e4a"
           "7a81388b1f390e18ea5240a1d8cc296ce1325128b445c48aa5a3b34fa07c324bf17"
           "bc7f1b3efebaff81d7e032948f1477493bc183d2f8d94c947c984c6f0757527615b"
           "f2a2f0ef0db5ad80ce99905beed0440b47fa5cb9a2334fea40ad88e6ef1")});

  // Test vector 2
  test_vectors.push_back(
      {.public_key = public_key,
       .public_metadata = "",
       .new_e = absl::HexStringToBytes(
           "2ed5a8d2592a11bbeef728bb39018ef5c3cf343507dd77dd156d5eec7f06f04732e"
           "4be944c5d2443d244c59e52c9fa5e8de40f55ffd0e70fbe9093d3f7be2aafd77c14"
           "b263b71c1c6b3ca2b9629842a902128fee4878392a950906fae35d6194e0d2548e5"
           "8bbc20f841188ca2fceb20b2b1b45448da5c7d1c73fb6e83fa58867397b")});

  return test_vectors;
}

TEST(PublicMetadataCryptoUtilsTest,
     IetfNewPublicExponentWithPublicMetadataTests) {
  const auto test_vectors =
      GetIetfNewPublicExponentWithPublicMetadataTestVectors();
  for (const IetfNewPublicExponentWithPublicMetadataTestVector& test_vector :
       test_vectors) {
    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
        bssl::UniquePtr<BIGNUM> rsa_modulus,
        StringToBignum(test_vector.public_key.n()));
    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
        bssl::UniquePtr<BIGNUM> rsa_e,
        StringToBignum(test_vector.public_key.e()));
    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> expected_new_e,
                                     StringToBignum(test_vector.new_e));
    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
        bssl::UniquePtr<BIGNUM> modified_e,
        ComputeFinalExponentUnderPublicMetadata(
            *rsa_modulus.get(), *rsa_e.get(), test_vector.public_metadata));

    EXPECT_EQ(BN_cmp(modified_e.get(), expected_new_e.get()), 0);
  }
}

// copybara:strip_begin(internal comment)
// The input public key and the expected DER encoding are taken from the
// following Goa test:
// http://google3/privacy/net/boq/common/tokens/token_types_test.go;l=21;rcl=528885322
// copybara:strip_end
TEST(CryptoUtilsTest, RsaPssDerEncodingTest) {
  RSAPublicKey public_key_e_not_padded;
  RSAPublicKey public_key_e_padded;

  public_key_e_not_padded.set_n(absl::HexStringToBytes(
      "b259758bb02bc75b68b17612c9bf68c5fa05958a334c61e167bc20bcc75757c126e892"
      "10b9df3989072cf6260e6883c7cd4af4d31dde9915b69b301fbef962de8c71bd2db5ec62"
      "5da259712f86a8dc3d241e9688c82391b7bf1ebc358311f55c26be910b76f61fea408ed6"
      "92f1a9578a622c82c0fcf6f69ef3670e38bfc90f63da4f3bbbd088c8ae7a3c5a55e66f64"
      "74d562d32cce7b7edd7cf0149ca0e96cb6525e81fbba815a8f12748e34e5135f572b2e17"
      "b7ba430081597e6fb9033c005884d5935118c60d75b010f6fece7ecdcc1cb7d58d138969"
      "3d43377f4f3de949cb1e4105e792b96d7f04b0cd262ac33cffc5a890d267425e61c19e93"
      "63550f2285"));
  // A hex string of 3 bytes in length is passed.
  public_key_e_not_padded.set_e(absl::HexStringToBytes("010001"));

  public_key_e_padded.set_n(public_key_e_not_padded.n());
  // A hex string of 4 bytes in length is passed.
  public_key_e_padded.set_e(absl::HexStringToBytes("00010001"));

  // Convert both padded and not padded rsa public keys to rsa structs.
  ASSERT_OK_AND_ASSIGN(
      bssl::UniquePtr<RSA> rsa_e_not_padded,
      AnonymousTokensRSAPublicKeyToRSA(public_key_e_not_padded));
  ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<RSA> rsa_e_padded,
                       AnonymousTokensRSAPublicKeyToRSA(public_key_e_padded));
  // Encode both padded and not padded rsa structs to DER.
  ASSERT_OK_AND_ASSIGN(std::string result_e_not_padded,
                       RsaSsaPssPublicKeyToDerEncoding(rsa_e_not_padded.get()));
  ASSERT_OK_AND_ASSIGN(std::string result_e_padded,
                       RsaSsaPssPublicKeyToDerEncoding(rsa_e_padded.get()));

  std::string expected_der_encoding = absl::HexStringToBytes(
      "30820152303d06092a864886f70d01010a3030a00d300b0609608648016503040202a11a"
      "301806092a864886f70d010108300b0609608648016503040202a2030201300382010f00"
      "3082010a0282010100b259758bb02bc75b68b17612c9bf68c5fa05958a334c61e167bc20"
      "bcc75757c126e89210b9df3989072cf6260e6883c7cd4af4d31dde9915b69b301fbef962"
      "de8c71bd2db5ec625da259712f86a8dc3d241e9688c82391b7bf1ebc358311f55c26be91"
      "0b76f61fea408ed692f1a9578a622c82c0fcf6f69ef3670e38bfc90f63da4f3bbbd088c8"
      "ae7a3c5a55e66f6474d562d32cce7b7edd7cf0149ca0e96cb6525e81fbba815a8f12748e"
      "34e5135f572b2e17b7ba430081597e6fb9033c005884d5935118c60d75b010f6fece7ecd"
      "cc1cb7d58d1389693d43377f4f3de949cb1e4105e792b96d7f04b0cd262ac33cffc5a890"
      "d267425e61c19e9363550f22850203010001");

  EXPECT_EQ(result_e_not_padded, expected_der_encoding);
  EXPECT_EQ(result_e_padded, expected_der_encoding);
}

// The public key used in this test is taken from the test vectors found here:
// https://www.ietf.org/archive/id/draft-ietf-privacypass-protocol-10.html#name-issuance-protocol-2-blind-rs
TEST(CryptoUtilsTest, IetfPrivacyPassBlindRsaPublicKeyToDerTest) {
  RSAPublicKey public_key;
  public_key.set_n(absl::HexStringToBytes(
      "cb1aed6b6a95f5b1ce013a4cfcab25b94b2e64a23034e4250a7eab43c0df3a8c12993af1"
      "2b111908d4b471bec31d4b6c9ad9cdda90612a2ee903523e6de5a224d6b02f09e5c374d0"
      "cfe01d8f529c500a78a2f67908fa682b5a2b430c81eaf1af72d7b5e794fc98a313927687"
      "9757ce453b526ef9bf6ceb99979b8423b90f4461a22af37aab0cf5733f7597abe44d31c7"
      "32db68a181c6cbbe607d8c0e52e0655fd9996dc584eca0be87afbcd78a337d17b1dba9e8"
      "28bbd81e291317144e7ff89f55619709b096cbb9ea474cead264c2073fe49740c01f00e1"
      "09106066983d21e5f83f086e2e823c879cd43cef700d2a352a9babd612d03cad02db134b"
      "7e225a5f"));
  public_key.set_e(absl::HexStringToBytes("010001"));
  ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<RSA> rsa,
                       AnonymousTokensRSAPublicKeyToRSA(public_key));
  ASSERT_OK_AND_ASSIGN(std::string result,
                       RsaSsaPssPublicKeyToDerEncoding(rsa.get()));

  std::string expected_der_encoding = absl::HexStringToBytes(
      "30820152303d06092a864886f70d01010a3030a00d300b0609608648016503040202a11a"
      "301806092a864886f70d010108300b0609608648016503040202a2030201300382010f00"
      "3082010a0282010100cb1aed6b6a95f5b1ce013a4cfcab25b94b2e64a23034e4250a7eab"
      "43c0df3a8c12993af12b111908d4b471bec31d4b6c9ad9cdda90612a2ee903523e6de5a2"
      "24d6b02f09e5c374d0cfe01d8f529c500a78a2f67908fa682b5a2b430c81eaf1af72d7b5"
      "e794fc98a3139276879757ce453b526ef9bf6ceb99979b8423b90f4461a22af37aab0cf5"
      "733f7597abe44d31c732db68a181c6cbbe607d8c0e52e0655fd9996dc584eca0be87afbc"
      "d78a337d17b1dba9e828bbd81e291317144e7ff89f55619709b096cbb9ea474cead264c2"
      "073fe49740c01f00e109106066983d21e5f83f086e2e823c879cd43cef700d2a352a9bab"
      "d612d03cad02db134b7e225a5f0203010001");

  EXPECT_EQ(result, expected_der_encoding);
}

using CreateTestKeyPairFunction =
    absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>>();

class CryptoUtilsTest
    : public testing::TestWithParam<CreateTestKeyPairFunction*> {
 protected:
  void SetUp() override {
    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto keys_pair, (*GetParam())());
    public_key_ = std::move(keys_pair.first);
    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_modulus_,
                                     StringToBignum(keys_pair.second.n()));
    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_e_,
                                     StringToBignum(keys_pair.second.e()));
    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_p_,
                                     StringToBignum(keys_pair.second.p()));
    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_q_,
                                     StringToBignum(keys_pair.second.q()));
  }

  bssl::UniquePtr<BIGNUM> rsa_modulus_;
  bssl::UniquePtr<BIGNUM> rsa_e_;
  bssl::UniquePtr<BIGNUM> rsa_p_;
  bssl::UniquePtr<BIGNUM> rsa_q_;
  RSAPublicKey public_key_;
};

TEST_P(CryptoUtilsTest, PublicExponentCoprime) {
  std::string metadata = "md";
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
      bssl::UniquePtr<BIGNUM> exp,
      PublicMetadataExponent(*rsa_modulus_.get(), metadata));
  int rsa_mod_size_bits = BN_num_bits(rsa_modulus_.get());
  // Check that exponent is odd.
  EXPECT_EQ(BN_is_odd(exp.get()), 1);
  // Check that exponent is small enough.
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> sqrt2,
                                   GetRsaSqrtTwo(rsa_mod_size_bits / 2));
  EXPECT_LT(BN_cmp(exp.get(), sqrt2.get()), 0);
  EXPECT_LT(BN_cmp(exp.get(), rsa_p_.get()), 0);
  EXPECT_LT(BN_cmp(exp.get(), rsa_q_.get()), 0);
}

TEST_P(CryptoUtilsTest, PublicExponentHash) {
  std::string metadata1 = "md1";
  std::string metadata2 = "md2";
  // Check that hash is deterministic.
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
      bssl::UniquePtr<BIGNUM> exp1,
      PublicMetadataExponent(*rsa_modulus_.get(), metadata1));
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
      bssl::UniquePtr<BIGNUM> another_exp1,
      PublicMetadataExponent(*rsa_modulus_.get(), metadata1));
  EXPECT_EQ(BN_cmp(exp1.get(), another_exp1.get()), 0);
  // Check that hashes are distinct for different metadata.
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
      bssl::UniquePtr<BIGNUM> exp2,
      PublicMetadataExponent(*rsa_modulus_.get(), metadata2));
  EXPECT_NE(BN_cmp(exp1.get(), exp2.get()), 0);
}

TEST_P(CryptoUtilsTest, FinalExponentCoprime) {
  std::string metadata = "md";
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
      bssl::UniquePtr<BIGNUM> final_exponent,
      ComputeFinalExponentUnderPublicMetadata(*rsa_modulus_.get(),
                                              *rsa_e_.get(), metadata));
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx());

  // Check that exponent is odd.
  EXPECT_EQ(BN_is_odd(final_exponent.get()), 1);
  // Check that exponent is co-prime to factors of the rsa modulus.
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> gcd_p_fe,
                                   NewBigNum());
  ASSERT_EQ(
      BN_gcd(gcd_p_fe.get(), rsa_p_.get(), final_exponent.get(), ctx.get()), 1);
  EXPECT_EQ(BN_cmp(gcd_p_fe.get(), BN_value_one()), 0);
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> gcd_q_fe,
                                   NewBigNum());
  ASSERT_EQ(
      BN_gcd(gcd_q_fe.get(), rsa_q_.get(), final_exponent.get(), ctx.get()), 1);
  EXPECT_EQ(BN_cmp(gcd_q_fe.get(), BN_value_one()), 0);
}

TEST_P(CryptoUtilsTest, DeterministicModificationOfPublicExponentWithMetadata) {
  std::string metadata = "md";
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
      bssl::UniquePtr<BIGNUM> public_exp_1,
      ComputeFinalExponentUnderPublicMetadata(*rsa_modulus_.get(),
                                              *rsa_e_.get(), metadata));
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
      bssl::UniquePtr<BIGNUM> public_exp_2,
      ComputeFinalExponentUnderPublicMetadata(*rsa_modulus_.get(),
                                              *rsa_e_.get(), metadata));

  EXPECT_EQ(BN_cmp(public_exp_1.get(), public_exp_2.get()), 0);
}

TEST_P(CryptoUtilsTest, DifferentPublicExponentWithDifferentPublicMetadata) {
  std::string metadata_1 = "md1";
  std::string metadata_2 = "md2";
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
      bssl::UniquePtr<BIGNUM> public_exp_1,
      ComputeFinalExponentUnderPublicMetadata(*rsa_modulus_.get(),
                                              *rsa_e_.get(), metadata_1));
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
      bssl::UniquePtr<BIGNUM> public_exp_2,
      ComputeFinalExponentUnderPublicMetadata(*rsa_modulus_.get(),
                                              *rsa_e_.get(), metadata_2));
  // Check that exponent is different in all keys
  EXPECT_NE(BN_cmp(public_exp_1.get(), public_exp_2.get()), 0);
  EXPECT_NE(BN_cmp(public_exp_1.get(), rsa_e_.get()), 0);
  EXPECT_NE(BN_cmp(public_exp_2.get(), rsa_e_.get()), 0);
}

TEST_P(CryptoUtilsTest, ModifiedPublicExponentWithEmptyPublicMetadata) {
  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> new_public_exp,
                                   ComputeFinalExponentUnderPublicMetadata(
                                       *rsa_modulus_.get(), *rsa_e_.get(), ""));

  EXPECT_NE(BN_cmp(new_public_exp.get(), rsa_e_.get()), 0);
}

INSTANTIATE_TEST_SUITE_P(CryptoUtilsTest, CryptoUtilsTest,
                         testing::Values(&GetStrongRsaKeys2048,
                                         &GetAnotherStrongRsaKeys2048,
                                         &GetStrongRsaKeys3072,
                                         &GetStrongRsaKeys4096));

}  // namespace
}  // namespace anonymous_tokens
}  // namespace private_membership
