Zero Server Contact
WebCrypto API  ·  AES-256-GCM
01 Select File to Encrypt
Drop any file here, or click to browse
Your file never leaves this browser — zero server contact
02 Passphrase
key = PBKDF2(pw, salt, 300k) ⊕ HKDF(SHA256(geo + geoSalt + fp))
03 Lock Radius
Decryption only succeeds within this radius of the lock point
04 Device Binding
factor selection override
⚠ Unstable factors may cause permanent decryption failure after display changes.
05 Capture Lock Location
GPS
Signal No fix — press Capture
GPS accuracy is low. Move near a window or step outside and re-capture.
— Files sealed here can only be opened at this location. Coordinates are hashed with a random geo-salt and are not stored in the bundle.
01 Load Sealed File
Drop a .labyrinth file here, or click to browse
Only files sealed by Labyrinth are accepted
02 Passphrase
Device binding factors are read from the sealed bundle — same factors applied automatically.
03 Your Current Location
GPS
Signal No fix — press Capture
GPS accuracy low — decryption may fail even at correct location.
— Lock location is cryptographically hidden. This map shows only your current position.
I
Password → PBKDF2-SHA256 (300,000 iterations)

Passphrase stretched with a random 256-bit PBKDF2 salt. 300k iterations resists GPU brute-force for years. Iteration count stored explicitly in bundle for future migration.

password + pbkdf2_salt → PBKDF2(SHA-256, 300 000) → 32-byte pw_key
II
Location + Geo-Salt → Geo Key — offline brute-force impossible

GPS coordinates rounded to chosen precision, combined with a random 16-byte geo-salt stored in the bundle, user-selected device fingerprint factors, and timezone. The geo-salt means even perfect coordinate knowledge yields zero information without it.

"{lat_r}::{lon_r}::{geo_salt_hex}::{tz}::{fp}" → SHA-256 → 32-byte geo_key
III
Combine → HKDF (domain-separated key derivation)

Password key and geo key concatenated and run through HKDF-SHA256 with domain separation. Neither factor alone can decrypt.

[pw_key ‖ geo_key] → HKDF(SHA-256, "labyrinth-geo-vault-v1.0") → 32-byte final_key
IV
AAD — Metadata Cryptographically Authenticated

Filename, filesize, and precision hashed and passed as AES-GCM Additional Authenticated Data. Any metadata modification is detected at decryption — even with the correct key.

SHA-256({filename, filesize, precision, version:1}) → aad → AES-GCM additionalData
V
AES-256-GCM + Memory Wipe

AES-256-GCM, random 96-bit IV, 128-bit auth tag. Raw file buffer zeroed with fill(0) after encryption. Wrong password and wrong location produce identical generic rejection.

file → AES-256-GCM(final_key, iv, aad) → ciphertext + auth_tag → rawData.fill(0)
Protected Against
ScenarioStatus
Stolen ciphertext alone✓ Protected
Stolen password alone✓ Protected
File + password, wrong location✓ Protected
Offline coordinate brute-force✓ Geo-salt
Bundle metadata tampering✓ Detected (AAD)
Lock location read from file✓ Not stored
Known Limitations
Attack VectorStatus
GPS spoof + geo-salt + coords⚠ Requires bundle access
Full device compromise (root)✗ Not covered
Browser memory forensics⚠ Mitigated (fill(0))
Adversary physically at same location⚠ Partial
Bundle Contents — Zero Location Data
Nothing geographic is stored. The .labyrinth bundle contains: encrypted ciphertext · PBKDF2 salt · AES IV · random geo-salt · filename · filesize · timestamp · precision setting · device binding factor IDs (not values) · versioned crypto parameters. No coordinates, no timezone, no raw fingerprint values. Opening the file in a text editor reveals nothing about where it was sealed.
AES-256-GCM PBKDF2-SHA256 HKDF AAD Auth Zero Servers Geo-Salt Coords Not Stored Configurable Binding Memory Wiped Versioned Params
Device Factor Stability Reference
FactorStabilityChanged ByRecommendation
User AgentHighMajor browser updateAlways include
LanguageVery HighManual language changeAlways include
PlatformMediumOS reinstall, dual-bootOptional
CPU CoresHighHardware change onlyOptional (low entropy)
Screen ResolutionLowMonitor, scaling, fullscreenAvoid for critical files