Horcrux

Digital Estate Planning
Guide
Create Vault
Recover Vault
Technical Docs

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.

How it works

1
Choose a folder of files to protectAll the files in that folder get zipped and encrypted with a secure passphrase. The original files are not changed or deleted.
2
Generate a passphrase using diceYou roll five physical dice five times to create a random passphrase. No one — not even you — needs to remember it.
3
Split the key among trusted peopleThe passphrase is split into “shards” — pieces of the key. Each person gets a USB drive with their shard. Alone, a shard is useless. Together, any k people can unlock the vault.
4
To recover: open this file and use the Recover tabGather the required number of shard holders, combine their shards, select the encrypted vault file, and unlock.
The encrypted vault file (.enc) is safe to store anywhere — cloud storage, email, a shared USB drive. Without the required number of shards it is mathematically impossible to open.

Creating a vault — step by step

  1. Click the Create Vault tab above.
  2. Enter a Vault ID — a short name for this vault, 2–20 characters, uppercase letters, digits, and hyphens (e.g. 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.
  3. Click Choose folder and select the folder you want to protect.
  4. Choose Total shards (how many USB drives to make) and Threshold (how many are needed to unlock). A common choice is 5 shards with a threshold of 3 — any 3 of the 5 people can unlock the vault.
  5. Roll 5 physical dice five times and type each roll into the passphrase generator to build a 5-word diceware passphrase.
  6. Click Create Encrypted Vault.
  7. Save the shard folders:
    • Chrome or Edge: a folder picker appears. Pick a folder, and the tool writes one Shard_N directory per shard directly into it.
    • Firefox or Safari (or if you cancel the folder picker): the results page shows a Download button for each shard. Click them one at a time. Each button produces a small zip (Vault_XX_Shard_N.zip) containing that shard’s three files.
  8. Copy each shard onto its own USB drive — one USB per shard. If you got a zip per shard, unzip it onto the USB; the USB should end up with three files at the top level: Vault_XX.enc, XX_N.txt, and restore_instructions.txt.
  9. Copy the Horcrux tool onto every USB too, so holders can recover the vault years from now without having to find the tool online. Copy these five files to each USB alongside the shard files:
    • horcrux.html
    • horcrux-core.js
    • diceware.js
    • eff_wordlist.js
    • fflate.js
    Total size about 225 KB — negligible on any USB drive.
Important: After each USB is prepared and delivered, delete every local copy of the shard files and any downloaded zips from your computer. If shards remain on your machine, anyone with access to it could reconstruct the passphrase and decrypt the vault — defeating the purpose of splitting the key among multiple people. See “After distribution” below for deletion instructions.

Recovering a vault — step by step

  1. Gather at least the required number of shard holders together (or their USBs).
  2. Put any one of the USB drives into a computer and open horcrux.html from it (double-click, or right-click → Open with → any browser). No internet needed. No installation needed.
  3. Go to the Recover Vault tab.
  4. Set Threshold (k) to the number shown on any USB’s restore_instructions.txt.
  5. For each holder’s USB, open their 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.
  6. Click Combine Shards. The 5-word passphrase should appear. If it doesn’t, check the pasted shards for typos. You can supply more than the threshold — the tool will tolerate one typo when you do.
  7. Under Encrypted Vault File, pick Vault_XX.enc from any of the USBs (they’re all identical copies).
  8. Click Unlock Vault. On Chrome or Edge you choose where to save the recovered files; on Firefox or Safari the files download as a zip.
If the tool shows an orange “Legacy vault format” message after a successful recovery, the vault was created by an older version. The files came through fine — but consider creating a new vault with the recovered files to upgrade to the authenticated Horcrux1 format.

After distribution — deleting the originals

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.

Windows

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.

macOS

Drag the vault folder to the Trash, then choose Empty Trash from the Finder menu.

Linux

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 {} \;

Your original files are never modified by Horcrux. The encrypted vault is a separate copy. You are free to keep or delete your originals as you normally would.

Technical documentation for implementors, auditors, and the curious.

Architecture

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://.

ComponentImplementationNotes
AES-256-CBCWeb Crypto API (SubtleCrypto)Hardware-accelerated on most platforms. Custom Horcrux1 container; legacy Salted__ (OpenSSL) accepted on read.
PBKDF2-HMAC-SHA256Web Crypto API600,000 iterations (Horcrux1), derives 80 bytes (32 AES key + 16 IV + 32 HMAC key). Legacy reads use 100,000 iterations / 48 bytes.
HMAC-SHA256Web Crypto APIAuthenticates the vault container (encrypt-then-MAC) in Horcrux1 format. Verified in constant time via crypto.subtle.verify.
SHA-256Web Crypto APIUsed for the vault manifest (file integrity checksums, checked on every recovery).
Secret SharingPure JavaScript (BigInt)Shamir’s Secret Sharing Scheme over GF(2^deg). See below.
XTEA DiffusionPure JavaScript64-bit block cipher used as a pseudo-random permutation on the secret before splitting.
Zip/Unzipfflate libraryDEFLATE compression. Can be vendored locally for offline use.
Random Numberscrypto.getRandomValues()OS-level CSPRNG. Used for salt generation and polynomial coefficients.
Diceware WordlistEmbedded JavaScript7,776-entry EFF Large Wordlist. See credits below.

Shamir’s Secret Sharing Scheme

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).

Splitting

  1. The passphrase is encoded as UTF-8, right-justified into a deg/8 byte buffer, and optionally diffused using 40·n rounds of XTEA (for deg ≥ 64).
  2. The diffused secret becomes the constant term (coefficient 0) of a random polynomial of degree k−1, where k is the threshold.
  3. Coefficients 1 through k−1 are generated from the OS CSPRNG.
  4. The polynomial is evaluated at x = 1, 2, …, n using Horner’s method in GF(2^deg). Each evaluation produces one shard.

Combining

  1. Given k shard points (xi, yi), the constant term is recovered via Lagrange interpolation in GF(2^deg).
  2. The XTEA diffusion is reversed.
  3. The resulting bytes are decoded as UTF-8 to recover the passphrase.

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:

Field arithmetic

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.

XTEA Diffusion Layer

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).

Encryption Format

Horcrux1 (current)

New vaults use an authenticated container with an HMAC-SHA256 tag over the entire ciphertext:

OffsetLengthContent
08 bytesHorcrux1 (ASCII magic)
816 bytesRandom salt
24remainder − 32AES-256-CBC ciphertext (PKCS#7 padded)
end − 3232 bytesHMAC-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.

Legacy (OpenSSL, read-only)

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.

OffsetLengthContent
08 bytesSalted__ (ASCII magic)
88 bytesRandom salt
16remainderAES-256-CBC ciphertext (PKCS#7 padded)

Vault Manifest

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.

Shard String Format

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.

File Output

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.

Compatibility

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.

Credits & References

Shamir’s Secret Sharing Scheme — Reference Implementation

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.

EFF Diceware Wordlist

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.

Cryptographic Primitives

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.

Third-Party Libraries

fflate — High-performance zip/unzip for JavaScript by 101arrowz. MIT licensed. https://github.com/101arrowz/fflate

About the Name

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.

Click to choose folder — or drag it here

Enter dice rolls one at a time. Roll 5 dice and type the 5 numbers (1–6).

1. Shard Handling

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.

2. Encrypted Vault File
Click to choose .enc file
3. Unlock Vault