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