BlogInsights
Reproducible builds in hardware wallets: why "same source, same binary" matters

Reproducible builds in hardware wallets: why "same source, same binary" matters

K
Kamila
on 31 Aug 2026
Diagram showing reproducible build verification between hardware wallet source code and shipped firmware binary

A reproducible build means that anyone can take the published source code of a hardware wallet's firmware, compile it with the documented toolchain, and get a binary that is bit-for-bit identical to what the vendor ships. This matters because it is the only way to verify, rather than trust, that the firmware running on your device matches the code you can read and audit. Without it, open source is a transparency gesture rather than a security property.

Open-sourcing firmware is necessary but not sufficient. A vendor can publish clean source code on GitHub while shipping a binary compiled from a different, modified codebase. A reproducible build closes that gap. The verification chain works like this:

  1. 1
    The vendor publishes the exact source revision, compiler version, build flags, pinned toolchain, and frozen build environment.
  2. 2
    A third party clones the repository, runs the prescribed build, and produces an output binary.
  3. 3
    That binary is compared, byte for byte or hash for hash, against the binary the vendor distributes (or, in some designs, against a hash the device itself reports).

The mechanism is simple in concept but demanding in practice. Compilers are not naturally deterministic: timestamps, file ordering, path strings, and linker randomization can all produce different output from the same input. Achieving reproducibility means locking every variable in the toolchain, from the compiler binary down to the C library version and the locale settings.

Reproducible builds impose real engineering cost. Every toolchain upgrade, every dependency bump, every build-flag change must be tested for bitwise output stability. Development velocity slows. Smaller teams may lack the CI infrastructure to catch non-determinism regressions before a release ships. The benefit is proportional to the stakes: for a device that holds cryptographic keys, the cost is justified precisely because the alternative is blind trust.

Reproducible builds verify firmware, not hardware. They cannot tell you whether the secure element silicon matches its datasheet, whether the PCB layout introduces an undocumented debug port, or whether the factory loaded the correct binary onto the chip. They are one layer in a verification stack, not a complete answer.

Most hardware wallet firmware is cross-compiled: the build runs on a desktop (x86_64 Linux, typically) and produces an ARM binary for the device's microcontroller. The sources of non-determinism in that pipeline include:

  • Timestamps embedded by the compiler or linker. C compilers historically write __DATE__ and __TIME__ into object files. Reproducible builds either strip these or pin them to a fixed value.
  • File-system ordering. Directory traversal order can differ between machines and even between runs on the same machine. Build systems must sort inputs explicitly.
  • Randomized address-space layout. Some linkers randomize section placement. Reproducible builds disable this or use a fixed seed.
  • Floating-point determinism and locale. Subtle, but real. Different glibc versions or locale settings can alter printf formatting in generated code.

A common solution is a pinned toolchain and frozen build environment. The builder reproduces the documented environment, runs the prescribed build, and compares the SHA-256 of the output against the vendor's published hash. Keycard Shell uses CMake and Ninja with an ARM GCC toolchain pinned per release tag by tools/download-toolchain.sh, plus uv for the Python tools. Its firmware-hash.py script produces a firmware hash for comparison. The same verification model applies to its on-device database (token lists, chain registry, ABI selectors), using database-hash.py.

Not every hardware wallet that claims to be open source offers reproducible builds, and among those that do, the depth of documentation and verification varies.

AttributeKeycard ShellTrezor (Safe 3 / Safe 5)Coldcard (Mk4 / Q)BitBox02Foundation Passport (Core)Keystone 3 ProSeedSigner
Firmware open sourceYesYesSource-availableYesYesPartially (MH1903 vendor lib closed)Yes
Reproducible buildsYes (CMake + Python tooling)Yes (documented)YesYes (BitBox documented build-and-compare process)Yes (Core and Founder's Ed. only)Partial (Docker build, compare against device-displayed checksum, not against shipped signed artifact)Yes (since v0.7.0)
Hardware design publishedYes, complete for production (Gerbers, BOM, pick-and-place, editable CAD, STEP)Open but not complete for production (schematic PDFs, renders)Published but not licensed (schematics, BOM; no Gerbers, no CAD, no commercial-use grant)Published but not licensed (PDF schematics, BOM, PCB v2.10 x-ray; no Gerbers, CAD, or hardware licence)OpenOpen (circuit diagrams, BOM)Open DIY design using off-the-shelf parts
SE openness classOpen source SE (applet published)Fixed command set (Optiga Trust M)Fixed command set (ATECC608B/C + DS28C36B)Fixed command set (ATECC608A/B)Fixed command set (ATECC608B)Fixed command set (ATECC608B, DS28S60); closed source (MAX32520)Not applicable (no secure element)

Several things stand out. Keystone's build process lets a user build firmware and compare its checksum against what the device displays, but because the signed release artifact differs from the unsigned build output, the comparison is not byte-for-byte against the binary shipped on the device. Foundation Passport's reproducibility documentation covers only the Core and Founder's Edition, not the upcoming Prime. Ledger does not offer reproducible builds at all, and its secure-element OS (BOLOS) remains proprietary.

For Keycard Shell, the firmware build is reproducible. The Keycard applet has a different verification model inherent to JavaCard deployment: there is no downloadable on-card binary to rebuild and compare, and a fused production card does not expose its installed applet. The applet source, including the HD-wallet logic and signing policy, is published and auditable. Anyone who wants to remove trust in the factory-loaded binary can compile the open-source applet, load their own build onto an unfused Keycard for Developers, randomize the GlobalPlatform keys, and fuse the card themselves. This build-your-own secure-element route substitutes a user-controlled build for the vendor binary rather than trying to reproduce an inaccessible installed artifact.

Reproducibility is not a universal defense. It addresses a specific class of threat and is irrelevant to others.

  • Backdoored firmware (supply-chain or insider threat). This is the primary threat. A vendor, a compromised employee, or an attacker who gains access to the build pipeline could insert key-exfiltration code. Reproducible builds let anyone catch this by independently building and comparing.
  • Compromised update. Firmware updates are the ongoing version of the same risk. Devices that accept signed updates (most of the market) must let users verify each update against reproducible builds, not just the initial release. The Keycard Shell bootloader verifies update signatures. Updates require physical approval and use a dual-bank mechanism with rollback on failure, while the firmware updater blocks downgrades. Reproducibility lets a user verify the update content before flashing.
  • What reproducibility does not address. It says nothing about hardware-level attacks (probing, fault injection, side-channel analysis). Those are mitigated by the secure element's Common Criteria evaluation, not by build transparency. It also does not protect against logic bugs in legitimate firmware. In August 2026, TestMachine disclosed a command-interleaving flaw in Ledger's Ethereum app: a malicious host with WebHID access could start a second signing request while the first transaction remained on screen, causing the device to display one transaction while returning a signature for another. Ledger fixed the reported path in Ethereum app 1.22.2 and later recommended 1.22.3 or newer. A reproducible build would faithfully reproduce this bug because the legitimate source contained it. The attack also depended on a live bidirectional host channel during review; a one-shot QR signing flow gives the host no channel over which to race a replacement APDU. Clear-signing and transport isolation therefore address risks that reproducibility alone does not. (Disclosure coverage)

Keycard's architecture adds another layer relevant to this discussion. Public Keycards are fused during production: GlobalPlatform keys are randomized and the card is set to SECURED state, so no applet can be loaded afterward. This production state is not externally verifiable, but it fixes the signer's behavior at factory time and forecloses the category of post-deployment applet changes. A skeptic can instead use the substitution route: load a self-compiled applet onto a Keycard for Developers, randomize the GlobalPlatform keys, and fuse it. Ledger's own support team confirmed in 2023 that it has always been possible to write Ledger firmware that facilitates key extraction, and the Ledger Recover service, launched that October, put an opt-in seed-fragment export into production. An immutable card makes that class of change architecturally impossible.

Reproducible builds are a necessary condition for verifiable security, not a sufficient one. The remaining trust assumptions, even with perfect reproducibility, include:

  • Silicon trust. Every secure element rests on proprietary silicon. Keycard runs on an EAL6+ certified NXP JCOP4 P71, and that certification (months of physical attack testing by an accredited lab) is the closest thing to independent silicon verification that exists. But the chip design itself is not open.
  • Factory integrity. Reproducible builds verify what the binary should be. Verifying that the factory loaded that binary onto the chip is a separate problem. Keycard addresses this through a factory-signed ECDSA certificate in the Ident applet (challenge-response authenticity check) and, for the Shell, mutual authentication at shell.keycard.tech/verify with a verification counter that flags cloning attempts.
  • User behavior. No build system protects a user who does not read the transaction details on screen, shares their PIN, or loses both their card and their seed phrase.

Reproducible builds are one tile in a verification mosaic that also includes open hardware designs, certified secure elements, immutable signer code, and device authenticity checks. The value of each tile depends on the others.

What exactly does "reproducible build" mean for a hardware wallet?

It means anyone can take the published source code, use the documented compiler and build environment, and produce a firmware binary that is bit-for-bit identical to the one the vendor distributes. This proves the shipped firmware matches the auditable source, removing the need to trust the vendor's build pipeline.

Does open-source firmware automatically mean the build is reproducible?

No. Open source means the code is readable. Reproducibility requires additional engineering to eliminate non-determinism in the compiler, linker, and build environment. Many open-source hardware wallet projects do not achieve full reproducibility.

Which hardware wallets currently support reproducible builds?

Trezor, Coldcard, BitBox02, SeedSigner, Foundation Passport (Core and Founder's Edition), and Keycard Shell all offer documented reproducible builds. Keystone offers a partial process (build and compare against a device-displayed checksum, but not byte-for-byte against the signed release). Ledger does not offer reproducible builds.

Can I verify the Keycard Shell firmware myself?

Yes. The Keycard Shell repository uses CMake and Ninja with an ARM GCC toolchain pinned per release tag, plus uv for its Python tooling. Its firmware-hash.py script outputs a firmware hash to compare against the published release hash. A separate database-hash.py script does the same for the on-device token and ABI database.

Is the Keycard applet (secure element code) also reproducible?

The applet uses a different verification model. JavaCard does not provide a downloadable on-card binary to rebuild and compare, and a fused production Keycard does not expose its installed applet. The source is published and auditable. Anyone can compile it, load their own build onto an unfused Keycard for Developers, randomize the GlobalPlatform keys, and fuse the card themselves, eliminating the need to trust a vendor-supplied applet binary.

Does a reproducible build protect against hardware tampering?

No. Reproducible builds verify software, not hardware. Hardware-level protection comes from the secure element's Common Criteria evaluation (EAL6+ for the Keycard's NXP JCOP4 P71), device authenticity certificates, and, where available, open hardware designs that can be independently inspected.

How does immutability relate to reproducible builds?

They complement each other. A reproducible build lets you verify what code should be on the device. Immutability (as with fused public Keycards, which refuse any applet installation after manufacture) guarantees that the code cannot be changed afterward. Together, they cover both the initial state and the ongoing state of the signer.

Why don't all hardware wallets offer reproducible builds?

Achieving reproducibility requires significant engineering effort: pinning every dependency, eliminating compiler non-determinism, maintaining CI infrastructure, and documenting the process for third-party verifiers. Some vendors prioritize development speed or keep parts of their codebase proprietary, which makes full reproducibility either impractical or impossible.

Can a reproducible build guarantee there are no bugs in the firmware?

No. It guarantees that the binary matches the source, not that the source is correct. Bugs, logic errors, and design flaws in the published code will be faithfully reproduced. Code audits and formal verification address code correctness; reproducible builds address code authenticity.