firmware/docs/seed-xor.md
2026-06-19 12:48:49 -04:00

273 lines
13 KiB
Markdown

# Seed XOR
## The Problem
What do I do to secure my [SEEDPLATE](https://bitcoinmetalbackup.com/)?
Most people now understand that metal seed backups are paramount,
as paper burns. The challenge is how to store clear-text secrets?
Anyone with physical access could use it and gain complete
control of your funds! Encrypted digital backups are great, but they
are not discrete and you could be compelled to produce the passphrase.
Enter [_Seed XOR_](https://seedxor.com), a plausibly deniable means
of storing secrets in two or more parts that look and behave just
like the original secret. One 12-, 18-, or 24-word seed phrase becomes two or more parts
that are also BIP-39 compatible seeds phrases. These should be backed up in your
preferred method, metal or otherwise. These parts can be individually loaded
with honeypot funds as each one has same word length, with the last being
the checksum and will work as such in any normal BIP-39 compatible wallet.
This one more solution for your game-theory arsenal.
- *Q*: I'm lazy, can I do this to my Existing Seed?
- *A*: Yes. You can split the words you have already in your Coldcard, making
2, 3 or 4 new SEEDPLATES. You could also use any number of existing SEEDPLATES
you have, and combine them to make a new random wallet that is the XOR of
their values. Effectively that makes a new random wallet.
## Background
[_Seed XOR_](https://seedxor.com) works by taking any number of
seed phrases in BIP-39 style, and simply XOR-ing them together,
bit-by-bit into a new phrase. All seed phrases have to be of the same length.
The last word contains checksum.
For the "parts" (sometimes called "shares") this checksum
is calculated as normal for BIP-39, but those final bits are not used in
the XOR process. But the checksums still protects the integrity of the
individual parts. In 24-words XOR last 8 bits are checksum and in 12-words
XOR last 4 bits are checksum.
Useful properties of this approach:
- Every "part" looks and operates as a valid BIP-39 wallet.
- All the parts can be combined in any order and you arrive at the same result.
- You must have all parts, because any combination of less than all parts is a
valid Seed XOR wallet too.
- Each "part" can be recorded on a SEEDPLATE like normal and no new recording tools
are needed. No information about you original seed is leaked by finding up
to N-1 of the parts.
- You can store funds on the seeds of any part, and any subset of parts, which
opens even more duress options.
We recommend storing the checksum word of the original
wallet along with your N parts. This allows you to be sure you've
gotten all the parts and assembled them correctly. This does reveal
3 bits of your real wallet however, and also reveals that a
working and correct subset of parts has been assembled.
It is not hard to calculate a Seed XOR on paper (or to verify or
reconstruct a seed split by Coldcard). Below is a complete example,
and a lookup table that allows you to XOR together hex digits. You
can do the XOR at the bit level, but we recommend looking up each
word and finding it's 3-digit hex value (0x000 to 0x7FF), and going
hex-digit by hex-digit (4 bits).
## How Parts are Generated
Create new parts on your Coldcard:
Advanced > Danger Zone > Seed Functions > Seed XOR > Split Existing
You can choose between 2, 3 or 4 parts. You can also choose (next
screen) to generate them deterministically or using the TRNG. The
advantage of the deterministic approach is you'll always get the
same answers, so you can check that you've recorded the correct
words right the next day.
When the parts are made deterministically, we take a double-SHA256 over
a fixed string (`Batshitoshi`), your master secret, and the text
`0 of 4 parts` which changes for each part (the index is 0-based).
In random mode, we simply pick random bytes (and then double-SHA256
them) from the Coldcard's True Random Number Generator (TRNG). The number
of bytes matches your secret length: 16, 24, or 32 bytes for a 12-, 18-,
or 24-word seed respectively.
This is done to make all but the one part. The final part is the
value needed to get back to your secret, so it's the XOR of the
other N-1 parts. It contains just as much entropy as the other
parts.
### Other Notes
- So many possible duress games are possible once you've split your
seed up, and you are able to "give up" all of the seed phrases,
except one, and the attackers will still get nothing. You can load
various possible combinations of your Seed XOR's with various amounts,
so none are obviously empty and so on.
- Any two or more SEEDPLATES you have already encoded can be used
together to make a new wallet based on their XOR. No changes to
their existing values are needed... just import the set into a new
Coldcard and effectively a new random seed is in play at that point.
- One downside of the deterministic approach is that it allows
attackers to verify they have a seed that was split by Coldcard.
They can import the N parts into a Coldcard, and then split them
again on that Coldcard, and should arrive at the same values. If
they don't then either you used the TRNG, or they have some subset
of all the parts.
- You can pick your XOR parts randomly, and the result when XOR'ed
together, is a random wallet. However, it would be best to get the
last word checksum recorded correctly, so please use a tool such
as the Coldcard to lookup the 24th word and save that (for each
part). For example, you might take a fresh Coldcard (no secret)
and draw 23 words from a hat. After providing the 23rd word, the
Coldcard will show 8 possible final words. You can pick randomly
from that list, or simply use the first one, and then cancel the seed
import process on the Coldcard. Record that final word along
with the others on a SEEDPLATE.
## XOR Lookup Table
| XOR | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
|----:|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---
|**0**| 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | A | B | C | D | E | F
|**1**| 1 | 0 | 3 | 2 | 5 | 4 | 7 | 6 | 9 | 8 | B | A | D | C | F | E
|**2**| 2 | 3 | 0 | 1 | 6 | 7 | 4 | 5 | A | B | 8 | 9 | E | F | C | D
|**3**| 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4 | B | A | 9 | 8 | F | E | D | C
|**4**| 4 | 5 | 6 | 7 | 0 | 1 | 2 | 3 | C | D | E | F | 8 | 9 | A | B
|**5**| 5 | 4 | 7 | 6 | 1 | 0 | 3 | 2 | D | C | F | E | 9 | 8 | B | A
|**6**| 6 | 7 | 4 | 5 | 2 | 3 | 0 | 1 | E | F | C | D | A | B | 8 | 9
|**7**| 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0 | F | E | D | C | B | A | 9 | 8
|**8**| 8 | 9 | A | B | C | D | E | F | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
|**9**| 9 | 8 | B | A | D | C | F | E | 1 | 0 | 3 | 2 | 5 | 4 | 7 | 6
|**A**| A | B | 8 | 9 | E | F | C | D | 2 | 3 | 0 | 1 | 6 | 7 | 4 | 5
|**B**| B | A | 9 | 8 | F | E | D | C | 3 | 2 | 1 | 0 | 7 | 6 | 5 | 4
|**C**| C | D | E | F | 8 | 9 | A | B | 4 | 5 | 6 | 7 | 0 | 1 | 2 | 3
|**D**| D | C | F | E | 9 | 8 | B | A | 5 | 4 | 7 | 6 | 1 | 0 | 3 | 2
|**E**| E | F | C | D | A | B | 8 | 9 | 6 | 7 | 4 | 5 | 2 | 3 | 0 | 1
|**F**| F | E | D | C | B | A | 9 | 8 | 7 | 6 | 5 | 4 | 3 | 2 | 1 | 0
- XOR = EOR = ⊕ = Exclusive OR [Wikipedia](https://en.wikipedia.org/wiki/Exclusive_or)
- values in table are: x ⊕ y in hex
- go sideways for first digit, then look down for second digit
- in fact, doesn't matter if you do row or column first
- example: 2 XOR 6 => 4 same as 6 XOR 2 => 4
- any values XOR itself is zero (diagonal on this table)
- alternative view: (x) XOR (y) = flip bits of (x) that are set in (y)
- XOR with zero does nothing (flips no bits)
- XOR with 0xF flips all four bits
- XOR with self flips all set bits, so gives zero
- to XOR three values together, do (a⊕b)=X then (X⊕c)=answer
- right to A, down to B ... take that number, and go to that column
- down to C, that is answer: a ⊕ b ⊕ c
## Open Standard
Seed XOR is an open standard. Other software and hardware wallets are encouraged to
implement support. No license or permission is required, including usage of the term
"Seed XOR" when referring to implementations of this feature. Such implementations
should match the process described in this documentation and be fully interoperable.
---
# 24 Words XOR Seed Example Using 3 Parts
## Seed A (1 of 3)
1=romance [5DC], 2=wink [7DE], 3=lottery [420], 4=autumn [07D], 5=shop [635], 6=bring [0E1],
7=dawn [1BF], 8=tongue [723], 9=range [58E], 10=crater [194], 11=truth [74E], 12=ability [001],
13=miss [46E], 14=spice [68C], 15=fitness [2BF], 16=easy [22E], 17=legal [3FB], 18=release [5A9],
19=recall [59B], 20=obey [4BF], 21=exchange [275], 22=recycle [59F], 23=dragon [210], 24=room [5DF]
A = 5DC 7DE 420 07D 635 0E1 1BF 723 58E 194 74E 001 46E 68C 2BF 22E 3FB 5A9 59B 4BF 275 59F 210 5DF
## Seed B (2 of 3)
1=lion [411], 2=misery [46D], 3=divide [1FF], 4=hurry [37D], 5=latin [3EB], 6=fluid [2CD], 7=camp [106],
8=advance [01F], 9=illegal [388], 10=lab [3E0], 11=pyramid [578], 12=unaware [763], 13=eager [227],
14=fringe [2E8], 15=sick [63E], 16=camera [105], 17=series [620], 18=noodle [4B0], 19=toy [733],
20=crowd [1A2], 21=jeans [3BD], 22=select [61A], 23=depth [1D9], 24=lounge [422]
B = 411 46D 1FF 37D 3EB 2CD 106 01F 388 3E0 578 763 227 2E8 63E 105 620 4B0 733 1A2 3BD 61A 1D9 422
## Seed C (3 of 3)
1=vault [78E], 2=nominee [4AF], 3=cradle [18F], 4=silk [644], 5=own [4F0], 6=frown [2EC], 7=throw [70A],
8=leg [3FA], 9=cactus [100], 10=recall [59B], 11=talent [6EB], 12=worry [7EE], 13=gadget [2F5],
14=surface [6D1], 15=shy [63C], 16=planet [52F], 17=purpose [573], 18=coffee [169], 19=drip [219],
20=few [2AC], 21=seven [625], 22=term [6FB], 23=squeeze [69C], 24=educate [234]
C = 78E 4AF 18F 644 4F0 2EC 70A 3FA 100 59B 6EB 7EE 2F5 6D1 63C 52F 573 169 219 2AC 625 6FB 69C 234
## Calculation (XOR each hex digit)
A = 5DC 7DE 420 07D 635 0E1 1BF 723 58E 194 74E 001 46E 68C 2BF 22E 3FB 5A9 59B 4BF 275 59F 210 5DF
B = 411 46D 1FF 37D 3EB 2CD 106 01F 388 3E0 578 763 227 2E8 63E 105 620 4B0 733 1A2 3BD 61A 1D9 422
C = 78E 4AF 18F 644 4F0 2EC 70A 3FA 100 59B 6EB 7EE 2F5 6D1 63C 52F 573 169 219 2AC 625 6FB 69C 234
| | | | | | |
XOR = 643 71C 450 544 12E 0C0 7B3 4C6 706 7EF 4DD 08C 4BC 2B5 2BD 604 0A8 070 0B1 7B1 7ED 57E 555 3xx
## Resulting Seed Phrase
1=silent [643], 2=toe [71C], 3=meat [450], 4=possible [544], 5=chair [12E], 6=blossom [0C0],
7=wait [7B3], 8=occur [4C6], 9=this [706], 10=worth [7EF], 11=option [4DD], 12=bag [08C],
13=nurse [4BC], 14=find [2B5], 15=fish [2BD], 16=scene [604], 17=bench [0A8], 18=asthma [070],
19=bike [0B1], 20=wage [7B1], 21=world [7ED], 22=quit [57E], 23=primary [555]
final word between: gas [300] - lend [3FF]
correct final word: indoor [398]
# 12 Words XOR Seed Example Using 3 Parts
## Seed A (1 of 3)
1=romance [5DC], 2=wink [7DE], 3=lottery [420], 4=autumn [07D], 5=shop [635], 6=bring [0E1],
7=dawn [1BF], 8=tongue [723], 9=range [58E], 10=crater [194], 11=truth [74E], 12=ability [001]
A = 5DC 7DE 420 07D 635 0E1 1BF 723 58E 194 74E 001
## Seed B (2 of 3)
1=boat [0C6], 2=unfair [768], 3=shell [62B], 4=violin [7A2], 5=tree [73F], 6=robust [5DA], 7=open [4D9],
8=ride [5CB], 9=visual [7A7], 10=forest [2D9], 11=vintage [7A1], 12=approve [056]
B = 0C6 768 62B 7A2 73F 5DA 4D9 5CB 7A7 2D9 7A1 056
## Seed C (3 of 3)
1=lion [411], 2=misery [46D], 3=divide [1FF], 4=hurry [37D], 5=latin [3EB], 6=fluid [2CD], 7=camp [106],
8=advance [01F], 9=illegal [388], 10=lab [3E0], 11=pyramid [578], 12=unhappy [76A]
C = 411 46D 1FF 37D 3EB 2CD 106 01F 388 3E0 578 76A
## Calculation (XOR each hex digit)
A = 5DC 7DE 420 07D 635 0E1 1BF 723 58E 194 74E 001
B = 0C6 768 62B 7A2 73F 5DA 4D9 5CB 7A7 2D9 7A1 056
C = 411 46D 1FF 37D 3EB 2CD 106 01F 388 3E0 578 76A
| | |
XOR = 10B 4DB 3F4 4A2 2E1 7F6 460 2F7 1A1 0AD 597 73x
## Resulting Seed Phrase
1=cannon [10B], 2=opinion [4DB], 3=leader [3F4], 4=nephew [4A2], 5=found [2E1], 6=yard [7F6],
7=metal [460], 8=galaxy [2F7], 9=crouch [1A1], 10=between [0AD], 11=real [597]
final word between: toward [730] - tree [73F]
correct final word: trade [735]
- It's not possible to calculate the checksum of the final seed phrase on paper (needs SHA256).
- But it must start with the indicated digit(s). If using 24 words XOR, there will be only one
suitable choice offered by the Coldcard in that range (x00 to xFF),
once you have entered the other 23 words.
- The checksum of each of the XOR-parts protects the final result, assuming your XOR
math is correct.