1
0
forked from cheng/wallet

wiped scalars on destruction, and added extended public keys to unit_test.cpp

This commit is contained in:
Cheng 2024-08-02 05:36:07 +00:00
parent 133b7d27c8
commit ba84172bbd
No known key found for this signature in database
8 changed files with 38 additions and 34 deletions

View File

@ -56,7 +56,6 @@ namespace ro {
auto st = (*this)->Isqlite3_column_blob(i);
if (st.size_bytes() != sizeof(T)) throw BadDataException();
static_assert (std::is_standard_layout<T>(), "not standard layout");
static_assert (std::is_trivial<T>(), "not trivial");
return reinterpret_cast<const T*>(&st[0]);
}
else if constexpr (std::is_integral<T>::value) {

View File

@ -21,7 +21,7 @@ namespace ristretto255 {
point point::ptBase({
0xe2, 0xf2, 0xae, 0x0a, 0x6a, 0xbc, 0x4e, 0x71, 0xa8, 0x84, 0xa9, 0x61, 0xc5, 0x00, 0x51, 0x5f, 0x58, 0xe3, 0x0b, 0x6a, 0xa5, 0x82, 0xdd, 0x8d, 0xb6, 0xa6, 0x59, 0x45, 0xe0, 0x8d, 0x2d, 0x76});
static constexpr scalar curveOrder({ 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7,
static const scalar curveOrder({ 0xed, 0xd3, 0xf5, 0x5c, 0x1a, 0x63, 0x12, 0x58, 0xd6, 0x9c, 0xf7,
0xa2, 0xde, 0xf9, 0xde, 0x14, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x10 });
const scalar& scalar::scOrder{ curveOrder };

View File

@ -334,7 +334,7 @@ namespace ristretto255 {
std::array<uint8_t, crypto_core_ristretto255_SCALARBYTES> blob;
static_assert(sizeof(blob) == 32, "watch for size and alignment bugs. Everyone should standarize on 256 bit secret keys except for special needs");
explicit scalar() = default;
~scalar() = default;
~scalar() noexcept { wxSecretValue::Wipe(sizeof(*this), this); }
explicit constexpr scalar(std::array<uint8_t, crypto_core_ristretto255_BYTES>&& in) : blob{ in } {};
explicit constexpr scalar(std::array<uint8_t, crypto_core_ristretto255_BYTES>* in) :blob(*in) {};
explicit constexpr scalar(uintmax_t k){ for (auto& j : blob) { j = k; k = k >> 8; } }
@ -480,7 +480,6 @@ namespace ristretto255 {
// and DBL_MANT_DIG
static_assert(sizeof(decltype(ro::serialize(std::declval<scalar>())[0])) == 1);
static_assert (std::is_standard_layout<scalar>(), "scalar for some reason is not standard layout");
static_assert (std::is_trivial<scalar>(), "scalar for some reason is not trivial");
static_assert(sizeof(point) == 32, "funny alignment");
static_assert(sizeof(scalar) == 32, "funny alignment");

View File

@ -63,26 +63,26 @@ ristretto255::scalar DeriveSecret(const scalar &sc, uint_fast64_t i) {
}
namespace ristretto255 {
extended_private_key::extended_private_key(extended_private_key& parent, std::span<byte> path) :
extended_private_key::extended_private_key(extended_private_key& parent, std::span<byte> path) noexcept:
privatekey(parent.privatekey* scalar(hash<512>(parent.chain, path))),
chain(parent.chain, path)
{};
extended_private_key::extended_private_key(hash<512>&& s) :
extended_private_key::extended_private_key(hash<512>&& s) noexcept :
privatekey(s),
chain(s)
{};
extended_private_key::extended_private_key(const char* const passwd) :
extended_private_key::extended_private_key(const char* const passwd) noexcept :
extended_private_key(DeriveStrongSecretHash(passwd))
{};
extended_public_key::extended_public_key(extended_public_key& parent, std::span<byte> path) :
extended_public_key::extended_public_key(extended_public_key& parent, std::span<byte> path) noexcept :
publickey(parent.publickey* scalar(hash<512>(parent.chain, path))),
chain(parent.chain, path)
{};
extended_public_key::extended_public_key(extended_private_key& p) :
extended_public_key::extended_public_key(extended_private_key& p) noexcept :
publickey{ p.privatekey.timesBase() },
chain{ p.chain }
{};

View File

@ -29,16 +29,16 @@ namespace ristretto255 {
Also, the BIP0032 -- BIP0044 extended keys use 32 bitunsigned integers
for the path, but since I want to allow names, among other things,
I use spans of bytes. */
extended_private_key(hash<512>&&);
extended_private_key(hash<512>&&)noexcept;
public:
static constexpr bool is_machine_independent() { return true; };
scalar privatekey;
hash<256> chain;
static constexpr unsigned int type_indentifier = 3;
public:
extended_private_key()=default;
extended_private_key(extended_private_key& parent, std::span<byte> path);
extended_private_key(const char* const passwd);
extended_private_key(extended_private_key& parent, std::span<byte> path) noexcept;
extended_private_key(const char* const passwd) noexcept;
~extended_private_key()noexcept { wxSecretValue::Wipe(sizeof(*this), this); }
template<class T> auto operator()(T psz) {
return privatekey*scalar(hash<512>(chain, psz));
}
@ -51,19 +51,21 @@ namespace ristretto255 {
/* This is the same name and concept as BIP0032 and BIP0044 extended private
and public keys, and used for the same purpose, to deterministically
create a hierarchical tree of secrets each defined by a path from the master
extended key, but utterly incompatible */
extended key, but utterly incompatible.
*/
public:
static constexpr bool is_machine_independent() { return true; };
point publickey;
hash<256> chain;
static constexpr unsigned int type_indentifier = 4;
extended_public_key()=default;
extended_public_key(extended_public_key& parent, std::span<byte> path);
extended_public_key(extended_private_key&);
extended_public_key(extended_public_key& parent, std::span<byte> path) noexcept;
extended_public_key(extended_private_key&) noexcept;
~extended_public_key()noexcept { wxSecretValue::Wipe(sizeof(*this), this); }
template<class T> auto operator()(T psz) {
scalar& t(*this);
return publickey * scalar(hash<512>(chain, psz));
}
bool operator==(const extended_public_key& pt) const& { return this->publickey == pt.publickey && this->chain == pt.chain; }
};
static_assert(sizeof(extended_public_key) == sizeof(hash<256>) + sizeof(point));

View File

@ -24,24 +24,16 @@
*tsz = '\0';
}
}
operator char* () & {
char* pc = &(static_cast<std::array<char, stringlen + 1>*>(this)->operator[](0));
operator char* () {
char* pc = (char*)this;
return pc;
}
operator const char* () const& {
const char* pc = &(static_cast<const std::array<char, stringlen + 1>*>(this)->operator[](0));
operator const char* () {
const char* pc = (const char*)this;
return pc;
}
operator const char* () const&& {
const char* pc = &(static_cast<const std::array<char, stringlen + 1>*>(this)->operator[](0));
return pc;
}
operator std::string() const& {
return std::string((const char*)*this, this->length);
}
operator std::string() const&& {
return std::string((const char*)*this, this->length);
operator std::string() {
return std::string((const char*)this);
}
operator wxString() const& {
return wxString::FromUTF8Unchecked((const char*)(*this));
@ -50,7 +42,7 @@
return std::span<byte>(static_cast<std::nullptr_t>((char*)*this), stringlen + 1);
}
operator wxString() const&& {
return wxString::FromUTF8Unchecked((const char*)(*this));
return wxString::FromUTF8Unchecked((const char*)(this));
}
operator std::span<byte>() const&& {
return std::span<byte>(static_cast<std::nullptr_t>((char*)*this), stringlen + 1);

View File

@ -25,6 +25,7 @@ constexpr bool b_WINDOWS = false;
#endif
#include <wx/filename.h>
#include <wx/modalhook.h>
#include <wx/secretstore.h>
#include <cstddef>
#include <cstdint>
#include <array>

View File

@ -641,16 +641,27 @@ namespace ristretto255 {
{ auto start_time{ std::chrono::high_resolution_clock::now() };
extended_private_key s1(&text_secret[0]);
auto end_time{ std::chrono::high_resolution_clock::now() };
std::string str_s1{ &(base58(s1))[0] };
std::string str_s1((char*)base58(s1) );
wxLogMessage("\t\textended private key: %s", str_s1);
const char* str_s2 = "jyRioJfob242toZDETkd7nG4YW6oYeGBEVEw4KLGWZaJfCPV2hQbT3AFUcnu6ZXEvDPPpSmM5ivMJ2awJxSBS5DoE";
if (str_s2 != str_s1) {
throw MyException("unexpected value of private key", __LINE__, __func__, SrcFilename);
throw MyException("unexpected value of extended private key", __LINE__, __func__, SrcFilename);
}
auto s2 = base58<extended_private_key>::bin(str_s2);
if (s1 != s2) {
throw MyException("Round trip for extended_private_key to and from base 58 representation failed", __LINE__, __func__, SrcFilename);
}
extended_public_key p1(s1);
std::string str_p1((char*)base58(p1));
wxLogMessage("\t\textended public key: %s", str_p1);
const char* sz_p2 = "W7rr3Egaf9eqs6km7RfYSuh6ydxN2ucHe6iEm7P3YUcFzmirQFRJEQm8Q9KUiQMpZjz1Km6wD2GLgTWp8CBWQRLKo";
if (sz_p2 != str_p1) {
throw MyException("unexpected value of extended public key", __LINE__, __func__, SrcFilename);
}
auto p2 = base58<extended_public_key>::bin(sz_p2);
if (p1 != p2) {
throw MyException("Round trip for extended_public_key to and from base 58 representation failed", __LINE__, __func__, SrcFilename);
}
auto time_taken{ std::chrono::duration_cast<std::chrono::microseconds> (end_time - start_time) };
wxLogMessage("\t\tStrong secret extended private key derivation took %lld microseconds", time_taken.count());
}