mirror of
https://git.wownero.com/wowlet/wownero-seed.git
synced 2024-12-21 23:38:52 +00:00
Merge pull request 'wowify' (#5) from wownero-seed into master
Reviewed-on: https://git.wownero.com/wowlet/monero-seed/pulls/5
This commit is contained in:
commit
7830fddcc3
@ -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)
|
||||||
|
22
README.md
22
README.md
@ -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;
|
||||||
|
14
src/main.cpp
14
src/main.cpp
@ -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…
Reference in New Issue
Block a user