wownero-seed
dsc 2 years ago
parent 8d19ea23db
commit 3d70455534

@ -2,14 +2,14 @@
cmake_minimum_required(VERSION 3.13) cmake_minimum_required(VERSION 3.13)
option(MONERO_SEED_DEMO "Build a demo executable for monero-seed") option(WOWNERO_SEED_DEMO "Build a demo executable for wownero-seed")
if(NOT CMAKE_BUILD_TYPE) if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE Release) set(CMAKE_BUILD_TYPE Release)
message(STATUS "Setting default build type: ${CMAKE_BUILD_TYPE}") message(STATUS "Setting default build type: ${CMAKE_BUILD_TYPE}")
endif() endif()
project(monero-seed) project(wownero-seed)
include(GNUInstallDirs) include(GNUInstallDirs)
@ -21,7 +21,7 @@ src/argon2/ref.c
src/galois_field.cpp src/galois_field.cpp
src/gf_elem.cpp src/gf_elem.cpp
src/gf_poly.cpp src/gf_poly.cpp
src/monero_seed.cpp src/wownero_seed.cpp
src/pbkdf2.c src/pbkdf2.c
src/reed_solomon_code.cpp src/reed_solomon_code.cpp
src/secure_random.cpp src/secure_random.cpp
@ -30,9 +30,9 @@ src/wordlist.cpp)
set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11) set_property(TARGET ${PROJECT_NAME} PROPERTY CXX_STANDARD 11)
target_include_directories(${PROJECT_NAME} PUBLIC target_include_directories(${PROJECT_NAME} PUBLIC
$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include> $<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>
$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/monero_seed>) $<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/wownero_seed>)
if(MONERO_SEED_DEMO) if(WOWNERO_SEED_DEMO)
add_executable(demo src/main.cpp) add_executable(demo src/main.cpp)
set_property(TARGET demo PROPERTY CXX_STANDARD 11) set_property(TARGET demo PROPERTY CXX_STANDARD 11)
target_link_libraries(demo -Wl,--whole-archive ${PROJECT_NAME} -Wl,--no-whole-archive) target_link_libraries(demo -Wl,--whole-archive ${PROJECT_NAME} -Wl,--no-whole-archive)

@ -1,7 +1,7 @@
## Build ## Build
``` ```
git clone https://github.com/tevador/monero-seed.git git clone https://git.wownero.com/wowlet/wownero-seed.git
cd monero-seed cd wownero-seed
mkdir build && cd build mkdir build && cd build
cmake .. cmake ..
make make
@ -19,35 +19,35 @@ make
### Create a new seed ### Create a new seed
``` ```
> ./monero-seed --create [--date <yyyy-MM-dd>] [--coin <monero|aeon>] > ./wownero-seed --create [--date <yyyy-MM-dd>] [--coin <monero|aeon>]
``` ```
Example: Example:
``` ```
> ./monero-seed --create --date 2100/03/14 --coin monero > ./wownero-seed --create --date 2100/03/14 --coin monero
Mnemonic phrase: test park taste security oxygen decorate essence ridge ship fish vehicle dream fluid pattern Mnemonic phrase: test park taste security oxygen decorate essence ridge ship fish vehicle dream fluid pattern
- coin: monero - coin: wownero
- private key: 7b816d8134e29393b0333eed4b6ed6edf97c156ad139055a706a6fb9599dcf8c - private key: 7b816d8134e29393b0333eed4b6ed6edf97c156ad139055a706a6fb9599dcf8c
- created on or after: 02/Mar/2100 - created on or after: 02/Mar/2100
``` ```
### Restore seed ### Restore seed
``` ```
./monero-seed --restore "<14-word seed>" [--coin <monero|aeon>] ./wownero-seed --restore "<14-word seed>" [--coin <monero|aeon>]
``` ```
Example: Example:
``` ```
> ./monero-seed --restore "test park taste security oxygen decorate essence ridge ship fish vehicle dream fluid pattern" --coin monero > ./wownero-seed --restore "test park taste security oxygen decorate essence ridge ship fish vehicle dream fluid pattern" --coin monero
- coin: monero - coin: wownero
- private key: 7b816d8134e29393b0333eed4b6ed6edf97c156ad139055a706a6fb9599dcf8c - private key: 7b816d8134e29393b0333eed4b6ed6edf97c156ad139055a706a6fb9599dcf8c
- created on or after: 02/Mar/2100 - created on or after: 02/Mar/2100
``` ```
Attempting to restore the same seed under a different coin will fail: Attempting to restore the same seed under a different coin will fail:
``` ```
> ./monero-seed --restore "test park taste security oxygen decorate essence ridge ship fish vehicle dream fluid pattern" --coin aeon > ./wownero-seed --restore "test park taste security oxygen decorate essence ridge ship fish vehicle dream fluid pattern" --coin aeon
ERROR: phrase is invalid (checksum mismatch) ERROR: phrase is invalid (checksum mismatch)
``` ```
@ -55,9 +55,9 @@ Restore has limited error correction capability, namely it can correct a single
This can be tested by replacing a word with `xxxx`: This can be tested by replacing a word with `xxxx`:
``` ```
> ./monero-seed --restore "test park xxxx security oxygen decorate essence ridge ship fish vehicle dream fluid pattern" --coin monero > ./wownero-seed --restore "test park xxxx security oxygen decorate essence ridge ship fish vehicle dream fluid pattern" --coin monero
Warning: corrected erasure: xxxx -> taste Warning: corrected erasure: xxxx -> taste
- coin: monero - coin: wownero
- private key: 7b816d8134e29393b0333eed4b6ed6edf97c156ad139055a706a6fb9599dcf8c - private key: 7b816d8134e29393b0333eed4b6ed6edf97c156ad139055a706a6fb9599dcf8c
- created on or after: 02/Mar/2100 - created on or after: 02/Mar/2100
``` ```

@ -11,15 +11,15 @@
#include <ctime> #include <ctime>
#include "gf_poly.hpp" #include "gf_poly.hpp"
class monero_seed { class wownero_seed {
public: public:
static const std::string erasure; static const std::string erasure;
static constexpr size_t size = 16; static constexpr size_t size = 16;
static constexpr size_t key_size = 32; static constexpr size_t key_size = 32;
using secret_key = std::array<uint8_t, key_size>; using secret_key = std::array<uint8_t, key_size>;
using secret_seed = std::array<uint8_t, size>; using secret_seed = std::array<uint8_t, size>;
monero_seed(const std::string& phrase, const std::string& coin); wownero_seed(const std::string& phrase, const std::string& coin);
monero_seed(std::time_t date_created, const std::string& coin); wownero_seed(std::time_t date_created, const std::string& coin);
std::time_t date() const { std::time_t date() const {
return date_; return date_;
} }
@ -29,7 +29,7 @@ public:
const secret_key& key() const { const secret_key& key() const {
return key_; return key_;
} }
friend std::ostream& operator<<(std::ostream& os, const monero_seed& seed); friend std::ostream& operator<<(std::ostream& os, const wownero_seed& seed);
private: private:
secret_seed seed_; secret_seed seed_;
secret_key key_; secret_key key_;
@ -39,4 +39,4 @@ private:
gf_poly message_; gf_poly message_;
}; };
std::ostream& operator<<(std::ostream& os, const monero_seed::secret_key& key); std::ostream& operator<<(std::ostream& os, const wownero_seed::secret_key& key);

@ -3,7 +3,7 @@
All rights reserved. All rights reserved.
*/ */
#include <monero_seed/galois_field.hpp> #include <wownero_seed/galois_field.hpp>
template<unsigned bits, gf_item primitive> template<unsigned bits, gf_item primitive>
galois_field<bits, primitive>::galois_field() { galois_field<bits, primitive>::galois_field() {

@ -3,6 +3,6 @@
All rights reserved. All rights reserved.
*/ */
#include <monero_seed/gf_elem.hpp> #include <wownero_seed/gf_elem.hpp>
const gf_2048 gf_elem::field; const gf_2048 gf_elem::field;

@ -3,7 +3,7 @@
All rights reserved. All rights reserved.
*/ */
#include <monero_seed/gf_poly.hpp> #include <wownero_seed/gf_poly.hpp>
gf_poly::gf_poly(gf_elem coeff, unsigned degree) : degree_(0) { gf_poly::gf_poly(gf_elem coeff, unsigned degree) : degree_(0) {
coeff_[degree] = coeff; coeff_[degree] = coeff;

@ -3,7 +3,7 @@
All rights reserved. All rights reserved.
*/ */
#include <monero_seed/monero_seed.hpp> #include <wownero_seed/wownero_seed.hpp>
#include <iostream> #include <iostream>
#include <iomanip> #include <iomanip>
#include <sstream> #include <sstream>
@ -51,9 +51,9 @@ static time_t parse_date(const char* s) {
throw std::runtime_error("invalid date"); throw std::runtime_error("invalid date");
} }
void print_seed(const monero_seed& seed, const char* coin, bool phrase) { void print_seed(const wownero_seed& seed, const char* coin, bool phrase) {
if (!seed.correction().empty()) { if (!seed.correction().empty()) {
std::cout << "Warning: corrected erasure: " << monero_seed::erasure << " -> " << seed.correction() << std::endl; std::cout << "Warning: corrected erasure: " << wownero_seed::erasure << " -> " << seed.correction() << std::endl;
} }
if (phrase) { if (phrase) {
std::cout << "Mnemonic phrase: " << seed << std::endl; std::cout << "Mnemonic phrase: " << seed << std::endl;
@ -72,7 +72,7 @@ int main(int argc, const char* argv[]) {
const char* restore; const char* restore;
read_option("--create", argc, argv, create); read_option("--create", argc, argv, create);
read_string_option("--date", argc, argv, &create_date); read_string_option("--date", argc, argv, &create_date);
read_string_option("--coin", argc, argv, &coin, "monero"); read_string_option("--coin", argc, argv, &coin, "wownero");
read_string_option("--restore", argc, argv, &restore); read_string_option("--restore", argc, argv, &restore);
try { try {
@ -84,15 +84,15 @@ int main(int argc, const char* argv[]) {
else { else {
time = std::time(nullptr); time = std::time(nullptr);
} }
monero_seed seed(time, coin); wownero_seed seed(time, coin);
print_seed(seed, coin, true); print_seed(seed, coin, true);
} }
else if (restore != nullptr) { else if (restore != nullptr) {
monero_seed seed(restore, coin); wownero_seed seed(restore, coin);
print_seed(seed, coin, false); print_seed(seed, coin, false);
} }
else { else {
std::cout << "Monero 14-word mnemonic seed proof of concept" << std::endl; std::cout << "14-word mnemonic seed" << std::endl;
std::cout << "Usage: " << std::endl; std::cout << "Usage: " << std::endl;
std::cout << argv[0] << " --create [--date <yyyy-MM-dd>] [--coin <monero|aeon|wownero>]" << std::endl; std::cout << argv[0] << " --create [--date <yyyy-MM-dd>] [--coin <monero|aeon|wownero>]" << std::endl;
std::cout << argv[0] << " --restore \"<14-word seed>\" [--coin <monero|aeon|wownero>]" << std::endl; std::cout << argv[0] << " --restore \"<14-word seed>\" [--coin <monero|aeon|wownero>]" << std::endl;

@ -3,7 +3,7 @@
All rights reserved. All rights reserved.
*/ */
#include <monero_seed/reed_solomon_code.hpp> #include <wownero_seed/reed_solomon_code.hpp>
#include <cassert> #include <cassert>
reed_solomon_code::reed_solomon_code(unsigned check_digits) : generator(1, 0) { reed_solomon_code::reed_solomon_code(unsigned check_digits) : generator(1, 0) {

@ -3,7 +3,7 @@
All rights reserved. All rights reserved.
*/ */
#include <monero_seed/secure_random.hpp> #include <wownero_seed/secure_random.hpp>
#include <stdexcept> #include <stdexcept>
#include <cstdlib> #include <cstdlib>

@ -3,7 +3,7 @@
All rights reserved. All rights reserved.
*/ */
#include <monero_seed/wordlist.hpp> #include <wownero_seed/wordlist.hpp>
#include <algorithm> #include <algorithm>
const static std::string english_words[] = { const static std::string english_words[] = {

@ -3,11 +3,11 @@
All rights reserved. All rights reserved.
*/ */
#include <monero_seed/monero_seed.hpp> #include <wownero_seed/wownero_seed.hpp>
#include <monero_seed/secure_random.hpp> #include <wownero_seed/secure_random.hpp>
#include <monero_seed/wordlist.hpp> #include <wownero_seed/wordlist.hpp>
#include <monero_seed/gf_poly.hpp> #include <wownero_seed/gf_poly.hpp>
#include <monero_seed/reed_solomon_code.hpp> #include <wownero_seed/reed_solomon_code.hpp>
#include "argon2/argon2.h" #include "argon2/argon2.h"
#include "argon2/blake2/blake2-impl.h" #include "argon2/blake2/blake2-impl.h"
#include "pbkdf2.h" #include "pbkdf2.h"
@ -20,14 +20,14 @@
#include <sstream> #include <sstream>
#include <algorithm> #include <algorithm>
const std::string monero_seed::erasure = "xxxx"; const std::string wownero_seed::erasure = "xxxx";
class monero_seed_exception : public std::exception { class wownero_seed_exception : public std::exception {
public: public:
monero_seed_exception(const std::string& msg) wownero_seed_exception(const std::string& msg)
: msg_(msg) : msg_(msg)
{ } { }
~monero_seed_exception() throw() {} ~wownero_seed_exception() throw() {}
const char* what() const throw() override { const char* what() const throw() override {
return msg_.c_str(); return msg_.c_str();
@ -39,7 +39,7 @@ private:
#define THROW_EXCEPTION(message) do { \ #define THROW_EXCEPTION(message) do { \
std::ostringstream oss; \ std::ostringstream oss; \
oss << message; \ oss << message; \
throw monero_seed_exception(oss.str()); } \ throw wownero_seed_exception(oss.str()); } \
while(false) while(false)
constexpr std::time_t epoch = 1590969600; //1st June 2020 constexpr std::time_t epoch = 1590969600; //1st June 2020
@ -69,7 +69,7 @@ static const char* KDF_PBKDF2 = "PBKDF2-HMAC-SHA256/4096";
static_assert(total_bits static_assert(total_bits
== reserved_bits + date_bits + checksum_size + == reserved_bits + date_bits + checksum_size +
sizeof(monero_seed::secret_seed) * CHAR_BIT, sizeof(wownero_seed::secret_seed) * CHAR_BIT,
"Invalid mnemonic seed size"); "Invalid mnemonic seed size");
static void write_data(gf_poly& poly, unsigned& rem_bits, unsigned value, unsigned bits) { static void write_data(gf_poly& poly, unsigned& rem_bits, unsigned value, unsigned bits) {
@ -117,7 +117,7 @@ static gf_elem get_coin_flag(const std::string& coin) {
static const reed_solomon_code rs(check_digits); static const reed_solomon_code rs(check_digits);
monero_seed::monero_seed(std::time_t date_created, const std::string& coin) { wownero_seed::wownero_seed(std::time_t date_created, const std::string& coin) {
if (date_created < epoch) { if (date_created < epoch) {
THROW_EXCEPTION("date_created must not be before 1st June 2020"); THROW_EXCEPTION("date_created must not be before 1st June 2020");
} }
@ -142,7 +142,7 @@ monero_seed::monero_seed(std::time_t date_created, const std::string& coin) {
message_[check_digits] -= coin_flag; message_[check_digits] -= coin_flag;
} }
monero_seed::monero_seed(const std::string& phrase, const std::string& coin) { wownero_seed::wownero_seed(const std::string& phrase, const std::string& coin) {
gf_elem coin_flag = get_coin_flag(coin); gf_elem coin_flag = get_coin_flag(coin);
int word_count = 0; int word_count = 0;
size_t offset = 0; size_t offset = 0;
@ -222,7 +222,7 @@ monero_seed::monero_seed(const std::string& phrase, const std::string& coin) {
pbkdf2_hmac_sha256(seed_.data(), seed_.size(), salt, sizeof(salt), pbkdf2_iterations, key_.data(), key_.size()); pbkdf2_hmac_sha256(seed_.data(), seed_.size(), salt, sizeof(salt), pbkdf2_iterations, key_.data(), key_.size());
} }
std::ostream& operator<<(std::ostream& os, const monero_seed& seed) { std::ostream& operator<<(std::ostream& os, const wownero_seed& seed) {
for (int i = 0; i <= seed.message_.degree(); ++i) { for (int i = 0; i <= seed.message_.degree(); ++i) {
if (i > 0) { if (i > 0) {
os << " "; os << " ";
@ -232,7 +232,7 @@ std::ostream& operator<<(std::ostream& os, const monero_seed& seed) {
return os; return os;
} }
std::ostream& operator<<(std::ostream& os, const monero_seed::secret_key& key) { std::ostream& operator<<(std::ostream& os, const wownero_seed::secret_key& key) {
os << std::hex; os << std::hex;
for (int i = 0; i < key.size(); ++i) { for (int i = 0; i < key.size(); ++i) {
os << std::setw(2) << std::setfill('0') << (unsigned)key[i]; os << std::setw(2) << std::setfill('0') << (unsigned)key[i];
Loading…
Cancel
Save