mirror of
https://github.com/XRPLF/rippled.git
synced 2025-11-28 23:15:52 +00:00
New wallet system. Still missing unit tests, ledger synchronization,
and SQL code. This uses some of the 'magic' properties of elliptic curves to create related families of public and private keys. Wallet encryption is not needed because the private keys do not need to be stored.
This commit is contained in:
@@ -8,16 +8,16 @@
|
||||
|
||||
#include "Serializer.h"
|
||||
|
||||
uint256 CKey::GetBaseFromString(const std::string& phrase)
|
||||
uint256 CKey::PassPhraseToKey(const std::string& passPhrase)
|
||||
{
|
||||
Serializer s;
|
||||
s.addRaw((const void *) phrase.c_str(), phrase.length());
|
||||
uint256 base(s.getSHA512Half());
|
||||
s.addRaw(passPhrase.c_str(), passPhrase.size());
|
||||
uint256 ret(s.getSHA512Half());
|
||||
s.secureErase();
|
||||
return base;
|
||||
return ret;
|
||||
}
|
||||
|
||||
EC_KEY* CKey::GenerateDeterministicKey(const uint256& base, uint32 n, bool private_key)
|
||||
EC_KEY* CKey::GenerateRootDeterministicKey(const uint256& key)
|
||||
{
|
||||
BN_CTX* ctx=BN_CTX_new();
|
||||
if(!ctx) return NULL;
|
||||
@@ -44,9 +44,8 @@ EC_KEY* CKey::GenerateDeterministicKey(const uint256& base, uint32 n, bool priva
|
||||
int seq=0;
|
||||
do
|
||||
{ // private key must be non-zero and less than the curve's order
|
||||
Serializer s;
|
||||
s.add32(n);
|
||||
s.add256(base);
|
||||
Serializer s(72);
|
||||
s.add256(key);
|
||||
s.add32(seq++);
|
||||
uint256 root=s.getSHA512Half();
|
||||
s.secureErase();
|
||||
@@ -62,7 +61,7 @@ EC_KEY* CKey::GenerateDeterministicKey(const uint256& base, uint32 n, bool priva
|
||||
|
||||
BN_free(order);
|
||||
|
||||
if(private_key && !EC_KEY_set_private_key(pkey, privKey))
|
||||
if(!EC_KEY_set_private_key(pkey, privKey))
|
||||
{ // set the random point as the private key
|
||||
assert(false);
|
||||
EC_KEY_free(pkey);
|
||||
@@ -98,8 +97,91 @@ EC_KEY* CKey::GenerateDeterministicKey(const uint256& base, uint32 n, bool priva
|
||||
return pkey;
|
||||
}
|
||||
|
||||
uint256 CKey::GetRandomBase(void)
|
||||
static BIGNUM* makeHash(const uint160& family, int seq)
|
||||
{
|
||||
uint256 r;
|
||||
return (RAND_bytes((unsigned char *) &r, sizeof(uint256)) == 1) ? r : 0;
|
||||
Serializer s;
|
||||
s.add160(family);
|
||||
s.add32(seq);
|
||||
uint256 root=s.getSHA512Half();
|
||||
s.secureErase();
|
||||
return BN_bin2bn((const unsigned char *) &root, sizeof(root), NULL);
|
||||
}
|
||||
|
||||
EC_KEY* CKey::GeneratePublicDeterministicKey(const uint160& family, EC_POINT* rootPubKey, int seq)
|
||||
{ // publicKey(n) = rootPublicKey EC_POINT_+ Hash(pubHash|seq)*point
|
||||
BN_CTX* ctx=BN_CTX_new();
|
||||
if(ctx==NULL) return NULL;
|
||||
|
||||
EC_KEY* pkey=EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
if(pkey==NULL)
|
||||
{
|
||||
BN_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EC_POINT *newPoint=EC_POINT_new(EC_KEY_get0_group(pkey));
|
||||
if(newPoint==NULL)
|
||||
{
|
||||
EC_KEY_free(pkey);
|
||||
BN_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BIGNUM* hash=makeHash(family, seq);
|
||||
if(hash==NULL)
|
||||
{
|
||||
EC_POINT_free(newPoint);
|
||||
BN_CTX_free(ctx);
|
||||
EC_KEY_free(pkey);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
EC_POINT_mul(EC_KEY_get0_group(pkey), newPoint, hash, NULL, NULL, ctx);
|
||||
BN_free(hash);
|
||||
|
||||
EC_POINT_add(EC_KEY_get0_group(pkey), newPoint, newPoint, rootPubKey, ctx);
|
||||
EC_KEY_set_public_key(pkey, newPoint);
|
||||
|
||||
EC_POINT_free(newPoint);
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return pkey;
|
||||
}
|
||||
|
||||
EC_KEY* CKey::GeneratePrivateDeterministicKey(const uint160& family, BIGNUM* rootPrivKey, int seq)
|
||||
{ // privateKey(n) = (rootPrivateKey + Hash(pubHash|seq)) % order
|
||||
BN_CTX* ctx=BN_CTX_new();
|
||||
if(ctx==NULL) return NULL;
|
||||
|
||||
EC_KEY* pkey=EC_KEY_new_by_curve_name(NID_secp256k1);
|
||||
if(pkey==NULL)
|
||||
{
|
||||
BN_CTX_free(ctx);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
BIGNUM* order=BN_new();
|
||||
if(order==NULL)
|
||||
{
|
||||
BN_CTX_free(ctx);
|
||||
EC_KEY_free(pkey);
|
||||
}
|
||||
|
||||
EC_GROUP_get_order(EC_KEY_get0_group(pkey), order, ctx);
|
||||
|
||||
BIGNUM* privKey=makeHash(family, seq);
|
||||
BN_mod_add(privKey, privKey, rootPrivKey, order, ctx);
|
||||
BN_free(order);
|
||||
|
||||
EC_KEY_set_private_key(pkey, privKey);
|
||||
|
||||
EC_POINT* pubKey=EC_POINT_new(EC_KEY_get0_group(pkey));
|
||||
EC_POINT_mul(EC_KEY_get0_group(pkey), pubKey, privKey, NULL, NULL, ctx);
|
||||
BN_free(privKey);
|
||||
EC_KEY_set_public_key(pkey, pubKey);
|
||||
|
||||
EC_POINT_free(pubKey);
|
||||
BN_CTX_free(ctx);
|
||||
|
||||
return pkey;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user