Rework addresses.

This commit is contained in:
Arthur Britto
2012-03-17 20:19:09 -07:00
parent 6e8421dd99
commit 73ff9b95ad
33 changed files with 1287 additions and 708 deletions

View File

@@ -7,16 +7,23 @@
#include "Serializer.h"
uint256 CKey::PassPhraseToKey(const std::string& passPhrase)
// <-- seed
uint128 CKey::PassPhraseToKey(const std::string& passPhrase)
{
Serializer s;
s.addRaw(passPhrase.c_str(), passPhrase.size());
uint256 ret(s.getSHA512Half());
uint256 hash256 = s.getSHA512Half();
uint128 ret(hash256);
s.secureErase();
return ret;
}
EC_KEY* CKey::GenerateRootDeterministicKey(const uint256& key)
// --> seed
// <-- private root generator + public root generator
EC_KEY* CKey::GenerateRootDeterministicKey(const uint128& seed)
{
BN_CTX* ctx=BN_CTX_new();
if(!ctx) return NULL;
@@ -49,8 +56,8 @@ EC_KEY* CKey::GenerateRootDeterministicKey(const uint256& key)
int seq=0;
do
{ // private key must be non-zero and less than the curve's order
Serializer s(72);
s.add256(key);
Serializer s((128+32)/8);
s.add128(seed);
s.add32(seq++);
uint256 root=s.getSHA512Half();
s.secureErase();
@@ -102,46 +109,48 @@ EC_KEY* CKey::GenerateRootDeterministicKey(const uint256& key)
return pkey;
}
EC_KEY* CKey::GenerateRootPubKey(const std::string& pubHex)
// Take newcoin address.
// --> root public generator (consumes)
// <-- root public generator in EC format
EC_KEY* CKey::GenerateRootPubKey(BIGNUM* pubGenerator)
{
BIGNUM* bn=NULL;
BN_hex2bn(&bn, pubHex.c_str());
if(bn==NULL) return NULL;
if(pubGenerator==NULL) return NULL;
EC_KEY* pkey=EC_KEY_new_by_curve_name(NID_secp256k1);
if(!pkey)
{
BN_free(bn);
BN_free(pubGenerator);
return NULL;
}
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
EC_POINT* pubPoint=EC_POINT_bn2point(EC_KEY_get0_group(pkey), bn, NULL, NULL);
BN_free(bn);
EC_POINT* pubPoint=EC_POINT_bn2point(EC_KEY_get0_group(pkey), pubGenerator, NULL, NULL);
BN_free(pubGenerator);
if(!pubPoint)
{
EC_KEY_free(pkey);
return NULL;
}
if(!EC_KEY_set_public_key(pkey, pubPoint))
{
EC_POINT_free(pubPoint);
EC_KEY_free(pkey);
return NULL;
}
return pkey;
}
static BIGNUM* makeHash(const uint160& family, int seq, BIGNUM* order)
// --> public generator
static BIGNUM* makeHash(const NewcoinAddress& family, int seq, BIGNUM* order)
{
int subSeq=0;
BIGNUM* ret=NULL;
do
{
Serializer s(28);
s.add160(family);
Serializer s((128+32+32)/8);
s.add128(family.getFamilySeed());
s.add32(seq);
s.add32(subSeq++);
uint256 root=s.getSHA512Half();
@@ -149,64 +158,66 @@ static BIGNUM* makeHash(const uint160& family, int seq, BIGNUM* order)
ret=BN_bin2bn((const unsigned char *) &root, sizeof(root), ret);
if(!ret) return NULL;
} while (BN_is_zero(ret) || (BN_cmp(ret, order)>=0));
return ret;
}
EC_KEY* CKey::GeneratePublicDeterministicKey(const uint160& family, const EC_POINT* rootPubKey, int seq)
// --> public generator
EC_KEY* CKey::GeneratePublicDeterministicKey(const NewcoinAddress& family, int seq)
{ // publicKey(n) = rootPublicKey EC_POINT_+ Hash(pubHash|seq)*point
BN_CTX* ctx=BN_CTX_new();
if(ctx==NULL) return NULL;
EC_KEY* rootKey = CKey::GenerateRootPubKey(family.getFamilyGeneratorBN());
const EC_POINT* rootPubKey = EC_KEY_get0_public_key(rootKey);
BN_CTX* ctx = BN_CTX_new();
EC_KEY* pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
EC_POINT* newPoint = 0;
BIGNUM* order = 0;
BIGNUM* hash = 0;
bool success = true;
EC_KEY* pkey=EC_KEY_new_by_curve_name(NID_secp256k1);
if(pkey==NULL)
{
BN_CTX_free(ctx);
return NULL;
}
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
if (!ctx || !pkey) success = false;
EC_POINT *newPoint=EC_POINT_new(EC_KEY_get0_group(pkey));
if(newPoint==NULL)
{
EC_KEY_free(pkey);
BN_CTX_free(ctx);
return NULL;
if (success)
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
if (success) {
newPoint = EC_POINT_new(EC_KEY_get0_group(pkey));
if(!newPoint) success = false;
}
BIGNUM* order=BN_new();
if(!order || !EC_GROUP_get_order(EC_KEY_get0_group(pkey), order, ctx))
{
if(order) BN_free(order);
EC_KEY_free(pkey);
BN_CTX_free(ctx);
return NULL;
if (success) {
order = BN_new();
if(!order || !EC_GROUP_get_order(EC_KEY_get0_group(pkey), order, ctx))
success = false;
}
// calculate the private additional key
BIGNUM* hash=makeHash(family, seq, order);
BN_free(order);
if(hash==NULL)
{
EC_POINT_free(newPoint);
BN_CTX_free(ctx);
EC_KEY_free(pkey);
return NULL;
// Calculate the private additional key.
if (success) {
hash = makeHash(family, seq, order);
if(!hash) success = false;
}
// calculate the corresponding public key
EC_POINT_mul(EC_KEY_get0_group(pkey), newPoint, hash, NULL, NULL, ctx);
BN_free(hash);
// add the master public key and set
EC_POINT_add(EC_KEY_get0_group(pkey), newPoint, newPoint, rootPubKey, ctx);
EC_KEY_set_public_key(pkey, newPoint);
if (success) {
// Calculate the corresponding public key.
EC_POINT_mul(EC_KEY_get0_group(pkey), newPoint, hash, NULL, NULL, ctx);
EC_POINT_free(newPoint);
BN_CTX_free(ctx);
return pkey;
// Add the master public key and set.
EC_POINT_add(EC_KEY_get0_group(pkey), newPoint, newPoint, rootPubKey, ctx);
EC_KEY_set_public_key(pkey, newPoint);
}
if (order) BN_free(order);
if (hash) BN_free(hash);
if (newPoint) EC_POINT_free(newPoint);
if (ctx) BN_CTX_free(ctx);
if (rootKey) EC_KEY_free(rootKey);
if (pkey && !success) EC_KEY_free(pkey);
return success ? pkey : NULL;
}
EC_KEY* CKey::GeneratePrivateDeterministicKey(const uint160& family, const BIGNUM* rootPrivKey, int seq)
// --> root private key
EC_KEY* CKey::GeneratePrivateDeterministicKey(const NewcoinAddress& family, const BIGNUM* rootPrivKey, int seq)
{ // privateKey(n) = (rootPrivateKey + Hash(pubHash|seq)) % order
BN_CTX* ctx=BN_CTX_new();
if(ctx==NULL) return NULL;
@@ -218,7 +229,7 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey(const uint160& family, const BIGNU
return NULL;
}
EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED);
BIGNUM* order=BN_new();
if(order==NULL)
{
@@ -226,7 +237,7 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey(const uint160& family, const BIGNU
EC_KEY_free(pkey);
return NULL;
}
if(!EC_GROUP_get_order(EC_KEY_get0_group(pkey), order, ctx))
{
BN_free(order);
@@ -271,5 +282,7 @@ EC_KEY* CKey::GeneratePrivateDeterministicKey(const uint160& family, const BIGNU
EC_POINT_free(pubKey);
BN_CTX_free(ctx);
return pkey;
return pkey;
}
// vim:ts=4