added extended keys
but not going to start using them until I can save them to the database and reload them
This commit is contained in:
parent
fe3015b851
commit
feb040d800
@ -422,7 +422,7 @@ COMMIT;
|
||||
wxLogMessage("\t\tGenerating random 128 bit wallet secret");
|
||||
auto text_secret{ DeriveTextSecret(ristretto255::scalar::random(), 1) };
|
||||
ro::msec start_time{ ro::msec_since_epoch() };
|
||||
ristretto255::CMasterSecret MasterSecret(DeriveStrongSecret(&text_secret[0]));
|
||||
ristretto255::CMasterSecret MasterSecret(ristretto255::scalar(DeriveStrongSecretHash(&text_secret[0])));
|
||||
decltype(start_time) end_time{ ro::msec_since_epoch() };
|
||||
wxLogMessage("\t\tStrong secret derivation took %d milliseconds", (end_time - start_time).count());
|
||||
sql_update_to_misc update_to_misc(db);
|
||||
|
@ -106,9 +106,13 @@ namespace ristretto255 {
|
||||
|
||||
template<unsigned int hashsize = 256> class hsh {
|
||||
public:
|
||||
static_assert(hashsize > 63 && hashsize % 64 == 0 && crypto_generichash_BYTES_MIN * 8 <= hashsize && hashsize <= crypto_generichash_BYTES_MAX * 8, "Bad hash size.");
|
||||
static constexpr unsigned int type_indentifier = 2 + (hashsize + 0x90 * 8) / 64;
|
||||
static_assert(crypto_generichash_BYTES_MAX < 0x90, "Change in max hash has broken our type ids");
|
||||
static_assert(
|
||||
hashsize % 64 == 0 &&
|
||||
crypto_generichash_BYTES_MIN * 8 /*128*/ <= hashsize && hashsize <= crypto_generichash_BYTES_MAX * 8 /*512*/,
|
||||
"Bad hash size."
|
||||
);
|
||||
static constexpr unsigned int type_indentifier = 5 + (hashsize + 1024) / 64;
|
||||
static_assert(crypto_generichash_BYTES_MAX < 1024/8, "Change in max hash has broken our type ids");
|
||||
crypto_generichash_blake2b_state st;
|
||||
hsh() {
|
||||
int i{ crypto_generichash_blake2b_init(
|
||||
@ -197,9 +201,8 @@ namespace ristretto255 {
|
||||
// is running.
|
||||
template<unsigned int hashsize = 256> class hash {
|
||||
static_assert(
|
||||
hashsize > 63 && hashsize % 64 == 0
|
||||
&& crypto_generichash_BYTES_MIN * 8 <= hashsize
|
||||
&& hashsize <= crypto_generichash_BYTES_MAX * 8,
|
||||
hashsize % 64 == 0
|
||||
&& crypto_generichash_BYTES_MIN * 8 <= hashsize && hashsize <= crypto_generichash_BYTES_MAX * 8,
|
||||
"Bad hash size."
|
||||
);
|
||||
friend point;
|
||||
|
@ -30,9 +30,30 @@ std::array<char, 27> DeriveTextSecret(const scalar & blob, uint_fast64_t i){
|
||||
return txt;
|
||||
}
|
||||
|
||||
//Derive a strong hash secret from a string with password strengthening.
|
||||
//Net effect is convert one scalar into another by a process that is lengthy and costly.
|
||||
ristretto255::hash<512> DeriveStrongSecretHash(const char* const passwd) {
|
||||
static std::array<uint8_t, crypto_pwhash_SALTBYTES> salt{ 0 };
|
||||
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 hash<512>(randb);
|
||||
}
|
||||
|
||||
//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.
|
||||
ristretto255::scalar DeriveStrongSecret(const char* const passwd){
|
||||
ristretto255::scalar DeriveStrongSecretScalar(const char* const passwd){
|
||||
static std::array<uint8_t, crypto_pwhash_SALTBYTES> salt{ 0 };
|
||||
std::array<uint8_t, sizeof(ristretto255::hash<512>)>randb;
|
||||
int i{
|
||||
@ -54,4 +75,42 @@ ristretto255::scalar DeriveStrongSecret(const char* const passwd){
|
||||
//Derive scalar secret from another quickly.
|
||||
ristretto255::scalar DeriveSecret(const scalar &sc, uint_fast64_t i) {
|
||||
return ristretto255::scalar(ristretto255::hash<512>(sc, i));
|
||||
}
|
||||
}
|
||||
|
||||
namespace ristretto255 {
|
||||
extended_private_key::extended_private_key(extended_private_key& parent, std::span<byte> path) :
|
||||
privatekey(parent.privatekey* scalar(hash<512>(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) :
|
||||
privatekey(s),
|
||||
chain(s),
|
||||
m_valid{ true }
|
||||
{};
|
||||
|
||||
extended_private_key::extended_private_key(const char* const 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) :
|
||||
publickey(parent.publickey* scalar(hash<512>(parent.chain, path))),
|
||||
chain(parent.chain, path),
|
||||
m_valid{ true }
|
||||
{};
|
||||
|
||||
extended_public_key::extended_public_key(extended_private_key& p) :
|
||||
publickey{ p.privatekey.timesBase() },
|
||||
chain{ p.chain },
|
||||
m_valid{ true }
|
||||
{};
|
||||
|
||||
}
|
||||
|
@ -2,9 +2,9 @@
|
||||
//Derive a Short text Secret from a 256 bit random value and a sixty four bit integer
|
||||
std::array<char, 0x1b> DeriveTextSecret(const ristretto255::scalar& blob, uint_fast64_t i);
|
||||
|
||||
//Derive a strong scalar secret from a string with password strengthening.
|
||||
//Derive a strong hash secret from a string with password strengthening.
|
||||
//Net effect is convert one scalar into another by a process that is lengthy and costly.
|
||||
ristretto255::scalar DeriveStrongSecret(const char* const passwd);
|
||||
ristretto255::hash<512> DeriveStrongSecretHash(const char* const passwd);
|
||||
|
||||
//Derive scalar secret from another quickly.
|
||||
ristretto255::scalar DeriveSecret(const ristretto255::scalar &sc, uint_fast64_t i);
|
||||
@ -12,3 +12,70 @@ template <class T, std::enable_if_t<std::_Is_standard_unsigned_integer<T>, int>
|
||||
constexpr int rounded_log2(const T val) noexcept {
|
||||
return std::numeric_limits<T>::digits - std::countl_zero(val);
|
||||
}
|
||||
|
||||
namespace ristretto255 {
|
||||
class extended_private_key {
|
||||
/* 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, for BIP secrets use the SECp256k1
|
||||
elliptic curve, while I am using ristretto25519, which is much better.
|
||||
|
||||
SECp256k1 was the best curve of Satoshi's day, because Satoshi knew the NIST
|
||||
curves were and are backdoored, but ristretto25519 is a better elliptic curve
|
||||
because faster, more compact, and fewer subtle, difficult to comprehend, esoteric,
|
||||
security holes that the engineer trying to use it is going to fall into.
|
||||
|
||||
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>&&);
|
||||
public:
|
||||
static constexpr bool is_machine_independent() { return true; };
|
||||
scalar privatekey;
|
||||
hash<256> chain;
|
||||
static constexpr unsigned int type_indentifier = 3;
|
||||
private:
|
||||
bool m_valid;
|
||||
public:
|
||||
extended_private_key();
|
||||
extended_private_key(extended_private_key& parent, std::span<byte> path);
|
||||
extended_private_key(const char* const passwd);
|
||||
template<class T> auto operator()(T psz) {
|
||||
assert(m_valid);
|
||||
return privatekey*scalar(hash<512>(chain, psz));
|
||||
}
|
||||
bool valid() { return m_valid; }
|
||||
|
||||
};
|
||||
|
||||
static_assert(sizeof(extended_private_key) == sizeof(hash<256>) + sizeof(scalar) + sizeof(bool));
|
||||
|
||||
class extended_public_key {
|
||||
/* 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 */
|
||||
public:
|
||||
static constexpr bool is_machine_independent() { return true; };
|
||||
point publickey;
|
||||
hash<256> chain;
|
||||
static constexpr unsigned int type_indentifier = 4;
|
||||
private:
|
||||
bool m_valid;
|
||||
public:
|
||||
extended_public_key();
|
||||
extended_public_key(extended_public_key& parent, std::span<byte> path);
|
||||
extended_public_key(extended_private_key&);
|
||||
template<class T> auto operator()(T psz) {
|
||||
scalar& t(*this);
|
||||
assert(m_valid);
|
||||
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));
|
||||
std::span<const byte> serialize(const extended_private_key& pt);
|
||||
std::span<const byte> serialize(const extended_public_key& pt);
|
||||
}
|
||||
|
@ -528,7 +528,7 @@ COMMIT;
|
||||
wxLogMessage(wxT("\t\tGenerating random 128 bit wallet secret"));
|
||||
auto text_secret{ DeriveTextSecret(ristretto255::scalar::random(), 1) };
|
||||
ro::msec start_time{ ro::msec_since_epoch() };
|
||||
ristretto255::CMasterSecret MasterSecret(DeriveStrongSecret(&text_secret[0]) );
|
||||
ristretto255::CMasterSecret MasterSecret(scalar(DeriveStrongSecretHash(&text_secret[0])) );
|
||||
decltype(start_time) end_time{ ro::msec_since_epoch() };
|
||||
wxLogMessage(wxT("\t\tStrong secret derivation took %d milliseconds"), (end_time - start_time).count());
|
||||
sql_update_to_misc update_to_misc(db.get());
|
||||
@ -610,7 +610,7 @@ namespace ristretto255 {
|
||||
}
|
||||
if (!(singletonApp->m_quick_unit_test)){
|
||||
auto start_time{ std::chrono::high_resolution_clock::now() };
|
||||
auto s1{ DeriveStrongSecret(&text_secret[0]) };
|
||||
auto s1{ scalar( DeriveStrongSecretHash(&text_secret[0])) };
|
||||
auto end_time{ std::chrono::high_resolution_clock::now() };
|
||||
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)");
|
||||
|
Loading…
Reference in New Issue
Block a user