From ae6019b3a5f99e63b5f23e48fd430147b8500877 Mon Sep 17 00:00:00 2001 From: josibake Date: Tue, 18 Jul 2023 22:26:04 +0200 Subject: [PATCH] Add functions for decoding SP addresses Add a function for decoding the string address and a second function for decoding the data part of the silent payment address. --- src/key_io.cpp | 32 ++++++++++++++++++++++++++++++++ src/key_io.h | 4 ++++ 2 files changed, 36 insertions(+) diff --git a/src/key_io.cpp b/src/key_io.cpp index 454a96df5e5bc..46e2559077102 100644 --- a/src/key_io.cpp +++ b/src/key_io.cpp @@ -15,6 +15,8 @@ /// Maximum witness length for Bech32 addresses. static constexpr std::size_t BECH32_WITNESS_PROG_MAX_LEN = 40; +/// Data size for decoded Bech32m silent payment addresses (33 byte pubkey + 33 byte pubkey) +static constexpr std::size_t SILENT_PAYMENT_V0_DATA_SIZE = 66; namespace { class DestinationEncoder { @@ -309,3 +311,33 @@ bool IsValidDestinationString(const std::string& str) { return IsValidDestinationString(str, Params()); } + +std::pair DecodeSilentData(const std::vector& data) +{ + + std::vector scan_pubkey_data(data.begin(), data.begin() + 33); + CPubKey scan_pubkey{scan_pubkey_data}; + + std::vector spend_pubkey_data(data.begin() + 33, data.end()); + CPubKey spend_pubkey{spend_pubkey_data}; + + return {scan_pubkey, spend_pubkey}; +} + +std::vector DecodeSilentAddress(const std::string& str) +{ + const auto& params{Params()}; + const auto& silent_payment_hrp = params.SilentPaymentHRP(); + const auto dec = bech32::Decode(str, /*silent=*/true); + if (dec.encoding != bech32::Encoding::BECH32M || dec.hrp != silent_payment_hrp) { + return {}; + } + auto version = dec.data.front(); // retrieve the version + std::vector silent_payment_data; + silent_payment_data.reserve(((dec.data.size() - 1) * 5) / 8); + if (!ConvertBits<5, 8, false>([&](unsigned char c) { silent_payment_data.push_back(c); }, dec.data.begin() + 1, dec.data.end())) { + return {}; + } + if ((version == 0 && silent_payment_data.size() != SILENT_PAYMENT_V0_DATA_SIZE) || silent_payment_data.size() < SILENT_PAYMENT_V0_DATA_SIZE) return {}; + return silent_payment_data; +} diff --git a/src/key_io.h b/src/key_io.h index 07b80c4b859fe..9c67d819141d1 100644 --- a/src/key_io.h +++ b/src/key_io.h @@ -24,6 +24,10 @@ std::string EncodeExtPubKey(const CExtPubKey& extpubkey); std::string EncodeDestination(const CTxDestination& dest); CTxDestination DecodeDestination(const std::string& str); CTxDestination DecodeDestination(const std::string& str, std::string& error_msg, std::vector* error_locations = nullptr); + +std::pair DecodeSilentData(const std::vector& data); +std::vector DecodeSilentAddress(const std::string& str); + bool IsValidDestinationString(const std::string& str); bool IsValidDestinationString(const std::string& str, const CChainParams& params);