Skip to content

Subwallets

MMGen edited this page Nov 16, 2023 · 10 revisions

Introduction

Beginning with MMGen Wallet Version 0.11.0, every wallet has a two sets of associated subwallets with “long“ and “short” seeds.

MMGen subwallets are identical to ordinary MMGen wallets in every respect. This provides a real-world security benefit, as it prevents an attacker from knowing whether a wallet is indeed a subwallet, i.e. whether it has a parent from which it was derived.

Subwallets are specified by a “Subseed Index” consisting of:

a) an integer in the range 1-1000000, plus b) an optional single letter, L or S

The letter designates the length of the subwallet’s seed. If omitted, L is assumed.

Long (L) subwallets have the same seed length as their parent wallet (typically 256 bits), while short (S) subwallets always have 128-bit seeds. Long and short subwallets for a given index are derived independently, so both may be used.

If you have a default wallet installed, you may view the Seed IDs of its subwallets like this:

$ mmgen-tool list_subseeds 1-5
Parent Seed: DF449DA4 (256 bits)

 Long Subseeds     Short Subseeds
 -------------     --------------
  1L: FC9A8735       1S: 930E1AD5
  2L: 62B02F54       2S: DF14AB49
  3L: 9E884E99       3S: AD3ABD98
  4L: DB595AE1       4S: 3E885EC4
  5L: 36D5A0D1       5S: 30D66FF5

Here a range of 1-5 was chosen. Indexes of up to one million are allowed, which means every wallet has a total of two million potential subwallets.

Subwallets may be referenced either by their Subseed Index or Seed ID:

$ mmgen-tool get_subseed 4S
3E885EC4

$ mmgen-tool get_subseed_by_seed_id 3E885EC4
4S

Subwallet generation

To generate a subwallet, use the mmgen-subwalletgen command. For example, you’d generate your default wallet’s 4th short subwallet as follows:

$ mmgen-subwalletgen 4S
...
MMGen wallet written to file '3E885EC4-ABCDEF00[128,3].mmdat'

And view its seed phrase like this:

$ mmgen-walletconv -qS -o words 3E885EC4-ABCDEF00[128,3].mmdat
...
peaceful marry wrong surround treasure sort use favorite enough wolf suspend path

Since subwallets generated by mmgen-subwalletgen are just ordinary MMGen wallets, you can use them anywhere you’d use the latter.

Being ordinary wallets, subwallets may be used to generate other subwallets in turn, leading to hierarchies of arbitrary depth. However, this is inadvisable in practice for two reasons: Firstly, it creates accounting complexity, requiring the user to independently keep track of a derivation tree. More importantly, however, it leads to the danger of Seed ID collisions between subseeds at different levels of the hierarchy, as the software checks and avoids ID collisions only among sibling subseeds and their parent.

An exception to this caveat would be a multi-user setup where sibling subwallets are distributed to different users as their default wallets. Since the subseeds derived from these subwallets are private to each user, Seed ID collisions among them don’t present a problem.

A safe rule of thumb, therefore, is for each user to limit his/her installation to a single master wallet and derive all subwallets from this single parent.

Address generation and transaction signing using the parent wallet

A parent wallet may be used to generate keys and addresses for its associated subwallets. Given our above example (a default wallet having subwallet 4S with Seed ID 3E885EC4), the following two commands are equivalent:

# Generate ten bech32 addresses from the subwallet:
$ mmgen-addrgen --type=bech32 3E885EC4-ABCDEF00[128,3].mmdat 1-10

# Do the same thing, but using the parent wallet:
$ mmgen-addrgen --type=bech32 --subwallet=4S 1-10

The same goes for transaction signing. Consider a transaction that spends to and from addresses in the subwallet:

$ mmgen-txcreate 3E885EC4:B:2
(choose an input from subwallet 3E885EC4)
Transaction written to file '<something>.rawtx'

This transaction can now be signed either with the subwallet itself:

$ mmgen-txsign *.rawtx 3E885EC4-ABCDEF00[128,3].mmdat
...
Signed transaction written to file '<something>.sigtx'

Or with its parent wallet:

$ mmgen-txsign *.rawtx
...
Found subseed 3E885EC4 (DF449DA4:4S)
...
Signed transaction written to file '<something>.sigtx'

The latter command works “by magic” because by default each wallet scans its first 100 subwallets for Seed IDs. For a transaction containing addresses from a subwallet with an index higher than 100, say 144, we must extend the parent wallet’s search like this:

$ mmgen-txsign --subseeds=144 *.rawtx

This is basically all you need to know about subwallets. For live versions of the above examples that can be run as-is, see commits 7538a94, d1b8aef and 82086c9.

For more detailed usage information, see the mmgen-subwalletgen help screen.

Clone this wiki locally