xref: /aosp_15_r20/external/anonymous-counting-tokens/act/act_v0/act_v0_test.cc (revision a26f13018b999b025c962678da434c0a5aec4dae)
1 /*
2  * Copyright 2023 Google LLC.
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 
16 #include "act/act_v0/act_v0.h"
17 
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 
21 #include <memory>
22 #include <string>
23 #include <utility>
24 #include <vector>
25 
26 #include "act/act.h"
27 #include "act/act.pb.h"
28 #include "act/act_v0/act_v0.pb.h"
29 #include "act/act_v0/parameters.h"
30 #include "private_join_and_compute/crypto/camenisch_shoup.h"
31 #include "private_join_and_compute/crypto/context.h"
32 #include "private_join_and_compute/crypto/dodis_yampolskiy_prf/bb_oblivious_signature.pb.h"
33 #include "private_join_and_compute/crypto/dodis_yampolskiy_prf/dy_verifiable_random_function.pb.h"
34 #include "private_join_and_compute/crypto/ec_group.h"
35 #include "private_join_and_compute/crypto/ec_point.h"
36 #include "private_join_and_compute/crypto/pedersen_over_zn.h"
37 #include "private_join_and_compute/crypto/proto/big_num.pb.h"
38 #include "private_join_and_compute/crypto/proto/camenisch_shoup.pb.h"
39 #include "private_join_and_compute/crypto/proto/pedersen.pb.h"
40 #include "private_join_and_compute/util/status.inc"
41 #include "private_join_and_compute/util/status_testing.inc"
42 
43 namespace private_join_and_compute {
44 namespace anonymous_counting_tokens {
45 namespace {
46 
47 using ::testing::HasSubstr;
48 using testing::StatusIs;
49 
50 const int kTestCurveId = NID_X9_62_prime256v1;
51 
52 class AnonymousCountingTokensV0Test : public ::testing::Test {
53  protected:
GetRandomOraclePrefix()54   static std::string GetRandomOraclePrefix() {
55     return "TestRandomOraclePrefix";
56   }
57 
GetSchemeParameters()58   static SchemeParameters GetSchemeParameters() {
59     return ActV0TestSchemeParameters();
60   }
61 
SetUpTestSuite()62   static void SetUpTestSuite() {
63     std::unique_ptr<AnonymousCountingTokens> act =
64         AnonymousCountingTokensV0::Create();
65     ServerParameters server_parameters_temp =
66         act->GenerateServerParameters(GetSchemeParameters()).value();
67     server_parameters_ = new ServerParameters(server_parameters_temp);
68   }
69 
TearDownTestSuite()70   static void TearDownTestSuite() { delete server_parameters_; }
71 
SetUp()72   void SetUp() override {
73     anonymous_counting_tokens_ = AnonymousCountingTokensV0::Create();
74 
75     ASSERT_OK_AND_ASSIGN(auto ec_group_do_not_use_later,
76                          ECGroup::Create(kTestCurveId, &ctx_));
77     ec_group_ = std::make_unique<ECGroup>(std::move(ec_group_do_not_use_later));
78 
79     // Deserialize components of the precomputed server parameters.
80     ASSERT_OK_AND_ASSIGN(PedersenOverZn::Parameters pedersen_parameters,
81                          PedersenOverZn::ParseParametersProto(
82                              &ctx_, server_parameters_->public_parameters()
83                                         .server_public_parameters_v0()
84                                         .pedersen_parameters()));
85     ASSERT_OK_AND_ASSIGN(
86         pedersen_,
87         PedersenOverZn::Create(&ctx_, pedersen_parameters.gs,
88                                pedersen_parameters.h, pedersen_parameters.n));
89 
90     dy_prf_base_g_ = std::make_unique<ECPoint>(
91         ec_group_
92             ->CreateECPoint(server_parameters_->public_parameters()
93                                 .server_public_parameters_v0()
94                                 .prf_base_g())
95             .value());
96 
97     cs_public_key_ = std::make_unique<CamenischShoupPublicKey>(
98         ParseCamenischShoupPublicKeyProto(
99             &ctx_, server_parameters_->public_parameters()
100                        .server_public_parameters_v0()
101                        .camenisch_shoup_public_key())
102             .value());
103     cs_private_key_ = std::make_unique<CamenischShoupPrivateKey>(
104         ParseCamenischShoupPrivateKeyProto(
105             &ctx_, server_parameters_->private_parameters()
106                        .server_private_parameters_v0()
107                        .camenisch_shoup_private_key())
108             .value());
109 
110     public_camenisch_shoup_ = std::make_unique<PublicCamenischShoup>(
111         &ctx_, cs_public_key_->n, cs_public_key_->s, cs_public_key_->g,
112         cs_public_key_->ys);
113     private_camenisch_shoup_ = std::make_unique<PrivateCamenischShoup>(
114         &ctx_, cs_public_key_->n, cs_public_key_->s, cs_public_key_->g,
115         cs_public_key_->ys, cs_private_key_->xs);
116 
117     ASSERT_OK_AND_ASSIGN(
118         client_parameters_,
119         anonymous_counting_tokens_->GenerateClientParameters(
120             GetSchemeParameters(), server_parameters_->public_parameters()));
121   }
122 
123   // Holds a transcript for an EndToEnd request.
124   struct Transcript {
125     std::vector<std::string> fingerprints;
126     TokensRequest tokens_request;
127     TokensRequestPrivateState tokens_request_private_state;
128     TokensResponse tokens_response;
129     std::vector<Token> tokens;
130   };
131 
132   // Generates an end-to-end request transcript. Does not verify request or
133   // response proofs.
GenerateTranscript(absl::Span<const std::string> messages)134   StatusOr<Transcript> GenerateTranscript(
135       absl::Span<const std::string> messages) {
136     Transcript transcript;
137     ASSIGN_OR_RETURN(
138         std::tie(transcript.fingerprints, transcript.tokens_request,
139                  transcript.tokens_request_private_state),
140         anonymous_counting_tokens_->GenerateTokensRequest(
141             messages, GetSchemeParameters(),
142             client_parameters_.public_parameters(),
143             client_parameters_.private_parameters(),
144             server_parameters_->public_parameters()));
145 
146     ASSIGN_OR_RETURN(transcript.tokens_response,
147                      anonymous_counting_tokens_->GenerateTokensResponse(
148                          transcript.tokens_request, GetSchemeParameters(),
149                          client_parameters_.public_parameters(),
150                          server_parameters_->public_parameters(),
151                          server_parameters_->private_parameters()));
152 
153     ASSIGN_OR_RETURN(
154         transcript.tokens,
155         anonymous_counting_tokens_->RecoverTokens(
156             messages, transcript.tokens_request,
157             transcript.tokens_request_private_state, transcript.tokens_response,
158             GetSchemeParameters(), client_parameters_.public_parameters(),
159             client_parameters_.private_parameters(),
160             server_parameters_->public_parameters()));
161 
162     return std::move(transcript);
163   }
164 
165   // Server Parameters, generated once and available to be reused across tests
166   // to save expensive safe modulus computation.
167   static ServerParameters* server_parameters_;
168 
169   // Instance of AnonymousCountingTokensV0.
170   std::unique_ptr<AnonymousCountingTokens> anonymous_counting_tokens_;
171 
172   Context ctx_;
173   std::unique_ptr<ECGroup> ec_group_;
174 
175   // Deserialized objects from the saved serialized parameters above.
176   std::unique_ptr<PedersenOverZn> pedersen_;
177   std::unique_ptr<ECPoint> dy_prf_base_g_;
178   std::unique_ptr<CamenischShoupPublicKey> cs_public_key_;
179   std::unique_ptr<CamenischShoupPrivateKey> cs_private_key_;
180   std::unique_ptr<PublicCamenischShoup> public_camenisch_shoup_;
181   std::unique_ptr<PrivateCamenischShoup> private_camenisch_shoup_;
182 
183   // Client parameters for AnonymousCountingTokensV0.
184   ClientParameters client_parameters_;
185 };
186 
187 ServerParameters* AnonymousCountingTokensV0Test::server_parameters_ = nullptr;
188 
TEST_F(AnonymousCountingTokensV0Test,ServerParametersHasNonEmptyFields)189 TEST_F(AnonymousCountingTokensV0Test, ServerParametersHasNonEmptyFields) {
190   // Expect all fields are nonempty.
191   EXPECT_TRUE(server_parameters_->has_public_parameters());
192   EXPECT_TRUE(server_parameters_->public_parameters()
193                   .has_server_public_parameters_v0());
194   EXPECT_FALSE(server_parameters_->public_parameters()
195                    .server_public_parameters_v0()
196                    .prf_base_g()
197                    .empty());
198   EXPECT_TRUE(server_parameters_->public_parameters()
199                   .server_public_parameters_v0()
200                   .has_pedersen_parameters());
201   EXPECT_TRUE(server_parameters_->public_parameters()
202                   .server_public_parameters_v0()
203                   .has_camenisch_shoup_public_key());
204   EXPECT_TRUE(server_parameters_->public_parameters()
205                   .server_public_parameters_v0()
206                   .has_bb_oblivious_signature_public_key());
207 
208   EXPECT_TRUE(server_parameters_->has_private_parameters());
209   EXPECT_TRUE(server_parameters_->private_parameters()
210                   .has_server_private_parameters_v0());
211   EXPECT_TRUE(server_parameters_->private_parameters()
212                   .server_private_parameters_v0()
213                   .has_camenisch_shoup_private_key());
214   EXPECT_TRUE(server_parameters_->private_parameters()
215                   .server_private_parameters_v0()
216                   .has_bb_oblivious_signature_private_key());
217 }
218 
TEST_F(AnonymousCountingTokensV0Test,GeneratesDifferentServerParameters)219 TEST_F(AnonymousCountingTokensV0Test, GeneratesDifferentServerParameters) {
220   ASSERT_OK_AND_ASSIGN(ServerParameters other_server_parameters,
221                        anonymous_counting_tokens_->GenerateServerParameters(
222                            GetSchemeParameters()));
223 
224   // Expect all fields in the public parameters are different across the 2
225   // keys.
226   EXPECT_NE(server_parameters_->public_parameters()
227                 .server_public_parameters_v0()
228                 .prf_base_g(),
229             other_server_parameters.public_parameters()
230                 .server_public_parameters_v0()
231                 .prf_base_g());
232   EXPECT_NE(server_parameters_->public_parameters()
233                 .server_public_parameters_v0()
234                 .pedersen_parameters()
235                 .gs()
236                 .serialized_big_nums(0),
237             other_server_parameters.public_parameters()
238                 .server_public_parameters_v0()
239                 .pedersen_parameters()
240                 .gs()
241                 .serialized_big_nums(0));
242   EXPECT_NE(server_parameters_->public_parameters()
243                 .server_public_parameters_v0()
244                 .camenisch_shoup_public_key()
245                 .ys()
246                 .serialized_big_nums(0),
247             other_server_parameters.public_parameters()
248                 .server_public_parameters_v0()
249                 .camenisch_shoup_public_key()
250                 .ys()
251                 .serialized_big_nums(0));
252   EXPECT_NE(server_parameters_->public_parameters()
253                 .server_public_parameters_v0()
254                 .bb_oblivious_signature_public_key()
255                 .encrypted_k(0)
256                 .u(),
257             other_server_parameters.public_parameters()
258                 .server_public_parameters_v0()
259                 .bb_oblivious_signature_public_key()
260                 .encrypted_k(0)
261                 .u());
262   EXPECT_NE(server_parameters_->public_parameters()
263                 .server_public_parameters_v0()
264                 .bb_oblivious_signature_public_key()
265                 .encrypted_y(0)
266                 .u(),
267             other_server_parameters.public_parameters()
268                 .server_public_parameters_v0()
269                 .bb_oblivious_signature_public_key()
270                 .encrypted_y(0)
271                 .u());
272 }
273 
TEST_F(AnonymousCountingTokensV0Test,ClientParametersHaveValidFields)274 TEST_F(AnonymousCountingTokensV0Test, ClientParametersHaveValidFields) {
275   EXPECT_TRUE(client_parameters_.has_public_parameters());
276   EXPECT_TRUE(
277       client_parameters_.public_parameters().has_client_public_parameters_v0());
278   EXPECT_TRUE(client_parameters_.public_parameters()
279                   .client_public_parameters_v0()
280                   .has_dy_vrf_public_key());
281 
282   EXPECT_TRUE(client_parameters_.has_private_parameters());
283   EXPECT_TRUE(client_parameters_.private_parameters()
284                   .has_client_private_parameters_v0());
285   EXPECT_TRUE(client_parameters_.private_parameters()
286                   .client_private_parameters_v0()
287                   .has_dy_vrf_private_key());
288 }
289 
TEST_F(AnonymousCountingTokensV0Test,GeneratesDifferentClientParameters)290 TEST_F(AnonymousCountingTokensV0Test, GeneratesDifferentClientParameters) {
291   ASSERT_OK_AND_ASSIGN(
292       ClientParameters other_client_parameters,
293       anonymous_counting_tokens_->GenerateClientParameters(
294           GetSchemeParameters(), server_parameters_->public_parameters()));
295 
296   EXPECT_NE(client_parameters_.public_parameters()
297                 .client_public_parameters_v0()
298                 .dy_vrf_public_key()
299                 .commit_prf_key(),
300             other_client_parameters.public_parameters()
301                 .client_public_parameters_v0()
302                 .dy_vrf_public_key()
303                 .commit_prf_key());
304 }
305 
TEST_F(AnonymousCountingTokensV0Test,ProofFromOtherClientParametersFails)306 TEST_F(AnonymousCountingTokensV0Test, ProofFromOtherClientParametersFails) {
307   ASSERT_OK_AND_ASSIGN(
308       ClientParameters other_client_parameters,
309       anonymous_counting_tokens_->GenerateClientParameters(
310           GetSchemeParameters(), server_parameters_->public_parameters()));
311 
312   *client_parameters_.mutable_public_parameters()
313        ->mutable_client_public_parameters_v0()
314        ->mutable_dy_vrf_generate_keys_proof() =
315       other_client_parameters.public_parameters()
316           .client_public_parameters_v0()
317           .dy_vrf_generate_keys_proof();
318 
319   EXPECT_THAT(
320       anonymous_counting_tokens_->CheckClientParameters(
321           GetSchemeParameters(), client_parameters_.public_parameters(),
322           server_parameters_->public_parameters(),
323           server_parameters_->private_parameters()),
324       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("Failed")));
325 }
326 
TEST_F(AnonymousCountingTokensV0Test,ClientParametersPassCheck)327 TEST_F(AnonymousCountingTokensV0Test, ClientParametersPassCheck) {
328   EXPECT_OK(anonymous_counting_tokens_->CheckClientParameters(
329       GetSchemeParameters(), client_parameters_.public_parameters(),
330       server_parameters_->public_parameters(),
331       server_parameters_->private_parameters()));
332 }
333 
TEST_F(AnonymousCountingTokensV0Test,ClientParametersWithoutActV0FailCheck)334 TEST_F(AnonymousCountingTokensV0Test, ClientParametersWithoutActV0FailCheck) {
335   client_parameters_.mutable_public_parameters()
336       ->clear_client_public_parameters_v0();
337 
338   EXPECT_THAT(anonymous_counting_tokens_->CheckClientParameters(
339                   GetSchemeParameters(), client_parameters_.public_parameters(),
340                   server_parameters_->public_parameters(),
341                   server_parameters_->private_parameters()),
342               StatusIs(absl::StatusCode::kInvalidArgument,
343                        HasSubstr("CheckClientParameters")));
344 }
345 
TEST_F(AnonymousCountingTokensV0Test,EmptyClientParametersProofFailsCheck)346 TEST_F(AnonymousCountingTokensV0Test, EmptyClientParametersProofFailsCheck) {
347   client_parameters_.mutable_public_parameters()
348       ->mutable_client_public_parameters_v0()
349       ->clear_dy_vrf_generate_keys_proof();
350 
351   EXPECT_THAT(
352       anonymous_counting_tokens_->CheckClientParameters(
353           GetSchemeParameters(), client_parameters_.public_parameters(),
354           server_parameters_->public_parameters(),
355           server_parameters_->private_parameters()),
356       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("Failed")));
357 }
358 
TEST_F(AnonymousCountingTokensV0Test,GeneratesTokenRequest)359 TEST_F(AnonymousCountingTokensV0Test, GeneratesTokenRequest) {
360   EXPECT_OK(anonymous_counting_tokens_->GenerateTokensRequest(
361       {"message_0", "message_1", "message_2"}, GetSchemeParameters(),
362       client_parameters_.public_parameters(),
363       client_parameters_.private_parameters(),
364       server_parameters_->public_parameters()));
365 }
366 
TEST_F(AnonymousCountingTokensV0Test,FingerprintsMatchOnlyForEqualMessages)367 TEST_F(AnonymousCountingTokensV0Test, FingerprintsMatchOnlyForEqualMessages) {
368   std::vector<std::string> fingerprints_1;
369   ASSERT_OK_AND_ASSIGN(
370       std::tie(fingerprints_1, std::ignore, std::ignore),
371       anonymous_counting_tokens_->GenerateTokensRequest(
372           {"message_0", "message_1", "message_2"}, GetSchemeParameters(),
373           client_parameters_.public_parameters(),
374           client_parameters_.private_parameters(),
375           server_parameters_->public_parameters()));
376 
377   std::vector<std::string> fingerprints_2;
378   ASSERT_OK_AND_ASSIGN(
379       std::tie(fingerprints_2, std::ignore, std::ignore),
380       anonymous_counting_tokens_->GenerateTokensRequest(
381           {"message_2", "message_3", "message_4"}, GetSchemeParameters(),
382           client_parameters_.public_parameters(),
383           client_parameters_.private_parameters(),
384           server_parameters_->public_parameters()));
385 
386   // Fingerprints should be equal only for "message_2".
387   EXPECT_EQ(fingerprints_1[2], fingerprints_2[0]);
388 
389   for (size_t i = 1; i < fingerprints_1.size(); ++i) {
390     for (size_t j = 0; j < fingerprints_2.size(); ++j) {
391       if (!(i == 2 && j == 0)) {
392         EXPECT_NE(fingerprints_1[i], fingerprints_2[j]);
393       }
394     }
395   }
396 }
397 
TEST_F(AnonymousCountingTokensV0Test,TokensRequestIsValid)398 TEST_F(AnonymousCountingTokensV0Test, TokensRequestIsValid) {
399   std::vector<std::string> messages = {"message_1", "message_2", "message_3"};
400   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
401   EXPECT_OK(anonymous_counting_tokens_->CheckTokensRequest(
402       transcript.fingerprints, transcript.tokens_request, GetSchemeParameters(),
403       client_parameters_.public_parameters(),
404       server_parameters_->public_parameters(),
405       server_parameters_->private_parameters()));
406 }
407 
TEST_F(AnonymousCountingTokensV0Test,TokensRequestProofFailsWithDifferentFingerprints)408 TEST_F(AnonymousCountingTokensV0Test,
409        TokensRequestProofFailsWithDifferentFingerprints) {
410   std::vector<std::string> messages_1 = {"message_1", "message_2", "message_3"};
411   ASSERT_OK_AND_ASSIGN(Transcript transcript_1, GenerateTranscript(messages_1));
412   std::vector<std::string> messages_2 = {"message_4", "message_5", "message_6"};
413   ASSERT_OK_AND_ASSIGN(Transcript transcript_2, GenerateTranscript(messages_2));
414   // fingerprints from the second transcript should not allow the proof to
415   // verify.
416   EXPECT_THAT(
417       anonymous_counting_tokens_->CheckTokensRequest(
418           transcript_2.fingerprints, transcript_1.tokens_request,
419           GetSchemeParameters(), client_parameters_.public_parameters(),
420           server_parameters_->public_parameters(),
421           server_parameters_->private_parameters()),
422       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("failed")));
423 }
424 
TEST_F(AnonymousCountingTokensV0Test,TokensRequestProofFailsWithWrongNumberOfFingerprints)425 TEST_F(AnonymousCountingTokensV0Test,
426        TokensRequestProofFailsWithWrongNumberOfFingerprints) {
427   std::vector<std::string> messages = {"message_1", "message_2", "message_3"};
428   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
429   // delete one of the fingerprints.
430   transcript.fingerprints.pop_back();
431   EXPECT_THAT(
432       anonymous_counting_tokens_->CheckTokensRequest(
433           transcript.fingerprints, transcript.tokens_request,
434           GetSchemeParameters(), client_parameters_.public_parameters(),
435           server_parameters_->public_parameters(),
436           server_parameters_->private_parameters()),
437       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("Number")));
438 }
439 
TEST_F(AnonymousCountingTokensV0Test,BbSignatureRequestFromDifferentTranscriptIsInvalid)440 TEST_F(AnonymousCountingTokensV0Test,
441        BbSignatureRequestFromDifferentTranscriptIsInvalid) {
442   std::vector<std::string> messages = {"message_1", "message_2", "message_3"};
443   ASSERT_OK_AND_ASSIGN(Transcript transcript_1, GenerateTranscript(messages));
444   ASSERT_OK_AND_ASSIGN(Transcript transcript_2, GenerateTranscript(messages));
445   // Replace the bb oblivious signature request from the first transcript with
446   // that from the second.
447   *transcript_1.tokens_request.mutable_tokens_request_v0()
448        ->mutable_bb_oblivious_signature_request() =
449       transcript_2.tokens_request.tokens_request_v0()
450           .bb_oblivious_signature_request();
451   EXPECT_THAT(
452       anonymous_counting_tokens_->CheckTokensRequest(
453           transcript_1.fingerprints, transcript_1.tokens_request,
454           GetSchemeParameters(), client_parameters_.public_parameters(),
455           server_parameters_->public_parameters(),
456           server_parameters_->private_parameters()),
457       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("Failed")));
458 }
459 
TEST_F(AnonymousCountingTokensV0Test,FingerprintsProofFromDifferentTranscriptIsInvalid)460 TEST_F(AnonymousCountingTokensV0Test,
461        FingerprintsProofFromDifferentTranscriptIsInvalid) {
462   std::vector<std::string> messages = {"message_1", "message_2", "message_3"};
463   ASSERT_OK_AND_ASSIGN(Transcript transcript_1, GenerateTranscript(messages));
464   ASSERT_OK_AND_ASSIGN(Transcript transcript_2, GenerateTranscript(messages));
465   // Replace the fingerprints proof from the first transcript with
466   // that from the second.
467   *transcript_1.tokens_request.mutable_tokens_request_v0()
468        ->mutable_part_1()
469        ->mutable_fingerprints_proof() =
470       transcript_2.tokens_request.tokens_request_v0()
471           .part_1()
472           .fingerprints_proof();
473   EXPECT_THAT(
474       anonymous_counting_tokens_->CheckTokensRequest(
475           transcript_1.fingerprints, transcript_1.tokens_request,
476           GetSchemeParameters(), client_parameters_.public_parameters(),
477           server_parameters_->public_parameters(),
478           server_parameters_->private_parameters()),
479       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("failed")));
480 }
481 
TEST_F(AnonymousCountingTokensV0Test,BbSignatureRequestProofFromDifferentTranscriptIsInvalid)482 TEST_F(AnonymousCountingTokensV0Test,
483        BbSignatureRequestProofFromDifferentTranscriptIsInvalid) {
484   std::vector<std::string> messages = {"message_1", "message_2", "message_3"};
485   ASSERT_OK_AND_ASSIGN(Transcript transcript_1, GenerateTranscript(messages));
486   ASSERT_OK_AND_ASSIGN(Transcript transcript_2, GenerateTranscript(messages));
487   // Replace the bb signature request proof from the first transcript with
488   // that from the second.
489   *transcript_1.tokens_request.mutable_tokens_request_v0()
490        ->mutable_bb_oblivious_signature_request_proof() =
491       transcript_2.tokens_request.tokens_request_v0()
492           .bb_oblivious_signature_request_proof();
493   EXPECT_THAT(
494       anonymous_counting_tokens_->CheckTokensRequest(
495           transcript_1.fingerprints, transcript_1.tokens_request,
496           GetSchemeParameters(), client_parameters_.public_parameters(),
497           server_parameters_->public_parameters(),
498           server_parameters_->private_parameters()),
499       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("Failed")));
500 }
501 
TEST_F(AnonymousCountingTokensV0Test,EmptyRequestIsInvalid)502 TEST_F(AnonymousCountingTokensV0Test, EmptyRequestIsInvalid) {
503   std::vector<std::string> messages = {"message_1", "message_2", "message_3"};
504   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
505   transcript.tokens_request.clear_tokens_request_v0();
506   EXPECT_THAT(anonymous_counting_tokens_->CheckTokensRequest(
507                   transcript.fingerprints, transcript.tokens_request,
508                   GetSchemeParameters(), client_parameters_.public_parameters(),
509                   server_parameters_->public_parameters(),
510                   server_parameters_->private_parameters()),
511               StatusIs(absl::StatusCode::kInvalidArgument,
512                        HasSubstr("supplied parameters")));
513 }
514 
TEST_F(AnonymousCountingTokensV0Test,RequestWithoutFingerprintsProofIsInvalid)515 TEST_F(AnonymousCountingTokensV0Test,
516        RequestWithoutFingerprintsProofIsInvalid) {
517   std::vector<std::string> messages = {"message_1", "message_2", "message_3"};
518   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
519   transcript.tokens_request.mutable_tokens_request_v0()
520       ->mutable_part_1()
521       ->clear_fingerprints_proof();
522   EXPECT_THAT(
523       anonymous_counting_tokens_->CheckTokensRequest(
524           transcript.fingerprints, transcript.tokens_request,
525           GetSchemeParameters(), client_parameters_.public_parameters(),
526           server_parameters_->public_parameters(),
527           server_parameters_->private_parameters()),
528       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("Number")));
529 }
530 
TEST_F(AnonymousCountingTokensV0Test,RequestWithoutBbSignatureRequestProofIsInvalid)531 TEST_F(AnonymousCountingTokensV0Test,
532        RequestWithoutBbSignatureRequestProofIsInvalid) {
533   std::vector<std::string> messages = {"message_1", "message_2", "message_3"};
534   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
535   transcript.tokens_request.mutable_tokens_request_v0()
536       ->clear_bb_oblivious_signature_request_proof();
537   EXPECT_THAT(
538       anonymous_counting_tokens_->CheckTokensRequest(
539           transcript.fingerprints, transcript.tokens_request,
540           GetSchemeParameters(), client_parameters_.public_parameters(),
541           server_parameters_->public_parameters(),
542           server_parameters_->private_parameters()),
543       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("number")));
544 }
545 
TEST_F(AnonymousCountingTokensV0Test,GeneratesTokenResponse)546 TEST_F(AnonymousCountingTokensV0Test, GeneratesTokenResponse) {
547   TokensRequest tokens_request;
548   ASSERT_OK_AND_ASSIGN(
549       std::tie(std::ignore, tokens_request, std::ignore),
550       anonymous_counting_tokens_->GenerateTokensRequest(
551           {"message_0", "message_1", "message_2"}, GetSchemeParameters(),
552           client_parameters_.public_parameters(),
553           client_parameters_.private_parameters(),
554           server_parameters_->public_parameters()));
555 
556   EXPECT_OK(anonymous_counting_tokens_->GenerateTokensResponse(
557       tokens_request, GetSchemeParameters(),
558       client_parameters_.public_parameters(),
559       server_parameters_->public_parameters(),
560       server_parameters_->private_parameters()));
561 }
562 
TEST_F(AnonymousCountingTokensV0Test,TokensResponseIsValid)563 TEST_F(AnonymousCountingTokensV0Test, TokensResponseIsValid) {
564   std::vector<std::string> messages = {"message_1", "message_2", "message_3"};
565   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
566   EXPECT_OK(anonymous_counting_tokens_->VerifyTokensResponse(
567       messages, transcript.tokens_request,
568       transcript.tokens_request_private_state, transcript.tokens_response,
569       GetSchemeParameters(), client_parameters_.public_parameters(),
570       client_parameters_.private_parameters(),
571       server_parameters_->public_parameters()));
572 }
573 
TEST_F(AnonymousCountingTokensV0Test,TokensResponseIsInvalidForProofFromAnotherTranscript)574 TEST_F(AnonymousCountingTokensV0Test,
575        TokensResponseIsInvalidForProofFromAnotherTranscript) {
576   std::vector<std::string> messages = {"message_1", "message_2", "message_3"};
577   ASSERT_OK_AND_ASSIGN(Transcript transcript_1, GenerateTranscript(messages));
578   ASSERT_OK_AND_ASSIGN(Transcript transcript_2, GenerateTranscript(messages));
579   // Put the proof from the second transcript into the first
580   *transcript_1.tokens_response.mutable_tokens_response_v0()
581        ->mutable_bb_oblivious_signature_response_proof() =
582       transcript_2.tokens_response.tokens_response_v0()
583           .bb_oblivious_signature_response_proof();
584   EXPECT_THAT(
585       anonymous_counting_tokens_->VerifyTokensResponse(
586           messages, transcript_1.tokens_request,
587           transcript_1.tokens_request_private_state,
588           transcript_1.tokens_response, GetSchemeParameters(),
589           client_parameters_.public_parameters(),
590           client_parameters_.private_parameters(),
591           server_parameters_->public_parameters()),
592       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("Failed")));
593 }
594 
TEST_F(AnonymousCountingTokensV0Test,TokensResponseIsInvalidForRequestFromAnotherTranscript)595 TEST_F(AnonymousCountingTokensV0Test,
596        TokensResponseIsInvalidForRequestFromAnotherTranscript) {
597   std::vector<std::string> messages = {"message_1", "message_2", "message_3"};
598   ASSERT_OK_AND_ASSIGN(Transcript transcript_1, GenerateTranscript(messages));
599   ASSERT_OK_AND_ASSIGN(Transcript transcript_2, GenerateTranscript(messages));
600   // The request and state from transcript_1 should be inconsistent with the
601   // response from transcript_2.
602   EXPECT_THAT(
603       anonymous_counting_tokens_->VerifyTokensResponse(
604           messages, transcript_1.tokens_request,
605           transcript_1.tokens_request_private_state,
606           transcript_2.tokens_response, GetSchemeParameters(),
607           client_parameters_.public_parameters(),
608           client_parameters_.private_parameters(),
609           server_parameters_->public_parameters()),
610       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("Failed")));
611 }
612 
TEST_F(AnonymousCountingTokensV0Test,EmptyResponseShouldBeInvalid)613 TEST_F(AnonymousCountingTokensV0Test, EmptyResponseShouldBeInvalid) {
614   std::vector<std::string> messages = {"message_1", "message_2", "message_3"};
615   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
616 
617   transcript.tokens_response.clear_tokens_response_v0();
618 
619   EXPECT_THAT(
620       anonymous_counting_tokens_->VerifyTokensResponse(
621           messages, transcript.tokens_request,
622           transcript.tokens_request_private_state, transcript.tokens_response,
623           GetSchemeParameters(), client_parameters_.public_parameters(),
624           client_parameters_.private_parameters(),
625           server_parameters_->public_parameters()),
626       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("parameters")));
627 }
628 
TEST_F(AnonymousCountingTokensV0Test,EmptyResponseProofShouldBeInvalid)629 TEST_F(AnonymousCountingTokensV0Test, EmptyResponseProofShouldBeInvalid) {
630   std::vector<std::string> messages = {"message_1", "message_2", "message_3"};
631   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
632 
633   transcript.tokens_response.mutable_tokens_response_v0()
634       ->clear_bb_oblivious_signature_response_proof();
635 
636   EXPECT_THAT(
637       anonymous_counting_tokens_->VerifyTokensResponse(
638           messages, transcript.tokens_request,
639           transcript.tokens_request_private_state, transcript.tokens_response,
640           GetSchemeParameters(), client_parameters_.public_parameters(),
641           client_parameters_.private_parameters(),
642           server_parameters_->public_parameters()),
643       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("number")));
644 }
645 
TEST_F(AnonymousCountingTokensV0Test,ProducesValidTokens)646 TEST_F(AnonymousCountingTokensV0Test, ProducesValidTokens) {
647   std::vector<std::string> messages = {"message_1", "message_2", "message_3"};
648 
649   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
650 
651   EXPECT_EQ(messages.size(), transcript.tokens.size());
652 
653   for (size_t i = 0; i < messages.size(); ++i) {
654     EXPECT_OK(anonymous_counting_tokens_->VerifyToken(
655         messages[i], transcript.tokens[i], GetSchemeParameters(),
656         server_parameters_->public_parameters(),
657         server_parameters_->private_parameters()));
658   }
659 }
660 
TEST_F(AnonymousCountingTokensV0Test,TokensDoNotVerifyWithWrongMessages)661 TEST_F(AnonymousCountingTokensV0Test, TokensDoNotVerifyWithWrongMessages) {
662   std::vector<std::string> messages = {"message_1", "message_2", "message_3"};
663   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
664 
665   for (size_t i = 0; i < messages.size(); ++i) {
666     EXPECT_THAT(
667         anonymous_counting_tokens_->VerifyToken(
668             "wrong_message", transcript.tokens[i], GetSchemeParameters(),
669             server_parameters_->public_parameters(),
670             server_parameters_->private_parameters()),
671         StatusIs(absl::StatusCode::kInvalidArgument,
672                  HasSubstr("fails to match the token")));
673   }
674 }
675 
TEST_F(AnonymousCountingTokensV0Test,TokensHaveUniqueNonces)676 TEST_F(AnonymousCountingTokensV0Test, TokensHaveUniqueNonces) {
677   std::vector<std::string> messages = {"message_1", "message_2"};
678   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
679 
680   EXPECT_NE(transcript.tokens[0].nonce_bytes(),
681             transcript.tokens[1].nonce_bytes());
682 }
683 
684 }  // namespace
685 }  // namespace anonymous_counting_tokens
686 }  // namespace private_join_and_compute
687