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");
|
wxLogMessage("\t\tGenerating random 128 bit wallet secret");
|
||||||
auto text_secret{ DeriveTextSecret(ristretto255::scalar::random(), 1) };
|
auto text_secret{ DeriveTextSecret(ristretto255::scalar::random(), 1) };
|
||||||
ro::msec start_time{ ro::msec_since_epoch() };
|
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() };
|
decltype(start_time) end_time{ ro::msec_since_epoch() };
|
||||||
wxLogMessage("\t\tStrong secret derivation took %d milliseconds", (end_time - start_time).count());
|
wxLogMessage("\t\tStrong secret derivation took %d milliseconds", (end_time - start_time).count());
|
||||||
sql_update_to_misc update_to_misc(db);
|
sql_update_to_misc update_to_misc(db);
|
||||||
|
@ -106,9 +106,13 @@ namespace ristretto255 {
|
|||||||
|
|
||||||
template<unsigned int hashsize = 256> class hsh {
|
template<unsigned int hashsize = 256> class hsh {
|
||||||
public:
|
public:
|
||||||
static_assert(hashsize > 63 && hashsize % 64 == 0 && crypto_generichash_BYTES_MIN * 8 <= hashsize && hashsize <= crypto_generichash_BYTES_MAX * 8, "Bad hash size.");
|
static_assert(
|
||||||
static constexpr unsigned int type_indentifier = 2 + (hashsize + 0x90 * 8) / 64;
|
hashsize % 64 == 0 &&
|
||||||
static_assert(crypto_generichash_BYTES_MAX < 0x90, "Change in max hash has broken our type ids");
|
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;
|
crypto_generichash_blake2b_state st;
|
||||||
hsh() {
|
hsh() {
|
||||||
int i{ crypto_generichash_blake2b_init(
|
int i{ crypto_generichash_blake2b_init(
|
||||||
@ -197,9 +201,8 @@ namespace ristretto255 {
|
|||||||
// is running.
|
// is running.
|
||||||
template<unsigned int hashsize = 256> class hash {
|
template<unsigned int hashsize = 256> class hash {
|
||||||
static_assert(
|
static_assert(
|
||||||
hashsize > 63 && hashsize % 64 == 0
|
hashsize % 64 == 0
|
||||||
&& crypto_generichash_BYTES_MIN * 8 <= hashsize
|
&& crypto_generichash_BYTES_MIN * 8 <= hashsize && hashsize <= crypto_generichash_BYTES_MAX * 8,
|
||||||
&& hashsize <= crypto_generichash_BYTES_MAX * 8,
|
|
||||||
"Bad hash size."
|
"Bad hash size."
|
||||||
);
|
);
|
||||||
friend point;
|
friend point;
|
||||||
|
@ -30,9 +30,30 @@ std::array<char, 27> DeriveTextSecret(const scalar & blob, uint_fast64_t i){
|
|||||||
return txt;
|
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.
|
//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 DeriveStrongSecret(const char* const passwd){
|
ristretto255::scalar DeriveStrongSecretScalar(const char* const passwd){
|
||||||
static std::array<uint8_t, crypto_pwhash_SALTBYTES> salt{ 0 };
|
static std::array<uint8_t, crypto_pwhash_SALTBYTES> salt{ 0 };
|
||||||
std::array<uint8_t, sizeof(ristretto255::hash<512>)>randb;
|
std::array<uint8_t, sizeof(ristretto255::hash<512>)>randb;
|
||||||
int i{
|
int i{
|
||||||
@ -55,3 +76,41 @@ ristretto255::scalar DeriveStrongSecret(const char* const passwd){
|
|||||||
ristretto255::scalar DeriveSecret(const scalar &sc, uint_fast64_t i) {
|
ristretto255::scalar DeriveSecret(const scalar &sc, uint_fast64_t i) {
|
||||||
return ristretto255::scalar(ristretto255::hash<512>(sc, 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
|
//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);
|
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.
|
//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.
|
//Derive scalar secret from another quickly.
|
||||||
ristretto255::scalar DeriveSecret(const ristretto255::scalar &sc, uint_fast64_t i);
|
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 {
|
constexpr int rounded_log2(const T val) noexcept {
|
||||||
return std::numeric_limits<T>::digits - std::countl_zero(val);
|
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"));
|
wxLogMessage(wxT("\t\tGenerating random 128 bit wallet secret"));
|
||||||
auto text_secret{ DeriveTextSecret(ristretto255::scalar::random(), 1) };
|
auto text_secret{ DeriveTextSecret(ristretto255::scalar::random(), 1) };
|
||||||
ro::msec start_time{ ro::msec_since_epoch() };
|
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() };
|
decltype(start_time) end_time{ ro::msec_since_epoch() };
|
||||||
wxLogMessage(wxT("\t\tStrong secret derivation took %d milliseconds"), (end_time - start_time).count());
|
wxLogMessage(wxT("\t\tStrong secret derivation took %d milliseconds"), (end_time - start_time).count());
|
||||||
sql_update_to_misc update_to_misc(db.get());
|
sql_update_to_misc update_to_misc(db.get());
|
||||||
@ -610,7 +610,7 @@ namespace ristretto255 {
|
|||||||
}
|
}
|
||||||
if (!(singletonApp->m_quick_unit_test)){
|
if (!(singletonApp->m_quick_unit_test)){
|
||||||
auto start_time{ std::chrono::high_resolution_clock::now() };
|
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() };
|
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 })) {
|
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)");
|
wxLogMessage("\t\tObtained expected strong scalar secret from scalar(7)");
|
||||||
|
Loading…
Reference in New Issue
Block a user