My last blog post discussed why we need private email attestation. As promised at the end of that blog post, this is a deeper dive into how exactly we achieve this goodness. Let's establish our goals first. What do we want to accomplish here?
The SealCred email domain verification aims to provide a simple, privacy-preserving, decentralized service for people to attest that they own/control an email with a particular domain (say, an @apple.com email). A user should be able to generate a token attesting to this fact post verification.
- Simplicity: A user should ideally not receive more than one email.
- Privacy-preserving: A user's exact email address should not be exposed to any adversary. SealCred should not know the user's actual email address either. Furthermore, IT administrators have access to all employee emails in many companies. Even in this case, our protocol should ensure that the IT administrator does not know who requested a SealCred email attestation token.
- Decentralization: It shouldn't be the case that the creators of SealCred can generate fake proofs if they want to.
A first approach
This approach uses a node server that generates EdDSA signatures as attestations for a specific credential. This node server is called the 🌈
attestor🌈. This approach proceeds as follows:
- The user wants to generate a ZK badge for the fact that they own an @apple.com email
- The user submits this email to our server
- Our server uses its EdDSA signature keypair to sign the
message = domain(here "apple.com") and sends the signature to the specified email
- The signature received over email acts as an attestation token
- The user generates the ZK proof that they possess the attestation token for the said email domain
Properties available in this approach:
- Simplicity ✅
- Privacy-preserving: All users who generate such a token are sent an email by SealCred, so their exact email address is known at some point. An IT administrator in a company where, let's say, only one person requested a SealCred token will know precisely who it is who asked for the token.
- Decentralization: The attestor could, in principle, go rogue and generate fake badges/tokens for email domains.
Improving this approach
We need to make changes so that the privacy-preserving property is assured and that the attestor (if gone rogue) can not generate malicious tokens by itself.
Anonymity Sets: There are multiple people at each organization, all with the same domain email address. People in an organization have access to the email address of others in the organization. We leverage that simple but crucial fact to hide users in anonymity sets:
- Instead of submitting just their email address to our server, the user submits a bunch of addresses (let's say 100) with the same domain
- The attestor signs
message = H(domain, anonymity set, password)and sends the signature as an email, at once, to all email addresses in the anonymity set
- The user generates the ZK proof that they: (possess the attestation token for the said email domain + they know the password)
- Privacy-preserving: ✅ SealCred and some nosy IT administrator can never know who requested the token out of the emails/people in the anonymity set
Community Attestors: Aside from the SealCred attestor, we can add another party to the protocol to make it more decentralized and disallow the possibility of malicious proofs created by a rogue attestor. The user has to perform precisely the same operations with one/a set of community attestors. The community attestor + SealCred attestor signatures together act as the attestation token. The result is:
- Decentralization: ✅ Neither the SealCred attestor nor the community attestor(s) can create a malicious proof on their own. We can also develop future features so that if one of the attestors goes under a DoS attack, a committee of attestors (with some honesty threshold) can complete the attestation process.
Should attestors advertise themselves over the network so clients can connect to it (or maybe just register in a smart contract we have as OpenGSN relayers do)?
We are looking at other networks/protocols with similar notions to attestors and deciding on the UX. One reason for clients to give the ability to select their community attestor is because maybe they want to run their own. People using the Tor browser have in the past expressed the great benefit of choosing their own Tor relayers.
How do we combine community attestor(s) and the SealCred attestor?
This is a tough one. We can design our protocol so that both the SealCred attestor and community attestors are required for attestation. This way neither can create malicious proofs. However, let's say the SealCred attestor goes offline; it is like a DoS attack. Same for the case if the community attestors are fully offline. However, this is still decentralized. A potential issue is that since we're a privacy-focused project, what if one day the government comes after us to shut us down as a service? All they have to do is unplug/turn off the SealCred attestor, and the protocol for email attestation is over. So here we have to make a call out of the following two options:
Option 1. No SealCred attestor. Only a group of community attestors. We will operate in this case under an honesty assumption for community attestors. Let's say at least 1/3rd of the attestors will behave honestly at all points. For example, the following is the approach taken by Ethereum's beacon chain:
"We make these assumptions: Majority validator honesty: We assume 2/3 of the validators are honest. (This assumption is also made for sharding.) Minority validator liveness: We assume up to 3/4 of the honest validators are offline, possibly."
Option 2: SealCred attestor + Community attestor(s) approach. One community validator and SealCred attestor can validate a proof together.
We pick option 1 for now. The reason is that in the beginning, it is our responsibility as the team behind this service to ensure it is available and gets off the ground. In the future, we plan to move to a fully decentralized approach where there is no SealCred attestor, and a set of community attestors run the whole protocol. Meanwhile, if there is an attack on SealCred as a service, the community can fork our public codebases and run the entire protocol themselves.
How to incentivize attestors?
The simple answer is tokens. As we build our roadmap, such ideas will arise naturally. The goal behind the protocol incentivization would be that community attestors are rewarded for performing the expected attestations honestly. In the future, a small staking type mechanism would be required before becoming a validator to disincentivize bad behaviour via loss of staked funds.
Should we hide community attestors in the anonymity set when checking their public keys?
Privacy for community attestors isn't a cause for concern for now. If someone bribes a few community attestors and they sign malicious stuff, the SealCred attestor still won't sign anything invalid.
Should we have a notion of attestor reputation? Should it be a zk-based reputation?
We plan to have such a notion as community attestors increase in number. The key idea is that bad behaviour should result in slashing, and delays from community attestors should damage reputation.