Skip to content

Releases: hosseinpro/yubishard

v1.0.4 — Mobile header fixes

Choose a tag to compare

@hosseinpro hosseinpro released this 04 Sep 18:26

Layout fixes for narrow screens. The crypto, the share format and the stored record are
unchanged from v1.0.2 and v1.0.3, so there is no reason to re-do a backup: shares written by
any earlier version restore here unchanged, and shares written here read back in the older
ones.

The header no longer breaks on a phone

Below 720px the download strip and the top bar now wrap instead of squeezing: the strip's
"Download →" link drops to its own line under the message, and the origin notice moves beneath
the brand with a rule above it rather than being crushed into a sliver beside it. Both gain the
same side padding as the rest of the page.

The unsupported-browser notice is now a stop, not a warning

Opening YubiShard in a browser without the largeBlob extension — Firefox and Safari — used to
show a warning alongside the normal "keys enrolled here are tied to this hostname" line, which
read as something you could work around. It is now a single, plain statement that the browser is
not supported, naming Chrome on macOS or Windows 11.

v1.0.3 — a straight answer on trust

Choose a tag to compare

@hosseinpro hosseinpro released this 30 Aug 00:01

Documentation and presentation only. app.js, styles.css and the application markup are
byte-for-byte identical to v1.0.2 — the only code change is the version string in the footer.
Nothing about the crypto, the share format or the stored record moved, so there is no reason to
re-do a backup: shares written by any earlier version restore here unchanged, and shares written
here read back in the older ones.

A straight answer to "should I trust this with a seed phrase?"

The README now opens with it, because typing a recovery phrase into a web page is normally
terrible advice and the question deserves evidence rather than reassurance: that app.js contains
no fetch, no XMLHttpRequest, no WebSocket and no dynamic import, so after the page loads it
cannot make a network request at all; that nothing is written to localStorage, sessionStorage,
IndexedDB or a cookie; that there is no analytics and no third-party script; and that all of this
takes a minute to confirm with grep or the Network tab. It also states plainly what the tool
does not protect you from.

Why it is built the way it is

A new "Design philosophy" section explains the constraints — no dependencies, no package manager,
no build step, every line of JavaScript in one file — and the reasoning behind each. A dependency
you have not read is trust you have delegated, and a build step hides the artifact you actually
run. The cost is hand-written code proved against the official vectors; the benefit is that the
whole thing can be reviewed in an afternoon.

A demo, and clearer hardware guidance

The README now leads with a recording of a complete 2-of-3 backup, from entering a phrase through
writing three keys to the verified "Your backup is ready" screen. The firmware table has been
simplified to three rows with support marked directly, and the record-size figures were re-measured
and corrected against the real 900-byte cap.

v1.0.2 — verifiable tests, safer origins

Choose a tag to compare

@hosseinpro hosseinpro released this 29 Aug 20:47

Nothing about the crypto or the share format changed. Shares written by v1.0.0 or v1.0.1 restore
here identically, and a key written by this version reads back in the older ones.

The vector tests now run in CI

The SLIP-39 implementation was always checked against the official vectors, but you had to take
that on faith. node test/run.mjs is now in the repo and runs on every push — all 45 vectors from
trezor/python-shamir-mnemonic, the BIP-39 English vectors, BIP-32 test vectors 1 and 2,
RIPEMD-160, and split/recover round-trips. 132 checks, and the badge at the top of the README says
whether they pass right now. The test vectors are committed, so you can run it yourself offline.

The buttons now refuse an address that cannot work

Opening the page at 127.0.0.1 or over file:// warned you in the banner but still let you start
a backup — which would then fail at the key, partway in. "Back up a seed" and "Restore a seed" are
now disabled in any environment where a security key cannot be used, including a bare IP, a
non-secure context, or a browser without WebAuthn.

A security policy

SECURITY.md sets out how to report a vulnerability privately, and what is in scope. Private
vulnerability reporting is enabled on the repository.

Documentation

The README now explains where the randomness comes from — one source, crypto.getRandomValues,
and what actually depends on it — and which primitives are hand-written because Chrome ships no
native for them.

v1.0.1 — download from GitHub

Choose a tag to compare

@hosseinpro hosseinpro released this 29 Aug 20:43

Housekeeping release. No change to the crypto, the share format, or anything already written to
a key — shares made with v1.0.0 restore identically here.

Changed

  • The Download link now points at the source archive on this releases page, instead of a ZIP
    the page assembled in your browser. Fewer moving parts, and the file you get is the one GitHub
    built from the tag.
  • Removed the hand-written ZIP writer that made this possible — about 135 lines of CRC-32, DOS
    timestamps and container headers that no longer need to exist or be reviewed.
  • The footer now shows which version you are running and links to its release.

v1.0.0 — first release

Choose a tag to compare

@hosseinpro hosseinpro released this 29 Aug 20:43

First release.

YubiShard splits a wallet recovery phrase into standard SLIP-39 shares and stores one share on
each YubiKey, using the WebAuthn largeBlob extension. Any threshold of the keys rebuilds the
phrase; fewer reveal nothing at all.

What it does

  • Accepts a 12- or 24-word BIP-39 phrase, or a 20-word SLIP-39 share.
  • Splits it into a threshold scheme you choose — 3 of 5, say — and writes one share per key.
  • Verifies the backup by making you unplug each key and read the share back before finishing.
  • Restores from a threshold of keys, re-encoding BIP-39 entropy back into your original words.
  • Shows the BIP-32 fingerprint at every stage, so you can see which wallet you are handling.

The shares are ordinary SLIP-39 mnemonics — Trezor, Electrum, Sparrow, Rabby and BlueWallet all
read them.

Requirements

Chrome on macOS or Windows 11, and YubiKeys on firmware 5.7 or newer. The page must be served
over http://localhost or https — file:// cannot work, because a security key identifies a
site by its hostname.

Getting it

Download the source archive below, unzip it, and run serve.command (macOS) or serve.bat
(Windows). Three hand-written files, no dependencies, no build step — what ships is what you
read.

Verification

The SLIP-39 implementation is checked against all 45 official vectors from
trezor/python-shamir-mnemonic, plus RIPEMD-160, BIP-32 and BIP-39 vectors, and cross-checked
against Trezor's shamir-mnemonic package.

Read the README before trusting this with a real seed — in particular "Things you have to know",
which covers the PIN, the BIP-39/SLIP-39 asymmetry, and what a lost key does or does not cost you.