Anonymous Tokens
Anonymous tokens let a user prove they are authorized to use a service without revealing who they are.
Understanding Anonymous Tokens
Anonymous tokens are a way for users to prove they are authorized to use a service without revealing who they are. The idea is simple: a user obtains a token once (where they may be identified), and later presents that token to access a service anonymously. The challenge is ensuring that:
- The user cannot forge tokens.
- The service provider cannot link a redeemed token back to the original user.
- Tokens cannot be reused (no double-spending).
A standard way to create such tokens is to use a Pseudorandom Function (PRF). The server has a secret key K, and a valid token is a pair (x, y) such that y = H(K, x). However, issuing (x, y) directly would reveal x and y to the server, which means the server could later recognize the token and deanonymize the user. This breaks anonymity.
To solve this, we need an Oblivious PRF (OPRF): the server evaluates the PRF without learning the input or output, meaning it issues a token without being able to recognize it later.
How Bubble Solves This
Bubble already provides the ability to compute H(x) securely without revealing x or H(x) to anyone. We use this to implement anonymous tokens functionalities.
-
Token Issuance (identified stage)
- A user requests a token using their known address.
- The Bubble system privately generates a random value
x. - It privately computes
y = H(x)using MPC. - No one, not even the service, sees the actual values.
This is done using the OPRF mint function.
-
Anonymous Redemption
- The user later interacts from a different, unrelated address.
- The user submits the token
(x, y)while x remains encrypted under a different key associated with the alternate address, so it remains hidden publicly. Y is given in the clear. - Bubble decrypts the token internally, verifies that:
y = H(x)(the token is valid)yhas not been used before (no replay using a nullifier list)
- If valid, the user is granted access without linking to their original identity.
-
Token splitting and merging
Tokens can represent a value
q. To change denominations, the user burns the existing token or tokens. They then mint replacement tokens with the required values.Replacement tokens receive fresh, private
xvalues. They cannot be linked to the burned tokens by their public values.The application must enforce value conservation. The sum of replacement values must equal the sum of burned values. It should perform the burn and mint operations atomically. This prevents a user from spending an input token while its replacement is created.
Example, split: A user burns one token with
q = 100. The application mints two new tokens withq = 40andq = 60. The user can redeem them separately from unrelated addresses.Example, merge: A user burns tokens with
q = 25andq = 75. The application mints one replacement token withq = 100. The original tokens remain unusable after the burn.
Bubble Anonymous token functionalities
oprfMint
function oprfMint(gtUint128 key, gtUint256 q) internal returns (gtUint128, gtUint128)Purpose: Create a new token (X, Q, Y)
Inputs:
- Key: OPRF key
- Q: The requested token value
Outputs:
- Q value of the token
oprfBurn
function oprfBurn(gtUint128 key, gtUint128 x, gtUint256 q, uint128 y) internal returns (gtUint256)Purpose: Burn the token (X, Q, Y)
Inputs:
- Key: OPRF key
- X: The x value of the token, encrypted.
- Q: The q value of the token, encrypted.
- Y: The y value of the token, in the clear. Y value is not encrypted in order to check nullification.
Outputs:
- X Handle
- Y Handle
Secret Randomness
Generate random encrypted values in Bubble, with randomness shared across the MPC parties so no single party knows it.
How to Transform Your Smart Contract into a Bubble Smart Contract?
Convert a public Solidity contract into a confidential one: encrypted handles, MPC logic, and explicit ACL permissions.