MarvelousPrivacy

Documentation

MarvelousPrivacy is a privacy workspace: a browser-local encrypted file vault, a read-only transaction inspector, a clearly bounded private-pool integration for Robinhood Chain, and a local activity record. This page explains what each part does, what it stores, and where its limits are. The README in the repository carries setup details and test results.

Overview

Encrypted vault

Key hierarchy

passphrase ──PBKDF2-HMAC-SHA-256 (600,000 iterations, 128-bit salt)──▶ KEK
KEK        ──AES-256-GCM (96-bit IV, AAD = header)──▶ wraps the 256-bit vault key
vault key  ──AES-256-GCM (fresh 96-bit IV per record, AAD = record id + purpose)──▶ file bytes, file metadata

What stays observable

Anyone with access to the browser profile can see that a vault exists, how many records it holds, the size of each ciphertext, the KDF parameters and the salt. Ciphertext length equals plaintext length plus a 16-byte tag, so file sizes are inferable. Timestamps are inside the encrypted metadata, but IndexedDB itself may record modification times.

Storage

Records live in IndexedDB (database marvelousprivacy, stores vault, files, activity). Clearing site data removes them. Settings offers persistent storage where the browser supports it, which protects against automatic eviction but not against deliberate clearing.

Backup format

An export is a JSON document (*.mpvault.json). It contains exactly what IndexedDB contains, base64-encoded. It is readable only with the passphrase.

{
  "format": "marvelousprivacy-vault-backup",
  "version": 1,
  "exportedAt": "2026-10-02T12:00:00.000Z",
  "vault": {
    "vaultId": "uuid",
    "createdAt": "ISO-8601",
    "kdf":    { "name": "PBKDF2", "hash": "SHA-256", "iterations": 600000, "salt": "base64 (16 bytes)" },
    "cipher": { "name": "AES-GCM", "keyLength": 256, "ivLength": 96, "tagLength": 128 },
    "wrappedKey": { "iv": "base64 (12 bytes)", "data": "base64 (32 + 16 bytes)" }
  },
  "files": [
    { "id": "uuid", "order": 1,
      "meta":    { "iv": "base64", "data": "base64 — AES-GCM(JSON{name,type,size,lastModified,addedAt})" },
      "content": { "iv": "base64", "data": "base64 — AES-GCM(file bytes)" },
      "ciphertextBytes": 12345 }
  ]
}

Authenticated data

Import validation

Before any key derivation: format id and version, vault id shape, KDF name/hash, iteration count within 100,000–5,000,000, salt 16–64 bytes, cipher parameters, IV lengths, ciphertext sizes (≤ 25 MB + tag per file, metadata ≤ 16 KB), duplicate ids, file count ≤ 10,000 and total size ≤ 400 MB. Then the passphrase must unwrap the key and every file's metadata record must authenticate. Only then is the current vault replaced, in one transaction.

Transaction review

Supported networks: Robinhood Chain (4663), Robinhood Chain Testnet (46630), Ethereum (1), Arbitrum One (42161).

Stealth addresses (ERC-5564)

The supported privacy tool on Robinhood Chain. The ERC-5564 Announcer (0x55649E01B5Df198D18D95b5cc5051630cfD45564) and ERC-6538 Registry (0x6538E6bf4B0eBd30A8Ea093027Ac2422ce5d6538) singletons have code on chain 4663 since block 8,283,577; the Announcer bytecode is byte-identical to the Ethereum and Arbitrum deployments, and both contracts are a Sourcify match on 4663 (submitted 2026-10-02 with the mainnet standard-JSON input, compiler 0.8.23).

Private pools

Status: integration not configured (checked 2026-10-02). The survey covered Privacy Pools (0xbow), RAILGUN, Robinhood Chain ecosystem listings, Privacy Hood (self-described zk pool), VeiledHood (self-described shielded vault). None publishes a verified, audited pool deployment on Robinhood Chain (4663) or its testnet (46630): Privacy Pools and RAILGUN are not deployed here; Privacy Hood is in a testnet phase without published contracts; VeiledHood's contracts are unverified and its withdrawals need an operator signature (custodial ledger). The pools page probes these addresses live (eth_getCode + Sourcify) instead of showing a placeholder form, and src/lib/pools/registry.ts lists the six dependencies a legitimate integration needs. No pool deposit or withdrawal control exists; no custody contract of our own exists.

Activity and settings

Limitations

Integration sources

ItemSource
Robinhood Chain ids, RPC, explorerdocs.robinhood.com/chain/connecting; public endpoints from chainlist (publicnode, dRPC)
Verified ABIsSourcify API v2 — sourcify.dev/server/v2/contract/{chainId}/{address}; chains 1, 42161, 4663, 46630 listed as supported
Selector candidatesOpenChain signature database — api.openchain.xyz
Standard interfacesEIP-20, EIP-721, EIP-1155, EIP-2612, WETH9, Uniswap Permit2, Multicall3, ERC-4337 EntryPoint v0.6/0.7/0.8, Uniswap Universal Router
Privacy Pools (0xbow)https://docs.privacypools.com/deployments — Ethereum Mainnet
RAILGUNhttps://docs.railgun.org — Ethereum, Polygon, BNB Chain, Arbitrum One, Sepolia
Robinhood Chain ecosystem listingshttps://docs.robinhood.com/chain — No privacy protocol listed for chain 4663 / 46630
Privacy Hood (self-described zk pool)https://www.privacyhood.org/whitepaper — Testnet phase per its whitepaper; no contract addresses, audit or source published
VeiledHood (self-described shielded vault)https://www.veiledhood.com/ — Contracts on 4663 but unverified; off-chain ledger with operator-signed withdrawals (custodial); own FAQ: testnet, not audited
PBKDF2 work factorOWASP Password Storage Cheat Sheet (PBKDF2-HMAC-SHA256: 600,000)

Setup and deployment

pnpm install
pnpm dev            # http://localhost:21500
pnpm test           # vitest: crypto, format, engine, decoder
pnpm typecheck && pnpm lint && pnpm build
pnpm smoke          # route + header checks against a running server

Environment variables are optional and server-side only: ROBINHOOD_RPC_URL, ROBINHOOD_TESTNET_RPC_URL, ETHEREUM_RPC_URL, ARBITRUM_RPC_URL (private RPCs tried before the public ones), RESOLVE_OVERRIDE (DNS pins for developer machines). NEXT_PUBLIC_SITE_URL is the only public variable and only feeds metadata. There are no secrets in the browser bundle, no analytics and no remote scripts; the Content-Security-Policy is nonce-based and set per request.

Documentation · MarvelousPrivacy