Many fixes and clean up for NewcoinAddress.

This commit is contained in:
Arthur Britto
2012-03-18 19:00:28 -07:00
parent 73ff9b95ad
commit 925cc6ff86
11 changed files with 159 additions and 240 deletions

View File

@@ -36,14 +36,6 @@ static bool isHex(char j)
return false; return false;
} }
bool AccountState::isHexAccountID(const std::string& acct)
{
if(acct.size()!=40) return false;
for(int i=1; i<40; i++)
if(!isHex(acct[i])) return false;
return true;
}
void AccountState::addJson(Json::Value& val) void AccountState::addJson(Json::Value& val)
{ {
Json::Value as(Json::objectValue); Json::Value as(Json::objectValue);

View File

@@ -51,7 +51,6 @@ public:
assert(mAccountSeq!=0); assert(mAccountSeq!=0);
mAccountSeq--; mAccountSeq--;
} }
static bool isHexAccountID(const std::string& acct);
std::vector<unsigned char> getRaw() const; std::vector<unsigned char> getRaw() const;
void addJson(Json::Value& value); void addJson(Json::Value& value);

View File

@@ -76,13 +76,12 @@ void Application::run()
std::cout << "Before Run." << std::endl; std::cout << "Before Run." << std::endl;
// Temporary root account will be ["This is my payphrase."]:0 // Temporary root account will be ["This is my payphrase."]:0
NewcoinAddress rootFamilySeed; NewcoinAddress rootFamilySeed; // Hold the 128 password.
rootFamilySeed.setFamilySeed(CKey::PassPhraseToKey("This is my payphrase")); NewcoinAddress rootFamilyGenerator; // Hold the generator.
NewcoinAddress rootFamilyGenerator;
rootFamilyGenerator.setFamilyGenerator(rootFamilySeed);
NewcoinAddress rootAddress; NewcoinAddress rootAddress;
rootFamilySeed.setFamilySeed(CKey::PassPhraseToKey("This is my payphrase"));
rootFamilyGenerator.setFamilyGenerator(rootFamilySeed);
rootAddress.setAccountPublic(rootFamilyGenerator, 0); rootAddress.setAccountPublic(rootFamilyGenerator, 0);
Ledger::pointer firstLedger(new Ledger(rootAddress, 100000000)); Ledger::pointer firstLedger(new Ledger(rootAddress, 100000000));

View File

@@ -143,14 +143,14 @@ EC_KEY* CKey::GenerateRootPubKey(BIGNUM* pubGenerator)
} }
// --> public generator // --> public generator
static BIGNUM* makeHash(const NewcoinAddress& family, int seq, BIGNUM* order) static BIGNUM* makeHash(const NewcoinAddress& generator, int seq, BIGNUM* order)
{ {
int subSeq=0; int subSeq=0;
BIGNUM* ret=NULL; BIGNUM* ret=NULL;
do do
{ {
Serializer s((128+32+32)/8); Serializer s((33*8+32+32)/8);
s.add128(family.getFamilySeed()); s.addRaw(generator.getFamilyGenerator());
s.add32(seq); s.add32(seq);
s.add32(subSeq++); s.add32(subSeq++);
uint256 root=s.getSHA512Half(); uint256 root=s.getSHA512Half();
@@ -163,9 +163,9 @@ static BIGNUM* makeHash(const NewcoinAddress& family, int seq, BIGNUM* order)
} }
// --> public generator // --> public generator
EC_KEY* CKey::GeneratePublicDeterministicKey(const NewcoinAddress& family, int seq) EC_KEY* CKey::GeneratePublicDeterministicKey(const NewcoinAddress& generator, int seq)
{ // publicKey(n) = rootPublicKey EC_POINT_+ Hash(pubHash|seq)*point { // publicKey(n) = rootPublicKey EC_POINT_+ Hash(pubHash|seq)*point
EC_KEY* rootKey = CKey::GenerateRootPubKey(family.getFamilyGeneratorBN()); EC_KEY* rootKey = CKey::GenerateRootPubKey(generator.getFamilyGeneratorBN());
const EC_POINT* rootPubKey = EC_KEY_get0_public_key(rootKey); const EC_POINT* rootPubKey = EC_KEY_get0_public_key(rootKey);
BN_CTX* ctx = BN_CTX_new(); BN_CTX* ctx = BN_CTX_new();
EC_KEY* pkey = EC_KEY_new_by_curve_name(NID_secp256k1); EC_KEY* pkey = EC_KEY_new_by_curve_name(NID_secp256k1);
@@ -193,7 +193,7 @@ EC_KEY* CKey::GeneratePublicDeterministicKey(const NewcoinAddress& family, int s
// Calculate the private additional key. // Calculate the private additional key.
if (success) { if (success) {
hash = makeHash(family, seq, order); hash = makeHash(generator, seq, order);
if(!hash) success = false; if(!hash) success = false;
} }

View File

@@ -5,10 +5,12 @@
#include "openssl/ec.h" #include "openssl/ec.h"
#include <cassert> #include <cassert>
#include <algorithm>
#include <iostream>
NewcoinAddress::NewcoinAddress() NewcoinAddress::NewcoinAddress()
{ {
version = VER_NONE; nVersion = VER_NONE;
} }
bool NewcoinAddress::IsValid() bool NewcoinAddress::IsValid()
@@ -22,10 +24,9 @@ bool NewcoinAddress::IsValid()
uint160 NewcoinAddress::getHanko() const uint160 NewcoinAddress::getHanko() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_HANKO: case VER_HANKO:
return uint160(vchData); return uint160(vchData);
@@ -35,18 +36,15 @@ uint160 NewcoinAddress::getHanko() const
return Hash160(vchData); return Hash160(vchData);
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return 0;
} }
std::string NewcoinAddress::humanHanko() const std::string NewcoinAddress::humanHanko() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_HANKO: case VER_HANKO:
return ToString(); return ToString();
@@ -61,10 +59,8 @@ std::string NewcoinAddress::humanHanko() const
} }
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return 0;
} }
bool NewcoinAddress::setHanko(const std::string& strHanko) bool NewcoinAddress::setHanko(const std::string& strHanko)
@@ -83,45 +79,36 @@ void NewcoinAddress::setHanko(const uint160& hash160)
const std::vector<unsigned char>& NewcoinAddress::getNodePublic() const const std::vector<unsigned char>& NewcoinAddress::getNodePublic() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_HANKO: case VER_HANKO:
std::runtime_error("public not available from hanko"); throw std::runtime_error("public not available from hanko");
break;
case VER_NODE_PUBLIC: case VER_NODE_PUBLIC:
// Do nothing. return vchData;
break;
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return vchData;
} }
std::string NewcoinAddress::humanNodePublic() const std::string NewcoinAddress::humanNodePublic() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_HANKO: case VER_HANKO:
std::runtime_error("public not available from hanko"); throw std::runtime_error("public not available from hanko");
break;
case VER_NODE_PUBLIC: case VER_NODE_PUBLIC:
return ToString(); return ToString();
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return 0;
} }
bool NewcoinAddress::setNodePublic(const std::string& strPublic) bool NewcoinAddress::setNodePublic(const std::string& strPublic)
@@ -140,37 +127,30 @@ void NewcoinAddress::setNodePublic(const std::vector<unsigned char>& vPublic)
uint256 NewcoinAddress::getNodePrivate() const uint256 NewcoinAddress::getNodePrivate() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_NODE_PRIVATE: case VER_NODE_PRIVATE:
// Nothing return uint256(vchData);
break;
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return uint256(vchData);
} }
std::string NewcoinAddress::humanNodePrivate() const std::string NewcoinAddress::humanNodePrivate() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_NODE_PRIVATE: case VER_NODE_PRIVATE:
return ToString(); return ToString();
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return 0;
} }
bool NewcoinAddress::setNodePrivate(const std::string& strPrivate) bool NewcoinAddress::setNodePrivate(const std::string& strPrivate)
@@ -189,10 +169,9 @@ void NewcoinAddress::setNodePrivate(uint256 hash256)
uint160 NewcoinAddress::getAccountID() const uint160 NewcoinAddress::getAccountID() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_ACCOUNT_ID: case VER_ACCOUNT_ID:
return uint160(vchData); return uint160(vchData);
@@ -202,18 +181,15 @@ uint160 NewcoinAddress::getAccountID() const
return Hash160(vchData); return Hash160(vchData);
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return 0;
} }
std::string NewcoinAddress::humanAccountID() const std::string NewcoinAddress::humanAccountID() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_ACCOUNT_ID: case VER_ACCOUNT_ID:
return ToString(); return ToString();
@@ -222,16 +198,14 @@ std::string NewcoinAddress::humanAccountID() const
{ {
NewcoinAddress accountID; NewcoinAddress accountID;
(void) accountID.setHanko(getAccountID()); (void) accountID.setAccountID(getAccountID());
return accountID.ToString(); return accountID.ToString();
} }
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return 0;
} }
bool NewcoinAddress::setAccountID(const std::string& strAccountID) bool NewcoinAddress::setAccountID(const std::string& strAccountID)
@@ -250,45 +224,37 @@ void NewcoinAddress::setAccountID(const uint160& hash160)
const std::vector<unsigned char>& NewcoinAddress::getAccountPublic() const const std::vector<unsigned char>& NewcoinAddress::getAccountPublic() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_ACCOUNT_ID: case VER_ACCOUNT_ID:
std::runtime_error("public not available from account id"); throw std::runtime_error("public not available from account id");
break; break;
case VER_ACCOUNT_PUBLIC: case VER_ACCOUNT_PUBLIC:
// Do nothing. return vchData;
break;
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return vchData;
} }
std::string NewcoinAddress::humanAccountPublic() const std::string NewcoinAddress::humanAccountPublic() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_ACCOUNT_ID: case VER_ACCOUNT_ID:
std::runtime_error("public not available from account id"); throw std::runtime_error("public not available from account id");
break;
case VER_ACCOUNT_PUBLIC: case VER_ACCOUNT_PUBLIC:
return ToString(); return ToString();
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return 0;
} }
bool NewcoinAddress::setAccountPublic(const std::string& strPublic) bool NewcoinAddress::setAccountPublic(const std::string& strPublic)
@@ -314,37 +280,30 @@ void NewcoinAddress::setAccountPublic(const NewcoinAddress& generator, int seq)
uint256 NewcoinAddress::getAccountPrivate() const uint256 NewcoinAddress::getAccountPrivate() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_ACCOUNT_PRIVATE: case VER_ACCOUNT_PRIVATE:
// Do nothing. return uint256(vchData);
break;
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return uint256(vchData);
} }
std::string NewcoinAddress::humanAccountPrivate() const std::string NewcoinAddress::humanAccountPrivate() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_ACCOUNT_PRIVATE: case VER_ACCOUNT_PRIVATE:
return ToString(); return ToString();
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return 0;
} }
bool NewcoinAddress::setAccountPrivate(const std::string& strPrivate) bool NewcoinAddress::setAccountPrivate(const std::string& strPrivate)
@@ -363,63 +322,53 @@ void NewcoinAddress::setAccountPrivate(uint256 hash256)
BIGNUM* NewcoinAddress::getFamilyGeneratorBN() const BIGNUM* NewcoinAddress::getFamilyGeneratorBN() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_FAMILY_GENERATOR: case VER_FAMILY_GENERATOR:
// Do nothing. // Do nothing.
break; break;
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
// Convert to big-endian BIGNUM* ret = BN_bin2bn(&vchData[0], vchData.size(), NULL);
unsigned char be[vchData.size()]; assert(ret);
std::reverse_copy(vchData.begin(), vchData.end(), &be[0]); return ret;
return BN_bin2bn(be, vchData.size(), NULL);
} }
const std::vector<unsigned char>& NewcoinAddress::getFamilyGenerator() const const std::vector<unsigned char>& NewcoinAddress::getFamilyGenerator() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_FAMILY_GENERATOR: case VER_FAMILY_GENERATOR:
// Do nothing. // Do nothing.
break; return vchData;
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return vchData;
} }
std::string NewcoinAddress::humanFamilyGenerator() const std::string NewcoinAddress::humanFamilyGenerator() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_FAMILY_GENERATOR: case VER_FAMILY_GENERATOR:
return ToString(); return ToString();
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return 0;
} }
// YYY Would be nice if you could pass a family seed and derive the generator.
bool NewcoinAddress::setFamilyGenerator(const std::string& strGenerator) bool NewcoinAddress::setFamilyGenerator(const std::string& strGenerator)
{ {
return SetString(strGenerator.c_str(), VER_FAMILY_GENERATOR); return SetString(strGenerator.c_str(), VER_FAMILY_GENERATOR);
@@ -439,42 +388,31 @@ void NewcoinAddress::setFamilyGenerator(const NewcoinAddress& seed)
// Family Seed // Family Seed
// //
// --> dstGenerator: Set the public generator from our seed.
void NewcoinAddress::seedInfo(NewcoinAddress* dstGenerator, BIGNUM** dstPrivateKey) const void NewcoinAddress::seedInfo(NewcoinAddress* dstGenerator, BIGNUM** dstPrivateKey) const
{ {
// Generate root key CKey pubkey = CKey(getFamilySeed());
EC_KEY *base=CKey::GenerateRootDeterministicKey(getFamilySeed());
// Extract family name if (dstGenerator) {
std::vector<unsigned char> rootPubKey(33, 0); dstGenerator->setFamilyGenerator(pubkey.GetPubKey());
unsigned char *begin=&rootPubKey[0]; }
i2o_ECPublicKey(base, &begin);
while(rootPubKey.size()<33) rootPubKey.push_back((unsigned char)0);
if (dstGenerator)
dstGenerator->setFamilyGenerator(rootPubKey);
if (dstPrivateKey) if (dstPrivateKey)
*dstPrivateKey = BN_dup(EC_KEY_get0_private_key(base)); *dstPrivateKey = pubkey.GetSecretBN();
EC_KEY_free(base);
} }
uint128 NewcoinAddress::getFamilySeed() const uint128 NewcoinAddress::getFamilySeed() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_FAMILY_SEED: case VER_FAMILY_SEED:
// Do nothing. return uint128(vchData);
break;
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return uint128(vchData);
} }
BIGNUM* NewcoinAddress::getFamilyPrivateKey() const BIGNUM* NewcoinAddress::getFamilyPrivateKey() const
@@ -488,19 +426,16 @@ BIGNUM* NewcoinAddress::getFamilyPrivateKey() const
std::string NewcoinAddress::humanFamilySeed() const std::string NewcoinAddress::humanFamilySeed() const
{ {
switch (version) { switch (nVersion) {
case VER_NONE: case VER_NONE:
std::runtime_error("unset source"); throw std::runtime_error("unset source");
break;
case VER_FAMILY_SEED: case VER_FAMILY_SEED:
return ToString(); return ToString();
default: default:
std::runtime_error("bad source"); throw std::runtime_error("bad source");
} }
return 0;
} }
bool NewcoinAddress::setFamilySeed(const std::string& strSeed) bool NewcoinAddress::setFamilySeed(const std::string& strSeed)

View File

@@ -12,18 +12,16 @@ class NewcoinAddress : public CBase58Data
private: private:
typedef enum { typedef enum {
VER_NONE = 1, VER_NONE = 1,
VER_HANKO = 13, VER_HANKO = 8,
VER_NODE_PUBLIC = 18, VER_NODE_PUBLIC = 28,
VER_NODE_PRIVATE = 23, VER_NODE_PRIVATE = 32,
VER_ACCOUNT_ID = 0, VER_ACCOUNT_ID = 0,
VER_ACCOUNT_PUBLIC = 3, VER_ACCOUNT_PUBLIC = 35,
VER_ACCOUNT_PRIVATE = 8, VER_ACCOUNT_PRIVATE = 34,
VER_FAMILY_GENERATOR = 28, VER_FAMILY_GENERATOR = 41,
VER_FAMILY_SEED = 33, VER_FAMILY_SEED = 33,
} VersionEncoding; } VersionEncoding;
VersionEncoding version;
void seedInfo(NewcoinAddress* dstGenerator, BIGNUM** dstPrivateKey) const; void seedInfo(NewcoinAddress* dstGenerator, BIGNUM** dstPrivateKey) const;
public: public:
@@ -32,43 +30,63 @@ public:
bool IsValid(); bool IsValid();
// //
// Nodes // hanko
// //
uint160 getHanko() const; uint160 getHanko() const;
const std::vector<unsigned char>& getNodePublic() const;
uint256 getNodePrivate() const;
std::string humanHanko() const; std::string humanHanko() const;
std::string humanNodePublic() const;
std::string humanNodePrivate() const;
bool setHanko(const std::string& strHanko); bool setHanko(const std::string& strHanko);
void setHanko(const uint160& hash160); void setHanko(const uint160& hash160);
//
// Node Public
//
const std::vector<unsigned char>& getNodePublic() const;
std::string humanNodePublic() const;
bool setNodePublic(const std::string& strPublic); bool setNodePublic(const std::string& strPublic);
void setNodePublic(const std::vector<unsigned char>& vPublic); void setNodePublic(const std::vector<unsigned char>& vPublic);
//
// Node Private
//
uint256 getNodePrivate() const;
std::string humanNodePrivate() const;
bool setNodePrivate(const std::string& strPrivate); bool setNodePrivate(const std::string& strPrivate);
void setNodePrivate(uint256 hash256); void setNodePrivate(uint256 hash256);
// //
// Accounts // Accounts IDs
// //
uint160 getAccountID() const; uint160 getAccountID() const;
const std::vector<unsigned char>& getAccountPublic() const;
uint256 getAccountPrivate() const;
std::string humanAccountID() const; std::string humanAccountID() const;
std::string humanAccountPublic() const;
std::string humanAccountPrivate() const;
bool setAccountID(const std::string& strAccountID); bool setAccountID(const std::string& strAccountID);
void setAccountID(const uint160& hash160In); void setAccountID(const uint160& hash160In);
//
// Accounts Public
//
const std::vector<unsigned char>& getAccountPublic() const;
std::string humanAccountPublic() const;
bool setAccountPublic(const std::string& strPublic); bool setAccountPublic(const std::string& strPublic);
void setAccountPublic(const std::vector<unsigned char>& vPublic); void setAccountPublic(const std::vector<unsigned char>& vPublic);
void setAccountPublic(const NewcoinAddress& generator, int seq); void setAccountPublic(const NewcoinAddress& generator, int seq);
//
// Accounts Private
//
uint256 getAccountPrivate() const;
std::string humanAccountPrivate() const;
bool setAccountPrivate(const std::string& strPrivate); bool setAccountPrivate(const std::string& strPrivate);
void setAccountPrivate(uint256 hash256); void setAccountPrivate(uint256 hash256);
@@ -89,7 +107,9 @@ public:
// //
uint128 getFamilySeed() const; uint128 getFamilySeed() const;
BIGNUM* getFamilyPrivateKey() const; BIGNUM* getFamilyPrivateKey() const;
std::string humanFamilySeed() const; std::string humanFamilySeed() const;
bool setFamilySeed(const std::string& strSeed); bool setFamilySeed(const std::string& strSeed);
void setFamilySeed(uint128 hash128); void setFamilySeed(uint128 hash128);
}; };

View File

@@ -361,20 +361,20 @@ void Wallet::load()
if(!db->startIterRows()) return; if(!db->startIterRows()) return;
while(db->getNextRow()) while(db->getNextRow())
{ {
std::string familyGenerator, comment; std::string generator, comment;
db->getStr("FamilyGenerator", familyGenerator); db->getStr("FamilyGenerator", generator);
db->getStr("Comment", comment); db->getStr("Comment", comment);
int seq=db->getBigInt("Seq"); int seq=db->getBigInt("Seq");
NewcoinAddress family; NewcoinAddress familyGenerator;
family.setFamilyGenerator(familyGenerator); familyGenerator.setFamilyGenerator(generator);
LocalAccountFamily::pointer f(doPublic(family, true, false)); LocalAccountFamily::pointer f(doPublic(familyGenerator, true, false));
if(f) if(f)
{ {
// XXX Compare could be better. // XXX Compare could be better.
assert(f->getFamily().getFamilyGenerator()==family.getFamilyGenerator()); assert(f->getFamily().getFamilyGenerator()==familyGenerator.getFamilyGenerator());
f->setSeq(seq); f->setSeq(seq);
f->setComment(comment); f->setComment(comment);
} }
@@ -515,57 +515,34 @@ void Wallet::delFamily(const NewcoinAddress& familyName)
// --> pubKey: hex // --> pubKey: hex
// --> do_create: Add to mFamilies // --> do_create: Add to mFamilies
// --> do_db: write out db // --> do_db: write out db
LocalAccountFamily::pointer Wallet::doPublic(const NewcoinAddress& pubKey, bool do_create, bool do_db) LocalAccountFamily::pointer Wallet::doPublic(const NewcoinAddress& familyGenerator, bool do_create, bool do_db)
{ {
// Generate root key
EC_KEY *pkey=CKey::GenerateRootPubKey(pubKey.getFamilyGeneratorBN());
if(!pkey)
{
#ifdef DEBUG
std::cerr << "Unable to generate root public key" << std::endl;
assert(false);
#endif
return LocalAccountFamily::pointer();
}
// Extract family name
std::vector<unsigned char> rootPubKey(33, 0);
unsigned char *begin=&rootPubKey[0];
i2o_ECPublicKey(pkey, &begin);
while(rootPubKey.size()<33) rootPubKey.push_back((unsigned char)0);
NewcoinAddress family;
family.setFamilyGenerator(rootPubKey);
boost::recursive_mutex::scoped_lock sl(mLock); boost::recursive_mutex::scoped_lock sl(mLock);
std::map<NewcoinAddress, LocalAccountFamily::pointer>::iterator fit=mFamilies.find(family); std::map<NewcoinAddress, LocalAccountFamily::pointer>::iterator fit=mFamilies.find(familyGenerator);
if(fit!=mFamilies.end()) // already added if(fit!=mFamilies.end()) // already added
{ {
EC_KEY_free(pkey);
return fit->second; return fit->second;
} }
if(!do_create) if(!do_create)
{ {
EC_KEY_free(pkey);
return LocalAccountFamily::pointer(); return LocalAccountFamily::pointer();
} }
LocalAccountFamily::pointer fam; LocalAccountFamily::pointer fam;
if(do_db) if(do_db)
{ {
fam=LocalAccountFamily::readFamily(family); fam=LocalAccountFamily::readFamily(familyGenerator);
if(fam) do_create=false; if(fam) do_create=false;
} }
if(do_create) if(do_create)
{ {
fam=boost::make_shared<LocalAccountFamily>(family); fam=boost::make_shared<LocalAccountFamily>(familyGenerator);
mFamilies.insert(std::make_pair(family, fam)); mFamilies.insert(std::make_pair(familyGenerator, fam));
if(do_db) fam->write(true); if(do_db) fam->write(true);
} }
sl.unlock(); sl.unlock();
EC_KEY_free(pkey);
return fam; return fam;
} }

View File

@@ -31,7 +31,7 @@ protected:
uint32 mLedger; // ledger we last synched to uint32 mLedger; // ledger we last synched to
LocalAccountFamily::pointer doPrivate(const NewcoinAddress& familySeed, bool do_create, bool do_unlock); LocalAccountFamily::pointer doPrivate(const NewcoinAddress& familySeed, bool do_create, bool do_unlock);
LocalAccountFamily::pointer doPublic(const NewcoinAddress& pubKey, bool do_create, bool do_db); LocalAccountFamily::pointer doPublic(const NewcoinAddress& familyGenerator, bool do_create, bool do_db);
// void addFamily(const NewcoinAddress& family, const std::string& pubKey, int seq, const std::string& name, const std::string& comment); // void addFamily(const NewcoinAddress& family, const std::string& pubKey, int seq, const std::string& name, const std::string& comment);

View File

@@ -18,12 +18,11 @@
#include <string> #include <string>
#include <algorithm> #include <algorithm>
#include <vector> #include <vector>
#include "bignum.h" #include "bignum.h"
#include "BitcoinUtil.h" #include "BitcoinUtil.h"
// Bitcoin's encoding: "123456789ABCDEFGHJKLMNPQRSTUVWXYZabcdefghijkmnopqrstuvwxyz"; static const char* pszBase58 = "ipshnaf39wBUDNEGHJKLM4PQRST7VWXYZ2bcdeCg65jkm8oFqr1tuvAxyz";
static const char* pszBase58 = "sa3A5h7n9NBfDFEGHJKLM4PQRSTUVWXYZ2bcdeCg6ijkm8opqr1tuvwxyz";
inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend) inline std::string EncodeBase58(const unsigned char* pbegin, const unsigned char* pend)
{ {
@@ -158,10 +157,6 @@ inline bool DecodeBase58Check(const std::string& str, std::vector<unsigned char>
} }
class CBase58Data class CBase58Data
{ {
protected: protected:
@@ -226,7 +221,9 @@ public:
std::string ToString() const std::string ToString() const
{ {
std::vector<unsigned char> vch(1, nVersion); std::vector<unsigned char> vch(1, nVersion);
vch.insert(vch.end(), vchData.begin(), vchData.end()); vch.insert(vch.end(), vchData.begin(), vchData.end());
return EncodeBase58Check(vch); return EncodeBase58Check(vch);
} }
@@ -246,6 +243,4 @@ public:
bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; } bool operator> (const CBase58Data& b58) const { return CompareTo(b58) > 0; }
}; };
#endif #endif

View File

@@ -126,7 +126,7 @@ public:
static uint128 PassPhraseToKey(const std::string& passPhrase); static uint128 PassPhraseToKey(const std::string& passPhrase);
static EC_KEY* GenerateRootDeterministicKey(const uint128& passPhrase); static EC_KEY* GenerateRootDeterministicKey(const uint128& passPhrase);
static EC_KEY* GenerateRootPubKey(BIGNUM* pubGenerator); static EC_KEY* GenerateRootPubKey(BIGNUM* pubGenerator);
static EC_KEY* GeneratePublicDeterministicKey(const NewcoinAddress& family, int n); static EC_KEY* GeneratePublicDeterministicKey(const NewcoinAddress& generator, int n);
static EC_KEY* GeneratePrivateDeterministicKey(const NewcoinAddress& family, const BIGNUM* rootPriv, int n); static EC_KEY* GeneratePrivateDeterministicKey(const NewcoinAddress& family, const BIGNUM* rootPriv, int n);
CKey(const uint128& passPhrase) : fSet(true) CKey(const uint128& passPhrase) : fSet(true)
@@ -135,9 +135,9 @@ public:
assert(pkey); assert(pkey);
} }
CKey(const NewcoinAddress& base, int n) : fSet(true) CKey(const NewcoinAddress& generator, int n) : fSet(true)
{ // public deterministic key { // public deterministic key
pkey = GeneratePublicDeterministicKey(base, n); pkey = GeneratePublicDeterministicKey(generator, n);
assert(pkey); assert(pkey);
} }
@@ -202,6 +202,11 @@ public:
return vchRet; return vchRet;
} }
BIGNUM* GetSecretBN() const
{
return BN_dup(EC_KEY_get0_private_key(pkey));
}
CPrivKey GetPrivKey() const CPrivKey GetPrivKey() const
{ {
unsigned int nSize = i2d_ECPrivateKey(pkey, NULL); unsigned int nSize = i2d_ECPrivateKey(pkey, NULL);

View File

@@ -5,7 +5,7 @@
#ifndef NEWCOIN_UINT256_H #ifndef NEWCOIN_UINT256_H
#define NEWCOIN_UINT256_H #define NEWCOIN_UINT256_H
#include <algorithm>
#include <climits> #include <climits>
#include <string> #include <string>
#include <vector> #include <vector>
@@ -39,11 +39,8 @@ public:
{ {
// Convert to big-endian // Convert to big-endian
unsigned char *be[WIDTH]; unsigned char *be[WIDTH];
unsigned char *bep;
unsigned int *pnp = &pn[WIDTH];
for (int i=WIDTH; i--;) std::reverse_copy(begin(), end(), be);
*bep++ = *--pnp;
return BN_bin2bn(be, WIDTH, NULL); return BN_bin2bn(be, WIDTH, NULL);
} }