doc(core): add references to schema specifications, add Purpose48 document

pull/1328/head
matejcik 4 years ago committed by matejcik
parent b8e654d8e5
commit 50e648636f

@ -29,12 +29,19 @@ if False:
MsgIn = TypeVar("MsgIn", bound=MsgWithCoinName)
HandlerWithCoinInfo = Callable[..., Awaitable[MsgOut]]
# common patterns
# BIP-45 for multisig: https://github.com/bitcoin/bips/blob/master/bip-0045.mediawiki
PATTERN_BIP45 = "m/45'/[0-100]/change/address_index"
PATTERN_PURPOSE48_LEGACY = "m/48'/coin_type'/account'/0'/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-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"
# BIP-84 for segwit: https://github.com/bitcoin/bips/blob/master/bip-0084.mediawiki
PATTERN_BIP84 = "m/84'/coin_type'/account'/change/address_index"
# compatibility patterns, will be removed in the future
@ -72,7 +79,7 @@ def validate_path_against_script_type(
elif script_type in (I.SPENDADDRESS, I.SPENDMULTISIG) and multisig:
patterns.append(PATTERN_BIP45)
patterns.append(PATTERN_PURPOSE48_LEGACY)
patterns.append(PATTERN_PURPOSE48_RAW)
if coin.coin_name in BITCOIN_NAMES:
patterns.append(PATTERN_GREENADDRESS_A)
patterns.append(PATTERN_GREENADDRESS_B)
@ -104,7 +111,7 @@ def get_schemas_for_coin(coin: coininfo.CoinInfo) -> Iterable[PathSchema]:
patterns = [
PATTERN_BIP44,
PATTERN_BIP45,
PATTERN_PURPOSE48_LEGACY,
PATTERN_PURPOSE48_RAW,
]
# compatibility patterns

@ -238,8 +238,13 @@ class _NeverMatchingSchema:
AlwaysMatchingSchema: PathSchemaType = _AlwaysMatchingSchema # type: ignore
NeverMatchingSchema: PathSchemaType = _NeverMatchingSchema # type: ignore
# BIP-44 for basic (legacy) Bitcoin accounts, and widely used for other currencies:
# https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki
PATTERN_BIP44 = "m/44'/coin_type'/account'/change/address_index"
# BIP-44 public key export, starting at end of the hardened part
PATTERN_BIP44_PUBKEY = "m/44'/coin_type'/account'/*"
# SEP-0005 for non-UTXO-based currencies, defined by Stellar:
# https://github.com/stellar/stellar-protocol/blob/master/ecosystem/sep-0005.md
PATTERN_SEP5 = "m/44'/coin_type'/account'"

@ -42,5 +42,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)
- [TOIF Image Format](misc/toif.md)

@ -0,0 +1,52 @@
# 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
Loading…
Cancel
Save