xref: /aosp_15_r20/external/tink/cc/signature/ed25519_public_key_test.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
1 // Copyright 2023 Google LLC
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 //      http://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 
17 #include "tink/signature/ed25519_public_key.h"
18 
19 #include <string>
20 
21 #include "gmock/gmock.h"
22 #include "gtest/gtest.h"
23 #include "tink/partial_key_access.h"
24 #include "tink/subtle/random.h"
25 #include "tink/util/statusor.h"
26 #include "tink/util/test_matchers.h"
27 
28 namespace crypto {
29 namespace tink {
30 namespace {
31 
32 using ::crypto::tink::test::IsOk;
33 using ::crypto::tink::test::StatusIs;
34 using ::testing::Eq;
35 using ::testing::TestWithParam;
36 using ::testing::Values;
37 
38 struct TestCase {
39   Ed25519Parameters::Variant variant;
40   absl::optional<int> id_requirement;
41   std::string output_prefix;
42 };
43 
44 using Ed25519PublicKeyTest = TestWithParam<TestCase>;
45 
46 INSTANTIATE_TEST_SUITE_P(
47     Ed25519PublicKeyTestSuite, Ed25519PublicKeyTest,
48     Values(TestCase{Ed25519Parameters::Variant::kTink, 0x02030400,
49                     std::string("\x01\x02\x03\x04\x00", 5)},
50            TestCase{Ed25519Parameters::Variant::kCrunchy, 0x01030005,
51                     std::string("\x00\x01\x03\x00\x05", 5)},
52            TestCase{Ed25519Parameters::Variant::kLegacy, 0x07080910,
53                     std::string("\x00\x07\x08\x09\x10", 5)},
54            TestCase{Ed25519Parameters::Variant::kNoPrefix, absl::nullopt, ""}));
55 
TEST_P(Ed25519PublicKeyTest,CreateSucceeds)56 TEST_P(Ed25519PublicKeyTest, CreateSucceeds) {
57   TestCase test_case = GetParam();
58 
59   util::StatusOr<Ed25519Parameters> params =
60       Ed25519Parameters::Create(test_case.variant);
61   ASSERT_THAT(params, IsOk());
62 
63   std::string public_key_bytes = subtle::Random::GetRandomBytes(32);
64   util::StatusOr<Ed25519PublicKey> public_key =
65       Ed25519PublicKey::Create(*params, public_key_bytes,
66                                test_case.id_requirement, GetPartialKeyAccess());
67   ASSERT_THAT(public_key, IsOk());
68 
69   EXPECT_THAT(public_key->GetParameters(), Eq(*params));
70   EXPECT_THAT(public_key->GetIdRequirement(), Eq(test_case.id_requirement));
71   EXPECT_THAT(public_key->GetOutputPrefix(), Eq(test_case.output_prefix));
72   EXPECT_THAT(public_key->GetPublicKeyBytes(GetPartialKeyAccess()),
73               Eq(public_key_bytes));
74 }
75 
TEST(Ed25519PublicKeyTest,CreateWithInvalidPublicKeyLength)76 TEST(Ed25519PublicKeyTest, CreateWithInvalidPublicKeyLength) {
77   util::StatusOr<Ed25519Parameters> params =
78       Ed25519Parameters::Create(Ed25519Parameters::Variant::kTink);
79   ASSERT_THAT(params, IsOk());
80 
81   std::string public_key_bytes = subtle::Random::GetRandomBytes(31);
82 
83   EXPECT_THAT(
84       Ed25519PublicKey::Create(*params, public_key_bytes,
85                                /*id_requirement=*/123, GetPartialKeyAccess())
86           .status(),
87       StatusIs(absl::StatusCode::kInvalidArgument));
88 }
89 
TEST(Ed25519PublicKeyTest,CreateKeyWithInvalidIdRequirementFails)90 TEST(Ed25519PublicKeyTest, CreateKeyWithInvalidIdRequirementFails) {
91   util::StatusOr<Ed25519Parameters> no_prefix_params =
92       Ed25519Parameters::Create(Ed25519Parameters::Variant::kNoPrefix);
93   ASSERT_THAT(no_prefix_params, IsOk());
94 
95   util::StatusOr<Ed25519Parameters> tink_params =
96       Ed25519Parameters::Create(Ed25519Parameters::Variant::kTink);
97   ASSERT_THAT(tink_params, IsOk());
98 
99   std::string public_key_bytes = subtle::Random::GetRandomBytes(32);
100 
101   EXPECT_THAT(
102       Ed25519PublicKey::Create(*no_prefix_params, public_key_bytes,
103                                /*id_requirement=*/123, GetPartialKeyAccess())
104           .status(),
105       StatusIs(absl::StatusCode::kInvalidArgument));
106 
107   EXPECT_THAT(Ed25519PublicKey::Create(*tink_params, public_key_bytes,
108                                        /*id_requirement=*/absl::nullopt,
109                                        GetPartialKeyAccess())
110                   .status(),
111               StatusIs(absl::StatusCode::kInvalidArgument));
112 }
113 
TEST_P(Ed25519PublicKeyTest,KeyEquals)114 TEST_P(Ed25519PublicKeyTest, KeyEquals) {
115   TestCase test_case = GetParam();
116 
117   util::StatusOr<Ed25519Parameters> params =
118       Ed25519Parameters::Create(test_case.variant);
119   ASSERT_THAT(params, IsOk());
120 
121   std::string public_key_bytes = subtle::Random::GetRandomBytes(32);
122 
123   util::StatusOr<Ed25519PublicKey> public_key =
124       Ed25519PublicKey::Create(*params, public_key_bytes,
125                                test_case.id_requirement, GetPartialKeyAccess());
126   ASSERT_THAT(public_key, IsOk());
127 
128   util::StatusOr<Ed25519PublicKey> other_public_key =
129       Ed25519PublicKey::Create(*params, public_key_bytes,
130                                test_case.id_requirement, GetPartialKeyAccess());
131   ASSERT_THAT(other_public_key, IsOk());
132 
133   EXPECT_TRUE(*public_key == *other_public_key);
134   EXPECT_TRUE(*other_public_key == *public_key);
135   EXPECT_FALSE(*public_key != *other_public_key);
136   EXPECT_FALSE(*other_public_key != *public_key);
137 }
138 
TEST(Ed25519PublicKeyTest,DifferentVariantNotEqual)139 TEST(Ed25519PublicKeyTest, DifferentVariantNotEqual) {
140   util::StatusOr<Ed25519Parameters> crunchy_params =
141       Ed25519Parameters::Create(Ed25519Parameters::Variant::kCrunchy);
142   ASSERT_THAT(crunchy_params, IsOk());
143 
144   util::StatusOr<Ed25519Parameters> tink_params =
145       Ed25519Parameters::Create(Ed25519Parameters::Variant::kTink);
146   ASSERT_THAT(tink_params, IsOk());
147 
148   std::string public_key_bytes = subtle::Random::GetRandomBytes(32);
149 
150   util::StatusOr<Ed25519PublicKey> public_key = Ed25519PublicKey::Create(
151       *crunchy_params, public_key_bytes, /*id_requirement=*/0x01020304,
152       GetPartialKeyAccess());
153   ASSERT_THAT(public_key, IsOk());
154 
155   util::StatusOr<Ed25519PublicKey> other_public_key = Ed25519PublicKey::Create(
156       *tink_params, public_key_bytes, /*id_requirement=*/0x01020304,
157       GetPartialKeyAccess());
158   ASSERT_THAT(other_public_key, IsOk());
159 
160   EXPECT_TRUE(*public_key != *other_public_key);
161   EXPECT_TRUE(*other_public_key != *public_key);
162   EXPECT_FALSE(*public_key == *other_public_key);
163   EXPECT_FALSE(*other_public_key == *public_key);
164 }
165 
TEST(Ed25519PublicKeyTest,DifferentPublicKeyBytesNotEqual)166 TEST(Ed25519PublicKeyTest, DifferentPublicKeyBytesNotEqual) {
167   util::StatusOr<Ed25519Parameters> params =
168       Ed25519Parameters::Create(Ed25519Parameters::Variant::kTink);
169   ASSERT_THAT(params, IsOk());
170 
171   std::string public_key_bytes1 = subtle::Random::GetRandomBytes(32);
172   std::string public_key_bytes2 = subtle::Random::GetRandomBytes(32);
173 
174   util::StatusOr<Ed25519PublicKey> public_key = Ed25519PublicKey::Create(
175       *params, public_key_bytes1, /*id_requirement=*/0x01020304,
176       GetPartialKeyAccess());
177   ASSERT_THAT(public_key, IsOk());
178 
179   util::StatusOr<Ed25519PublicKey> other_public_key = Ed25519PublicKey::Create(
180       *params, public_key_bytes2, /*id_requirement=*/0x01020304,
181       GetPartialKeyAccess());
182   ASSERT_THAT(other_public_key, IsOk());
183 
184   EXPECT_TRUE(*public_key != *other_public_key);
185   EXPECT_TRUE(*other_public_key != *public_key);
186   EXPECT_FALSE(*public_key == *other_public_key);
187   EXPECT_FALSE(*other_public_key == *public_key);
188 }
189 
TEST(Ed25519PublicKeyTest,DifferentIdRequirementNotEqual)190 TEST(Ed25519PublicKeyTest, DifferentIdRequirementNotEqual) {
191   util::StatusOr<Ed25519Parameters> params =
192       Ed25519Parameters::Create(Ed25519Parameters::Variant::kTink);
193   ASSERT_THAT(params, IsOk());
194 
195   std::string public_key_bytes = subtle::Random::GetRandomBytes(32);
196 
197   util::StatusOr<Ed25519PublicKey> public_key = Ed25519PublicKey::Create(
198       *params, public_key_bytes, /*id_requirement=*/0x01020304,
199       GetPartialKeyAccess());
200   ASSERT_THAT(public_key, IsOk());
201 
202   util::StatusOr<Ed25519PublicKey> other_public_key = Ed25519PublicKey::Create(
203       *params, public_key_bytes, /*id_requirement=*/0x02030405,
204       GetPartialKeyAccess());
205   ASSERT_THAT(other_public_key, IsOk());
206 
207   EXPECT_TRUE(*public_key != *other_public_key);
208   EXPECT_TRUE(*other_public_key != *public_key);
209   EXPECT_FALSE(*public_key == *other_public_key);
210   EXPECT_FALSE(*other_public_key == *public_key);
211 }
212 
213 }  // namespace
214 }  // namespace tink
215 }  // namespace crypto
216