Example #1
0
void Keychain::importBIP32(const secure_bytes_t& extkey, const secure_bytes_t& lock_key)
{
    Coin::HDKeychain hdKeychain(extkey);

    depth_ = (uint32_t)hdKeychain.depth();
    parent_fp_ = hdKeychain.parent_fp();
    child_num_ = hdKeychain.child_num();
    chain_code_ = hdKeychain.chain_code();
    privkey_.clear();
    if (hdKeychain.isPrivate())
    {
        if (!lock_key.empty())
        {
            privkey_salt_ = AES::random_salt();
            privkey_ciphertext_ = AES::encrypt(lock_key, hdKeychain.key(), true, privkey_salt_);
        }
        else
        {
            privkey_salt_ = 0;
            privkey_ciphertext_ = hdKeychain.key();
        }
    }
    else
    {
        privkey_salt_ = 0;
        privkey_ciphertext_.clear();
    }

    pubkey_ = hdKeychain.pubkey();
    hash_ = hdKeychain.full_hash();
}
Example #2
0
bool Keychain::setPrivateKeyUnlockKey(const secure_bytes_t& lock_key, const bytes_t& /*salt*/)
{
    if (!isPrivate()) throw std::runtime_error("Cannot lock the private key of a public keychain.");
    if (privkey_.empty()) throw std::runtime_error("Key is locked.");

#ifdef ENABLE_CRYPTO
    if (lock_key.empty())
    {
        privkey_ciphertext_ = privkey_;
        privkey_salt_.clear(); // empty salt means no encryption
    }
    else
    {
        // TODO: add real salt, better crypto function
        privkey_ciphertext_ = aes_encrypt(lock_key, privkey_, 0);
        privkey_salt_.clear();
        privkey_salt_.push_back(1);
    }
#else
    privkey_ciphertext_ = privkey_;
    privkey_salt_.clear();
#endif

    return true;
}
Example #3
0
Keychain::Keychain(const std::string& name, const secure_bytes_t& entropy, const secure_bytes_t& lock_key)
    : name_(name), hidden_(false)
{
    if (name.empty() || name[0] == '@') throw std::runtime_error("Invalid keychain name.");
    if (entropy.size() < 16) throw std::runtime_error("At least 128 bits of entropy must be supplied.");

    Coin::HDSeed hdSeed(entropy);
    Coin::HDKeychain hdKeychain(hdSeed.getMasterKey(), hdSeed.getMasterChainCode());

    depth_ = (uint32_t)hdKeychain.depth();
    parent_fp_ = hdKeychain.parent_fp();
    child_num_ = hdKeychain.child_num();
    chain_code_ = hdKeychain.chain_code();
    pubkey_ = hdKeychain.pubkey();
    privkey_ = hdKeychain.privkey();
    seed_ = entropy;
    if (lock_key.empty())
    {
        privkey_salt_ = 0;
        privkey_ciphertext_ = privkey_;

        seed_salt_ = 0;
        seed_ciphertext_ = seed_;
    }
    else
    {
        privkey_salt_ = AES::random_salt();
        privkey_ciphertext_ = AES::encrypt(lock_key, privkey_, true, privkey_salt_);

        seed_salt_ = AES::random_salt();
        seed_ciphertext_ = AES::encrypt(lock_key, seed_, true, seed_salt_);
    }
    privkey_.clear();
    seed_.clear();
    hash_ = hdKeychain.full_hash();
}
Example #4
0
bool Keychain::setChainCodeUnlockKey(const secure_bytes_t& lock_key, const bytes_t& /*salt*/)
{
    if (chain_code_.empty()) throw std::runtime_error("Chain code is locked.");

#ifdef ENABLE_CRYPTO
    if (lock_key.empty())
    {
        chain_code_ciphertext_ = chain_code_;
        chain_code_salt_.clear();
    }
    else
    {
        // TODO: add real salt, better crypto function
        chain_code_ciphertext_ = aes_encrypt(lock_key, chain_code_, 0);
        chain_code_salt_.clear();
        chain_code_salt_.push_back(1);
    }
#else
    chain_code_ciphertext_ = chain_code_;
    chain_code_salt_.clear();
#endif

    return true;
}
Example #5
0
std::shared_ptr<Keychain> Keychain::child(uint32_t i, bool get_private, const secure_bytes_t& lock_key)
{
    if (get_private && !isPrivate()) throw std::runtime_error("Cannot get private child from nonprivate keychain.");
    if (get_private)
    {
        if (privkey_.empty()) throw std::runtime_error("Private key is locked.");
        Coin::HDKeychain hdkeychain(privkey_, chain_code_, child_num_, parent_fp_, depth_);
        hdkeychain = hdkeychain.getChild(i);
        std::shared_ptr<Keychain> child(new Keychain());
        child->parent_ = get_shared_ptr();
        child->pubkey_ = hdkeychain.pubkey();
        child->chain_code_ = hdkeychain.chain_code();

        child->privkey_ = hdkeychain.privkey();
        if (lock_key.empty())
        {
            child->privkey_salt_ = 0;
            child->privkey_ciphertext_ = privkey_;

            child->seed_salt_ = 0;
            child->seed_ciphertext_ = seed_;
        }
        else
        {
            child->privkey_salt_ = AES::random_salt();
            child->privkey_ciphertext_ = AES::encrypt(lock_key, child->privkey_, true, child->privkey_salt_);

            if (seed_.empty())
            {
                child->seed_salt_ = 0;
            }
            else
            {
                child->seed_salt_ = AES::random_salt();
                child->seed_ciphertext_ = AES::encrypt(lock_key, seed_, true, child->seed_salt_);
            }
        }
        child->privkey_.clear();

        child->child_num_ = hdkeychain.child_num();
        child->parent_fp_ = hdkeychain.parent_fp();
        child->depth_ = hdkeychain.depth();
        child->hash_ = hdkeychain.full_hash();
        child->derivation_path_ = derivation_path_;
        child->derivation_path_.push_back(i);
        return child;
    }
    else
    {
        Coin::HDKeychain hdkeychain(pubkey_, chain_code_, child_num_, parent_fp_, depth_);
        hdkeychain = hdkeychain.getChild(i);
        std::shared_ptr<Keychain> child(new Keychain());;
        child->parent_ = get_shared_ptr();
        child->pubkey_ = hdkeychain.pubkey();
        child->chain_code_ = hdkeychain.chain_code();
        child->child_num_ = hdkeychain.child_num();
        child->parent_fp_ = hdkeychain.parent_fp();
        child->depth_ = hdkeychain.depth();
        child->hash_ = hdkeychain.full_hash();
        child->derivation_path_ = derivation_path_;
        child->derivation_path_.push_back(i);
        return child;
    }
}