Beispiel #1
0
void RunDeriveTest(std::vector<DeriveTestData> &vData)
{
    int rv;
    CBitcoinExtKey extKey58;
    CExtKey evkeyM;
    CExtPubKey epkeyM;
    
    for (uint32_t k = 0; k < vData.size(); ++k)
    {
        DeriveTestData &dt = vData[k];
        
        if (dt.nDerives == 0)
        {
            // - set master
            
            BOOST_CHECK(0 == (rv = extKey58.Set58(dt.vKey58.c_str())));
            BOOST_CHECK(0 == (rv += abs(strcmp(extKey58.ToString().c_str(), dt.vKey58.c_str()))));
            
            evkeyM = extKey58.GetKey();
            BOOST_CHECK(0 == (rv += abs(strcmp(CBitcoinExtKey(evkeyM).ToString().c_str(), dt.vKey58.c_str()))));
            epkeyM = evkeyM.Neutered();
            
            BOOST_CHECK(0 == (rv += abs(strcmp(CBitcoinExtPubKey(epkeyM).ToString().c_str(), dt.pKey58.c_str()))));
            
            BOOST_CHECK(CBitcoinExtPubKey(epkeyM).ToString().c_str());
            
            if (rv != 0)
            {
                BOOST_TEST_MESSAGE("Set master failed, aborting test.");
                break;
            }
            continue;
        };
        
        
        CExtKey evkey[2], evkeyOut;
        CExtPubKey epkeyOut;
        evkey[0] = evkeyM;
        rv = 0;
        for (uint32_t d = 0; d < dt.nDerives; ++d)
        {
            rv += evkey[d % 2].Derive(evkey[(d+1) % 2], 1);
        }
        BOOST_CHECK(dt.nDerives == (uint32_t)rv);
        evkeyOut = evkey[dt.nDerives % 2];
        
        BOOST_CHECK(CBitcoinExtKey(evkeyOut).ToString().c_str());
        BOOST_TEST_MESSAGE("evkeyOut.nDepth " << (int)evkeyOut.nDepth);
        BOOST_CHECK(evkeyOut.nDepth == dt.nDerives % 256);
        
        BOOST_CHECK(0 == strcmp(CBitcoinExtKey(evkeyOut).ToString().c_str(), dt.vKey58.c_str()));
        
        epkeyOut = evkeyOut.Neutered();
        BOOST_CHECK(0 == strcmp(CBitcoinExtPubKey(epkeyOut).ToString().c_str(), dt.pKey58.c_str()));
    };
    
}
void TestMnemonic(int nLanguage, const Array &va)
{
    std::string sError;
    
    std::string sEntropy = va[0].get_str();
    std::string sWords = va[1].get_str();
    std::string sSeed;
    std::string sPassphrase;
    if (va.size() > 3)
    {
        sPassphrase = va[2].get_str();
        sSeed = va[3].get_str();
    } else
    {
        sPassphrase = "TREZOR";
        sSeed = va[2].get_str();
    };
    
    //BOOST_MESSAGE("sEntropy " << sEntropy);
    //BOOST_MESSAGE("sWords " << sWords);
    //BOOST_MESSAGE("sSeed " << sSeed);
    //BOOST_MESSAGE("sPassphrase " << sPassphrase);
    
    std::vector<uint8_t> vEntropy = ParseHex(sEntropy);
    std::vector<uint8_t> vEntropyTest;
    
    std::string sWordsTest;
    BOOST_CHECK_MESSAGE(0 == MnemonicEncode(nLanguage, vEntropy, sWordsTest, sError), "MnemonicEncode: " << sError);
    
    BOOST_CHECK(sWords == sWordsTest);
    
    BOOST_CHECK_MESSAGE(0 == MnemonicDecode(-1, sWords, vEntropyTest, sError), "MnemonicDecode: " << sError);
    BOOST_CHECK(vEntropy == vEntropyTest);
    
    std::vector<uint8_t> vSeed = ParseHex(sSeed);
    std::vector<uint8_t> vSeedTest;
    
    BOOST_CHECK(0 == MnemonicToSeed(sWords, sPassphrase, vSeedTest));
    BOOST_CHECK(vSeed == vSeedTest);
    //BOOST_MESSAGE("vSeedTest " << HexStr(vSeedTest));
    
    if (va.size() > 4)
    {
        CExtKey58 eKey58;
        std::string sExtKey = va[4].get_str();
        
        CExtKey ekTest;
        ekTest.SetMaster(&vSeed[0], vSeed.size());
        
        eKey58.SetKey(ekTest, CChainParams::EXT_SECRET_KEY_BTC);
        BOOST_CHECK(eKey58.ToString() == sExtKey);
        
        //BOOST_MESSAGE("sExtKey " << sExtKey);
        //BOOST_MESSAGE("eKey58  " << eKey58.ToString());
    };
};
Beispiel #3
0
CExtKey DecodeExtKey(const std::string& str)
{
    CExtKey key;
    std::vector<unsigned char> data;
    if (DecodeBase58Check(str, data)) {
        const std::vector<unsigned char>& prefix = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
        if (data.size() == BIP32_EXTKEY_SIZE + prefix.size() && std::equal(prefix.begin(), prefix.end(), data.begin())) {
            key.Decode(data.data() + prefix.size());
        }
    }
    return key;
}
bool CHDKeyStore::DeriveKey(const CHDPubKey hdPubKey, CKey& keyOut) const
{
    //this methode required no locking

    std::string chainPath = hdPubKey.chainPath;
    std::vector<std::string> pathFragments;
    boost::split(pathFragments, chainPath, boost::is_any_of("/"));

    CExtKey extKey;
    CExtKey parentKey;
    BOOST_FOREACH(std::string fragment, pathFragments)
    {
        bool harden = false;
        if (*fragment.rbegin() == '\'')
        {
            harden = true;
            fragment = fragment.substr(0,fragment.size()-1);
        }

        if (fragment == "m")
        {
            CExtKey bip32MasterKey;
            CKeyingMaterial masterSeed;

            // get master seed
            if (!GetMasterSeed(hdPubKey.chainHash, masterSeed))
                return false;

            if (masterSeed.size() == BIP32_EXTKEY_SIZE)
            {
                //if the seed size matches the BIP32_EXTKEY_SIZE, we assume its a encoded ext priv key
                bip32MasterKey.Decode(&masterSeed[0]);
            }
            else
                bip32MasterKey.SetMaster(&masterSeed[0], masterSeed.size());

            parentKey = bip32MasterKey;
        }
        else if (fragment == "c")
        {
            return false;
        }
        else
        {
            CExtKey childKey;
            int32_t nIndex;
            if (!ParseInt32(fragment,&nIndex))
                return false;
            parentKey.Derive(childKey, (harden ? 0x80000000 : 0)+nIndex);
            parentKey = childKey;
        }
    }
Beispiel #5
0
std::string EncodeExtKey(const CExtKey& key)
{
    std::vector<unsigned char> data = Params().Base58Prefix(CChainParams::EXT_SECRET_KEY);
    size_t size = data.size();
    data.resize(size + BIP32_EXTKEY_SIZE);
    key.Encode(data.data() + size);
    std::string ret = EncodeBase58Check(data);
    memory_cleanse(data.data(), data.size());
    return ret;
}
Beispiel #6
0
bool CAccountHD::GetKey(const CKeyID& keyID, CKey& key) const
{
    assert(!m_readOnly);
    assert(IsHD());

    // Witness keys are a special case.
    // They are stored instead of generated on demand (so that they work in encrypted wallets)
    if (IsPoW2Witness())
    {
        if (internalKeyStore.GetKey(keyID, key))
        {
            // But skip it if it is an empty key... (Which can happen by design)
            // Technical: Witness keystore is filled with "public/empty" pairs as the public keys are created and then populated on demand with "public/witness" keys only when they are needed/generated (first use)
            if (key.IsValid())
                return true;
        }
    }

    if (IsLocked())
        return false;

    int64_t nKeyIndex = -1;
    CExtKey privKey;
    if (externalKeyStore.GetKey(keyID, nKeyIndex))
    {
        primaryChainKeyPriv.Derive(privKey, nKeyIndex);
        if(privKey.Neuter().pubkey.GetID() != keyID)
            assert(0);
        key = privKey.key;
        return true;
    }
    if (internalKeyStore.GetKey(keyID, nKeyIndex))
    {
        changeChainKeyPriv.Derive(privKey, nKeyIndex);
        if(privKey.Neuter().pubkey.GetID() != keyID)
            assert(0);
        key = privKey.key;
        return true;
    }
    return false;
}
Beispiel #7
0
bool CAccountHD::GetKey(const CKeyID& keyID, CKey& key) const
{
    if (IsLocked())
        return false;

    int64_t nKeyIndex = -1;
    CExtKey privKey;
    if (externalKeyStore.GetKey(keyID, nKeyIndex)) {
        primaryChainKeyPriv.Derive(privKey, nKeyIndex);
        if (privKey.Neuter().pubkey.GetID() != keyID)
            assert(0);
        key = privKey.key;
        return true;
    }
    if (internalKeyStore.GetKey(keyID, nKeyIndex)) {
        changeChainKeyPriv.Derive(privKey, nKeyIndex);
        if (privKey.Neuter().pubkey.GetID() != keyID)
            assert(0);
        key = privKey.key;
        return true;
    }
    return false;
}