Compare commits
3 Commits
536a71a818
...
58f29b8977
Author | SHA1 | Date | |
---|---|---|---|
|
58f29b8977 | ||
|
595863e63e | ||
|
d81b7043df |
@ -334,7 +334,11 @@ 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() noexcept { wxSecretValue::Wipe(sizeof(*this), this); }
|
||||
~scalar() noexcept { wxSecretValue::Wipe(sizeof(*this), this); } /*calls wipe to avoid leaving secrets around in memory.
|
||||
Because wxSecretValue::Wipe is in a different optimisation unit, a separately compiled library,
|
||||
optimisation of the destructor cannot optimise away the call to the wipe,
|
||||
because the destructor optimiser does not know that all wipe does is
|
||||
write to memory that is about to be discarded, nor can the wipe optimiser know that. */
|
||||
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; } }
|
||||
@ -345,9 +349,9 @@ namespace ristretto255 {
|
||||
static_assert (ro::is_standard_signed_integer<T>);
|
||||
if (i < 0) crypto_core_ristretto255_scalar_negate(&blob[0], &blob[0]);
|
||||
}
|
||||
scalar(scalar&&) = default; // Move constructor
|
||||
scalar(scalar&&) = default; // Move constructor. Does not need to call wipe, because destructor will be called on source
|
||||
scalar(const scalar&) = default; // Copy constructor
|
||||
scalar& operator=(scalar&&) = default; // Move assignment.
|
||||
scalar& operator=(scalar&&) = default; // Move assignment. Does not need to call wipe, because destructor will be called on source
|
||||
scalar& operator=(const scalar&) = default; // Copy assignment.
|
||||
/* Don't need constant time equality test
|
||||
bool operator==(const scalar& sc) const& {
|
||||
|
@ -427,9 +427,8 @@ static bool OpenWallet(void) {
|
||||
fWalletNameOk = true;
|
||||
}
|
||||
}
|
||||
else fWalletNameOk = true;
|
||||
std::unique_ptr<ISqlite3> db;
|
||||
if (fWalletNameOk) {
|
||||
else {
|
||||
std::unique_ptr<ISqlite3> db;
|
||||
if (!LastUsedSqlite.FileExists()) throw MyException("Expected wallet file not found", __LINE__, __func__, SrcFilename);
|
||||
db.reset(Sqlite3_open(LastUsedSqlite.GetFullPath().ToUTF8()));
|
||||
sql_read_from_misc read_from_misc(db.get());
|
||||
@ -452,102 +451,6 @@ static bool OpenWallet(void) {
|
||||
wxLogMessage(wxT("\t\t\"%s\" has expected public key #%s"), name, (wxString)(ro::base58(pubkey).operator const char* ()));
|
||||
}
|
||||
}
|
||||
else {
|
||||
// At this point in the code the filename LastUsedSqlite is a bad filename, normally the empty string, and the default wallet file does not exist in the default location.
|
||||
// Construct default wallet and filename*/
|
||||
wxFileName path{ StandardPaths.GetUserLocalDataDir() };
|
||||
try {
|
||||
// Disk operations to create wallet, which may throw.
|
||||
// This try/catch block exists to catch disk io issues.
|
||||
if (!path.DirExists())path.Mkdir();
|
||||
if (!DefaultSqlite.DirExists())DefaultSqlite.Mkdir();
|
||||
db.reset(Sqlite3_create(DefaultSqlite.GetFullPath().ToUTF8()));
|
||||
db->exec(R"|(
|
||||
PRAGMA journal_mode = WAL;
|
||||
PRAGMA synchronous = 1;
|
||||
BEGIN IMMEDIATE TRANSACTION;
|
||||
CREATE TABLE "Keys"(
|
||||
"ROWID" INTEGER PRIMARY KEY,
|
||||
"pubkey" BLOB NOT NULL UNIQUE,
|
||||
"id" integer NOT NULL,
|
||||
"use" INTEGER NOT NULL
|
||||
) STRICT;
|
||||
|
||||
CREATE UNIQUE INDEX i_pubkey ON Keys (pubkey);
|
||||
CREATE UNIQUE INDEX i_id ON Keys (use, id);
|
||||
|
||||
CREATE TABLE "Names"(
|
||||
"ROWID" INTEGER PRIMARY KEY,
|
||||
"name" TEXT NOT NULL UNIQUE
|
||||
) STRICT;
|
||||
|
||||
CREATE UNIQUE INDEX i_names ON Names (name);
|
||||
|
||||
CREATE TABLE "Misc"(
|
||||
"ROWID" INTEGER PRIMARY KEY,
|
||||
"m" ANY
|
||||
) STRICT;
|
||||
COMMIT;
|
||||
|
||||
BEGIN IMMEDIATE TRANSACTION;
|
||||
CREATE VIEW UserZookoIDs AS
|
||||
SELECT
|
||||
"Names".name AS name,
|
||||
"Keys".pubkey AS pubkey
|
||||
FROM "Names" INNER JOIN "Keys"
|
||||
ON "Names"."ROWID"="Keys"."id" AND "Keys"."use"=1
|
||||
ORDER BY LOWER("name"), "name"
|
||||
COLLATE BINARY;
|
||||
COMMIT;
|
||||
|
||||
BEGIN IMMEDIATE TRANSACTION;
|
||||
CREATE TRIGGER InsertUserZookoID INSTEAD OF INSERT ON UserZookoIDs FOR EACH ROW BEGIN
|
||||
INSERT OR FAIL INTO "Names" VALUES(
|
||||
NULL,
|
||||
NEW."name"
|
||||
);
|
||||
INSERT OR FAIL INTO "Keys" VALUES(
|
||||
NULL,
|
||||
NEW."pubkey",
|
||||
last_insert_rowid(),
|
||||
1
|
||||
);
|
||||
END;
|
||||
|
||||
CREATE TRIGGER DeleteUserZookoID INSTEAD OF DELETE ON UserZookoIDs FOR EACH ROW BEGIN
|
||||
DELETE FROM "Keys" WHERE "Keys"."pubkey" = OLD."pubkey";
|
||||
DELETE FROM "Names" WHERE "Names"."name" = OLD."name";
|
||||
END;
|
||||
COMMIT;
|
||||
)|");
|
||||
LastUsedSqlite = DefaultSqlite;
|
||||
singletonFrame->m_LastUsedWallet = LastUsedSqlite;
|
||||
wxLogMessage(wxT("\t\tConstructing default wallet %s"), DefaultSqlite.GetFullPath());
|
||||
// We now have a working wallet file with no valid data. Attempting to create a strong random secret, a name, and public and private keys for that name.
|
||||
|
||||
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(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());
|
||||
update_to_misc(1, WALLET_FILE_IDENTIFIER);
|
||||
update_to_misc(2, WALLET_FILE_SCHEMA_VERSION_0_0);
|
||||
update_to_misc(3, &text_secret[0]);
|
||||
|
||||
update_to_misc(4, MasterSecret);
|
||||
sql_insert_name insert_name(db.get());
|
||||
const char cpsz[]{ "Unit Tester" };
|
||||
insert_name(cpsz, MasterSecret(cpsz).timesBase());
|
||||
}
|
||||
catch (const MyException & e) {
|
||||
ILogError(R"|(Failed to create or failed to properly initialize wallet)|");
|
||||
errorCode = 20;
|
||||
szError = e.what();
|
||||
ILogError(szError.c_str());
|
||||
}
|
||||
} // End of wallet creation branch
|
||||
}
|
||||
catch (const MyException& e) {
|
||||
errorCode = e.what_num();
|
||||
|
Loading…
Reference in New Issue
Block a user