mirror of
https://github.com/trezor/trezor-firmware.git
synced 2024-12-24 15:28:10 +00:00
docs(core): replace Purpose48 with BIP-48
https://github.com/bitcoin/bips/blob/master/bip-0048.mediawiki
This commit is contained in:
parent
e4be53459d
commit
b5710b820a
1
core/.changelog.d/1744.changed
Normal file
1
core/.changelog.d/1744.changed
Normal file
@ -0,0 +1 @@
|
||||
Refer to `m/48'/...` multisig derivation paths as BIP-48 instead of Purpose48.
|
@ -35,11 +35,12 @@ if False:
|
||||
# BIP-45 for multisig: https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki
|
||||
PATTERN_BIP45 = "m/45'/[0-100]/change/address_index"
|
||||
|
||||
# Electrum Purpose48. See docs/misc/purpose48.md
|
||||
# Electrum does not seem to use the raw script type, it is included here for completeness.
|
||||
PATTERN_PURPOSE48_RAW = "m/48'/coin_type'/account'/0'/change/address_index"
|
||||
PATTERN_PURPOSE48_P2SHSEGWIT = "m/48'/coin_type'/account'/1'/change/address_index"
|
||||
PATTERN_PURPOSE48_SEGWIT = "m/48'/coin_type'/account'/2'/change/address_index"
|
||||
# BIP-48 for multisig: https://github.com/bitcoin/bips/blob/master/bip-0048.mediawiki
|
||||
# The raw script type is not part of the BIP (and Electrum, as a notable implementation,
|
||||
# does not use it), it is included here for completeness.
|
||||
PATTERN_BIP48_RAW = "m/48'/coin_type'/account'/0'/change/address_index"
|
||||
PATTERN_BIP48_P2SHSEGWIT = "m/48'/coin_type'/account'/1'/change/address_index"
|
||||
PATTERN_BIP48_SEGWIT = "m/48'/coin_type'/account'/2'/change/address_index"
|
||||
|
||||
# BIP-49 for segwit-in-P2SH: https://github.com/bitcoin/bips/blob/master/bip-0049.mediawiki
|
||||
PATTERN_BIP49 = "m/49'/coin_type'/account'/change/address_index"
|
||||
@ -97,7 +98,7 @@ def validate_path_against_script_type(
|
||||
script_type in (InputScriptType.SPENDADDRESS, InputScriptType.SPENDMULTISIG)
|
||||
and multisig
|
||||
):
|
||||
patterns.append(PATTERN_PURPOSE48_RAW)
|
||||
patterns.append(PATTERN_BIP48_RAW)
|
||||
if coin.slip44 == SLIP44_BITCOIN or (
|
||||
coin.fork_id is not None and coin.slip44 != SLIP44_TESTNET
|
||||
):
|
||||
@ -113,7 +114,7 @@ def validate_path_against_script_type(
|
||||
elif coin.segwit and script_type == InputScriptType.SPENDP2SHWITNESS:
|
||||
patterns.append(PATTERN_BIP49)
|
||||
if multisig:
|
||||
patterns.append(PATTERN_PURPOSE48_P2SHSEGWIT)
|
||||
patterns.append(PATTERN_BIP48_P2SHSEGWIT)
|
||||
if coin.slip44 == SLIP44_BITCOIN:
|
||||
patterns.append(PATTERN_GREENADDRESS_A)
|
||||
patterns.append(PATTERN_GREENADDRESS_B)
|
||||
@ -123,7 +124,7 @@ def validate_path_against_script_type(
|
||||
elif coin.segwit and script_type == InputScriptType.SPENDWITNESS:
|
||||
patterns.append(PATTERN_BIP84)
|
||||
if multisig:
|
||||
patterns.append(PATTERN_PURPOSE48_SEGWIT)
|
||||
patterns.append(PATTERN_BIP48_SEGWIT)
|
||||
if coin.slip44 == SLIP44_BITCOIN:
|
||||
patterns.append(PATTERN_GREENADDRESS_A)
|
||||
patterns.append(PATTERN_GREENADDRESS_B)
|
||||
@ -137,7 +138,7 @@ def get_schemas_for_coin(coin: coininfo.CoinInfo) -> Iterable[PathSchema]:
|
||||
# basic patterns
|
||||
patterns = [
|
||||
PATTERN_BIP44,
|
||||
PATTERN_PURPOSE48_RAW,
|
||||
PATTERN_BIP48_RAW,
|
||||
]
|
||||
|
||||
# patterns without coin_type field must be treated as if coin_type == 0
|
||||
@ -173,8 +174,8 @@ def get_schemas_for_coin(coin: coininfo.CoinInfo) -> Iterable[PathSchema]:
|
||||
(
|
||||
PATTERN_BIP49,
|
||||
PATTERN_BIP84,
|
||||
PATTERN_PURPOSE48_P2SHSEGWIT,
|
||||
PATTERN_PURPOSE48_SEGWIT,
|
||||
PATTERN_BIP48_P2SHSEGWIT,
|
||||
PATTERN_BIP48_SEGWIT,
|
||||
)
|
||||
)
|
||||
|
||||
|
@ -43,7 +43,6 @@
|
||||
- [Generated Files](misc/generated-files.md)
|
||||
- [Git Hooks](misc/git-hooks.md)
|
||||
- [Monorepo Notes](misc/monorepo.md)
|
||||
- [Purpose48 derivation scheme](misc/purpose48.md)
|
||||
- [Review Process](misc/review.md)
|
||||
- [Changelog](misc/changelog.md)
|
||||
- [TOIF Image Format](misc/toif.md)
|
||||
|
@ -1,52 +0,0 @@
|
||||
# Purpose48 derivation scheme
|
||||
|
||||
Per [BIP-43], the first level of the derivation path is used as a "purpose". The purpose
|
||||
number is usually selected to match the BIP number: e.g., BIP-49 uses purpose `49'`.
|
||||
|
||||
There is no officially proposed **BIP-48** standard. Despite that, a de-facto standard
|
||||
for the purpose `48'` exists in the wild and is implemented by several HD wallets, most
|
||||
notably [Electrum]. This standard was never before formally
|
||||
specified, and this document aims to rectify the situation.
|
||||
|
||||
## Motivation
|
||||
|
||||
Purpose48 is intended for multisig scenarios. It allows using multiple script types from
|
||||
a single logical account or root key, while keeping multisig keys separate from
|
||||
single-sig keys.
|
||||
|
||||
## Specification
|
||||
|
||||
The following BIP-32 path levels are defined:
|
||||
|
||||
```
|
||||
m / 48' / coin_type' / account' / script_type' / change / address_index
|
||||
```
|
||||
|
||||
Meaning of all fields except `script_type` is defined in [BIP-44]
|
||||
|
||||
`script_type` can have the following values:
|
||||
|
||||
* `0`: raw [BIP-11] (p2ms) multisig
|
||||
* `1`: p2sh-wrapped segwit multisig (p2wsh-p2sh)
|
||||
* `2`: native segwit multisig (p2wsh)
|
||||
|
||||
The path derivation is hardened up to and including the `script_type` field.
|
||||
|
||||
## Trezor implementation
|
||||
|
||||
`script_type` value `0` corresponds to `SPENDMULTISIG`/`PAYTOMULTISIG`.
|
||||
|
||||
Value `1` corresponds to `SPENDP2SHWITNESS`/`PAYTOP2SHWITNESS`.
|
||||
|
||||
Value `2` corresponds to `SPENDWITNESS`/`PAYTOWITNESS`.
|
||||
|
||||
## References
|
||||
|
||||
Electrum implementation: https://github.com/spesmilo/electrum/blob/9931df9f254e49eb929723be62af61971b3032c8/electrum/keystore.py#L862-L889
|
||||
|
||||
Trezor implementation: TBD
|
||||
|
||||
[Electrum]: https://electrum.org/
|
||||
[BIP-11]: https://github.com/bitcoin/bips/blob/master/bip-0011.mediawiki
|
||||
[BIP-43]: https://github.com/bitcoin/bips/blob/master/bip-0043.mediawiki
|
||||
[BIP-44]: https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
|
@ -92,7 +92,7 @@ def test_show_multisig_3(client):
|
||||
)
|
||||
|
||||
|
||||
VECTORS_MULTISIG = ( # script_type, purpose48_type, address, xpubs, ignore_xpub_magic
|
||||
VECTORS_MULTISIG = ( # script_type, bip48_type, address, xpubs, ignore_xpub_magic
|
||||
(
|
||||
messages.InputScriptType.SPENDMULTISIG,
|
||||
0,
|
||||
@ -165,15 +165,15 @@ VECTORS_MULTISIG = ( # script_type, purpose48_type, address, xpubs, ignore_xpub
|
||||
@pytest.mark.skip_t1
|
||||
@pytest.mark.multisig
|
||||
@pytest.mark.parametrize(
|
||||
"script_type, purpose48_type, address, xpubs, ignore_xpub_magic", VECTORS_MULTISIG
|
||||
"script_type, bip48_type, address, xpubs, ignore_xpub_magic", VECTORS_MULTISIG
|
||||
)
|
||||
def test_show_multisig_xpubs(
|
||||
client, script_type, purpose48_type, address, xpubs, ignore_xpub_magic
|
||||
client, script_type, bip48_type, address, xpubs, ignore_xpub_magic
|
||||
):
|
||||
nodes = [
|
||||
btc.get_public_node(
|
||||
client,
|
||||
tools.parse_path(f"48h/0h/{i}h/{purpose48_type}h"),
|
||||
tools.parse_path(f"48h/0h/{i}h/{bip48_type}h"),
|
||||
coin_name="Bitcoin",
|
||||
)
|
||||
for i in range(3)
|
||||
@ -235,7 +235,7 @@ def test_show_multisig_xpubs(
|
||||
btc.get_address(
|
||||
client,
|
||||
"Bitcoin",
|
||||
tools.parse_path(f"48h/0h/{i}h/{purpose48_type}h/0/0"),
|
||||
tools.parse_path(f"48h/0h/{i}h/{bip48_type}h/0/0"),
|
||||
show_display=True,
|
||||
multisig=multisig,
|
||||
script_type=script_type,
|
||||
|
Loading…
Reference in New Issue
Block a user