Skip to content
This repository was archived by the owner on Apr 17, 2024. It is now read-only.

Commit d847e39

Browse files
ioannanedelcucopybara-github
authored andcommitted
Add proto parser and serializer for SLH-DSA private key.
PiperOrigin-RevId: 625599407
1 parent 1798b7c commit d847e39

File tree

2 files changed

+393
-1
lines changed

2 files changed

+393
-1
lines changed

cc/experimental/pqcrypto/signature/slh_dsa_proto_serialization.cc

+113-1
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "absl/strings/string_view.h"
2121
#include "absl/types/optional.h"
2222
#include "tink/experimental/pqcrypto/signature/slh_dsa_parameters.h"
23+
#include "tink/experimental/pqcrypto/signature/slh_dsa_private_key.h"
2324
#include "tink/experimental/pqcrypto/signature/slh_dsa_public_key.h"
2425
#include "tink/insecure_secret_key_access.h"
2526
#include "tink/internal/key_parser.h"
@@ -59,6 +60,11 @@ using SlhDsaProtoPublicKeyParserImpl =
5960
using SlhDsaProtoPublicKeySerializerImpl =
6061
internal::KeySerializerImpl<SlhDsaPublicKey,
6162
internal::ProtoKeySerialization>;
63+
using SlhDsaProtoPrivateKeyParserImpl =
64+
internal::KeyParserImpl<internal::ProtoKeySerialization, SlhDsaPrivateKey>;
65+
using SlhDsaProtoPrivateKeySerializerImpl =
66+
internal::KeySerializerImpl<SlhDsaPrivateKey,
67+
internal::ProtoKeySerialization>;
6268

6369
const absl::string_view kPrivateTypeUrl =
6470
"type.googleapis.com/google.crypto.tink.SlhDsaPrivateKey";
@@ -249,6 +255,46 @@ util::StatusOr<SlhDsaPublicKey> ParsePublicKey(
249255
GetPartialKeyAccess());
250256
}
251257

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+
252298
util::StatusOr<internal::ProtoParametersSerialization> SerializeParameters(
253299
const SlhDsaParameters& parameters) {
254300
util::StatusOr<OutputPrefixType> output_prefix_type =
@@ -295,6 +341,48 @@ util::StatusOr<internal::ProtoKeySerialization> SerializePublicKey(
295341
*output_prefix_type, key.GetIdRequirement());
296342
}
297343

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+
298386
SlhDsaProtoParametersParserImpl& SlhDsaProtoParametersParser() {
299387
static auto parser =
300388
new SlhDsaProtoParametersParserImpl(kPrivateTypeUrl, ParseParameters);
@@ -319,6 +407,18 @@ SlhDsaProtoPublicKeySerializerImpl& SlhDsaProtoPublicKeySerializer() {
319407
return *serializer;
320408
}
321409

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+
322422
} // namespace
323423

324424
util::Status RegisterSlhDsaProtoSerialization() {
@@ -342,8 +442,20 @@ util::Status RegisterSlhDsaProtoSerialization() {
342442
return status;
343443
}
344444

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+
345457
return internal::MutableSerializationRegistry::GlobalInstance()
346-
.RegisterKeySerializer(&SlhDsaProtoPublicKeySerializer());
458+
.RegisterKeySerializer(&SlhDsaProtoPrivateKeySerializer());
347459
}
348460

349461
} // namespace tink

0 commit comments

Comments
 (0)