25
25
#include " absl/strings/string_view.h"
26
26
#include " absl/types/optional.h"
27
27
#include " tink/experimental/pqcrypto/signature/slh_dsa_parameters.h"
28
+ #include " tink/experimental/pqcrypto/signature/slh_dsa_public_key.h"
29
+ #include " tink/insecure_secret_key_access.h"
28
30
#include " tink/internal/mutable_serialization_registry.h"
31
+ #include " tink/internal/proto_key_serialization.h"
29
32
#include " tink/internal/proto_parameters_serialization.h"
30
33
#include " tink/internal/serialization.h"
34
+ #include " tink/key.h"
31
35
#include " tink/parameters.h"
36
+ #include " tink/partial_key_access.h"
37
+ #include " tink/restricted_data.h"
38
+ #include " tink/subtle/random.h"
32
39
#include " tink/util/statusor.h"
33
40
#include " tink/util/test_matchers.h"
34
41
#include " proto/experimental/pqcrypto/slh_dsa.pb.h"
@@ -38,8 +45,10 @@ namespace crypto {
38
45
namespace tink {
39
46
namespace {
40
47
48
+ using ::crypto::tink::subtle::Random;
41
49
using ::crypto::tink::test::IsOk;
42
50
using ::crypto::tink::test::StatusIs;
51
+ using ::google::crypto::tink::KeyData;
43
52
using ::google::crypto::tink::OutputPrefixType;
44
53
using ::google::crypto::tink::SlhDsaHashType;
45
54
using ::google::crypto::tink::SlhDsaKeyFormat;
@@ -54,6 +63,8 @@ using ::testing::Values;
54
63
55
64
const absl::string_view kPrivateTypeUrl =
56
65
" type.googleapis.com/google.crypto.tink.SlhDsaPrivateKey" ;
66
+ const absl::string_view kPublicTypeUrl =
67
+ " type.googleapis.com/google.crypto.tink.SlhDsaPublicKey" ;
57
68
58
69
struct TestCase {
59
70
SlhDsaParameters::Variant variant;
@@ -289,6 +300,152 @@ TEST_P(SlhDsaProtoSerializationTest,
289
300
EXPECT_THAT (key_format.params ().key_size (), Eq (64 ));
290
301
}
291
302
303
+ TEST_P (SlhDsaProtoSerializationTest, ParsePublicKeyWorks) {
304
+ TestCase test_case = GetParam ();
305
+ ASSERT_THAT (RegisterSlhDsaProtoSerialization (), IsOk ());
306
+
307
+ SlhDsaParams params;
308
+ params.set_sig_type (SlhDsaSignatureType::SMALL_SIGNATURE);
309
+ params.set_hash_type (SlhDsaHashType::SHA2);
310
+ params.set_key_size (64 );
311
+
312
+ std::string raw_key_bytes = Random::GetRandomBytes (32 );
313
+ google::crypto::tink::SlhDsaPublicKey key_proto;
314
+ key_proto.set_version (0 );
315
+ key_proto.set_key_value (raw_key_bytes);
316
+ *key_proto.mutable_params () = params;
317
+ RestrictedData serialized_key = RestrictedData (
318
+ key_proto.SerializeAsString (), InsecureSecretKeyAccess::Get ());
319
+
320
+ util::StatusOr<internal::ProtoKeySerialization> serialization =
321
+ internal::ProtoKeySerialization::Create (
322
+ kPublicTypeUrl , serialized_key, KeyData::ASYMMETRIC_PUBLIC,
323
+ test_case.output_prefix_type , test_case.id_requirement );
324
+ ASSERT_THAT (serialization, IsOk ());
325
+
326
+ util::StatusOr<std::unique_ptr<Key>> key =
327
+ internal::MutableSerializationRegistry::GlobalInstance ().ParseKey (
328
+ *serialization, /* token=*/ absl::nullopt);
329
+ ASSERT_THAT (key, IsOk ());
330
+ EXPECT_THAT ((*key)->GetIdRequirement (), Eq (test_case.id_requirement ));
331
+ EXPECT_THAT ((*key)->GetParameters ().HasIdRequirement (),
332
+ test_case.id_requirement .has_value ());
333
+
334
+ util::StatusOr<SlhDsaParameters> expected_parameters =
335
+ SlhDsaParameters::Create (
336
+ SlhDsaParameters::HashType::kSha2 , /* private_key_size_in_bytes=*/ 64 ,
337
+ SlhDsaParameters::SignatureType::kSmallSignature , test_case.variant );
338
+ ASSERT_THAT (expected_parameters, IsOk ());
339
+
340
+ util::StatusOr<SlhDsaPublicKey> expected_key =
341
+ SlhDsaPublicKey::Create (*expected_parameters, raw_key_bytes,
342
+ test_case.id_requirement , GetPartialKeyAccess ());
343
+ ASSERT_THAT (expected_key, IsOk ());
344
+
345
+ EXPECT_THAT (**key, Eq (*expected_key));
346
+ }
347
+
348
+ TEST_F (SlhDsaProtoSerializationTest,
349
+ ParsePublicKeyWithInvalidSerializationFails) {
350
+ ASSERT_THAT (RegisterSlhDsaProtoSerialization (), IsOk ());
351
+
352
+ RestrictedData serialized_key =
353
+ RestrictedData (" invalid_serialization" , InsecureSecretKeyAccess::Get ());
354
+
355
+ util::StatusOr<internal::ProtoKeySerialization> serialization =
356
+ internal::ProtoKeySerialization::Create (kPublicTypeUrl , serialized_key,
357
+ KeyData::ASYMMETRIC_PUBLIC,
358
+ OutputPrefixType::TINK,
359
+ /* id_requirement=*/ 0x23456789 );
360
+ ASSERT_THAT (serialization, IsOk ());
361
+
362
+ util::StatusOr<std::unique_ptr<Key>> key =
363
+ internal::MutableSerializationRegistry::GlobalInstance ().ParseKey (
364
+ *serialization, InsecureSecretKeyAccess::Get ());
365
+ EXPECT_THAT (key.status (),
366
+ StatusIs (absl::StatusCode::kInvalidArgument ,
367
+ HasSubstr (" Failed to parse SlhDsaPublicKey proto" )));
368
+ }
369
+
370
+ TEST_F (SlhDsaProtoSerializationTest, ParsePublicKeyWithInvalidVersionFails) {
371
+ ASSERT_THAT (RegisterSlhDsaProtoSerialization (), IsOk ());
372
+
373
+ SlhDsaParams params;
374
+ params.set_sig_type (SlhDsaSignatureType::SMALL_SIGNATURE);
375
+ params.set_hash_type (SlhDsaHashType::SHA2);
376
+ params.set_key_size (64 );
377
+
378
+ std::string raw_key_bytes = Random::GetRandomBytes (32 );
379
+ google::crypto::tink::SlhDsaPublicKey key_proto;
380
+ key_proto.set_version (1 );
381
+ key_proto.set_key_value (raw_key_bytes);
382
+ *key_proto.mutable_params () = params;
383
+ RestrictedData serialized_key = RestrictedData (
384
+ key_proto.SerializeAsString (), InsecureSecretKeyAccess::Get ());
385
+
386
+ util::StatusOr<internal::ProtoKeySerialization> serialization =
387
+ internal::ProtoKeySerialization::Create (kPublicTypeUrl , serialized_key,
388
+ KeyData::ASYMMETRIC_PUBLIC,
389
+ OutputPrefixType::TINK,
390
+ /* id_requirement=*/ 0x23456789 );
391
+ ASSERT_THAT (serialization, IsOk ());
392
+
393
+ util::StatusOr<std::unique_ptr<Key>> key =
394
+ internal::MutableSerializationRegistry::GlobalInstance ().ParseKey (
395
+ *serialization, /* token=*/ absl::nullopt);
396
+ EXPECT_THAT (key.status (),
397
+ StatusIs (absl::StatusCode::kInvalidArgument ,
398
+ HasSubstr (" Only version 0 keys are accepted" )));
399
+ }
400
+
401
+ TEST_P (SlhDsaProtoSerializationTest, SerializePublicKeyWorks) {
402
+ TestCase test_case = GetParam ();
403
+ ASSERT_THAT (RegisterSlhDsaProtoSerialization (), IsOk ());
404
+
405
+ util::StatusOr<SlhDsaParameters> parameters = SlhDsaParameters::Create (
406
+ SlhDsaParameters::HashType::kSha2 , /* private_key_size_in_bytes=*/ 64 ,
407
+ SlhDsaParameters::SignatureType::kSmallSignature , test_case.variant );
408
+ ASSERT_THAT (parameters, IsOk ());
409
+
410
+ std::string raw_key_bytes = Random::GetRandomBytes (32 );
411
+ util::StatusOr<SlhDsaPublicKey> key =
412
+ SlhDsaPublicKey::Create (*parameters, raw_key_bytes,
413
+ test_case.id_requirement , GetPartialKeyAccess ());
414
+ ASSERT_THAT (key, IsOk ());
415
+
416
+ util::StatusOr<std::unique_ptr<Serialization>> serialization =
417
+ internal::MutableSerializationRegistry::GlobalInstance ()
418
+ .SerializeKey <internal::ProtoKeySerialization>(
419
+ *key, /* token=*/ absl::nullopt);
420
+ ASSERT_THAT (serialization, IsOk ());
421
+ EXPECT_THAT ((*serialization)->ObjectIdentifier (), Eq (kPublicTypeUrl ));
422
+
423
+ const internal::ProtoKeySerialization* proto_serialization =
424
+ dynamic_cast <const internal::ProtoKeySerialization*>(
425
+ serialization->get ());
426
+ ASSERT_THAT (proto_serialization, NotNull ());
427
+ EXPECT_THAT (proto_serialization->TypeUrl (), Eq (kPublicTypeUrl ));
428
+ EXPECT_THAT (proto_serialization->KeyMaterialType (),
429
+ Eq (KeyData::ASYMMETRIC_PUBLIC));
430
+ EXPECT_THAT (proto_serialization->GetOutputPrefixType (),
431
+ Eq (test_case.output_prefix_type ));
432
+ EXPECT_THAT (proto_serialization->IdRequirement (),
433
+ Eq (test_case.id_requirement ));
434
+
435
+ google::crypto::tink::SlhDsaPublicKey proto_key;
436
+ ASSERT_THAT (proto_key.ParseFromString (
437
+ proto_serialization->SerializedKeyProto ().GetSecret (
438
+ InsecureSecretKeyAccess::Get ())),
439
+ IsTrue ());
440
+ EXPECT_THAT (proto_key.version (), Eq (0 ));
441
+ EXPECT_THAT (proto_key.key_value (), Eq (raw_key_bytes));
442
+ EXPECT_THAT (proto_key.has_params (), IsTrue ());
443
+ EXPECT_THAT (proto_key.params ().key_size (), Eq (64 ));
444
+ EXPECT_THAT (proto_key.params ().hash_type (), Eq (SlhDsaHashType::SHA2));
445
+ EXPECT_THAT (proto_key.params ().sig_type (),
446
+ Eq (SlhDsaSignatureType::SMALL_SIGNATURE));
447
+ }
448
+
292
449
} // namespace
293
450
} // namespace tink
294
451
} // namespace crypto
0 commit comments