// zero-knowledge password login · SRP-6a

Log in.
Tell nothing.

Mainnet live checking… Status: Ticker (placeholder, no token exists):
// the working app

Register, log in, then try to cheat.

Every message below is the real request or response, as it crossed the network. Look for your password in it — it isn't there.

Signed in as · server proved itself (M2 ✓)

1Account

Pick a throwaway username and password. The password is stretched and turned into a proof in this tab; it is never sent.

    3What the server stores

    The complete record for your account, as the server returned it. This is all it has.

    Register or log in to see your record.

    5Bind a Solana address optional

    After logging in you can attach a public Solana address to this demo account and read its live balance from mainnet. Never paste a seed phrase or private key — Nopass never needs one.

    Log in first — the server only releases or changes the bound address after a valid SRP proof.

    2On the wire

    Exactly what this tab sent and received. Click any shortened hex value to expand it.

    Nothing sent yet.
    Never sent: your password, the stretched key x, the secret a, the shared value S and the session key K. They exist only in this tab.

    4Replay a captured login

    Pretend you recorded every byte of the last successful login. Can you log in again with it? These buttons send the recording back to the real server.

    Log in once to capture a transcript.

    6If the server were breached

    A thief with your record can't log in with it, but can guess passwords offline: each guess costs a full PBKDF2 run plus one 2048-bit exponentiation. Try one against your own verifier.

    Register or log in to load your verifier.
    // how it works

    A proof instead of a password

    1. Registration makes a verifier. Your browser picks a random salt, stretches username:password with PBKDF2-SHA-256 (600,000 rounds) into x, and sends only salt and v = g^x mod N. Recovering x from v is the discrete-log problem in a 2048-bit group.
    2. Login is a fresh exchange each time. The browser sends a one-time public value A = g^a; the server answers with the salt and its own one-time B = k·v + g^b. Both sides derive the same secret S — the browser from the password, the server from the verifier — without ever sending it.
    3. The browser proves it first. It sends M1, a hash over A, B, the salt, the username and the shared key. Only someone who knew the password could compute it, and it is bound to this session's random B.
    4. Then the server proves itself. It answers with M2 = H(A | M1 | K). A fake server that doesn't hold your verifier can't produce it, so the browser can detect an impostor.
    group RFC 5054 2048-bit, g = 2, H = SHA-256, PAD = 256-byte big-endian k = H(N | PAD(g)) x = H(s | PBKDF2-SHA256(I ":" P, s, 600000, 32)) browser only v = g^x mod N sent once, at registration A = g^a mod N B = (k·v + g^b) mod N u = H(PAD(A) | PAD(B)) S = (B − k·g^x)^(a + u·x) mod N == (A·v^u)^b mod N K = H(PAD(S)) M1 = H(H(N) xor H(PAD(g)) | H(I) | s | PAD(A) | PAD(B) | K) M2 = H(PAD(A) | M1 | K)
    // privacy model

    What the server can and can't do

    The server never gets

    • Your password — not at registration, not at login, not hashed
    • Anything that lets it log in as you elsewhere, even on a site where you reused the password (it can still try to guess it — see limits)
    • A reusable login secret: every proof is bound to a one-time session
    • The session key K in transit — both sides compute it

    The server does get

    • Your username, salt, verifier and PBKDF2 round count
    • Whether each login proof was right or wrong, and when
    • Your IP address and browser headers, like any website
    • Your bound Solana address, if you add one — linked to your username

    Nopass reduces what a password login exposes. It does not make you anonymous, and a weak password is still weak.

    Known limitations — please read

    • Weak passwords can still be guessed offline. If the server's memory leaks, an attacker can test guesses against your verifier (try it in panel 6). PBKDF2 makes each guess slower; it does not make a weak password strong.
    • You trust the page you load. SRP protects the password from the server's database and the network, but the server also sends you this page. A malicious copy could simply read the password box. Real deployments pin or audit the client code.
    • Demo accounts are temporary. Users live in server memory only: at most 2,000 at once, each deleted after 24 hours, all lost on restart. Your login token lives only in this tab — reload and you are logged out.
    • Not constant-time. The BigInt arithmetic in the browser and in server.js is written for clarity, not side-channel resistance. Response timing may also reveal whether a username exists, even though unknown usernames get a decoy salt.
    • Binding an address links it to you. The bound address sits next to your username in server memory, and reading its balance sends it to the RPC provider.
    • Use HTTPS in practice. SRP keeps the password off the wire, but your session token and everything else still need transport encryption.
    • Experimental and unaudited. The SRP-6a code here was written for this demo and checked against RFC 5054's published test vectors, but it has not been reviewed by anyone else. Do not use it to protect anything real.
    • No token. The ticker shown is a placeholder label; no token exists.