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

Commit 3e4e908

Browse files
ioannanedelcucopybara-github
authored andcommitted
Add proto parser and serializer for SLH-DSA parameters.
PiperOrigin-RevId: 625366253
1 parent f3c76e1 commit 3e4e908

File tree

3 files changed

+577
-0
lines changed

3 files changed

+577
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,252 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
////////////////////////////////////////////////////////////////////////////////
16+
17+
#include "tink/experimental/pqcrypto/signature/slh_dsa_proto_serialization.h"
18+
19+
#include "absl/status/status.h"
20+
#include "absl/strings/string_view.h"
21+
#include "tink/experimental/pqcrypto/signature/slh_dsa_parameters.h"
22+
#include "tink/internal/mutable_serialization_registry.h"
23+
#include "tink/internal/parameters_parser.h"
24+
#include "tink/internal/parameters_serializer.h"
25+
#include "tink/internal/proto_parameters_serialization.h"
26+
#include "tink/util/status.h"
27+
#include "tink/util/statusor.h"
28+
#include "proto/experimental/pqcrypto/slh_dsa.pb.h"
29+
#include "proto/tink.pb.h"
30+
31+
namespace crypto {
32+
namespace tink {
33+
namespace {
34+
35+
using ::google::crypto::tink::OutputPrefixType;
36+
using ::google::crypto::tink::SlhDsaHashType;
37+
using ::google::crypto::tink::SlhDsaKeyFormat;
38+
using ::google::crypto::tink::SlhDsaParams;
39+
using ::google::crypto::tink::SlhDsaSignatureType;
40+
41+
using SlhDsaProtoParametersParserImpl =
42+
internal::ParametersParserImpl<internal::ProtoParametersSerialization,
43+
SlhDsaParameters>;
44+
using SlhDsaProtoParametersSerializerImpl =
45+
internal::ParametersSerializerImpl<SlhDsaParameters,
46+
internal::ProtoParametersSerialization>;
47+
48+
const absl::string_view kPrivateTypeUrl =
49+
"type.googleapis.com/google.crypto.tink.SlhDsaPrivateKey";
50+
51+
util::StatusOr<SlhDsaParameters::Variant> ToVariant(
52+
OutputPrefixType output_prefix_type) {
53+
switch (output_prefix_type) {
54+
case OutputPrefixType::RAW:
55+
return SlhDsaParameters::Variant::kNoPrefix;
56+
case OutputPrefixType::TINK:
57+
return SlhDsaParameters::Variant::kTink;
58+
default:
59+
return util::Status(absl::StatusCode::kInvalidArgument,
60+
"Could not determine SlhDsaParameters::Variant");
61+
}
62+
}
63+
64+
util::StatusOr<OutputPrefixType> ToOutputPrefixType(
65+
SlhDsaParameters::Variant variant) {
66+
switch (variant) {
67+
case SlhDsaParameters::Variant::kNoPrefix:
68+
return OutputPrefixType::RAW;
69+
case SlhDsaParameters::Variant::kTink:
70+
return OutputPrefixType::TINK;
71+
default:
72+
return util::Status(absl::StatusCode::kInvalidArgument,
73+
"Could not determine output prefix type");
74+
}
75+
}
76+
77+
util::StatusOr<SlhDsaParameters::HashType> ToHashType(
78+
SlhDsaHashType proto_hash_type) {
79+
switch (proto_hash_type) {
80+
case SlhDsaHashType::SHA2:
81+
return SlhDsaParameters::HashType::kSha2;
82+
case SlhDsaHashType::SHAKE:
83+
return SlhDsaParameters::HashType::kShake;
84+
default:
85+
return util::Status(absl::StatusCode::kInvalidArgument,
86+
"Could not determine SlhDsaParameters::HashType");
87+
}
88+
}
89+
90+
util::StatusOr<SlhDsaHashType> ToProtoHashType(
91+
SlhDsaParameters::HashType hash_type) {
92+
switch (hash_type) {
93+
case SlhDsaParameters::HashType::kSha2:
94+
return SlhDsaHashType::SHA2;
95+
case SlhDsaParameters::HashType::kShake:
96+
return SlhDsaHashType::SHAKE;
97+
default:
98+
return util::Status(absl::StatusCode::kInvalidArgument,
99+
"Could not determine SlhDsaHashType");
100+
}
101+
}
102+
103+
util::StatusOr<SlhDsaParameters::SignatureType> ToSignatureType(
104+
SlhDsaSignatureType proto_signature_type) {
105+
switch (proto_signature_type) {
106+
case SlhDsaSignatureType::FAST_SIGNING:
107+
return SlhDsaParameters::SignatureType::kFastSigning;
108+
case SlhDsaSignatureType::SMALL_SIGNATURE:
109+
return SlhDsaParameters::SignatureType::kSmallSignature;
110+
default:
111+
return util::Status(
112+
absl::StatusCode::kInvalidArgument,
113+
"Could not determine SlhDsaParameters::SignatureType");
114+
}
115+
}
116+
117+
util::StatusOr<SlhDsaSignatureType> ToProtoSignatureType(
118+
SlhDsaParameters::SignatureType signature_type) {
119+
switch (signature_type) {
120+
case SlhDsaParameters::SignatureType::kFastSigning:
121+
return SlhDsaSignatureType::FAST_SIGNING;
122+
case SlhDsaParameters::SignatureType::kSmallSignature:
123+
return SlhDsaSignatureType::SMALL_SIGNATURE;
124+
default:
125+
return util::Status(absl::StatusCode::kInvalidArgument,
126+
"Could not determine SlhDsaSignatureType");
127+
}
128+
}
129+
130+
util::StatusOr<SlhDsaParameters> ToParameters(
131+
OutputPrefixType output_prefix_type, const SlhDsaParams& params) {
132+
util::StatusOr<SlhDsaParameters::Variant> variant =
133+
ToVariant(output_prefix_type);
134+
if (!variant.ok()) {
135+
return variant.status();
136+
}
137+
138+
util::StatusOr<SlhDsaParameters::HashType> hash_type =
139+
ToHashType(params.hash_type());
140+
if (!hash_type.ok()) {
141+
return hash_type.status();
142+
}
143+
144+
util::StatusOr<SlhDsaParameters::SignatureType> signature_type =
145+
ToSignatureType(params.sig_type());
146+
if (!signature_type.ok()) {
147+
return signature_type.status();
148+
}
149+
150+
return SlhDsaParameters::Create(*hash_type, params.key_size(),
151+
*signature_type, *variant);
152+
}
153+
154+
util::StatusOr<SlhDsaParams> FromParameters(
155+
const SlhDsaParameters& parameters) {
156+
/* Only SLH-DSA-SHA2-128s is currently supported*/
157+
util::StatusOr<SlhDsaHashType> hash_type =
158+
ToProtoHashType(parameters.GetHashType());
159+
if (!hash_type.ok()) {
160+
return hash_type.status();
161+
}
162+
163+
util::StatusOr<SlhDsaSignatureType> signature_type =
164+
ToProtoSignatureType(parameters.GetSignatureType());
165+
if (!signature_type.ok()) {
166+
return signature_type.status();
167+
}
168+
169+
SlhDsaParams params;
170+
params.set_key_size(parameters.GetPrivateKeySizeInBytes());
171+
params.set_hash_type(*hash_type);
172+
params.set_sig_type(*signature_type);
173+
174+
return params;
175+
}
176+
177+
util::StatusOr<SlhDsaParameters> ParseParameters(
178+
const internal::ProtoParametersSerialization& serialization) {
179+
if (serialization.GetKeyTemplate().type_url() != kPrivateTypeUrl) {
180+
return util::Status(absl::StatusCode::kInvalidArgument,
181+
"Wrong type URL when parsing SlhDsaParameters.");
182+
}
183+
184+
SlhDsaKeyFormat proto_key_format;
185+
if (!proto_key_format.ParseFromString(
186+
serialization.GetKeyTemplate().value())) {
187+
return util::Status(absl::StatusCode::kInvalidArgument,
188+
"Failed to parse SlhDsaKeyFormat proto");
189+
}
190+
if (proto_key_format.version() != 0) {
191+
return util::Status(absl::StatusCode::kInvalidArgument,
192+
"Only version 0 keys are accepted.");
193+
}
194+
195+
if (!proto_key_format.has_params()) {
196+
return util::Status(absl::StatusCode::kInvalidArgument,
197+
"SlhDsaKeyFormat proto is missing params field.");
198+
}
199+
200+
return ToParameters(serialization.GetKeyTemplate().output_prefix_type(),
201+
proto_key_format.params());
202+
}
203+
204+
util::StatusOr<internal::ProtoParametersSerialization> SerializeParameters(
205+
const SlhDsaParameters& parameters) {
206+
util::StatusOr<OutputPrefixType> output_prefix_type =
207+
ToOutputPrefixType(parameters.GetVariant());
208+
if (!output_prefix_type.ok()) {
209+
return output_prefix_type.status();
210+
}
211+
212+
util::StatusOr<SlhDsaParams> params = FromParameters(parameters);
213+
if (!params.ok()) {
214+
return params.status();
215+
}
216+
SlhDsaKeyFormat proto_key_format;
217+
*proto_key_format.mutable_params() = *params;
218+
proto_key_format.set_version(0);
219+
220+
return internal::ProtoParametersSerialization::Create(
221+
kPrivateTypeUrl, *output_prefix_type,
222+
proto_key_format.SerializeAsString());
223+
}
224+
225+
SlhDsaProtoParametersParserImpl* SlhDsaProtoParametersParser() {
226+
static auto* parser =
227+
new SlhDsaProtoParametersParserImpl(kPrivateTypeUrl, ParseParameters);
228+
return parser;
229+
}
230+
231+
SlhDsaProtoParametersSerializerImpl* SlhDsaProtoParametersSerializer() {
232+
static auto* serializer = new SlhDsaProtoParametersSerializerImpl(
233+
kPrivateTypeUrl, SerializeParameters);
234+
return serializer;
235+
}
236+
237+
} // namespace
238+
239+
util::Status RegisterSlhDsaProtoSerialization() {
240+
util::Status status =
241+
internal::MutableSerializationRegistry::GlobalInstance()
242+
.RegisterParametersParser(SlhDsaProtoParametersParser());
243+
if (!status.ok()) {
244+
return status;
245+
}
246+
247+
return internal::MutableSerializationRegistry::GlobalInstance()
248+
.RegisterParametersSerializer(SlhDsaProtoParametersSerializer());
249+
}
250+
251+
} // namespace tink
252+
} // namespace crypto
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,31 @@
1+
// Copyright 2024 Google LLC
2+
//
3+
// Licensed under the Apache License, Version 2.0 (the "License");
4+
// you may not use this file except in compliance with the License.
5+
// You may obtain a copy of the License at
6+
//
7+
// http://www.apache.org/licenses/LICENSE-2.0
8+
//
9+
// Unless required by applicable law or agreed to in writing, software
10+
// distributed under the License is distributed on an "AS IS" BASIS,
11+
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12+
// See the License for the specific language governing permissions and
13+
// limitations under the License.
14+
//
15+
////////////////////////////////////////////////////////////////////////////////
16+
17+
#ifndef TINK_EXPERIMENTAL_PQCRYPTO_SIGNATURE_SLH_DSA_PROTO_SERIALIZATION_H_
18+
#define TINK_EXPERIMENTAL_PQCRYPTO_SIGNATURE_SLH_DSA_PROTO_SERIALIZATION_H_
19+
20+
#include "tink/util/status.h"
21+
22+
namespace crypto {
23+
namespace tink {
24+
25+
// Registers proto parsers and serializers for SLH-DSA parameters and keys.
26+
crypto::tink::util::Status RegisterSlhDsaProtoSerialization();
27+
28+
} // namespace tink
29+
} // namespace crypto
30+
31+
#endif // TINK_EXPERIMENTAL_PQCRYPTO_SIGNATURE_SLH_DSA_PROTO_SERIALIZATION_H_

0 commit comments

Comments
 (0)