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/simultaneous_fixed_bases_exp.h"
17 
18 #include <gmock/gmock.h>
19 #include <gtest/gtest.h>
20 
21 #include <cstdint>
22 #include <memory>
23 #include <utility>
24 #include <vector>
25 
26 #include "private_join_and_compute/crypto/big_num.h"
27 #include "private_join_and_compute/crypto/context.h"
28 #include "private_join_and_compute/crypto/ec_group.h"
29 #include "private_join_and_compute/crypto/ec_point.h"
30 #include "private_join_and_compute/util/status.inc"
31 #include "private_join_and_compute/util/status_testing.inc"
32 
33 namespace private_join_and_compute {
34 namespace {
35 
36 using ::testing::HasSubstr;
37 using testing::StatusIs;
38 
39 const uint64_t P = 35879;
40 const uint64_t Q = 63587;
41 const uint64_t N = P * Q;
42 const uint64_t S = 2;
43 
44 using ZnExp = SimultaneousFixedBasesExp<ZnElement, ZnContext>;
45 
46 const int kTestCurveId = NID_secp224r1;
47 
48 class SimultaneousFixedBasesExpTest : public ::testing::Test {
49  protected:
SetUp()50   void SetUp() override {
51     ASSERT_OK_AND_ASSIGN(
52         auto ec_group,
53         private_join_and_compute::ECGroup::Create(kTestCurveId, &ctx_));
54     ec_group_ = std::make_unique<private_join_and_compute::ECGroup>(
55         std::move(ec_group));
56   }
57 
58   private_join_and_compute::Context ctx_;
59   std::unique_ptr<private_join_and_compute::ECGroup> ec_group_;
60 };
61 
TEST_F(SimultaneousFixedBasesExpTest,ZnMultipleExp)62 TEST_F(SimultaneousFixedBasesExpTest, ZnMultipleExp) {
63   private_join_and_compute::BigNum n = ctx_.CreateBigNum(P);  // Prime modulus.
64   auto base1 = ctx_.GenerateRandLessThan(n);
65   auto base2 = ctx_.GenerateRandLessThan(n);
66   private_join_and_compute::BigNum exponent1 = ctx_.CreateBigNum(29);
67   private_join_and_compute::BigNum exponent2 = ctx_.CreateBigNum(2245);
68 
69   std::vector<ZnElement> bases;
70   bases.push_back(base1);
71   bases.push_back(base2);
72   std::unique_ptr<ZnContext> zn_context(new ZnContext({n}));
73 
74   ASSERT_OK_AND_ASSIGN(
75       auto exp, ZnExp::Create(bases, ctx_.One(), 2, std::move(zn_context)));
76 
77   std::vector<private_join_and_compute::BigNum> exponents;
78   exponents.push_back(exponent1);
79   exponents.push_back(exponent2);
80   ASSERT_OK_AND_ASSIGN(auto result, exp->SimultaneousExp(exponents));
81 
82   auto result1 = base1.ModExp(exponent1, n);
83   auto result2 = base2.ModExp(exponent2, n);
84   auto expected = result1.ModMul(result2, n);
85 
86   EXPECT_EQ(result, expected);
87 }
88 
TEST_F(SimultaneousFixedBasesExpTest,FailsWhenNumExponentsNotEqualNumBases)89 TEST_F(SimultaneousFixedBasesExpTest, FailsWhenNumExponentsNotEqualNumBases) {
90   private_join_and_compute::BigNum n = ctx_.CreateBigNum(P);  // Prime modulus.
91   auto base1 = ctx_.GenerateRandLessThan(n);
92   auto base2 = ctx_.GenerateRandLessThan(n);
93   private_join_and_compute::BigNum exponent1 = ctx_.CreateBigNum(29);
94   private_join_and_compute::BigNum exponent2 = ctx_.CreateBigNum(2245);
95 
96   std::vector<ZnElement> bases;
97   bases.push_back(base1);
98   std::unique_ptr<ZnContext> zn_context(new ZnContext({n}));
99 
100   ASSERT_OK_AND_ASSIGN(
101       auto exp, ZnExp::Create(bases, ctx_.One(), 1, std::move(zn_context)));
102 
103   std::vector<private_join_and_compute::BigNum> exponents;
104   exponents.push_back(exponent1);
105   exponents.push_back(exponent2);
106 
107   EXPECT_THAT(exp->SimultaneousExp(exponents),
108               StatusIs(absl::StatusCode::kInvalidArgument,
109                        HasSubstr("Number of exponents")));
110 }
111 
TEST_F(SimultaneousFixedBasesExpTest,FailsWhenNumSimultaneousLargerThanBases)112 TEST_F(SimultaneousFixedBasesExpTest, FailsWhenNumSimultaneousLargerThanBases) {
113   private_join_and_compute::BigNum n = ctx_.CreateBigNum(P);  // Prime modulus.
114   auto base1 = ctx_.GenerateRandLessThan(n);
115   auto base2 = ctx_.GenerateRandLessThan(n);
116   private_join_and_compute::BigNum exponent1 = ctx_.CreateBigNum(29);
117   private_join_and_compute::BigNum exponent2 = ctx_.CreateBigNum(2245);
118 
119   std::vector<ZnElement> bases;
120   bases.push_back(base1);
121   std::unique_ptr<ZnContext> zn_context(new ZnContext({n}));
122 
123   EXPECT_THAT(ZnExp::Create(bases, ctx_.One(), 2, std::move(zn_context)),
124               StatusIs(absl::StatusCode::kInvalidArgument,
125                        HasSubstr("num_simultaneous parameter")));
126 }
127 
TEST_F(SimultaneousFixedBasesExpTest,FailsWhenNumSimultaneousZero)128 TEST_F(SimultaneousFixedBasesExpTest, FailsWhenNumSimultaneousZero) {
129   private_join_and_compute::BigNum n = ctx_.CreateBigNum(P);  // Prime modulus.
130   auto base1 = ctx_.GenerateRandLessThan(n);
131   auto base2 = ctx_.GenerateRandLessThan(n);
132   private_join_and_compute::BigNum exponent1 = ctx_.CreateBigNum(29);
133   private_join_and_compute::BigNum exponent2 = ctx_.CreateBigNum(2245);
134 
135   std::vector<ZnElement> bases;
136   bases.push_back(base1);
137   bases.push_back(base2);
138   std::unique_ptr<ZnContext> zn_context(new ZnContext({n}));
139 
140   EXPECT_THAT(
141       ZnExp::Create(bases, ctx_.One(), 0, std::move(zn_context)),
142       StatusIs(absl::StatusCode::kInvalidArgument, HasSubstr("positive")));
143 }
144 
145 }  // namespace
146 }  // namespace private_join_and_compute
147