
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:
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:
__DATE__ and __TIME__ into object files. Reproducible builds either strip these or pin them to a fixed value.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.
| Attribute | Keycard Shell | Trezor (Safe 3 / Safe 5) | Coldcard (Mk4 / Q) | BitBox02 | Foundation Passport (Core) | Keystone 3 Pro | SeedSigner |
|---|---|---|---|---|---|---|---|
| Firmware open source | Yes | Yes | Source-available | Yes | Yes | Partially (MH1903 vendor lib closed) | Yes |
| Reproducible builds | Yes (CMake + Python tooling) | Yes (documented) | Yes | Yes (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 published | Yes, 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) | Open | Open (circuit diagrams, BOM) | Open DIY design using off-the-shelf parts |
| SE openness class | Open 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.
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:
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.