1 · Problem
A seed phrase is a single point of failure. Kept in one place, it can be lost or found. Given to family, it can be misused or coerced out of them. Custodial services solve inheritance by holding the keys, which removes the reason for self-custody.
Inheritance needs three properties at once: nobody can act early, the right people can act later, and outsiders cannot even see who those people are.
2 · Design principles
- Non-custodial. Alagael never holds seeds, keys, letters or assets.
- Open standards. SLIP-39, tlock/drand, Safe, ERC-1167 and ERC-5564, so recovery never depends on Alagael.
- Local-first. One static page, usable offline; no backend, analytics or accounts.
- Token stays outside the vault. Gas is paid in ETH and assets stay ETH and ERC-20s in the user's Safe. The Alagael token is never required to split, seal or inherit.
- Verifiable. The app checks on-chain code against the build it ships.
3 · Privacy Robe: seed shares
A BIP-39 mnemonic is decoded to its entropy E (16–32 bytes). E is the SLIP-39 master secret. It is encrypted with a 4-round Feistel network whose round function is PBKDF2-HMAC-SHA256 (2500·2e iterations per round), then split with Shamir's scheme over GF(28) into n shares with threshold k (2 ≤ k ≤ n ≤ 16). Each share is encoded as 20 or 33 words with an RS1024 checksum.
E = BIP39⁻¹(mnemonic)
EMS = Feistel₄(E, passphrase, id, e)
{s₁ … sₙ} = Shamir_k(EMS) any k shares → EMS → E → mnemonic
k − 1 shares → no information about E
Recovery returns the original BIP-39 words, so any wallet can restore them. The implementation passes all 45 official Trezor SLIP-39 vectors.
4 · Herald: time- and people-locked letters
A letter M is encrypted with a random 256-bit key K using AES-256-GCM. K is split with SLIP-39 among Keepers. The ciphertext is then time-locked with tlock to a future round r of drand quicknet, a threshold BLS network (signatures on G1, RFC 9380 hashing) that emits a round every 3 seconds.
C = AES-GCM_K(M)
L = tlock(C, r) r = ⌊(t − genesis) / 3⌋ + 1
open(L) needs σ_r (the drand signature of round r, public only after time t)
and ≥ k Keeper shares of K
Sealing needs no network: the quicknet public key is pinned. Opening fetches σr from a relay or accepts it pasted by hand, and checks it against the public key before use. To move the date, the owner re-seals with the same K, rebuilt from the Keepers' existing shares.
5 · Vault: a dead man's switch for Safe
Assets sit in a Safe owned by the user. A DeadManSwitch contract (blockful, MIT) is enabled on it as both a module and a guard. As guard, its checkAfterExecution hook records every Safe transaction as activity. As module, it may call triggerTakeover for the heir once block.timestamp ≥ lastActivity + delay (delay ≤ 365 days). Takeover removes all other owners, makes the heir the sole owner with threshold 1, and pauses the switch permanently.
Each user deploys their own implementation and factory. The factory creates per-Safe ERC-1167 clones and initialises them in the same transaction, so no one can front-run initialisation. Owners can Tick (ping), change the heir or delay, and pause, all through Safe transactions.
6 · Private heir: ERC-5564 stealth addresses
The switch stores its heir in public storage. To keep the heir anonymous, the heir derives spending and viewing keys from a wallet signature and publishes only a meta-address (Pspend, Pview). The owner creates a one-time address from it:
owner: e ← random, R = e·G, h = keccak256(e·P_view)
heir address A = addr(P_spend + h·G) stores A in the switch
heir: h = keccak256(p_view·R), key a = p_spend + h (mod n)
R, the unlock key, travels in the Herald letter rather than on-chain. Without pview, A cannot be linked to the heir. The owner can send gas money to A from the Safe, so the heir never funds it from an identifying wallet. The derivation is compatible with ScopeLift's stealth-address-sdk.
7 · Threat model
| ADVERSARY | CAN | CANNOT |
|---|---|---|
| Thief with k−1 shares | Read those shares | Learn anything about the seed or letter key |
| Colluding Keepers before the date | Rebuild the letter key | Open the letter before round r |
| Chain observer | See the Safe, Ticks, switch and heir address | Link a stealth heir address to the heir |
| Heir, early | See the countdown | Take over before the delay, or while paused |
| Third party | Call checkAfterExecution | Reset the timer (only the Safe can) |
| RPC provider | See which Safe a wallet reads, and its IP | See seeds, shares, letters or heir keys |
8 · Limitations
- The DeadManSwitch contract has not been audited.
- A drand time-lock cannot be revoked; old sealed copies still open on their date with enough shares.
- A wrong SLIP-39 passphrase yields a different, valid seed by design.
- Heir keys require the heir's wallet to sign deterministically.
- Ticks are public and reveal activity timing.
- Alagael is not a legal will and does not replace one.
9 · Verification
- SLIP-39: 45/45 official Trezor vectors; BIP-39 vectors.
- Herald: full seal/open against a BLS chain with the quicknet scheme, including early, missing-share, wrong-share and forged-beacon cases.
- Contracts: 40 Foundry tests, 7 against the real Safe v1.4.1.
- Stealth: ScopeLift fixtures and 25 generate/derive cycles.
- End to end: the complete Vault flow in the app on a local chain, ending in a successful heir takeover.
10 · References
- SLIP-0039: Shamir's Secret-Sharing for Mnemonic Codes. github.com/satoshilabs/slips
- Trezor reference implementation and test vectors. github.com/trezor/python-shamir-mnemonic
- Gailly, Melissaris, Romailler. tlock: Practical Timelock Encryption from Threshold BLS. eprint.iacr.org/2023/189
- drand timelock encryption. docs.drand.love
- blockful, Dead man's switch module for Safe. github.com/blockful/deadman-switch-safe
- ERC-5564: Stealth Addresses. ercs.ethereum.org/ERCS/erc-5564
- ScopeLift, stealth-address-sdk. github.com/ScopeLift/stealth-address-sdk
- Safe smart account v1.4.1. github.com/safe-global/safe-smart-account
- Vitalik Buterin, Snowmoon (GPL v3). vitalik.eth.limo/snowmoon
Alagael