diff --git a/src/Application.cpp b/src/Application.cpp index 3218490bc4..4057e86f77 100644 --- a/src/Application.cpp +++ b/src/Application.cpp @@ -103,11 +103,11 @@ void Application::run() // New stuff. NewcoinAddress rootSeedMaster; - NewcoinAddress rootGeneratorMaster; NewcoinAddress rootAddress; rootSeedMaster.setFamilySeed(CKey::PassPhraseToKey("masterpassphrase")); - rootGeneratorMaster.setFamilyGenerator(rootSeedMaster); + + NewcoinAddress rootGeneratorMaster = NewcoinAddress::createGeneratorPublic(rootSeedMaster); rootAddress.setAccountPublic(rootGeneratorMaster, 0); diff --git a/src/NewcoinAddress.cpp b/src/NewcoinAddress.cpp index f3b92ff3bf..f31036963e 100644 --- a/src/NewcoinAddress.cpp +++ b/src/NewcoinAddress.cpp @@ -36,7 +36,7 @@ bool NewcoinAddress::isValid() const break; case VER_ACCOUNT_PRIVATE: - bValid = key.SetPrivKey(getAccountPrivate()); + bValid = key.SetPrivateKeyU(getAccountPrivate()); break; default: @@ -58,6 +58,17 @@ void NewcoinAddress::clear() // NodePublic // +NewcoinAddress NewcoinAddress::createNodePublic(NewcoinAddress& naSeed) +{ + CKey ckSeed(naSeed.getFamilySeed()); + NewcoinAddress naNew; + + // YYY Should there be a GetPubKey() equiv that returns a uint256? + naNew.setNodePublic(ckSeed.GetPubKey()); + + return naNew; +} + const std::vector& NewcoinAddress::getNodePublic() const { switch (nVersion) { @@ -125,6 +136,19 @@ bool NewcoinAddress::verifyNodePublic(const uint256& hash, const std::string& st // NodePrivate // +NewcoinAddress NewcoinAddress::createNodePrivate(NewcoinAddress& naSeed) +{ + uint256 uPrivKey; + NewcoinAddress naNew; + CKey ckSeed(naSeed.getFamilySeed()); + + ckSeed.GetPrivateKeyU(uPrivKey); + + naNew.setNodePrivate(uPrivKey); + + return naNew; +} + const std::vector& NewcoinAddress::getNodePrivateData() const { switch (nVersion) { @@ -183,12 +207,11 @@ void NewcoinAddress::setNodePrivate(uint256 hash256) void NewcoinAddress::signNodePrivate(const uint256& hash, std::vector& vchSig) const { - CKey privkey = CKey(); + CKey ckPrivKey; - if (!privkey.SetSecret(getNodePrivateData())) - throw std::runtime_error("SetSecret failed."); + ckPrivKey.SetPrivateKeyU(getNodePrivate()); - if (!privkey.Sign(hash, vchSig)) + if (!ckPrivKey.Sign(hash, vchSig)) throw std::runtime_error("Signing failed."); } @@ -251,6 +274,16 @@ void NewcoinAddress::setAccountID(const uint160& hash160) // AccountPublic // +NewcoinAddress NewcoinAddress::createAccountPublic(const NewcoinAddress& naGenerator, int iSeq) +{ + CKey ckPub(naGenerator, iSeq); + NewcoinAddress naNew; + + naNew.setAccountPublic(ckPub.GetPubKey()); + + return naNew; +} + const std::vector& NewcoinAddress::getAccountPublic() const { switch (nVersion) { @@ -335,14 +368,23 @@ NewcoinAddress NewcoinAddress::createAccountID(const uint160& uiAccountID) // AccountPrivate // -const std::vector& NewcoinAddress::getAccountPrivate() const +NewcoinAddress NewcoinAddress::createAccountPrivate(const NewcoinAddress& naGenerator, const NewcoinAddress& naSeed, int iSeq) +{ + NewcoinAddress naNew; + + naNew.setAccountPrivate(naGenerator, naSeed, iSeq); + + return naNew; +} + +uint256 NewcoinAddress::getAccountPrivate() const { switch (nVersion) { case VER_NONE: throw std::runtime_error("unset source"); case VER_ACCOUNT_PRIVATE: - return vchData; + return uint256(vchData); default: throw std::runtime_error(str(boost::format("bad source: %d") % int(nVersion))); @@ -378,11 +420,15 @@ void NewcoinAddress::setAccountPrivate(uint256 hash256) SetData(VER_ACCOUNT_PRIVATE, hash256.begin(), 32); } -void NewcoinAddress::setAccountPrivate(const NewcoinAddress& generator, const NewcoinAddress& seed, int seq) +void NewcoinAddress::setAccountPrivate(const NewcoinAddress& naGenerator, const NewcoinAddress& naSeed, int seq) { - CKey privkey = CKey(generator, seed.getFamilyPrivateKey(), seq); + CKey pubkey = CKey(naSeed.getFamilySeed()); + CKey ckPrivkey = CKey(naGenerator, pubkey.GetSecretBN(), seq); + uint256 uPrivKey; - setAccountPrivate(privkey.GetPrivKey()); + ckPrivkey.GetPrivateKeyU(uPrivKey); + + setAccountPrivate(uPrivKey); } bool NewcoinAddress::accountPrivateSign(const uint256& uHash, std::vector& vucSig) const @@ -390,7 +436,7 @@ bool NewcoinAddress::accountPrivateSign(const uint256& uHash, std::vector& vucSig) const { CKey ckPrivate; bool bVerified; - if (!ckPrivate.SetPrivKey(getAccountPrivate())) + if (!ckPrivate.SetPrivateKeyU(getAccountPrivate())) { // Bad private key. std::cerr << "accountPrivateVerify: Bad private key." << std::endl; @@ -424,6 +471,7 @@ bool NewcoinAddress::accountPrivateVerify(const uint256& uHash, const std::vecto return bVerified; } +#endif std::vector NewcoinAddress::accountPrivateEncrypt(const NewcoinAddress& naPublicTo, const std::vector& vucPlainText) const { @@ -436,7 +484,7 @@ std::vector NewcoinAddress::accountPrivateEncrypt(const NewcoinAd // Bad public key. std::cerr << "accountPrivateEncrypt: Bad public key." << std::endl; } - else if (!ckPrivate.SetPrivKey(getAccountPrivate())) + else if (!ckPrivate.SetPrivateKeyU(getAccountPrivate())) { // Bad private key. std::cerr << "accountPrivateEncrypt: Bad private key." << std::endl; @@ -466,7 +514,7 @@ std::vector NewcoinAddress::accountPrivateDecrypt(const NewcoinAd // Bad public key. std::cerr << "accountPrivateDecrypt: Bad public key." << std::endl; } - else if (!ckPrivate.SetPrivKey(getAccountPrivate())) + else if (!ckPrivate.SetPrivateKeyU(getAccountPrivate())) { // Bad private key. std::cerr << "accountPrivateDecrypt: Bad private key." << std::endl; @@ -547,15 +595,28 @@ void NewcoinAddress::setFamilyGenerator(const std::vector& vPubli SetData(VER_FAMILY_GENERATOR, vPublic); } +#if 0 void NewcoinAddress::setFamilyGenerator(const NewcoinAddress& seed) { seed.seedInfo(this, 0); } +#endif + +NewcoinAddress NewcoinAddress::createGeneratorPublic(const NewcoinAddress& naSeed) +{ + CKey ckSeed(naSeed.getFamilySeed()); + NewcoinAddress naNew; + + naNew.setFamilyGenerator(ckSeed.GetPubKey()); + + return naNew; +} // // Family Seed // +#if 0 // --> dstGenerator: Set the public generator from our seed. void NewcoinAddress::seedInfo(NewcoinAddress* dstGenerator, BIGNUM** dstPrivateKey) const { @@ -568,6 +629,7 @@ void NewcoinAddress::seedInfo(NewcoinAddress* dstGenerator, BIGNUM** dstPrivateK if (dstPrivateKey) *dstPrivateKey = pubkey.GetSecretBN(); } +#endif uint128 NewcoinAddress::getFamilySeed() const { @@ -583,6 +645,7 @@ uint128 NewcoinAddress::getFamilySeed() const } } +#if 0 BIGNUM* NewcoinAddress::getFamilyPrivateKey() const { BIGNUM* ret; @@ -591,6 +654,7 @@ BIGNUM* NewcoinAddress::getFamilyPrivateKey() const return ret; } +#endif std::string NewcoinAddress::humanFamilySeed1751() const { @@ -691,6 +755,7 @@ void NewcoinAddress::setFamilySeed(uint128 hash128) { void NewcoinAddress::setFamilySeedRandom() { + // XXX Maybe we should call MakeNewKey uint128 key; RAND_bytes((unsigned char *) &key, sizeof(key)); @@ -698,11 +763,77 @@ void NewcoinAddress::setFamilySeedRandom() NewcoinAddress::setFamilySeed(key); } +NewcoinAddress NewcoinAddress::createSeedRandom() +{ + NewcoinAddress naNew; + + naNew.setFamilySeedRandom(); + + return naNew; +} + BOOST_AUTO_TEST_SUITE(newcoin_address) BOOST_AUTO_TEST_CASE( my_test ) { - // BOOST_CHECK( false ); + // Construct a seed. + NewcoinAddress naSeed; + + BOOST_CHECK(naSeed.setFamilySeedGeneric("masterpassphrase")); + BOOST_CHECK_MESSAGE(naSeed.humanFamilySeed() == "snoPBiXtMeMyMHUVTgbuqAfg1SUTb", naSeed.humanFamilySeed()); + + // Create node public/private key pair + NewcoinAddress naNodePublic = NewcoinAddress::createNodePublic(naSeed); + NewcoinAddress naNodePrivate = NewcoinAddress::createNodePrivate(naSeed); + + BOOST_CHECK_MESSAGE(naNodePublic.humanNodePublic() == "n94a1u4jAz288pZLtw6yFWVbr89YamrC6JBXPVUj5zmExe5fTVg9", naNodePublic.humanNodePublic()); + BOOST_CHECK_MESSAGE(naNodePrivate.humanNodePrivate() == "pnen77YEeUd4fFKG7rycBWcwKpTaeFRkW2WFostaATy1DSupwXe", naNodePrivate.humanNodePrivate()); + + // Check node signing. + std::vector vucTextSrc = strCopy("Hello, nurse!"); + uint256 uHash = Serializer::getSHA512Half(vucTextSrc); + std::vector vucTextSig; + + naNodePrivate.signNodePrivate(uHash, vucTextSig); + BOOST_CHECK_MESSAGE(naNodePublic.verifyNodePublic(uHash, vucTextSig), "Verify failed."); + + // Construct a public generator from the seed. + NewcoinAddress naGenerator = NewcoinAddress::createGeneratorPublic(naSeed); + + BOOST_CHECK_MESSAGE(naGenerator.humanFamilyGenerator() == "fhuJKihSDzV2SkjLn9qbwm5AaRmixDPfFsHDCP6yfDZWcxDFz4mt", naGenerator.humanFamilyGenerator()); + + // Create account #0 public/private key pair. + NewcoinAddress naAccountPublic0 = NewcoinAddress::createAccountPublic(naGenerator, 0); + NewcoinAddress naAccountPrivate0 = NewcoinAddress::createAccountPrivate(naGenerator, naSeed, 0); + + BOOST_CHECK_MESSAGE(naAccountPublic0.humanAccountID() == "iHb9CJAWyB4ij91VRWn96DkukG4bwdtyTh", naAccountPublic0.humanAccountID()); + BOOST_CHECK_MESSAGE(naAccountPublic0.humanAccountPublic() == "aBQG8RQAzjs1eTKFEAQXi2gS4utcDrEC9wmr7pfUPTr27VCahwgw", naAccountPublic0.humanAccountPublic()); + BOOST_CHECK_MESSAGE(naAccountPrivate0.humanAccountPrivate() == "p9JfM6HHr64m6mvB6v5k7G2b1cXzGmYrCNJf6GHPKvFTWdeRVjh", naAccountPrivate0.humanAccountPrivate()); + + // Create account #1 public/private key pair. + NewcoinAddress naAccountPublic1 = NewcoinAddress::createAccountPublic(naGenerator, 1); + NewcoinAddress naAccountPrivate1 = NewcoinAddress::createAccountPrivate(naGenerator, naSeed, 1); + + BOOST_CHECK_MESSAGE(naAccountPublic1.humanAccountID() == "i4bYF7SLUMD7QgSLLpgJx38WJSY12VrRjP", naAccountPublic1.humanAccountID()); + BOOST_CHECK_MESSAGE(naAccountPublic1.humanAccountPublic() == "aBPXpTfuLy1Bhk3HnGTTAqnovpKWQ23NpFMNkAF6F1Atg5vDyPiw", naAccountPublic1.humanAccountPublic()); + BOOST_CHECK_MESSAGE(naAccountPrivate1.humanAccountPrivate() == "p9JEm822LMizJrr1k7TvdphfENTp6G5ji253Xa5ikzUWVi8ogQt", naAccountPrivate1.humanAccountPrivate()); + + // Check account signing. + BOOST_CHECK_MESSAGE(naAccountPrivate0.accountPrivateSign(uHash, vucTextSig), "Signing failed."); + BOOST_CHECK_MESSAGE(naAccountPublic0.accountPublicVerify(uHash, vucTextSig), "Verify failed."); + BOOST_CHECK_MESSAGE(!naAccountPublic1.accountPublicVerify(uHash, vucTextSig), "Anti-verify failed."); + + BOOST_CHECK_MESSAGE(naAccountPrivate1.accountPrivateSign(uHash, vucTextSig), "Signing failed."); + BOOST_CHECK_MESSAGE(naAccountPublic1.accountPublicVerify(uHash, vucTextSig), "Verify failed."); + BOOST_CHECK_MESSAGE(!naAccountPublic0.accountPublicVerify(uHash, vucTextSig), "Anti-verify failed."); + + // Check account encryption. + std::vector vucTextCipher + = naAccountPrivate0.accountPrivateEncrypt(naAccountPublic1, vucTextSrc); + std::vector vucTextRecovered + = naAccountPrivate1.accountPrivateDecrypt(naAccountPublic0, vucTextCipher); + + BOOST_CHECK_MESSAGE(vucTextSrc == vucTextRecovered, "Encrypt-decrypt failed."); } BOOST_AUTO_TEST_SUITE_END() diff --git a/src/NewcoinAddress.h b/src/NewcoinAddress.h index 3418669152..284e35c680 100644 --- a/src/NewcoinAddress.h +++ b/src/NewcoinAddress.h @@ -21,7 +21,7 @@ private: VER_FAMILY_SEED = 33, } VersionEncoding; - void seedInfo(NewcoinAddress* dstGenerator, BIGNUM** dstPrivateKey) const; +// void seedInfo(NewcoinAddress* dstGenerator, BIGNUM** dstPrivateKey) const; public: NewcoinAddress(); @@ -42,6 +42,8 @@ public: bool verifyNodePublic(const uint256& hash, const std::vector& vchSig) const; bool verifyNodePublic(const uint256& hash, const std::string& strSig) const; + static NewcoinAddress createNodePublic(NewcoinAddress& naSeed); + // // Node Private // @@ -55,6 +57,8 @@ public: void setNodePrivate(uint256 hash256); void signNodePrivate(const uint256& hash, std::vector& vchSig) const; + static NewcoinAddress createNodePrivate(NewcoinAddress& naSeed); + // // Accounts IDs // @@ -67,9 +71,8 @@ public: static NewcoinAddress createAccountID(const uint160& uiAccountID); - static std::string createHumanAccountID(const std::vector& vPrivate) { - return createAccountPrivate(vPrivate).humanAccountID(); - } + static std::string createHumanAccountID(const std::vector& vPrivate) + { return createAccountPrivate(vPrivate).humanAccountID(); } // // Accounts Public @@ -85,32 +88,35 @@ public: bool accountPublicVerify(const uint256& uHash, const std::vector& vucSig) const; static NewcoinAddress createAccountPublic(const std::vector& vPublic) - { - NewcoinAddress naNew; + { + NewcoinAddress naNew; - naNew.setAccountPublic(vPublic); + naNew.setAccountPublic(vPublic); - return naNew; - } + return naNew; + } static std::string createHumanAccountPublic(const std::vector& vPublic) { return createAccountPublic(vPublic).humanAccountPublic(); } + // Create a deterministic public key from a public generator. + static NewcoinAddress createAccountPublic(const NewcoinAddress& naGenerator, int iSeq); + // // Accounts Private // - const std::vector& getAccountPrivate() const; + uint256 getAccountPrivate() const; std::string humanAccountPrivate() const; bool setAccountPrivate(const std::string& strPrivate); void setAccountPrivate(const std::vector& vPrivate); void setAccountPrivate(uint256 hash256); - void setAccountPrivate(const NewcoinAddress& generator, const NewcoinAddress& seed, int seq); + void setAccountPrivate(const NewcoinAddress& naGenerator, const NewcoinAddress& naSeed, int seq); bool accountPrivateSign(const uint256& uHash, std::vector& vucSig) const; - bool accountPrivateVerify(const uint256& uHash, const std::vector& vucSig) const; + // bool accountPrivateVerify(const uint256& uHash, const std::vector& vucSig) const; // Encrypt a message. std::vector accountPrivateEncrypt(const NewcoinAddress& naPublicTo, const std::vector& vucPlainText) const; @@ -118,14 +124,16 @@ public: // Decrypt a message. std::vector accountPrivateDecrypt(const NewcoinAddress& naPublicFrom, const std::vector& vucCipherText) const; + static NewcoinAddress createAccountPrivate(const NewcoinAddress& naGenerator, const NewcoinAddress& naSeed, int iSeq); + static NewcoinAddress createAccountPrivate(const std::vector& vPrivate) - { - NewcoinAddress naNew; + { + NewcoinAddress naNew; - naNew.setAccountPrivate(vPrivate); + naNew.setAccountPrivate(vPrivate); - return naNew; - } + return naNew; + } static std::string createHumanAccountPrivate(const std::vector& vPrivate) { return createAccountPrivate(vPrivate).humanAccountPrivate(); @@ -142,13 +150,16 @@ public: bool setFamilyGenerator(const std::string& strGenerator); void setFamilyGenerator(const std::vector& vPublic); - void setFamilyGenerator(const NewcoinAddress& seed); + // void setFamilyGenerator(const NewcoinAddress& seed); + + // Create generator for making public deterministic keys. + static NewcoinAddress createGeneratorPublic(const NewcoinAddress& naSeed); // // Family Seeds // Clients must disallow reconizable entries from being seeds. uint128 getFamilySeed() const; - BIGNUM* getFamilyPrivateKey() const; + // BIGNUM* getFamilyPrivateKey() const; std::string humanFamilySeed() const; std::string humanFamilySeed1751() const; @@ -158,6 +169,8 @@ public: bool setFamilySeedGeneric(const std::string& strText); void setFamilySeed(uint128 hash128); void setFamilySeedRandom(); + + static NewcoinAddress createSeedRandom(); }; #endif diff --git a/src/RPCServer.cpp b/src/RPCServer.cpp index 6f56fe499e..1e06ce82e0 100644 --- a/src/RPCServer.cpp +++ b/src/RPCServer.cpp @@ -241,11 +241,10 @@ bool RPCServer::extractString(std::string& param, const Json::Value& params, int // <-- naMasterGenerator Json::Value RPCServer::getMasterGenerator(const uint256& uLedger, const NewcoinAddress& naRegularSeed, NewcoinAddress& naMasterGenerator) { - NewcoinAddress naGenerator; NewcoinAddress na0Public; // To find the generator's index. NewcoinAddress na0Private; // To decrypt the master generator's cipher. + NewcoinAddress naGenerator = NewcoinAddress::createGeneratorPublic(naRegularSeed); - naGenerator.setFamilyGenerator(naRegularSeed); na0Public.setAccountPublic(naGenerator, 0); na0Private.setAccountPrivate(naGenerator, naRegularSeed, 0); @@ -289,10 +288,9 @@ Json::Value RPCServer::authorize(const uint256& uLedger, { return RPCError(rpcSRC_MISSING); } - + NewcoinAddress naMasterGenerator; - if(asSrc->bHaveAuthorizedKey()) { Json::Value obj = getMasterGenerator(uLedger, naRegularSeed, naMasterGenerator); @@ -302,7 +300,7 @@ Json::Value RPCServer::authorize(const uint256& uLedger, }else { // Try the seed as a master seed. - naMasterGenerator.setFamilyGenerator(naRegularSeed); + naMasterGenerator = NewcoinAddress::createGeneratorPublic(naRegularSeed); } // If naVerifyGenerator is provided, make sure it is the master generator. @@ -324,9 +322,8 @@ Json::Value RPCServer::authorize(const uint256& uLedger, } while (naSrcAccountID.getAccountID() != naMasterAccountPublic.getAccountID()); // Use the regular generator to determine the associated public and private keys. - NewcoinAddress naGenerator; + NewcoinAddress naGenerator = NewcoinAddress::createGeneratorPublic(naRegularSeed); - naGenerator.setFamilyGenerator(naRegularSeed); naAccountPublic.setAccountPublic(naGenerator, iIndex); naAccountPrivate.setAccountPrivate(naGenerator, naRegularSeed, iIndex); @@ -374,11 +371,10 @@ Json::Value RPCServer::accountFromString(const uint256& uLedger, NewcoinAddress& { // We allow the use of the seeds to access #0. // This is poor practice and merely for debuging convenience. - NewcoinAddress naGenerator; NewcoinAddress naRegular0Public; NewcoinAddress naRegular0Private; - naGenerator.setFamilyGenerator(naSeed); + NewcoinAddress naGenerator = NewcoinAddress::createGeneratorPublic(naSeed); naRegular0Public.setAccountPublic(naGenerator, 0); naRegular0Private.setAccountPrivate(naGenerator, naSeed, 0); @@ -1054,20 +1050,17 @@ Json::Value RPCServer::doPasswordSet(Json::Value& params) } else { - NewcoinAddress naMasterGenerator; - NewcoinAddress naRegularGenerator; + NewcoinAddress naMasterGenerator = NewcoinAddress::createGeneratorPublic(naMasterSeed); + NewcoinAddress naRegularGenerator = NewcoinAddress::createGeneratorPublic(naRegularSeed); NewcoinAddress naRegular0Public; NewcoinAddress naRegular0Private; NewcoinAddress naAccountPublic; NewcoinAddress naAccountPrivate; - naMasterGenerator.setFamilyGenerator(naMasterSeed); naAccountPublic.setAccountPublic(naMasterGenerator, 0); naAccountPrivate.setAccountPrivate(naMasterGenerator, naMasterSeed, 0); - naRegularGenerator.setFamilyGenerator(naRegularSeed); - naRegular0Public.setAccountPublic(naRegularGenerator, 0); naRegular0Private.setAccountPrivate(naRegularGenerator, naRegularSeed, 0); @@ -1495,9 +1488,6 @@ Json::Value RPCServer::doUnlAdd(Json::Value& params) // shell history file (e.g. .bash_history) and it may be leaked via the process status command (i.e. ps). Json::Value RPCServer::doValidatorCreate(Json::Value& params) { NewcoinAddress familySeed; - NewcoinAddress familyGenerator; - NewcoinAddress nodePublicKey; - NewcoinAddress nodePrivateKey; if (params.empty()) { @@ -1511,11 +1501,9 @@ Json::Value RPCServer::doValidatorCreate(Json::Value& params) { } // Derive generator from seed. - familyGenerator.setFamilyGenerator(familySeed); - - // The node public and private is 0th of the sequence. - nodePublicKey.setNodePublic(CKey(familyGenerator, 0).GetPubKey()); - nodePrivateKey.setNodePrivate(CKey(familyGenerator, familySeed.getFamilyPrivateKey(), 0).GetSecret()); + NewcoinAddress familyGenerator = NewcoinAddress::createGeneratorPublic(familySeed); + NewcoinAddress nodePublicKey = NewcoinAddress::createNodePublic(familySeed); + NewcoinAddress nodePrivateKey = NewcoinAddress::createNodePrivate(familySeed); // Paranoia assert(1 == familySeed.setFamilySeed1751(familySeed.humanFamilySeed1751())); @@ -1571,10 +1559,8 @@ Json::Value RPCServer::doWalletAccounts(Json::Value& params) return RPCError(rpcBAD_SEED); } - NewcoinAddress naMasterGenerator; - // Try the seed as a master seed. - naMasterGenerator.setFamilyGenerator(naSeed); + NewcoinAddress naMasterGenerator = NewcoinAddress::createGeneratorPublic(naSeed); Json::Value jsonAccounts = accounts(uLedger, naMasterGenerator); @@ -1629,11 +1615,8 @@ Json::Value RPCServer::doWalletAdd(Json::Value& params) } else { - NewcoinAddress naMasterGenerator; - NewcoinAddress naRegularGenerator; - - naMasterGenerator.setFamilyGenerator(naMasterSeed); - naRegularGenerator.setFamilyGenerator(naRegularSeed); + NewcoinAddress naMasterGenerator = NewcoinAddress::createGeneratorPublic(naMasterSeed); + NewcoinAddress naRegularGenerator = NewcoinAddress::createGeneratorPublic(naRegularSeed); NewcoinAddress naAccountPublic; NewcoinAddress naAccountPrivate; @@ -1739,20 +1722,17 @@ Json::Value RPCServer::doWalletClaim(Json::Value& params) // XXX Annotation is ignored. std::string strAnnotation = (params.size() == 3) ? "" : params[3u].asString(); - NewcoinAddress naMasterGenerator; - NewcoinAddress naRegularGenerator; + NewcoinAddress naMasterGenerator = NewcoinAddress::createGeneratorPublic(naMasterSeed); + NewcoinAddress naRegularGenerator = NewcoinAddress::createGeneratorPublic(naRegularSeed); NewcoinAddress naRegular0Public; NewcoinAddress naRegular0Private; NewcoinAddress naAccountPublic; NewcoinAddress naAccountPrivate; - naMasterGenerator.setFamilyGenerator(naMasterSeed); naAccountPublic.setAccountPublic(naMasterGenerator, 0); naAccountPrivate.setAccountPrivate(naMasterGenerator, naMasterSeed, 0); - naRegularGenerator.setFamilyGenerator(naRegularSeed); - naRegular0Public.setAccountPublic(naRegularGenerator, 0); naRegular0Private.setAccountPrivate(naRegularGenerator, naRegularSeed, 0); @@ -1862,27 +1842,18 @@ Json::Value RPCServer::doWalletCreate(Json::Value& params) Json::Value RPCServer::doWalletPropose(Json::Value& params) { NewcoinAddress naSeed; - NewcoinAddress naGenerator; NewcoinAddress naAccount; naSeed.setFamilySeedRandom(); - naGenerator.setFamilyGenerator(naSeed); + + NewcoinAddress naGenerator = NewcoinAddress::createGeneratorPublic(naSeed); naAccount.setAccountPublic(naGenerator, 0); - // - // Extra functionality: generate a key pair - // - CKey key; - - key.MakeNewKey(); - Json::Value obj(Json::objectValue); obj["master_seed"] = naSeed.humanFamilySeed(); obj["master_key"] = naSeed.humanFamilySeed1751(); obj["account_id"] = naAccount.humanAccountID(); - obj["extra_public"] = NewcoinAddress::createHumanAccountPublic(key.GetPubKey()); - obj["extra_private"] = NewcoinAddress::createHumanAccountPrivate(key.GetSecret()); return obj; } @@ -1899,14 +1870,15 @@ Json::Value RPCServer::doWalletSeed(Json::Value& params) } else { - NewcoinAddress naGenerator; NewcoinAddress naAccount; if (!params.size()) { naSeed.setFamilySeedRandom(); } - naGenerator.setFamilyGenerator(naSeed); + + NewcoinAddress naGenerator = NewcoinAddress::createGeneratorPublic(naSeed); + naAccount.setAccountPublic(naGenerator, 0); Json::Value obj(Json::objectValue); diff --git a/src/Wallet.cpp b/src/Wallet.cpp index 29454a18ae..293c58ac62 100644 --- a/src/Wallet.cpp +++ b/src/Wallet.cpp @@ -75,15 +75,11 @@ bool Wallet::nodeIdentityCreate() { // // Generate the public and private key // - NewcoinAddress nodePublicKey; - NewcoinAddress nodePrivateKey; + NewcoinAddress naSeed = NewcoinAddress::createSeedRandom(); + NewcoinAddress naNodePublic = NewcoinAddress::createNodePublic(naSeed); + NewcoinAddress naNodePrivate = NewcoinAddress::createNodePrivate(naSeed); // Make new key. - CKey key; - - key.MakeNewKey(); - nodePublicKey.setNodePublic(key.GetPubKey()); - nodePrivateKey.setNodePrivate(key.GetSecret()); std::string strDh512, strDh1024; @@ -101,8 +97,8 @@ bool Wallet::nodeIdentityCreate() { ScopedLock sl(theApp->getWalletDB()->getDBLock()); db->executeSQL(str(boost::format("INSERT INTO NodeIdentity (PublicKey,PrivateKey,Dh512,Dh1024) VALUES (%s,%s,%s,%s);") - % db->escape(nodePublicKey.humanNodePublic()) - % db->escape(nodePrivateKey.humanNodePrivate()) + % db->escape(naNodePublic.humanNodePublic()) + % db->escape(naNodePrivate.humanNodePrivate()) % db->escape(strDh512) % db->escape(strDh1024))); // XXX Check error result. diff --git a/src/key.h b/src/key.h index 213bae4ddc..4fe681631e 100644 --- a/src/key.h +++ b/src/key.h @@ -73,13 +73,11 @@ public: explicit key_error(const std::string& str) : std::runtime_error(str) {} }; - - //JED: typedef std::vector > CPrivKey; //typedef std::vector > CSecret; -typedef std::vector CPrivKey; -typedef std::vector CSecret; +typedef std::vector CPrivKey; +typedef std::vector CSecret; class CKey { protected: @@ -153,6 +151,7 @@ public: CKey(const uint256& privateKey) : pkey(NULL), fSet(false) { + // XXX Broken pkey is null. SetPrivateKeyU(privateKey); } @@ -180,48 +179,7 @@ public: fSet = true; } - bool SetPrivKey(const CPrivKey& vchPrivKey) - { // DEPRECATED - const unsigned char* pbegin = &vchPrivKey[0]; - if (!d2i_ECPrivateKey(&pkey, &pbegin, vchPrivKey.size())) - return false; - EC_KEY_set_conv_form(pkey, POINT_CONVERSION_COMPRESSED); - fSet = true; - return true; - } - - bool SetSecret(const CSecret& vchSecret) - { // DEPRECATED - EC_KEY_free(pkey); - pkey = EC_KEY_new_by_curve_name(NID_secp256k1); - if (pkey == NULL) - throw key_error("CKey::SetSecret() : EC_KEY_new_by_curve_name failed"); - if (vchSecret.size() != 32) - throw key_error("CKey::SetSecret() : secret must be 32 bytes"); - BIGNUM *bn = BN_bin2bn(&vchSecret[0], 32, BN_new()); - if (bn == NULL) - throw key_error("CKey::SetSecret() : BN_bin2bn failed"); - if (!EC_KEY_regenerate_key(pkey, bn)) - throw key_error("CKey::SetSecret() : EC_KEY_regenerate_key failed"); - BN_clear_free(bn); - fSet = true; - return true; - } - - CSecret GetSecret() - { // DEPRECATED - CSecret vchRet; - vchRet.resize(32); - const BIGNUM *bn = EC_KEY_get0_private_key(pkey); - int nBytes = BN_num_bytes(bn); - if (bn == NULL) - throw key_error("CKey::GetSecret() : EC_KEY_get0_private_key failed"); - int n=BN_bn2bin(bn, &vchRet[32 - nBytes]); - if (n != nBytes) - throw key_error("CKey::GetSecret(): BN_bn2bin failed"); - return vchRet; - } - + // XXX Still used! BIGNUM* GetSecretBN() const { // DEPRECATED return BN_dup(EC_KEY_get0_private_key(pkey)); @@ -236,54 +194,24 @@ public: BN_bn2bin(bn, privKey.begin() + (privKey.size() - BN_num_bytes(bn))); } - void SetPrivateKeyU(const uint256& key) + bool SetPrivateKeyU(const uint256& key, bool bThrow=false) { - BIGNUM* bn = BN_bin2bn(key.begin(), key.size(), NULL); - if (!EC_KEY_set_private_key(pkey, bn)) + // XXX Broken if pkey is not set. + BIGNUM* bn = BN_bin2bn(key.begin(), key.size(), NULL); + bool bSuccess = !!EC_KEY_set_private_key(pkey, bn); + + BN_clear_free(bn); + + if (bSuccess) + { + fSet = true; + } + else if (bThrow) { - BN_clear_free(bn); throw key_error("CKey::SetPrivateKeyU: EC_KEY_set_private_key failed"); } - fSet = true; - BN_clear_free(bn); - } - void SetPubSeq(const NewcoinAddress& masterKey, int keyNum) - { - EC_KEY* key = GeneratePublicDeterministicKey(masterKey, keyNum); - if (key == NULL) - throw key_error("CKey::SetPubSeq: GenPubDetKey failed"); - if (pkey != NULL) - EC_KEY_free(pkey); - pkey = key; - fSet = true; - } - -#if 0 - void SetPrivSeq(const NewcoinAddress& masterKey, int keyNum) - { // broken: Need the seed - uint256 privKey; - EC_KEY* key = GeneratePrivateDeterministicKey(masterKey, masterKey.getFamilyGeneratorU(), keyNum); - privKey.zero(); - if (pkey != NULL) - EC_KEY_free(pkey); - pkey = key; - fSet = true; - } -#endif - - CPrivKey GetPrivKey() - { - unsigned int nSize = i2d_ECPrivateKey(pkey, NULL); - if (!nSize) - throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey failed"); - assert(nSize<=279); - CPrivKey vchPrivKey(279, 0); - unsigned char* pbegin = &vchPrivKey[0]; - if (i2d_ECPrivateKey(pkey, &pbegin) != nSize) - throw key_error("CKey::GetPrivKey() : i2d_ECPrivateKey returned unexpected size"); - assert(vchPrivKey.size()<=279); - return vchPrivKey; + return bSuccess; } bool SetPubKey(const void *ptr, size_t len) @@ -322,14 +250,17 @@ public: bool Sign(const uint256& hash, std::vector& vchSig) { - vchSig.clear(); unsigned char pchSig[10000]; unsigned int nSize = 0; + + vchSig.clear(); + if (!ECDSA_sign(0, (unsigned char*)hash.begin(), hash.size(), pchSig, &nSize, pkey)) return false; vchSig.resize(nSize); memcpy(&vchSig[0], pchSig, nSize); + return true; } diff --git a/src/utils.cpp b/src/utils.cpp index 742c91cffb..92f2379c26 100644 --- a/src/utils.cpp +++ b/src/utils.cpp @@ -55,6 +55,42 @@ void strUnHex(std::string& strDst, const std::string& strSrc) strDst[i] = (charUnHex(strSrc[i*2]) << 4) | charUnHex(strSrc[i*2+1]); } +std::vector strUnHex(const std::string& strSrc) +{ + std::string strTmp; + + strUnHex(strTmp, strSrc); + + return strCopy(strTmp); +} + +// +// Misc string +// + +std::vector strCopy(const std::string& strSrc) +{ + std::vector vucDst; + + vucDst.resize(strSrc.size()); + + std::copy(strSrc.begin(), strSrc.end(), vucDst.begin()); + + return vucDst; +} + +std::string strCopy(const std::vector& vucSrc) +{ + std::string strDst; + + strDst.resize(vucSrc.size()); + + std::copy(vucSrc.begin(), vucSrc.end(), strDst.begin()); + + return strDst; + +} + // // DH support // diff --git a/src/utils.h b/src/utils.h index b7e888d4b7..2fa78e09d9 100644 --- a/src/utils.h +++ b/src/utils.h @@ -94,6 +94,11 @@ bool isZero(Iterator first, int iSize) int charUnHex(char cDigit); void strUnHex(std::string& strDst, const std::string& strSrc); +std::vector strUnHex(const std::string& strSrc); + +std::vector strCopy(const std::string& strSrc); +std::string strCopy(const std::vector& vucSrc); + DH* DH_der_load(const std::string& strDer); DH* DH_der_load_hex(const std::string& strDer); void DH_der_gen(std::string& strDer, int iKeyLength);