base 58 representation of extended keys works

This commit is contained in:
Cheng 2024-07-31 13:43:52 +00:00
parent 8792d59c67
commit deac6e35d1
No known key found for this signature in database
3 changed files with 49 additions and 45 deletions

View File

@ -54,22 +54,7 @@ ristretto255::hash<512> DeriveStrongSecretHash(const char* const passwd) {
//Derive a strong scalar secret from a string with password strengthening. //Derive a strong scalar secret from a string with password strengthening.
//Net effect is convert one scalar into another by a process that is lengthy and costly. //Net effect is convert one scalar into another by a process that is lengthy and costly.
ristretto255::scalar DeriveStrongSecretScalar(const char* const passwd){ ristretto255::scalar DeriveStrongSecretScalar(const char* const passwd){
static std::array<uint8_t, crypto_pwhash_SALTBYTES> salt{ 0 }; return scalar(DeriveStrongSecretHash(passwd));
std::array<uint8_t, sizeof(ristretto255::hash<512>)>randb;
int i{
crypto_pwhash(
&randb[0],
sizeof(randb),
passwd,
strlen(passwd)+1,
&salt[0],
2, 0x10000000,
crypto_pwhash_ALG_ARGON2ID13
)
};
static_assert(crypto_pwhash_OPSLIMIT_MODERATE == 0x00000003 && crypto_pwhash_MEMLIMIT_MODERATE == 0x10000000, "Argon changed, likely breaking all passphrases");
assert(i == 0);
return scalar(hash<512>(randb));
} }
//Derive scalar secret from another quickly. //Derive scalar secret from another quickly.
@ -83,34 +68,23 @@ namespace ristretto255 {
chain(parent.chain, path) chain(parent.chain, path)
{}; {};
extended_private_key::extended_private_key() :
m_valid{ false }
{}
extended_private_key::extended_private_key(hash<512>&& s) : extended_private_key::extended_private_key(hash<512>&& s) :
privatekey(s), privatekey(s),
chain(s), chain(s)
m_valid{ true }
{}; {};
extended_private_key::extended_private_key(const char* const passwd) : extended_private_key::extended_private_key(const char* const passwd) :
extended_private_key(DeriveStrongSecretHash(passwd)) extended_private_key(DeriveStrongSecretHash(passwd))
{}; {};
extended_public_key::extended_public_key() :
m_valid{ false }
{};
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) :
publickey(parent.publickey* scalar(hash<512>(parent.chain, path))), publickey(parent.publickey* scalar(hash<512>(parent.chain, path))),
chain(parent.chain, path), chain(parent.chain, path)
m_valid{ true }
{}; {};
extended_public_key::extended_public_key(extended_private_key& p) : extended_public_key::extended_public_key(extended_private_key& p) :
publickey{ p.privatekey.timesBase() }, publickey{ p.privatekey.timesBase() },
chain{ p.chain }, chain{ p.chain }
m_valid{ true }
{}; {};
} }

View File

@ -35,21 +35,17 @@ namespace ristretto255 {
scalar privatekey; scalar privatekey;
hash<256> chain; hash<256> chain;
static constexpr unsigned int type_indentifier = 3; static constexpr unsigned int type_indentifier = 3;
private:
bool m_valid;
public: public:
extended_private_key(); extended_private_key()=default;
extended_private_key(extended_private_key& parent, std::span<byte> path); extended_private_key(extended_private_key& parent, std::span<byte> path);
extended_private_key(const char* const passwd); extended_private_key(const char* const passwd);
template<class T> auto operator()(T psz) { template<class T> auto operator()(T psz) {
assert(m_valid);
return privatekey*scalar(hash<512>(chain, psz)); return privatekey*scalar(hash<512>(chain, psz));
} }
bool valid() { return m_valid; } bool operator==(const extended_private_key& pt) const& { return this->privatekey == pt.privatekey && this->chain == pt.chain; }
}; };
static_assert(sizeof(extended_private_key) == sizeof(hash<256>) + sizeof(scalar) + sizeof(bool)); static_assert(sizeof(extended_private_key) == sizeof(hash<256>) + sizeof(scalar));
class extended_public_key { class extended_public_key {
/* This is the same name and concept as BIP0032 and BIP0044 extended private /* This is the same name and concept as BIP0032 and BIP0044 extended private
@ -61,21 +57,16 @@ namespace ristretto255 {
point publickey; point publickey;
hash<256> chain; hash<256> chain;
static constexpr unsigned int type_indentifier = 4; static constexpr unsigned int type_indentifier = 4;
private: extended_public_key()=default;
bool m_valid;
public:
extended_public_key();
extended_public_key(extended_public_key& parent, std::span<byte> path); extended_public_key(extended_public_key& parent, std::span<byte> path);
extended_public_key(extended_private_key&); extended_public_key(extended_private_key&);
template<class T> auto operator()(T psz) { template<class T> auto operator()(T psz) {
scalar& t(*this); scalar& t(*this);
assert(m_valid);
return publickey * scalar(hash<512>(chain, psz)); return publickey * scalar(hash<512>(chain, psz));
} }
bool valid() { return m_valid; }
}; };
static_assert(sizeof(extended_public_key) == sizeof(hash<256>) + sizeof(point) + sizeof(bool)); static_assert(sizeof(extended_public_key) == sizeof(hash<256>) + sizeof(point));
std::span<const byte> serialize(const extended_private_key& pt); std::span<const byte> serialize(const extended_private_key& pt);
std::span<const byte> serialize(const extended_public_key& pt); std::span<const byte> serialize(const extended_public_key& pt);
} }

View File

@ -29,7 +29,9 @@ namespace testbed {
using ristretto255::hash, ristretto255::hsh, ristretto255::scalar, using ristretto255::hash, ristretto255::hsh, ristretto255::scalar,
ristretto255::point, ro::serialize, ro::bin2hex, ro::hex2bin, ristretto255::point, ro::serialize, ro::bin2hex, ro::hex2bin,
ro::bin2hex, ro::fasthash, ro::CompileSizedString, ro::bin2hex, ro::fasthash, ro::CompileSizedString,
ro::base58, ro::has_machine_independent_representation; ro::base58, ro::has_machine_independent_representation,
ristretto255::extended_private_key,
ristretto255::extended_public_key;
static constexpr char SrcFilename[]{ "src/testbed.cpp" }; static constexpr char SrcFilename[]{ "src/testbed.cpp" };
@ -70,5 +72,42 @@ If using queumessage, the testbed code will complete while the dialog
// wxLogMessage(wx.ToString()); // wxLogMessage(wx.ToString());
// queue_error_message("hello world"); // queue_error_message("hello world");
// throw MyException("hello world exception", __LINE__, __func__, SrcFilename); // throw MyException("hello world exception", __LINE__, __func__, SrcFilename);
ILogMessage("begin testbed");
auto text_secret{ DeriveTextSecret(scalar(7), 1) };
if (text_secret == decltype(text_secret){"Rmc mLSu mDk DhfV 9gBK kKj"}) {
ILogMessage("\t\tObtained expected text secret from scalar(7)");
}
else {
errorCode = 18;
szError = "Fail\tUnexpected text secret from scalar(7)";
ILogError(szError.c_str());
}
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] };
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);
}
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);
}
/* if (s1 == scalar({0x59, 0xf6, 0x73, 0xb4, 0xa0, 0xc7, 0x0d, 0x8b, 0x51, 0xe5, 0x87, 0x7c, 0xf5, 0xd7, 0x6f, 0x55, 0x31, 0xa7, 0x0b, 0x14, 0x28, 0x54, 0x97, 0x08, 0x9f, 0x27, 0x83, 0xe1, 0xc7, 0x5f, 0x55, 0x0f})) {
wxLogMessage("\t\tObtained expected strong scalar secret from scalar(7)");
}
else {
errorCode = 17;
szError = "Fail\tUnexpected strong scalar secret from text secret";
ILogError(szError.c_str());
}*/
auto time_taken{ std::chrono::duration_cast<std::chrono::microseconds> (end_time - start_time) };
wxLogMessage("\t\tStrong secret derivation took %lld microseconds", time_taken.count());
ILogMessage("end testbed");
} }
} }