Updating PublicMetadataHashWithHKDF function according to the latest IETF draft before we use it in prod. Adding the latest test vectors as well.

This CL also makes sure that openssl RSA struct is not used as storage for the exponent augmented with the public metadata in blinder as well as the verifier in third_party/anonymous_tokens/cpp/crypto.

These changes will let us enable public metadata support in prod in follow-up CLs as well as accept empty public metadata as a valid value when public metadata support in enabled.

PiperOrigin-RevId: 518984326
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc
index 656862a..d007d44 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc
@@ -31,6 +31,12 @@
 namespace anonymous_tokens {
 namespace {
 
+struct IetfNewPublicExponentWithPublicMetadataTestVector {
+  RSAPublicKey public_key;
+  std::string public_metadata;
+  std::string new_e;
+};
+
 TEST(CryptoUtilsTest, BignumToStringAndBack) {
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx());
 
@@ -148,164 +154,6 @@
 INSTANTIATE_TEST_SUITE_P(ComputeHashTests, ComputeHashTest,
                          testing::ValuesIn(GetComputeHashTestParams()));
 
-std::pair<RSAPublicKey, std::string> GetFixedTestPublicKeyAndPublicMetadata() {
-  RSAPublicKey public_key;
-  public_key.set_n(absl::HexStringToBytes(
-      "b2ae391467872a7506468a9ac4e980fa76164666955ef8999917295dbbd89dd7aa9c0e41"
-      "2dcda3dd1aa867e0c414d80afb9544a7c71c32d83e1b8417f293f325d2ffe2f9e296d28f"
-      "b89a443de5cc06ab3c516913fc18694539c370315d3e7f4ac5f87faaf3fee751c9f439ae"
-      "8d53eee249d8c49b33bd3bb7aa060eb462522da98a02f92eff110cc9408ca0ccc54abf2c"
-      "fcb68b77fb0ec7048d8b76416f61f2b182ea73169ed18f0d1d238dcaf6fc9de067d4831f"
-      "68f485483dd5c9ec17d9384825ba7284bc38bb1ea5e40d9207d9007e609a19e3fab695a1"
-      "8c30f1a7c4b03c77ef72211415a0bfeacd3298dccafa7e06e41dc2131f9076b92bb352c8"
-      "f7bccfe9"));
-  public_key.set_e(absl::HexStringToBytes("03"));
-  std::string public_metadata = absl::HexStringToBytes("6d65746164617461");
-  return std::make_pair(std::move(public_key), std::move(public_metadata));
-}
-
-std::string GetFixedTestNewPublicKeyExponentUnderPublicMetadata() {
-  std::string new_e = absl::HexStringToBytes(
-      "0b2d80537b4c899c7107eef3b74ddc0dcd931aff9c583ce3cf3527d42483052b27d55dd4"
-      "d2f831a38430f13d81574c51aa97af6f5c3a6c03b269bc156d029273bd60e7af578fff15"
-      "c52cbb5c19288fd1ce59f6f756b2d93b6f2586210fb969efb5065700da5598bb8914d395"
-      "4d97a49c5ca05b2386bc3cf098281958cf372481");
-  return new_e;
-}
-
-using CreateTestKeyPairFunction =
-    absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>>();
-
-class CryptoUtilsTest
-    : public testing::TestWithParam<CreateTestKeyPairFunction*> {
- protected:
-  void SetUp() override {
-    ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(auto keys_pair, (*GetParam())());
-    ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-        private_key_, AnonymousTokensRSAPrivateKeyToRSA(keys_pair.second));
-    public_key_ = std::move(keys_pair.first);
-  }
-
-  bssl::UniquePtr<RSA> private_key_;
-  RSAPublicKey public_key_;
-};
-
-TEST_P(CryptoUtilsTest, PublicExponentCoprime) {
-  std::string metadata = "md";
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      bssl::UniquePtr<BIGNUM> exp,
-      PublicMetadataExponent(*RSA_get0_n(private_key_.get()), metadata));
-  int rsa_mod_size_bits = BN_num_bits(RSA_get0_n(private_key_.get()));
-  // Check that exponent is odd.
-  EXPECT_EQ(BN_is_odd(exp.get()), 1);
-  // Check that exponent is small enough.
-  ANON_TOKENS_QUICHE_EXPECT_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_get0_p(private_key_.get())), 0);
-  EXPECT_LT(BN_cmp(exp.get(), RSA_get0_q(private_key_.get())), 0);
-}
-
-TEST_P(CryptoUtilsTest, PublicExponentHash) {
-  std::string metadata1 = "md1";
-  std::string metadata2 = "md2";
-  // Check that hash is deterministic.
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      bssl::UniquePtr<BIGNUM> exp1,
-      PublicMetadataExponent(*RSA_get0_n(private_key_.get()), metadata1));
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      bssl::UniquePtr<BIGNUM> another_exp1,
-      PublicMetadataExponent(*RSA_get0_n(private_key_.get()), metadata1));
-  EXPECT_EQ(BN_cmp(exp1.get(), another_exp1.get()), 0);
-  // Check that hashes are distinct for different metadata.
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      bssl::UniquePtr<BIGNUM> exp2,
-      PublicMetadataExponent(*RSA_get0_n(private_key_.get()), metadata2));
-  EXPECT_NE(BN_cmp(exp1.get(), exp2.get()), 0);
-}
-
-TEST_P(CryptoUtilsTest, FinalExponentCoprime) {
-  std::string metadata = "md";
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      bssl::UniquePtr<BIGNUM> final_exponent,
-      ComputeFinalExponentUnderPublicMetadata(*RSA_get0_n(private_key_.get()),
-                                              *RSA_get0_e(private_key_.get()),
-                                              metadata));
-  ANON_TOKENS_QUICHE_EXPECT_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_QUICHE_EXPECT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> gcd_p_fe,
-                                   NewBigNum());
-  ASSERT_EQ(BN_gcd(gcd_p_fe.get(), RSA_get0_p(private_key_.get()),
-                   final_exponent.get(), ctx.get()),
-            1);
-  EXPECT_EQ(BN_cmp(gcd_p_fe.get(), BN_value_one()), 0);
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> gcd_q_fe,
-                                   NewBigNum());
-  ASSERT_EQ(BN_gcd(gcd_q_fe.get(), RSA_get0_q(private_key_.get()),
-                   final_exponent.get(), ctx.get()),
-            1);
-  EXPECT_EQ(BN_cmp(gcd_q_fe.get(), BN_value_one()), 0);
-}
-
-TEST_P(CryptoUtilsTest, DeterministicRSAPublicKeyToRSAUnderPublicMetadata) {
-  std::string metadata = "md";
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      bssl::UniquePtr<RSA> rsa_public_key_1,
-      RSAPublicKeyToRSAUnderPublicMetadata(public_key_, metadata));
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      bssl::UniquePtr<RSA> rsa_public_key_2,
-      RSAPublicKeyToRSAUnderPublicMetadata(public_key_, metadata));
-  EXPECT_EQ(BN_cmp(RSA_get0_e(rsa_public_key_1.get()),
-                   RSA_get0_e(rsa_public_key_2.get())),
-            0);
-}
-
-TEST_P(CryptoUtilsTest,
-       DifferentPublicMetadataRSAPublicKeyToRSAUnderPublicMetadata) {
-  std::string metadata_1 = "md1";
-  std::string metadata_2 = "md2";
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      bssl::UniquePtr<RSA> rsa_public_key_1,
-      RSAPublicKeyToRSAUnderPublicMetadata(public_key_, metadata_1));
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      bssl::UniquePtr<RSA> rsa_public_key_2,
-      RSAPublicKeyToRSAUnderPublicMetadata(public_key_, metadata_2));
-  // Check that exponent is different in all keys
-  EXPECT_NE(BN_cmp(RSA_get0_e(rsa_public_key_1.get()),
-                   RSA_get0_e(rsa_public_key_2.get())),
-            0);
-  EXPECT_NE(BN_cmp(RSA_get0_e(rsa_public_key_1.get()),
-                   RSA_get0_e(private_key_.get())),
-            0);
-  EXPECT_NE(BN_cmp(RSA_get0_e(rsa_public_key_1.get()),
-                   RSA_get0_e(private_key_.get())),
-            0);
-}
-
-TEST_P(CryptoUtilsTest, NoPublicMetadataRSAPublicKeyToRSAUnderPublicMetadata) {
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      bssl::UniquePtr<RSA> rsa_public_key,
-      RSAPublicKeyToRSAUnderPublicMetadata(public_key_, ""));
-
-  // Check that exponent is same in output and input.
-  EXPECT_EQ(
-      BN_cmp(RSA_get0_e(rsa_public_key.get()), RSA_get0_e(private_key_.get())),
-      0);
-  // Check that rsa_modulus is correct
-  EXPECT_EQ(
-      BN_cmp(RSA_get0_n(rsa_public_key.get()), RSA_get0_n(private_key_.get())),
-      0);
-}
-
-INSTANTIATE_TEST_SUITE_P(CryptoUtilsTest, CryptoUtilsTest,
-                         testing::Values(&GetStrongRsaKeys2048,
-                                         &GetAnotherStrongRsaKeys2048,
-                                         &GetStrongRsaKeys3072,
-                                         &GetStrongRsaKeys4096));
-
 TEST(CryptoUtilsInternalTest, PublicMetadataHashWithHKDF) {
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx());
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> max_value,
@@ -341,41 +189,208 @@
   std::string metadata = "md";
   // Check that same metadata and different modulus result in different
   // hashes.
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      auto rsa_private_key_1,
-      AnonymousTokensRSAPrivateKeyToRSA(key_pair_1.second));
+  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> rsa_modulus_1,
+                                   StringToBignum(key_pair_1.first.n()));
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
       bssl::UniquePtr<BIGNUM> exp1,
-      PublicMetadataExponent(*RSA_get0_n(rsa_private_key_1.get()), metadata));
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      auto rsa_private_key_2,
-      AnonymousTokensRSAPrivateKeyToRSA(key_pair_2.second));
+      PublicMetadataExponent(*rsa_modulus_1.get(), metadata));
+  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(auto rsa_modulus_2,
+                                   StringToBignum(key_pair_2.first.n()));
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
       bssl::UniquePtr<BIGNUM> exp2,
-      PublicMetadataExponent(*RSA_get0_n(rsa_private_key_2.get()), metadata));
+      PublicMetadataExponent(*rsa_modulus_2.get(), metadata));
   EXPECT_NE(BN_cmp(exp1.get(), exp2.get()), 0);
 }
 
-TEST(CryptoUtilsTest, FixedTestRSAPublicKeyToRSAUnderPublicMetadata) {
-  const auto public_key_and_metadata = GetFixedTestPublicKeyAndPublicMetadata();
-  const std::string expected_new_e_str =
-      GetFixedTestNewPublicKeyExponentUnderPublicMetadata();
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      bssl::UniquePtr<BIGNUM> rsa_modulus,
-      StringToBignum(public_key_and_metadata.first.n()));
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> expected_new_e,
-                                   StringToBignum(expected_new_e_str));
-  ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      bssl::UniquePtr<RSA> modified_rsa_public_key,
-      RSAPublicKeyToRSAUnderPublicMetadata(public_key_and_metadata.first,
-                                           public_key_and_metadata.second));
-  EXPECT_EQ(
-      BN_cmp(RSA_get0_n(modified_rsa_public_key.get()), rsa_modulus.get()), 0);
-  EXPECT_EQ(
-      BN_cmp(RSA_get0_e(modified_rsa_public_key.get()), expected_new_e.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(CryptoUtilsTest, IetfNewPublicExponentWithPublicMetadataTests) {
+  const auto test_vectors =
+      GetIetfNewPublicExponentWithPublicMetadataTestVectors();
+  for (const IetfNewPublicExponentWithPublicMetadataTestVector& test_vector :
+       test_vectors) {
+    ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
+        bssl::UniquePtr<BIGNUM> rsa_modulus,
+        StringToBignum(test_vector.public_key.n()));
+    ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
+        bssl::UniquePtr<BIGNUM> rsa_e,
+        StringToBignum(test_vector.public_key.e()));
+    ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> expected_new_e,
+                                     StringToBignum(test_vector.new_e));
+    ANON_TOKENS_QUICHE_EXPECT_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);
+  }
+}
+
+using CreateTestKeyPairFunction =
+    absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>>();
+
+class CryptoUtilsTest
+    : public testing::TestWithParam<CreateTestKeyPairFunction*> {
+ protected:
+  void SetUp() override {
+    ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(auto keys_pair, (*GetParam())());
+    public_key_ = std::move(keys_pair.first);
+    ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(rsa_modulus_,
+                                     StringToBignum(keys_pair.second.n()));
+    ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(rsa_e_,
+                                     StringToBignum(keys_pair.second.e()));
+    ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(rsa_p_,
+                                     StringToBignum(keys_pair.second.p()));
+    ANON_TOKENS_QUICHE_EXPECT_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_QUICHE_EXPECT_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_QUICHE_EXPECT_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_QUICHE_EXPECT_OK_AND_ASSIGN(
+      bssl::UniquePtr<BIGNUM> exp1,
+      PublicMetadataExponent(*rsa_modulus_.get(), metadata1));
+  ANON_TOKENS_QUICHE_EXPECT_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_QUICHE_EXPECT_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_QUICHE_EXPECT_OK_AND_ASSIGN(
+      bssl::UniquePtr<BIGNUM> final_exponent,
+      ComputeFinalExponentUnderPublicMetadata(*rsa_modulus_.get(),
+                                              *rsa_e_.get(), metadata));
+  ANON_TOKENS_QUICHE_EXPECT_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_QUICHE_EXPECT_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_QUICHE_EXPECT_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_QUICHE_EXPECT_OK_AND_ASSIGN(
+      bssl::UniquePtr<BIGNUM> public_exp_1,
+      ComputeFinalExponentUnderPublicMetadata(*rsa_modulus_.get(),
+                                              *rsa_e_.get(), metadata));
+  ANON_TOKENS_QUICHE_EXPECT_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_QUICHE_EXPECT_OK_AND_ASSIGN(
+      bssl::UniquePtr<BIGNUM> public_exp_1,
+      ComputeFinalExponentUnderPublicMetadata(*rsa_modulus_.get(),
+                                              *rsa_e_.get(), metadata_1));
+  ANON_TOKENS_QUICHE_EXPECT_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_QUICHE_EXPECT_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
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.cc
index e543759..f6f70e0 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.cc
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.cc
@@ -69,9 +69,11 @@
     absl::string_view public_metadata, absl::string_view rsa_modulus_str,
     size_t out_len_bytes) {
   const EVP_MD* evp_md_sha_384 = EVP_sha384();
+  // Prepend "key" to input.
+  std::string modified_input = absl::StrCat("key", public_metadata);
+  std::vector<uint8_t> input_buffer(modified_input.begin(),
+                                    modified_input.end());
   // Append 0x00 to input.
-  std::vector<uint8_t> input_buffer(public_metadata.begin(),
-                                    public_metadata.end());
   input_buffer.push_back(0x00);
   std::string out_e;
   // We set the out_e size beyond out_len_bytes so that out_e bytes are
@@ -284,6 +286,29 @@
   return std::move(rsa_private_key);
 }
 
+absl::StatusOr<bssl::UniquePtr<RSA>> AnonymousTokensRSAPublicKeyToRSA(
+    const RSAPublicKey& public_key) {
+  ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_modulus,
+                               StringToBignum(public_key.n()));
+  ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_e,
+                               StringToBignum(public_key.e()));
+  // Convert to OpenSSL RSA.
+  bssl::UniquePtr<RSA> rsa_public_key(RSA_new());
+  if (!rsa_public_key.get()) {
+    return absl::InternalError(
+        absl::StrCat("RSA_new failed: ", GetSslErrors()));
+  } else if (RSA_set0_key(rsa_public_key.get(), rsa_modulus.get(), rsa_e.get(),
+                          nullptr) != kBsslSuccess) {
+    return absl::InternalError(
+        absl::StrCat("RSA_set0_key failed: ", GetSslErrors()));
+  }
+  // RSA_set0_key takes ownership of the pointers under rsa_modulus, new_e on
+  // success.
+  rsa_modulus.release();
+  rsa_e.release();
+  return rsa_public_key;
+}
+
 absl::StatusOr<bssl::UniquePtr<BIGNUM>> ComputeCarmichaelLcm(
     const BIGNUM& phi_p, const BIGNUM& phi_q, BN_CTX& bn_ctx) {
   // To compute lcm(phi(p), phi(q)), we first compute phi(n) =
@@ -356,47 +381,12 @@
   ANON_TOKENS_ASSIGN_OR_RETURN(BnCtxPtr bn_ctx, GetAndStartBigNumCtx());
   // new_e=e*md_exp
   ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> new_e, NewBigNum());
-  if (BN_mul(new_e.get(), md_exp.get(), &e, bn_ctx.get()) != 1) {
+  if (BN_mul(new_e.get(), md_exp.get(), &e, bn_ctx.get()) != kBsslSuccess) {
     return absl::InternalError(
         absl::StrCat("Unable to multiply e with md_exp: ", GetSslErrors()));
   }
   return new_e;
 }
 
-// TODO(b/259581423) Remove RSAPublicKeyToRSAUnderPublicMetadata as we should
-// not put public exponent values in borignssl RSA struct other than the
-// standard public exponent values.
-absl::StatusOr<bssl::UniquePtr<RSA>> RSAPublicKeyToRSAUnderPublicMetadata(
-    const RSAPublicKey& public_key, absl::string_view public_metadata) {
-  ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_modulus,
-                               StringToBignum(public_key.n()));
-  ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> old_e,
-                               StringToBignum(public_key.e()));
-  bssl::UniquePtr<BIGNUM> new_e;
-  if (!public_metadata.empty()) {
-    // Final exponent under Public metadata
-    ANON_TOKENS_ASSIGN_OR_RETURN(
-        new_e, ComputeFinalExponentUnderPublicMetadata(
-                   *rsa_modulus.get(), *old_e.get(), public_metadata));
-  } else {
-    new_e = std::move(old_e);
-  }
-  // Convert to OpenSSL RSA.
-  bssl::UniquePtr<RSA> rsa_public_key(RSA_new());
-  if (!rsa_public_key.get()) {
-    return absl::InternalError(
-        absl::StrCat("RSA_new failed: ", GetSslErrors()));
-  } else if (RSA_set0_key(rsa_public_key.get(), rsa_modulus.get(), new_e.get(),
-                          nullptr) != kBsslSuccess) {
-    return absl::InternalError(
-        absl::StrCat("RSA_set0_key failed: ", GetSslErrors()));
-  }
-  // RSA_set0_key takes ownership of the pointers under rsa_modulus, new_e on
-  // success.
-  rsa_modulus.release();
-  new_e.release();
-  return rsa_public_key;
-}
-
 }  // namespace anonymous_tokens
 }  // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h
index 9f6e301..a776e59 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h
@@ -39,6 +39,9 @@
 // input and the rsa modulus as salt. The expected output hash size is passed as
 // out_len_bytes.
 //
+// Implementation follows the steps listed in
+// https://datatracker.ietf.org/doc/draft-amjad-cfrg-partially-blind-rsa/
+//
 // This method internally calls HKDF with output size of more than
 // out_len_bytes and later truncates the output to out_len_bytes. This is done
 // so that the output is indifferentiable from truly random bytes.
@@ -106,7 +109,7 @@
 absl::StatusOr<std::string> QUICHE_EXPORT ComputeHash(
     absl::string_view input, const EVP_MD& hasher);
 
-// Computes the Carmichael LCM given phi(p) and phi(q) where N = pq is a safe
+// Computes the Carmichael LCM given phi(p) and phi(q) where N = p*q is a safe
 // RSA modulus.
 absl::StatusOr<bssl::UniquePtr<BIGNUM>> QUICHE_EXPORT
 ComputeCarmichaelLcm(const BIGNUM& phi_p, const BIGNUM& phi_q, BN_CTX& bn_ctx);
@@ -116,6 +119,11 @@
 absl::StatusOr<bssl::UniquePtr<RSA>> QUICHE_EXPORT
 AnonymousTokensRSAPrivateKeyToRSA(const RSAPrivateKey& private_key);
 
+// Converts AnonymousTokens::RSAPublicKey to bssl::UniquePtr<RSA> without
+// public metadata augmentation.
+absl::StatusOr<bssl::UniquePtr<RSA>> QUICHE_EXPORT
+AnonymousTokensRSAPublicKeyToRSA(const RSAPublicKey& public_key);
+
 // Compute exponent based only on the public metadata. Assumes that n is a safe
 // modulus i.e. it produces a strong RSA key pair. If not, the exponent may be
 // invalid.
@@ -125,21 +133,13 @@
 // Computes final exponent by multiplying the public exponent e with the
 // exponent derived from public metadata. Assumes that n is a safe modulus i.e.
 // it produces a strong RSA key pair. If not, the exponent may be invalid.
+//
+// Empty public metadata is considered to be a valid value for public_metadata
+// and will output an exponent different than `e` as well.
 absl::StatusOr<bssl::UniquePtr<BIGNUM>> QUICHE_EXPORT
 ComputeFinalExponentUnderPublicMetadata(const BIGNUM& n, const BIGNUM& e,
                                         absl::string_view public_metadata);
 
-// Converts AnonymousTokens RSAPublicKey to RSA under a fixed public_metadata.
-//
-// If the public_metadata is empty, this method doesn't modify the public
-// exponent but instead simply outputs the RSA for the unmodified RSAPublicKey.
-//
-// TODO(b/271441409): Stop using RSA object from boringssl in
-// AnonymousTokensService. Replace with a new internal struct.
-absl::StatusOr<bssl::UniquePtr<RSA>> QUICHE_EXPORT
-RSAPublicKeyToRSAUnderPublicMetadata(const RSAPublicKey& public_key,
-                                     absl::string_view public_metadata);
-
 }  // namespace anonymous_tokens
 }  // namespace private_membership
 
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer_test.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer_test.cc
index d3040ee..a15fa30 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer_test.cc
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer_test.cc
@@ -79,7 +79,7 @@
                                    signer->Sign(encoded_message));
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
       const auto verifier,
-      RsaSsaPssVerifier::New(public_key_, sig_hash_, mgf1_hash_, salt_length_));
+      RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_));
   QUICHE_EXPECT_OK(verifier->Verify(potentially_insecure_signature, message));
 }
 
@@ -98,7 +98,7 @@
                                    signer->Sign(message2));
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
       const auto verifier,
-      RsaSsaPssVerifier::New(public_key_, sig_hash_, mgf1_hash_, salt_length_));
+      RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_, public_key_));
   EXPECT_THAT(
       verifier->Verify(insecure_sig, message2),
       quiche::test::StatusIs(absl::StatusCode::kInvalidArgument,
@@ -149,8 +149,8 @@
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(std::string potentially_insecure_signature,
                                    signer->Sign(encoded_message));
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      auto verifier, RsaSsaPssVerifier::New(public_key_, sig_hash_, mgf1_hash_,
-                                            salt_length_, public_metadata));
+      auto verifier, RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_,
+                                            public_key_, public_metadata));
   QUICHE_EXPECT_OK(verifier->Verify(potentially_insecure_signature, message));
 }
 
@@ -169,8 +169,8 @@
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(std::string potentially_insecure_signature,
                                    signer->Sign(encoded_message));
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      auto verifier, RsaSsaPssVerifier::New(public_key_, sig_hash_, mgf1_hash_,
-                                            salt_length_, public_metadata_2));
+      auto verifier, RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_,
+                                            public_key_, public_metadata_2));
   EXPECT_THAT(
       verifier->Verify(potentially_insecure_signature, message),
       quiche::test::StatusIs(absl::StatusCode::kInvalidArgument,
@@ -192,8 +192,8 @@
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(std::string potentially_insecure_signature,
                                    signer->Sign(encoded_message));
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      auto verifier, RsaSsaPssVerifier::New(public_key_, sig_hash_, mgf1_hash_,
-                                            salt_length_, public_metadata_2));
+      auto verifier, RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_,
+                                            public_key_, public_metadata_2));
   EXPECT_THAT(
       verifier->Verify(potentially_insecure_signature, message),
       quiche::test::StatusIs(absl::StatusCode::kInvalidArgument,
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.cc
index 385ab05..1c04b58 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.cc
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.cc
@@ -39,13 +39,30 @@
     return absl::InvalidArgumentError("Public key is malformed.");
   }
 
-  // Convert to OpenSSL RSA.
+  // Convert to OpenSSL RSA which will be used in the code paths for the
+  // standard RSA blind signature scheme.
   //
-  // If public metadata is empty, RSAPublicKeyToRSAUnderPublicMetadata returns
-  // bssl::UniquePtr<RSA> valid for no public metadata.
-  ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<RSA> rsa_public_key,
-                               RSAPublicKeyToRSAUnderPublicMetadata(
-                                   rsa_public_key_proto, public_metadata));
+  // Moreover, it will also be passed as an argument to PSS related padding and
+  // padding verification methods irrespective of whether RsaBlinder is being
+  // used as a part of the standard RSA blind signature scheme or the scheme
+  // with public metadata support.
+  ANON_TOKENS_ASSIGN_OR_RETURN(
+      bssl::UniquePtr<RSA> rsa_public_key,
+      AnonymousTokensRSAPublicKeyToRSA(rsa_public_key_proto));
+  ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_modulus,
+                               StringToBignum(rsa_public_key_proto.n()));
+  ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_e,
+                               StringToBignum(rsa_public_key_proto.e()));
+
+  bssl::UniquePtr<BIGNUM> augmented_rsa_e = nullptr;
+  // Currently if public metadata is not empty, RsaBlinder will compute a
+  // modified public exponent.
+  if (!public_metadata.empty()) {
+    ANON_TOKENS_ASSIGN_OR_RETURN(
+        augmented_rsa_e,
+        ComputeFinalExponentUnderPublicMetadata(*rsa_modulus.get(),
+                                                *rsa_e.get(), public_metadata));
+  }
 
   // Owned by BoringSSL.
   const EVP_MD* sig_hash;
@@ -72,8 +89,7 @@
 
   // Limit r between [2, n) so that an r of 1 never happens. An r of 1 doesn't
   // blind.
-  if (BN_rand_range_ex(r.get(), 2, RSA_get0_n(rsa_public_key.get())) !=
-      kBsslSuccess) {
+  if (BN_rand_range_ex(r.get(), 2, rsa_modulus.get()) != kBsslSuccess) {
     return absl::InternalError(
         "BN_rand_range_ex failed when called from RsaBlinder::New.");
   }
@@ -83,8 +99,8 @@
     return absl::InternalError("BN_CTX_new failed.");
   }
 
-  bssl::UniquePtr<BN_MONT_CTX> bn_mont_ctx(BN_MONT_CTX_new_for_modulus(
-      RSA_get0_n(rsa_public_key.get()), bn_ctx.get()));
+  bssl::UniquePtr<BN_MONT_CTX> bn_mont_ctx(
+      BN_MONT_CTX_new_for_modulus(rsa_modulus.get(), bn_ctx.get()));
   if (!bn_mont_ctx) {
     return absl::InternalError("BN_MONT_CTX_new_for_modulus failed.");
   }
@@ -106,25 +122,25 @@
   }
 
   return absl::WrapUnique(new RsaBlinder(
-      std::move(r), std::move(r_inv_mont), std::move(rsa_public_key),
-      std::move(bn_mont_ctx), sig_hash, mgf1_hash, public_key.salt_length(),
-      public_metadata));
+      public_key.salt_length(), sig_hash, mgf1_hash, std::move(rsa_public_key),
+      std::move(rsa_modulus), std::move(augmented_rsa_e), std::move(r),
+      std::move(r_inv_mont), std::move(bn_mont_ctx)));
 }
 
-RsaBlinder::RsaBlinder(bssl::UniquePtr<BIGNUM> r,
-                       bssl::UniquePtr<BIGNUM> r_inv_mont,
-                       bssl::UniquePtr<RSA> public_key,
-                       bssl::UniquePtr<BN_MONT_CTX> mont_n,
-                       const EVP_MD* sig_hash, const EVP_MD* mgf1_hash,
-                       int32_t salt_length, absl::string_view public_metadata)
-    : r_(std::move(r)),
-      r_inv_mont_(std::move(r_inv_mont)),
-      public_key_(std::move(public_key)),
-      mont_n_(std::move(mont_n)),
+RsaBlinder::RsaBlinder(
+    int salt_length, const EVP_MD* sig_hash, const EVP_MD* mgf1_hash,
+    bssl::UniquePtr<RSA> rsa_public_key, bssl::UniquePtr<BIGNUM> rsa_modulus,
+    bssl::UniquePtr<BIGNUM> augmented_rsa_e, bssl::UniquePtr<BIGNUM> r,
+    bssl::UniquePtr<BIGNUM> r_inv_mont, bssl::UniquePtr<BN_MONT_CTX> mont_n)
+    : salt_length_(salt_length),
       sig_hash_(sig_hash),
       mgf1_hash_(mgf1_hash),
-      salt_length_(salt_length),
-      public_metadata_(public_metadata),
+      rsa_public_key_(std::move(rsa_public_key)),
+      rsa_modulus_(std::move(rsa_modulus)),
+      augmented_rsa_e_(std::move(augmented_rsa_e)),
+      r_(std::move(r)),
+      r_inv_mont_(std::move(r_inv_mont)),
+      mont_n_(std::move(mont_n)),
       message_(""),
       blinder_state_(RsaBlinder::BlinderState::kCreated) {}
 
@@ -150,7 +166,7 @@
   }
 
   // Allocate for padded length
-  const int padded_len = RSA_size(public_key_.get());
+  const int padded_len = BN_num_bytes(rsa_modulus_.get());
   std::vector<uint8_t> padded(padded_len);
 
   // The |md| and |mgf1_md| arguments identify the hash used to calculate
@@ -159,7 +175,7 @@
   // is -1, then the salt length is the same as the hash length. If -2, then the
   // salt length is maximal given the size of |rsa|. If unsure, use -1.
   if (RSA_padding_add_PKCS1_PSS_mgf1(
-          /*rsa=*/public_key_.get(), /*EM=*/padded.data(),
+          /*rsa=*/rsa_public_key_.get(), /*EM=*/padded.data(),
           /*mHash=*/digest.data(), /*Hash=*/sig_hash_, /*mgf1Hash=*/mgf1_hash_,
           /*sLen=*/salt_length_) != kBsslSuccess) {
     return absl::InternalError(
@@ -179,11 +195,22 @@
   // Take `r^e mod n`. This is an equivalent operation to RSA_encrypt, without
   // extra encode/decode trips.
   ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rE, NewBigNum());
-  if (BN_mod_exp_mont(rE.get(), r_.get(), RSA_get0_e(public_key_.get()),
-                      RSA_get0_n(public_key_.get()), bn_ctx.get(),
-                      mont_n_.get()) != kBsslSuccess) {
-    return absl::InternalError(
-        "BN_mod_exp_mont failed when called from RsaBlinder::Blind.");
+  // TODO(b/259581423) When public metadata is not enabled, put standard rsa
+  // public exponent in augmented_rsa_e_ to avoid branching here.
+  if (augmented_rsa_e_) {
+    if (BN_mod_exp_mont(rE.get(), r_.get(), augmented_rsa_e_.get(),
+                        rsa_modulus_.get(), bn_ctx.get(),
+                        mont_n_.get()) != kBsslSuccess) {
+      return absl::InternalError(
+          "BN_mod_exp_mont failed when called from RsaBlinder::Blind.");
+    }
+  } else {
+    if (BN_mod_exp_mont(rE.get(), r_.get(), RSA_get0_e(rsa_public_key_.get()),
+                        rsa_modulus_.get(), bn_ctx.get(),
+                        mont_n_.get()) != kBsslSuccess) {
+      return absl::InternalError(
+          "BN_mod_exp_mont failed when called from RsaBlinder::Blind.");
+    }
   }
 
   // Do `encoded_message*r^e mod n`.
@@ -208,8 +235,8 @@
         "BN_mod_mul failed when called from RsaBlinder::Blind.");
   }
 
-  absl::StatusOr<std::string> blinded_msg = BignumToString(
-      *multiplication_res, BN_num_bytes(RSA_get0_n(public_key_.get())));
+  absl::StatusOr<std::string> blinded_msg =
+      BignumToString(*multiplication_res, BN_num_bytes(rsa_modulus_.get()));
 
   // Update RsaBlinder state to kBlinded
   blinder_state_ = RsaBlinder::BlinderState::kBlinded;
@@ -224,7 +251,7 @@
     return absl::FailedPreconditionError(
         "RsaBlinder is in wrong state to unblind signature.");
   }
-  const size_t mod_size = RSA_size(public_key_.get());
+  const int mod_size = BN_num_bytes(rsa_modulus_.get());
   // Parse the signed_blinded_data as BIGNUM.
   if (blind_signature.size() != mod_size) {
     return absl::InternalError(absl::StrCat(
@@ -254,9 +281,9 @@
     return absl::InternalError(
         "BN_mod_mul failed when called from RsaBlinder::Unblind.");
   }
-  absl::StatusOr<std::string> unblinded_signed_message = BignumToString(
-      *unblinded_sig_big,
-      /*output_len=*/BN_num_bytes(RSA_get0_n(public_key_.get())));
+  absl::StatusOr<std::string> unblinded_signed_message =
+      BignumToString(*unblinded_sig_big,
+                     /*output_len=*/BN_num_bytes(rsa_modulus_.get()));
   blinder_state_ = RsaBlinder::BlinderState::kUnblinded;
   return unblinded_signed_message;
 }
@@ -269,63 +296,62 @@
   ANON_TOKENS_ASSIGN_OR_RETURN(std::string message_digest,
                                ComputeHash(message, *sig_hash_));
 
-  const size_t kHashSize = EVP_MD_size(sig_hash_);
+  const int hash_size = EVP_MD_size(sig_hash_);
   // Make sure the size of the digest is correct.
-  if (message_digest.size() != kHashSize) {
+  if (message_digest.size() != hash_size) {
     return absl::InvalidArgumentError(
         absl::StrCat("Size of the digest doesn't match the one "
                      "of the hashing algorithm; expected ",
-                     kHashSize, " got ", message_digest.size()));
+                     hash_size, " got ", message_digest.size()));
   }
-  const int kRsaModulusSize = RSA_size(public_key_.get());
-  if (signature.size() != kRsaModulusSize) {
+  const int rsa_modulus_size = BN_num_bytes(rsa_modulus_.get());
+  if (signature.size() != rsa_modulus_size) {
     return absl::InvalidArgumentError(
         "Signature size not equal to modulus size.");
   }
 
-  std::string recovered_message_digest(kRsaModulusSize, 0);
-  if (public_metadata_.empty()) {
+  std::string recovered_message_digest(rsa_modulus_size, 0);
+  if (augmented_rsa_e_ == nullptr) {
     int recovered_message_digest_size = RSA_public_decrypt(
         /*flen=*/signature.size(),
         /*from=*/reinterpret_cast<const uint8_t*>(signature.data()),
         /*to=*/
         reinterpret_cast<uint8_t*>(recovered_message_digest.data()),
-        /*rsa=*/public_key_.get(),
+        /*rsa=*/rsa_public_key_.get(),
         /*padding=*/RSA_NO_PADDING);
-    if (recovered_message_digest_size != kRsaModulusSize) {
+    if (recovered_message_digest_size != rsa_modulus_size) {
       return absl::InvalidArgumentError(
           absl::StrCat("Invalid signature size (likely an incorrect key is "
                        "used); expected ",
-                       kRsaModulusSize, " got ", recovered_message_digest_size,
+                       rsa_modulus_size, " got ", recovered_message_digest_size,
                        ": ", GetSslErrors()));
     }
   } else {
     ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> signature_bn,
                                  StringToBignum(signature));
-    if (BN_ucmp(signature_bn.get(), RSA_get0_n(public_key_.get())) >= 0) {
+    if (BN_ucmp(signature_bn.get(), rsa_modulus_.get()) >= 0) {
       return absl::InvalidArgumentError("Data too large for modulus.");
     }
     ANON_TOKENS_ASSIGN_OR_RETURN(BnCtxPtr bn_ctx, GetAndStartBigNumCtx());
-    bssl::UniquePtr<BN_MONT_CTX> bn_mont_ctx(BN_MONT_CTX_new_for_modulus(
-        RSA_get0_n(public_key_.get()), bn_ctx.get()));
+    bssl::UniquePtr<BN_MONT_CTX> bn_mont_ctx(
+        BN_MONT_CTX_new_for_modulus(rsa_modulus_.get(), bn_ctx.get()));
     if (!bn_mont_ctx) {
       return absl::InternalError("BN_MONT_CTX_new_for_modulus failed.");
     }
     ANON_TOKENS_ASSIGN_OR_RETURN(
         bssl::UniquePtr<BIGNUM> recovered_message_digest_bn, NewBigNum());
     if (BN_mod_exp_mont(recovered_message_digest_bn.get(), signature_bn.get(),
-                        RSA_get0_e(public_key_.get()),
-                        RSA_get0_n(public_key_.get()), bn_ctx.get(),
-                        bn_mont_ctx.get()) != kBsslSuccess) {
+                        augmented_rsa_e_.get(), rsa_modulus_.get(),
+                        bn_ctx.get(), bn_mont_ctx.get()) != kBsslSuccess) {
       return absl::InternalError("Exponentiation failed.");
     }
     ANON_TOKENS_ASSIGN_OR_RETURN(
         recovered_message_digest,
-        BignumToString(*recovered_message_digest_bn, kRsaModulusSize));
+        BignumToString(*recovered_message_digest_bn, rsa_modulus_size));
   }
 
   if (RSA_verify_PKCS1_PSS_mgf1(
-          public_key_.get(),
+          rsa_public_key_.get(),
           reinterpret_cast<const uint8_t*>(&message_digest[0]), sig_hash_,
           mgf1_hash_,
           reinterpret_cast<const uint8_t*>(&recovered_message_digest[0]),
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.h
index 4ba9c07..1dd77e6 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.h
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.h
@@ -55,21 +55,28 @@
 
  private:
   // Use `New` to construct
-  RsaBlinder(bssl::UniquePtr<BIGNUM> r, bssl::UniquePtr<BIGNUM> r_inv_mont,
-             bssl::UniquePtr<RSA> public_key,
-             bssl::UniquePtr<BN_MONT_CTX> mont_n, const EVP_MD* sig_hash_,
-             const EVP_MD* mgf1_hash_, int32_t salt_length_,
-             absl::string_view public_metadata);
+  RsaBlinder(int salt_length, const EVP_MD* sig_hash, const EVP_MD* mgf1_hash,
+             bssl::UniquePtr<RSA> rsa_public_key,
+             bssl::UniquePtr<BIGNUM> rsa_modulus,
+             bssl::UniquePtr<BIGNUM> augmented_rsa_e, bssl::UniquePtr<BIGNUM> r,
+             bssl::UniquePtr<BIGNUM> r_inv_mont,
+             bssl::UniquePtr<BN_MONT_CTX> mont_n);
+
+  const int salt_length_;
+  const EVP_MD* sig_hash_;   // Owned by BoringSSL.
+  const EVP_MD* mgf1_hash_;  // Owned by BoringSSL.
+
+  const bssl::UniquePtr<RSA> rsa_public_key_;
+  // Storing RSA modulus separately for helping with BN computations.
+  const bssl::UniquePtr<BIGNUM> rsa_modulus_;
+  // If public metadata is not supported, augmented_rsa_e_ will be a null
+  // pointer.
+  const bssl::UniquePtr<BIGNUM> augmented_rsa_e_;
 
   const bssl::UniquePtr<BIGNUM> r_;
   // r^-1 mod n in the Montgomery domain
   const bssl::UniquePtr<BIGNUM> r_inv_mont_;
-  const bssl::UniquePtr<RSA> public_key_;
   const bssl::UniquePtr<BN_MONT_CTX> mont_n_;
-  const EVP_MD* sig_hash_;   // Owned by BoringSSL.
-  const EVP_MD* mgf1_hash_;  // Owned by BoringSSL.
-  const int32_t salt_length_;
-  const absl::string_view public_metadata_;
 
   std::string message_;
   BlinderState blinder_state_;
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.cc
index aee8f15..be6dba4 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.cc
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.cc
@@ -29,32 +29,54 @@
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h"
+#include "openssl/bn.h"
 #include "openssl/rsa.h"
 
 namespace private_membership {
 namespace anonymous_tokens {
 
 absl::StatusOr<std::unique_ptr<RsaSsaPssVerifier>> RsaSsaPssVerifier::New(
-    const RSAPublicKey& rsa_public_key, const EVP_MD* sig_hash,
-    const EVP_MD* mgf1_hash, const int salt_length,
-    absl::string_view public_metadata) {
-  ANON_TOKENS_ASSIGN_OR_RETURN(
-      bssl::UniquePtr<RSA> rsa,
-      RSAPublicKeyToRSAUnderPublicMetadata(rsa_public_key, public_metadata));
+    const int salt_length, const EVP_MD* sig_hash, const EVP_MD* mgf1_hash,
+    const RSAPublicKey& public_key, absl::string_view public_metadata) {
+  // Convert to OpenSSL RSA which will be used in the code paths for the
+  // standard RSA blind signature scheme.
+  //
+  // Moreover, it will also be passed as an argument to PSS related padding
+  // verification methods irrespective of whether RsaBlinder is being used as a
+  // part of the standard RSA blind signature scheme or the scheme with public
+  // metadata support.
+  ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<RSA> rsa_public_key,
+                               AnonymousTokensRSAPublicKeyToRSA(public_key));
+  ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_modulus,
+                               StringToBignum(public_key.n()));
+  ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> rsa_e,
+                               StringToBignum(public_key.e()));
+
+  bssl::UniquePtr<BIGNUM> augemented_rsa_e = nullptr;
+  // Currently if public metadata is not empty, RsaBlinder will compute a
+  // modified public exponent.
+  if (!public_metadata.empty()) {
+    ANON_TOKENS_ASSIGN_OR_RETURN(
+        augemented_rsa_e,
+        ComputeFinalExponentUnderPublicMetadata(*rsa_modulus.get(),
+                                                *rsa_e.get(), public_metadata));
+  }
   return absl::WrapUnique(new RsaSsaPssVerifier(
-      std::move(rsa), sig_hash, mgf1_hash, salt_length, public_metadata));
+      salt_length, sig_hash, mgf1_hash, std::move(rsa_public_key),
+      std::move(rsa_modulus), std::move(augemented_rsa_e)));
 }
 
-RsaSsaPssVerifier::RsaSsaPssVerifier(bssl::UniquePtr<RSA> public_key,
-                                     const EVP_MD* sig_hash,
+RsaSsaPssVerifier::RsaSsaPssVerifier(int salt_length, const EVP_MD* sig_hash,
                                      const EVP_MD* mgf1_hash,
-                                     int32_t salt_length,
-                                     absl::string_view public_metadata)
-    : public_key_(std::move(public_key)),
+                                     bssl::UniquePtr<RSA> rsa_public_key,
+                                     bssl::UniquePtr<BIGNUM> rsa_modulus,
+                                     bssl::UniquePtr<BIGNUM> augmented_rsa_e)
+    : salt_length_(salt_length),
       sig_hash_(sig_hash),
       mgf1_hash_(mgf1_hash),
-      salt_length_(salt_length),
-      public_metadata_(public_metadata) {}
+      rsa_public_key_(std::move(rsa_public_key)),
+      rsa_modulus_(std::move(rsa_modulus)),
+      augmented_rsa_e_(std::move(augmented_rsa_e)) {}
 
 absl::Status RsaSsaPssVerifier::Verify(absl::string_view unblind_token,
                                        absl::string_view message) {
@@ -64,61 +86,61 @@
 
   ANON_TOKENS_ASSIGN_OR_RETURN(std::string message_digest,
                                ComputeHash(message, *sig_hash_));
-  const int kHashSize = EVP_MD_size(sig_hash_);
+  const int hash_size = EVP_MD_size(sig_hash_);
   // Make sure the size of the digest is correct.
-  if (message_digest.size() != kHashSize) {
+  if (message_digest.size() != hash_size) {
     return absl::InvalidArgumentError(
         absl::StrCat("Size of the digest doesn't match the one "
                      "of the hashing algorithm; expected ",
-                     kHashSize, " got ", message_digest.size()));
+                     hash_size, " got ", message_digest.size()));
   }
-  const int kRsaModulusSize = RSA_size(public_key_.get());
-  if (unblind_token.size() != kRsaModulusSize) {
+  const int rsa_modulus_size = BN_num_bytes(rsa_modulus_.get());
+  if (unblind_token.size() != rsa_modulus_size) {
     return absl::InternalError("Signature size not equal to modulus size.");
   }
 
-  std::string recovered_message_digest(kRsaModulusSize, 0);
-  if (public_metadata_.empty()) {
+  std::string recovered_message_digest(rsa_modulus_size, 0);
+  if (augmented_rsa_e_ == nullptr) {
     int recovered_message_digest_size = RSA_public_decrypt(
         /*flen=*/unblind_token.size(),
         /*from=*/reinterpret_cast<const uint8_t*>(unblind_token.data()),
         /*to=*/
         reinterpret_cast<uint8_t*>(recovered_message_digest.data()),
-        /*rsa=*/public_key_.get(),
+        /*rsa=*/rsa_public_key_.get(),
         /*padding=*/RSA_NO_PADDING);
-    if (recovered_message_digest_size != kRsaModulusSize) {
+    if (recovered_message_digest_size != rsa_modulus_size) {
       return absl::InvalidArgumentError(
           absl::StrCat("Invalid signature size (likely an incorrect key is "
                        "used); expected ",
-                       kRsaModulusSize, " got ", recovered_message_digest_size,
+                       rsa_modulus_size, " got ", recovered_message_digest_size,
                        ": ", GetSslErrors()));
     }
   } else {
     ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> unblind_token_bn,
                                  StringToBignum(unblind_token));
-    if (BN_ucmp(unblind_token_bn.get(), RSA_get0_n(public_key_.get())) >= 0) {
+    if (BN_ucmp(unblind_token_bn.get(), rsa_modulus_.get()) >= 0) {
       return absl::InternalError("Data too large for modulus.");
     }
     ANON_TOKENS_ASSIGN_OR_RETURN(BnCtxPtr bn_ctx, GetAndStartBigNumCtx());
-    bssl::UniquePtr<BN_MONT_CTX> bn_mont_ctx(BN_MONT_CTX_new_for_modulus(
-        RSA_get0_n(public_key_.get()), bn_ctx.get()));
+    bssl::UniquePtr<BN_MONT_CTX> bn_mont_ctx(
+        BN_MONT_CTX_new_for_modulus(rsa_modulus_.get(), bn_ctx.get()));
     if (!bn_mont_ctx) {
       return absl::InternalError("BN_MONT_CTX_new_for_modulus failed.");
     }
     ANON_TOKENS_ASSIGN_OR_RETURN(
         bssl::UniquePtr<BIGNUM> recovered_message_digest_bn, NewBigNum());
     if (BN_mod_exp_mont(recovered_message_digest_bn.get(),
-                        unblind_token_bn.get(), RSA_get0_e(public_key_.get()),
-                        RSA_get0_n(public_key_.get()), bn_ctx.get(),
+                        unblind_token_bn.get(), augmented_rsa_e_.get(),
+                        rsa_modulus_.get(), bn_ctx.get(),
                         bn_mont_ctx.get()) != kBsslSuccess) {
       return absl::InternalError("Exponentiation failed.");
     }
     ANON_TOKENS_ASSIGN_OR_RETURN(
         recovered_message_digest,
-        BignumToString(*recovered_message_digest_bn, kRsaModulusSize));
+        BignumToString(*recovered_message_digest_bn, rsa_modulus_size));
   }
   if (RSA_verify_PKCS1_PSS_mgf1(
-          public_key_.get(),
+          rsa_public_key_.get(),
           reinterpret_cast<const uint8_t*>(&message_digest[0]), sig_hash_,
           mgf1_hash_,
           reinterpret_cast<const uint8_t*>(recovered_message_digest.data()),
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.h
index 1bd3739..34ab1e3 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.h
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier.h
@@ -34,10 +34,12 @@
 // inputted message using a public key and other input parameters.
 class QUICHE_EXPORT RsaSsaPssVerifier : public Verifier {
  public:
+  // TODO(b/259581423) Change absl::string_view public_metadata to
+  // std::optional<absl::string_view> public_metadata to help determine whether
+  // public metadata is supported.
   static absl::StatusOr<std::unique_ptr<RsaSsaPssVerifier>> New(
-      const RSAPublicKey& rsa_public_key, const EVP_MD* sig_hash,
-      const EVP_MD* mgf1_hash, int salt_length,
-      absl::string_view public_metadata = "");
+      int salt_length, const EVP_MD* sig_hash, const EVP_MD* mgf1_hash,
+      const RSAPublicKey& public_key, absl::string_view public_metadata = "");
 
   // Verifies the signature.
   //
@@ -47,15 +49,22 @@
 
  private:
   // Use `New` to construct
-  RsaSsaPssVerifier(bssl::UniquePtr<RSA> public_key, const EVP_MD* sig_hash,
-                    const EVP_MD* mgf1_hash, int32_t salt_length,
-                    absl::string_view public_metadata);
+  RsaSsaPssVerifier(int salt_length, const EVP_MD* sig_hash,
+                    const EVP_MD* mgf1_hash,
+                    bssl::UniquePtr<RSA> rsa_public_key,
+                    bssl::UniquePtr<BIGNUM> rsa_modulus,
+                    bssl::UniquePtr<BIGNUM> augmented_rsa_e);
 
-  const bssl::UniquePtr<RSA> public_key_;
+  const int salt_length_;
   const EVP_MD* sig_hash_;   // Owned by BoringSSL.
   const EVP_MD* mgf1_hash_;  // Owned by BoringSSL.
-  const int32_t salt_length_;
-  const absl::string_view public_metadata_;
+
+  const bssl::UniquePtr<RSA> rsa_public_key_;
+  // Storing RSA modulus separately for helping with BN computations.
+  const bssl::UniquePtr<BIGNUM> rsa_modulus_;
+  // If public metadata is not supported, modified_rsa_e_ will be a null
+  // pointer.
+  const bssl::UniquePtr<BIGNUM> augmented_rsa_e_;
 };
 
 }  // namespace anonymous_tokens
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier_test.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier_test.cc
index d897c9e..59d9722 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier_test.cc
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_ssa_pss_verifier_test.cc
@@ -44,8 +44,8 @@
   const EVP_MD *mgf1_hash = EVP_sha384();  // Owned by BoringSSL
   const int salt_length = kSaltLengthInBytes48;
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      const auto verifier, RsaSsaPssVerifier::New(test_keys.first, sig_hash,
-                                                  mgf1_hash, salt_length));
+      const auto verifier, RsaSsaPssVerifier::New(salt_length, sig_hash,
+                                                  mgf1_hash, test_keys.first));
   QUICHE_EXPECT_OK(verifier->Verify(test_vec.signature, test_vec.message));
 }
 
@@ -58,8 +58,8 @@
   const EVP_MD *mgf1_hash = EVP_sha384();  // Owned by BoringSSL
   const int salt_length = kSaltLengthInBytes48;
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      const auto verifier, RsaSsaPssVerifier::New(test_keys.first, sig_hash,
-                                                  mgf1_hash, salt_length));
+      const auto verifier, RsaSsaPssVerifier::New(salt_length, sig_hash,
+                                                  mgf1_hash, test_keys.first));
   // corrupt signature
   std::string wrong_sig = test_vec.signature;
   wrong_sig.replace(10, 1, "x");
@@ -79,8 +79,9 @@
   // wrong key
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(auto new_keys_pair, GetStandardRsaKeyPair());
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      const auto verifier, RsaSsaPssVerifier::New(new_keys_pair.first, sig_hash,
-                                                  mgf1_hash, salt_length));
+      const auto verifier,
+      RsaSsaPssVerifier::New(salt_length, sig_hash, mgf1_hash,
+                             new_keys_pair.first));
 
   EXPECT_THAT(
       verifier->Verify(test_vec.signature, test_vec.message),
@@ -97,8 +98,8 @@
   const EVP_MD *mgf1_hash = EVP_sha384();  // Owned by BoringSSL
   const int salt_length = kSaltLengthInBytes48;
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      const auto verifier, RsaSsaPssVerifier::New(test_keys.first, sig_hash,
-                                                  mgf1_hash, salt_length));
+      const auto verifier, RsaSsaPssVerifier::New(salt_length, sig_hash,
+                                                  mgf1_hash, test_keys.first));
 
   EXPECT_THAT(verifier->Verify(test_vec.signature, ""),
               testing::status::StatusIs(
@@ -147,8 +148,8 @@
       TestSignWithPublicMetadata(encoded_message, public_metadata,
                                  *private_key_));
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      auto verifier, RsaSsaPssVerifier::New(public_key_, sig_hash_, mgf1_hash_,
-                                            salt_length_, public_metadata));
+      auto verifier, RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_,
+                                            public_key_, public_metadata));
   QUICHE_EXPECT_OK(verifier->Verify(potentially_insecure_signature, message));
 }
 
@@ -166,8 +167,8 @@
       TestSignWithPublicMetadata(encoded_message, public_metadata,
                                  *private_key_));
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      auto verifier, RsaSsaPssVerifier::New(public_key_, sig_hash_, mgf1_hash_,
-                                            salt_length_, public_metadata_2));
+      auto verifier, RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_,
+                                            public_key_, public_metadata_2));
   EXPECT_THAT(
       verifier->Verify(potentially_insecure_signature, message),
       quiche::test::StatusIs(absl::StatusCode::kInvalidArgument,
@@ -188,8 +189,8 @@
       TestSignWithPublicMetadata(encoded_message, public_metadata,
                                  *private_key_));
   ANON_TOKENS_QUICHE_EXPECT_OK_AND_ASSIGN(
-      auto verifier, RsaSsaPssVerifier::New(public_key_, sig_hash_, mgf1_hash_,
-                                            salt_length_, public_metadata_2));
+      auto verifier, RsaSsaPssVerifier::New(salt_length_, sig_hash_, mgf1_hash_,
+                                            public_key_, public_metadata_2));
   EXPECT_THAT(
       verifier->Verify(potentially_insecure_signature, message),
       quiche::test::StatusIs(absl::StatusCode::kInvalidArgument,