HIP-15: Privacy layer to unlink public profile from address while providing sybil-resistance list of humans

Privacy Layer for Proof of Humanity (PoH)

PoH provides a sybil-resistant list of humans and their associated wallet addresses. Integration with projects like Gitcoin shows how PoH can be a cornerstone for other dapps which require protections from sybil attacks. However, as real world identities are linked to each address in the registry, several concerns have emerged from the community:

  • fear of retaliation (ie contesting vouches)
  • fear of being a subject of intimidation
  • being subject of public scrutiny

In addition, once these profiles have been linked to multiple dapps, other concerns like disclosure of personal finances & blockchain activities to family, friends & nation might emerge.


In the form of an identity mixer, a privacy infrastructure can be built to allow some PoH users to partake in activities anonymously.

  1. Anonymous Registry

A separate “list of humans” can be created, alongside the current registry. Users from the existing PoH registry will be able to insert a new address into the anonymous registry to prevent the association from the anonymous list to the public list. Zero-knowledge proof technology will be used to ensure that:

(1) the new address belongs to a member of the PoH registry
(2) each member of the PoH registry may only submit at most one anonymous address
(3) the anonymous address submission is completely untraceable to the original address.

The effect is that external contracts will be able to verify that an address belongs to the PoH list without knowing exactly which human is it. This is a non-interactive approach where external platforms do not need users to generate unique proofs for each activity/transaction.

Since it will be impossible for the anonymous address to be tied to the original profiles, there will be discrepancies when a profile is removed on the original registry but remains active on the anonymous registry. A suggestion is to use a different registry for different time periods, for instance, each registry is valid for one year and there will be a change of register every year. Each year the anonymous registry will be made obsolete and users on the public registry will simply recommit an address they would like to use. This not only ensures that the anonymous registry is up to date but also encourages users to rotate their accounts since they could use a different unlinked address.

  1. PoH Membership Proof

For cases where projects require more up-to-date membership proof, it is also possible that they request for membership proof from the user directly.

What Does This Mean?

For PoH Users

  • Everyone will still continue to receive UBI on their address linked to their public profile
  • Users who do not want to be bothered with their privacy do not need to do anything, they will continue to be able to participate in voting and other apps like Gitcoin.
  • Users who want to anonymize their votes on Snapshot will simply follow the two-step process (described in the UX section) and they will be able to vote from their anonymous address instead of the address linked to their public profile.
  • Users using privacy enable account when interacting with other applications like Gitcoin, Kleros, etc will either use their anonymous account on that platform or generate a membership proof that can be verified via both on-chain or off-chain mechanism on the other platform. Developers of that platform will decide if they want to use the proxy interface which will be easier to use or if they want to build the proof verification logic within their app.

For Developers Building on PoH

  • You have access to sybil-resistance list of humans using the new proxy, the interface isRegistered(address) is used in the same way.
  • You may alternatively request from membership proof directly from users of PoH for various reasons:
    1. You want to allow anonymous address that are namespaced (is anonymous address are not linked together)
    2. You want to have smaller margin of error (discussed below)

Detailed Writeup

The project will extend the current ProofOfHumanity contract and upgrade the ProofofHumanityProxy contract.

A contract, PoHIdentityCommitments, will be created to map the existing addresses to known identity commitments. The identity commitment is used in the ZKP gadget for the generation of proof in later steps.

Another contract, ProofVerifier will be deployed to allow any smart contract or even off-chain applications to verify a proof generated by a PoH user.

Another contract, ProofOfHumanityAnon, will be the registry that will accept a proof from any addresses. By checking the proof, it can assert that:

  1. The proof was generated by one of the users found in the PoHIdentityCommitments contract
  2. The user has not generated such proof before, and therefore preventing double submission

Upon said verification, it will then include the sender’s address to the list of anonymous humans.

With two lists of humans now, the ProofOfHumanityProxy, which powers the Snapshot page currently will need up upgrade. It will read from the 3 smart contracts ProofOfHumanity, PoHIdentityCommitments, and ProofOfHumanityAnonto recreate the sybil-resistant list. The set of humans will now be defined as:

  • isRegistered(address) on ProofOfHumanity and not hasCommitment(address) on PoHIdentityCommitments, or
  • isRegistered(address) on ProofOfHumanityAnon

With the proxy token returning 1 upon the above condition being met for a given address for the ERC20 method of balanceOf(address), PoH users will be able to conduct polls on Snapshot pages anonymously if they have anonymized their address.

User Experience (UX)

For users of PoH who want to link an anonymous address to their identity, they will need to follow a two-step process. This would be part of the PoH frontend tools, possibly at privacy.proofofhumanity.id.

[Removed image due to account restriction, see full draft link below]

The first is to register their generated identity commitment. They will be required to save the identity commitment secret which will be used for proof generation in later stages. There will be a smart contract transaction to the PoHIdentityCommitmentscontract, from the original PoH profile address, to register this commitment.

Once that happens, the user should wait for a random amount of time to pass for other users to register their identity commitment as well. This is important to prevent attackers from figuring out the association between the public and anonymous address by looking at transaction time between an identity commitment transaction and the anonymous address registration

[Removed image due to account restriction, see full draft link below]

The second step is to register the anonymous address. The identity commitment’s secret will be used to generate a proof to register the new anonymous address. This transaction will be sent from the anonymous address to the ProofOfHumanityAnon to register the new address

The user experience with Snapshot will remain the same for end users. They will either vote with:

  • The public account if and only if they have not submitted an identity commitment, or,
  • The anonymous account if the anonymous address has been submitted
  • Note that the UX flow is for illustration purposes, the actual text, design and steps may vary.

The Margin of Error Discussion

The above proposal includes an anonymous address for ease of use by dependant applications like Snapshot, Gitcoin, etc. This approach introduces a margin of error in the system as there will be cases where an anonymous address is linked to an invalid profile.

One example will be when a profile is added to PoH list and the user has generated an anonymous address but is later removed from the list (reasons include expiry or removal), the anonymous address is still on the anonymous address registry.

Approach #1 - Simple annual registry

The initial approach to solve this problem will be to reset the anonymous registry every given period, let’s say a year. This means that users will register for the anonymous address once each year and has anonymity set over the entire population.

Approach #2 - Sliding window

To further reduce error rate Clement suggested a sliding window logic over a period of 1 year, composing of 4 internal sub-trees, each corresponding to a quarter of a year. This means that users will register on the identity commitment contract that corresponds to when their profile expires. This means that users will register for the anonymous address once each year and has anonymity set over approximately a quarter of the population.

Approach #3 - Address change as exceptions

Another approach, adding on to #1, is to allow users to only re-register the public profile with the same address. If users want to re-register with a different address (maybe due to loss of keys), it will be treated as an exception and is dealt with in the Kleros court. This prevents cases where users can have multiple anonymous addresses when they have a profile that was linked to more than one account at a single time period.


  • How do we encourage users to be anonymous

To encourage the adoption and offset the cost for registering the anonymous address, the DAO may also drip additional UBI to the anonymous address on top of those on the public registry. This could be discussed in greater detail in a separate proposal.

  • What is the custodian proof generation?

Computation of zk-SNARK proofs takes significant computation resources during the generation but is fast to verify, which makes it suitable for on-chain verification. Many browsers do not have the necessary call-stack depth to allow for the proof generation. From initial testing, Firefox browser is the only browser that is capable of doing it. The custodian proof generation is a service to be hosted by PoH to allow users to submit both the identity commitment secret and additional parameters to have the proof computed on the server side.

The Dapp will default the proof generation to client-side proof generation and will prompt the user to switch to the custodian service if the browser is unable to generate the proof.

  • What is the gas cost we are looking at?

The most expensive cost is on-chain proof verification, used when inserting the anonymous address into the list. The ballpark is 325k gas. At 50 Gwei, that will translate to 0.01625ETH or $42 (current rate)

Additional Notes

The core technology powering the two solutions will be owned and maintained by the developing entity. This allows the core technology to be upgraded and maintained separately outside of PoH which will be maintained by a high quality team in the long run.

This consultancy engagement grants PoH the license to use the identity mixer perpetually.

Additional Readings

[Links are removed from below article due to account restriction on discourse, you may look them up on a hosted version]

Why should you care about privacy - even if you had nothing to hide

ZKP in Civi Tech - Re-imagining Identity Infrastructures

Decentralized Food Distribution Organisation

VeilOS - Preview of Privacy Preserving Application Engine

Privacy for Public Registries - Proof Of Humanity x VeilOS

Full Draft

Some images and links are removed on the post due to my account level on discourse, the full draft is made available here

What’s Next

The above proposal is the 3rd draft of the privacy idea that has been submitted to @clesaege team and we have reached a standstill. The drafts prior suggested the scope and delivery which the team could not agree on and have not shown interest in continuing the discussion. So I’m leaving the proposal here if anyone would like to pick it up from where it’s left.

Feel free to partake in the discussion to improve this proposal if you want to build privacy onto PoH. Some of the issues that we might want to address prior to deciding if we should build this layer is:

  • Does our user care about privacy to pay for it? That refers to things like gas fees (individual contribution) and to pay for such features to be developed (like from DAO’s treasury). Also, what is a fair price for privacy?
  • What margin of error is acceptable for sybil-resistance?
  • Should one attempt to engineer a perfect solution from the get-go and building on lots of assumptions or attempt to approach the problem iteratively?
  • How would dependant applications like to use the PoH list? A simple approach like isRegistered or something more complex?

Very interesting that it’s stalled. Obviously not a high enough priority ATM? Would a half way house solution be to just hide the identifying photo/video in some way? It’s not total privacy but maybe psychologically it’s enough for now?

This sounds really interesting. I would like to see this idea develop further. Unfortunately recent issues regarding exposure of personal information were disregarded as priority so I do not thing that this would be implemented in the near future, unless more manpower is brought to the system.

1 Like

Agreed. I think the governance / ownership issues are dominating discussion and attention at the moment.