Nobody holds the whole key, us included
Private Wallet is a 2-of-2 MPC (multi-party computation) wallet. The key behind each vault exists only as two shares: one that only your phone can open, and one on our server. A valid signature needs both. We cannot sign without you, and you cannot sign without us. Your recovery phrase is neither share. It is created on your phone, and our server never receives it, or anything made from it, in a form it can open.
What each side holds
| Secret | Where it is kept | Who can read it |
|---|---|---|
| Recovery phrase | On your phone, encrypted; in memory only while the wallet is unlocked | You |
| Your key share | On our server, as a backup encrypted with a key made from your phrase; opened only in your phone’s memory, to sign | You |
| Our key share | On our server, encrypted, with a second encrypted copy kept apart from the main database | Our server |
| Your PIN | Not stored; our server keeps a check value it cannot turn back into the PIN | You |
| Full-access API key | Wherever you keep it; shown to you once, never sent to us, and carrying a copy of your share | Whoever holds it |
| The whole signing key | Nowhere; it is never assembled, not even when the vault is created | Nobody |
How the key is made without anyone seeing it
Your phone and our server create each vault’s key together. The method is a distributed key generation: each side picks its own random secret, the two trade commitments and then private values over two rounds, and each ends up holding one share. The complete private key is never computed, on either side, at any moment.
Both sides do compute the public key. It becomes the vault’s account, the identity your balance is recorded under and every signature is checked against. Your phone works it out on its own and stops if our server reports a different one, so a vault exists only once both sides agree on the key that controls it.
How a transfer gets signed
Signing follows FROST, the threshold signature scheme published as RFC 9591. Your phone and our server each commit to a one-time random value, then each produces a signature share over the same message. Our server combines the two into one Ed25519 signature, and the chain checks it against the vault’s public key like any other. Nothing on the chain shows that two parties signed.
Before your phone adds its share, it checks the request against what you approved. The message must be exactly the transfer our server disclosed; it must move money out of the vault you picked and no other; and the total cannot exceed the amount on your confirmation screen. If any of the three fails, your phone refuses and its share is never used.
Why we cannot read your recovery phrase
Your phone generates the phrase. It is 12 words from the standard BIP39 list, carrying 128 bits of randomness from the phone’s own generator. Our server plays no part in making it and never stores it, in the clear or encrypted.
On the phone, the phrase is kept encrypted with AES-256-GCM. The key for it is mixed from two inputs. One is your PIN, stretched with Argon2id through 64 MiB of memory. The other is a random secret our server releases only after your phone proves it knows the PIN. The encrypted phrase never leaves the phone, so our secret unlocks nothing we could reach.
Setting up a second phone keeps the same rule. The two phones agree on an encryption key between themselves using ECDH, you compare a short code shown on both screens to catch a swapped key, and only then does the old phone send the phrase. Our server passes the ciphertext along, only between phones signed in to the same Telegram account, and holds no key that opens it.
What the phrase unlocks
The phrase opens exactly one thing. That is the backup of your key share, which our server stores encrypted under a key your phone makes from the phrase, a separate key for each vault. No signing key is derived from the phrase at all. Our server cannot read the backup; your phone opens it in memory each time you sign.
That is why restoring works only here. On a new phone you sign in with the same Telegram account and type the phrase; your phone downloads the encrypted backups and opens them. A third-party wallet cannot do this, because the phrase gives it nothing to derive and the other share stays with us.
It also means the phrase and your Telegram account need guarding together. Someone holding both could restore your vaults on their own phone, and our server would co-sign for them as it does for you. Guessing the phrase is no way in: 128 bits of randomness are out of reach of any search, and a wrong phrase fails the backup’s integrity check instead of opening it.
If someone takes your phone
A stolen phone holds the encrypted phrase and nothing that opens it. Trying PINs offline gets a thief nowhere, since every guess needs our server’s secret, and our server hands it out only for the right PIN.
After a few wrong PINs, our server makes each new attempt wait longer, up to 24 hours. The phone keeps its own count as well: after 6 wrong PINs it deletes its encrypted copy of the phrase, and the way back is to restore from the phrase itself.
A phone lost for good is handled the same way. Sign in on a new one with your Telegram account, enter the phrase, and your vaults come back with their balances.
What we can and cannot do
Our server cannot start a transfer or sign one on its own. It cannot read your phrase, your PIN, or the backup of your share, and it cannot restore a phrase you have lost, because it never had one to restore.
What our server can do is refuse. It can decline to co-sign, and an operator can halt all transfers for every account at once. That stops money moving; it cannot send your balance anywhere.
One thing can sign for you without your phone: a full-access API key, which you can issue in the wallet’s settings for a program of your own. It carries a copy of your share, is shown to you once, and is never sent to us. Whoever holds it can move funds together with our server, so keep it as carefully as the phrase.
Where the protection stops
Every signature needs our server. If it is unreachable, nothing can be signed until it is back, and the phrase will not help: it restores your share, not ours. Our share has its own encrypted backup, kept apart from the main database, so damage to the database does not take it with it.
There is no way to withdraw without us, and that is a choice. A third share, as in a 2-of-3 scheme, would let one party sign without the other, and preventing exactly that is what the design is for.
Before signing, your phone checks the message, the vault, and the amount. The destination written into the transfer is not on that list: it comes from our server, and your phone takes it as given. A compromised server could not start a transfer or take more than you approved, but it could redirect one you are making.
The threshold signing is built on frost-ed25519, the Zcash Foundation’s open-source FROST library, and the wallet’s own code has been through internal reviews. An independent firm has not audited the scheme yet.
Read next
Several wallets in one account, separate on-chain
Hold as many wallets as you need inside one Telegram account. Each is its own account on-chain, and nothing links them until you move money between them, so paying from one tells nobody about the others. Send to a @username or to any address.
Questions
Is Private Wallet an MPC wallet?
Yes. Each vault’s key is split into two shares by a 2-of-2 threshold scheme, FROST over Ed25519. Only your phone can open one share, only our server holds the other, and every signature needs both.
Can you move my funds without me?
No. Our share cannot sign on its own, and your phone signs only a transfer you confirm. Our server can refuse to co-sign or halt all transfers; it cannot send your money anywhere by itself.
What happens if your server goes offline?
Your balance stays where it is, but nothing can be signed until the server is back, because every signature needs our share. That share is backed up, encrypted, apart from the main database, so losing the database does not destroy it.
What if someone steals my phone?
They get an encrypted phrase and nothing that opens it. Our server checks every PIN guess and makes wrong ones wait longer and longer, up to 24 hours, and the phone erases its copy after 6 wrong PINs. Restore on a new phone with your phrase.
Has the wallet been audited?
Not by an outside firm yet. The signing is built on the open-source frost-ed25519 library, and the wallet’s code has been through internal reviews, but no independent cryptographic audit of the scheme has been done.