Skip to content

M3 relay: v3 RemoteRestore + async-relay E2E#3

Merged
redsolver merged 1 commit into
mainfrom
m3-relay
Apr 27, 2026
Merged

M3 relay: v3 RemoteRestore + async-relay E2E#3
redsolver merged 1 commit into
mainfrom
m3-relay

Conversation

@redsolver

Copy link
Copy Markdown
Contributor

Validates the marquee M3 deliverable (async relay mode) end to end.

Implements paper-key disaster recovery against the v3 registry schema. Recipient flow:

  1. Enumerate blobs in the relay, try age decrypt each with the paper key. First blob that parses as a Node with KEY_SLOT_RECOVERY is a vault root, that gives us recovery_secret.
  2. Derive vault_id + recovery_signing_key.
  3. Look up (recovery_pubkey, vault_id) to get the device pubkey.
  4. Look up (device_pubkey, vault_id) to get the latest TN hash.
  5. Fetch + age-decrypt, verify KEY_SLOT_RECOVERY matches (substitution defence), restore.

Discover step is O(N) blobs. A registry-keyed breadcrumb to make it O(1) is a follow-up.

Validation

cargo test --test async_relay

Models device A → relay → device A offline → device B restores. Asserts SHA-256 of every restored file matches the original.

Implements paper-key disaster recovery against the v3 registry
schema. Recipient flow:

  1. Enumerate blobs in the relay, try age-decrypt each with the
     paper key. The first blob that decrypts and parses as a Node
     carrying KEY_SLOT_RECOVERY is a vault root (any snap of any
     vault for this paper recipient is fine here, we only need it
     to bootstrap recovery_secret).
  2. Derive vault_id and recovery_signing_key from the recovered
     secret (same derivation publish.rs uses).
  3. Lookup recovery registry entry at (recovery_pubkey, vault_id)
     to get the device's signing pubkey.
  4. Lookup vault registry entry at (device_pubkey, vault_id) to
     get the latest TN's encrypted blob hash.
  5. Fetch + age-decrypt that TN, verify its KEY_SLOT_RECOVERY
     matches what we discovered (substitution defence), restore.

The discover step is O(N) over the relay's blob count. For the M3
demo single-vault case the first hit is typically the encrypted TN
itself; for production-scale relays a registry-keyed discovery
breadcrumb is a follow-up.

Validation:

  cargo test --test async_relay
  # async_relay_via_remote_store ... ok

The test models the marquee M3 deliverable: device A backs up a
source tree to the relay, A's runtime is dropped (offline
simulation), B starts up with a fresh memory backend + the same
relay store + the shared paper key, RemoteRestore reproduces the
file tree, SHA-256 of every restored file matches the original.

Assisted-by: claude-opus-4-7
@redsolver redsolver merged commit 6e6a46f into main Apr 27, 2026
1 of 2 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant