Don't take chances rolling the dice.
An article on verifying ColdCard firmware, generating a 24-word seed phrase with dice, verifying the dice rolls, backing up the seed with a 3D printed Blockmit jig, and stress testing the backup.
Having a reliable backup of a seed phrase is an important part of self-custody. There are many ways to backup a seed phrase, but there is no way to get bailed out if the backup is lost or damaged beyond recognition. This level of radical responsibility can be shocking to some people; there is no Bitcoin customer support desk, or Bitcoin chargebacks, or Bitcoin card-lock feature, those who are righteous enough to take custody into their own hands take the full responsibility of their Bitcoin with them.
So why would someone be crazy enough to self-custody their bitcoin, with all the pitfalls, scams, & hackers? Wouldn't people be better off just leaving custody to the pros? The short answer is "no", the long answer is "fuck no!". In this article, I aim to demonstrate how to create and verify a simple, robust, and inexpensive backup so that you can rest assured that your bitcoin is better off in your hands, not the custodians.
Self-custody is an important aspect of censorship-resistance. Self-custody enables a person to interact with the world however they choose. Because of censorship-resistance, people have the freedom to donate to any cause they find value in, obtain goods & services that may not align with a banker's vision of the world, and secure their wealth in a manner that mitigates confiscation. There are several disadvantages when a person hands over control of their bitcoin to someone else:
Creates a permissioned relationship; the owner needs to ask the controller to send payment or make a trade or send the funds elsewhere. Permissioned relationships are problematic in that the controller, not the owner, has final say over how the bitcoin is used. This enables the controller to decide what is an appropriate use of the owner's funds, and if the controller doesn't like Wikileaks, for example, then the owner's donation won't be processed. Or if the controller doesn't like marijuana, then the owner may not be able to procure valuable medication. Through overreaching regulations, the government forces the controller to wield the governments vision of the world, forcing their objectives and their morals down the owner's throat. The controller is incentivized to uphold the government's vision of the world by censoring the owner's transactions, if the controller allows the owner to spend their bitcoin in a manner that is not consistent with government approved activities then the controller may face fines and penalties. The controller may even freeze and seize the owner's bitcoin with little or no explanation. Self-custody ensures the owner has the final say in how their funds are used. As the saying goes, "You don't like our life style, we don't like your laws".
Introduces counter party risk; what happens to the owner when the controller gets hacked, or mysteriously dies while on honeymoon, or files for bankruptcy? There is no FDIC or SIPC insurance on bitcoin, not from any service provider. There is no recourse to ensure the financial safety of the owner in the event the controller doesn't uphold their end of the bargain. There is no way for the owner to know exactly what the controller is doing with the bitcoin. Is it being invested in Yams? Was it just used to send the CEO's kids to spring break? What kind of risk is the owner unknowingly being exposed to by the controller's decisions? Self-custody shields the owner from someone's bad decisions. The controller may only have a fraction of the bitcoin they are "selling" or they may not have any at all, rehypothecation drives down market price as "bitcoin" get's bought & sold without affecting the actual markets.
Diminishes privacy through KYC; because most controllers in this context would be Money Services Businesses (MSB), they are required to comply with regulations stemming from the Bank Secrecy Act. These regulations stipulate that certain information must be collected from customers and that this information must be used in certain ways to inform the regulators and law enforcement about certain activities. The triggers and thresholds for which activities need to be reported are continuously becoming more minuscule and invasive, the most recent proposed rule change would require MSB's to automatically file a suspicious activity report on any customer sending $250.00 or more in bitcoin across a US border. I don't know about you, but to me, being reported to federal regulators and/or law enforcement for using Bitcoin to move $250.00 outside the US just defeats the purpose of Bitcoin. It's important to note that once a person uses a KYC service to obtain bitcoin, then there will be permanent record of that person buying X amount of bitcoin on Y date. Even if the person tries to take responsibility and self-custody their bitcoin, MSB's have record of that person possessing control of certain bitcoin address. Tracing bitcoin movements throughout the network is commonplace, so it is difficult for a person to disassociate their identity from their Bitcoin activity. Even if this isn't known publicly, it is known by someone who won't hesitate for a second to share that information if asked by law enforcement. Considering how the laws have changed in less than a year, making it a crime to gather in groups, go outdoors without a mask, and stand closer than 6ft to another person, it's becoming easier by the day to be classified as a criminal for leading a normal life. If you can't see how ever-encroaching laws will wind up turning your normal behavior into illegal activity sooner than later, then maybe censorship-resistant money isn't for you. Self-custody protects the owner from triggering suspicious activity reporting, non-KYC bitcoin assists the owner in remaining unidentified.
That's enough rambling from me about self-custody, let's get on with the article. The following describes how to verify the latest version of the ColdCard firmware is being used; how to generate a new seed with 256 bits of entropy using a 6-sided dice; how to verify that the ColdCard is actually deriving seed words from the user's unique dice rolls; how to backup that seed phrase into stainless steel washers using the Blockmit 3D printed jig; and finally, stress testing the backup. To get started, there are few necessities. If you're following along at home, gather the following items:
6-sided dice, preferably a balanced casino dice.
ColdCard with cable, power adaptor, & battery.
Letter & Number Stamp Set. 3mm (1/8").
Stainless Steel Washers. 8mm I.D. x 24mm O.D. x 2mm thick.
Stainless Steel Wingnuts. M8-1.25
Stainless Steel Bolts. M8-1.25 x 60mm.
I already had a notebook, pen, hammer, dice, and ColdCard at home so I spent about $65.00 gathering the other materials, which was enough to make four of these backups which come out to less than $17.00 each.
First, the firmware on the ColdCard can be updated if it isn't the latest version. The latest version can be found on ColdCard's website, here. I will demonstrate how I verify the firmware file on Windows using Kleopatra.
Basically what will be happening here is: download the CoinKite public PGP, save it as an .asc file, import that key to Kleopatra, then use that key to verify the clear-signed text file to confirm the hash value of the firmware file, and then finally independently generate a sha256 hash value to compare with the verified hash value online.
Navigate to https://coldcardwallet.com/docs/upgrade and click on the hyperlink with the latest firmware version, this should automatically start the download of the file.
Next, scroll down to the Advanced: Verify Your Downloads section. Once there, click on the hyperlink that reads:
Clicking on that hyperlink will bring the user to the plaintext html page which contains the public PGP key for peter@coinkite. Press ctrl+s to save the PGP public key.
Ensure that the "all files" type is selected so that the file can be saved with the .asc extension. If it is saved as a .txt file, it will not work. I simply named the file "email@example.com" and saved it to the same file location the firmware file was downloaded.
Once saved, the .asc file should have a lock icon, that is how the user knows it will work with Kleopatra.
Now that the PGP public key is saved to the PC, it needs to be imported to Kleopatra. If you have not used Kleopatra before, you will need to establish your own PGP key. For information on the GPG4Win suite of tools, including Kleopatra and to learn how to use them and download them, start here: https://www.gpg4win.org/documentation.html
In Kleopatra, click on the Import icon.
Navigate to the file location that the firstname.lastname@example.org file is saved and select that file. Kleopatra will generate a prompt informing the user that the PGP public key being imported will need to be certified. In order to verify this really is the right PGP public key, another source can be used such as https://keybase.io/DocHex. Now the fingerprint on the certification window can be compared with the fingerprint displayed on KeyBase.
Once the PGP public key has been imported it will be displayed in the list on Kleopatra.
Now that the PGP public key is imported and certified, navigate back to: https://coldcardwallet.com/docs/upgrade and scroll down to the Advanced: Verify Your Downloads section again. This time, click on the hyperlink for the clear-signed text file.
Clicking on that hyperlink will bring the user to the plain text html page which contains all of the ColdCard wallet firmware files and their corresponding SHA256 hash values. Again, hit ctrl+s to save this, ensure the file type is set to all types, and then save it to the PC as an .asc file.
Once the file is saved, then right-click and select More GpgEX options > Verify
Kleopatra will automatically find and use the CoinKite key and produce the valid dialog box. It's important to understand the visual difference between a valid result from a certified key, a valid result from a non-certified key, and a failed verification with a signature that doesn't match the public key.
Once the result is a valid signature, it can be said with confidence that the data contained in the clear-signed text is true and accurate. This means that the sha256 hash value next to the firmware version should be the same as the hash value of the .dfu firmware file that was downloaded earlier.
To generate and verify checksums like sha256, I use a program called HxD, which can be found here: https://mh-nexus.de/en/hxd/.
Open HxD and then select Open File and navigate to the file location that the .dfu firmware file is saved. Once that file is open, select the Analysis tab and choose Checksums from the drop-down menu, then select SHA-256 in the pop-up window.
Now the sha256 hash value has been independently generated on the downloaded .dfu firmware file. This hash value can be compared with the hash value on the clear-signed text webpage knowing that the information contained on that clear-signed text page was in fact signed by CoinKite which was verified with the PGP public key.
Now the .dfu file can be saved to a microSD card, inserted into the ColdCard and the update can be made to the latest version. If this is the first time turning on the ColdCard, then proceed through all the setup steps of establishing a PIN & anti-phishing words, ect.
Once the PIN is set on the ColdCard, navigate to Import Existing > Dice Rolls.
Once there, the "0 rolls" screen will always be displayed with the hash value, e3b0c... 27ae4... b855. The keys 1-6 can be used to enter the values that correspond to the results of each dice roll.
Write down each dice roll as it is entered into the ColdCard. Do as many rolls as it takes to satisfy your curiosity. In this example I did 100 dice rolls.
It's important to understand that it is not advisable to use your actual dice rolls to validate the dice-roll math, meaning that a user only should enter a few dice rolls, write them down, and generate the list of 24-words and then verify that information. This is only to satisfy one's curiosity that the ColdCard is producing a list of seed words that accurately represent the random dice rolls that the user entered. Once that curiosity has been satisfied, then the process should be repeated without typing the dice rolls into a computer. This could potentially result in loss of funds if any of the user's computer systems have been compromised. Typing seed words or dice rolls for an actual wallet that the user plans to fund is a bad idea. Simply use this information as a guide to understand that the ColdCard is doing what it purports to be doing and then do the actual wallet creation with information that is never typed into the computer.
With a pen & notepad, start rolling the dice, writing down the number, and entering the number on the ColdCard. Repeat 50 times for 128 bits of entropy or 99 times for 256 bits of entropy. Entropy is calculated by using log2(6^99) = 255.9.
Now that the dice rolls have been copied to the notebook and entered into the ColdCard, let's see what 24-word seed phrase the ColdCard comes up with. This will also be written down.
A BIP39 passphrase is not necessary to use while simply verifying the dice roll math. But I am going to cover the topic here because I think it is an important added security that should be used often. Adding a BIP39 passphrase can be a useful technique for adding an extra piece of security. With the BIP39 passphrase, it is like having a "25th word" in that this passphrase will also be required in addition to the 24-word seed phrase in order to restore the wallet.
The ColdCard will accept just about any string of characters the user wants to use as the passphrase. Each user will need to consider their own threat model and decide what a suitable passphrase will be. In this example, I am utilizing the Blockmit 3D printed jig to add a BIP39 passphrase that can be kept with the rest of the washers, meaning that I am using a random password generator to come up with a 16 digit password consisting of capital letters & numbers. 8 characters will be stamped into two separate washers.
You may not want to keep your passphrase stored with your 24-word seed phrase, you may want to store them separately since, combined, they could unlock your funds.
Using a 16-character passphrase allows me to designate two additional washers in the backup stack, P1 & P2 for passphrase part 1 and passphrase part 2. Each washer has enough room for 8 characters plus a 2 character identifier. When generating your own passwords, consider the chart below for determining how much entropy is suitable for your needs. Info-graphic shared by @wakaizashi. I recommend using passphrases with at least 82 bits of entropy since the projected brute force time with a computer cycling 100,000,000,000,000 guesses per second is 1,500 years. Using the same entropy equation, log2(36^16) = 82.7 bits of entropy, where 36 is the pool of characters to choose from and 16 is the length of the passphrase.
Once the BIP39 passphrase is applied to your main ColdCard wallet, the new wallet fingerprint will be displayed. This should also be documented since it can be used as a means to verify that you have entered the correct BIP39 phrase next time the wallet is accessed. The ColdCard wallet has no way of knowing if the user has entered the correct BIP39 passphrase or not. Any string of characters will generate a valid wallet, but if you enter the wrong BIP39 passphrase, then you will be looking at an empty wallet. Since the wallet fingerprint is 8 characters, I will also be stamping it into a washer to include with the backup.
Now that the dice rolls have been entered and the 24-word seed phrase has been copied down, the dice roll math can be verified. Everything done so far has been copied into the notebook:
ColdCard's guide on verifying Dice Roll math can be found here: https://coldcardwallet.com/docs/verifying-dice-roll-math
I did the following on a RaspberryPi in the CLI shell. The idea with the following command is to verify the sha256 has value of the entered dice roll. In my example, my dice roll was 100 numbers in length and the resulting hash value was a match compared to the one displayed on the ColdCard when I reached 100 rolls.
$ echo -n 123456 | sha256sum
Now it has been verified that resulting hash value displayed on the ColdCard does in deed represent the numbers from the entered dice rolls. But how do we know the hash value really generates the same 24 words?
The ideal environment to perform this checking is a computer running Tails - The Amnesic Incognito Live System, preferable without any network connection and no hard drives. Do not use your actual dice rolls on a normal desktop system as that will completely comprise the security of your Coldcard!
Simply navigate to: https://coldcardwallet.com/docs/rolls.py and save the script and then change directories to where you save it. Once there, run the following command with same dice rolls used on the first command:
$ echo 123456 | python3 rolls.py
The returned data will be a list of 24 words that should match the ones written in the notebook.
Now the 24-word seed phrase has been independently verified and the ColdCard can be trusted to be doing what it purports to be doing. Once your curiosity has been satisfied that everything is working as expected and advertised, now repeat the process with you actual dice rolls on the ColdCard and do not enter them into the computer when you're done.
Next, the 24-word seed phrase, the BIP39 passphrase, and the wallet fingerprint can be stamped into stainless steel washers for a simple backup that can withstand fire, flooding, and other harsh environments. Having a robust backup helps ensure that in the event the ColdCard is lost or stolen that the wallet can still be restored later from the information stamped into the backup washers.
To help with this, Blockmit came up with a really cool idea for a 3D printed jig. This jig allows the user to center the washer and the stamps in a clean way that keeps everything uniform and legible. Be sure to check out Blockmit's guide on using this jig here. Thank you to @Multicripto for originally bringing this awesome idea to my attention.
Make sure to source all the materials correctly, this jig was designed to use metric hardware. It is recommended to use double sided tape to keep the washers and jig aligned while stamping, but I didn't use any double sided tape and I was still very pleased with the results. My son helped supervise me to make sure I got the stamping done right.
Once finished, you will have a robust stainless steel backup of your 24-word seed phrase.
I was curious how well a stainless steel washer backup would be able to withstand extreme heat. So I heated up the backup until it was white hot and just starting to melt. Then took the washers apart and found that they were all still totally legible.
Then I decided to mix up some salt-water and throw the backup into the jar, I'm planning on letting it sit in the salt-water until Christmas (40 days) and then I'll open it and see if any corrosion has occurred. I'm not expecting much, since it is stainless steel, but I will post the results here at that time anyways.
40 days later...
After sitting in the salt-water mix for 40 days, I opened the jar on Christmas day. The stainless steel backup was rinsed off with fresh water and then taken apart and the individual washers were dried out. As I suspected, since this is stainless steel, there was no sign of deterioration. The information was still fully legible and the seed phrase was still 100% recoverable.
Thank you for reading! I hope this got you thinking about backing up your seed phrases with stainless steel washers. Self-custody is a way to interact with Bitcoin in a way that protects the user from the downfalls of third parties. There are tradeoffs to all choices, but I hope this made you realize that self-custody can be easy and is not frightening.
If you enjoyed this content, leave me a tip here: Donate.
This article can be found on Twitter as a thread here.