Proof of Baguette mints you a Soulbound Token if you are a holder of a passport.
Proof of Baguette fetches the cryptographic signature of a user's passport (leveraging electronic passport NFC chips) through our Android app and verifies that it was indeed signed by the issuing government. If so, the phone app sends the signature to our Web frontend.
The user can go to that frontend and input their passport number; after which they'll be able to mint the Soulbound Token (SBT).
We are able to verify the signature onchain through a ZK SNARK verifier contract that we generated from a custom circuit. That custom circuit takes the passport data and the signature privately and verifies them with the public key associated with the passport (owned by a government). If the verification goes through, the SBT is minted.
The signature is verified with RSA and SHA256.
This project forks two other projects in order to build on top of them. The first one is an Android app (written in Kotlin), called passport-reader, that scans the passport. We modified it in order to extract the signature and send it to our Next.js server.
The second one is zkrsa, which contains a circuit to verify RSA signatures and a frontend to generate proofs. We modified the circuit to allow for private data (it was all public) and to bind the verification to an address (to avoid mempool frontrunning) and then generated the corresponding Solidity verifier contract. We also modified the (Next.js) frontend in order to, firstly implement an API that can store/retrieve temporary passport data (for the verification) and secondly add the functionality to actually mint the SBT. We also had to do heavy work to make all formats work together between the Kotlin code, the circuit and the Typescript which all had various ByteArray and hexadecimal implementations.