-
Notifications
You must be signed in to change notification settings - Fork 12
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
RFC-0007: zkPassport #11
base: main
Are you sure you want to change the base?
Conversation
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is great @es92! Just a couple of comments on format & some potential additional requirements that came to mind 😃
1. An iOS & Android App that uses NFC to allow users to get the data from their own passports, and store that data in their MINA wallet for secure use by web3 applications through the (in-progress) Mina Attestation API Standard. | ||
2. An o1js library that uses the Mina Attestation API Standard to create proofs of various components of one's zkPassport identity, for use in proof-of-unique-user and proof of nationality & age use cases. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another great feature would be if the zkPassport is a credential owned by the user & stored in the wallet, then compliance with W3C Verifiable Credentials Data Model. This would help applications that held the credential to standardise indexing and handling of the credential.
I'll also post the wallet attestation APIs shortly that can be referenced here too.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Very curious if there is a need for a iOS & Android App when NFC could be connected with a standard browser similar to friend.tech
Tested the following website with my cheapish Android phone on Chrome
https://whatwebcando.today/nfc.html
Some Dell computers also come with NFC
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Using NFC scanning directly in the browser instead of creating separate iOS & Android app would make the process more modular and user-friendly, I think. It would be simpler and more direct: go to a website, scan your passport using NFC, and then transfer the data to your wallet, zkApp, etc.
I think the Web NFC API currently only supports basic scanning functions. With a passport NFC scan, there's an additional step to decrypt the data using a key found on the passport's first page. This particular interaction isn't included in the native Web NFC API, I think.
I hope this is achievable. Such a fantastic use case.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yep, the Web NFC API doesn't support reading passport unfortunately.
|
||
## Abstract | ||
|
||
This RFC proposes a grant to build a private proof-of-passport attestation (zkPassport) leveraging smartphone NFC, ZKPs, and Mina, with an aim to provide a private identity primitive for Mina, blockchains that are connected to it, and ultimately web2 applications. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome! 🦾
| Aspect | Description | | ||
|------------------|-------------| | ||
| **Description** | A zkApp wants a user to prove facts about what country they are / are not from. | | ||
| **Requirements** | An implementation of zkPassport in the Attestation API Standard (see objectives). | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another requirement would be to use the Attestation API to recursively prove many properties of a credential. For example Prove(Prove(nationality===UK) & Prove(documentExpiryDate>currentBlockHeight))
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it will be good to add a link to the mentioned MINA Attestation API.
RFCs/rfc-0007-zkPassport.md
Outdated
| Aspect | Description | | ||
|------------------|-------------| | ||
| **Description** | A zkApp wants a user to prove they are unique. | | ||
| **Requirements** | An implementation of zkPassport in the Attestation API Standard (see objectives), plus an on-chain nullifier that users can use with the zkApp. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
As well as nullifiers, users can also decouple an on-chain identity from the zkPassport credential with a Diffie-Hellman like key-exchange with the credential issue using viewing keys where viewing key is something like Poseidon.hash(PrivateKey.toFields().toBigInt())
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Oh interesting - I'm not sure how this would work exactly though? What exactly is it accomplishing?
|
||
Lastly, a passport isn't something that everyone has or is able to get, so this is unlikely to work as a universal solution for proving personhood. That said, it could be a useful "anchor", for decentralized social-graph based approaches, which I think could be promising future work. | ||
|
||
This could be done via passport-holders verifying non-passport-holders. One way this could work is requiring multiple passport-holders, say 3, to attest to the validity of a non-passport-holder, and limiting the number of times they can do this (if 3 passport-holders are required, and each passport-holder gets 3 verifications, this would mean each passport-holder could verify up to one non-passport-holder on average). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Social identity is really cool, I like this one! 💡
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is interesting but really difficult to avoid collusion of passport holders to validate a fake/malicious non passport holder. The validated malicious non-holder can latter perform malicious actions without any difficulty. The non-holder may not even exist and be just a way of the 3 holders to act together and perform some action. Having no traceability back from the initial holder approvers to the fake non-holder also makes it quite worse.
Validating identity by social methods is much more complex. ProofOfHumanity has some way of doing it, we used randomly chosen anonymous trusted validators in the Identicon protocol (the idea that originated Socialcap), and there are others.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
BrightID is another viable identity model
Revoking identity and multiple validations could be another way to solve this
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Proof of uniqueness can be a solution here if user don't have passport or prefer not to share the data. Any kind of social system is always open to be gamed
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I dont think the solution is to track every single person all the time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
A remaining question is exactly what new cryptography primitives would need to be implemented in o1js, if any new ones are needed. It looks like RSA, DSA, ECDSA, and Sha-xxx are used (see pages 15, 16, and 17 here[4]).
I've looked around in some other places for confirmation, and this seems to be the full list!
All the tech checks out by my reading, this will be a very exciting addition to the ecosystem.
Nice! Do you know if this is already all in o1js after the recent ECDSA/SHA256 work, or is there more that would need to be in any grant on the cryptography front? |
I don't know about the status of the Sha-XXX hashes, but let me ask around. We already have ECDSA, and I've heard about since experiments on the DSA and RSA fronts though, so we're close already! |
Just came here to say that this is a fantastic idea that seems technically feasible and extremely promising! |
Now that the Attestation API RFC is out, we can link the two together! |
I think this is quite useful and many apps in MINA may benefit from it. Having a well defined and standard way of doing identity verification is key in many uses cases. Socialcap is one of them, and any credential system may benefit from it also. In many cases you don't even need to access any personal info, just the verification that this is a "unique" person. I also understand this will be limited to just passports with NFC enabled, and this creates some issues:
So I think this may be a good starting point for a more complete "identity verification", but many border cases should also be acknowledged. Vitalik's post What do I think about biometric proof of personhood? shows the difficulties associated with identity verification in general (including both biometrics and social proofs). |
Continued thinking about this, and what this will actually prove is that "someone has a given NFC enabled passport in his/her hands". It does not prove that that person "holding" the passport in his/her hands is the real owner of the passport. The passport could have been stolen or even belong to a dead person. That is why all KYC programs require you to take a photo of the passport and a real time video/photo selfie to assert you are alive (proof of life) and that both are the same. As I mentioned before "identity verification" is tricky :-) |
And just to finish here (sorry for the long comments) this graph from Vitalik's article helps to define the scope of the NFC passport proposal: I would say that it falls in the "Specialized-hardware biometric" category, because in person biometrics are used and verified by the country issuing the passport when the passport is requested. In fact the passport is a readable paper/electronic proof of that biometrics verification. And so, for all the recursion fans here, it wil be a proof of a proof. |
Thanks @mazito , some thoughts:
|
|
What if there are mutliple issuers attesting the same information, similar to having multiple passports. |
I just want to go ever few points and share our knowledge on certain aspects of the topic here. There is no way to verify an NFC actually being real on its own. It can be easily faked. That's why the entire online KYC/AML process relies on facial recognition to match the OCR-extracted data from the passport. To tackle this issue, there are a few ML/AI-based software solutions and a few new upcoming challengers which specialize in these kinds of documents and require human presence for verification. There are reputable third-party auditors for these software solutions. For example, ibeta.com conducts tests on accuracy, penetration, etc., from face scans to fingerprint scanners, which governments use in border controls and embed in passports. The digital ID space has been booming in recent years, with many governments exploring experimental solutions that prioritize privacy. I can provide a few examples of this trend. In the UK, digitalidconnect.com offers a standard framework for digital ID. Meanwhile, oesterreich.gv.at provides a direct digital ID from the government, phasing out plastic IDs. I believe that in the next 5-10 years, we will see a full transition towards digital IDs, which will be much easier to integrate with ZKpassport. For special hardware biometrics, the only affordable solution would be fingerprint scanners. To my knowledge, there is only one company that creates portable/small fingerprint scanners usable in this manner, which could still cost $40-$100 each, plus logistical challenges and distribution costs. We believe the biggest issue is the duplication of identities. Because the space is growing very fast, everyone is trying different approaches. For example, digitalidconnect is a standard only for the UK. Even if we establish global standards, I don't think the isolated structure of these solutions will change because each solution accesses specialized data from local government databases, etc., for verification. I don't see governments sharing all this data in a global system as sensible. |
@EmrePiconbello according to the RFC, passport data is signed by the host country. we would verify that signature in the proof. you wouldn't be able to fake that. |
@mitschabaude I am not saying that NFC data is forged. Issue is NFC is very easily cloneable and the verification signature is part of it. While you can't alter the data(data can be outdated etc. those are still the downsides). On it's own nfc part of very easily duplicated. You just need to close enough with nfc device for few second. Implementing that would be very wrong in my opinion just because of that reason. |
Besides reading the data from the NFC chip, seems like it is also possible to verify if the data and chip are genuine and not cloned or faked. https://www.inverid.com/blog/cloning-detection-epassports |
Thanks on this - just added a section commenting on exactly what is being proved here and on security. |
We did research on this over a year. Unfortunately I don't have like resources on me right now but with quick google I find this. I like to summarize what I know concisely. We have many methods. Chip Authentication, is secure can still be compromised if a chip is extracted from a legitimate passport and placed into a fake one not to mention it doesn't protect from cloning. However, integrating the chip brings complexity, and many countries, including the majority of the EU, do not utilize it. Not to mention chip doesn't block reading the data. Since there is no standard and it's all around the place with suggested not mandatory implementations. Even when better standard is implemented support for older ones existing just makes it insecure. Additionally, we have a system that verifies these different types of authentication systems. However, due to the lack of uniformity and insufficient security measures behind these methods, as evidenced by extensive research with companies developing hardware and software, along with third-party auditor firms testing these systems, we have concluded that matching all elements provides the highest level of certainty the person and document present at that time. This matching aligns with legal standards for verification. Our focus remains on biometric authentication solutions, as there are few products we wish to explore in this area. We are currently looking in to portable fingerprint scanners viability. While we are not experts in this space, considering the global usage of the same few software and hardware solutions utilized in law enforcement, border controls, and banking, despite differing approaches, instills confidence. |
|
||
A remaining question is exactly what new cryptography primitives would need to be implemented in o1js, if any new ones are needed. It looks like RSA, DSA, ECDSA, and Sha-xxx are used (see pages 15, 16, and 17 here[[4](https://www.icao.int/publications/Documents/9303_p12_cons_en.pdf)]). | ||
|
||
It seems countries keep databases of lost, stolen, and revoked travel documents[[5](https://www.icao.int/publications/Documents/9303_p2_cons_en.pdf)]. It doesn't seem like this is public however, so there may also have to be logic for invalidating one's old passport if one gets a new passport (due to the old one either being lost, stolen, revoked, or just expired). |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
They have their own databases but it's not public. When passport is issued. The certification and data of it is valid on average 10years +3 months. So if they are stolen, lost etc. You can't use it to exit the country since they would know while you trying to leave. To my knowledge from NFC stand point there is no difference and I don't know any country with public DB on these documents.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
My understanding is that 10 years is the number due to expiration of NFC tags
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
In Belgium citizens can log in to their government services portal with eID card reader
https://www.youtube.com/watch?v=RBFe-FdPw34
It only requires a pin number, eID card reader and a card
The security can certainly be enhanced with MFA
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What you outlined here is eID not a passport. The 10 years is because passports are mostly valid for 10 years the problem is NFC is permanent the certificate is 10 years + few months so if it's stolen or something it will be always valid when you are checking it according to certificate.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
No, NFC tags typically expire in 10 years. I have seen this number on vendors pages, articles, etc
For example,
Finally, NFC tags could also be deleted if their data retention time expires. Data retention on NFC tags is intended to last for a set amount of time, typically 10 years. The tag might not be able to keep data properly if the data retention time has passed.
https://taptag.shop/blogs/how-tos/ways-an-nfc-tag-or-nfc-card-can-be-erased-magnets-heat-etc
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sure, but we can create an api service that helps in emergencies and that stores and is responsible for the data storage
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Here is NFC Tag Issuance Process from Near Field Communication (NFC) Technology with Jordan Mobile Payment (JoMoPay) https://www.cbj.gov.jo/EchoBusV3.0/SystemAssets/PDFs/EN/NFC.pdf
there are 3 pages more in the pdf
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ideally, any architecture makes it possible to override a previously registered passport with a newer one. That seems to be an important fallback flow in case your identity is stolen. If that is possible, it doesn't matter how long the original passport or NFC tag is valid
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't think that covers cloning or stolen at all. As random people from earth's population. I will never learn my identity utilized on mina blockchain in the first place.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, it doesn't cover that (a liveness test is also needed), but in an ideal system you can still override an old passport + liveness test with a newer one, and so it doesn't matter how long the old one is valid
@es92 cc @teddyjfpender and @mitschabaude there have been quite a few really good zkp ID proposals in zkIgnite 3, see, for examples: https://zkignite.minaprotocol.com/zkignite/zkapp-cohort-3/feedbackandrefinement/suggestion/652 Each of them have sound and unique implementation plans, but they all touch upon the interactions with passport. I'm sure etonec is similar too. To fully take advantages of the talent and make them pull in the same direction, I personally think it might be very beneficial if Mina Foundation could form a working group on zkp ID, regardless of the funding outcomes of the zkIgnite proposals, so that these teams can participate in the discussion about zkPassport and expand its horizon on potential applications. |
@EmrePiconbello raises a point regarding cloning. Besides this, people give their passports to others for all sorts of legit reasons (getting a visa, checking into a flight etc). Passports get misplaced or stolen all the time. There is another, more subtle and more severe issue in the proof-of-uniqueness proposal outlined here. The proof-of-uniqueness secret has to be computed from some constant value such as the user's government unique ID. Whatever computation the user does in isolation can be replicated by a motivated actor to link all on-chain traces to people's government IDs. Note that even the nullifiers are deterministic functions of the proof-of-uniqueness secret, so the motivated actor can obtain the user's government ID just by looking at the nullifiers. (note government unique ID search space is tiny, even if it weren't guess-and-check attacks make this a no-go) Fortunately, one can engage in a trust minimized zero-knowledge protocol, which achieves info-theoretic unlinkability between the user's IRL ID and the proof-of-uniqueness secret. See this (for now; we'll make a public doc as soon as we can) https://zkignite.minaprotocol.com/zkignite/zkapp-cohort-3/feedbackandrefinement/suggestion/739/detail |
Just to add to the list, we've developed a fully functional zkp ID app as part of zkIgnite 2, called id-mask. Currently, the app's reach is limited geographically because we've only integrated it with a single local KYC personal data provider. Eager to see how can we leverage passport-NFC interaction. Moreover, I believe there are some unexplored issues that every zkp ID app will encounter later on. We briefly discussed this with @EmrePiconbello on Telegram. How can we design systems that prevent others from sharing proofs? For instance, once a zk-proof is created using passport-NFC, how do we ensure that only the original creator of the zk-proof can utilize it, preventing unauthorized sharing? |
| Aspect | Description | | ||
|------------------|-------------| | ||
| **Description** | A zkApp wants a user to prove they are unique. | | ||
| **Requirements** | An implementation of zkPassport in the Attestation API Standard (see objectives), plus an on-chain nullifier that users can use with the zkApp. zkPassport nullifier proofs should be sure to have a *context* input salt that is hashed with the unique zkPassport identifier to ensure identities are unique across their context, but cannot be associated cross-context unless a proof is provided by the user. | |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@KimlikDAO-bot this is one way to ensure that identities aren't traceable cross application - the salt can make sure that how one proves uniqueness for one application isn't traceable across applications.
It would probably be important that however wallets interact with nullifiers, wallets check and make sure the same nullifier-key isn't being used across applications
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Unlinkability between different on-chain uses can be achieved via nullifiers, we are in agreement there. This is also how our HumanIDv2 is designed.
The devil lies elsewhere: ensuring unlinkability between any of the on-chain uses and my IRL id. It appears that there is no way to achieve this if the user generates the proof-of-uniqueness secret in isolation (without talking to anyone else)
Any time you use the outlined system, anyone observing the Mina blockchain can just brute force the user passport number or SSN, whatever constant value we're using for the secret generation.
For instance folks below are suggesting using (name, lastName, localIdNumber) as the basis for proof-of-uniqueness secret. With this proposal, taken on face value, anytime a user includes a nullifier in a Mina tx, we can easily brute for the (name, lastName, localIdNumber) of the user
The path from (name, lastName, localIdNumber) to the nullifier is entirely deterministic. (It has to be, otherwise it will not ensure uniqueness)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yeah that's a good point. I think for this passport case, I think there should be enough data to avoid this, by using the passport signature from the authority itself as part of the hash - so unique_passport_hash = hash(passportSignature, passportData)
, and it shouldn't be brute-forceable I think.
And then using hash(application_salt, unique_passport_hash)
for any nullifiers on-chain to avoid revealing the unique_passport_hash, seems like it should work. Even if the application_salt is constant, there shouldn't be a way to find the unique_passport_hash then, (or the additional requirement of creating a proof that one possesses the data underlying that hash that has been signed by the passport authority).
Any group implementing / auditors should definitely make sure this works out in the implementation and specifics of any passport cryptography though, as well as put together a more complete spec. Curious if you think this seems right or any other thoughts though.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am not a fan of using the passport signature as entropy. This gives the passport signing authority (or even airlines) full surveillance over all on-chain sybil detection. Anytime someone uses on-chain sybil detection, the full passport data becomes available and gets linked to their wallet address for certain organizations and companies.
The good news is that we have found a solution through a novel zk protocol: the user has to talk with n parties but in a totally zero-knowledge way. While minting their on-chain ID, the user engages in bilateral communication with n parties (nodes) to obtain their secret shares and combine them in their own device. This bilateral communication reveals nothing about the user, based on the security assumptions of Kimchi. At the end, the user obtains a proof-of-uniqueness secret which provides
-
information theoretic unlinkability to their IRL ID, even from the perspective of n-1 colluding nodes.
-
different on-chain uses (through nullifiers) are unlinkable based on Kimchi assumptions (just like in this proposal)
Full details: https://zkignite.minaprotocol.com/zkignite/zkapp-cohort-3/feedbackandrefinement/suggestion/739/detail
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Ah I see, yeah that makes a lot of sense. Yeah it would probably be best to avoid the passport authority being able to do that.
Maybe the following could be done to do this without needing a multiparty protocol? (and any additional trust assumptions that would need to follow from that?)
- have an "identity-registration" zkApp, that uses a nullifier using the passport-authority-visible hash as the key, to allow users to register their own user-selected unique hash.
- have other applications use the user-selected hash for proofs of uniqueness - which should work because each user-selected hash corresponds to an passport-authority-generated hash, and there isn't a way to generate multiple user-selected hashes per passport-authority generated credential.
Curious on any thoughts? Seems like something multistage is needed though yeah for on-chain privacy from the passport authority.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
For the Bloom filter: not only do we get the final Bloom filter, but also all the intermediary steps. This should reveal the same as the Merkle tree, no? There may be a solution along these lines though
Differential privacy literature may have something for this
There may be a randomized algorithm for this and the user may prove that I know a seed such that Poseidon(seed) is used as the random source for the algorithm and ...
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Well actually I think the front-running thing can be solved with a commit-and-reveal scheme. You "preregister" first, by showing a blinding commitment to
P
i.e.H(S, P)
. And it's only possible to register once n blocks have passed since a preregister was done. So, unless someone manages to completely block you from posting a transaction for n blocks, they aren't able to front-run it because they'd need to create their own preregistration after seeing your data
Yep - further, the zkApp can require a proof that alice knows S in H(S), so knowing H(S) shouldn't be enough to front-run then either (if we're talking about front-running H(S)).
I'm not sure on the entropy, but I'll add that to a "todo" section of this RFC - I'd think there'd be enough entropy between all the data in P (includes I think maybe fingerprint / photo data as well?) and the signature from the issuing authority, but its definitely something someone on the cryptography side should check (it sounds like definitely a risk at least to make sure of).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depends on passport since they are all around the place but majority of them have very low entropy because of limited bit space they have and data they need to put in to that space.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Depends on passport since they are all around the place but majority of them have very low entropy because of limited bit space they have and data they need to put in to that space.
This is false. Even if you put 128bit RSA signatures behind a hash function they will have roughly 128 bits of entropy. I cannot fathom passports having less than 128 bit RSA. Note RSA 128 is believed to have less than 30 bits of security if you show the signature outright (without hashing)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
https://eprint.iacr.org/2005/095.pdf
This is the most detailed document. While this is old if you do your research you can find this still applies to many passports globally. The biggest problem comes from general practices since this paper didn't change. Few countries changed their structure and it's safer, majority of them didn't make that. There is a new standard published but it's a big question when it's adopted or even at all.
Thanks for the suggestion @lampardlamps on that note I like to add this. Because we have been conducting our research and planning for a very long time, I mentioned something similar to this in our proposal since zkIgnite 1 or 2. Now that we are preparing to launch the product, I want to discuss the details and establish some kind of standard, as our aim is to link all ID solutions to a single ID. Recently, @RaidasGrisk was very helpful with his insights on the matter. He developed ID-Mask, and I believe we have found a middle ground with a structure like hashed (name, surname, personal number) as public output. There is a lot of variance, which could be a limitation for some solutions, as not all solutions might include a personal number. I firmly believe we need these discussions to establish some kind of standard/best practice so that future interactions between these zkApps would be smoother. Otherwise, we will end up with many solutions that are disconnected from each other or cannot work with other zkApps. |
@RaidasGrisk
This should be covered by the Attestation API, to make sure it doesn't leave the wallet of the user who has created the attestation. This would ensure browser pages cannot access the original credential, and only get context-specific proofs. |
Agree & that definiteley makes sense re some kind of working group btw, I can check in if there's bandwidth to organize it or if it would need to be more adhoc, lms |
You can ensure that the sender is the owner by implementing a function with struct that checks who sent the message and whether the struct owner is the same as the sender code from https://www.npmjs.com/package/pin-mina and @method initNft(item: Nft, keyWitness: MerkleMapWitness) {
let initedAmount = this.totalInited.getAndRequireEquals();
initedAmount.assertLessThanOrEqual(this.maxSupply);
const sender = this.sender;
sender.assertEquals(item.owner);
...
} the struct export class Nft extends Struct({
name: Field,
description: Field,
id: Field,
cid: Field,
owner: PublicKey,
}) {
changeOwner(newAddress: PublicKey) {
this.owner = newAddress;
}
} |
Do these solutions assume that a public address is linked to single IRL identity? Let's think about proof-of-adulthood again. Two people work together to cheat the system: one is an adult, the other is underage. The adult uses their passport (or other means of passing private data) to create proof-of-adulthood. After making the proof, they link it to a public address (ignoring how it's done). Then they give the underage person the private key for that address. This tricks the system, right? Is this a big problem with the system? The way we currently check for adulthood can also be cheated in similar ways. But if we aim for adoption and if more people start using the new system, they'll look for security problems. Would the government approve of this system if it has such flaws? I'm not sure of a good solution, just want to point out the problems so we can find good solutions. |
@RaidasGrisk Evan's architecture outlined here, and also the system of Worldcoin which is similar, ensures that every IRL identity can only be linked to a single public key. (That property is needed to make it a proof of uniqueness!) So, yes, an adult can create a unique ID and then let their child use their computer (absolutely unavoidable feature of every digital system). But no, they can't create multiple wallets all "proved to be owned by an adult" and then hand them out. So, AFAIU, the issue you're concerned with is avoidable. Btw, re ensuring in a zkApp that a user owns a certain address: It's easy - you just need to create an account update for that address and require a signature on it. let update = AccountUpdate.create(userAddress);
update.requireSignature(); @Pfed-prog the solution you posted is insecure, because |
How do you achieve uniqueness here I don't get it. |
Private zkPassport registration
I looked at @KimlikDAO-bot's proposal and wanted to highlight it because it shows a way to avoid the privacy concerns of registering with a potentially brute-forceable passport hash which has to be sent to the chain in the open. I'm not fully convinced that the protocol as written in the zkIgnite proposal achieves uniqueness/privacy (will comment on the proposal), but the core idea is great and works. I'll describe a slight variation of it here, that I think achieves both. For simplicity I only consider the passport NFC data and no extra liveness check. The protocol consists of 3 steps, which I first summarize in non-mathematical form:
This protocol achieves creating a Merkle tree of unique humans, which can now be used in several ways - either for anonymous use cases like private voting, where you just show that you own one of the addresses in that tree but not which one, and post a nullifier (so that every human can only vote once) -- or even for use cases where you interact with your address in the open and can prove that it is that of a unique human. The committee only exists to assist with encryption. They are not trusted with any authority, and they have no access to the private passport data. Only by colluding and putting their secret keys together they might be able to brute-force the original passport data, and learn the identity of a user who registered (but not necessarily the address they registered with if we only store a commitment to that). We can increase the number of committee members from 2 to n to gain more confidence that at least 1 of n members will not collude. Mathematical detailsEDIT: I originally posted a flawed version of this protocol. Below, you find the fixed version. (This is one possible way, I'm sure there are others. This here only relies on provable operations that exist now in o1js) In short, the unique human ID that is computed in the final step is where Preregistration. The user calls a zkapp method The user also passes in a random scalar Encryption assistance. This can happen offchain. Recall that the two members of the encryption committee have private keys The user sends They also send an offchain proof of this computation, created by a Final registration. The user calls a
|
Hi @mitschabaude, thank you for your kind words and thanks for the mention! I still didn't get a chance yet to digest your post fully. Allow me some more time. In short, in our solution, we use functional signatures (as opposed to relational signatures, where single digest may have multiple valid signatures) as verifiable hash functions. The humanID secret is simply the sum of n parts, each of which is a (deterministic) hash of the user government ID number (example: user's SSN for a user from the US). This ensures that it's unique, right? |
Ok, so here's how I understood your proposal -- the "shares" are the BLS signatures by the nodes after we multiplied by for any candidate This can be easily fixed by hashing the The second issue is that you don't really describe (or maybe I missed it!) how the user proves to other parties that he has a valid, unique human id. You write
However, if I'm concerned about uniqueness, it's surely not enough that the user knows that they have a valid unique id. Others must be convinced of this as well! Otherwise the user could just make up a number and say "this is my unique id". Both of those issues are easy to fix and I really appreciate your input and proposal @KimlikDAO-bot! |
I want to get some details about brute forcing argument with hashing since I believe there is enough entropy. Let me start with example. Leyla Shashi Bláha Here are 5 outputs from a random name generator. Considering all languages and different symbols and them being different codes in Unicode. People can have 2 names or even more. There is no standard for GOV ID numbers either, with some having not just numbers, and their lengths varying greatly. With all these variables, I don't understand how this can be brute-forceable since any hash we see can be from any country with any form of different structure. Creating this kind of hash's aim was making possible same user can be know to zkapps by different ID providers. If that's not a solution we still need some kind of standard to make this communication possible. So I like hear people ideas on that matter and how we can achieve that. |
Great, thank you! Your solution fixes some important issues and simplifies the proposed protocol overall. Some bells and whistles:
For a passport with AA support, the passport signing authority signs In our case, before we talk with the encryption helpers, we will send the challenge We will send a proof to the encryption helpers attesting
This way even if the dApp code steals the users HumanID secret, they cannot generate new nullifiers with it, but they can detect the user's past actions. |
IMO we want to prevent even very common names, and passports that have the most standardized GOV ID, from being brute-forceable. Also, I think it could be an issue to include the name in the hash that forms a unique ID, since names do change at least once in the life of many people. They could get a second "unique" ID after marrying :D @EmrePiconbello do you know whether parts of the data on each passport are absolutely guaranteed to be unique over the lifetime of a citizen? GOV ID maybe? If yes, using just this unique part as The other, non-unique parts that we also want to associate with a user, like name, could go into the commitments that form the Merkle leafs. (Or could be stored alongside the ID in other ways, depending on the architecture) |
@mitschabaude With your permission, I'll update our proposal to fix all the issues in the protocol and to give you due credit. Btw,
Such a hash gives anyone a lookup table: if you know someones name and id, you can lookup their Mina wallet address if they have used the zkPassport app (or ~50 likely Mina addresses if the pre registration is used.) We don't need to try all possible unicode characters. Even starting from a simple names dictionary one should be able to brute force all of it in minutes. If you have a list of names / government IDs in front of you, like a state actor or a large company would have, no brute forcing is needed. |
Sure, thanks!
The idea for preregistering was to avoid the problem with getting frontrun, i.e. as you're trying to register your humanID (sending it in the open), someone else does so before you can. I was thinking about the specific context of registering into a Merkle tree of confirmed unique humans, which I thought was useful.
At first glance this sounds like it could also work. Although I see potential downsides with not recording that stuff onchain:
|
Would something like this be possible: The communication with the encryption helpers happens using Vesta points. I generate the proof of correct derivation of the human_id_secret only once and then store this proof off-chain (for instance inside the KimlikDAO Pass) When generating the human id nullifier, my circuit would prove that there exists a proof of correctness for the humanID and that the nullifier is computed truthfully using the correct human_id. The exact details above may be inaccurate, but can't we efficiently prove the existence of a correct proof and then prove other things such as correct nullifier computation? |
We can do that, but again, both the proof of correctness of the humanID and especially the recursive proof verification take quite a lot of constraints that would make everything that uses humanIDs heavier than necessary |
GOV ID is mostly a 11 number. Since there is no standard there might be regions with less and that can be a problem even if we are combining it name and surname prehash.
Yes it can change. Considering everything like these with about a year of research we come up with this proposal to cover everything. https://zkignite.minaprotocol.com/zkignite/zkapp-cohort-3/feedbackandrefinement/suggestion/652/discussions uniqueness actually comes from ml extracted data from face being hashed.
GOV ID doesn't change but not all passports have gov ID in it :) I don't think we can achieve it from any government document consistently. In another note. The hashing part of name and gov ID is actually match the users id's we can avoid them putting as a public output if we can't find a way to achieve this safely. The reason we look for something like that is. We plan our platform as a bridge for all identities so when pass3 user said this is my idmask user I want to link them. We need to run some kind of check to be sure these two identities at some level for same person. The putting it as public output was generally make it more user friendly for zkapp developers so they can know who is unique or not between id protocols. Considering what we discuss this doesn't likely but still we can have something like that where id protocols can link with other id protocols on client side. |
@EmrePiconbello thanks for your insights and research. It seems to me that the best solution, in a first iteration, might be to restrict the unique proof of personhood to people who have such a unique government id available from a signed document.
That doesn't sound like something you can do in a zk proof though, or that can be trusted by a smart contract and used in a permissionless way. I'm looking at your architecture diagram https://www.mermaidchart.com/raw/4861da3a-9370-417a-b3fb-861f585f086f?theme=light&version=v0.1&format=svg There's no detail about the role Mina or zkApps play in it - just two steps "create proof of user" and "validate proofs". Proofs are created by the Pass3 backend, with the input of a face scan which was confirmed by the facetec SDK to be a unique human. It seems that the facetec SDK is able to tell you about uniqueness by asking their database about previous face scans. See facetec.com:
Obviously there's no way to put this interaction with facetec inside a zk proof. You can prove pure computations, but not network calls or lookups in a traditional db
|
@mitschabaude we are open to any solution and like to pivot if we can have a conviction on a path there.
Extensive research needs to be done to single out the weak ones if this approach is utilised, which would limit the user base drastically. For some of the “unique” ones, there is an essential algorithm involved to generate, such as one digit being specifically one number according to the gender and such, hence it reduces the entropy drastically and opens the possibility of brute forcing.
The aim here is keeping the shared and stored data at minimal. For low risk authentication, utilising recursive proof with simple data verification(such as some basic info gathered via NFC scan) is the main part where Mina comes to the picture. Yet, due to the uncertainty of our current design in terms of public and private fields on chain due to having no certain standardisation, further examination is required to ensure the correct way of implementing the flow with least possibility of forge, as well as with least public information.
Proofs are generated by the user side. We have the software, and we have full control. In the proposed approach, we match three elements from the user: passport data from NFC, passport data from OCR, and matching face data with the face obtained from OCR and NFC. Here, the SDK does the work on the client side. The server verifies the liveness and returns a positive or negative result. The proof is generated according to this response on the client side.
Yes, unfortunately, the machine learning model is very resource intensive, making it unsuitable for running on a phone. We are not planning to utilise continuous face scan authentication. The current plan is to store the hash result from the scan on a data availability solution that we can utilise.
It's not just about the face, as I shared above; all the methods need to match. You can't invent unique hashes without performing these steps. Additionally, there are only a few organisations conducting audits/benchmarks on these solutions, and they measure FRR (false rejection rate) and FAR (false acceptance rate). According to these metrics, they rank among the top performers, with rates as low as 0.0000008% in some cases. We cannot tamper with the software SDK (I believe we can utilise the SDK inside proof) and server-side function simultaneously. Therefore, we cannot push a random hash from the server side as long as the SDK is utilised on the frontend, which will be public. The plan involves storing the hashes on the chain, but due to limitations with Mina, we are still uncertain about how to approach this. We want the hash storage to be public if it cannot be verified with zkApp. We are still considering many options, such as verifying age without uniqueness or verifying specific data aspects, since it's customizable.
Pass3 is our branding; we utilise the technology from FaceTec. In every existing solution, you need to place trust in one of the many providers around the globe. They all undergo audits and benchmarks from organisations like NIST.gov, iBeta.com, etc., and comply with many standards. The issue is that you always have to give your data to a third party for compliance. For example, https://www.jumio.com/kyx/ has a direct plugin for AML screening DB provider, which performs the checks. However, for these checks, they need to share your data, or after KYC, they need to retain your data for 5-10 years, depending on regional laws. There are only a few solutions that allow customers to build a custom solution. That's why we are not offering any compliance and legal aspects; we are simply providing verification. For each verification, we require all the steps again (because we do not plan to store any identifiable data). However, after completing a full ID enrollment, something like a signature from a private key combined with proof generated from NFC data could be sufficient to authenticate low-risk cases. Our long-term plan is to run it in a hardened confidential VM environment, where it is completely isolated. Additionally, we will strive to make it as open as possible or have 3rd party audits and certifications. The proposal is kept simple and concise because when it comes to these details, it quickly becomes out of scope (due to the delivery timeline of three months) and complicated. Also, some decisions about the flow will be made based on the viability of zkApp and ProtoKit. Since we are not 100% familiar with the platform we are building, we do not want to create detailed flows at the start and end up delivering something completely different due to limitations. In summary, our goal is to deliver the most private and unique ID solution we can on the platform, solving ID solutions interoperability issue. As a final note, as outlined in the proposal, many governments are currently exploring digital ID solutions, with some testing or migrating towards them. These digital IDs are mostly developed with privacy concerns in mind. Since they are directly from governments, they are also compliant. In the very long term, what we envision is that instead of KYC providers like Onfido, Sumsub, and many others collecting vast amounts of user data and relying on these solutions for compliance, they would store proof of digital IDs. |
You can't use the facetec SDK inside a proof
Before worrying about how to store hashes on chain I really recommend to think about how to prove that those hashes are not just random numbers. From my perspective, that's a core part you need to get right and not a detail to be figured out eventually. |
I should be more clear. They have a sdk which some part of it is OCR functions so idea here is utilizing them. One more thing we have as a options is building simple OCR which can be run in proofing. As long as first onboarding combining all factors of OCR-NFC-Liveness the authentication mostly will rely on the linked wallet and occasional checks which is not all elements but for small data match from NFC or OCR.
Here, I am not sure, so I'll answer from two angles. When we talk about our backend just throwing random hashes to the front, and since our backend can't be run inside a proof, there are a few ignited proposals around ML and AI. One of them revolves around proving computation, so if something like that is possible, we'd like to explore it. However, in the current state, we don't have a way of running these computations inside snarkyjs. Also, I don't think it's a very realistic expectation because with all ID solutions and everything, you get verification from somewhere. It could be a government endpoint or a KYC provider, etc. You don't run their software in snarkyjs; you just build an oracle which verifies the data from them. This is what our proposal is at a very basic level. Where we differentiate is we have control, so we can adjust it according to developments. We can extract the data and verify it on the client-side without sharing any data on our end, but that brings a lot of issues with fake IDs. Here's a recent article https://x.com/josephfcox/status/1754514949995384996?t=PO5Nnvn4IzCRv4LS6I-LJA&s=09 where OKX, which looks like it was not doing enough for KYC/AML, is mentioned. They are using Jumio, which I mentioned above, and they have a liveness check, AML, everything baked in, but OKX prefers not to utilize them (I am speculating at this point since I can't know exact details, but this mostly happens because however all these solutions claim easy onboarding and everything, people mostly do not comply with following instructions or try to do the process in very suboptimal conditions with a dirty camera lens, a lot of glare, etc., so instead of losing the customer at onboarding, they do this so they can onboard users without friction). The reason we are taking all these steps is to ensure fake or cloned documents are not getting in. When we talk about the hash, they are not just random numbers; they are the result of user data. It's not in our core plan to utilize something like that, but we believe it is required as a standard. So, at least some part of the ID solutions would have certain aspects that can be interoperable and utilized by zkapps. Since this hash is derived from the user data which exists on the user's client where computation and proof generation happen. |
No description provided.