Deriving The Login Bucket
How to derive login_bidx using the OPRF challenge endpoint — the prerequisite step before every login and registration.
Zero-Knowledge Guarantee
Your email address never reaches the server in any form during this step. Your device blinds it cryptographically before transmission. The server evaluates a transformed point and returns a result — without learning the input. You unblind the result locally to derive your login bucket. Neither party learns the other's secret.
What This Step Is For
Every login and registration requires a login_bidx — a 13-bit integer (0–8191) that tells the
server which bucket of candidate records to return. Deriving it requires a single round-trip to
POST /v1/auth/challenges.
This step happens before any OPAQUE handshake. You cannot call authenticate-start or
register-start without a valid login_bidx.
Overview
| Step | Where | What Happens |
|---|---|---|
| 1. Normalize | Your device | Trim whitespace, apply Unicode NFC, lowercase |
| 2. Blind | Your device | Hash email to a curve point, multiply by a random scalar |
| 3. Evaluate | Server | Multiply blinded point by server's secret key |
| 4. Unblind | Your device | Remove the blinding scalar, hash the result, truncate to 13 bits |
The server sees only a random-looking curve point. You see only the server's transformed result. The original email and the server's key remain private to their respective owners throughout.
Step 1 — Normalize Your Email
Before blinding, normalize the email so the same address always produces the same bucket regardless of how it was typed:
- Trim leading and trailing whitespace
- Apply Unicode NFC normalization
- Convert to lowercase
This matches the normalization applied server-side for consistency. Do not strip + tags or Gmail
dots — those are provider-specific and are preserved.
Step 2 — Blind The Email
Hash the normalized email to a point on the ristretto255 group using hash-to-curve
(RFC 9380, XMD:SHA-512) with the domain separation tag "kyndex-oprf-v1". Then multiply that
point by a random scalar r:
blinded_element = r * hash_to_curve(normalized_email)r is your blinding scalar — keep it in memory. It is never sent anywhere. Without it, the
server's response cannot be unblinded.
Encode the resulting 32-byte point as standard base64 for transmission.
Step 3 — Call The Challenge Endpoint
curl -X POST https://api.kyndex.co/v1/auth/challenges \
-H 'Content-Type: application/json' \
-d '{
"blinded_element": "<base64-32-byte-ristretto255-point>"
}'No authentication is required. The endpoint is rate-limited — repeated failures will result in
429 Too Many Requests.
Request body:
| Field | Type | Description |
|---|---|---|
blinded_element | string | Base64-encoded 32-byte ristretto255 point (your blinded email) |
Response (200 OK):
{
"evaluated_element": "<base64-32-byte-ristretto255-point>"
}| Field | Description |
|---|---|
evaluated_element | Base64-encoded 32-byte ristretto255 point (server's OPRF evaluation) |
Step 4 — Unblind And Derive The Login Bucket
Decode evaluated_element from base64. Remove your blinding scalar by multiplying by its modular
inverse:
unblinded = (1/r) * evaluated_elementThen finalize to produce login_bidx:
digest = SHA-256(unblinded_bytes || "kyndex-oprf-finalize-v1")
login_bidx = (digest[0] | (digest[1] << 8)) & 0x1FFFTake the first two bytes of the SHA-256 digest as a little-endian 16-bit integer, then mask to 13
bits. The result is an integer in [0, 8191] — your login_bidx.
Pass this value as the login_bidx field in register-start or authenticate-start.
Error Handling
| Status | Meaning | What To Do |
|---|---|---|
400 | Invalid blinded element | The submitted point is not a valid ristretto255 point. Check your encoding and curve arithmetic. |
429 | Rate limited | Back off and retry. This endpoint enforces strict rate limits. |
500 | Server error | Retry with exponential backoff. |
Invalid points always return 400 — the server never returns 422 or 500 for a malformed
point. This is intentional: a response that distinguishes valid from invalid curve points would
act as an oracle. If you receive a 400, the issue is in your point encoding, not the server.
Security Properties
The server cannot learn your email. The blinding scalar r transforms your email hash into a
point indistinguishable from random. Without r, the server's evaluation reveals nothing about
the input.
The server observes the bucket number, not the email. The login_bidx value is sent in the
clear to authenticate-start. The server uses it to return a padded set of candidate records —
the response always contains the same number of entries regardless of how many real records exist
in that bucket. The bucket number alone reveals nothing about the email that produced it.
Your device cannot learn the server's key. The server multiplies by its secret scalar without exposing it. You receive only the transformed output.
The login bucket is non-reversible. The finalization step (SHA-256 with a domain separator, truncated to 13 bits) destroys any residual information about the unblinded point.
Cross-protocol separation. The domain separation tag "kyndex-oprf-v1" ensures that the
email OPRF output is cryptographically distinct from any other use of the same curve in the
platform.
Think of it like a sealed envelope through a stamping machine. Your device seals the envelope (blinding). The server stamps it through the slot without opening it (OPRF evaluation). Your device opens the envelope and reads the stamp (unblinding). The server stamped something — but never read what was inside.
Related Resources
- Authentication — registration and login flows that consume
login_bidx - Zero-Knowledge Model — why the server is structured to never see your credentials
- Blind Routing — how other identifiers are similarly protected throughout the platform
Blind Routing
How sensitive relationships and lookup predicates are tokenized to prevent the server from mapping who owns what, who shares with whom, and which users belong to which organizations.
Document Upload With Client-Side Encryption
Walk through uploading an encrypted document from authentication through enclave processing to search verification.