Skip to content

Commit

Permalink
f: add xpub id
Browse files Browse the repository at this point in the history
  • Loading branch information
coolaj86 committed Jul 15, 2023
1 parent 71c459f commit c177474
Showing 1 changed file with 95 additions and 16 deletions.
111 changes: 95 additions & 16 deletions aj-wallet-id.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<pre>
DIP: aj-wallet-id
Title: A Method For Creating Wallet IDs via Fingerprint
Title: Method For Creating Wallet IDs & XPub IDs
Authors: coolaj86
Special-Thanks: Rion Gull
Comments-Summary: No comments yet.
Expand All @@ -17,20 +17,26 @@
- [Prior Art](#prior-art)
- [Motivation](#motivation)
- [Specification](#specification)
- [Example](#example)
- [Pseudocode](#pseudocode)
- [Copyright](#copyright)

## Abstract

In a single-wallet application an HD Path (`m/44'/5'/0'`) is sufficient for
identifying an account/contact, or address/private key.

However, in multi-wallet systems (using multiple Wallet Phrases) there must be a
deterministic id to identify which wallet the HD Path should be applied to.
However, in multi-Wallet and multi-XPub systems (using multiple Wallet Phrases
or XPubs from multiple contacts) there must be deterministic IDs to associate
the Wallet or XPub to which the HD Path should be applied.

keywords: hdpath, recovery phrase, wallet phrase, seed
keywords: \
hdpath, HD Path, recovery phrase, wallet phrase, seed, \
XPub, X Pub, XPrv, X Prv, HDKey, HD Key, XKey, X Key

## Prior Art

- [Key Identifiers of Hierarchical Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#key-identifiers)
- [Mnemonic code for generating deterministic keys](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)
- [Multi-Account Hierarchy for Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki)
- [Base 64 Encoding with URL and Filename Safe Alphabet](https://datatracker.ietf.org/doc/html/rfc4648#section-5)
Expand All @@ -42,9 +48,16 @@ keywords: hdpath, recovery phrase, wallet phrase, seed
Dash Incubator is working on multiple user- and merchant-focused projects where
multiple wallets may need to be cached offline locally and synchronized online.

As such, we need a deterministic, conflict-free wallet identifier to use
pairwise with the HD Path in order to unambiguously identify contacts and
addresses.
Similarly, as mentioned in
[Hierarchical Deterministic Wallets: Key Identifiers](https://github.com/bitcoin/bips/blob/master/bip-0032.mediawiki#key-identifiers),
the 32-bit "Key Identifiers" are prone to collusion and, as such, are not
suitable for these types of applications. \
(also, RIPEMD160 has been found weak and removed from - or never added to - popular
crypto libraries such as `WebCrypto` and `libssl3`)

As such, we need a deterministic, conflict-free Wallet and XPub identifiers to
use pairwise with HD Paths in order to unambiguously identify contacts and
payment addresses.

## Specification

Expand All @@ -58,15 +71,29 @@ and databases.
The ID is NOT suitable as cryptographically secure input for derivation or
encryption.

1. Produce the `seed` from the Wallet Phrase as per
### For Wallets

1. Produce the `seed` bytes from the Wallet Phrase as per
[Mnemonic code for generating deterministic keys](https://github.com/bitcoin/bips/blob/master/bip-0039.mediawiki)
2. Take the SHA-256 hash of the `seed` bytes.
2. Take the bytes of the SHA-256 hash of the `seed` bytes
3. The ID is a slice of the first 8 bytes (64 bits) of the hash

### For XPubs (& XPrvs)

1. Produce the raw `XPub` bytes from the `XPub` (or `XPrv`) `base58check` string
2. Take the SHA-256 hash of the `XPub` bytes \
(the whole of depth, parent fingerprint, index, chain code, and pub key)
3. The ID is a slice of the first 8 bytes (64 bits) of the hash.
4. The canonical encoding of the id URL-safe Base64.
5. Int64, Crockford Base32, and Hexidecimal are acceptable alternate formats for
use-case specific encoding.

### Example
### Canonical & Acceptable Encodings

- The canonical encoding of the ID is URL-safe Base64.
- The following encodings are acceptable for use-case specific formatting:
- Int64 (Big-Endian bytes)
- Crockford Base32
- Hexadecimal

### Example Wallet

Wallet Phrase:

Expand Down Expand Up @@ -106,18 +133,61 @@ CB32: 58W9N40ZKEFQ4
Base64Url: KjiakB-bn3I
```

### Psuedo-Code
### Example HD Key

Wallet `KjiakB-bn3I @ m/44'/5'/0'/0`

```text
XPrv: xprvA2L7qar7dyJNhxnE47gK5J6cc1oEHQuAk8WrZLnLeHTtnkeyP4w6E
o6Tt65trtdkTRtx8opazGnLbpWrkhzNaL6ZsgG3sQmc2yS8AxoMjfZ
XPub: xpub6FKUF6P1ULrfvSrhA9DKSS3MA3digsd27MSTMjBxCczsfYz7vcFLn
bQwjP9CsAfEJsnD4UwtbU43iZaibv4vnzQNZmQAVcufN4r3pva8kTz
```

XPub ID (HD Key ID):

```text
64-Bit Int: 7140927559579778096
Hex: 6319abc7fb8cbc30
CB32: CCCTQHZVHJY30
Base64Url: Yxmrx_uMvDA
```

### Pseudocode

- `walletToId`
- `xkeyToId`
- `bytesToId`

```js
/**
* Convert Wallet Phrase to Seed Bytes and print IDs
*/
async function walletToId(phrase, salt) {
let seedBytes = await DashPhrase.toSeed(phrase, salt);
let hashBuffer = await crypto.subtle.digest("SHA-256", seedBytes);

await bytesToId(seedBytes);
}

/**
* Convert XPrv or XPub (XKey) to XPub Bytes and print IDs
*/
async function xkeyToId(xkey) {
let hdkey = await DashHd.fromXKey(xkey);
let xpubBytes = await DashHd.toXPubBytes(hdkey);

await bytesToId(xpubBytes);
}

async function bytesToId(bytes) {
let hashBuffer = await crypto.subtle.digest("SHA-256", bytes);

let idBuffer = hashBuffer.slice(0, 8);
let idBytes = new Uint8Array(idBuffer);

let id = bytesToBase64Url(idBytes);
let idBase32Crock = bytesToBase32Crock(idBytes);
let idBase32Crock = base32crockford.encode(idBytes);
let idHex = bytesToHex(idBytes);
let idInt64 = BigInt(`0x${idHex}`);

Expand All @@ -131,9 +201,18 @@ async function walletToId(phrase, salt) {
```js
let phrase = "zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo zoo wrong";
let salt = "TREZOR";

walletToId(phrase, salt);
```

```js
// XPub @ m/44'/5'/0'/0 of the "Zoomonic" Wallet above
let xpub =
"xpub6FKUF6P1ULrfvSrhA9DKSS3MA3digsd27MSTMjBxCczsfYz7vcFLnbQwjP9CsAfEJsnD4UwtbU43iZaibv4vnzQNZmQAVcufN4r3pva8kTz";

xkeyToId(xpub);
```

## Copyright

Copyright 2023 AJ ONeal.
Expand Down

0 comments on commit c177474

Please sign in to comment.