This is an attempt to consolidate and clarify the idea from this tweet stream
Sign-in with Zcash
Background
I have been thinking about how to make register/login with zcash work for sites.
Websites need a secure way to validate users are who they say they are, and most users understand the username/password registration process is out of date, risky, and creates a poor user experience as their data is stored on the server. Fido2 and other key sharing scheme exist and are industry best practices. This method is similar in concept, not execution to fido2.
Zcash currently lacks the ability to sign messages with a z-address and it is impossible to verify that a given z-address belongs to a user(by design). This could be accomplished with ZIP-304
A UA can solve for both problems. Using a UA as proposed, the system is forward compatible since a UA could be extended to new pools and retain the same T-addr.
Motivation
Users
- A SWIZ Tx would be indistinguishable from payment transactions and increase the shielded tx pool volume.
- A user could be signing any arbitrary data and processed by the server:
- Viewing key
- User information updates
- IPFS hash with user data JSON
- Creating a secure two-way communication (push notifications, subscriptions, etc.)
- Making sybil more attacks costly
Websites
- The fact that the server receives no secret has far-reaching implications for the security of users and organizations.
- Databases are no longer as attractive to hackers because the public keys aren’t useful to them
- Some sites will charge a 'registration fee' since sending memos is not free. A fee of .01 zec ($.04) would cover the fees for 1000 logins, sites could charge a premium or subscription using this model
Assumptions:
Users
- a user generates a UA with at least a p2pkh and orchard addy per site they interact with.
- never use the UA for anything other than interacting with this single sit
- is comfortable with 0-conf transactions since little or no value is exchanged
Website
- has a public shielded addresses for registration and for logins
- has full access to a zcashd api
SWIZ workflows
Registration
USER
- visits a website to find their registration address
- wanting to register, they send their UA addr in a shielded memo to the address
Website
- monitors the public address for incoming UA addresses,
- some logic needs to be in place to call the z_listunifiedreceivers api with the UA
- stores the p2pkh as a user ID in their system
- stores orchard(or latest shielded pool type) as the users contact address(or stores a UA for convenience)
Workflow
UX is not great as wallets do not support this currently. This flow, however, can be done today with the existing zcashd api by power users. For the purpose of this post, I will use my own UA to demonstrate:
Getting a UA account address
$ zcash-cli z_getaddressforaccount 0{ "account": 0, "address": "u1lst8aumal5dvfxmxg8n44rlswewefdkf4dvnjgjr56cnmks4djsy3ydvez8djw4f4lrmepvjdy6qj7004kqnlungfr4ce2clgtqqz8azq79v9hrv20rdrzal99xhul6ew5zc6f9gy0rnt2mwpryw6wavl4l467vx2u2ut0dsevllvs4e3m0s25ue6z6u74z4kmhaswzv8mh5kp3mh3h", "diversifier_index": 32, "receiver_types": [ "p2pkh", "sapling", "orchard" ]}
This address was created for this post, and it contains a p2pkh (T-address) and an Orchard address.
Getting a t-addr from UA
$zcash-cli z_listunifiedreceivers u1lst8aumal5dvfxmxg8n44rlswewefdkf4dvnjgjr56cnmks4djsy3ydvez8djw4f4lrmepvjdy6qj7004kqnlungfr4ce2clgtqqz8azq79v9hrv20rdrzal99xhul6ew5zc6f9gy0rnt2mwpryw6wavl4l467vx2u2ut0dsevllvs4e3m0s25ue6z6u74z4kmhaswzv8mh5kp3mh3h{ "orchard": "u1nx48xwxza6ah2695wgljwrg3muvuntnk8n57l8je2c4226apzl7k7wx9j3rxx4268c0w7hk8fu54wlt3h0qxhjttjw6cswqersfhrq0f", "sapling": "zs1a9kp6j5mtsugcjlhxyrwqhyccwp2nqu0j90858q9yv5xnggxwdqgawjmj3zdqwvz5xc97ccc35q", "p2pkh": "t1YbzgdT6ZAUC7NKvGHDz97qgc17b62ZgUK"}
The p2pkh is the address that the website will want to save since we will be doing our signing from there. The shielded pool addresses can be used for secure two-way communication between the site and user.
Committing to the address
$ zcash-cli signmessage "t1YbzgdT6ZAUC7NKvGHDz97qgc17b62ZgUK" "u1lst8aumal5dvfxmxg8n44rlswewefdkf4dvnjgjr56cnmks4djsy3ydvez8djw4f4lrmepvjdy6qj7004kqnlungfr4ce2clgtqqz8azq79v9hrv20rdrzal99xhul6ew5zc6f9gy0rnt2mwpryw6wavl4l467vx2u2ut0dsevllvs4e3m0s25ue6z6u74z4kmhaswzv8mh5kp3mh3h"H+QiHEAg5A70kDFjfrbaxEktcWJTDbQ+Vs9FFCMFZF9xLI671okfNzCmqqvm8FakgD0PISQSAi9DjztexeXv0Z8=
The user will need to sign the UA with the p2pkh and provide both the UA and signature in a shielded memo.
Verify
$ zcash-cli verifymessage "t1YbzgdT6ZAUC7NKvGHDz97qgc17b62ZgUK" "H+QiHEAg5A70kDFjfrbaxEktcWJTDbQ+Vs9FFCMFZF9xLI671okfNzCmqqvm8FakgD0PISQSAi9DjztexeXv0Z8=" "u1lst8aumal5dvfxmxg8n44rlswewefdkf4dvnjgjr56cnmks4djsy3ydvez8djw4f4lrmepvjdy6qj7004kqnlungfr4ce2clgtqqz8azq79v9hrv20rdrzal99xhul6ew5zc6f9gy0rnt2mwpryw6wavl4l467vx2u2ut0dsevllvs4e3m0s25ue6z6u74z4kmhaswzv8mh5kp3mh3h"true
Since the UA and signature have been transmitted by the network to the website in a shielded memo, the site is able to extract the p2pkh and verify the signed UA
Since the user generates this UA on their side, and only used for this site, the site owner learns nothing about the user other than they possess the key pairs in the UA.
Login
User
- visits the site login page
- clicks 'sign in with z' or something
Website
- generates a cryptographic challenge for the session (a UUID and random short code )
- in the simplest case this will be a UUID presented to the user, preferable in a URI encoded QR code
User
- scans/copies the UUID
- signs the UUID with the p2phk
- sends the UUID, p2phk, and signature in a shielded memo to the websites shielded login address
Website
- receives a memo with the UUID, p2phk, and signature
- Verifies the signature
- looks up the z-addr of the user from the stored UA
Two-way matching
The website at this point has a valid signed message that has been sent from an unknown sender.
Two-way matching occurs in one of two ways:
Option A
Website
- sends a short user readable (i.e. 6 numbers or 3 emoji or similar) memo to the users z-addr
User
- enters the short code into the website which displayed the UUID
Website
- grants access
Option B
Website
- sends a different UUID memo to the users z-addr
User
- signs the new UUID with their p2phk key
- sends the UUID, p2phk, and signature in a shielded memo to the websites shielded login address
Website
- receives a memo with the UUID, p2phk, and signature
- Verifies the signature
- grants access
Conclusion
My preference is on option B since it is a 'touchless' login. In either case the UX would need to be worked out so normal users could do all this seamlessly of course. All the api calls exist to do this in nu5, so power users could in theory do this today. If a site setup a --walletnotify script it could mostly be automated as well.
Feedback and discussion are very much welcome.
