Why UnifiedID stays private
Where UnifiedID appears
The UnifiedID only appears inside the challenge string:
"Prove ownership of 0x… for UnifiedID alice at 1699..."
This challenge string is:
Signed off-chain with ECDSA.
Converted to bytes and padded to 32 bytes before entering the circuit as challengeMessage[32].
UnifiedID is never exposed as a public signal.
What is publicly visible
Publicly visible (to any verifier, chain, or zkVerify):
walletAddressHash = Poseidon(wallet bytes)
challengeHash = Poseidon(challenge bytes, which include UnifiedID)
signatureHash = Poseidon(signature bytes)
ownershipProof = Poseidon(walletHash, messageHash, signatureHash)
Groth16 proof elements (elliptic-curve points)
Circuit verification key (structure, no secrets)
Not visible:
Raw wallet address
Raw ECDSA signature
Clear-text UnifiedID or challenge string
Security / privacy outcome
To any relying party (dApp, chain, or zkVerify) the statement is:
“There exists some wallet, some signature, and some challenge message such that:
They hash to the public commitments you see, and
(By SDK policy) that signature is valid for that wallet and challenge.”
They do not learn:
Which wallet address it actually is
Which UnifiedID string was used
The exact challenge message or timestamp
The raw ECDSA signature bytes
This is how Glyph implements its privacy philosophy:
User-owned control – the user proves control over a wallet without revealing it.
Selective disclosure – apps see verifiable claims (“this wallet controls UnifiedID Y”) via commitments, not raw identifiers.
ZK-native infrastructure – zk circuits + Groth16 + zkVerify provide a reusable, chain-agnostic verification layer.
In short, Glyph certifies wallet ownership for a UnifiedID using zero-knowledge, keeping the wallet, signature, and UnifiedID private by default, while still giving apps a strong cryptographic assurance that the claim is true.
Last updated