LearnBitcoin

Bitcoin Dev Archive 2017

Proposal: bip32 version bytes for segwit scripts

10 messages, 5 to 7 Sep 2017. Started by Thomas Voegtlin.

Thomas Voegtlin (3), Pavol Rusnak (2), Luke Dashjr (2), Kabuto Samourai (2), Andreas Schildbach

Permalink Original thread on gnusha.org

Thomas Voegtlin permalink original

BIP32 extended public/private keys have version bytes that result in the user visible xpub/xprv prefix. The BIP's recommendation is to use different version bytes for other networks (such as tpub/tprv for testnet)

I would like to use additional version bytes to indicate the type of output script used with the public keys.

I believe the change should be user visible, because users are exposed to master public keys. I propose the following prefixes:

========== =========== =================================== Version Prefix Description ========== =========== =================================== 0x0488ade4 xprv P2PKH or P2SH 0x0488b21e xpub P2PKH or P2SH 0x049d7878 yprv (P2WPKH or P2WSH) nested in P2SH 0x049d7cb2 ypub (P2WPKH or P2WSH) nested in P2SH 0x04b2430c zprv P2WPKH or P2WSH 0x04b24746 zpub P2WPKH or P2WSH ========== =========== =================================== (source: http://docs.electrum.org/en/latest/seedphrase.html)

I have heard the argument that xpub/xprv serialization is a format for keys, and that it should not be used to encode how these keys are used. However, the very existence of version bytes, and the fact that they are used to signal whether keys will be used on testnet or mainnet goes against that argument.

If we do not signal the script type in the version bytes, I believe wallet developers are going to use dirtier tricks, such as the bip32 child number field in combination with bip43/bip44/bip49.

Thomas

Pavol Rusnak in reply to Thomas Voegtlin permalink original

On 05/09/17 12:25, Thomas Voegtlin via bitcoin-dev wrote:

Quoted text (14 lines)
> ========== =========== ===================================
> Version    Prefix      Description
> ========== =========== ===================================
> 0x0488ade4 xprv        P2PKH or P2SH
> 0x0488b21e xpub        P2PKH or P2SH
> 0x049d7878 yprv        (P2WPKH or P2WSH) nested in P2SH
> 0x049d7cb2 ypub        (P2WPKH or P2WSH) nested in P2SH
> 0x04b2430c zprv        P2WPKH or P2WSH
> 0x04b24746 zpub        P2WPKH or P2WSH
> ========== =========== ===================================
> (source: http://docs.electrum.org/en/latest/seedphrase.html)
>
> I have heard the argument that xpub/xprv serialization is a format for
> keys, and that it should not be used to encode how these keys are used.

I used this argument for mnemonic/seed, not xpub/xprv. I am fine with this proposal of yours, so don't worry.

Luke Dashjr in reply to Thomas Voegtlin permalink original

On Tuesday 05 September 2017 06:25:16 Thomas Voegtlin via bitcoin-dev wrote:

Quoted text (9 lines)
> I have heard the argument that xpub/xprv serialization is a format for
> keys, and that it should not be used to encode how these keys are used.
> However, the very existence of version bytes, and the fact that they are
> used to signal whether keys will be used on testnet or mainnet goes
> against that argument.
>
> If we do not signal the script type in the version bytes, I believe
> wallet developers are going to use dirtier tricks, such as the bip32
> child number field in combination with bip43/bip44/bip49.

I think it makes more sense to use a child number field for this purpose. It seems desirable to use the same seed for all different script formats...

As you note, xpub\xprv are already being used for both P2PKH and P2SH. It really doesn't make sense to differentiate segwit specifically.

Luke

Thomas Voegtlin in reply to Luke Dashjr permalink original

On 05.09.2017 19:03, Luke Dashjr wrote:

Quoted text (1 line)
> It seems desirable to use the same seed for all different script formats...

That does not seem desirable to everybody.

If you want to guarantee that users will be able to recover all their funds from their mnemonic seed (and that is what they expect), then wallets must implement all script formats, even the ones that are deprecated. In addition, the list of script formats that must be supported is not defined in advance, but it keeps growing. This makes wallet implementation increasingly difficult. In the long run, seed portability is guaranteed to fail in such a system.

Quoted text (2 lines)
> As you note, xpub\xprv are already being used for both P2PKH and P2SH. It
> really doesn't make sense to differentiate segwit specifically.

That's not a reason. The fact that xpub/xprv can be used for both P2PKH and P2SH has already resulted in users receiving coins on addresses they do not control.

Kabuto Samourai in reply to Thomas Voegtlin permalink original

We support a change to the version bits of the HD serialization that will inform the receiving utility of the exact derivation method used for the pubkeys. Third-parties handling xpubs must not require additional information from the user about the derivation path or serialization format of the addresses under that xpub. When you have to ask, "Is this a SegWit xpub?" then you've already lost.

Avoiding a total UX nightmare is in everyone's interests.

I think Luke and Thomas may be talking past one another. When exporting a root master HD seed, encoding the {x,y,z}{pub,prv} distinctions makes no sense, as the root seed should derive all paths for all coins. Wallets may need additional code to discover which paths have been used when importing a root seed. But when exporting / importing an account-level seed for watch-only and receive address generation, changing the serialization version bytes is appropriate and (in our view) essential to avoid loss of funds.

The Electrum approach is nice but may not go far enough, as xpub and zpub both list "P2PKH or P2SH." Why not expand the number of version prefixes to eliminate the ambiguity?

On Tue, Sep 5, 2017 at 1:09 PM, Thomas Voegtlin via bitcoin-dev < bitcoin-dev@lists•linuxfoundation•org> wrote:

Quoted text (28 lines)
>
>
> On 05.09.2017 19:03, Luke Dashjr wrote:
>
> > It seems desirable to use the same seed for all different script
> formats...
>
> That does not seem desirable to everybody.
>
> If you want to guarantee that users will be able to recover all their
> funds from their mnemonic seed (and that is what they expect), then
> wallets must implement all script formats, even the ones that are
> deprecated. In addition, the list of script formats that must be
> supported is not defined in advance, but it keeps growing. This makes
> wallet implementation increasingly difficult. In the long run, seed
> portability is guaranteed to fail in such a system.
>
> > As you note, xpub\xprv are already being used for both P2PKH and P2SH. It
> > really doesn't make sense to differentiate segwit specifically.
>
> That's not a reason. The fact that xpub/xprv can be used for both P2PKH
> and P2SH has already resulted in users receiving coins on addresses they
> do not control.
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation•org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>
Andreas Schildbach in reply to Thomas Voegtlin permalink original

Generally I like the idea, but maybe we should come up with a (Bech32-based?) new standard that also includes the key birthdate (aka "wallet birthdate").

Also I heard Core will mix addresses of all types on the same HD chain. What prefix would it pick? "*pub"?

On 09/05/2017 12:25 PM, Thomas Voegtlin via bitcoin-dev wrote:

Quoted text (31 lines)
> BIP32 extended public/private keys have version bytes that result in the
> user visible xpub/xprv prefix. The BIP's recommendation is to use
> different version bytes for other networks (such as tpub/tprv for testnet)
>
> I would like to use additional version bytes to indicate the type of
> output script used with the public keys.
>
> I believe the change should be user visible, because users are exposed
> to master public keys. I propose the following prefixes:
>
> ========== =========== ===================================
> Version    Prefix      Description
> ========== =========== ===================================
> 0x0488ade4 xprv        P2PKH or P2SH
> 0x0488b21e xpub        P2PKH or P2SH
> 0x049d7878 yprv        (P2WPKH or P2WSH) nested in P2SH
> 0x049d7cb2 ypub        (P2WPKH or P2WSH) nested in P2SH
> 0x04b2430c zprv        P2WPKH or P2WSH
> 0x04b24746 zpub        P2WPKH or P2WSH
> ========== =========== ===================================
> (source: http://docs.electrum.org/en/latest/seedphrase.html)
>
> I have heard the argument that xpub/xprv serialization is a format for
> keys, and that it should not be used to encode how these keys are used.
> However, the very existence of version bytes, and the fact that they are
> used to signal whether keys will be used on testnet or mainnet goes
> against that argument.
>
> If we do not signal the script type in the version bytes, I believe
> wallet developers are going to use dirtier tricks, such as the bip32
> child number field in combination with bip43/bip44/bip49.
Thomas Voegtlin in reply to Kabuto Samourai permalink original

On 05.09.2017 21:00, Kabuto Samourai wrote:

Quoted text (5 lines)
>
> The Electrum approach is nice but may not go far enough, as xpub and zpub
> both list "P2PKH or P2SH." Why not expand the number of version prefixes to
> eliminate the ambiguity?
>

I agree that this would make sense if we had done it from the start. However, fixing that now might be difficult.

My "xyz" proposal extends the current format in a way that is very easy to deploy, because existing software will require minimal changes. However, if we eliminate the p2sh ambiguity now, wallets will need to add extra safeguards, in order to prevent scenarios that are currently allowed, and they will need to handle legacy xpub/xprv differently than ypub and zpub. This would take much more time to deploy.

In addition, consensus might be more difficult to reach on that; I guess not all developers will not agree that removing that ambiguity is useful. Since there is an infinity of possible P2SH scripts, it will never be possible to remove ambiguity from a master key associated to a P2SH script. Thus, the benefit of separating P2SH from P2PKH is not as strong.

Kabuto Samourai in reply to Thomas Voegtlin permalink original
Quoted text (1 line)
> In addition, consensus might be more difficult to reach on that

Let's move forward with the simplest solution that solves the problem and achieves consensus! Version bytes {x,y,z} fits the bill.

On Wed, Sep 6, 2017 at 4:26 AM, Thomas Voegtlin via bitcoin-dev < bitcoin-dev@lists•linuxfoundation•org> wrote:

Quoted text (31 lines)
>
>
> On 05.09.2017 21:00, Kabuto Samourai wrote:
> >
> > The Electrum approach is nice but may not go far enough, as xpub and zpub
> > both list "P2PKH or P2SH." Why not expand the number of version prefixes
> to
> > eliminate the ambiguity?
> >
>
> I agree that this would make sense if we had done it from the start.
> However, fixing that now might be difficult.
>
> My "xyz" proposal extends the current format in a way that is very easy
> to deploy, because existing software will require minimal changes.
> However, if we eliminate the p2sh ambiguity now, wallets will need to
> add extra safeguards, in order to prevent scenarios that are currently
> allowed, and they will need to handle legacy xpub/xprv differently than
> ypub and zpub. This would take much more time to deploy.
>
> In addition, consensus might be more difficult to reach on that; I guess
> not all developers will not agree that removing that ambiguity is
> useful. Since there is an infinity of possible P2SH scripts, it will
> never be possible to remove ambiguity from a master key associated to a
> P2SH script. Thus, the benefit of separating P2SH from P2PKH is not as
> strong.
> _______________________________________________
> bitcoin-dev mailing list
> bitcoin-dev@lists•linuxfoundation•org
> https://lists.linuxfoundation.org/mailman/listinfo/bitcoin-dev
>
Pavol Rusnak in reply to Luke Dashjr permalink original

On 05/09/17 19:03, Luke Dashjr via bitcoin-dev wrote:

Quoted text (2 lines)
> I think it makes more sense to use a child number field for this purpose.
> It seems desirable to use the same seed for all different script formats...

If I were designing the serialization format today, I would drop the fingerprint and expand child number to full BIP32 path. Good thing is that we already have depth, so we know how long the BIP32 path would be.

So I suggest the following:

4 byte: version bytes 1 byte: depth depth * 4 bytes: bip32 path 32 bytes 33 bytes

Luke Dashjr in reply to Kabuto Samourai permalink original

On Tuesday 05 September 2017 15:00:04 Kabuto Samourai via bitcoin-dev wrote:

Quoted text (8 lines)
> I think Luke and Thomas may be talking past one another. When exporting a
> root master HD seed, encoding the {x,y,z}{pub,prv} distinctions makes no
> sense, as the root seed should derive all paths for all coins. Wallets may
> need additional code to discover which paths have been used when importing
> a root seed. But when exporting / importing an account-level seed for
> watch-only and receive address generation, changing the serialization
> version bytes is appropriate and (in our view) essential to avoid loss of
> funds.

In that case, I think we should go back to the proposal I started with in March...

https://lists.linuxfoundation.org/pipermail/bitcoin-dev/2017-March/013726.html

This handles not only simple HD seeds, but also multisig HD and such.

Luke