<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
     xmlns:content="http://purl.org/rss/1.0/modules/content/"
     xmlns:atom="http://www.w3.org/2005/Atom">
<channel>
  <title>Bitcoin Witness</title>
  <link>https://bitcoinwitness.org/blog/</link>
  <description>Verification guides, air-gap walkthroughs, and self-custody analysis.</description>
  <language>en</language>
  <atom:link href="https://bitcoinwitness.org/blog/index.xml" rel="self" type="application/rss+xml"/>
  <item>
    <title>How to verify your hardware wallet's addresses - ColdCard, Ledger, Trezor - without trusting the vendor's code</title>
    <link>https://bitcoinwitness.org/blog/verify-your-hardware-wallet/</link>
    <guid isPermaLink="true">https://bitcoinwitness.org/blog/verify-your-hardware-wallet/</guid>
    <description>Every hardware wallet vendor gives the same advice, and in our opinion it is excellent. Before you receive coins, confirm the address on the device's own screen.</description>
    <category>Verification</category>
    <pubDate>Fri, 18 Sep 2026 00:00:00 +0000</pubDate>
    <content:encoded><![CDATA[<p>Every hardware wallet vendor gives the same advice, and in our opinion it is excellent. Before you receive coins, confirm the address on the device's own screen. Keep following it.</p>
<p>However, notice what it checks. The device defends against malware on your online computer, particularly against swapping the address from your wallet app. Few consider that the device itself might have an issue at generation time. It may be introduced during a routine update, a new derivation standard implementation, or in a number of other, well-meaning ways. We have a page that walks through the failure modes a self-custody setup can have, the derivation path among them, and it is well worth any bitcoiner's time. See <a href="https://bitcoinwitness.org/verification-layer.html">the verification layer</a> page.</p>
<p>In other words, if the derivation logic is wrong or outdated, the screen will render the wrong address as confidently as the correct one. Checking the device against the vendor's companion app wouldn't help either: two programs from the same source agreeing is the proverbial witness vouching for itself.</p>
<p>Luckily, there is a check that can help. Export the extended public key, together with the derivation path and script type (the account's public data). Then re-derive the addresses with software that shares zero code with the original device, and compare the two lists. If your wallet exports a full output descriptor, even better, use that. It has the key, the path and the policy in one string, and it is the better thing to keep. If the lists agree, then the derivation has been confirmed by an independent implementation, not just the vendor's. Clean.</p>
<p>One should be aware of a privacy detail, though. The extended public key is privacy-sensitive. Anyone who obtains it can compute every address in the account, past and future, and watch them on-chain. So handle the exported file accordingly. It's generally better to delete it from any online machine when the check is done, and run the re-derivation offline if possible.</p>
<p>Step one: get the public data out of the device.</p>
<p>Coldcard writes it to a microSD card, so nothing needs to be plugged into a computer. This is a good thing.</p>
<p>Trezor would hand it over through its desktop app, as text and as a QR code.</p>
<p>In case of a Ledger device you will be retrieving it from an advanced panel. Also its app expects a network connection. So export once, move the file to your offline machine, and do everything after that step off the network.</p>
<p>Look at the first four characters of what you exported. The most common are <code>xpub</code>. A native SegWit account key usually begins <code>zpub</code>, and a nested SegWit key <code>ypub</code>. All three are ok. Some tools accept a <code>zpub</code> directly, others want it converted to plain <code>xpub</code> form with the path supplied separately. The conversion changes only the version bytes. Depth, parent fingerprint, child number, chain code and public key all survive it. In any case, keep the verified path and policy beside the key.</p>
<p>The standard account paths are <code>m/44'/0'/0'</code> for legacy addresses beginning with <code>1</code>, <code>m/49'/0'/0'</code> for nested SegWit beginning with <code>3</code>, <code>m/84'/0'/0'</code> for native SegWit beginning with <code>bc1q</code>, and <code>m/86'/0'/0'</code> for Taproot beginning with <code>bc1p</code>. Receive addresses extend the account path with <code>/0/0</code>, <code>/0/1</code>, <code>/0/2</code> and so on. Change addresses extend it with <code>/1/0</code>, <code>/1/1</code>. An account-level key plus its policy and path is everything the independent side needs. A descriptor is that same information in one long string.</p>
<p>Step two: re-derive. The tool must share no code with the original device and none with the vendor's companion app. Otherwise the comparison collapses back into the device agreeing with itself.</p>
<p><code>xpubverify</code>, the free MIT-licensed script on the Bitcoin Witness GitHub, was written for this check. It is plain Python, standard library only, short enough to read in full before you run it. Give it the exported public key and it prints receive and change addresses. Ten and five by default, more if you ask. On the Bitcoin Witness station (see the demo in the <a href="https://bitcoinwitness.org/preview/index.html">preview section</a>), the same check is Extended Public Key Verification. Import the key and the air-gapped machine derives the addresses and writes a <a href="https://bitcoinwitness.org/index.html#report">timestamped Confidence Report</a>. Since the verification tools don't touch the network, they won't show you a balance. They tell you which addresses belong to the key, not what those addresses hold.</p>
<p>You can rehearse the whole procedure with public test vectors. <code>xpubverify</code> will do this via its <code>--self-test</code> flag. It runs its embedded test vectors and exits.</p>
<p>Step three: compare, properly. Put the derived list next to the device, then read the full string. A partial visual match is not an identity check. Compare every character.</p>
<p>Don't stop at index 0. Confirm the first receive address, and a few more further down the list. We know it may be boring, but especially if you plan to use these addresses long term, it is well worth your time. Where your device offers an address explorer or another safe way to display one, verify at least one change address from the <code>/1/</code> branch. Change addresses are where a derivation bug hides longest, since coins flow to them without you necessarily reading one. If the same key and policy produce the same full addresses at several receive and change indices, the derivation has been cross-checked by independent code. Note the fingerprint, the account path, the policy, the indices you tested and the date beside your backup records, and treat them as privacy-sensitive.</p>
<p>The agreement between the two confirms that the public key the device handed you derives, under standard BIP32 math and the policy you named, the addresses you tested.</p>
<p>It does not opine, nor should it, on how well the seed inside the device was generated, how safely the device stores it, or whether the signatures leak anything when you spend. Those are separate questions. Some have verification procedures of their own. Others, like the randomness behind a seed that was generated elsewhere, cannot be verified after the fact. We compiled and visualized some examples on <a href="https://bitcoinwitness.org/verification-layer.html">the verification layer</a> page. What it does help address though is one specific issue. That your receive addresses were independently verified, and ideally on an offline computer.</p>
<p><em>Bitcoin Witness. Verify your self-custody setup.</em></p>]]></content:encoded>
  </item>
  <item>
    <title>Why this blog exists</title>
    <link>https://bitcoinwitness.org/blog/why-this-blog-exists/</link>
    <guid isPermaLink="true">https://bitcoinwitness.org/blog/why-this-blog-exists/</guid>
    <description>Good morning! The internet is not short on things to read, so we appreciate you spending a click.</description>
    <category>Verification</category>
    <pubDate>Wed, 09 Sep 2026 00:00:00 +0000</pubDate>
    <content:encoded><![CDATA[<p>Good morning! The internet is not short on things to read, so we appreciate you spending a click.</p>
<p>Below is a recap of why we are building Bitcoin Witness.</p>
<p>On a good Wednesday morning about a year ago, I went looking for a way to verify my own bitcoin backup without trusting anyone, and discovered there wasn't an easy way of doing that. Every check I could run relied on something or somebody: the device that generated the keys, that device's proprietary firmware, a second black-box device, a software on an internet-connected machine, an company's reputation, an influencer's track record.</p>
<p>On the other side, there was my own ability to get Ian Coleman's open-source tool (excellent, go try it) onto an Air-Gapped, clean offline machine without one misstep along the way. Each of those... let's call them methods is good on their own. However, none of them is easy and completely trustless. After deliberating for a few days, I built a tool for myself. I then added open-source password management software, Ian Colemans BIP39 tool and PSBT signing ability, support for older standards and seeds just in case someone needs it. Turns out all of it was useful for others as well.</p>
<p>So this is the what and the why.</p>
<p>Now, onto some details.</p>
<p>Verifying your own cryptocurrency backup is the financial equivalent of inspecting the parachute before you jump. Today, though, it mostly comes packed by someone you'll never meet, in a language you may not read. And the instructor has gone home too. That should be a double-click, yet, somehow, in 2026 it isn't.</p>
<p>The raw material is all there: guides for hardware wallets, threads on steel seed plates, enough derivation code on GitHub to fill a long weekend and have your family notice you weren't around (true story). What none of it answered was the question that sounds simple: do the 24 words from my cold wallet produce the addresses they should? Is my multisig setup correct? Can I confirm it without trusting the device that made them or anything that has ever touched a network, no middleman or black-box? I couldn't find a clean answer, so I wrote one and I am in the final weeks of testing to eventually publish it.</p>
<p>Most people I asked about this issue turned out to be living with it too. Very few of my friends who hold their own keys have verified them beyond just retyping them in the same place that had generated them. Less so against totally independent code, offline. Clearly the reason wasn't laziness. The tooling has always assumed you were a developer. The verification was never double-click-easy.</p>
<p>That assumption is what we in this blog set out to take apart. We will do some personal exposé, and also technical posts. Some tutorials (anyone?). Why retyping your seed into the same device proves very little, how to pull trustworthy entropy from a pair of dice. How the code for Bitcoin Witness itself is built as a glass box: plain text that you (or your favorite AI) can read before trusting a line of it. No binaries, firmware, compilers, obfuscation. Simple text that runs on your offline device you bought yourself.</p>
<p>And yes, some historical references too. We love history.</p>
<p>Bitcoin Witness will not recover a seed you've lost, unlock a passphrase you've forgotten, nor revive a device already compromised. Bitcoin Witness does one job: manage and verify the existing cryptographical standards on a hardened, encrypted, airgapped generic hardware device (Raspberry Pi). That's the whole design.</p>
<p>Where it should be dull, the design is gloriously dull. No network calls, nothing of ours that runs that you cannot read first, in place. There is no new cryptogaphy (if you see one anywhere - run away) or exagerrated claims: BIP32, BIP39, BIP84, and secp256k1 are public, heavily reviewed. The mathematics under them is older than Windows 98, and rather better tested too. The project bundles established, openly auditable tools like Electrum, Sparrow, and Ian Coleman's BIP39 tool instead of reinventing them. What we built is the workflow that ties them into something you can check yourself.</p>
<p>One piece is public today <a href="https://github.com/BitcoinWitness/xpubverify" target="_blank" rel="noopener noreferrer">xpubverify.py</a>, a short MIT-licensed script, confirms your addresses from your wallet's public key alone, no seed required. We intend to keep publishing more as we finish our internal testing. The specifications, downloadable examples and the Preview on this website are based on the real code as of September 2026.</p>
<p>Not your keys, not your coins, and, it turns out, not necessarily your addresses either. The standards have been public for over a decade. What was missing is an independent verification layer that checks and reports, offline, itself fully verifiable. We will be back shortly with more updates.</p>
<p><em>Bitcoin Witness is coming. Join the waitlist at bitcoinwitness.org.</em></p>]]></content:encoded>
  </item>
</channel>
</rss>
