Signal's code adds phone-free accounts backed by a zero-knowledge credential
Commits to Signal-Android on September 2 add a registration flow with no phone number: a one-time Google Play purchase that yields a zkgroup receipt credential the server can verify without learning who paid. Signal has not announced it. The code is public.
Signal's Android code adds a numberless login: pay once, prove it with a zero-knowledge credential.
Signal has required a phone number to register since it launched, and the number has been a standing privacy complaint about an app built for privacy. On September 2, Signal engineer greyson-signal landed a commit in the public Signal-Android repository titled "Add ability to pay for a signal login." It touches 44 files, adds 2,439 lines, and, read alongside two companion commits from the same day, describes a registration path with no phone number in it. Signal has published no blog post about it. Everything below is read from the code.
What the commits add
Commit 7da3357 wires a one-time purchase through Google Play Billing into the registration flow. It adds a screen called SignalLoginPaymentScreen, a getLoginConfiguration API call, a step enum for the purchase, and a supportsGooglePlayBilling check so the flow only appears in Play Store builds. The two sibling commits from the same author carry the rest of the story in their titles:
Add basic ability to register numberless account
Use new zkgroup credential for numberless accounts
Add ability to pay for a signal loginThe credential is the interesting part. The commit adds receipt credential handling: a client creates a request context, the client expects the server to issue a receipt credential after the purchase, and the client later presents it. Signal already uses the same zkgroup machinery for private groups and for donation badges: prove you hold a valid credential without revealing which purchase produced it. Applied here, the server can confirm that some account paid the fee without linking the account to the payment.
What the code does not say
The price is not in the code. Neither is a launch date, an iOS implementation, or any purchase path other than Google Play. The Hacker News thread on the commits, which reached 378 points, spent most of its length on that last gap: on Android the purchase goes through Google, so Google knows a Signal login was bought even if Signal does not know by whom. One commenter's summary of the design: "usually, the implication of ZKP is that you buy coupons and claim them without attribution." Suggestions of Monero or an F-Droid path came from the thread, not from Signal.
A long-running thread on the Signal community forum tracks the feature. No post in it from Signal describes the mechanism end to end. Until Signal writes one, the payment-plus-credential design is an inference from a diff, and the server side of it is not visible at all.
Why a build studio cares
Every app we build that accepts sign-ups has to solve the problem Signal is solving here: how to make abuse expensive without collecting an identifier you then have to protect. The usual answer is a phone number or an email, which is also the thing that leaks. The pattern in this diff is the better answer, and it is not new; Signal has shipped it twice already, for groups and for badges. A small fee turned into an unlinkable credential means the server can rate-limit registration by cost without ever holding a list of who paid.
We would not copy the Google Play dependency. For a client app, the version of this we would reach for is a credential minted after any payment or proof-of-work step, with the receipt separated from the account at issue time. That is a Deep Audit finding in reverse: a design where a breach of the payments table tells an attacker nothing about the users table.
Next step: read the commit and the Signal community thread around it, then the Hacker News discussion for the Google Play objection. If you want your sign-up flow's abuse controls reviewed for what they collect, write to us at hello@gattyworks.com.