• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2019 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 "private_join_and_compute/crypto/dodis_yampolskiy_prf/dy_verifiable_random_function.h"
17 
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 
21 #include <memory>
22 #include <string>
23 #include <tuple>
24 #include <utility>
25 #include <vector>
26 
27 #include "private_join_and_compute/crypto/big_num.h"
28 #include "private_join_and_compute/crypto/dodis_yampolskiy_prf/dy_verifiable_random_function.pb.h"
29 #include "private_join_and_compute/crypto/ec_group.h"
30 #include "private_join_and_compute/crypto/ec_point.h"
31 #include "private_join_and_compute/crypto/pedersen_over_zn.h"
32 #include "private_join_and_compute/crypto/proto/pedersen.pb.h"
33 #include "private_join_and_compute/crypto/proto/proto_util.h"
34 #include "private_join_and_compute/util/status_testing.inc"
35 
36 namespace private_join_and_compute {
37 namespace {
38 
39 using ::testing::Eq;
40 using ::testing::HasSubstr;
41 using testing::IsOkAndHolds;
42 using testing::StatusIs;
43 
44 const int kTestCurveId = NID_X9_62_prime256v1;
45 const int kSafePrimeLengthBits = 600;
46 const int kSecurityParameter = 128;
47 const int kChallengeLengthBits = 128;
48 
49 class DyVerifiableRandomFunctionTest : public ::testing::Test {
50  protected:
SetUpTestSuite()51   static void SetUpTestSuite() {
52     Context ctx;
53     BigNum prime = ctx.GenerateSafePrime(kSafePrimeLengthBits);
54     serialized_safe_prime_ = new std::string(prime.ToBytes());
55   }
56 
TearDownTestSuite()57   static void TearDownTestSuite() { delete serialized_safe_prime_; }
58 
59   struct Transcript {
60     std::vector<ECPoint> prf_evaluations;
61     PedersenOverZn::CommitmentAndOpening commit_and_open_messages;
62     proto::DyVrfApplyProof apply_proof;
63     BigNum challenge;
64   };
65 
SetUp()66   void SetUp() override {
67     ASSERT_OK_AND_ASSIGN(auto ec_group_do_not_use_later,
68                          ECGroup::Create(kTestCurveId, &ctx_));
69     ec_group_ = std::make_unique<ECGroup>(std::move(ec_group_do_not_use_later));
70 
71     // We generate a Pedersen with fixed bases 2, 3, 5 and h=7, and use a random
72     // safe prime as N.
73     std::vector<BigNum> bases = {ctx_.CreateBigNum(2), ctx_.CreateBigNum(3),
74                                  ctx_.CreateBigNum(5)};
75     pedersen_parameters_.set_n(*serialized_safe_prime_);
76     *pedersen_parameters_.mutable_gs() = BigNumVectorToProto(bases);
77     pedersen_parameters_.set_h(ctx_.CreateBigNum(7).ToBytes());
78     ASSERT_OK_AND_ASSIGN(
79         pedersen_, PedersenOverZn::FromProto(&ctx_, pedersen_parameters_));
80 
81     // All other params are set to the defaults.
82     parameters_.set_security_parameter(kSecurityParameter);
83     parameters_.set_challenge_length_bits(kChallengeLengthBits);
84     dy_prf_base_g_ =
85         std::make_unique<ECPoint>(ec_group_->GetRandomGenerator().value());
86     ASSERT_OK_AND_ASSIGN(*parameters_.mutable_dy_prf_base_g(),
87                          dy_prf_base_g_->ToBytesCompressed());
88     *parameters_.mutable_pedersen_parameters() = pedersen_parameters_;
89 
90     ASSERT_OK_AND_ASSIGN(
91         dy_vrf_, DyVerifiableRandomFunction::Create(
92                      parameters_, &ctx_, ec_group_.get(), pedersen_.get()));
93 
94     std::tie(public_key_, private_key_, std::ignore) =
95         dy_vrf_->GenerateKeyPair().value();
96   }
97 
GenerateTranscript(const std::vector<BigNum> & messages)98   StatusOr<Transcript> GenerateTranscript(const std::vector<BigNum>& messages) {
99     // Apply the PRF.
100     ASSIGN_OR_RETURN(std::vector<ECPoint> prf_evaluations,
101                      dy_vrf_->Apply(messages, private_key_));
102 
103     // Commit to the messages.
104     ASSIGN_OR_RETURN(
105         PedersenOverZn::CommitmentAndOpening commit_and_open_messages,
106         pedersen_->Commit(messages));
107 
108     // Generate the proof.
109     ASSIGN_OR_RETURN(
110         proto::DyVrfApplyProof apply_proof,
111         dy_vrf_->GenerateApplyProof(messages, prf_evaluations, public_key_,
112                                     private_key_, commit_and_open_messages));
113 
114     // Regenerate the challenge.
115     ASSIGN_OR_RETURN(BigNum challenge, dy_vrf_->GenerateApplyProofChallenge(
116                                            prf_evaluations, public_key_,
117                                            commit_and_open_messages.commitment,
118                                            apply_proof.message_1()));
119 
120     return Transcript{std::move(prf_evaluations),
121                       std::move(commit_and_open_messages),
122                       std::move(apply_proof), std::move(challenge)};
123   }
124 
125   // Shared across tests, generated once
126   static std::string* serialized_safe_prime_;
127 
128   Context ctx_;
129   std::unique_ptr<ECGroup> ec_group_;
130   proto::PedersenParameters pedersen_parameters_;
131   std::unique_ptr<PedersenOverZn> pedersen_;
132 
133   std::unique_ptr<ECPoint> dy_prf_base_g_;
134   proto::DyVrfParameters parameters_;
135   std::unique_ptr<DyVerifiableRandomFunction> dy_vrf_;
136 
137   proto::DyVrfPublicKey public_key_;
138   proto::DyVrfPrivateKey private_key_;
139 };
140 
141 std::string* DyVerifiableRandomFunctionTest::serialized_safe_prime_ = nullptr;
142 
TEST_F(DyVerifiableRandomFunctionTest,GenerateKeyPairProducesConsistentPublicKey)143 TEST_F(DyVerifiableRandomFunctionTest,
144        GenerateKeyPairProducesConsistentPublicKey) {
145   // Replicate the key for each Pedersen base.
146   std::vector<BigNum> key_vector(pedersen_->gs().size(),
147                                  ctx_.CreateBigNum(private_key_.prf_key()));
148   // Check that private and public key are consistent.
149   EXPECT_THAT(
150       pedersen_->CommitWithRand(
151           key_vector, ctx_.CreateBigNum(private_key_.open_commit_prf_key())),
152       IsOkAndHolds(Eq(ctx_.CreateBigNum(public_key_.commit_prf_key()))));
153 }
154 
TEST_F(DyVerifiableRandomFunctionTest,GenerateKeyPairProducesDifferentValues)155 TEST_F(DyVerifiableRandomFunctionTest, GenerateKeyPairProducesDifferentValues) {
156   ASSERT_OK_AND_ASSIGN(auto key_pair_1, dy_vrf_->GenerateKeyPair());
157   ASSERT_OK_AND_ASSIGN(auto key_pair_2, dy_vrf_->GenerateKeyPair());
158 
159   // Check that private keys are different
160   EXPECT_NE(std::get<1>(key_pair_1).prf_key(),
161             std::get<1>(key_pair_2).prf_key());
162   EXPECT_NE(std::get<1>(key_pair_1).open_commit_prf_key(),
163             std::get<1>(key_pair_2).open_commit_prf_key());
164 }
165 
TEST_F(DyVerifiableRandomFunctionTest,GenerateKeyProofSucceeds)166 TEST_F(DyVerifiableRandomFunctionTest, GenerateKeyProofSucceeds) {
167   proto::DyVrfPublicKey public_key_proto;
168   proto::DyVrfPrivateKey private_key_proto;
169   proto::DyVrfGenerateKeysProof generate_keys_proof_proto;
170   ASSERT_OK_AND_ASSIGN(
171       std::tie(public_key_proto, private_key_proto, generate_keys_proof_proto),
172       dy_vrf_->GenerateKeyPair());
173 
174   EXPECT_OK(dy_vrf_->VerifyGenerateKeysProof(public_key_proto,
175                                              generate_keys_proof_proto));
176 }
177 
TEST_F(DyVerifiableRandomFunctionTest,EmptyGenerateKeyProofFails)178 TEST_F(DyVerifiableRandomFunctionTest, EmptyGenerateKeyProofFails) {
179   proto::DyVrfPublicKey public_key_proto;
180   proto::DyVrfPrivateKey private_key_proto;
181   proto::DyVrfGenerateKeysProof generate_keys_proof_proto;
182   ASSERT_OK_AND_ASSIGN(
183       std::tie(public_key_proto, private_key_proto, generate_keys_proof_proto),
184       dy_vrf_->GenerateKeyPair());
185 
186   // Empty proof should fail.
187   EXPECT_THAT(
188       dy_vrf_->VerifyGenerateKeysProof(public_key_proto,
189                                        proto::DyVrfGenerateKeysProof()),
190       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("Failed")));
191 }
192 
TEST_F(DyVerifiableRandomFunctionTest,GenerateKeyProofFailsForDifferentKeys)193 TEST_F(DyVerifiableRandomFunctionTest, GenerateKeyProofFailsForDifferentKeys) {
194   proto::DyVrfPublicKey public_key_proto;
195   proto::DyVrfPrivateKey private_key_proto;
196   proto::DyVrfGenerateKeysProof generate_keys_proof_proto;
197   ASSERT_OK_AND_ASSIGN(
198       std::tie(public_key_proto, private_key_proto, generate_keys_proof_proto),
199       dy_vrf_->GenerateKeyPair());
200 
201   // Using this proof with the keys generated by the test fixture should fail.
202   EXPECT_THAT(
203       dy_vrf_->VerifyGenerateKeysProof(public_key_, generate_keys_proof_proto),
204       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("Failed")));
205 }
206 
TEST_F(DyVerifiableRandomFunctionTest,GenerateKeyProofFailsWhenPrfCommitmentIsMissing)207 TEST_F(DyVerifiableRandomFunctionTest,
208        GenerateKeyProofFailsWhenPrfCommitmentIsMissing) {
209   proto::DyVrfPublicKey public_key_proto;
210   proto::DyVrfPrivateKey private_key_proto;
211   proto::DyVrfGenerateKeysProof generate_keys_proof_proto;
212   ASSERT_OK_AND_ASSIGN(
213       std::tie(public_key_proto, private_key_proto, generate_keys_proof_proto),
214       dy_vrf_->GenerateKeyPair());
215 
216   public_key_proto.clear_commit_prf_key();
217   // Technically this proof fails because the verification method fails to
218   // compute a modular inverse.
219   EXPECT_THAT(
220       dy_vrf_->VerifyGenerateKeysProof(public_key_proto,
221                                        generate_keys_proof_proto),
222       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("Inverse")));
223 }
224 
TEST_F(DyVerifiableRandomFunctionTest,GenerateKeyProofFailsWhenMaskedDummyPrfKeyIsTooLarge)225 TEST_F(DyVerifiableRandomFunctionTest,
226        GenerateKeyProofFailsWhenMaskedDummyPrfKeyIsTooLarge) {
227   proto::DyVrfPublicKey public_key_proto;
228   proto::DyVrfPrivateKey private_key_proto;
229   proto::DyVrfGenerateKeysProof generate_keys_proof_proto;
230   ASSERT_OK_AND_ASSIGN(
231       std::tie(public_key_proto, private_key_proto, generate_keys_proof_proto),
232       dy_vrf_->GenerateKeyPair());
233 
234   BigNum too_large =
235       ctx_.CreateBigNum(
236               generate_keys_proof_proto.message_2().masked_dummy_prf_key())
237           .Lshift(20);
238 
239   generate_keys_proof_proto.mutable_message_2()->set_masked_dummy_prf_key(
240       too_large.ToBytes());
241 
242   EXPECT_THAT(dy_vrf_->VerifyGenerateKeysProof(public_key_proto,
243                                                generate_keys_proof_proto),
244               StatusIs(absl::StatusCode::kInvalidArgument,
245                        HasSubstr("masked_dummy_prf_key")));
246 }
247 
TEST_F(DyVerifiableRandomFunctionTest,GenerateKeyProofFailsWhenMaskedDummyPrfKeyOpeningIsMissing)248 TEST_F(DyVerifiableRandomFunctionTest,
249        GenerateKeyProofFailsWhenMaskedDummyPrfKeyOpeningIsMissing) {
250   proto::DyVrfPublicKey public_key_proto;
251   proto::DyVrfPrivateKey private_key_proto;
252   proto::DyVrfGenerateKeysProof generate_keys_proof_proto;
253   ASSERT_OK_AND_ASSIGN(
254       std::tie(public_key_proto, private_key_proto, generate_keys_proof_proto),
255       dy_vrf_->GenerateKeyPair());
256 
257   generate_keys_proof_proto.mutable_message_2()->clear_masked_dummy_prf_key();
258 
259   EXPECT_THAT(
260       dy_vrf_->VerifyGenerateKeysProof(public_key_proto,
261                                        generate_keys_proof_proto),
262       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("Failed")));
263 }
264 
TEST_F(DyVerifiableRandomFunctionTest,ApplySucceeds)265 TEST_F(DyVerifiableRandomFunctionTest, ApplySucceeds) {
266   std::vector<BigNum> messages = {ctx_.CreateBigNum(0),
267                                   ctx_.CreateBigNum(5),
268                                   ec_group_->GetOrder() - ctx_.CreateBigNum(1),
269                                   ctx_.CreateBigNum(0),
270                                   ctx_.CreateBigNum(5),
271                                   ec_group_->GetOrder() - ctx_.CreateBigNum(1)};
272 
273   ASSERT_OK_AND_ASSIGN(std::vector<ECPoint> prf_evaluations,
274                        dy_vrf_->Apply(messages, private_key_));
275 
276   // Check that different values have different outputs
277   EXPECT_NE(prf_evaluations[0], prf_evaluations[1]);
278   EXPECT_NE(prf_evaluations[0], prf_evaluations[2]);
279   EXPECT_NE(prf_evaluations[1], prf_evaluations[2]);
280 
281   // Check that the same value has the same output.
282   EXPECT_EQ(prf_evaluations[0], prf_evaluations[3]);
283   EXPECT_EQ(prf_evaluations[1], prf_evaluations[4]);
284   EXPECT_EQ(prf_evaluations[2], prf_evaluations[5]);
285 
286   BigNum prf_key = ctx_.CreateBigNum(private_key_.prf_key());
287   // Check the concrete value of the outputs.
288   for (size_t i = 0; i < prf_evaluations.size(); ++i) {
289     BigNum message_plus_key = messages[i] + prf_key;
290     EXPECT_EQ(prf_evaluations[i].Mul(message_plus_key).value(),
291               *dy_prf_base_g_);
292   }
293 }
294 
TEST_F(DyVerifiableRandomFunctionTest,ProofSucceedsEndToEnd)295 TEST_F(DyVerifiableRandomFunctionTest, ProofSucceedsEndToEnd) {
296   std::vector<BigNum> messages = {ctx_.CreateBigNum(0), ctx_.CreateBigNum(5),
297                                   ec_group_->GetOrder() - ctx_.CreateBigNum(1)};
298 
299   // Apply the PRF.
300   ASSERT_OK_AND_ASSIGN(std::vector<ECPoint> prf_evaluations,
301                        dy_vrf_->Apply(messages, private_key_));
302 
303   // Commit to the messages.
304   ASSERT_OK_AND_ASSIGN(
305       PedersenOverZn::CommitmentAndOpening commit_and_open_messages,
306       pedersen_->Commit(messages));
307 
308   // Generate the proof.
309   ASSERT_OK_AND_ASSIGN(
310       proto::DyVrfApplyProof apply_proof,
311       dy_vrf_->GenerateApplyProof(messages, prf_evaluations, public_key_,
312                                   private_key_, commit_and_open_messages));
313   // Verify the result
314   EXPECT_OK(dy_vrf_->VerifyApplyProof(prf_evaluations, public_key_,
315                                       commit_and_open_messages.commitment,
316                                       apply_proof));
317 }
318 
TEST_F(DyVerifiableRandomFunctionTest,SucceedsWithFewerMessagesThanBases)319 TEST_F(DyVerifiableRandomFunctionTest, SucceedsWithFewerMessagesThanBases) {
320   std::vector<BigNum> messages = {ctx_.CreateBigNum(5)};
321   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
322   // Verify the result
323   EXPECT_OK(dy_vrf_->VerifyApplyProof(
324       transcript.prf_evaluations, public_key_,
325       transcript.commit_and_open_messages.commitment, transcript.apply_proof));
326 }
327 
328 // The test with too many messages is skipped because it fails when trying to
329 // create the Pedersen commitment before GenerateApplyProof is called.
330 
TEST_F(DyVerifiableRandomFunctionTest,ProofFailsOnChangedMessages)331 TEST_F(DyVerifiableRandomFunctionTest, ProofFailsOnChangedMessages) {
332   std::vector<BigNum> messages = {ctx_.CreateBigNum(0), ctx_.CreateBigNum(5),
333                                   ec_group_->GetOrder() - ctx_.CreateBigNum(1)};
334 
335   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
336   std::vector<BigNum> wrong_messages = {
337       ctx_.CreateBigNum(2), ctx_.CreateBigNum(3), ctx_.CreateBigNum(7)};
338 
339   // Apply the PRF to wrong_messages.
340   ASSERT_OK_AND_ASSIGN(std::vector<ECPoint> wrong_prf_evaluations,
341                        dy_vrf_->Apply(wrong_messages, private_key_));
342 
343   // Expect the verification fails.
344   EXPECT_THAT(
345       dy_vrf_->VerifyApplyProof(wrong_prf_evaluations, public_key_,
346                                 transcript.commit_and_open_messages.commitment,
347                                 transcript.apply_proof),
348       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("fail")));
349 }
350 
TEST_F(DyVerifiableRandomFunctionTest,ProofFailsIfRoPrefixIsChanged)351 TEST_F(DyVerifiableRandomFunctionTest, ProofFailsIfRoPrefixIsChanged) {
352   std::vector<BigNum> messages = {ctx_.CreateBigNum(0), ctx_.CreateBigNum(5),
353                                   ec_group_->GetOrder() - ctx_.CreateBigNum(1)};
354   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
355 
356   proto::DyVrfParameters modified_parameters = parameters_;
357   modified_parameters.set_random_oracle_prefix("modified");
358 
359   ASSERT_OK_AND_ASSIGN(
360       auto modified_dy_vrf,
361       DyVerifiableRandomFunction::Create(modified_parameters, &ctx_,
362                                          ec_group_.get(), pedersen_.get()));
363 
364   // Expect the verification fails when using the modified parameters.
365   EXPECT_THAT(modified_dy_vrf->VerifyApplyProof(
366                   transcript.prf_evaluations, public_key_,
367                   transcript.commit_and_open_messages.commitment,
368                   transcript.apply_proof),
369               StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("fail")));
370 }
371 
TEST_F(DyVerifiableRandomFunctionTest,ChallengeIsCorrectlyBounded)372 TEST_F(DyVerifiableRandomFunctionTest, ChallengeIsCorrectlyBounded) {
373   std::vector<BigNum> messages = {ctx_.CreateBigNum(0), ctx_.CreateBigNum(5),
374                                   ec_group_->GetOrder() - ctx_.CreateBigNum(1)};
375   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
376 
377   EXPECT_LE(transcript.challenge, ctx_.One().Lshift(kChallengeLengthBits));
378 }
379 
TEST_F(DyVerifiableRandomFunctionTest,ChallengeChangesOnWrongMessages)380 TEST_F(DyVerifiableRandomFunctionTest, ChallengeChangesOnWrongMessages) {
381   std::vector<BigNum> messages = {ctx_.CreateBigNum(0), ctx_.CreateBigNum(5),
382                                   ec_group_->GetOrder() - ctx_.CreateBigNum(1)};
383 
384   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
385 
386   std::vector<BigNum> wrong_messages = {
387       ctx_.CreateBigNum(2), ctx_.CreateBigNum(3), ctx_.CreateBigNum(7)};
388 
389   // Apply the PRF to wrong_messages.
390   ASSERT_OK_AND_ASSIGN(std::vector<ECPoint> wrong_prf_evaluations,
391                        dy_vrf_->Apply(wrong_messages, private_key_));
392 
393   // Expect the challenge changes.
394   ASSERT_OK_AND_ASSIGN(BigNum challenge_2,
395                        dy_vrf_->GenerateApplyProofChallenge(
396                            wrong_prf_evaluations, public_key_,
397                            transcript.commit_and_open_messages.commitment,
398                            transcript.apply_proof.message_1()));
399 
400   EXPECT_NE(transcript.challenge, challenge_2);
401 }
402 
TEST_F(DyVerifiableRandomFunctionTest,DifferentTranscriptsHaveDifferentChallenges)403 TEST_F(DyVerifiableRandomFunctionTest,
404        DifferentTranscriptsHaveDifferentChallenges) {
405   std::vector<BigNum> messages = {ctx_.CreateBigNum(0), ctx_.CreateBigNum(5),
406                                   ec_group_->GetOrder() - ctx_.CreateBigNum(1)};
407 
408   ASSERT_OK_AND_ASSIGN(Transcript transcript_1, GenerateTranscript(messages));
409   ASSERT_OK_AND_ASSIGN(Transcript transcript_2, GenerateTranscript(messages));
410 
411   EXPECT_NE(transcript_1.challenge, transcript_2.challenge);
412 }
413 
TEST_F(DyVerifiableRandomFunctionTest,ProofFailsWhenMessage1Deleted)414 TEST_F(DyVerifiableRandomFunctionTest, ProofFailsWhenMessage1Deleted) {
415   std::vector<BigNum> messages = {ctx_.CreateBigNum(0), ctx_.CreateBigNum(5),
416                                   ec_group_->GetOrder() - ctx_.CreateBigNum(1)};
417 
418   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
419 
420   transcript.apply_proof.clear_message_1();
421 
422   EXPECT_THAT(
423       dy_vrf_->VerifyApplyProof(transcript.prf_evaluations, public_key_,
424                                 transcript.commit_and_open_messages.commitment,
425                                 transcript.apply_proof),
426       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("different")));
427 }
428 
TEST_F(DyVerifiableRandomFunctionTest,ProofFailsWhenMessage2Deleted)429 TEST_F(DyVerifiableRandomFunctionTest, ProofFailsWhenMessage2Deleted) {
430   std::vector<BigNum> messages = {ctx_.CreateBigNum(0), ctx_.CreateBigNum(5),
431                                   ec_group_->GetOrder() - ctx_.CreateBigNum(1)};
432 
433   ASSERT_OK_AND_ASSIGN(Transcript transcript, GenerateTranscript(messages));
434 
435   transcript.apply_proof.clear_message_2();
436 
437   EXPECT_THAT(
438       dy_vrf_->VerifyApplyProof(transcript.prf_evaluations, public_key_,
439                                 transcript.commit_and_open_messages.commitment,
440                                 transcript.apply_proof),
441       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("different")));
442 }
443 
TEST_F(DyVerifiableRandomFunctionTest,ProofFailsWhenCommitDummyMessagesPlusKeySwapped)444 TEST_F(DyVerifiableRandomFunctionTest,
445        ProofFailsWhenCommitDummyMessagesPlusKeySwapped) {
446   std::vector<BigNum> messages = {ctx_.CreateBigNum(0), ctx_.CreateBigNum(5),
447                                   ec_group_->GetOrder() - ctx_.CreateBigNum(1)};
448 
449   ASSERT_OK_AND_ASSIGN(Transcript transcript_1, GenerateTranscript(messages));
450   ASSERT_OK_AND_ASSIGN(Transcript transcript_2, GenerateTranscript(messages));
451 
452   *transcript_1.apply_proof.mutable_message_1()
453        ->mutable_commit_dummy_messages_plus_key() =
454       transcript_2.apply_proof.message_1().commit_dummy_messages_plus_key();
455 
456   EXPECT_THAT(dy_vrf_->VerifyApplyProof(
457                   transcript_1.prf_evaluations, public_key_,
458                   transcript_1.commit_and_open_messages.commitment,
459                   transcript_1.apply_proof),
460               StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("fail")));
461 }
462 
TEST_F(DyVerifiableRandomFunctionTest,ProofFailsWhenDummyDyPrfBaseGSSwapped)463 TEST_F(DyVerifiableRandomFunctionTest, ProofFailsWhenDummyDyPrfBaseGSSwapped) {
464   std::vector<BigNum> messages = {ctx_.CreateBigNum(0), ctx_.CreateBigNum(5),
465                                   ec_group_->GetOrder() - ctx_.CreateBigNum(1)};
466 
467   ASSERT_OK_AND_ASSIGN(Transcript transcript_1, GenerateTranscript(messages));
468   ASSERT_OK_AND_ASSIGN(Transcript transcript_2, GenerateTranscript(messages));
469 
470   *transcript_1.apply_proof.mutable_message_1()
471        ->mutable_dummy_dy_prf_base_gs() =
472       transcript_2.apply_proof.message_1().dummy_dy_prf_base_gs();
473 
474   EXPECT_THAT(dy_vrf_->VerifyApplyProof(
475                   transcript_1.prf_evaluations, public_key_,
476                   transcript_1.commit_and_open_messages.commitment,
477                   transcript_1.apply_proof),
478               StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("fail")));
479 }
480 
TEST_F(DyVerifiableRandomFunctionTest,ProofFailsWhenMaskedDummyMessagesPlusKeySwapped)481 TEST_F(DyVerifiableRandomFunctionTest,
482        ProofFailsWhenMaskedDummyMessagesPlusKeySwapped) {
483   std::vector<BigNum> messages = {ctx_.CreateBigNum(0), ctx_.CreateBigNum(5),
484                                   ec_group_->GetOrder() - ctx_.CreateBigNum(1)};
485 
486   ASSERT_OK_AND_ASSIGN(Transcript transcript_1, GenerateTranscript(messages));
487   ASSERT_OK_AND_ASSIGN(Transcript transcript_2, GenerateTranscript(messages));
488 
489   *transcript_1.apply_proof.mutable_message_2()
490        ->mutable_masked_dummy_messages_plus_key() =
491       transcript_2.apply_proof.message_2().masked_dummy_messages_plus_key();
492 
493   EXPECT_THAT(dy_vrf_->VerifyApplyProof(
494                   transcript_1.prf_evaluations, public_key_,
495                   transcript_1.commit_and_open_messages.commitment,
496                   transcript_1.apply_proof),
497               StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("fail")));
498 }
499 
TEST_F(DyVerifiableRandomFunctionTest,ProofFailsWhenMaskedDummyOpeningSwapped)500 TEST_F(DyVerifiableRandomFunctionTest,
501        ProofFailsWhenMaskedDummyOpeningSwapped) {
502   std::vector<BigNum> messages = {ctx_.CreateBigNum(0), ctx_.CreateBigNum(5),
503                                   ec_group_->GetOrder() - ctx_.CreateBigNum(1)};
504 
505   ASSERT_OK_AND_ASSIGN(Transcript transcript_1, GenerateTranscript(messages));
506   ASSERT_OK_AND_ASSIGN(Transcript transcript_2, GenerateTranscript(messages));
507 
508   *transcript_1.apply_proof.mutable_message_2()
509        ->mutable_masked_dummy_opening() =
510       transcript_2.apply_proof.message_2().masked_dummy_opening();
511 
512   EXPECT_THAT(dy_vrf_->VerifyApplyProof(
513                   transcript_1.prf_evaluations, public_key_,
514                   transcript_1.commit_and_open_messages.commitment,
515                   transcript_1.apply_proof),
516               StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("fail")));
517 }
518 
519 }  // namespace
520 }  // namespace private_join_and_compute
521