Skip to main content

On Saturday, Ledger said the quiet part out loud: “Ledger can confirm that one of the impacted users’ devices contained an unauthorized hardware implant.” Not a phishing site, not a fake app, not a firmware bug. A physical object, added to a signing device, somewhere between a factory in France and a customer in Southeast Asia. On-chain researchers put the losses at $86m to $93m across more than 300 wallets on Bitcoin, Ethereum and Tron. Ledger has confirmed neither figure.

The device came from CryptoBilis, a reseller operating in Indonesia, Malaysia and the Philippines. It was an authorised reseller. That word is doing an enormous amount of work, and almost none of it is the work people think it does.

This is the ninety-third unasked half of fairness, and it is the one that sits underneath all the others. Every provably fair system on earth verifies forward from a key. Not one of them can verify backward to it.

TL;DR

  • Ledger confirmed an unauthorised hardware implant in a device sold through an authorised reseller, with third-party loss estimates of $86m to $93m across 300+ wallets.
  • Ledger’s own developer documentation describes the genuineness check as a WebSocket session to Ledger’s HSM backend that returns a single field, isGenuine, typed boolean. One bit, no artefact, nothing you can re-check tomorrow or show to anyone else.
  • Ledger already ships world-class supply-chain provenance: Sigstore attestations, a public transparency log, pre-install trust enforcement. For its npm package.
  • I verified that package’s provenance end to end in four HTTP requests with no account and no permission: the exact commit, the exact workflow file, the exact log entry, timestamped 3 minutes 38 seconds after the commit landed.
  • A draw can be perfectly provable and still pay a key somebody else generated. Fairness and ownership are different properties, and only one of them has a proof.

Give Ledger its due first

Ledger moved quickly and said more than it had to. It confirmed the implant rather than hiding behind “under investigation”. It told buyers from that reseller not to initialise unused devices and to move to a fresh seed if they already had. It asked the reseller to halt sales, and CryptoBilis did. It published a bounty address at bounty@ledger.fr and reminded people that it will never ask for a 24-word recovery phrase. It also said the thing most companies would have buried: “Security isn’t static and this incident underscores why we continuously review and strengthen our distribution and anti-tamper processes.”

It went further and called for “broader industry improvements in chain-of-custody practices”. That is the correct diagnosis, publicly stated, by the company with the most to lose from stating it. Ledger has sold more than seven million devices since 2014 and its infrastructure was not breached here. The failure was in the distance between a factory and a kitchen table.

Binance co-founder Changpeng Zhao has alleged on X that the attackers bought the reseller outright. That is unverified, CryptoBilis has not responded publicly, and this post does not rest on it. The confirmed implant is enough.

What an implant actually has to defeat

Here is the part the wire coverage skipped, and it is in Ledger’s own developer documentation, free to read, no NDA required.

A Ledger signer is not one chip. It is two. The documentation is blunt about what they are: “One is secure; the other has JTAG enabled and acts as a proxy.” The Secure Element does the cryptography. A separate STM32 microcontroller does everything else, because the Secure Element has no inputs or outputs of its own. The MCU “acts as a simple router between the SE and the peripherals”, meaning the screen, the buttons and the USB port. The protocol between them is called SEPROXYHAL, and the docs describe it as “the SE’s only channel for communicating with the outside world”.

Read that again with an attacker’s eyes. Every character the Secure Element shows you, and every button press it believes you made, travels over a link to a chip that Ledger itself describes as the non-secure one, with its debug port enabled. The published pairings are concrete: Nano X runs an STM32WB55 or STM32WB35 alongside an ST33J2M0; Nano S Plus an STM32F042 with an ST33K1M5C; Stax and Flex an STM32WB35 with an ST33K1M5C.

An implant does not need to break a certified Secure Element. It needs to sit somewhere on the path the architecture document already tells you is not the secure part. And the Secure Element’s own firmware, per the same page, “is under NDA and therefore closed source”, so the one component everybody is being asked to trust is also the one component nobody outside Ledger can read.

None of that is a scandal. It is a sane engineering trade-off, published openly. It matters because it tells you exactly what a genuineness check would have to cover to mean what buyers think it means.

The check that exists returns one bit

Ledger does ship a genuineness check, and it is cryptographically real. The documentation for the Device Management Kit describes how it works: “The secure connection is established between the connected device and Ledger HSM backend service via WebSocket.” The Genuine Check Device Action “checks the genuineness of the connected device. It returns true if the device is genuine, and false otherwise.”

The documented output is one field. Its name is isGenuine. Its type is boolean.

Consider everything that verdict does not come with. No statement of what was checked. No identifier for the device that was checked. No timestamp. No signature you can keep. No record you can query again in six months, after the money has gone, to establish what the check said on the day you set the thing up. No artefact you can hand to an insurer, a lawyer, or a stranger on the internet. The user interaction that authorises the connection is, per the same page, “only requested once per device reboot”.

And the verdict is produced by a server belonging to the company that made the device. That is not an accusation of dishonesty. Ledger has no incentive to lie about this and every incentive not to. It is a statement about the shape of the evidence: a claim with no supporting record is not a proof, it is a reference. You are not verifying a device. You are being told a result by someone who verified it for you.

Ledger already ships the good version of this. For its npm package.

Now the part that made me stop and check twice.

Ledger’s developer portal publishes 315 pages. Exactly one of their URLs contains the word “attestation”. It is not about hardware. It is titled “NPM package attestation verification”, and it describes the supply-chain assurances Ledger provides for @ledgerhq/ledger-wallet-provider, a JavaScript library.

What does a JavaScript library get that a $150 signing device does not? Sigstore. The registry “issues a short-lived certificate that binds the publisher’s identity to the specific release” and “records the attestation in a public transparency log for tamper-evidence”. The docs recommend pnpm over npm specifically because pnpm “compares trust before extraction” and blocks the install, while with npm “verification is reactive; install and any postinstall scripts have already run”. There is a named error for a provenance downgrade, ERR_PNPM_TRUST_DOWNGRADE, and a recommended policy setting, trustPolicy: no-downgrade, that blocks an entire dependency tree if any package in it has less evidence behind it than an earlier release did.

That is a serious, modern, well-reasoned supply-chain posture. It is also, line for line, a description of everything the physical channel lacks. There is no pre-install block on a cardboard box. There is no transparency log of devices.

The npm page even carries the exact caveat that is this post’s thesis, stated by Ledger about its own software: “This proves who published the package and when, and links the artifact to its source/build instructions. It does not review or audit the package’s code.” And the warning box: “Provenance does not guarantee code safety. It only proves origin and build details so you can decide whether to trust the package.”

Ledger understands perfectly that provenance and safety are different things. In software it publishes the provenance and warns you it is not safety. In hardware the industry has spent a decade selling provenance, “buy direct, buy from an authorised reseller”, as though it were safety, with no provenance record attached to the claim.

I verified the package in four requests. From Prague. With no account.

I did not take the documentation’s word for it, because the point of provenance is that you do not have to.

Request one, the npm registry: @ledgerhq/ledger-wallet-provider has 21 published versions and 20 of them carry attestations. The single exception is 1.0.0, the first stable release, which predates the policy. The current release is 2.0.0, 415 files, 6,132,786 bytes unpacked.

Request two, the attestation bundle: two attestations, an npm publish attestation and a SLSA provenance statement. The provenance names the builder as LedgerHQ/ledger-button-public/.github/workflows/release_npm.yml@refs/heads/main and the source material as that repository at commit 0f103606844bd9ec3d130d6b0b9bb4ad0dd0bdd3.

Request three, Sigstore’s public transparency log: both entries are there, unauthenticated, to anybody. Log index 3051765393, integrated at 08:48:08 UTC on 2 October 2026. Log index 3051899954, integrated at 08:56:47 UTC the same morning.

Request four, GitHub: the repository is public, the commit exists, it is dated 08:44:30 UTC on 2 October 2026, it touches 300 files and its message is “Release v2.0.0”.

Three minutes and thirty-eight seconds between a commit landing in a public repository and a tamper-evident, timestamped, third-party record of the build that came from it. No login. No support ticket. No relationship with Ledger whatsoever. If Ledger went out of business tomorrow, those records would still answer the question.

Now point the same curiosity at a Ledger on a desk and ask what you can establish about where it has been. Nothing. There is no request you can make, to anyone, that returns a signed, timestamped, independently logged statement about that object. The best available answer is a boolean from a WebSocket, and the second-best is a receipt from a shop.

A verdict is not a record

This is the distinction the series has not made before, and it is sharper than “hardware wallets can be tampered with”, which everyone already knew.

We have written about hardware failures here repeatedly. Coldcard’s entropy bug was a defect its own maker did not know about. BitBox’s patch was a remedy that only protects the people who install it. Trezor’s shipping breach was a third party holding your data outside the system. Coldcard’s dice let users contribute entropy, which is participation rather than verification.

Every one of those is about whether a check happened or whether a fix got applied. This one is about the form of the evidence. The check happened. It was cryptographic. It returned true. And it left nothing behind.

Compare the two columns. The software side gives you a signed statement written into a log somebody else operates. The hardware side gives you a yes. The software side can be re-verified by a stranger in 2031. The hardware side cannot be re-verified by its own owner the following morning.

We argued in “Your Draw Is Provable Forever. Who Is Storing the Proof?” that proof retention has drifted from the protocol layer, where it is enforced, to the commercial layer, where it is merely likely. Device provenance is one step worse off than that. It never had a protocol layer to drift out of. There is no record to lose, because none is emitted.

“Authorised” is a fact about a company, not about an object

CryptoBilis was an authorised Ledger reseller. The devices moved through a channel the manufacturer had blessed. The advice that every hardware wallet guide has given for years, buy direct or buy authorised, was followed, and it did not help.

Authorisation is a contract between two companies. It establishes commercial terms, trademark use and recourse. It is not an inspection, and it does not travel with the box. Ledger’s remedial list after the incident is to review authorised reseller controls, advance hardware protections and push the industry on chain of custody. The first of those strengthens the commercial layer, which is precisely the layer that was intact the whole time.

And look at the timing problem in Ledger’s own safety advice: “Do not initialize unused devices.” That instruction exists because initialisation is irreversible. The seed is generated once. In npm terms, it is the postinstall script, and Ledger’s own documentation already warns about this exact failure mode in the software case: with npm, “verification is reactive; install and any postinstall scripts have already run”. With pnpm, trust is “compared before extraction”.

The hardware channel is permanently stuck on the npm behaviour, with no pnpm available. You cannot block the install. You can only run it and check afterwards, and afterwards is after your key exists.

Why this is the unasked half, and what it does to a draw

Provable fairness is a claim about a function, not about a person.

Take our own stack, which is as good as this gets. A player calls a contract. The contract requests randomness from Chainlink VRF. The coordinator verifies the cryptographic proof on-chain before the callback is allowed to run, so an invalid proof is not a dispute, it is a failed transaction. The winner is computed in that callback, and the payout lands in a block anyone can read forever. Last week I measured 15,740 of those requests on Base over eight days and matched every single one to its fulfilment.

Every step of that verifies forward. Given a key, did this output come from it? Given a proof, does it check out? Given a block, did the payout happen? The chain is magnificent at all three.

Now ask the backward question. Where did the winner’s key come from? Who else has seen it? Was it generated by a device in a sealed box or by a device with something extra soldered into it?

The chain has no answer and no field in which an answer could be written. An address is twenty bytes. It carries no origin, no manufacturer, no birth certificate. For a contract you can fetch verified source and read what it does. For an externally owned account there is nothing to read, by construction, and that is a feature of the design, not an oversight.

So here is the uncomfortable sentence. A Satoshie draw can execute perfectly, prove itself completely, pay exactly the address the verifiable random function selected, and still deliver the money to a thief, if that address’s key was known to somebody before the player ever bought a ticket. Every proof in the system remains valid. Nothing in the audit trail looks wrong, because nothing is wrong, in the only sense the system can measure.

Fairness and ownership are different properties. We can prove one of them. The other one is a story about a box.

Where Satoshie actually stands

What we can say: the code that picks the winner is deployed and readable before you commit a stake. The coordinator that verifies the randomness is named in that code. The proof is checked on-chain, not asserted in a dashboard. The payout is a transaction. None of those steps requires you to trust a statement from us, and none of them produces a bare boolean. Every one of them leaves a record that outlives the company, which is the entire reason we build this way.

What we cannot say, and will not pretend: we have no idea where your key came from. We cannot detect a compromised signing device, we would not know if a winner’s key had been copied in a warehouse, and we have no mechanism to make you whole if it had been. Our verification surface begins at the moment a transaction arrives and extends forward from there, which is the same limit we described from the custodian’s side three posts ago, pointed in the opposite direction.

We are also not immune to the structure. Our own operational keys are held on hardware procured through ordinary commercial channels, like everyone else’s, and we can produce exactly the same quality of evidence about those devices as you can about yours, which is to say a boolean.

Honest limits

First: the implant is confirmed in one device, and Ledger says all confirmed cases to date trace to the single reseller. The loss figures come from a pseudonymous on-chain researcher and have not been confirmed by Ledger or by any court. The argument here does not depend on the number. It would hold identically if the total were $86,000.

Second: I am comparing an npm package to a physical object, and they are not equally hard problems. Build provenance for software is a solved research problem with a decade of tooling behind it. Attesting the physical history of a mass-manufactured object through retail distribution is genuinely difficult. The criticism is not that Ledger has failed to solve it. It is that the industry markets the unsolved problem as solved, using a word, “authorised”, that promises a property nobody is checking.

Third: a transparency log for devices would create real problems of its own, starting with privacy. A per-unit public record of who bought which serial number is a gift to the people conducting the physical attacks we wrote about in August. The right design is probably a signed provenance statement you hold rather than a public registry anyone can search, and I am describing a gap rather than shipping a specification.

Three questions worth asking

Of any hardware wallet, including ones I would still recommend over the alternative: when your software says my device is genuine, what artefact does that check produce, and can I read it a year from now without asking you?

Of any platform that calls itself provably fair: does your proof cover anything that happened before the transaction arrived, and if not, say so in the same sentence as the word “provably”.

Of yourself, before the next draw: if the key that would receive your winnings had been copied before you generated it, what in your setup would look any different today?

Ledger is right that the industry needs better chain-of-custody practices. It already knows what one looks like. It published the specification, in its own documentation, for a JavaScript file.

📷 Photo by Jay on Unsplash

Valentina Ní Críonna

Author Valentina Ní Críonna

More posts by Valentina Ní Críonna