Skip to content

Commit

Permalink
refactor: Make ParseHex(const char*) consteval
Browse files Browse the repository at this point in the history
Introduces FixedVec<T, size_t> type - useful because ParseHex() supports whitespace intermingled with the hex string, resulting in a smaller size, making std::array use problematic. FixedVec allows returning a smaller size() than what is given in the template parameter.
  • Loading branch information
hodlinator committed Jul 16, 2024
1 parent dc5bf66 commit 92b0fb0
Show file tree
Hide file tree
Showing 15 changed files with 154 additions and 68 deletions.
2 changes: 1 addition & 1 deletion src/bench/bech32.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@

static void Bech32Encode(benchmark::Bench& bench)
{
std::vector<uint8_t> v = ParseHex("c97f5a67ec381b760aeaf67573bc164845ff39a3bb26a1cee401ac67243b48db");
constexpr FixedVec<uint8_t, 32> v = ParseHex("c97f5a67ec381b760aeaf67573bc164845ff39a3bb26a1cee401ac67243b48db");
std::vector<unsigned char> tmp = {0};
tmp.reserve(1 + 32 * 8 / 5);
ConvertBits<8, 5, true>([&](unsigned char c) { tmp.push_back(c); }, v.begin(), v.end());
Expand Down
2 changes: 1 addition & 1 deletion src/kernel/chainparams.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -297,7 +297,7 @@ class SigNetParams : public CChainParams {
vSeeds.clear();

if (!options.challenge) {
bin = ParseHex("512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae");
bin = ParseHex("512103ad5e0edad18cb1f0fc0d28a3d4f1f3e445640337489abb10404f2d1e086be430210359ef5021964fe22d6f8e05b2463c9540ce96883fe3b278760f048f5189f2e6c452ae").to_dynamic();
vSeeds.emplace_back("seed.signet.bitcoin.sprovoost.nl.");
vSeeds.emplace_back("seed.signet.achownodes.xyz."); // Ava Chow, only supports x1, x5, x9, x49, x809, x849, xd, x400, x404, x408, x448, xc08, xc48, x40c

Expand Down
9 changes: 1 addition & 8 deletions src/pubkey.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -190,14 +190,7 @@ int ecdsa_signature_parse_der_lax(secp256k1_ecdsa_signature* sig, const unsigned
* For an example script for calculating H, refer to the unit tests in
* ./test/functional/test_framework/crypto/secp256k1.py
*/
static const std::vector<unsigned char> NUMS_H_DATA{ParseHex("50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0")};
const XOnlyPubKey XOnlyPubKey::NUMS_H{NUMS_H_DATA};

XOnlyPubKey::XOnlyPubKey(Span<const unsigned char> bytes)
{
assert(bytes.size() == 32);
std::copy(bytes.begin(), bytes.end(), m_keydata.begin());
}
constexpr XOnlyPubKey XOnlyPubKey::NUMS_H{ParseHex("50929b74c1a04954b78b4b6035e97a5e078a5a0f28ec96d547bfee9ace803ac0")};

std::vector<CKeyID> XOnlyPubKey::GetKeyIDs() const
{
Expand Down
6 changes: 5 additions & 1 deletion src/pubkey.h
Original file line number Diff line number Diff line change
Expand Up @@ -254,7 +254,11 @@ class XOnlyPubKey
bool IsNull() const { return m_keydata.IsNull(); }

/** Construct an x-only pubkey from exactly 32 bytes. */
explicit XOnlyPubKey(Span<const unsigned char> bytes);
constexpr explicit XOnlyPubKey(Span<const unsigned char> bytes)
{
assert(bytes.size() == 32);
std::copy(bytes.begin(), bytes.end(), m_keydata.begin());
}

/** Construct an x-only pubkey from a normal pubkey. */
explicit XOnlyPubKey(const CPubKey& pubkey) : XOnlyPubKey(Span{pubkey}.subspan(1, 32)) {}
Expand Down
2 changes: 1 addition & 1 deletion src/script/script.h
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ class CScript : public CScriptBase
return *this;
}

CScript& operator<<(const std::vector<unsigned char>& b) LIFETIMEBOUND
CScript& operator<<(std::span<const unsigned char> b) LIFETIMEBOUND
{
if (b.size() < OP_PUSHDATA1)
{
Expand Down
2 changes: 1 addition & 1 deletion src/test/base58_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,7 @@ BOOST_AUTO_TEST_CASE(base58_DecodeBase58)
// check that DecodeBase58 skips whitespace, but still fails with unexpected non-whitespace at the end.
BOOST_CHECK(!DecodeBase58(" \t\n\v\f\r skip \r\f\v\n\t a", result, 3));
BOOST_CHECK( DecodeBase58(" \t\n\v\f\r skip \r\f\v\n\t ", result, 3));
std::vector<unsigned char> expected = ParseHex("971a55");
constexpr FixedVec<unsigned char, 3> expected = ParseHex("971a55");
BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());

BOOST_CHECK(DecodeBase58Check("3vQB7B6MrGQZaxCuFg4oh"s, result, 100));
Expand Down
8 changes: 4 additions & 4 deletions src/test/bloom_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize)
DataStream stream{};
stream << filter;

std::vector<uint8_t> expected = ParseHex("03614e9b050000000000000001");
constexpr FixedVec<uint8_t, 13> expected = ParseHex("03614e9b050000000000000001");
auto result{MakeUCharSpan(stream)};

BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
Expand All @@ -70,7 +70,7 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_serialize_with_tweak)
DataStream stream{};
stream << filter;

std::vector<uint8_t> expected = ParseHex("03ce4299050000000100008001");
constexpr FixedVec<uint8_t, 13> expected = ParseHex("03ce4299050000000100008001");
auto result{MakeUCharSpan(stream)};

BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
Expand All @@ -91,7 +91,7 @@ BOOST_AUTO_TEST_CASE(bloom_create_insert_key)
DataStream stream{};
stream << filter;

std::vector<unsigned char> expected = ParseHex("038fc16b080000000000000001");
constexpr FixedVec<unsigned char, 13> expected = ParseHex("038fc16b080000000000000001");
auto result{MakeUCharSpan(stream)};

BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
Expand Down Expand Up @@ -352,7 +352,7 @@ BOOST_AUTO_TEST_CASE(merkle_block_3_and_serialize)
DataStream merkleStream{};
merkleStream << merkleBlock;

std::vector<uint8_t> expected = ParseHex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101");
constexpr FixedVec<uint8_t, 119> expected = ParseHex("0100000079cda856b143d9db2c1caff01d1aecc8630d30625d10e8b4b8b0000000000000b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f196367291b4d4c86041b8fa45d630100000001b50cc069d6a3e33e3ff84a5c41d9d3febe7c770fdcc96b2c3ff60abe184f19630101");
auto result{MakeUCharSpan(merkleStream)};

BOOST_CHECK_EQUAL_COLLECTIONS(expected.begin(), expected.end(), result.begin(), result.end());
Expand Down
10 changes: 5 additions & 5 deletions src/test/descriptor_tests.cpp

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion src/test/key_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -338,7 +338,7 @@ BOOST_AUTO_TEST_CASE(key_ellswift)

BOOST_AUTO_TEST_CASE(bip341_test_h)
{
std::vector<unsigned char> G_uncompressed = ParseHex("0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8");
constexpr FixedVec<unsigned char, 65> G_uncompressed = ParseHex("0479be667ef9dcbbac55a06295ce870b07029bfcdb2dce28d959f2815b16f81798483ada7726a3c4655da4fbfc0e1108a8fd17b448a68554199c47d08ffb10d4b8");
HashWriter hw;
hw.write(MakeByteSpan(G_uncompressed));
XOnlyPubKey H{hw.GetSHA256()};
Expand Down
4 changes: 2 additions & 2 deletions src/test/miniscript_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -642,12 +642,12 @@ BOOST_AUTO_TEST_CASE(fixed_tests)

// Misc unit tests
// A Script with a non minimal push is invalid
std::vector<unsigned char> nonminpush = ParseHex("0000210232780000feff00ffffffffffff21ff005f00ae21ae00000000060602060406564c2102320000060900fe00005f00ae21ae00100000060606060606000000000000000000000000000000000000000000000000000000000000000000");
constexpr FixedVec<unsigned char, 96> nonminpush = ParseHex("0000210232780000feff00ffffffffffff21ff005f00ae21ae00000000060602060406564c2102320000060900fe00005f00ae21ae00100000060606060606000000000000000000000000000000000000000000000000000000000000000000");
const CScript nonminpush_script(nonminpush.begin(), nonminpush.end());
BOOST_CHECK(miniscript::FromScript(nonminpush_script, wsh_converter) == nullptr);
BOOST_CHECK(miniscript::FromScript(nonminpush_script, tap_converter) == nullptr);
// A non-minimal VERIFY (<key> CHECKSIG VERIFY 1)
std::vector<unsigned char> nonminverify = ParseHex("2103a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7ac6951");
constexpr FixedVec<unsigned char, 37> nonminverify = ParseHex("2103a0434d9e47f3c86235477c7b1ae6ae5d3442d49b1943c2b752a68e2a47e247c7ac6951");
const CScript nonminverify_script(nonminverify.begin(), nonminverify.end());
BOOST_CHECK(miniscript::FromScript(nonminverify_script, wsh_converter) == nullptr);
BOOST_CHECK(miniscript::FromScript(nonminverify_script, tap_converter) == nullptr);
Expand Down
61 changes: 35 additions & 26 deletions src/test/util_tests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -145,56 +145,65 @@ static const unsigned char ParseHex_expected[65] = {
};
BOOST_AUTO_TEST_CASE(parse_hex)
{
// Forces compile time evaluation so we use the correct ParseHex() overload.
auto compile_time = [] (auto input) consteval {
return input;
};

std::vector<unsigned char> result;
std::vector<unsigned char> expected(ParseHex_expected, ParseHex_expected + sizeof(ParseHex_expected));
// Basic test vector
result = ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f");
result = compile_time(ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f")).to_dynamic();
BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
result = ParseHex("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f"sv);
BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());
result = TryParseHex<uint8_t>("04678afdb0fe5548271967f1a67130b7105cd6a828e03909a67962e0ea1f61deb649f6bc3f4cef38c4f35504e51ec112de5c384df7ba0b8d578a4c702b6bf11d5f").value();
BOOST_CHECK_EQUAL_COLLECTIONS(result.begin(), result.end(), expected.begin(), expected.end());

// Spaces between bytes must be supported
result = ParseHex("12 34 56 78");
BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
result = TryParseHex<uint8_t>("12 34 56 78").value();
BOOST_CHECK(result.size() == 4 && result[0] == 0x12 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
BOOST_CHECK(std::vector<uint8_t>({0x12, 0x34, 0x56, 0x78}) == compile_time(ParseHex("12 34 56 78")));
BOOST_CHECK(std::vector<uint8_t>({0x12, 0x34, 0x56, 0x78}) == ParseHex("12 34 56 78"sv));
BOOST_CHECK(std::vector<uint8_t>({0x12, 0x34, 0x56, 0x78}) == TryParseHex<uint8_t>("12 34 56 78").value());

// Leading space must be supported (used in BerkeleyEnvironment::Salvage)
result = ParseHex(" 89 34 56 78");
BOOST_CHECK(result.size() == 4 && result[0] == 0x89 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
result = TryParseHex<uint8_t>(" 89 34 56 78").value();
BOOST_CHECK(result.size() == 4 && result[0] == 0x89 && result[1] == 0x34 && result[2] == 0x56 && result[3] == 0x78);
BOOST_CHECK(std::vector<uint8_t>({0x89, 0x34, 0x56, 0x78}) == compile_time(ParseHex(" 89 34 56 78")));
BOOST_CHECK(std::vector<uint8_t>({0x89, 0x34, 0x56, 0x78}) == ParseHex(" 89 34 56 78"sv));
BOOST_CHECK(std::vector<uint8_t>({0x89, 0x34, 0x56, 0x78}) == TryParseHex<uint8_t>(" 89 34 56 78").value());

// Mixed case and spaces are supported
result = ParseHex(" Ff aA ");
BOOST_CHECK(result.size() == 2 && result[0] == 0xff && result[1] == 0xaa);
result = TryParseHex<uint8_t>(" Ff aA ").value();
BOOST_CHECK(result.size() == 2 && result[0] == 0xff && result[1] == 0xaa);
BOOST_CHECK(std::vector<uint8_t>({0xff, 0xaa}) == compile_time(ParseHex(" Ff aA ")));
BOOST_CHECK(std::vector<uint8_t>({0xff, 0xaa}) == ParseHex(" Ff aA "sv));
BOOST_CHECK(std::vector<uint8_t>({0xff, 0xaa}) == TryParseHex<uint8_t>(" Ff aA ").value());

// Empty string is supported
result = ParseHex("");
BOOST_CHECK(result.size() == 0);
result = TryParseHex<uint8_t>("").value();
BOOST_CHECK(result.size() == 0);
BOOST_CHECK(compile_time(ParseHex("")).size() == 0);
BOOST_CHECK(ParseHex(""sv).size() == 0);
BOOST_CHECK(TryParseHex<uint8_t>("").value().size() == 0);

// Spaces between nibbles is treated as invalid
BOOST_CHECK_EQUAL(ParseHex("AAF F").size(), 0);
BOOST_CHECK_EQUAL(compile_time(ParseHex("AAF F")).size(), 0);
BOOST_CHECK_EQUAL(ParseHex("AAF F"sv).size(), 0);
BOOST_CHECK(!TryParseHex("AAF F").has_value());

// Embedded null is treated as invalid
const std::string with_embedded_null{" 11 "s
" \0 "
" 22 "s};
BOOST_CHECK_EQUAL(with_embedded_null.size(), 11);
BOOST_CHECK_EQUAL(ParseHex(with_embedded_null).size(), 0);
BOOST_CHECK(!TryParseHex(with_embedded_null).has_value());
constexpr char with_embedded_null[] = " 11 "
" \0 "
" 22 ";
const std::string_view with_embedded_null_str(with_embedded_null, 11);
BOOST_CHECK_EQUAL(sizeof(with_embedded_null), 12);
BOOST_CHECK_EQUAL(with_embedded_null_str.size(), 11);
BOOST_CHECK_EQUAL(compile_time(ParseHex(with_embedded_null)).size(), 0);
BOOST_CHECK_EQUAL(ParseHex(with_embedded_null_str).size(), 0);
BOOST_CHECK(!TryParseHex(with_embedded_null_str).has_value());

// Non-hex is treated as invalid
BOOST_CHECK_EQUAL(ParseHex("1234 invalid 1234").size(), 0);
BOOST_CHECK_EQUAL(compile_time(ParseHex("1234 invalid 1234")).size(), 0);
BOOST_CHECK_EQUAL(ParseHex("1234 invalid 1234"sv).size(), 0);
BOOST_CHECK(!TryParseHex("1234 invalid 1234").has_value());

// Truncated input is treated as invalid
BOOST_CHECK_EQUAL(ParseHex("12 3").size(), 0);
BOOST_CHECK_EQUAL(compile_time(ParseHex("12 3")).size(), 0);
BOOST_CHECK_EQUAL(ParseHex("12 3"sv).size(), 0);
BOOST_CHECK(!TryParseHex("12 3").has_value());
}

Expand Down
82 changes: 82 additions & 0 deletions src/util/strencodings.h
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
#include <span.h>
#include <util/string.h>

#include <algorithm>
#include <charconv>
#include <cstddef>
#include <cstdint>
Expand Down Expand Up @@ -67,6 +68,87 @@ std::vector<Byte> ParseHex(std::string_view hex_str)
{
return TryParseHex<Byte>(hex_str).value_or(std::vector<Byte>{});
}

/**
* Max size fixed at compile time.
* Created to be used on the border between runtime and compile time which a
* dynamically allocating std::vector cannot cross.
* The type was created in preference over std::array to be able to parse hex
* strings at compile time which may contain whitespace, making exact size()
* unknown ahead of template instantiation.
*/
template<typename T, size_t N>
class FixedVec
{
std::array<T, N> m_data{};
size_t m_size{0};

public:
constexpr const T* data() const { return m_data.data(); }
constexpr size_t size() const { return m_size; }
constexpr const T* begin() const { return data(); }
constexpr const T* end() const { return data() + m_size; }
constexpr void push_back(const T& v)
{
assert(m_size < N);
m_data[m_size] = v;
++m_size;
}

/// Enables creation of a runtime allocated vector when necessary.
// NOT just a plain `operator std::vector<T>()` since we want to expose
// allocations.
constexpr std::vector<T> to_dynamic() const
{
return {begin(), end()};
}
};

template <typename T, size_t N>
constexpr bool operator==(const std::vector<T>& a, const FixedVec<T, N>& b)
{
return std::ranges::equal(a, b);
}

constexpr inline bool IsSpace(char c) noexcept;
template <typename Byte = uint8_t, size_t Size>
consteval FixedVec<Byte, Size / 2> ParseHex(const char (&hex_str)[Size])
{
// Non lookup table version of HexDigit().
auto from_hex = [](const uint8_t c) -> std::optional<uint8_t> {
if (c >= '0' && c <= '9')
return std::make_optional<uint8_t>(c - '0');
else if (c >= 'a' && c <= 'f')
return std::make_optional<uint8_t>(c - uint8_t{'a' - 0xA});
else if (c >= 'A' && c <= 'F')
return std::make_optional<uint8_t>(c - uint8_t{'A' - 0xA});
else
return std::nullopt;
};

FixedVec<Byte, Size / 2> rv;
size_t it = 0;
while (it < (Size - 1)) { // -1 - Assumes null-term at the end.
if (IsSpace(hex_str[it])) {
++it;
continue;
}
auto c1 = from_hex(hex_str[it++]);
if (it >= Size)
return {};
if (!c1.has_value())
return {};
auto c1_value = c1.value();
c1_value <<= 4;
Byte elem{c1_value};
auto c2 = from_hex(hex_str[it++]);
if (!c2.has_value())
return {};
elem |= Byte{c2.value()};
rv.push_back(elem);
}
return rv;
}
/* Returns true if each character in str is a hex character, and has an even
* number of hex digits.*/
bool IsHex(std::string_view str);
Expand Down
6 changes: 3 additions & 3 deletions src/wallet/crypter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
#include <vector>

namespace wallet {
int CCrypter::BytesToKeySHA512AES(const std::vector<unsigned char>& chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const
int CCrypter::BytesToKeySHA512AES(std::span<const unsigned char> chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const
{
// This mimics the behavior of openssl's EVP_BytesToKey with an aes256cbc
// cipher and sha512 message digest. Because sha512's output size (64b) is
Expand All @@ -37,7 +37,7 @@ int CCrypter::BytesToKeySHA512AES(const std::vector<unsigned char>& chSalt, cons
return WALLET_CRYPTO_KEY_SIZE;
}

bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
bool CCrypter::SetKeyFromPassphrase(const SecureString& strKeyData, std::span<const unsigned char> chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod)
{
if (nRounds < 1 || chSalt.size() != WALLET_CRYPTO_SALT_SIZE)
return false;
Expand Down Expand Up @@ -87,7 +87,7 @@ bool CCrypter::Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned
return true;
}

bool CCrypter::Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext) const
bool CCrypter::Decrypt(std::span<const unsigned char> vchCiphertext, CKeyingMaterial& vchPlaintext) const
{
if (!fKeySet)
return false;
Expand Down
6 changes: 3 additions & 3 deletions src/wallet/crypter.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@ friend class wallet_crypto_tests::TestCrypter; // for test access to chKey/chIV
std::vector<unsigned char, secure_allocator<unsigned char>> vchIV;
bool fKeySet;

int BytesToKeySHA512AES(const std::vector<unsigned char>& chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const;
int BytesToKeySHA512AES(std::span<const unsigned char> chSalt, const SecureString& strKeyData, int count, unsigned char *key,unsigned char *iv) const;

public:
bool SetKeyFromPassphrase(const SecureString &strKeyData, const std::vector<unsigned char>& chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
bool SetKeyFromPassphrase(const SecureString& strKeyData, std::span<const unsigned char> chSalt, const unsigned int nRounds, const unsigned int nDerivationMethod);
bool Encrypt(const CKeyingMaterial& vchPlaintext, std::vector<unsigned char> &vchCiphertext) const;
bool Decrypt(const std::vector<unsigned char>& vchCiphertext, CKeyingMaterial& vchPlaintext) const;
bool Decrypt(std::span<const unsigned char> vchCiphertext, CKeyingMaterial& vchPlaintext) const;
bool SetKey(const CKeyingMaterial& chNewKey, const std::vector<unsigned char>& chNewIV);

void CleanKey()
Expand Down
Loading

0 comments on commit 92b0fb0

Please sign in to comment.