aboutsummaryrefslogtreecommitdiff
path: root/src/crypto
diff options
context:
space:
mode:
authorThomas Winget <tewinget@gmail.com>2014-06-06 14:18:11 -0400
committerThomas Winget <tewinget@gmail.com>2014-06-12 19:05:51 -0400
commitd22e458c6c680f4b5dcf56a58a37a5f79912e65c (patch)
tree05a150051c892903c87d913dddf321996c035079 /src/crypto
parentmissing '.at' on two map calls. built on some machines, very strange... (diff)
downloadmonero-d22e458c6c680f4b5dcf56a58a37a5f79912e65c.tar.xz
builds, but doesn't link. other than that, electrum-style recovery implemented (but not tested\!)
Diffstat (limited to '')
-rw-r--r--src/crypto/crypto.cpp19
-rw-r--r--src/crypto/crypto.h8
-rw-r--r--src/crypto/electrum-words.cpp10
-rw-r--r--src/cryptonote_core/account.cpp13
-rw-r--r--src/cryptonote_core/account.h2
5 files changed, 37 insertions, 15 deletions
diff --git a/src/crypto/crypto.cpp b/src/crypto/crypto.cpp
index 31fc31d5b..98a17a3e4 100644
--- a/src/crypto/crypto.cpp
+++ b/src/crypto/crypto.cpp
@@ -68,12 +68,27 @@ namespace crypto {
* TODO: allow specifiying random value (for wallet recovery)
*
*/
- void crypto_ops::generate_keys(public_key &pub, secret_key &sec) {
+ secret_key crypto_ops::generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover) {
lock_guard<mutex> lock(random_lock);
ge_p3 point;
- random_scalar(sec);
+
+ secret_key rng;
+
+ if (recover)
+ {
+ rng = recovery_key;
+ }
+ else
+ {
+ random_scalar(rng);
+ }
+ sec = rng;
+ sc_reduce32(&sec); // reduce in case second round of keys (sendkeys)
+
ge_scalarmult_base(&point, &sec);
ge_p3_tobytes(&pub, &point);
+
+ return rng;
}
bool crypto_ops::check_key(const public_key &key) {
diff --git a/src/crypto/crypto.h b/src/crypto/crypto.h
index 61641fbcf..024713df1 100644
--- a/src/crypto/crypto.h
+++ b/src/crypto/crypto.h
@@ -62,8 +62,8 @@ namespace crypto {
void operator=(const crypto_ops &);
~crypto_ops();
- static void generate_keys(public_key &, secret_key &);
- friend void generate_keys(public_key &, secret_key &);
+ static secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false);
+ friend secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key, bool recover);
static bool check_key(const public_key &);
friend bool check_key(const public_key &);
static bool secret_key_to_public_key(const secret_key &, public_key &);
@@ -102,8 +102,8 @@ namespace crypto {
/* Generate a new key pair
*/
- inline void generate_keys(public_key &pub, secret_key &sec) {
- crypto_ops::generate_keys(pub, sec);
+ inline secret_key generate_keys(public_key &pub, secret_key &sec, const secret_key& recovery_key = secret_key(), bool recover = false) {
+ return crypto_ops::generate_keys(pub, sec, recovery_key, recover);
}
/* Check a public key. Returns true if it is valid, false otherwise.
diff --git a/src/crypto/electrum-words.cpp b/src/crypto/electrum-words.cpp
index b4580e01f..048aa403f 100644
--- a/src/crypto/electrum-words.cpp
+++ b/src/crypto/electrum-words.cpp
@@ -36,7 +36,7 @@ namespace crypto
// error on non-compliant word list
if (wlist.size() != 12 && wlist.size() != 24) return false;
- for (int i=0; i < wlist.size() / 3; i++)
+ for (unsigned int i=0; i < wlist.size() / 3; i++)
{
uint32_t val;
uint32_t w1, w2, w3;
@@ -55,12 +55,12 @@ namespace crypto
val = w1 + n * ((w2 - w1) % n) + n * n * ((w3 - w2) % n);
- memcpy(dst.data + i * 4, val, 4); // copy 4 bytes to position
+ memcpy(&dst.data + i * 4, &val, 4); // copy 4 bytes to position
}
if (wlist.size() == 12)
{
- memcpy(dst.data, dst.data + 16, 16); // if electrum 12-word seed, duplicate
+ memcpy(&dst.data, &dst.data + 16, 16); // if electrum 12-word seed, duplicate
}
return true;
@@ -78,13 +78,13 @@ namespace crypto
if (sizeof(src.data) % 4 != 0) return false;
// 8 bytes -> 3 words. 8 digits base 16 -> 3 digits base 1626
- for (int i=0; i < sizeof(src.data)/4; i++, words += ' ')
+ for (unsigned int i=0; i < sizeof(src.data)/4; i++, words += ' ')
{
uint32_t w1, w2, w3;
uint32_t val;
- memcpy(val, src, 4);
+ memcpy(&val, &src.data, 4);
w1 = val % n;
w2 = ((val / n) + w1) % n;
diff --git a/src/cryptonote_core/account.cpp b/src/cryptonote_core/account.cpp
index 9a96de2f0..bd47c8ba4 100644
--- a/src/cryptonote_core/account.cpp
+++ b/src/cryptonote_core/account.cpp
@@ -10,6 +10,7 @@
#include "account.h"
#include "warnings.h"
#include "crypto/crypto.h"
+#include "crypto/blake256.h"
#include "cryptonote_core/cryptonote_basic_impl.h"
#include "cryptonote_core/cryptonote_format_utils.h"
using namespace std;
@@ -29,11 +30,17 @@ DISABLE_VS_WARNINGS(4244 4345)
m_keys = account_keys();
}
//-----------------------------------------------------------------
- void account_base::generate(const crypto::secret_key& recovery_key, bool recover)
+ crypto::secret_key account_base::generate(const crypto::secret_key& recovery_key, bool recover)
{
- generate_keys(m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key);
- generate_keys(m_keys.m_account_address.m_view_public_key, m_keys.m_view_secret_key);
+ crypto::secret_key first = generate_keys(m_keys.m_account_address.m_spend_public_key, m_keys.m_spend_secret_key, recovery_key, recover);
+
+ // rng for generating second set of keys is hash of first rng. means only one set of electrum-style words needed for recovery
+ crypto::secret_key second;
+ blake256_hash((uint8_t *)&second, (uint8_t *)&first, sizeof(crypto::secret_key));
+
+ generate_keys(m_keys.m_account_address.m_view_public_key, m_keys.m_view_secret_key, second, true);
m_creation_timestamp = time(NULL);
+ return first;
}
//-----------------------------------------------------------------
const account_keys& account_base::get_keys() const
diff --git a/src/cryptonote_core/account.h b/src/cryptonote_core/account.h
index 745da0897..f07d4dd79 100644
--- a/src/cryptonote_core/account.h
+++ b/src/cryptonote_core/account.h
@@ -31,7 +31,7 @@ namespace cryptonote
{
public:
account_base();
- void generate(const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false);
+ crypto::secret_key generate(const crypto::secret_key& recovery_key = crypto::secret_key(), bool recover = false);
const account_keys& get_keys() const;
std::string get_public_address_str();