forked from cheng/wallet
base 58 representation of extended keys works
This commit is contained in:
parent
8792d59c67
commit
deac6e35d1
@ -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 }
|
|
||||||
{};
|
{};
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
|
@ -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");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user