Move protocol buffer dependent functions from crypto_utils to anonymous_tokens_pb_openssl_converters. This CL doesn't add any new code other than a few tests in anonymous_tokens_pb_openssl_converters_test.cc.

PiperOrigin-RevId: 541978821
diff --git a/build/source_list.bzl b/build/source_list.bzl
index e539204..df1bda5 100644
--- a/build/source_list.bzl
+++ b/build/source_list.bzl
@@ -1558,6 +1558,7 @@
 ]
 blind_sign_auth_hdrs = [
     "blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.h",
+    "blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h",
     "blind_sign_auth/anonymous_tokens/cpp/crypto/blind_signer.h",
     "blind_sign_auth/anonymous_tokens/cpp/crypto/blinder.h",
     "blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h",
@@ -1580,6 +1581,7 @@
 ]
 blind_sign_auth_srcs = [
     "blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc",
+    "blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.cc",
     "blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.cc",
     "blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.cc",
     "blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.cc",
@@ -1594,6 +1596,7 @@
 ]
 blind_sign_auth_tests_srcs = [
     "blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client_test.cc",
+    "blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters_test.cc",
     "blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc",
     "blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer_test.cc",
     "blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder_test.cc",
diff --git a/build/source_list.gni b/build/source_list.gni
index 2e5c6c2..0ca2990 100644
--- a/build/source_list.gni
+++ b/build/source_list.gni
@@ -1562,6 +1562,7 @@
 ]
 blind_sign_auth_hdrs = [
     "src/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.h",
+    "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h",
     "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blind_signer.h",
     "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blinder.h",
     "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h",
@@ -1584,6 +1585,7 @@
 ]
 blind_sign_auth_srcs = [
     "src/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc",
+    "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.cc",
     "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.cc",
     "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.cc",
     "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.cc",
@@ -1599,6 +1601,7 @@
 ]
 blind_sign_auth_tests_srcs = [
     "src/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client_test.cc",
+    "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters_test.cc",
     "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc",
     "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer_test.cc",
     "src/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder_test.cc",
diff --git a/build/source_list.json b/build/source_list.json
index f30cdfa..8423361 100644
--- a/build/source_list.json
+++ b/build/source_list.json
@@ -1561,6 +1561,7 @@
   ],
   "blind_sign_auth_hdrs": [
     "quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.h",
+    "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h",
     "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blind_signer.h",
     "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/blinder.h",
     "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h",
@@ -1583,6 +1584,7 @@
   ],
   "blind_sign_auth_srcs": [
     "quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc",
+    "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.cc",
     "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.cc",
     "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.cc",
     "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder.cc",
@@ -1598,6 +1600,7 @@
   ],
   "blind_sign_auth_tests_srcs": [
     "quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client_test.cc",
+    "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters_test.cc",
     "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/at_crypto_utils_test.cc",
     "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer_test.cc",
     "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder_test.cc",
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc
index 77e2e9e..b2490f3 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/client/anonymous_tokens_rsa_bssa_client.cc
@@ -25,6 +25,7 @@
 #include "absl/status/status.h"
 #include "absl/time/time.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h"
+#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/proto_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"
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.cc
new file mode 100644
index 0000000..f8f6385
--- /dev/null
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.cc
@@ -0,0 +1,86 @@
+// 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/anonymous_tokens_pb_openssl_converters.h"
+
+#include <cstdint>
+#include <string>
+
+#include "absl/status/status.h"
+#include "absl/status/statusor.h"
+#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h"
+#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h"
+#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h"
+#include "openssl/base.h"
+#include "openssl/digest.h"
+#include "openssl/rand.h"
+
+namespace private_membership {
+namespace anonymous_tokens {
+
+absl::StatusOr<std::string> GenerateMask(
+    const RSABlindSignaturePublicKey& public_key) {
+  std::string mask;
+  if (public_key.message_mask_type() == AT_MESSAGE_MASK_CONCAT &&
+      public_key.message_mask_size() >= kRsaMessageMaskSizeInBytes32) {
+    mask = std::string(public_key.message_mask_size(), '\0');
+    RAND_bytes(reinterpret_cast<uint8_t*>(mask.data()), mask.size());
+  } else {
+    return absl::InvalidArgumentError(
+        "Undefined or unsupported message mask type.");
+  }
+  return mask;
+}
+
+absl::StatusOr<const EVP_MD*> ProtoHashTypeToEVPDigest(
+    const HashType hash_type) {
+  switch (hash_type) {
+    case AT_HASH_TYPE_SHA256:
+      return EVP_sha256();
+    case AT_HASH_TYPE_SHA384:
+      return EVP_sha384();
+    case AT_HASH_TYPE_UNDEFINED:
+    default:
+      return absl::InvalidArgumentError("Unknown hash type.");
+  }
+}
+
+absl::StatusOr<const EVP_MD*> ProtoMaskGenFunctionToEVPDigest(
+    const MaskGenFunction mgf) {
+  switch (mgf) {
+    case AT_MGF_SHA256:
+      return EVP_sha256();
+    case AT_MGF_SHA384:
+      return EVP_sha384();
+    case AT_MGF_UNDEFINED:
+    default:
+      return absl::InvalidArgumentError(
+          "Unknown hash type for mask generation hash function.");
+  }
+}
+
+absl::StatusOr<bssl::UniquePtr<RSA>> AnonymousTokensRSAPrivateKeyToRSA(
+    const RSAPrivateKey& private_key) {
+  return CreatePrivateKeyRSA(private_key.n(), private_key.e(), private_key.d(),
+                             private_key.p(), private_key.q(), private_key.dp(),
+                             private_key.dq(), private_key.crt());
+}
+
+absl::StatusOr<bssl::UniquePtr<RSA>> AnonymousTokensRSAPublicKeyToRSA(
+    const RSAPublicKey& public_key) {
+  return CreatePublicKeyRSA(public_key.n(), public_key.e());
+}
+
+}  // namespace anonymous_tokens
+}  // namespace private_membership
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h
new file mode 100644
index 0000000..2ef4c06
--- /dev/null
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h
@@ -0,0 +1,59 @@
+// 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.
+
+#ifndef THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_ANONYMOUS_TOKENS_PB_OPENSSL_CONVERTERS_H_
+#define THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_ANONYMOUS_TOKENS_PB_OPENSSL_CONVERTERS_H_
+
+#include <string>
+
+#include "absl/status/statusor.h"
+#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h"
+#include "openssl/base.h"
+#include "quiche/common/platform/api/quiche_export.h"
+// copybara:strip_begin(internal comment)
+// The QUICHE_EXPORT annotation is necessary for some classes and functions
+// to link correctly on Windows. Please do not remove them!
+// copybara:strip_end
+
+namespace private_membership {
+namespace anonymous_tokens {
+
+// Generate a message mask. For more details, see
+// https://datatracker.ietf.org/doc/draft-irtf-cfrg-rsa-blind-signatures/
+absl::StatusOr<std::string> QUICHE_EXPORT GenerateMask(
+    const RSABlindSignaturePublicKey& public_key);
+
+// Converts the AnonymousTokens proto hash type to the equivalent EVP digest.
+absl::StatusOr<const EVP_MD*> QUICHE_EXPORT
+ProtoHashTypeToEVPDigest(HashType hash_type);
+
+// Converts the AnonymousTokens proto hash type for mask generation function to
+// the equivalent EVP digest.
+absl::StatusOr<const EVP_MD*> QUICHE_EXPORT
+ProtoMaskGenFunctionToEVPDigest(MaskGenFunction mgf);
+
+// Converts AnonymousTokens::RSAPrivateKey to bssl::UniquePtr<RSA> without
+// public metadata augmentation.
+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);
+
+}  // namespace anonymous_tokens
+}  // namespace private_membership
+
+#endif  // THIRD_PARTY_ANONYMOUS_TOKENS_CPP_CRYPTO_ANONYMOUS_TOKENS_PB_OPENSSL_CONVERTERS_H_
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters_test.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters_test.cc
new file mode 100644
index 0000000..23a2a96
--- /dev/null
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters_test.cc
@@ -0,0 +1,184 @@
+// 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/anonymous_tokens_pb_openssl_converters.h"
+
+#include <string>
+#include <utility>
+
+#include "quiche/common/platform/api/quiche_test.h"
+#include "quiche/common/test_tools/quiche_test_utils.h"
+#include "absl/status/status.h"
+#include "absl/status/statusor.h"
+#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h"
+#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h"
+#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.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/bn.h"
+#include "openssl/digest.h"
+#include "openssl/rsa.h"
+
+namespace private_membership {
+namespace anonymous_tokens {
+namespace {
+
+TEST(AnonymousTokensPbOpensslConvertersTests, GenerateMaskTestInvalidType) {
+  RSABlindSignaturePublicKey public_key;
+  public_key.set_message_mask_type(AT_MESSAGE_MASK_TYPE_UNDEFINED);
+  public_key.set_message_mask_size(kRsaMessageMaskSizeInBytes32);
+  absl::StatusOr<std::string> mask_32_bytes = GenerateMask(public_key);
+  EXPECT_EQ(mask_32_bytes.status().code(), absl::StatusCode::kInvalidArgument);
+  EXPECT_THAT(mask_32_bytes.status().message(),
+              ::testing::HasSubstr("unsupported message mask"));
+}
+
+TEST(AnonymousTokensPbOpensslConvertersTests, GenerateMaskTestInvalidLength) {
+  RSABlindSignaturePublicKey public_key;
+  public_key.set_message_mask_type(AT_MESSAGE_MASK_CONCAT);
+  public_key.set_message_mask_size(kRsaMessageMaskSizeInBytes32 - 1);
+  absl::StatusOr<std::string> mask_32_bytes = GenerateMask(public_key);
+  EXPECT_EQ(mask_32_bytes.status().code(), absl::StatusCode::kInvalidArgument);
+  EXPECT_THAT(mask_32_bytes.status().message(),
+              ::testing::HasSubstr("unsupported message mask"));
+}
+
+TEST(AnonymousTokensPbOpensslConvertersTests, GenerateMaskTestSuccess) {
+  RSABlindSignaturePublicKey public_key;
+  public_key.set_message_mask_type(AT_MESSAGE_MASK_CONCAT);
+  public_key.set_message_mask_size(kRsaMessageMaskSizeInBytes32);
+  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string mask_32_bytes,
+                                   GenerateMask(public_key));
+  // Longer mask.
+  public_key.set_message_mask_size(kRsaMessageMaskSizeInBytes32 * 2);
+  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string mask_64_bytes,
+                                   GenerateMask(public_key));
+
+  EXPECT_FALSE(mask_32_bytes.empty());
+  EXPECT_FALSE(mask_64_bytes.empty());
+  EXPECT_EQ(mask_32_bytes.size(), kRsaMessageMaskSizeInBytes32);
+  EXPECT_EQ(mask_64_bytes.size(), kRsaMessageMaskSizeInBytes32 * 2);
+}
+
+TEST(AnonymousTokensPbOpensslConvertersTests,
+     HashTypeConverterTestInvalidType) {
+  absl::StatusOr<const EVP_MD *> evp =
+      ProtoHashTypeToEVPDigest(AT_HASH_TYPE_UNDEFINED);
+  EXPECT_EQ(evp.status().code(), absl::StatusCode::kInvalidArgument);
+  EXPECT_THAT(evp.status().message(),
+              ::testing::HasSubstr("Unknown hash type"));
+}
+
+TEST(AnonymousTokensPbOpensslConvertersTests, HashTypeConverterTestSuccess) {
+  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
+      const EVP_MD *evp_256, ProtoHashTypeToEVPDigest(AT_HASH_TYPE_SHA256));
+  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
+      const EVP_MD *evp_384, ProtoHashTypeToEVPDigest(AT_HASH_TYPE_SHA384));
+  EXPECT_EQ(evp_256, EVP_sha256());
+  EXPECT_EQ(evp_384, EVP_sha384());
+}
+
+TEST(AnonymousTokensPbOpensslConvertersStrongTests,
+     MaskGenFunctionConverterStrongTestInvalidType) {
+  absl::StatusOr<const EVP_MD *> evp =
+      ProtoMaskGenFunctionToEVPDigest(AT_MGF_UNDEFINED);
+  EXPECT_EQ(evp.status().code(), absl::StatusCode::kInvalidArgument);
+  EXPECT_THAT(evp.status().message(),
+              ::testing::HasSubstr(
+                  "Unknown hash type for mask generation hash function"));
+}
+
+TEST(AnonymousTokensPbOpensslConvertersTests,
+     MaskGenFunctionConverterTestSuccess) {
+  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
+      const EVP_MD *evp_256, ProtoMaskGenFunctionToEVPDigest(AT_MGF_SHA256));
+  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
+      const EVP_MD *evp_384, ProtoMaskGenFunctionToEVPDigest(AT_MGF_SHA384));
+  EXPECT_EQ(evp_256, EVP_sha256());
+  EXPECT_EQ(evp_384, EVP_sha384());
+}
+
+using CreateTestKeyPairFunction =
+    absl::StatusOr<std::pair<RSAPublicKey, RSAPrivateKey>>();
+
+class AnonymousTokensRsaKeyPairConverterTest
+    : 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);
+    private_key_ = std::move(keys_pair.second);
+
+    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_modulus_,
+                                     StringToBignum(private_key_.n()));
+    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_e_, StringToBignum(private_key_.e()));
+    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_d_, StringToBignum(private_key_.d()));
+    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_p_, StringToBignum(private_key_.p()));
+    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_q_, StringToBignum(private_key_.q()));
+    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_dp_,
+                                     StringToBignum(private_key_.dp()));
+    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_dq_,
+                                     StringToBignum(private_key_.dq()));
+    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_crt_,
+                                     StringToBignum(private_key_.crt()));
+  }
+
+  bssl::UniquePtr<BIGNUM> rsa_modulus_;
+  bssl::UniquePtr<BIGNUM> rsa_e_;
+  bssl::UniquePtr<BIGNUM> rsa_d_;
+  bssl::UniquePtr<BIGNUM> rsa_p_;
+  bssl::UniquePtr<BIGNUM> rsa_q_;
+  bssl::UniquePtr<BIGNUM> rsa_dp_;
+  bssl::UniquePtr<BIGNUM> rsa_dq_;
+  bssl::UniquePtr<BIGNUM> rsa_crt_;
+
+  RSAPublicKey public_key_;
+  RSAPrivateKey private_key_;
+};
+
+TEST_P(AnonymousTokensRsaKeyPairConverterTest, PublicKeyTest) {
+  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
+      bssl::UniquePtr<RSA> rsa_public_key,
+      AnonymousTokensRSAPublicKeyToRSA(public_key_));
+
+  EXPECT_EQ(BN_cmp(RSA_get0_n(rsa_public_key.get()), rsa_modulus_.get()), 0);
+  EXPECT_EQ(BN_cmp(RSA_get0_e(rsa_public_key.get()), rsa_e_.get()), 0);
+}
+
+TEST_P(AnonymousTokensRsaKeyPairConverterTest, PrivateKeyTest) {
+  ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
+      bssl::UniquePtr<RSA> rsa_private_key,
+      AnonymousTokensRSAPrivateKeyToRSA(private_key_));
+
+  EXPECT_EQ(BN_cmp(RSA_get0_n(rsa_private_key.get()), rsa_modulus_.get()), 0);
+  EXPECT_EQ(BN_cmp(RSA_get0_e(rsa_private_key.get()), rsa_e_.get()), 0);
+  EXPECT_EQ(BN_cmp(RSA_get0_d(rsa_private_key.get()), rsa_d_.get()), 0);
+  EXPECT_EQ(BN_cmp(RSA_get0_p(rsa_private_key.get()), rsa_p_.get()), 0);
+  EXPECT_EQ(BN_cmp(RSA_get0_q(rsa_private_key.get()), rsa_q_.get()), 0);
+  EXPECT_EQ(BN_cmp(RSA_get0_dmp1(rsa_private_key.get()), rsa_dp_.get()), 0);
+  EXPECT_EQ(BN_cmp(RSA_get0_dmq1(rsa_private_key.get()), rsa_dq_.get()), 0);
+  EXPECT_EQ(BN_cmp(RSA_get0_iqmp(rsa_private_key.get()), rsa_crt_.get()), 0);
+}
+
+INSTANTIATE_TEST_SUITE_P(AnonymousTokensRsaKeyPairConverterTest,
+                         AnonymousTokensRsaKeyPairConverterTest,
+                         testing::Values(&GetStrongRsaKeys2048,
+                                         &GetAnotherStrongRsaKeys2048,
+                                         &GetStrongRsaKeys3072,
+                                         &GetStrongRsaKeys4096));
+
+}  // namespace
+}  // namespace anonymous_tokens
+}  // namespace private_membership
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 600b7b2..e8cd5c5 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
@@ -22,9 +22,7 @@
 #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/proto_utils.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"
 
@@ -33,7 +31,8 @@
 namespace {
 
 struct IetfNewPublicExponentWithPublicMetadataTestVector {
-  RSAPublicKey public_key;
+  std::string rsa_modulus;
+  std::string e;
   std::string public_metadata;
   std::string new_e;
 };
@@ -206,8 +205,7 @@
 GetIetfNewPublicExponentWithPublicMetadataTestVectors() {
   std::vector<IetfNewPublicExponentWithPublicMetadataTestVector> test_vectors;
 
-  RSAPublicKey public_key;
-  public_key.set_n(absl::HexStringToBytes(
+  std::string modulus = absl::HexStringToBytes(
       "d6930820f71fe517bf3259d14d40209b02a5c0d3d61991c731dd7da39f8d69821552e231"
       "8d6c9ad897e603887a476ea3162c1205da9ac96f02edf31df049bd55f142134c17d4382a"
       "0e78e275345f165fbe8e49cdca6cf5c726c599dd39e09e75e0f330a33121e73976e4facb"
@@ -215,12 +213,13 @@
       "5ec7256da3fddd0718b89c365410fce61bc7c99b115fb4c3c318081fa7e1b65a37774e8e"
       "50c96e8ce2b2cc6b3b367982366a2bf9924c4bafdb3ff5e722258ab705c76d43e5f1f121"
       "b984814e98ea2b2b8725cd9bc905c0bc3d75c2a8db70a7153213c39ae371b2b5dc1dafcb"
-      "19d6fae9"));
-  public_key.set_e(absl::HexStringToBytes("010001"));
+      "19d6fae9");
+  std::string e = absl::HexStringToBytes("010001");
 
   // Test vector 1
   test_vectors.push_back(
-      {.public_key = public_key,
+      {.rsa_modulus = modulus,
+       .e = e,
        .public_metadata = absl::HexStringToBytes("6d65746164617461"),
        .new_e = absl::HexStringToBytes(
            "30584b72f5cb557085106232f051d039e23358feee9204cf30ea567620e90d79e4a"
@@ -230,7 +229,8 @@
 
   // Test vector 2
   test_vectors.push_back(
-      {.public_key = public_key,
+      {.rsa_modulus = modulus,
+       .e = e,
        .public_metadata = "",
        .new_e = absl::HexStringToBytes(
            "2ed5a8d2592a11bbeef728bb39018ef5c3cf343507dd77dd156d5eec7f06f04732e"
@@ -247,12 +247,10 @@
       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> rsa_modulus,
+                                     StringToBignum(test_vector.rsa_modulus));
+    ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> rsa_e,
+                                     StringToBignum(test_vector.e));
     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> expected_new_e,
                                      StringToBignum(test_vector.new_e));
     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
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 7660860..8f6834a 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
@@ -30,7 +30,6 @@
 #include "absl/strings/string_view.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.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/bytestring.h"
 #include "openssl/err.h"
 #include "openssl/hkdf.h"
@@ -173,20 +172,6 @@
   return ret;
 }
 
-absl::StatusOr<std::string> GenerateMask(
-    const RSABlindSignaturePublicKey& public_key) {
-  std::string mask;
-  if (public_key.message_mask_type() == AT_MESSAGE_MASK_CONCAT &&
-      public_key.message_mask_size() >= kRsaMessageMaskSizeInBytes32) {
-    mask = std::string(public_key.message_mask_size(), '\0');
-    RAND_bytes(reinterpret_cast<uint8_t*>(mask.data()), mask.size());
-  } else {
-    return absl::InvalidArgumentError(
-        "Undefined or unsupported message mask type.");
-  }
-  return mask;
-}
-
 std::string MaskMessageConcat(absl::string_view mask,
                               absl::string_view message) {
   return absl::StrCat(mask, message);
@@ -208,33 +193,6 @@
   return absl::StrCat(encoding, public_metadata, message);
 }
 
-absl::StatusOr<const EVP_MD*> ProtoHashTypeToEVPDigest(
-    const HashType hash_type) {
-  switch (hash_type) {
-    case AT_HASH_TYPE_SHA256:
-      return EVP_sha256();
-    case AT_HASH_TYPE_SHA384:
-      return EVP_sha384();
-    case AT_HASH_TYPE_UNDEFINED:
-    default:
-      return absl::InvalidArgumentError("Unknown hash type.");
-  }
-}
-
-absl::StatusOr<const EVP_MD*> ProtoMaskGenFunctionToEVPDigest(
-    const MaskGenFunction mgf) {
-  switch (mgf) {
-    case AT_MGF_SHA256:
-      return EVP_sha256();
-    case AT_MGF_SHA384:
-      return EVP_sha384();
-    case AT_MGF_UNDEFINED:
-    default:
-      return absl::InvalidArgumentError(
-          "Unknown hash type for mask generation hash function.");
-  }
-}
-
 absl::StatusOr<bssl::UniquePtr<BIGNUM>> GetRsaSqrtTwo(int x) {
   // Compute hard-coded sqrt(2).
   ANON_TOKENS_ASSIGN_OR_RETURN(bssl::UniquePtr<BIGNUM> sqrt2, NewBigNum());
@@ -322,18 +280,6 @@
   return digest;
 }
 
-absl::StatusOr<bssl::UniquePtr<RSA>> AnonymousTokensRSAPrivateKeyToRSA(
-    const RSAPrivateKey& private_key) {
-  return CreatePrivateKeyRSA(private_key.n(), private_key.e(), private_key.d(),
-                             private_key.p(), private_key.q(), private_key.dp(),
-                             private_key.dq(), private_key.crt());
-}
-
-absl::StatusOr<bssl::UniquePtr<RSA>> AnonymousTokensRSAPublicKeyToRSA(
-    const RSAPublicKey& public_key) {
-  return CreatePublicKeyRSA(public_key.n(), public_key.e());
-}
-
 absl::StatusOr<bssl::UniquePtr<RSA>> CreatePrivateKeyRSA(
     const absl::string_view rsa_modulus,
     const absl::string_view public_exponent,
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 197b793..e9e036f 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
@@ -23,7 +23,6 @@
 
 #include "absl/status/statusor.h"
 #include "absl/strings/string_view.h"
-#include "quiche/blind_sign_auth/anonymous_tokens/proto/anonymous_tokens.pb.h"
 #include "openssl/base.h"
 #include "openssl/bn.h"
 #include "openssl/evp.h"
@@ -96,11 +95,6 @@
 // Retrieve error messages from OpenSSL.
 std::string QUICHE_EXPORT GetSslErrors();
 
-// Generate a message mask. For more details, see
-// https://datatracker.ietf.org/doc/draft-irtf-cfrg-rsa-blind-signatures/
-absl::StatusOr<std::string> QUICHE_EXPORT GenerateMask(
-    const RSABlindSignaturePublicKey& public_key);
-
 // Mask message using protocol at
 // https://datatracker.ietf.org/doc/draft-irtf-cfrg-rsa-blind-signatures/
 std::string QUICHE_EXPORT MaskMessageConcat(absl::string_view mask,
@@ -121,15 +115,6 @@
 absl::StatusOr<bssl::UniquePtr<BIGNUM>> QUICHE_EXPORT ComputePowerOfTwo(
     int x);
 
-// Converts the AnonymousTokens proto hash type to the equivalent EVP digest.
-absl::StatusOr<const EVP_MD*> QUICHE_EXPORT
-ProtoHashTypeToEVPDigest(HashType hash_type);
-
-// Converts the AnonymousTokens proto hash type for mask generation function to
-// the equivalent EVP digest.
-absl::StatusOr<const EVP_MD*> QUICHE_EXPORT
-ProtoMaskGenFunctionToEVPDigest(MaskGenFunction mgf);
-
 // ComputeHash sub-routine used during blindness and verification of RSA blind
 // signatures protocol with or without public metadata.
 absl::StatusOr<std::string> QUICHE_EXPORT ComputeHash(
@@ -140,16 +125,6 @@
 absl::StatusOr<bssl::UniquePtr<BIGNUM>> QUICHE_EXPORT
 ComputeCarmichaelLcm(const BIGNUM& phi_p, const BIGNUM& phi_q, BN_CTX& bn_ctx);
 
-// Converts AnonymousTokens::RSAPrivateKey to bssl::UniquePtr<RSA> without
-// public metadata augmentation.
-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);
-
 // Create bssl::UniquePtr<RSA> representing a RSA private key.
 absl::StatusOr<bssl::UniquePtr<RSA>> QUICHE_EXPORT
 CreatePrivateKeyRSA(absl::string_view rsa_modulus,
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.cc
index f138eb4..1206559 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.cc
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blind_signer.cc
@@ -27,6 +27,7 @@
 #include "absl/strings/string_view.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h"
+#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.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/rsa.h"
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 aacd445..92a21c3 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
@@ -23,6 +23,7 @@
 #include "absl/strings/string_view.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h"
+#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.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/digest.h"
diff --git a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder_test.cc b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder_test.cc
index 7c16753..16f6179 100644
--- a/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder_test.cc
+++ b/quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/rsa_blinder_test.cc
@@ -23,10 +23,10 @@
 #include "absl/status/status.h"
 #include "absl/status/statusor.h"
 #include "absl/strings/string_view.h"
+#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h"
-#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h"
-#include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/utils.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.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"
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 be88314..0c1b3f3 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
@@ -25,6 +25,7 @@
 #include "absl/status/statusor.h"
 #include "absl/strings/str_cat.h"
 #include "absl/strings/string_view.h"
+#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/shared/status_utils.h"
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 52dc988..fad236a 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
@@ -23,6 +23,7 @@
 #include "absl/status/status.h"
 #include "absl/status/statusor.h"
 #include "absl/strings/string_view.h"
+#include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/anonymous_tokens_pb_openssl_converters.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/constants.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/crypto/crypto_utils.h"
 #include "quiche/blind_sign_auth/anonymous_tokens/cpp/testing/proto_utils.h"