forked from cheng/wallet
wiped scalars on destruction, and added extended public keys to unit_test.cpp
This commit is contained in:
parent
133b7d27c8
commit
ba84172bbd
@ -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) {
|
||||
|
@ -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 };
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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 }
|
||||
{};
|
||||
|
@ -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));
|
||||
|
@ -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);
|
||||
|
@ -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>
|
||||
|
@ -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());
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user