aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorwconner <wconner@google.com>2023-07-27 09:38:52 -0700
committerCopybara-Service <copybara-worker@google.com>2023-07-27 09:40:06 -0700
commit5a5ae2b3fa00c614e700eed2f36a114c5996450c (patch)
tree602e0c0d4497d38a251ca26bb6eab7786a1d2ffc
parent8cc91e8f4ab249f07cb259f100967af4e05f92a2 (diff)
downloadtink-5a5ae2b3fa00c614e700eed2f36a114c5996450c.tar.gz
Add Ed25519 parameters type.
PiperOrigin-RevId: 551556793
-rw-r--r--cc/signature/BUILD.bazel22
-rw-r--r--cc/signature/CMakeLists.txt21
-rw-r--r--cc/signature/ed25519_parameters.cc48
-rw-r--r--cc/signature/ed25519_parameters.h69
-rw-r--r--cc/signature/ed25519_parameters_test.cc125
5 files changed, 285 insertions, 0 deletions
diff --git a/cc/signature/BUILD.bazel b/cc/signature/BUILD.bazel
index 8be1801eb..7f31b48a8 100644
--- a/cc/signature/BUILD.bazel
+++ b/cc/signature/BUILD.bazel
@@ -432,6 +432,17 @@ cc_library(
],
)
+cc_library(
+ name = "ed25519_parameters",
+ srcs = ["ed25519_parameters.cc"],
+ hdrs = ["ed25519_parameters.h"],
+ include_prefix = "tink/signature",
+ deps = [
+ ":signature_parameters",
+ "//util:statusor",
+ ],
+)
+
# tests
cc_test(
@@ -803,3 +814,14 @@ cc_test(
"@com_google_googletest//:gtest_main",
],
)
+
+cc_test(
+ name = "ed25519_parameters_test",
+ srcs = ["ed25519_parameters_test.cc"],
+ deps = [
+ ":ed25519_parameters",
+ "//util:statusor",
+ "//util:test_matchers",
+ "@com_google_googletest//:gtest_main",
+ ],
+)
diff --git a/cc/signature/CMakeLists.txt b/cc/signature/CMakeLists.txt
index b72a0427d..68a8fc6aa 100644
--- a/cc/signature/CMakeLists.txt
+++ b/cc/signature/CMakeLists.txt
@@ -412,6 +412,16 @@ tink_cc_library(
tink::core::private_key
)
+tink_cc_library(
+ NAME ed25519_parameters
+ SRCS
+ ed25519_parameters.cc
+ ed25519_parameters.h
+ DEPS
+ tink::signature::signature_parameters
+ tink::util::statusor
+)
+
# tests
tink_cc_test(
@@ -767,3 +777,14 @@ tink_cc_test(
absl::status
tink::util::test_matchers
)
+
+tink_cc_test(
+ NAME ed25519_parameters_test
+ SRCS
+ ed25519_parameters_test.cc
+ DEPS
+ tink::signature::ed25519_parameters
+ gmock
+ tink::util::statusor
+ tink::util::test_matchers
+)
diff --git a/cc/signature/ed25519_parameters.cc b/cc/signature/ed25519_parameters.cc
new file mode 100644
index 000000000..4f448ac3e
--- /dev/null
+++ b/cc/signature/ed25519_parameters.cc
@@ -0,0 +1,48 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include "tink/signature/ed25519_parameters.h"
+
+#include <set>
+
+#include "tink/util/statusor.h"
+
+namespace crypto {
+namespace tink {
+
+util::StatusOr<Ed25519Parameters> Ed25519Parameters::Create(Variant variant) {
+ static const std::set<Variant>* supported_variants =
+ new std::set<Variant>({Variant::kTink, Variant::kCrunchy,
+ Variant::kLegacy, Variant::kNoPrefix});
+ if (supported_variants->find(variant) == supported_variants->end()) {
+ return util::Status(
+ absl::StatusCode::kInvalidArgument,
+ "Cannot create Ed25519 parameters with unknown variant.");
+ }
+ return Ed25519Parameters(variant);
+}
+
+bool Ed25519Parameters::operator==(const Parameters& other) const {
+ const Ed25519Parameters* that =
+ dynamic_cast<const Ed25519Parameters*>(&other);
+ if (that == nullptr) {
+ return false;
+ }
+ return variant_ == that->variant_;
+}
+
+} // namespace tink
+} // namespace crypto
diff --git a/cc/signature/ed25519_parameters.h b/cc/signature/ed25519_parameters.h
new file mode 100644
index 000000000..959693e90
--- /dev/null
+++ b/cc/signature/ed25519_parameters.h
@@ -0,0 +1,69 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#ifndef TINK_SIGNATURE_ED25519_PARAMETERS_H_
+#define TINK_SIGNATURE_ED25519_PARAMETERS_H_
+
+#include "tink/signature/signature_parameters.h"
+#include "tink/util/statusor.h"
+
+namespace crypto {
+namespace tink {
+
+class Ed25519Parameters : public SignatureParameters {
+ public:
+ // Description of the output prefix prepended to the signature.
+ enum class Variant : int {
+ // Prepends '0x01<big endian key id>' to signature.
+ kTink = 1,
+ // Prepends '0x00<big endian key id>' to signature.
+ kCrunchy = 2,
+ // Appends a 0-byte to input message BEFORE computing the signature, then
+ // prepends '0x00<big endian key id>' to signature.
+ kLegacy = 3,
+ // Does not prepend any prefix (i.e., keys must have no ID requirement).
+ kNoPrefix = 4,
+ // Added to guard from failures that may be caused by future expansions.
+ kDoNotUseInsteadUseDefaultWhenWritingSwitchStatements = 20,
+ };
+
+ // Copyable and movable.
+ Ed25519Parameters(const Ed25519Parameters& other) = default;
+ Ed25519Parameters& operator=(const Ed25519Parameters& other) = default;
+ Ed25519Parameters(Ed25519Parameters&& other) = default;
+ Ed25519Parameters& operator=(Ed25519Parameters&& other) = default;
+
+ // Creates a new Ed25519 parameters object unless `variant` is invalid.
+ static util::StatusOr<Ed25519Parameters> Create(Variant variant);
+
+ Variant GetVariant() const { return variant_; }
+
+ bool HasIdRequirement() const override {
+ return variant_ != Variant::kNoPrefix;
+ }
+
+ bool operator==(const Parameters& other) const override;
+
+ private:
+ explicit Ed25519Parameters(Variant variant) : variant_(variant) {}
+
+ Variant variant_;
+};
+
+} // namespace tink
+} // namespace crypto
+
+#endif // TINK_SIGNATURE_ED25519_PARAMETERS_H_
diff --git a/cc/signature/ed25519_parameters_test.cc b/cc/signature/ed25519_parameters_test.cc
new file mode 100644
index 000000000..f79be9620
--- /dev/null
+++ b/cc/signature/ed25519_parameters_test.cc
@@ -0,0 +1,125 @@
+// Copyright 2023 Google LLC
+//
+// Licensed under the Apache License, Version 2.0 (the "License");
+// you may not use this file except in compliance with the License.
+// You may obtain a copy of the License at
+//
+// http://www.apache.org/licenses/LICENSE-2.0
+//
+// Unless required by applicable law or agreed to in writing, software
+// distributed under the License is distributed on an "AS IS" BASIS,
+// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+// See the License for the specific language governing permissions and
+// limitations under the License.
+//
+////////////////////////////////////////////////////////////////////////////////
+
+#include "tink/signature/ed25519_parameters.h"
+
+#include "gmock/gmock.h"
+#include "gtest/gtest.h"
+#include "tink/util/statusor.h"
+#include "tink/util/test_matchers.h"
+
+namespace crypto {
+namespace tink {
+namespace {
+
+using ::crypto::tink::test::IsOk;
+using ::crypto::tink::test::StatusIs;
+using ::testing::Eq;
+using ::testing::IsTrue;
+using ::testing::TestWithParam;
+using ::testing::Values;
+
+struct TestCase {
+ Ed25519Parameters::Variant variant;
+ bool has_id_requirement;
+};
+
+using Ed25519ParametersTest = TestWithParam<TestCase>;
+
+INSTANTIATE_TEST_SUITE_P(Ed25519ParametersTestSuite, Ed25519ParametersTest,
+ Values(TestCase{Ed25519Parameters::Variant::kTink,
+ /*has_id_requirement=*/true},
+ TestCase{Ed25519Parameters::Variant::kCrunchy,
+ /*has_id_requirement=*/true},
+ TestCase{Ed25519Parameters::Variant::kLegacy,
+ /*has_id_requirement=*/true},
+ TestCase{Ed25519Parameters::Variant::kNoPrefix,
+ /*has_id_requirement=*/false}));
+
+TEST_P(Ed25519ParametersTest, Create) {
+ TestCase test_case = GetParam();
+
+ util::StatusOr<Ed25519Parameters> parameters =
+ Ed25519Parameters::Create(test_case.variant);
+ ASSERT_THAT(parameters, IsOk());
+
+ EXPECT_THAT(parameters->GetVariant(), Eq(test_case.variant));
+ EXPECT_THAT(parameters->HasIdRequirement(), Eq(test_case.has_id_requirement));
+}
+
+TEST(Ed25519ParametersTest, CreateWithInvalidVariantFails) {
+ EXPECT_THAT(Ed25519Parameters::Create(
+ Ed25519Parameters::Variant::
+ kDoNotUseInsteadUseDefaultWhenWritingSwitchStatements)
+ .status(),
+ StatusIs(absl::StatusCode::kInvalidArgument));
+}
+
+TEST(Ed25519ParametersTest, CopyConstructor) {
+ util::StatusOr<Ed25519Parameters> parameters =
+ Ed25519Parameters::Create(Ed25519Parameters::Variant::kTink);
+ ASSERT_THAT(parameters, IsOk());
+
+ Ed25519Parameters copy(*parameters);
+
+ EXPECT_THAT(copy.GetVariant(), Eq(Ed25519Parameters::Variant::kTink));
+ EXPECT_THAT(copy.HasIdRequirement(), IsTrue());
+}
+
+TEST(Ed25519ParametersTest, CopyAssignment) {
+ util::StatusOr<Ed25519Parameters> parameters =
+ Ed25519Parameters::Create(Ed25519Parameters::Variant::kTink);
+ ASSERT_THAT(parameters, IsOk());
+
+ Ed25519Parameters copy = *parameters;
+
+ EXPECT_THAT(copy.GetVariant(), Eq(Ed25519Parameters::Variant::kTink));
+ EXPECT_THAT(copy.HasIdRequirement(), IsTrue());
+}
+
+TEST_P(Ed25519ParametersTest, ParametersEquals) {
+ TestCase test_case = GetParam();
+
+ util::StatusOr<Ed25519Parameters> parameters =
+ Ed25519Parameters::Create(test_case.variant);
+ ASSERT_THAT(parameters, IsOk());
+
+ util::StatusOr<Ed25519Parameters> other_parameters =
+ Ed25519Parameters::Create(test_case.variant);
+ ASSERT_THAT(other_parameters, IsOk());
+
+ EXPECT_TRUE(*parameters == *other_parameters);
+ EXPECT_TRUE(*other_parameters == *parameters);
+ EXPECT_FALSE(*parameters != *other_parameters);
+ EXPECT_FALSE(*other_parameters != *parameters);
+}
+
+TEST(Ed25519ParametersTest, VariantNotEqual) {
+ util::StatusOr<Ed25519Parameters> parameters =
+ Ed25519Parameters::Create(Ed25519Parameters::Variant::kTink);
+ ASSERT_THAT(parameters, IsOk());
+
+ util::StatusOr<Ed25519Parameters> other_parameters =
+ Ed25519Parameters::Create(Ed25519Parameters::Variant::kNoPrefix);
+ ASSERT_THAT(other_parameters, IsOk());
+
+ EXPECT_TRUE(*parameters != *other_parameters);
+ EXPECT_FALSE(*parameters == *other_parameters);
+}
+
+} // namespace
+} // namespace tink
+} // namespace crypto