Bitcoin Forum
November 04, 2024, 10:14:13 PM *
News: Latest Bitcoin Core release: 28.0 [Torrent]
 
   Home   Help Search Login Register More  
Pages: [1]
  Print  
Author Topic: Possible seeds for Bitcoin Core  (Read 187 times)
PawGo (OP)
Legendary
*
Offline Offline

Activity: 952
Merit: 1385


View Profile
November 13, 2022, 10:12:29 AM
Last edit: November 13, 2022, 11:18:02 AM by PawGo
Merited by ABCbits (2), NeuroticFish (1)
 #1

Hello

Recently I wanted to check how Bitcoin Core derivation path (BIP32) is different from other wallets (BIP39). I was also interested how to generate master private key. Reading bip32 specification (https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#Specification_Key_derivation) we may find that master private key is clearly dependent on seed only, but the question is - what is seed?
Then I found the operations performed by method "sethdseed" (seed for HD wallet may be generated by program or may be 'injected' by user). (https://github.com/bitcoin-dot-org/developer.bitcoin.org/blob/master/reference/rpc/sethdseed.rst)
 And in fact I was very surprised to see that seed is nothing else that public key of (random/specified) private key:
Code:
CPubKey LegacyScriptPubKeyMan::GenerateNewSeed()
{
    assert(!m_storage.IsWalletFlagSet(WALLET_FLAG_DISABLE_PRIVATE_KEYS));
    CKey key;
    key.MakeNewKey(true);
    return DeriveNewSeed(key);
}
Code:
CPubKey LegacyScriptPubKeyMan::DeriveNewSeed(const CKey& key)
{
    int64_t nCreationTime = GetTime();
    CKeyMetadata metadata(nCreationTime);

    // calculate the seed
    CPubKey seed = key.GetPubKey();
    assert(key.VerifyPubKey(seed));
....

As we see, when seed is generated by program, a random private key (compressed) is created, so I assume public key used as a seed has form "02/03 + X". I do not know how it is when user provide uncompressed WIF to sethdseed command, but then HD seed would be "04 + X + Y".

My concern is: let's say seed is generated by program based on compressed key - does it mean that each Bitcoin Core HD wallet could be derived from a ECDSA256K1 public keys?

In other words, may we say that each seed has form 02/03+X? There is no HD wallet which seed is "12345abcabc"?
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3542
Merit: 6885


Just writing some code


View Profile WWW
November 13, 2022, 04:34:17 PM
Merited by ABCbits (3), NeuroticFish (2), pooya87 (2)
 #2

No, the seed is not a public key. It is 32 bytes of random data. Bitcoin Core's (legacy) wallet stores this as a private key because it is convenient. Neither the compressedness nor the public key are used when computing the master private key, only the 32 bytes of random "private key" data is used.

PawGo (OP)
Legendary
*
Offline Offline

Activity: 952
Merit: 1385


View Profile
November 13, 2022, 04:46:04 PM
Merited by NeuroticFish (1)
 #3

No, the seed is not a public key. It is 32 bytes of random data. Bitcoin Core's (legacy) wallet stores this as a private key because it is convenient. Neither the compressedness nor the public key are used when computing the master private key, only the 32 bytes of random "private key" data is used.

How then you explain to me that new seed (line 518 https://github.com/bitcoin/bitcoin/blob/7921026a24594765f603d14ef87ff4e4541d2b76/src/wallet/rpc/wallet.cpp)
Code:
 master_pub_key = spk_man.DeriveNewSeed(key);

is generated as:
https://github.com/bitcoin/bitcoin/blob/ae6bb6e71e3082dd783e78c52b3af649fd5256cc/src/wallet/scriptpubkeyman.cpp

Quote
CPubKey LegacyScriptPubKeyMan::DeriveNewSeed(const CKey& key)
{
    int64_t nCreationTime = GetTime();
    CKeyMetadata metadata(nCreationTime);

    // calculate the seed
    CPubKey seed = key.GetPubKey();
    assert(key.VerifyPubKey(seed));

    // set the hd keypath to "s" -> Seed, refers the seed to itself
    metadata.hdKeypath     = "s";
    metadata.has_key_origin = false;
    metadata.hd_seed_id = seed.GetID();

    {
        LOCK(cs_KeyStore);

        // mem store the metadata
        mapKeyMetadata[seed.GetID()] = metadata;

        // write the key&metadata to the database
        if (!AddKeyPubKey(key, seed))
            throw std::runtime_error(std::string(__func__) + ": AddKeyPubKey failed");
    }

    return seed;
}
achow101
Moderator
Legendary
*
expert
Offline Offline

Activity: 3542
Merit: 6885


Just writing some code


View Profile WWW
November 13, 2022, 06:40:40 PM
Merited by ABCbits (4), NeuroticFish (3), nc50lc (1), DdmrDdmr (1), webtricks (1), PawGo (1)
 #4

Note that not all variable and function names necessarily match their actual behavior. seed is a local variable that contains an identifier for the seed itself. As it is also a local variable and is destroyed after this function completes, so don't read too much into its naming. We use pubkeys and their hash160 (CKeyID) as identifiers for the actual private data. Notice how it does AddKeyPubKey. This adds a key, along with its public key as an identifier, to the database. The actual seed is used in DeriveNewChildKey. There, the local variable seed is a CKey, and the data for the seed itself is loaded into that CKey by GetKey. Then that CKey is set as the seed for a CExtKey which represents BIP 32 extended private keys.

Pages: [1]
  Print  
 
Jump to:  

Powered by MySQL Powered by PHP Powered by SMF 1.1.19 | SMF © 2006-2009, Simple Machines Valid XHTML 1.0! Valid CSS!