xref: /aosp_15_r20/external/tink/cc/signature/ed25519_proto_serialization.cc (revision e7b1675dde1b92d52ec075b0a92829627f2c52a5)
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