1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //    https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14 
15 #include "anonymous_tokens/cpp/crypto/crypto_utils.h"
16 
17 #include <memory>
18 #include <string>
19 #include <utility>
20 #include <vector>
21 
22 #include <gmock/gmock.h>
23 #include <gtest/gtest.h>
24 #include "absl/strings/escaping.h"
25 #include "anonymous_tokens/cpp/testing/utils.h"
26 #include <openssl/base.h>
27 #include <openssl/rsa.h>
28 
29 namespace anonymous_tokens {
30 namespace {
31 
32 struct IetfNewPublicExponentWithPublicMetadataTestVector {
33   std::string rsa_modulus;
34   std::string e;
35   std::string public_metadata;
36   std::string new_e;
37 };
38 
TEST(AnonymousTokensCryptoUtilsTest,BignumToStringAndBack)39 TEST(AnonymousTokensCryptoUtilsTest, BignumToStringAndBack) {
40   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx());
41 
42   // Create a new BIGNUM using the context and set it
43   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> bn_1, NewBigNum());
44   ASSERT_EQ(BN_set_u64(bn_1.get(), 0x124435435), 1);
45   EXPECT_NE(bn_1, nullptr);
46   EXPECT_EQ(BN_is_zero(bn_1.get()), 0);
47   EXPECT_EQ(BN_is_one(bn_1.get()), 0);
48 
49   // Convert bn_1 to string from BIGNUM
50   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
51       const std::string converted_str,
52       BignumToString(*bn_1, BN_num_bytes(bn_1.get())));
53   // Convert the string version of bn_1 back to BIGNUM
54   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> bn_2,
55                                    StringToBignum(converted_str));
56   // Check whether the conversion back worked
57   EXPECT_EQ(BN_cmp(bn_1.get(), bn_2.get()), 0);
58 }
59 
TEST(AnonymousTokensCryptoUtilsTest,PowerOfTwoAndRsaSqrtTwo)60 TEST(AnonymousTokensCryptoUtilsTest, PowerOfTwoAndRsaSqrtTwo) {
61   // Compute 2^(10-1/2).
62   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> sqrt2,
63                                    GetRsaSqrtTwo(10));
64   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> small_pow2,
65                                    ComputePowerOfTwo(9));
66   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> large_pow2,
67                                    ComputePowerOfTwo(10));
68   EXPECT_GT(BN_cmp(sqrt2.get(), small_pow2.get()), 0);
69   EXPECT_LT(BN_cmp(sqrt2.get(), large_pow2.get()), 0);
70 }
71 
TEST(AnonymousTokensCryptoUtilsTest,ComputeHashAcceptsNullStringView)72 TEST(AnonymousTokensCryptoUtilsTest, ComputeHashAcceptsNullStringView) {
73   absl::StatusOr<std::string> null_hash =
74       ComputeHash(absl::string_view(nullptr, 0), *EVP_sha512());
75   absl::StatusOr<std::string> empty_hash = ComputeHash("", *EVP_sha512());
76   std::string str;
77   absl::StatusOr<std::string> empty_str_hash = ComputeHash(str, *EVP_sha512());
78 
79   ASSERT_TRUE(null_hash.ok());
80   ASSERT_TRUE(empty_hash.ok());
81   ASSERT_TRUE(empty_str_hash.ok());
82 
83   EXPECT_EQ(*null_hash, *empty_hash);
84   EXPECT_EQ(*null_hash, *empty_str_hash);
85 }
86 
TEST(AnonymousTokensCryptoUtilsTest,ComputeCarmichaelLcm)87 TEST(AnonymousTokensCryptoUtilsTest, ComputeCarmichaelLcm) {
88   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx());
89 
90   // Suppose that N = 1019 * 1187.
91   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> phi_p, NewBigNum());
92   ASSERT_TRUE(BN_set_word(phi_p.get(), 1019 - 1));
93   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> phi_q, NewBigNum());
94   ASSERT_TRUE(BN_set_word(phi_q.get(), 1187 - 1));
95   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> expected_lcm,
96                                    NewBigNum());
97   ASSERT_TRUE(BN_set_word(expected_lcm.get(), (1019 - 1) * (1187 - 1) / 2));
98 
99   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> lcm,
100                                    ComputeCarmichaelLcm(*phi_p, *phi_q, *ctx));
101   EXPECT_EQ(BN_cmp(lcm.get(), expected_lcm.get()), 0);
102 }
103 
104 struct ComputeHashTestParam {
105   const EVP_MD* hasher;
106   absl::string_view input_hex;
107   absl::string_view expected_digest_hex;
108 };
109 
110 using ComputeHashTest = testing::TestWithParam<ComputeHashTestParam>;
111 
112 // Returns the test parameters for ComputeHashTestParam from NIST's
113 // samples.
GetComputeHashTestParams()114 std::vector<ComputeHashTestParam> GetComputeHashTestParams() {
115   std::vector<ComputeHashTestParam> params;
116   params.push_back({
117       EVP_sha256(),
118       "af397a8b8dd73ab702ce8e53aa9f",
119       "d189498a3463b18e846b8ab1b41583b0b7efc789dad8a7fb885bbf8fb5b45c5c",
120   });
121   params.push_back({
122       EVP_sha256(),
123       "59eb45bbbeb054b0b97334d53580ce03f699",
124       "32c38c54189f2357e96bd77eb00c2b9c341ebebacc2945f97804f59a93238288",
125   });
126   params.push_back({
127       EVP_sha512(),
128       "16b17074d3e3d97557f9ed77d920b4b1bff4e845b345a922",
129       "6884134582a760046433abcbd53db8ff1a89995862f305b887020f6da6c7b903a314721e"
130       "972bf438483f452a8b09596298a576c903c91df4a414c7bd20fd1d07",
131   });
132   params.push_back({
133       EVP_sha512(),
134       "7651ab491b8fa86f969d42977d09df5f8bee3e5899180b52c968b0db057a6f02a886ad61"
135       "7a84915a",
136       "f35e50e2e02b8781345f8ceb2198f068ba103476f715cfb487a452882c9f0de0c720b2a0"
137       "88a39d06a8a6b64ce4d6470dfeadc4f65ae06672c057e29f14c4daf9",
138   });
139   return params;
140 }
141 
TEST_P(ComputeHashTest,ComputesHash)142 TEST_P(ComputeHashTest, ComputesHash) {
143   const ComputeHashTestParam& params = GetParam();
144   ASSERT_NE(params.hasher, nullptr);
145   std::string data;
146   ASSERT_TRUE(absl::HexStringToBytes(params.input_hex, &data));
147   std::string expected_digest;
148   ASSERT_TRUE(
149       absl::HexStringToBytes(params.expected_digest_hex, &expected_digest));
150   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto computed_hash,
151                                    ComputeHash(data, *params.hasher));
152   EXPECT_EQ(computed_hash, expected_digest);
153 }
154 
155 INSTANTIATE_TEST_SUITE_P(ComputeHashTests, ComputeHashTest,
156                          testing::ValuesIn(GetComputeHashTestParams()));
157 
TEST(PublicMetadataCryptoUtilsInternalTest,PublicMetadataHashWithHKDF)158 TEST(PublicMetadataCryptoUtilsInternalTest, PublicMetadataHashWithHKDF) {
159   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx());
160   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> max_value,
161                                    NewBigNum());
162   ASSERT_TRUE(BN_set_word(max_value.get(), 4294967295));
163   const auto [public_key, _] = GetStrongTestRsaKeyPair2048();
164   std::string input1 = "ro1";
165   std::string input2 = "ro2";
166   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
167       bssl::UniquePtr<BIGNUM> output1,
168       internal::PublicMetadataHashWithHKDF(input1, public_key.n,
169                                            1 + input1.size()));
170   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
171       bssl::UniquePtr<BIGNUM> another_output1,
172       internal::PublicMetadataHashWithHKDF(input1, public_key.n,
173                                            1 + input1.size()));
174   EXPECT_EQ(BN_cmp(output1.get(), another_output1.get()), 0);
175 
176   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
177       bssl::UniquePtr<BIGNUM> output2,
178       internal::PublicMetadataHashWithHKDF(input2, public_key.n,
179                                            1 + input2.size()));
180   EXPECT_NE(BN_cmp(output1.get(), output2.get()), 0);
181 
182   EXPECT_LE(BN_cmp(output1.get(), max_value.get()), 0);
183   EXPECT_LE(BN_cmp(output2.get(), max_value.get()), 0);
184 }
185 
TEST(PublicMetadataCryptoUtilsTest,PublicExponentHashDifferentModulus)186 TEST(PublicMetadataCryptoUtilsTest, PublicExponentHashDifferentModulus) {
187   const auto public_key_1 = std::get<0>(GetStrongTestRsaKeyPair2048());
188   const auto public_key_2 = std::get<0>(GetAnotherStrongTestRsaKeyPair2048());
189   std::string metadata = "md";
190   // Check that same metadata and different modulus result in different
191   // hashes.
192   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> rsa_modulus_1,
193                                    StringToBignum(public_key_1.n));
194   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
195       bssl::UniquePtr<BIGNUM> exp1,
196       ComputeExponentWithPublicMetadata(*rsa_modulus_1.get(), metadata));
197   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(auto rsa_modulus_2,
198                                    StringToBignum(public_key_2.n));
199   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
200       bssl::UniquePtr<BIGNUM> exp2,
201       ComputeExponentWithPublicMetadata(*rsa_modulus_2.get(), metadata));
202   EXPECT_NE(BN_cmp(exp1.get(), exp2.get()), 0);
203 }
204 
205 std::vector<IetfNewPublicExponentWithPublicMetadataTestVector>
GetIetfNewPublicExponentWithPublicMetadataTestVectors(bool use_rsa_public_exponent)206 GetIetfNewPublicExponentWithPublicMetadataTestVectors(
207     bool use_rsa_public_exponent) {
208   bool success = true;
209   std::vector<IetfNewPublicExponentWithPublicMetadataTestVector> test_vectors;
210   std::string modulus;
211   success &= absl::HexStringToBytes(
212       "d6930820f71fe517bf3259d14d40209b02a5c0d3d61991c731dd7da39f8d69821552e231"
213       "8d6c9ad897e603887a476ea3162c1205da9ac96f02edf31df049bd55f142134c17d4382a"
214       "0e78e275345f165fbe8e49cdca6cf5c726c599dd39e09e75e0f330a33121e73976e4facb"
215       "a9cfa001c28b7c96f8134f9981db6750b43a41710f51da4240fe03106c12acb1e7bb53d7"
216       "5ec7256da3fddd0718b89c365410fce61bc7c99b115fb4c3c318081fa7e1b65a37774e8e"
217       "50c96e8ce2b2cc6b3b367982366a2bf9924c4bafdb3ff5e722258ab705c76d43e5f1f121"
218       "b984814e98ea2b2b8725cd9bc905c0bc3d75c2a8db70a7153213c39ae371b2b5dc1dafcb"
219       "19d6fae9",
220       &modulus);
221   std::string e;
222   success &= absl::HexStringToBytes("010001", &e);
223 
224   if (use_rsa_public_exponent) {
225     std::string public_metadata_1;
226     success &= absl::HexStringToBytes("6d65746164617461", &public_metadata_1);
227     std::string new_e_1;
228     success &= absl::HexStringToBytes(
229         "30584b72f5cb557085106232f051d039e23358feee9204cf30ea567620e90d79e4a7a8"
230         "1388b1f390e18ea5240a1d8cc296ce1325128b445c48aa5a3b34fa07c324bf17bc7f1b"
231         "3efebaff81d7e032948f1477493bc183d2f8d94c947c984c6f0757527615bf2a2f0ef0"
232         "db5ad80ce99905beed0440b47fa5cb9a2334fea40ad88e6ef1",
233         &new_e_1);
234     // Test vector 1
235     test_vectors.push_back({.rsa_modulus = modulus,
236                             .e = e,
237                             .public_metadata = std::move(public_metadata_1),
238                             .new_e = std::move(new_e_1)});
239 
240     std::string new_e_2;
241     success &= absl::HexStringToBytes(
242         "2ed5a8d2592a11bbeef728bb39018ef5c3cf343507dd77dd156d5eec7f06f04732e4be"
243         "944c5d2443d244c59e52c9fa5e8de40f55ffd0e70fbe9093d3f7be2aafd77c14b263b7"
244         "1c1c6b3ca2b9629842a902128fee4878392a950906fae35d6194e0d2548e58bbc20f84"
245         "1188ca2fceb20b2b1b45448da5c7d1c73fb6e83fa58867397b",
246         &new_e_2);
247     // Test vector 2
248     test_vectors.push_back({.rsa_modulus = std::move(modulus),
249                             .e = std::move(e),
250                             .public_metadata = "",
251                             .new_e = std::move(new_e_2)});
252   } else {
253     std::string public_metadata_1;
254     success &= absl::HexStringToBytes("6d65746164617461", &public_metadata_1);
255     std::string new_e_1;
256     success &= absl::HexStringToBytes(
257         "30581b1adab07ac00a5057e2986f37caaa68ae963ffbc4d36c16ea5f3689d6f00db79a"
258         "5bee56053adc53c8d0414d4b754b58c7cc4abef99d4f0d0b2e29cbddf746c7d0f4ae26"
259         "90d82a2757b088820c0d086a40d180b2524687060d768ad5e431732102f4bc3572d97e"
260         "01dcd6301368f255faae4606399f91fa913a6d699d6ef1",
261         &new_e_1);
262     // Test vector 1
263     test_vectors.push_back({.rsa_modulus = modulus,
264                             .e = e,
265                             .public_metadata = std::move(public_metadata_1),
266                             .new_e = std::move(new_e_1)});
267 
268     std::string new_e_2;
269     success &= absl::HexStringToBytes(
270         "2ed579fcdf2d328ebc686c52ccaec247018832acd530a2ac72c0ec2b92db5d6bd578e9"
271         "1b6341c1021142b45b9e6e5bf031f3dd62226ec4a0f9ef99e45dd9ccd60aa60a0c59aa"
272         "c271a8caf9ee68a9d9ff281367dae09d588d3c7bca7f18de48b6981bbc729c4925c65e"
273         "4b2a7f054facbb7e5fc6e4c6c10110c62ef0b94eec397b",
274         &new_e_2);
275     // Test vector 2
276     test_vectors.push_back({.rsa_modulus = std::move(modulus),
277                             .e = std::move(e),
278                             .public_metadata = "",
279                             .new_e = std::move(new_e_2)});
280   }
281   EXPECT_TRUE(success);
282   return test_vectors;
283 }
284 
TEST(PublicMetadataCryptoUtilsTest,IetfNewPublicExponentWithPublicMetadataTests)285 TEST(PublicMetadataCryptoUtilsTest,
286      IetfNewPublicExponentWithPublicMetadataTests) {
287   const auto test_vectors =
288       GetIetfNewPublicExponentWithPublicMetadataTestVectors(
289           /*use_rsa_public_exponent=*/true);
290   for (const IetfNewPublicExponentWithPublicMetadataTestVector& test_vector :
291        test_vectors) {
292     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> rsa_modulus,
293                                      StringToBignum(test_vector.rsa_modulus));
294     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> rsa_e,
295                                      StringToBignum(test_vector.e));
296     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> expected_new_e,
297                                      StringToBignum(test_vector.new_e));
298     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
299         bssl::UniquePtr<BIGNUM> modified_e,
300         ComputeExponentWithPublicMetadataAndPublicExponent(
301             *rsa_modulus.get(), *rsa_e.get(), test_vector.public_metadata));
302 
303     EXPECT_EQ(BN_cmp(modified_e.get(), expected_new_e.get()), 0);
304   }
305 }
306 
TEST(PublicMetadataCryptoUtilsTest,IetfNewPublicExponentWithPublicMetadataNoPublicExponentTests)307 TEST(PublicMetadataCryptoUtilsTest,
308      IetfNewPublicExponentWithPublicMetadataNoPublicExponentTests) {
309   const auto test_vectors =
310       GetIetfNewPublicExponentWithPublicMetadataTestVectors(
311           /*use_rsa_public_exponent=*/false);
312   for (const IetfNewPublicExponentWithPublicMetadataTestVector& test_vector :
313        test_vectors) {
314     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> rsa_modulus,
315                                      StringToBignum(test_vector.rsa_modulus));
316     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> expected_new_e,
317                                      StringToBignum(test_vector.new_e));
318     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
319         bssl::UniquePtr<BIGNUM> modified_e,
320         ComputeExponentWithPublicMetadata(*rsa_modulus.get(),
321                                           test_vector.public_metadata));
322 
323     EXPECT_EQ(BN_cmp(modified_e.get(), expected_new_e.get()), 0);
324   }
325 }
326 
TEST(AnonymousTokensCryptoUtilsTest,RsaPssDerEncoding)327 TEST(AnonymousTokensCryptoUtilsTest, RsaPssDerEncoding) {
328   std::string rsa_modulus;
329   ASSERT_TRUE(absl::HexStringToBytes(
330       "b259758bb02bc75b68b17612c9bf68c5fa05958a334c61e167bc20bcc75757c126e892"
331       "10b9df3989072cf6260e6883c7cd4af4d31dde9915b69b301fbef962de8c71bd2db5ec62"
332       "5da259712f86a8dc3d241e9688c82391b7bf1ebc358311f55c26be910b76f61fea408ed6"
333       "92f1a9578a622c82c0fcf6f69ef3670e38bfc90f63da4f3bbbd088c8ae7a3c5a55e66f64"
334       "74d562d32cce7b7edd7cf0149ca0e96cb6525e81fbba815a8f12748e34e5135f572b2e17"
335       "b7ba430081597e6fb9033c005884d5935118c60d75b010f6fece7ecdcc1cb7d58d138969"
336       "3d43377f4f3de949cb1e4105e792b96d7f04b0cd262ac33cffc5a890d267425e61c19e93"
337       "63550f2285",
338       &rsa_modulus));
339   // A hex string of 3 bytes in length is passed.
340   std::string e_not_padded;
341   ASSERT_TRUE(absl::HexStringToBytes("010001", &e_not_padded));
342   // A hex string of 4 bytes in length is passed.
343   std::string e_padded;
344   ASSERT_TRUE(absl::HexStringToBytes("00010001", &e_padded));
345 
346   // Convert both padded and not padded rsa public keys to rsa structs.
347   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
348       bssl::UniquePtr<RSA> rsa_e_not_padded,
349       CreatePublicKeyRSA(rsa_modulus, e_not_padded));
350   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<RSA> rsa_e_padded,
351                                    CreatePublicKeyRSA(rsa_modulus, e_padded));
352   // Encode both padded and not padded rsa structs to DER.
353   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
354       std::string result_e_not_padded,
355       RsaSsaPssPublicKeyToDerEncoding(rsa_e_not_padded.get()));
356   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
357       std::string result_e_padded,
358       RsaSsaPssPublicKeyToDerEncoding(rsa_e_padded.get()));
359 
360   std::string expected_der_encoding;
361   ASSERT_TRUE(absl::HexStringToBytes(
362       "30820152303d06092a864886f70d01010a3030a00d300b0609608648016503040202a11a"
363       "301806092a864886f70d010108300b0609608648016503040202a2030201300382010f00"
364       "3082010a0282010100b259758bb02bc75b68b17612c9bf68c5fa05958a334c61e167bc20"
365       "bcc75757c126e89210b9df3989072cf6260e6883c7cd4af4d31dde9915b69b301fbef962"
366       "de8c71bd2db5ec625da259712f86a8dc3d241e9688c82391b7bf1ebc358311f55c26be91"
367       "0b76f61fea408ed692f1a9578a622c82c0fcf6f69ef3670e38bfc90f63da4f3bbbd088c8"
368       "ae7a3c5a55e66f6474d562d32cce7b7edd7cf0149ca0e96cb6525e81fbba815a8f12748e"
369       "34e5135f572b2e17b7ba430081597e6fb9033c005884d5935118c60d75b010f6fece7ecd"
370       "cc1cb7d58d1389693d43377f4f3de949cb1e4105e792b96d7f04b0cd262ac33cffc5a890"
371       "d267425e61c19e9363550f22850203010001",
372       &expected_der_encoding));
373 
374   EXPECT_EQ(result_e_not_padded, expected_der_encoding);
375   EXPECT_EQ(result_e_padded, expected_der_encoding);
376 }
377 
378 // The public key used in this test is taken from the test vectors found here:
379 // https://www.ietf.org/archive/id/draft-ietf-privacypass-protocol-10.html#name-issuance-protocol-2-blind-rs
TEST(AnonymousTokensCryptoUtilsTest,IetfPrivacyPassBlindRsaPublicKeyToDer)380 TEST(AnonymousTokensCryptoUtilsTest, IetfPrivacyPassBlindRsaPublicKeyToDer) {
381   std::string rsa_modulus;
382   ASSERT_TRUE(absl::HexStringToBytes(
383       "cb1aed6b6a95f5b1ce013a4cfcab25b94b2e64a23034e4250a7eab43c0df3a8c12993af1"
384       "2b111908d4b471bec31d4b6c9ad9cdda90612a2ee903523e6de5a224d6b02f09e5c374d0"
385       "cfe01d8f529c500a78a2f67908fa682b5a2b430c81eaf1af72d7b5e794fc98a313927687"
386       "9757ce453b526ef9bf6ceb99979b8423b90f4461a22af37aab0cf5733f7597abe44d31c7"
387       "32db68a181c6cbbe607d8c0e52e0655fd9996dc584eca0be87afbcd78a337d17b1dba9e8"
388       "28bbd81e291317144e7ff89f55619709b096cbb9ea474cead264c2073fe49740c01f00e1"
389       "09106066983d21e5f83f086e2e823c879cd43cef700d2a352a9babd612d03cad02db134b"
390       "7e225a5f",
391       &rsa_modulus));
392   std::string e;
393   ASSERT_TRUE(absl::HexStringToBytes("010001", &e));
394   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<RSA> rsa,
395                                    CreatePublicKeyRSA(rsa_modulus, e));
396   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(std::string result,
397                                    RsaSsaPssPublicKeyToDerEncoding(rsa.get()));
398 
399   std::string expected_der_encoding;
400   ASSERT_TRUE(absl::HexStringToBytes(
401       "30820152303d06092a864886f70d01010a3030a00d300b0609608648016503040202a11a"
402       "301806092a864886f70d010108300b0609608648016503040202a2030201300382010f00"
403       "3082010a0282010100cb1aed6b6a95f5b1ce013a4cfcab25b94b2e64a23034e4250a7eab"
404       "43c0df3a8c12993af12b111908d4b471bec31d4b6c9ad9cdda90612a2ee903523e6de5a2"
405       "24d6b02f09e5c374d0cfe01d8f529c500a78a2f67908fa682b5a2b430c81eaf1af72d7b5"
406       "e794fc98a3139276879757ce453b526ef9bf6ceb99979b8423b90f4461a22af37aab0cf5"
407       "733f7597abe44d31c732db68a181c6cbbe607d8c0e52e0655fd9996dc584eca0be87afbc"
408       "d78a337d17b1dba9e828bbd81e291317144e7ff89f55619709b096cbb9ea474cead264c2"
409       "073fe49740c01f00e109106066983d21e5f83f086e2e823c879cd43cef700d2a352a9bab"
410       "d612d03cad02db134b7e225a5f0203010001",
411       &expected_der_encoding));
412 
413   EXPECT_EQ(result, expected_der_encoding);
414 }
415 
416 using CreateTestKeyPairFunction = std::pair<
417     anonymous_tokens::TestRsaPublicKey, anonymous_tokens::TestRsaPrivateKey>();
418 
419 class CryptoUtilsTest
420     : public testing::TestWithParam<CreateTestKeyPairFunction*> {
421  protected:
SetUp()422   void SetUp() override {
423     const auto [_, private_key] = (*GetParam())();
424     private_key_ = private_key;
425 
426     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_modulus_,
427                                      StringToBignum(private_key_.n));
428     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_e_, StringToBignum(private_key_.e));
429     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_p_, StringToBignum(private_key_.p));
430     ANON_TOKENS_ASSERT_OK_AND_ASSIGN(rsa_q_, StringToBignum(private_key_.q));
431   }
432 
433   TestRsaPrivateKey private_key_;
434 
435   bssl::UniquePtr<BIGNUM> rsa_modulus_;
436   bssl::UniquePtr<BIGNUM> rsa_e_;
437   bssl::UniquePtr<BIGNUM> rsa_p_;
438   bssl::UniquePtr<BIGNUM> rsa_q_;
439 };
440 
TEST_P(CryptoUtilsTest,PublicExponentCoprime)441 TEST_P(CryptoUtilsTest, PublicExponentCoprime) {
442   std::string metadata = "md";
443   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
444       bssl::UniquePtr<BIGNUM> exp,
445       ComputeExponentWithPublicMetadata(*rsa_modulus_.get(), metadata));
446   int rsa_mod_size_bits = BN_num_bits(rsa_modulus_.get());
447   // Check that exponent is odd.
448   EXPECT_EQ(BN_is_odd(exp.get()), 1);
449   // Check that exponent is small enough.
450   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> sqrt2,
451                                    GetRsaSqrtTwo(rsa_mod_size_bits / 2));
452   EXPECT_LT(BN_cmp(exp.get(), sqrt2.get()), 0);
453   EXPECT_LT(BN_cmp(exp.get(), rsa_p_.get()), 0);
454   EXPECT_LT(BN_cmp(exp.get(), rsa_q_.get()), 0);
455 }
456 
TEST_P(CryptoUtilsTest,PublicExponentHash)457 TEST_P(CryptoUtilsTest, PublicExponentHash) {
458   std::string metadata1 = "md1";
459   std::string metadata2 = "md2";
460   // Check that hash is deterministic.
461   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
462       bssl::UniquePtr<BIGNUM> exp1,
463       ComputeExponentWithPublicMetadata(*rsa_modulus_.get(), metadata1));
464   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
465       bssl::UniquePtr<BIGNUM> another_exp1,
466       ComputeExponentWithPublicMetadata(*rsa_modulus_.get(), metadata1));
467   EXPECT_EQ(BN_cmp(exp1.get(), another_exp1.get()), 0);
468   // Check that hashes are distinct for different metadata.
469   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
470       bssl::UniquePtr<BIGNUM> exp2,
471       ComputeExponentWithPublicMetadata(*rsa_modulus_.get(), metadata2));
472   EXPECT_NE(BN_cmp(exp1.get(), exp2.get()), 0);
473 }
474 
TEST_P(CryptoUtilsTest,FinalExponentCoprime)475 TEST_P(CryptoUtilsTest, FinalExponentCoprime) {
476   std::string metadata = "md";
477   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
478       bssl::UniquePtr<BIGNUM> final_exponent,
479       ComputeExponentWithPublicMetadataAndPublicExponent(
480           *rsa_modulus_.get(), *rsa_e_.get(), metadata));
481   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(BnCtxPtr ctx, GetAndStartBigNumCtx());
482 
483   // Check that exponent is odd.
484   EXPECT_EQ(BN_is_odd(final_exponent.get()), 1);
485   // Check that exponent is co-prime to factors of the rsa modulus.
486   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> gcd_p_fe,
487                                    NewBigNum());
488   ASSERT_EQ(
489       BN_gcd(gcd_p_fe.get(), rsa_p_.get(), final_exponent.get(), ctx.get()), 1);
490   EXPECT_EQ(BN_cmp(gcd_p_fe.get(), BN_value_one()), 0);
491   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<BIGNUM> gcd_q_fe,
492                                    NewBigNum());
493   ASSERT_EQ(
494       BN_gcd(gcd_q_fe.get(), rsa_q_.get(), final_exponent.get(), ctx.get()), 1);
495   EXPECT_EQ(BN_cmp(gcd_q_fe.get(), BN_value_one()), 0);
496 }
497 
TEST_P(CryptoUtilsTest,DeterministicModificationOfPublicExponentWithMetadata)498 TEST_P(CryptoUtilsTest, DeterministicModificationOfPublicExponentWithMetadata) {
499   std::string metadata = "md";
500   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
501       bssl::UniquePtr<BIGNUM> public_exp_1,
502       ComputeExponentWithPublicMetadataAndPublicExponent(
503           *rsa_modulus_.get(), *rsa_e_.get(), metadata));
504   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
505       bssl::UniquePtr<BIGNUM> public_exp_2,
506       ComputeExponentWithPublicMetadataAndPublicExponent(
507           *rsa_modulus_.get(), *rsa_e_.get(), metadata));
508 
509   EXPECT_EQ(BN_cmp(public_exp_1.get(), public_exp_2.get()), 0);
510 }
511 
TEST_P(CryptoUtilsTest,DifferentPublicExponentWithDifferentPublicMetadata)512 TEST_P(CryptoUtilsTest, DifferentPublicExponentWithDifferentPublicMetadata) {
513   std::string metadata_1 = "md1";
514   std::string metadata_2 = "md2";
515   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
516       bssl::UniquePtr<BIGNUM> public_exp_1,
517       ComputeExponentWithPublicMetadataAndPublicExponent(
518           *rsa_modulus_.get(), *rsa_e_.get(), metadata_1));
519   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
520       bssl::UniquePtr<BIGNUM> public_exp_2,
521       ComputeExponentWithPublicMetadataAndPublicExponent(
522           *rsa_modulus_.get(), *rsa_e_.get(), metadata_2));
523   // Check that exponent is different in all keys
524   EXPECT_NE(BN_cmp(public_exp_1.get(), public_exp_2.get()), 0);
525   EXPECT_NE(BN_cmp(public_exp_1.get(), rsa_e_.get()), 0);
526   EXPECT_NE(BN_cmp(public_exp_2.get(), rsa_e_.get()), 0);
527 }
528 
TEST_P(CryptoUtilsTest,ModifiedPublicExponentWithEmptyPublicMetadata)529 TEST_P(CryptoUtilsTest, ModifiedPublicExponentWithEmptyPublicMetadata) {
530   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(
531       bssl::UniquePtr<BIGNUM> new_public_exp,
532       ComputeExponentWithPublicMetadataAndPublicExponent(*rsa_modulus_.get(),
533                                                          *rsa_e_.get(), ""));
534 
535   EXPECT_NE(BN_cmp(new_public_exp.get(), rsa_e_.get()), 0);
536 }
537 
TEST_P(CryptoUtilsTest,CreateRsaPublicKeyWithPublicMetadataSuccessfully)538 TEST_P(CryptoUtilsTest, CreateRsaPublicKeyWithPublicMetadataSuccessfully) {
539   std::string metadata = "md";
540   // Key derived using the public exponent, modulus and public metadata.
541   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<RSA> rsa_public_key,
542                                    CreatePublicKeyRSAWithPublicMetadata(
543                                        private_key_.n, private_key_.e, metadata,
544                                        /*use_rsa_public_exponent=*/true));
545   // Key derived using only the modulus and public metadata.
546   ANON_TOKENS_ASSERT_OK_AND_ASSIGN(bssl::UniquePtr<RSA> rsa_public_key_2,
547                                    CreatePublicKeyRSAWithPublicMetadata(
548                                        private_key_.n, private_key_.e, metadata,
549                                        /*use_rsa_public_exponent=*/false));
550 
551   EXPECT_EQ(BN_cmp(RSA_get0_n(rsa_public_key.get()), rsa_modulus_.get()), 0);
552   EXPECT_EQ(BN_cmp(RSA_get0_n(rsa_public_key_2.get()), rsa_modulus_.get()), 0);
553 
554   EXPECT_NE(BN_cmp(RSA_get0_e(rsa_public_key.get()), rsa_e_.get()), 0);
555   EXPECT_NE(BN_cmp(RSA_get0_e(rsa_public_key_2.get()), rsa_e_.get()), 0);
556   EXPECT_NE(BN_cmp(RSA_get0_e(rsa_public_key.get()),
557                    RSA_get0_e(rsa_public_key_2.get())),
558             0);
559 }
560 
561 INSTANTIATE_TEST_SUITE_P(CryptoUtilsTest, CryptoUtilsTest,
562                          testing::Values(&GetStrongTestRsaKeyPair2048,
563                                          &GetAnotherStrongTestRsaKeyPair2048,
564                                          &GetStrongTestRsaKeyPair3072,
565                                          &GetStrongTestRsaKeyPair4096));
566 
567 }  // namespace
568 }  // namespace anonymous_tokens
569