Horcrux lets you lock your important files inside an encrypted vault and split the key among trusted people — so that no single person can unlock it alone.
Everything runs in your browser. Nothing is sent to the internet. No installation required.
MOM-2026 or RETIREMENT-DOCS). Pick something descriptive so shard holders can tell one vault from another if they ever hold shards for more than one.Shard_N directory per shard directly into it.Vault_XX_Shard_N.zip) containing that shard’s three files.Vault_XX.enc, XX_N.txt, and restore_instructions.txt.horcrux.html from it (double-click, or right-click → Open with → any browser). No internet needed. No installation needed.restore_instructions.txt.XX_N.txt file (where XX is the vault ID and N is the shard number) and paste the line into one of the shard boxes. Optionally, type the 6-character Check code from that USB’s restore_instructions.txt into the small box next to the shard — a green ✓ confirms a clean paste and a red ✗ flags a likely typo before you proceed.Vault_XX.enc from any of the USBs (they’re all identical copies).Once you have confirmed that your vault was created correctly and each shard holder has their USB drive, you should delete the shard folders from your computer. They contain copies of the encrypted vault and are not needed locally.
Use your operating system’s standard delete. The shard folders do not contain your original files — only the encrypted vault and the shard string, which is useless without the others.
Right-click the vault folder and choose Delete, then empty the Recycle Bin. For extra assurance, open PowerShell and run cipher /w:C:\path\to\folder to overwrite the free space.
Drag the vault folder to the Trash, then choose Empty Trash from the Finder menu.
Delete from your file manager, or from a terminal: rm -rf ~/horcrux/XX (replace XX with your vault ID). For extra assurance: find ~/horcrux/XX -type f -exec shred -u {} \;
Technical documentation for implementors, auditors, and the curious.
Horcrux runs entirely in the browser. There is no server component. The HTML file, JavaScript modules, and embedded wordlist can be served statically, opened from a USB drive, or loaded via file://.
| Component | Implementation | Notes |
|---|---|---|
| AES-256-CBC | Web Crypto API (SubtleCrypto) | Hardware-accelerated on most platforms. Custom Horcrux1 container; legacy Salted__ (OpenSSL) accepted on read. |
| PBKDF2-HMAC-SHA256 | Web Crypto API | 600,000 iterations (Horcrux1), derives 80 bytes (32 AES key + 16 IV + 32 HMAC key). Legacy reads use 100,000 iterations / 48 bytes. |
| HMAC-SHA256 | Web Crypto API | Authenticates the vault container (encrypt-then-MAC) in Horcrux1 format. Verified in constant time via crypto.subtle.verify. |
| SHA-256 | Web Crypto API | Used for the vault manifest (file integrity checksums, checked on every recovery). |
| Secret Sharing | Pure JavaScript (BigInt) | Shamir’s Secret Sharing Scheme over GF(2^deg). See below. |
| XTEA Diffusion | Pure JavaScript | 64-bit block cipher used as a pseudo-random permutation on the secret before splitting. |
| Zip/Unzip | fflate library | DEFLATE compression. Can be vendored locally for offline use. |
| Random Numbers | crypto.getRandomValues() | OS-level CSPRNG. Used for salt generation and polynomial coefficients. |
| Diceware Wordlist | Embedded JavaScript | 7,776-entry EFF Large Wordlist. See credits below. |
The passphrase is split using polynomial interpolation over a finite field GF(2^deg), where deg is determined by the byte length of the secret (minimum 64 bits, maximum 1024 bits, always a multiple of 8).
Shamir’s scheme by itself produces some output for any k shard points; wrong shards yield garbage. The recovery UI guards against this in two ways:
All arithmetic operates in GF(2^deg) using irreducible polynomials from a hardcoded table of 128 pentanomials (degree 8 through 1024). Multiplication uses the standard shift-and-XOR algorithm. Inversion uses the Extended Euclidean Algorithm with modular reduction of the Bezout cofactor.
Before splitting, the secret bytes are permuted using a keyless XTEA block cipher. This is a diffusion layer, not an encryption layer — it ensures that similar secrets do not produce similar shares. The cipher operates on sliding 8-byte windows across the secret buffer, with 40·n passes (where n is the byte length). The key is implicitly all zeros.
This layer is identical to the one used in ssss (B. Poettering, 2005), though the byte serialization order differs (big-endian in Horcrux, mixed-endian via GMP in ssss).
New vaults use an authenticated container with an HMAC-SHA256 tag over the entire ciphertext:
| Offset | Length | Content |
|---|---|---|
| 0 | 8 bytes | Horcrux1 (ASCII magic) |
| 8 | 16 bytes | Random salt |
| 24 | remainder − 32 | AES-256-CBC ciphertext (PKCS#7 padded) |
| end − 32 | 32 bytes | HMAC-SHA256 tag over magic ‖ salt ‖ ciphertext |
Key derivation: PBKDF2-HMAC-SHA256 with the 16-byte salt, 600,000 iterations, producing 80 bytes. The first 32 bytes are the AES key; the next 16 bytes are the CBC initialization vector; the last 32 bytes are the HMAC key.
Decryption verifies the HMAC tag in constant time before attempting AES decryption. A wrong passphrase or a modified ciphertext both surface as a single failure mode; the two cannot be distinguished.
Vaults produced by earlier versions of this tool and by the Python edition (horcrux.py v1.2) use the OpenSSL Salted__ format with PBKDF2 at 100,000 iterations and no HMAC. Horcrux1 reads those files with a visible UI warning; writing the legacy format is no longer supported. To upgrade a legacy vault, recover it and create a new vault with the same files.
| Offset | Length | Content |
|---|---|---|
| 0 | 8 bytes | Salted__ (ASCII magic) |
| 8 | 8 bytes | Random salt |
| 16 | remainder | AES-256-CBC ciphertext (PKCS#7 padded) |
Inside the encrypted zip, a Vault_Manifest.txt file records the SHA-256 of every other file:
64-hex-hash relative/path/to/file
64-hex-hash …
On recovery, after the ciphertext decrypts and the zip unpacks, every file’s SHA-256 is recomputed and compared to the manifest. A mismatch (or a missing / unexpected entry) aborts recovery with a generic “vault has been tampered with or is corrupted” message — no files are written to disk. This is a secondary integrity gate behind the Horcrux1 HMAC tag; for legacy Salted__ vaults (no HMAC), the manifest is the only integrity check.
Each shard is a string of the form:
VaultID-N-HEX
Where VaultID is the user-chosen identifier (2–20 characters of A–Z, 0–9, and hyphens; no leading, trailing, or consecutive hyphens), N is the shard number (1-based), and HEX is the uppercase hexadecimal representation of the polynomial evaluation yN in GF(2^deg), zero-padded to deg/4 characters. The join parser splits from the right, so the VaultID itself may contain hyphens.
On Chromium-based browsers (Chrome, Edge, Opera), Horcrux uses the File System Access API to write shard folders directly to a user-chosen directory — one folder per shard containing Vault_XX.enc, the shard’s .txt file, and restore_instructions.txt.
On browsers without that API (Firefox, Safari) or when the user cancels the directory picker, the results page falls back to per-shard Download buttons. Each button produces one flat zip (Vault_XX_Shard_N.zip) containing the same three files, ready to copy directly onto a USB drive. The user paces the downloads manually — no multi-download prompt.
Shard strings (Shamir split/combine) remain interchangeable with the Python edition (horcrux.py). Vault ciphertext is no longer interchangeable: this edition emits the authenticated Horcrux1 format, which horcrux.py v1.2 cannot decrypt. Legacy Salted__ vaults written by horcrux.py remain readable here (with a UI warning).
Shards are not compatible with B. Poettering’s ssss-split/ssss-combine tools due to differences in polynomial structure (monic vs. random leading coefficient) and byte serialization order in the XTEA diffusion layer.
The GF(2^deg) field arithmetic and irreducible polynomial table used in Horcrux are based on the mathematical approach described by B. Poettering in ssss (Shamir’s Secret Sharing Scheme), version 0.5, Copyright 2005–2006.
Project homepage: http://point-at-infinity.org/ssss/
ssss is licensed under the GNU General Public License v2. Horcrux does not contain ssss code — the SSSS implementation was written independently using the same underlying mathematics (Lagrange interpolation over binary extension fields). The irreducible polynomial table is a mathematical constant and is not copyrightable.
The passphrase generator uses the EFF Large Wordlist, a list of 7,776 words designed for generating strong diceware passphrases.
Published by the Electronic Frontier Foundation (EFF) on July 18, 2016.
Source: https://www.eff.org/dice
The wordlist is embedded in eff_wordlist.js for offline use. It is redistributed under the Creative Commons Attribution 3.0 US license.
AES-256-CBC — NIST FIPS 197 (Advanced Encryption Standard) and SP 800-38A (Block Cipher Modes). Implemented via the browser’s Web Crypto API (SubtleCrypto).
PBKDF2-HMAC-SHA256 — RFC 8018 (PKCS #5 v2.1). 600,000 iterations for the Horcrux1 format; 100,000 iterations when reading legacy Salted__ vaults. Implemented via the browser’s Web Crypto API.
HMAC-SHA256 — RFC 2104 (HMAC) and FIPS 180-4 (SHA-256). Authenticates the Horcrux1 vault container in an encrypt-then-MAC construction.
SHA-256 — FIPS 180-4. Used for the per-file integrity manifest (Vault_Manifest.txt).
XTEA — Wheeler, D. and Needham, R. (1997). “Tea extensions.” Technical report, Computer Laboratory, University of Cambridge.
fflate — High-performance zip/unzip for JavaScript by 101arrowz. MIT licensed. https://github.com/101arrowz/fflate
A Horcrux is a fictional object from J.K. Rowling’s Harry Potter series. In the books, a Horcrux holds a fragment of a person’s soul — hidden away so that the whole can only be restored by reuniting the pieces. This tool borrows the metaphor: your vault’s passphrase is split into fragments (shards) distributed among trusted people, and only by bringing enough fragments together can the original secret be recovered. No single shard holder can unlock the vault alone, just as no single Horcrux tells the whole story.
Paste each holder’s shard into the long box. The short Check box is optional — if you type in the 6-character Check code printed on that holder’s USB, a green ✓ confirms a clean paste and a red ✗ flags a typo before you combine.