Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DIP: aj-hd-mixing to define mix tracking via hdpath #130

Open
wants to merge 1 commit into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
152 changes: 152 additions & 0 deletions dip-aj-hd-mixing.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
<pre>
DIP: aj-hd-mixing
Title: Coin Mix Tracking in HD Wallets via HDPath
Authors: coolaj86
Special-Thanks: Rion Gull
Comments-Summary: No comments yet.
Status: Draft
Type: Standard
Created: 2023-06-28
License: CC0-1.0
</pre>

## Table of Contents

- [Table of Contents](#table-of-contents)
- [Abstract](#abstract)
- [Prior Art](#prior-art)
- [Motivation](#motivation)
- [Specification](#specification)
- [Coin Mix Tracking via HDPath](#coin-mix-tracking-via-hdpath)
- [Other Considerations](#other-considerations)
- [Copyright](#copyright)

## Abstract

This DIP proposes to track "coin mixing" in HD Wallets using the HDPath.

keywords: CoinJoin PrivateSend mobile coin mixing mix hdpath mixpath

## Prior Art

- [Multi-Account Hierarchy for Deterministic Wallets](https://github.com/bitcoin/bips/blob/master/bip-0044.mediawiki)

## Motivation

Currently there's no strategy for tracking "coin mixing" on mobile devices, or
sharing "coin mixing" enabled wallet accounts between devices - such as in the
case where a second device should do the mixing because the mobile device cannot
reasonably do so.

Preferably we want a strategy that doesn't require syncing indexes, especially
not in one-off formats.

This solves all of those problems with minimal complexity.

This won't break any existing wallets - those that are unaware of mixing will
still be aware - and will enable shared data via an offline indexing scheme
protocol rather than requiring a new or custom format or online synced data.

## Specification

[lextx]: https://github.com/bitcoin/bips/blob/master/bip-0069.mediawiki

[Lexicographical Indexing of Transaction Inputs and Outputs][lextx] MUST be used
for all mixing transactions.

The _Usage_ component (at index 4) of the HDPath is designated for tracking coin
mixes for mixed accounts.

HDPaths are used in this format:

```text
m/<bip44>'/<coin>'/<account>'/<mixcount>/<index>
m/44'/5'/0'/0/0
```

Accounts should be designated as either Mixed or Unmixed. However, if any path
in the format of `m/44'/5'/<account>'/0/<index>` has only a single coin which is
a recognizable denomination, it should be searched from
`m/44'/5'/<account>'/1/<index>` up through `m/44'/5'/<account>'/<n>/<index>` to
the first unused address to find unspent mixed, denominated coins.

### Coin Mix Tracking via HDPath

**Summary of BIP-44**

The index to a particular private key or address of an HDPath is defined in this
format:

```text
m/<bip44>'/<coin>'/<account>'/<usage>/<index>
m/44'/5'/0'/0/0
```

The _Usage_ path component is presently used to indicate either:

- `0` as _External_, for sending money
- `1` as _Internal_ for receiving change

**Applied to Coin Mixing**

There are many factors that effect the viability of coin mixing, so for this
specification and these examples we'll make 2 assumptions:

1. mixed coins are generally not used in a scenarios where change is returned
2. any return change is denominated and its transaction adheres to
[Lexicographical Indexing of TX Inputs & Outputs][lextx]

Given those assumptions either A) _Usage_ will _never_ represent return change
or B) the return change will already have some measure of entropy added to it.

This means that the _Usage_ path can be used in for tracking the mix count with
coming into conflict with unmixed coins.

```text
m/<bip44>'/<coin>'/<account>'/<mixcount>/<index>
m/44'/5'/0'/0/0 - newly denominated coin
m/44'/5'/0'/1/0 - coin which has been mixed once
Comment on lines +107 to +108
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The usage 0 and 1 will "conflict" with the external and internal key usage. Perhaps this doesn't matter as 0 and 1 wouldn't be considered mixed. There is still a way to tell the differences between change and output that has been mixed once based on the TX history and the amount.

Copy link
Author

@coolaj86 coolaj86 Jul 25, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The usage 0 and 1 will "conflict" with the external and internal key usage.

A "CoinJoin" wallet wouldn't have change, so there would be no conflict.

That assuming that we use different account indexes for "CoinJoin" accounts than the legacy accounts. Tracking which is which would be a matter of indexing on the client side.

Example:

  • 0 legacy account
  • 1 savings account
  • 2 CoinJoin account
  • 3 shared account with wife

A specific metadata tag to relate an account's name, type, and any other metadata or notes about it would need its own DIP for the JSON format.

I suspect it would be something like this:

[
  {
    "nickname": "Primary",
    "wallet_id": "xxxxxxx", // as per DIP: Deterministic Wallet IDs
    "account_index": 0,
    "capabilities": ["coinjoin"],
    "desc": "Modern, Secure DASH Transactions",
  },
  {
    "nickname": "Legacy",
    "wallet_id": "yyyyyy", // as per DIP: Deterministic Wallet IDs
    "account_index": 0,
    "capabilities": [],
    "desc": "Fingerprinted Transactions for Legacy APIs and Apps",
  },
  {
    "nickname": "Marie",
    "wallet_id": "zzzzzz", // as per DIP: Deterministic Wallet IDs
    "account_index": 0,
    "capabilities": [],
    "desc": "Shared Account with Marie",
  }
]

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Perhaps this doesn't matter as 0 and 1 wouldn't be considered mixed.

Off-by-one errors are hard enough as-is. I'd say 0 should be the denomination (or transfer of existing denomination) and 1 should be the first mix.

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is still a way to tell the differences between change and output that has been mixed once based on the TX history and the amount.

That was a poor choice and can't be relied on for future development.

As long as the DashCore requires the cutesy style of 100001[0000], you'll always have to de-mix coins to spend them.

Denominations detection needs to be redone (eventually) so that they carry the excess of the fee balance with them. I address that in #131 (though some of my understanding was incorrect, the core concept remains the same).

So (eventually) 100002000 and 100001800 need to both be considered a denomination of 100000000 with usable stamp values that can be spent many times before having to be redenominated and remixed - such that there is no clear distinction between a "mix" and a "spend" - denominations all the way down.

m/44'/5'/0'/...
m/44'/5'/0'/16/0 - a fully mixed coin
m/44'/5'/0'/... - an overmixed coin
Comment on lines +106 to +111
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Currently, the DIP9 format is being used for CoinJoin development on mobile, which is based on using number 4 from
https://github.com/dashpay/dips/blob/master/dip-0009/assignments.md.

For example with mainnet, the path is the following:
m/9'/5'/4'/x

This follows the following scheme.
m / 9' / coin_type' / feature' / *

Presently, what is used doesn't include the account number. This will need to be added in the mobile scheme.

```

## Other Considerations

1. Mixed accounts could be designated to start at 2147483648 and count _down_
rather than starting at 0 and counting up.
```text
m/44'/5'/2147483648'/0/0 - newly denominated coin on first mixed account
m/44'/5'/2147483647'/0/0 - newly denominated coin on second mixed account
```
Counterpoint: More complexity, no benefit. Software either will or won't be
able to restore mixed accounts. This doesn't help.
2. A new HDPath designation path could be introduced.
```text
m/dipXX'/5'/0'/0/0
```
Counterpoint: Software that follows the 44' spec can still follow this spec,
so changing the identifier probably only makes it more difficult to adapt
otherwise working software. DASH software will know to check for mixed
funds.
3. A new HDPath component could be introduced.
```text
m/<bip44>'/<coin>'/<account>'/<usage>/<index>/<mixcount>
m/dipXX'/5'/0'/0/0
```
Counterpoint: Same as above, but more so.

## Copyright

Copyright 2023 AJ ONeal.

DIP to Secure Transactions - Patch Data Leak Vulnerability via Deterministic
Index Ordering

Written in 2023 by AJ ONeal <[email protected]> \
To the extent possible under law, the author(s) have dedicated all copyright \
and related and neighboring rights to this software to the public domain \
worldwide. This software is distributed without any warranty. \

You should have received a copy of the CC0 Public Domain Dedication along with \
this software. If not, see <https://creativecommons.org/publicdomain/zero/1.0/>.