1*e7b1675dSTing-Kang Chang // Copyright 2023 Google LLC
2*e7b1675dSTing-Kang Chang //
3*e7b1675dSTing-Kang Chang // Licensed under the Apache License, Version 2.0 (the "License");
4*e7b1675dSTing-Kang Chang // you may not use this file except in compliance with the License.
5*e7b1675dSTing-Kang Chang // You may obtain a copy of the License at
6*e7b1675dSTing-Kang Chang //
7*e7b1675dSTing-Kang Chang // http://www.apache.org/licenses/LICENSE-2.0
8*e7b1675dSTing-Kang Chang //
9*e7b1675dSTing-Kang Chang // Unless required by applicable law or agreed to in writing, software
10*e7b1675dSTing-Kang Chang // distributed under the License is distributed on an "AS IS" BASIS,
11*e7b1675dSTing-Kang Chang // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12*e7b1675dSTing-Kang Chang // See the License for the specific language governing permissions and
13*e7b1675dSTing-Kang Chang // limitations under the License.
14*e7b1675dSTing-Kang Chang //
15*e7b1675dSTing-Kang Chang ////////////////////////////////////////////////////////////////////////////////
16*e7b1675dSTing-Kang Chang
17*e7b1675dSTing-Kang Chang #include "tink/signature/ed25519_proto_serialization.h"
18*e7b1675dSTing-Kang Chang
19*e7b1675dSTing-Kang Chang #include <string>
20*e7b1675dSTing-Kang Chang
21*e7b1675dSTing-Kang Chang #include "absl/status/status.h"
22*e7b1675dSTing-Kang Chang #include "absl/strings/string_view.h"
23*e7b1675dSTing-Kang Chang #include "absl/types/optional.h"
24*e7b1675dSTing-Kang Chang #include "tink/insecure_secret_key_access.h"
25*e7b1675dSTing-Kang Chang #include "tink/internal/key_parser.h"
26*e7b1675dSTing-Kang Chang #include "tink/internal/key_serializer.h"
27*e7b1675dSTing-Kang Chang #include "tink/internal/mutable_serialization_registry.h"
28*e7b1675dSTing-Kang Chang #include "tink/internal/parameters_parser.h"
29*e7b1675dSTing-Kang Chang #include "tink/internal/parameters_serializer.h"
30*e7b1675dSTing-Kang Chang #include "tink/internal/proto_key_serialization.h"
31*e7b1675dSTing-Kang Chang #include "tink/internal/proto_parameters_serialization.h"
32*e7b1675dSTing-Kang Chang #include "tink/partial_key_access.h"
33*e7b1675dSTing-Kang Chang #include "tink/restricted_data.h"
34*e7b1675dSTing-Kang Chang #include "tink/secret_key_access_token.h"
35*e7b1675dSTing-Kang Chang #include "tink/signature/ed25519_parameters.h"
36*e7b1675dSTing-Kang Chang #include "tink/signature/ed25519_private_key.h"
37*e7b1675dSTing-Kang Chang #include "tink/signature/ed25519_public_key.h"
38*e7b1675dSTing-Kang Chang #include "tink/util/status.h"
39*e7b1675dSTing-Kang Chang #include "tink/util/statusor.h"
40*e7b1675dSTing-Kang Chang #include "proto/ed25519.pb.h"
41*e7b1675dSTing-Kang Chang #include "proto/tink.pb.h"
42*e7b1675dSTing-Kang Chang
43*e7b1675dSTing-Kang Chang namespace crypto {
44*e7b1675dSTing-Kang Chang namespace tink {
45*e7b1675dSTing-Kang Chang namespace {
46*e7b1675dSTing-Kang Chang
47*e7b1675dSTing-Kang Chang using ::google::crypto::tink::Ed25519KeyFormat;
48*e7b1675dSTing-Kang Chang using ::google::crypto::tink::KeyData;
49*e7b1675dSTing-Kang Chang using ::google::crypto::tink::OutputPrefixType;
50*e7b1675dSTing-Kang Chang
51*e7b1675dSTing-Kang Chang using Ed25519ProtoParametersParserImpl =
52*e7b1675dSTing-Kang Chang internal::ParametersParserImpl<internal::ProtoParametersSerialization,
53*e7b1675dSTing-Kang Chang Ed25519Parameters>;
54*e7b1675dSTing-Kang Chang using Ed25519ProtoParametersSerializerImpl =
55*e7b1675dSTing-Kang Chang internal::ParametersSerializerImpl<Ed25519Parameters,
56*e7b1675dSTing-Kang Chang internal::ProtoParametersSerialization>;
57*e7b1675dSTing-Kang Chang using Ed25519ProtoPublicKeyParserImpl =
58*e7b1675dSTing-Kang Chang internal::KeyParserImpl<internal::ProtoKeySerialization, Ed25519PublicKey>;
59*e7b1675dSTing-Kang Chang using Ed25519ProtoPublicKeySerializerImpl =
60*e7b1675dSTing-Kang Chang internal::KeySerializerImpl<Ed25519PublicKey,
61*e7b1675dSTing-Kang Chang internal::ProtoKeySerialization>;
62*e7b1675dSTing-Kang Chang using Ed25519ProtoPrivateKeyParserImpl =
63*e7b1675dSTing-Kang Chang internal::KeyParserImpl<internal::ProtoKeySerialization, Ed25519PrivateKey>;
64*e7b1675dSTing-Kang Chang using Ed25519ProtoPrivateKeySerializerImpl =
65*e7b1675dSTing-Kang Chang internal::KeySerializerImpl<Ed25519PrivateKey,
66*e7b1675dSTing-Kang Chang internal::ProtoKeySerialization>;
67*e7b1675dSTing-Kang Chang
68*e7b1675dSTing-Kang Chang const absl::string_view kPublicTypeUrl =
69*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.Ed25519PublicKey";
70*e7b1675dSTing-Kang Chang const absl::string_view kPrivateTypeUrl =
71*e7b1675dSTing-Kang Chang "type.googleapis.com/google.crypto.tink.Ed25519PrivateKey";
72*e7b1675dSTing-Kang Chang
ToVariant(OutputPrefixType output_prefix_type)73*e7b1675dSTing-Kang Chang util::StatusOr<Ed25519Parameters::Variant> ToVariant(
74*e7b1675dSTing-Kang Chang OutputPrefixType output_prefix_type) {
75*e7b1675dSTing-Kang Chang switch (output_prefix_type) {
76*e7b1675dSTing-Kang Chang case OutputPrefixType::LEGACY:
77*e7b1675dSTing-Kang Chang return Ed25519Parameters::Variant::kLegacy;
78*e7b1675dSTing-Kang Chang case OutputPrefixType::CRUNCHY:
79*e7b1675dSTing-Kang Chang return Ed25519Parameters::Variant::kCrunchy;
80*e7b1675dSTing-Kang Chang case OutputPrefixType::RAW:
81*e7b1675dSTing-Kang Chang return Ed25519Parameters::Variant::kNoPrefix;
82*e7b1675dSTing-Kang Chang case OutputPrefixType::TINK:
83*e7b1675dSTing-Kang Chang return Ed25519Parameters::Variant::kTink;
84*e7b1675dSTing-Kang Chang default:
85*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
86*e7b1675dSTing-Kang Chang "Could not determine Ed25519Parameters::Variant");
87*e7b1675dSTing-Kang Chang }
88*e7b1675dSTing-Kang Chang }
89*e7b1675dSTing-Kang Chang
ToOutputPrefixType(Ed25519Parameters::Variant variant)90*e7b1675dSTing-Kang Chang util::StatusOr<OutputPrefixType> ToOutputPrefixType(
91*e7b1675dSTing-Kang Chang Ed25519Parameters::Variant variant) {
92*e7b1675dSTing-Kang Chang switch (variant) {
93*e7b1675dSTing-Kang Chang case Ed25519Parameters::Variant::kLegacy:
94*e7b1675dSTing-Kang Chang return OutputPrefixType::LEGACY;
95*e7b1675dSTing-Kang Chang case Ed25519Parameters::Variant::kCrunchy:
96*e7b1675dSTing-Kang Chang return OutputPrefixType::CRUNCHY;
97*e7b1675dSTing-Kang Chang case Ed25519Parameters::Variant::kNoPrefix:
98*e7b1675dSTing-Kang Chang return OutputPrefixType::RAW;
99*e7b1675dSTing-Kang Chang case Ed25519Parameters::Variant::kTink:
100*e7b1675dSTing-Kang Chang return OutputPrefixType::TINK;
101*e7b1675dSTing-Kang Chang default:
102*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
103*e7b1675dSTing-Kang Chang "Could not determine output prefix type");
104*e7b1675dSTing-Kang Chang }
105*e7b1675dSTing-Kang Chang }
106*e7b1675dSTing-Kang Chang
ParseParameters(const internal::ProtoParametersSerialization & serialization)107*e7b1675dSTing-Kang Chang util::StatusOr<Ed25519Parameters> ParseParameters(
108*e7b1675dSTing-Kang Chang const internal::ProtoParametersSerialization& serialization) {
109*e7b1675dSTing-Kang Chang if (serialization.GetKeyTemplate().type_url() != kPrivateTypeUrl) {
110*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
111*e7b1675dSTing-Kang Chang "Wrong type URL when parsing Ed25519Parameters.");
112*e7b1675dSTing-Kang Chang }
113*e7b1675dSTing-Kang Chang
114*e7b1675dSTing-Kang Chang Ed25519KeyFormat proto_key_format;
115*e7b1675dSTing-Kang Chang if (!proto_key_format.ParseFromString(
116*e7b1675dSTing-Kang Chang serialization.GetKeyTemplate().value())) {
117*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
118*e7b1675dSTing-Kang Chang "Failed to parse Ed25519KeyFormat proto");
119*e7b1675dSTing-Kang Chang }
120*e7b1675dSTing-Kang Chang if (proto_key_format.version() != 0) {
121*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
122*e7b1675dSTing-Kang Chang "Only version 0 keys are accepted.");
123*e7b1675dSTing-Kang Chang }
124*e7b1675dSTing-Kang Chang
125*e7b1675dSTing-Kang Chang util::StatusOr<Ed25519Parameters::Variant> variant =
126*e7b1675dSTing-Kang Chang ToVariant(serialization.GetKeyTemplate().output_prefix_type());
127*e7b1675dSTing-Kang Chang if (!variant.ok()) {
128*e7b1675dSTing-Kang Chang return variant.status();
129*e7b1675dSTing-Kang Chang }
130*e7b1675dSTing-Kang Chang
131*e7b1675dSTing-Kang Chang return Ed25519Parameters::Create(*variant);
132*e7b1675dSTing-Kang Chang }
133*e7b1675dSTing-Kang Chang
ParsePublicKey(const internal::ProtoKeySerialization & serialization,absl::optional<SecretKeyAccessToken> token)134*e7b1675dSTing-Kang Chang util::StatusOr<Ed25519PublicKey> ParsePublicKey(
135*e7b1675dSTing-Kang Chang const internal::ProtoKeySerialization& serialization,
136*e7b1675dSTing-Kang Chang absl::optional<SecretKeyAccessToken> token) {
137*e7b1675dSTing-Kang Chang if (serialization.TypeUrl() != kPublicTypeUrl) {
138*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
139*e7b1675dSTing-Kang Chang "Wrong type URL when parsing Ed25519PublicKey.");
140*e7b1675dSTing-Kang Chang }
141*e7b1675dSTing-Kang Chang
142*e7b1675dSTing-Kang Chang google::crypto::tink::Ed25519PublicKey proto_key;
143*e7b1675dSTing-Kang Chang RestrictedData restricted_data = serialization.SerializedKeyProto();
144*e7b1675dSTing-Kang Chang // OSS proto library complains if input is not converted to a string.
145*e7b1675dSTing-Kang Chang if (!proto_key.ParseFromString(std::string(
146*e7b1675dSTing-Kang Chang restricted_data.GetSecret(InsecureSecretKeyAccess::Get())))) {
147*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
148*e7b1675dSTing-Kang Chang "Failed to parse Ed25519PublicKey proto");
149*e7b1675dSTing-Kang Chang }
150*e7b1675dSTing-Kang Chang if (proto_key.version() != 0) {
151*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
152*e7b1675dSTing-Kang Chang "Only version 0 keys are accepted.");
153*e7b1675dSTing-Kang Chang }
154*e7b1675dSTing-Kang Chang
155*e7b1675dSTing-Kang Chang util::StatusOr<Ed25519Parameters::Variant> variant =
156*e7b1675dSTing-Kang Chang ToVariant(serialization.GetOutputPrefixType());
157*e7b1675dSTing-Kang Chang if (!variant.ok()) {
158*e7b1675dSTing-Kang Chang return variant.status();
159*e7b1675dSTing-Kang Chang }
160*e7b1675dSTing-Kang Chang
161*e7b1675dSTing-Kang Chang util::StatusOr<Ed25519Parameters> parameters =
162*e7b1675dSTing-Kang Chang Ed25519Parameters::Create(*variant);
163*e7b1675dSTing-Kang Chang if (!parameters.ok()) {
164*e7b1675dSTing-Kang Chang return parameters.status();
165*e7b1675dSTing-Kang Chang }
166*e7b1675dSTing-Kang Chang
167*e7b1675dSTing-Kang Chang return Ed25519PublicKey::Create(*parameters, proto_key.key_value(),
168*e7b1675dSTing-Kang Chang serialization.IdRequirement(),
169*e7b1675dSTing-Kang Chang GetPartialKeyAccess());
170*e7b1675dSTing-Kang Chang }
171*e7b1675dSTing-Kang Chang
ParsePrivateKey(const internal::ProtoKeySerialization & serialization,absl::optional<SecretKeyAccessToken> token)172*e7b1675dSTing-Kang Chang util::StatusOr<Ed25519PrivateKey> ParsePrivateKey(
173*e7b1675dSTing-Kang Chang const internal::ProtoKeySerialization& serialization,
174*e7b1675dSTing-Kang Chang absl::optional<SecretKeyAccessToken> token) {
175*e7b1675dSTing-Kang Chang if (serialization.TypeUrl() != kPrivateTypeUrl) {
176*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
177*e7b1675dSTing-Kang Chang "Wrong type URL when parsing Ed25519PrivateKey.");
178*e7b1675dSTing-Kang Chang }
179*e7b1675dSTing-Kang Chang if (!token.has_value()) {
180*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kPermissionDenied,
181*e7b1675dSTing-Kang Chang "SecretKeyAccess is required");
182*e7b1675dSTing-Kang Chang }
183*e7b1675dSTing-Kang Chang google::crypto::tink::Ed25519PrivateKey proto_key;
184*e7b1675dSTing-Kang Chang RestrictedData restricted_data = serialization.SerializedKeyProto();
185*e7b1675dSTing-Kang Chang // OSS proto library complains if input is not converted to a string.
186*e7b1675dSTing-Kang Chang if (!proto_key.ParseFromString(
187*e7b1675dSTing-Kang Chang std::string(restricted_data.GetSecret(*token)))) {
188*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
189*e7b1675dSTing-Kang Chang "Failed to parse Ed25519PrivateKey proto");
190*e7b1675dSTing-Kang Chang }
191*e7b1675dSTing-Kang Chang if (proto_key.version() != 0) {
192*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kInvalidArgument,
193*e7b1675dSTing-Kang Chang "Only version 0 keys are accepted.");
194*e7b1675dSTing-Kang Chang }
195*e7b1675dSTing-Kang Chang
196*e7b1675dSTing-Kang Chang util::StatusOr<Ed25519Parameters::Variant> variant =
197*e7b1675dSTing-Kang Chang ToVariant(serialization.GetOutputPrefixType());
198*e7b1675dSTing-Kang Chang if (!variant.ok()) {
199*e7b1675dSTing-Kang Chang return variant.status();
200*e7b1675dSTing-Kang Chang }
201*e7b1675dSTing-Kang Chang
202*e7b1675dSTing-Kang Chang util::StatusOr<Ed25519Parameters> parameters =
203*e7b1675dSTing-Kang Chang Ed25519Parameters::Create(*variant);
204*e7b1675dSTing-Kang Chang if (!parameters.ok()) {
205*e7b1675dSTing-Kang Chang return parameters.status();
206*e7b1675dSTing-Kang Chang }
207*e7b1675dSTing-Kang Chang
208*e7b1675dSTing-Kang Chang util::StatusOr<Ed25519PublicKey> public_key = Ed25519PublicKey::Create(
209*e7b1675dSTing-Kang Chang *parameters, proto_key.public_key().key_value(),
210*e7b1675dSTing-Kang Chang serialization.IdRequirement(), GetPartialKeyAccess());
211*e7b1675dSTing-Kang Chang if (!public_key.ok()) {
212*e7b1675dSTing-Kang Chang return public_key.status();
213*e7b1675dSTing-Kang Chang }
214*e7b1675dSTing-Kang Chang
215*e7b1675dSTing-Kang Chang return Ed25519PrivateKey::Create(
216*e7b1675dSTing-Kang Chang *public_key, RestrictedData(proto_key.key_value(), *token),
217*e7b1675dSTing-Kang Chang GetPartialKeyAccess());
218*e7b1675dSTing-Kang Chang }
219*e7b1675dSTing-Kang Chang
SerializeParameters(const Ed25519Parameters & parameters)220*e7b1675dSTing-Kang Chang util::StatusOr<internal::ProtoParametersSerialization> SerializeParameters(
221*e7b1675dSTing-Kang Chang const Ed25519Parameters& parameters) {
222*e7b1675dSTing-Kang Chang util::StatusOr<OutputPrefixType> output_prefix_type =
223*e7b1675dSTing-Kang Chang ToOutputPrefixType(parameters.GetVariant());
224*e7b1675dSTing-Kang Chang if (!output_prefix_type.ok()) {
225*e7b1675dSTing-Kang Chang return output_prefix_type.status();
226*e7b1675dSTing-Kang Chang }
227*e7b1675dSTing-Kang Chang
228*e7b1675dSTing-Kang Chang Ed25519KeyFormat proto_key_format;
229*e7b1675dSTing-Kang Chang proto_key_format.set_version(0);
230*e7b1675dSTing-Kang Chang
231*e7b1675dSTing-Kang Chang return internal::ProtoParametersSerialization::Create(
232*e7b1675dSTing-Kang Chang kPrivateTypeUrl, *output_prefix_type,
233*e7b1675dSTing-Kang Chang proto_key_format.SerializeAsString());
234*e7b1675dSTing-Kang Chang }
235*e7b1675dSTing-Kang Chang
SerializePublicKey(const Ed25519PublicKey & key,absl::optional<SecretKeyAccessToken> token)236*e7b1675dSTing-Kang Chang util::StatusOr<internal::ProtoKeySerialization> SerializePublicKey(
237*e7b1675dSTing-Kang Chang const Ed25519PublicKey& key, absl::optional<SecretKeyAccessToken> token) {
238*e7b1675dSTing-Kang Chang google::crypto::tink::Ed25519PublicKey proto_key;
239*e7b1675dSTing-Kang Chang proto_key.set_version(0);
240*e7b1675dSTing-Kang Chang // OSS proto library complains if input is not converted to a string.
241*e7b1675dSTing-Kang Chang proto_key.set_key_value(
242*e7b1675dSTing-Kang Chang std::string(key.GetPublicKeyBytes(GetPartialKeyAccess())));
243*e7b1675dSTing-Kang Chang
244*e7b1675dSTing-Kang Chang util::StatusOr<OutputPrefixType> output_prefix_type =
245*e7b1675dSTing-Kang Chang ToOutputPrefixType(key.GetParameters().GetVariant());
246*e7b1675dSTing-Kang Chang if (!output_prefix_type.ok()) {
247*e7b1675dSTing-Kang Chang return output_prefix_type.status();
248*e7b1675dSTing-Kang Chang }
249*e7b1675dSTing-Kang Chang
250*e7b1675dSTing-Kang Chang RestrictedData restricted_output = RestrictedData(
251*e7b1675dSTing-Kang Chang proto_key.SerializeAsString(), InsecureSecretKeyAccess::Get());
252*e7b1675dSTing-Kang Chang return internal::ProtoKeySerialization::Create(
253*e7b1675dSTing-Kang Chang kPublicTypeUrl, restricted_output, KeyData::ASYMMETRIC_PUBLIC,
254*e7b1675dSTing-Kang Chang *output_prefix_type, key.GetIdRequirement());
255*e7b1675dSTing-Kang Chang }
256*e7b1675dSTing-Kang Chang
SerializePrivateKey(const Ed25519PrivateKey & key,absl::optional<SecretKeyAccessToken> token)257*e7b1675dSTing-Kang Chang util::StatusOr<internal::ProtoKeySerialization> SerializePrivateKey(
258*e7b1675dSTing-Kang Chang const Ed25519PrivateKey& key, absl::optional<SecretKeyAccessToken> token) {
259*e7b1675dSTing-Kang Chang util::StatusOr<RestrictedData> restricted_input =
260*e7b1675dSTing-Kang Chang key.GetPrivateKeyBytes(GetPartialKeyAccess());
261*e7b1675dSTing-Kang Chang if (!restricted_input.ok()) {
262*e7b1675dSTing-Kang Chang return restricted_input.status();
263*e7b1675dSTing-Kang Chang }
264*e7b1675dSTing-Kang Chang if (!token.has_value()) {
265*e7b1675dSTing-Kang Chang return util::Status(absl::StatusCode::kPermissionDenied,
266*e7b1675dSTing-Kang Chang "SecretKeyAccess is required");
267*e7b1675dSTing-Kang Chang }
268*e7b1675dSTing-Kang Chang
269*e7b1675dSTing-Kang Chang google::crypto::tink::Ed25519PublicKey proto_public_key;
270*e7b1675dSTing-Kang Chang proto_public_key.set_version(0);
271*e7b1675dSTing-Kang Chang // OSS proto library complains if input is not converted to a string.
272*e7b1675dSTing-Kang Chang proto_public_key.set_key_value(
273*e7b1675dSTing-Kang Chang std::string(key.GetPublicKey().GetPublicKeyBytes(GetPartialKeyAccess())));
274*e7b1675dSTing-Kang Chang
275*e7b1675dSTing-Kang Chang google::crypto::tink::Ed25519PrivateKey proto_private_key;
276*e7b1675dSTing-Kang Chang proto_private_key.set_version(0);
277*e7b1675dSTing-Kang Chang *proto_private_key.mutable_public_key() = proto_public_key;
278*e7b1675dSTing-Kang Chang // OSS proto library complains if input is not converted to a string.
279*e7b1675dSTing-Kang Chang proto_private_key.set_key_value(
280*e7b1675dSTing-Kang Chang std::string(restricted_input->GetSecret(*token)));
281*e7b1675dSTing-Kang Chang
282*e7b1675dSTing-Kang Chang util::StatusOr<OutputPrefixType> output_prefix_type =
283*e7b1675dSTing-Kang Chang ToOutputPrefixType(key.GetPublicKey().GetParameters().GetVariant());
284*e7b1675dSTing-Kang Chang if (!output_prefix_type.ok()) {
285*e7b1675dSTing-Kang Chang return output_prefix_type.status();
286*e7b1675dSTing-Kang Chang }
287*e7b1675dSTing-Kang Chang
288*e7b1675dSTing-Kang Chang RestrictedData restricted_output =
289*e7b1675dSTing-Kang Chang RestrictedData(proto_private_key.SerializeAsString(), *token);
290*e7b1675dSTing-Kang Chang return internal::ProtoKeySerialization::Create(
291*e7b1675dSTing-Kang Chang kPrivateTypeUrl, restricted_output, KeyData::ASYMMETRIC_PRIVATE,
292*e7b1675dSTing-Kang Chang *output_prefix_type, key.GetIdRequirement());
293*e7b1675dSTing-Kang Chang }
294*e7b1675dSTing-Kang Chang
Ed25519ProtoParametersParser()295*e7b1675dSTing-Kang Chang Ed25519ProtoParametersParserImpl* Ed25519ProtoParametersParser() {
296*e7b1675dSTing-Kang Chang static auto* parser =
297*e7b1675dSTing-Kang Chang new Ed25519ProtoParametersParserImpl(kPrivateTypeUrl, ParseParameters);
298*e7b1675dSTing-Kang Chang return parser;
299*e7b1675dSTing-Kang Chang }
300*e7b1675dSTing-Kang Chang
Ed25519ProtoParametersSerializer()301*e7b1675dSTing-Kang Chang Ed25519ProtoParametersSerializerImpl* Ed25519ProtoParametersSerializer() {
302*e7b1675dSTing-Kang Chang static auto* serializer = new Ed25519ProtoParametersSerializerImpl(
303*e7b1675dSTing-Kang Chang kPrivateTypeUrl, SerializeParameters);
304*e7b1675dSTing-Kang Chang return serializer;
305*e7b1675dSTing-Kang Chang }
306*e7b1675dSTing-Kang Chang
Ed25519ProtoPublicKeyParser()307*e7b1675dSTing-Kang Chang Ed25519ProtoPublicKeyParserImpl* Ed25519ProtoPublicKeyParser() {
308*e7b1675dSTing-Kang Chang static auto* parser =
309*e7b1675dSTing-Kang Chang new Ed25519ProtoPublicKeyParserImpl(kPublicTypeUrl, ParsePublicKey);
310*e7b1675dSTing-Kang Chang return parser;
311*e7b1675dSTing-Kang Chang }
312*e7b1675dSTing-Kang Chang
Ed25519ProtoPublicKeySerializer()313*e7b1675dSTing-Kang Chang Ed25519ProtoPublicKeySerializerImpl* Ed25519ProtoPublicKeySerializer() {
314*e7b1675dSTing-Kang Chang static auto* serializer =
315*e7b1675dSTing-Kang Chang new Ed25519ProtoPublicKeySerializerImpl(SerializePublicKey);
316*e7b1675dSTing-Kang Chang return serializer;
317*e7b1675dSTing-Kang Chang }
318*e7b1675dSTing-Kang Chang
Ed25519ProtoPrivateKeyParser()319*e7b1675dSTing-Kang Chang Ed25519ProtoPrivateKeyParserImpl* Ed25519ProtoPrivateKeyParser() {
320*e7b1675dSTing-Kang Chang static auto* parser =
321*e7b1675dSTing-Kang Chang new Ed25519ProtoPrivateKeyParserImpl(kPrivateTypeUrl, ParsePrivateKey);
322*e7b1675dSTing-Kang Chang return parser;
323*e7b1675dSTing-Kang Chang }
324*e7b1675dSTing-Kang Chang
Ed25519ProtoPrivateKeySerializer()325*e7b1675dSTing-Kang Chang Ed25519ProtoPrivateKeySerializerImpl* Ed25519ProtoPrivateKeySerializer() {
326*e7b1675dSTing-Kang Chang static auto* serializer =
327*e7b1675dSTing-Kang Chang new Ed25519ProtoPrivateKeySerializerImpl(SerializePrivateKey);
328*e7b1675dSTing-Kang Chang return serializer;
329*e7b1675dSTing-Kang Chang }
330*e7b1675dSTing-Kang Chang
331*e7b1675dSTing-Kang Chang } // namespace
332*e7b1675dSTing-Kang Chang
RegisterEd25519ProtoSerialization()333*e7b1675dSTing-Kang Chang util::Status RegisterEd25519ProtoSerialization() {
334*e7b1675dSTing-Kang Chang util::Status status =
335*e7b1675dSTing-Kang Chang internal::MutableSerializationRegistry::GlobalInstance()
336*e7b1675dSTing-Kang Chang .RegisterParametersParser(Ed25519ProtoParametersParser());
337*e7b1675dSTing-Kang Chang if (!status.ok()) {
338*e7b1675dSTing-Kang Chang return status;
339*e7b1675dSTing-Kang Chang }
340*e7b1675dSTing-Kang Chang
341*e7b1675dSTing-Kang Chang status =
342*e7b1675dSTing-Kang Chang internal::MutableSerializationRegistry::GlobalInstance()
343*e7b1675dSTing-Kang Chang .RegisterParametersSerializer(Ed25519ProtoParametersSerializer());
344*e7b1675dSTing-Kang Chang if (!status.ok()) {
345*e7b1675dSTing-Kang Chang return status;
346*e7b1675dSTing-Kang Chang }
347*e7b1675dSTing-Kang Chang
348*e7b1675dSTing-Kang Chang status = internal::MutableSerializationRegistry::GlobalInstance()
349*e7b1675dSTing-Kang Chang .RegisterKeyParser(Ed25519ProtoPublicKeyParser());
350*e7b1675dSTing-Kang Chang if (!status.ok()) {
351*e7b1675dSTing-Kang Chang return status;
352*e7b1675dSTing-Kang Chang }
353*e7b1675dSTing-Kang Chang
354*e7b1675dSTing-Kang Chang status = internal::MutableSerializationRegistry::GlobalInstance()
355*e7b1675dSTing-Kang Chang .RegisterKeySerializer(Ed25519ProtoPublicKeySerializer());
356*e7b1675dSTing-Kang Chang if (!status.ok()) {
357*e7b1675dSTing-Kang Chang return status;
358*e7b1675dSTing-Kang Chang }
359*e7b1675dSTing-Kang Chang
360*e7b1675dSTing-Kang Chang status = internal::MutableSerializationRegistry::GlobalInstance()
361*e7b1675dSTing-Kang Chang .RegisterKeyParser(Ed25519ProtoPrivateKeyParser());
362*e7b1675dSTing-Kang Chang if (!status.ok()) {
363*e7b1675dSTing-Kang Chang return status;
364*e7b1675dSTing-Kang Chang }
365*e7b1675dSTing-Kang Chang
366*e7b1675dSTing-Kang Chang return internal::MutableSerializationRegistry::GlobalInstance()
367*e7b1675dSTing-Kang Chang .RegisterKeySerializer(Ed25519ProtoPrivateKeySerializer());
368*e7b1675dSTing-Kang Chang }
369*e7b1675dSTing-Kang Chang
370*e7b1675dSTing-Kang Chang } // namespace tink
371*e7b1675dSTing-Kang Chang } // namespace crypto
372