From a022e2ecc45927d1e1e80c5d90f37a54fe9c08f2 Mon Sep 17 00:00:00 2001 From: Sjors Provoost Date: Thu, 1 Feb 2024 14:18:49 +0100 Subject: [PATCH] CKey: add Serialize and Unserialize Co-authored-by: Vasil Dimov --- src/key.h | 26 ++++++++++++++++++++++++++ src/test/key_tests.cpp | 23 +++++++++++++++++++++++ 2 files changed, 49 insertions(+) diff --git a/src/key.h b/src/key.h index 6ed6fd0fc3da77..d2ac120a0b062f 100644 --- a/src/key.h +++ b/src/key.h @@ -204,6 +204,7 @@ class CKey ECDHSecret ComputeBIP324ECDHSecret(const EllSwiftPubKey& their_ellswift, const EllSwiftPubKey& our_ellswift, bool initiating) const; + /** Compute a KeyPair * * Wraps a `secp256k1_keypair` type. @@ -220,6 +221,31 @@ class CKey * Merkle root of the script tree). */ KeyPair ComputeKeyPair(const uint256* merkle_root) const; + + /** Straight-forward serialization of key bytes (and compressed flag). + * Use GetPrivKey() for OpenSSL compatible DER encoding. + */ + template + void Serialize(Stream& s) const + { + if (!IsValid()) { + throw std::ios_base::failure("invalid key"); + } + s << fCompressed; + ::Serialize(s, Span{*this}); + } + + template + void Unserialize(Stream& s) + { + s >> fCompressed; + MakeKeyData(); + s >> Span{*keydata}; + if (!Check(keydata->data())) { + ClearKeyData(); + throw std::ios_base::failure("invalid key"); + } + } }; CKey GenerateRandomKey(bool compressed = true) noexcept; diff --git a/src/test/key_tests.cpp b/src/test/key_tests.cpp index 90e04bed8751dd..b6670218383f06 100644 --- a/src/test/key_tests.cpp +++ b/src/test/key_tests.cpp @@ -390,4 +390,27 @@ BOOST_AUTO_TEST_CASE(key_schnorr_tweak_smoke_test) secp256k1_context_destroy(secp256k1_context_sign); } +BOOST_AUTO_TEST_CASE(key_serialization) +{ + { + DataStream s{}; + CKey key; + BOOST_CHECK_EXCEPTION(s << key, std::ios_base::failure, + HasReason{"invalid key"}); + + s << MakeByteSpan(std::vector(33, std::byte(0))); + BOOST_CHECK_EXCEPTION(s >> key, std::ios_base::failure, + HasReason{"invalid key"}); + } + + for (bool compressed : {true, false}) { + CKey key{GenerateRandomKey(/*compressed=*/compressed)}; + DataStream s{}; + s << key; + CKey key_copy; + s >> key_copy; + BOOST_CHECK(key == key_copy); + } +} + BOOST_AUTO_TEST_SUITE_END()