Blind RSA

Persona’s Privacy Pass protocol is built on Blind RSA Signatures (RFC 9474), a signature scheme that allows a server to sign a message without ever seeing its contents.

Why blind signatures?

In a standard RSA signature scheme, the signer sees the message before signing it. For Relay, this would mean Persona sees the exact token being issued — creating a correlation risk between issuance (where Persona knows your platform identity via API key) and redemption (which is meant to be anonymous).

Blind RSA breaks this link. Your client blinds the token input before sending it to Persona for signing. Persona signs the blinded message without seeing the underlying data. You then unblind the signature locally — producing a valid RSA signature that Persona cannot trace back to the issuance request.

The three operations

Blind RSA is defined by three operations (RFC 9474 §4):

Blind(publicKey, message)

Transforms a message into a blinded message using the signer’s public key and a random blinding factor. Returns:

  • blindedMsg — send this to the signer
  • inv — the blinding inverse, kept secret on your end and used to unblind the response

BlindSign(privateKey, blindedMsg)

The signer’s operation — signs the blinded message without seeing the original. Returns a blindSig. This is what Persona does when you call POST /api/v1/privacy-passes.

Finalize(publicKey, message, blindSig, inv)

Unblinds the signature using inv. Returns a valid RSA-PSS signature over the original message — one that Persona produced without ever seeing.

Suite

Persona uses the RSABSSA-SHA384-PSS-Randomized suite:

ParameterValueDescription
HashSHA-384Hash function used in RSA-PSS padding
PaddingPSSProbabilistic Signature Scheme
BlindingRandomizedA fresh random blinding factor per request

Use a well-audited library that supports this suite. For TypeScript/Node.js, Cloudflare’s @cloudflare/blindrsa-ts implements RFC 9474 and supports RSABSSA-SHA384-PSS-Randomized directly.

Implementing blind RSA from scratch is strongly discouraged. Mistakes in blinding, padding, or unblinding can silently break the privacy guarantees of the protocol or produce signatures that fail verification. Proceed with a custom implementation at your own risk.

Further reading

  • RFC 9474 — RSA Blind Signatures (full algorithm specification)
  • RFC 9578 — Privacy Pass Issuance Protocol (how blind RSA is used in Privacy Pass)