vaultless

passwords from thin air
oracle disconnected

Your passwords, remembered by nobody

There is no vault here. Nothing is stored, synced, or uploaded — not by us, not on this computer. Your passwords are worked out fresh each time from one phrase you remember and one thing you keep.

Deterministic derivation through a two-party oblivious PRF over ristretto255, with a verified oracle. No vault, no sync, no stored secret.

Choose your oracle

Your oracle is the half of the secret that lives outside your head. It can be a small device, or a square of paper. Both do exactly the same job.

Neither yet? — the demo runs the whole handshake with a pretend key, so nothing you see is a real password.

How does this work?

Think of your oracle as a keyholder that never tells anyone its key.

  1. You type your phrase. It stays in this browser — it is never sent anywhere.
  2. Your browser scrambles the phrase into a puzzle piece and disguises it, so even the oracle can't tell what you typed.
  3. The oracle stamps the disguised piece with its secret key and hands it back, playing a little animation while it works.
  4. Your browser removes the disguise and turns the result into your password.

Because the answer depends on both your phrase and your oracle, someone who steals only one of them gets nothing. And because the same two things always produce the same answer, there's no vault to lose, back up, or have stolen.

Worth knowing: if you lose your oracle, you lose the passwords it makes. And anything plugged into it while it's connected can ask it to stamp things, so unplug it when you're done.

vaultless is a deterministic password manager: every password is re-derived on demand from your master passphrase and a sub-index. Same two inputs, same password, every time. Nothing to sync, back up, or leak.

Pure deterministic derivation lets anyone who steals the passphrase recompute every password offline. vaultless closes that with a second factor that never leaves a physical device: a two-party oblivious PRF over ristretto255.

  1. The browser hashes passphrase‖index to a curve point P and blinds it with a random scalar r to get B = r·P — indistinguishable from random.
  2. B goes to the oracle (hardware over WebSerial, or the simulator).
  3. The oracle returns B′ = k·B, its public key Y = k·G, and a Chaum-Pedersen DLEQ proof that log_G(Y) == log_B(B′).
  4. The browser verifies the proof, checks Y against the key pinned on first use, unblinds S = r⁻¹·B′ = k·P, and expands it through HKDF-SHA256.
why this resists theft
  • The oracle only ever sees a blinded point — never the passphrase, and since protocol v3 not the account number either. A device on v2 firmware still requires the account number, so the browser retries once and says so in the trace; reflash to stop disclosing which account you are opening.
  • Without k, a stolen passphrase alone regenerates nothing.
  • Without the passphrase, a stolen or cloned oracle regenerates nothing either.
  • A swapped or tampered oracle is rejected: the DLEQ proof and the pinned public key have to agree.
  • The oracle auto-approves every request, so anything reaching its serial port can use it while it is plugged in.
  • The default firmware stores k in unencrypted flash — see firmware/SECURE_PROVISIONING.md.
  • Nothing is persisted: not the passphrase, not intermediate points, not the password.
source

github.com/Ak1ra00/SK

Build your own hardware oracle
parts list
  • LilyGO T-Display — ESP32 + 1.14" ST7789 LCD (135×240), 4MB flash
  • USB-C or micro-USB data cable (check your board revision)
  • No extra wiring — the display is on-board
on-board pinout
Display (ST7789)SPI: MOSI 19 · SCLK 18 · CS 5 · DC 16 · RST 23 · BL 4
ButtonsGPIO 35 / GPIO 0 — cycle the info pages and wake the screen. Requests are still auto-approved; a button never approves one.
BacklightGPIO 4 — sleeps after 5 minutes idle, wakes on a button or an incoming request
flashing

Easiest: plug the board in over USB and press Install firmware above. It uses ESP Web Tools over WebSerial — no local toolchain needed.

To build from source instead:

git clone https://github.com/Ak1ra00/SK
cd SK/firmware
pio run -e esp32dev -t upload

The oracle scalar k is generated on first boot from the hardware RNG and stored in NVS — it never touches the serial line, the browser, or this repo. Source: firmware/src/main.cpp.

WebSerial: checking… protocol: OPRF-RISTRETTO255-HKDFSHA256 · v2 (DLEQ)