20
20
#include " absl/strings/string_view.h"
21
21
#include " absl/types/optional.h"
22
22
#include " tink/experimental/pqcrypto/signature/slh_dsa_parameters.h"
23
+ #include " tink/experimental/pqcrypto/signature/slh_dsa_private_key.h"
23
24
#include " tink/experimental/pqcrypto/signature/slh_dsa_public_key.h"
24
25
#include " tink/insecure_secret_key_access.h"
25
26
#include " tink/internal/key_parser.h"
@@ -59,6 +60,11 @@ using SlhDsaProtoPublicKeyParserImpl =
59
60
using SlhDsaProtoPublicKeySerializerImpl =
60
61
internal::KeySerializerImpl<SlhDsaPublicKey,
61
62
internal::ProtoKeySerialization>;
63
+ using SlhDsaProtoPrivateKeyParserImpl =
64
+ internal::KeyParserImpl<internal::ProtoKeySerialization, SlhDsaPrivateKey>;
65
+ using SlhDsaProtoPrivateKeySerializerImpl =
66
+ internal::KeySerializerImpl<SlhDsaPrivateKey,
67
+ internal::ProtoKeySerialization>;
62
68
63
69
const absl::string_view kPrivateTypeUrl =
64
70
" type.googleapis.com/google.crypto.tink.SlhDsaPrivateKey" ;
@@ -249,6 +255,46 @@ util::StatusOr<SlhDsaPublicKey> ParsePublicKey(
249
255
GetPartialKeyAccess ());
250
256
}
251
257
258
+ util::StatusOr<SlhDsaPrivateKey> ParsePrivateKey (
259
+ const internal::ProtoKeySerialization& serialization,
260
+ absl::optional<SecretKeyAccessToken> token) {
261
+ if (serialization.TypeUrl () != kPrivateTypeUrl ) {
262
+ return util::Status (absl::StatusCode::kInvalidArgument ,
263
+ " Wrong type URL when parsing SlhDsaPrivateKey." );
264
+ }
265
+ if (!token.has_value ()) {
266
+ return util::Status (absl::StatusCode::kPermissionDenied ,
267
+ " SecretKeyAccess is required" );
268
+ }
269
+ google::crypto::tink::SlhDsaPrivateKey proto_key;
270
+ const RestrictedData& restricted_data = serialization.SerializedKeyProto ();
271
+ if (!proto_key.ParseFromString (restricted_data.GetSecret (*token))) {
272
+ return util::Status (absl::StatusCode::kInvalidArgument ,
273
+ " Failed to parse SlhDsaPrivateKey proto" );
274
+ }
275
+ if (proto_key.version () != 0 ) {
276
+ return util::Status (absl::StatusCode::kInvalidArgument ,
277
+ " Only version 0 keys are accepted." );
278
+ }
279
+
280
+ util::StatusOr<SlhDsaParameters> parameters = ToParameters (
281
+ serialization.GetOutputPrefixType (), proto_key.public_key ().params ());
282
+ if (!parameters.ok ()) {
283
+ return parameters.status ();
284
+ }
285
+
286
+ util::StatusOr<SlhDsaPublicKey> public_key = SlhDsaPublicKey::Create (
287
+ *parameters, proto_key.public_key ().key_value (),
288
+ serialization.IdRequirement (), GetPartialKeyAccess ());
289
+ if (!public_key.ok ()) {
290
+ return public_key.status ();
291
+ }
292
+
293
+ return SlhDsaPrivateKey::Create (*public_key,
294
+ RestrictedData (proto_key.key_value (), *token),
295
+ GetPartialKeyAccess ());
296
+ }
297
+
252
298
util::StatusOr<internal::ProtoParametersSerialization> SerializeParameters (
253
299
const SlhDsaParameters& parameters) {
254
300
util::StatusOr<OutputPrefixType> output_prefix_type =
@@ -295,6 +341,48 @@ util::StatusOr<internal::ProtoKeySerialization> SerializePublicKey(
295
341
*output_prefix_type, key.GetIdRequirement ());
296
342
}
297
343
344
+ util::StatusOr<internal::ProtoKeySerialization> SerializePrivateKey (
345
+ const SlhDsaPrivateKey& key, absl::optional<SecretKeyAccessToken> token) {
346
+ if (!token.has_value ()) {
347
+ return util::Status (absl::StatusCode::kPermissionDenied ,
348
+ " SecretKeyAccess is required" );
349
+ }
350
+ util::StatusOr<RestrictedData> restricted_input =
351
+ key.GetPrivateKeyBytes (GetPartialKeyAccess ());
352
+ if (!restricted_input.ok ()) {
353
+ return restricted_input.status ();
354
+ }
355
+
356
+ util::StatusOr<SlhDsaParams> params =
357
+ FromParameters (key.GetPublicKey ().GetParameters ());
358
+ if (!params.ok ()) {
359
+ return params.status ();
360
+ }
361
+
362
+ google::crypto::tink::SlhDsaPublicKey proto_public_key;
363
+ proto_public_key.set_version (0 );
364
+ *proto_public_key.mutable_params () = *params;
365
+ proto_public_key.set_key_value (
366
+ key.GetPublicKey ().GetPublicKeyBytes (GetPartialKeyAccess ()));
367
+
368
+ google::crypto::tink::SlhDsaPrivateKey proto_private_key;
369
+ proto_private_key.set_version (0 );
370
+ *proto_private_key.mutable_public_key () = proto_public_key;
371
+ proto_private_key.set_key_value (restricted_input->GetSecret (*token));
372
+
373
+ util::StatusOr<OutputPrefixType> output_prefix_type =
374
+ ToOutputPrefixType (key.GetPublicKey ().GetParameters ().GetVariant ());
375
+ if (!output_prefix_type.ok ()) {
376
+ return output_prefix_type.status ();
377
+ }
378
+
379
+ RestrictedData restricted_output =
380
+ RestrictedData (proto_private_key.SerializeAsString (), *token);
381
+ return internal::ProtoKeySerialization::Create (
382
+ kPrivateTypeUrl , restricted_output, KeyData::ASYMMETRIC_PRIVATE,
383
+ *output_prefix_type, key.GetIdRequirement ());
384
+ }
385
+
298
386
SlhDsaProtoParametersParserImpl& SlhDsaProtoParametersParser () {
299
387
static auto parser =
300
388
new SlhDsaProtoParametersParserImpl (kPrivateTypeUrl , ParseParameters);
@@ -319,6 +407,18 @@ SlhDsaProtoPublicKeySerializerImpl& SlhDsaProtoPublicKeySerializer() {
319
407
return *serializer;
320
408
}
321
409
410
+ SlhDsaProtoPrivateKeyParserImpl& SlhDsaProtoPrivateKeyParser () {
411
+ static auto * parser =
412
+ new SlhDsaProtoPrivateKeyParserImpl (kPrivateTypeUrl , ParsePrivateKey);
413
+ return *parser;
414
+ }
415
+
416
+ SlhDsaProtoPrivateKeySerializerImpl& SlhDsaProtoPrivateKeySerializer () {
417
+ static auto * serializer =
418
+ new SlhDsaProtoPrivateKeySerializerImpl (SerializePrivateKey);
419
+ return *serializer;
420
+ }
421
+
322
422
} // namespace
323
423
324
424
util::Status RegisterSlhDsaProtoSerialization () {
@@ -342,8 +442,20 @@ util::Status RegisterSlhDsaProtoSerialization() {
342
442
return status;
343
443
}
344
444
445
+ status = internal::MutableSerializationRegistry::GlobalInstance ()
446
+ .RegisterKeySerializer (&SlhDsaProtoPublicKeySerializer ());
447
+ if (!status.ok ()) {
448
+ return status;
449
+ }
450
+
451
+ status = internal::MutableSerializationRegistry::GlobalInstance ()
452
+ .RegisterKeyParser (&SlhDsaProtoPrivateKeyParser ());
453
+ if (!status.ok ()) {
454
+ return status;
455
+ }
456
+
345
457
return internal::MutableSerializationRegistry::GlobalInstance ()
346
- .RegisterKeySerializer (&SlhDsaProtoPublicKeySerializer ());
458
+ .RegisterKeySerializer (&SlhDsaProtoPrivateKeySerializer ());
347
459
}
348
460
349
461
} // namespace tink
0 commit comments