In-depth technical look at VOPRF tokens and the Salary Confidential privacy model
For the technically curious, this page explains the cryptographic machinery that allows Salary Confidential to verify your right to participate in a survey without ever knowing who you are or linking your identity to your salary data.
The Primitive: RFC 9497 (VOPRF)
Salary Confidential utilizes a Verifiable Oblivious Pseudorandom Function (VOPRF) based on RFC 9497. Specifically, we implement Mode 2 (POPRF), which allows for "Partially Oblivious" evaluation.
Our implementation of this cryptography is done using the Privacy Pass protocol.
Why POPRF?
Standard "blind signatures" lack context. By using POPRF, we can bake "public metadata" (the SurveyID) into the cryptographic operation itself. This ensures:
- Unlinkability: The platform cannot link a token issuance to a token redemption.
- Scoping: A token issued for Survey A is mathematically invalid if presented to Survey B -- this prevents a requester from minting tokens they can use across surveys they don't own
- Efficiency: We use Elliptic Curve Cryptography (ECC) on the P-384 curve, which is natively supported in modern browsers and significantly faster than legacy RSA-based blinding.
The Life Cycle of a Token: A → B → C
Our privacy model relies on a one-way derivation chain. Also, at no point is a "raw" token ever stored in our database.
1. The Token (A)
The process begins with the Requester (the survey owner). They use our platform’s cryptographic keys to "mint" a unique invite token (e.g., Value 123).
-
Stateless Minting: When the Requester creates these tokens, the Platform (Salary Confidential) does not store them. We act as the "stamp," but we don't keep a log of what was stamped.
-
The Handover: The Requester gives this token to the Respondent. At this stage, the only people who know the token exists are the Requester (who sent it) and the Respondent (who holds it). To the Platform, the token is currently "invisible."
2. The Evaluation (B)
When the Respondent submits their survey, the token is presented to our Cloudflare Verify Endpoint. Our Worker evaluates it against our Global Private Key and the specific SurveyID:
Value_B = POPRF_Evaluate(Private_Key, Token_123, SurveyID)
Security Property: Value_B is a unique, deterministic result. This step proves the token is authentic without the Platform ever having seen it before.
3. The Commitment (C)
The math of VOPRF already makes it impossible to "reverse" Value B to find your original Token A. However, we add a final layer of defense called "Defense in Depth." We pass Value B through a keyed HMAC using a secondary system secret to create a final Commitment (C):
Commitment_C = HMAC(Value_B, Global_HMAC_Secret)
this commitment C is the hash we keep in our tables to have something to verify against one-time use.
This ensures the ledger is not "searchable." Even if someone had a list of all issued tokens and our private VOPRF keys, they still couldn't check which tokens were used because they lack the separate HMAC secret. We only store C.
The "Zero-Linkage" Firewall
We maintain two strictly separated logical siloes to prevent anyone from connecting an identity to a salary:
| Feature | Token Redemption (The Gate) | Response Submission (The Data) |
|---|---|---|
| Identifier | Token Commitment (C) | Response Fingerprint (IP/Timestamp) |
| Forensics? | None (No IP/Timestamp logged) | Yes (Stored for platform defense) |
| Visibility | Opaque to all | Salary data goes to requesters and respondents (who have secret results keys), and the forensics are never exposed |
Why we can't "Join" these tables:
Because the Platform does not log an IP address or timestamp when a token is "burnt" (at the Gate), there is no common data point to link that event to the moment the salary data was saved (the Data). We know a token was spent, and we know a response was received, but the "bridge" between them does not exist in our data.
Verifiability (The "V" in VOPRF)
Unlike older privacy protocols, our system is Verifiable. When our Worker signs your token, it also produces a DLEQ (Discrete Log Equality) Proof.
Your browser uses this proof to mathematically verify that the platform used the correct global key and the correct SurveyID metadata. This prevents the platform from "tagging" specific users with malicious keys to track them later.
Summary of the Privacy Guarantee
- The Requester knows who they invited, but cannot see who responded.
- The Platform facilitates the "burn," but cannot link the burn to the issuance or the final response.
- The Respondent remains anonymous to both parties, protected by state-of-the-art elliptic curve math.
We believe in "Show, don't tell." If you have questions about our @cloudflare/voprf-ts implementation or the P-384 suite we use, we’d love to chat. Get in touch with the team.