Skip to content

Start typing to search the documentation.

Identifier Obfuscation

On this page

The obfuscation process transforms a plaintext identifier into a privacy-preserving on-chain identifier.

Step-by-Step Process

1. Format the Identifier

Combine the identifier prefix with the plaintext identifier:

formatted = "{prefix}://{plaintextIdentifier}"

Example:

Phone: "tel://+12345678901"
Twitter: "twit://@alice"

2. Hash the Formatted Identifier

hashedIdentifier = sha3(formatted)

3. Blind the Hash

The client generates a random blinding factor and blinds the hash:

blindedHash = blind(hashedIdentifier, blindingFactor)

This step ensures ODIS cannot see the actual identifier.

4. Query ODIS

Send the blinded hash to ODIS operators.

5. ODIS Processing

Each ODIS operator:

  1. Receives the blinded hash
  2. Computes a partial signature using their key share
  3. Returns the blinded partial signature

6. Combine Signatures

When k signatures are received:

  1. Signatures are combined into a full signature
  2. This is the “blinded pepper signature”

7. Unblind the Signature

The client unblinds the signature:

unblinedSignature = unblind(blindedPepperSignature, blindingFactor)

8. Generate the Pepper

Extract the pepper from the unblinded signature:

pepper = first13Chars(sha256(unblindedSignature))

9. Create Obfuscated Identifier

Combine the hashed identifier with the pepper:

obfuscatedIdentifier = sha3(hashedIdentifier + "__" + pepper)

Final Formula:

obfuscatedIdentifier = sha3(sha3("{prefix}://{plaintext}") + "__" + pepper)

In practice, the SDK wraps this entire process in a single OdisUtils.Identifier.getObfuscatedIdentifier call. See SDK Integration with Viem.

Verification

Results from ODIS can be verified against the service’s public key, which is shared with users through the client library.

Was this page helpful?