diff --git a/book/src/SUMMARY.md b/book/src/SUMMARY.md index 52d21e1..917a0b2 100644 --- a/book/src/SUMMARY.md +++ b/book/src/SUMMARY.md @@ -8,6 +8,9 @@ - [Signing](tutorial/signing.md) - [Distributed Key Generation](tutorial/dkg.md) - [User Documentation](user.md) +- [FROST with Zcash](zcash.md) + - [Technical Details](zcash/technical-details.md) + - [Ywallet Demo](zcash/ywallet-demo.md) - [Terminology](terminology.md) - [Developer Documentation](dev.md) - [List of Dependencies for Audit](dev/frost-dependencies-for-audit.md) diff --git a/book/src/technical-details.md b/book/src/technical-details.md new file mode 100644 index 0000000..fd3fa08 --- /dev/null +++ b/book/src/technical-details.md @@ -0,0 +1 @@ +# Technical Details diff --git a/book/src/zcash.md b/book/src/zcash.md new file mode 100644 index 0000000..a8687a0 --- /dev/null +++ b/book/src/zcash.md @@ -0,0 +1,36 @@ +# FROST with Zcash + +FROST can be used with the [Zcash](https://z.cash/) cryptocurrency, allowing +the creation of a wallet shared between multiple participants where multiple +participants must authorize a transaction before it can go through. + +In a regular Zcash wallet, the spending key (commonly derived from a seed +phrase) allows freely spending from the wallet. If the key is lost or gets +hacked, then the wallet owner will lose access to their funds forever. + +With FROST, only shares of the related spend authorization key will exist, between multiple +participants. During wallet creation, a threshold is set, and only that number of +participants (or more) can jointly create a transaction that spends funds from the wallet. + +Some possible applications are: + +- Creating a wallet that is shared between members of a organization that + manages certain funds. For example, a 3-of-5 wallet can be created which + will require 3 members to authorize spending the funds. +- Shared custody services can be created so that users can have their own wallet + and can spend their funds with the help of the service, and will not lose + access to the funds in case they lose the device with their key share. For + example, a 2-of-3 wallet where the user keeps one share, the service keeps + another, and the third share is backed up in the user's cloud. + +FROST thus helps addressing one of the biggest challenges in cryptocurrencies, +which is the protecting the wallet key from either being accidentally lost or +being hacked. Before, users needed to choose to either manage their own funds +will puts a huge amount of responsibility on them and is well known to work +greatly in practice, or to leave their funds to be managed by some custody +service which is also known to be a risk. With FROST, users can share the +responsibility between multiple entities or persons (or even multiple devices +they own). + +This section describes in more details how FROST can be used with Zcash. + diff --git a/book/src/zcash/key-trees.png b/book/src/zcash/key-trees.png new file mode 100644 index 0000000..d7dccd3 Binary files /dev/null and b/book/src/zcash/key-trees.png differ diff --git a/book/src/zcash/technical-details.md b/book/src/zcash/technical-details.md new file mode 100644 index 0000000..76cd120 --- /dev/null +++ b/book/src/zcash/technical-details.md @@ -0,0 +1,124 @@ +# Technical Details + +FROST only works with Schnorr signatures. Zcash transaprent transactions use +ECDSA, therefore FROST does not work with Zcash transaparent addresses. (This +could change if the Taproot upgrade from Bitcoin is ported to Zcash, but it +seems unlikely.) + +Zcash supports three shielded pools: Sprout, Sapling and Orchard. Sprout +is being deprecated so we only need to care about Sapling and Orchard. + +Sapling and Orchard keys are commonly derived from a single spending key (which +in turn is commonly derived from a seed phrase). This is shown in the figure +below, taken from the [Zcash +protocol](https://zips.z.cash/protocol/protocol.pdf#addressesandkeys): + + +![Sapling and Orchard key trees](key-trees.png) + +To use FROST with Zcash, the key that needs to be split is the **Spend +Authorizing Key** or `ask`. This is the key that signs transactions and allow +they to go through. + +## Key Derivation and DKG Support + +As shown in the figure, the `ask` is commonly derived from the **Spending Key** +`sk`. At first, this could indicate that it is impossible to use Distributed Key +Generation (DKG) in this scenario, since the key it creates is unpredictable. + +However, the protocol does not *require* `ask` to be derived from `sk`. +This would allow creating key shares using DKG, which will also output +`ak` (which is simply the public key matching `ask`). Thus: + +- With Sapling, the rest of the keys can be derived from that `ak` and either: + - An `sk` which is used to derive only `nsk` and `ovk`; + - Or generating `nsk` and `ovk` by themselves (or generating them from a + random `sk` which is thrown away). +- With Orchard, the rest of the keys can be derived from that `ak` and either: + - An `sk` which is used to derive only `nk` and `rivk`; + - Or generating `nk` and `rivk` by themselves (or generating them from a + random `sk` which is thrown away). + +Arguably this should be done even if Trusted Dealer Key Generation is used: the +goal of FROST is requiring multiple entities to authorize a transaction, not +having a seed phrase that allows recreating the `ask` ensures that property. + +## Backing Up Key Shares + +Zcash users are familiar with the concept of seed phrases and with how they +can always recover their wallet with it. + +However, FROST wallets need more information to be restored: + +- FROST-related: + - Key share + - Verifying shares of all participants + - Public keys and identifiers of all participants if online communication is + being used +- Zcash-related: + - Sapling: `sk`, or both Proof authorizing key (`ak` and `nsk`) and Outgoing + viewing key (`ovk`) + - Orchard: `sk`, or Full viewing key (`ak`, `nk`, `rivk`). The upside of using + the Full viewing key is that there is already a format for encoding it. + +Thus, even if a `sk` derived from a seed phrase is used, that is not enough to +restore a FROST wallet. In fact it would be probably confusing to use a seed +phrase since users wouldn't be able to tell if it's a regular Zcash seed phrase +or a FROST seed phrase which needs additional information to be restored. + +For this reason it seems impossible to easily encode a FROST wallet, so using +something like a JSON file with all this information is advisable. + +Of course, unlike regular Zcash wallets, a user losing their FROST wallet is +not catastrophical. Users can recover their key share with the help of other +participants, and would only need to remember their identifier (and other +participants can probably help with that). + +```admonish note +Orchard is simpler to handle, so it may be a good idea to just +support it with FROST. +``` + +```admonish note +The only secret information is the key share. So another possibility +is to just ask the user to backup it (using a seed phrase format, or other +string encoding) and get the remaining information from the other participants +when recovering a wallet. +``` + +## Communications + +The biggest challenge in using FROST with Zcash is allowing participants to +communicate securely with each other, which is required to run the FROST +protocol. Since wallets don't currently need to communication to each other, a +whole new mechanism will need to be implemented. + +For this to happen, two things are required: + +- Allowing wallets to actually communicate with each other (regardless of + security). This is challenging because users are usually behind NATs and + firewalls, so they can't simply open TCP connections with each other. So + some kind of signaling server may be needed. +- Making the communication secure. This is actually fairly solvable while not + trivial and we're planning on working on a library to address it. It needs to + provide authentication and confidentiality, for example using the Noise + protocol. Also needs to provide a [broadcast + channel](https://frost.zfnd.org/terminology.html#broadcast-channel) on top of + it. +- Managing public keys. Another challenging part. Users need to be able to + create a key pair of keys used for the secure communication, and exporting + public keys to each other. This is similar to contact management that some + wallets have, so a possibility is to expand on that (instead of storing + just name and address, also store identifier and public key). + +```info +One long-term idea is to extend the Zcash protocol to allow P2P messaging. +This has been discussed in the context of sending encrypted notes via the network +instead of publishing them on the blockchain. +``` + +```info +Another idea is to extend lightwalletd servers to support messaging, since +wallets are all already connected to a server (not the same one, so inter-server +communications would be also needed) +``` \ No newline at end of file diff --git a/book/src/zcash/ywallet-demo.md b/book/src/zcash/ywallet-demo.md new file mode 100644 index 0000000..7d1db2c --- /dev/null +++ b/book/src/zcash/ywallet-demo.md @@ -0,0 +1,217 @@ +# Ywallet Demo Tutorial + +This tutorial explaing how to run the FROST demo using Ywallet that was +[presented during Zcon4](https://www.youtube.com/watch?v=xvzESdDtczo). + +Ywallet supports [offline +signing](https://ywallet.app/advanced/offline_signature/), which allows having a +view-only account that can generate a transaction plan, which can be signed by +a offline wallet also running Ywallet. The demo uses this mechanism but signs +the transaction plan with a command line tool, using FROST. + +This tutorial assumes familiarity with the command line. + +## Setting up + +Install `cargo` and `git`. + +[Install Ywallet](https://ywallet.app/installation/). + +Clone the repositories: + +``` +git clone --branch add-redpallas https://github.com/ZcashFoundation/frost-zcash-demo.git +git clone --branch frost-demo https://github.com/ZcashFoundation/zwallet.git +``` + +## Generating FROST key shares + +First we will generate the FROST key shares. For simplicity we'll use trusted +dealer, DKG will be described later. + +Run the following (it will take a bit to compile): + +``` +cd frost-zcash-demo/ +cargo run --bin trusted-dealer --features redpallas +``` + +Answer the prompts with `2` (minimum number of signers), `3` +(maximum) and empty, pressing enter to submit each. + +A bunch of information will be printed. Copy and paste them somewhere to use +them later, or leave the terminal open. + +```admonish info +If you want to use DKG instead of Trusted Dealer, instead of the command above, + run this for each participant, in separate terminals for each: + +`cargo run --bin dkg --features redpallas` + +and follow the instructions. (There will be a considerable amount of +copy&pasting!) +``` + +## Generating the Full Viewing Key for the wallet + +In a new terminal, switch to the folder of the signer tool: + + +``` +cd zwallet/native/zcash-sync/ +``` + +Before running it, you will need to create a seed phrase which is used to +generate the Sapling address. This wouldn't be needed since the demo only works +with an Orchard address, but due to current limitations in the underlying +crates, we also need to generate a Sapling address which won't be used in the +demo. Generate a fresh 24-word seed phrase, for example using [this +site](https://iancoleman.io/bip39/) (reminder: don't use random sites to +generate seed phrases unless for testing purposes!), then write to a file called +`.env` in the signer folder in the following format, putting the seed phrase +inside the quotes: + + ``` + KEY="seed phrase" + ``` + +We can finally generate a new wallet. Run the following command; it will +take a bit to compile. It will show a bunch of warnings which is normal. + +``` +cargo build --release --bin sign --features dotenv -- -g +``` + +When prompted for the `ak`, paste the `group_public` value that was printed in +the previous part, inside the Public Key Package. For example, in the following +package + +``` +Public key package: +{"signer_pubkeys": ...snip... ,"group_public":"d2bf40ca860fb97e9d6d15d7d25e4f17d2e8ba5dd7069188cbf30b023910a71b","ciphersuite":"FROST(Pallas, BLAKE2b-512)"} +``` + +you would need to use +`d2bf40ca860fb97e9d6d15d7d25e4f17d2e8ba5dd7069188cbf30b023910a71b`. Press +enter to submit. + +It will print an Orchard address, and a Unified Full Viewing Key. Copy and +paste both somewhere to use them later. + +## Importing the Full Viewing Key into Ywallet + +Open Ywallet and click "New account". Check "Restore an account" and +paste the Unified Full Viewing Key created in the previous step. Click +"Import". + +In the "Rescan from..." window, pick today's date (since the wallet was just +created) and press OK. The wallet should open. + +You will need to change some of Ywallet configurations. Click the three dots +at the top right and go to Settings. Switch to Advanced mode and click +OK. Go back to the Settings and uncheck "Use QR for offline signing". + +## Funding the wallet + +Now you will need to fund this wallet with some ZEC. Use the Orchard address +printed by the signer (see warning below). Send ZEC to that address using +another account (or try [ZecFaucet](https://zecfaucet.com/)). Wait until the +funds become spendable (this may take ~10 minutes). You can check if the funds +are spendable by clicking the arrow button and checking "Spendable Balance" + +```admonish warning +The address being show by Ywallet is an unified address that includes both +an Orchard and Sapling address. For the demo to work, you need to receive funds +in you Orchard address. Whether that will happens depend on multiple factors +so it's probably easier to just use the Orchard-only address printed by the +signer. +``` + +## Creating the transaction + +Now you will create the transaction that you wish to sign with FROST. Click +the arrow button and paste the destination address (send it to yourself if +you don't know where to send it). Type the amount you want to send and +click "Send". + +The wallet will show the transaction plan. Click "Send". It won't actually +send - it will prompt you for where to save the transaction plan. Save it +somewhere. + +## Signing the transaction + +Go back to the signer terminal and run (adjust paths accordingly. The "tx.json" +input parameters must point to the file you save in the previous step, and the +"tx.raw" output parameter is where the signed transaction will be written). + +``` +cargo run --release --bin sign --features dotenv -- -t ~/Downloads/tx.json -o ~/Downloads/tx.raw +``` + +When prompted, paste the UFVK generated previously. + +The program will print a SIGHASH and a Randomizer. + +Now you will need to simulate two participants and a Coordinator to sign the +transaction. It's probably easier to open three terminals. + +In the first one, the Coordinator, run (in the same folder where key +generation was run): + +``` +cargo run --bin coordinator --features redpallas +``` + +And then: + +- Paste the JSON public key package generate during key generation (it's a single + line with a JSON object. +- Type `2` for the number of participants. +- Paste the identifier of the first participant, you can see it in the Secret + Share printed during key generation. If you used trusted dealer key + generation, it will be + `0100000000000000000000000000000000000000000000000000000000000000`. +- Paste the second identifier, e.g. + `0200000000000000000000000000000000000000000000000000000000000000`. +- When prompted for the message to be signed, paste the SIGHASH printed by the + signer above (just the hex value, e.g. + ``4d065453cfa4cfb4f98dbc9cff60c4a3904ed91c523b8ef8d67d28bea7f12ea3``). + +Create a new terminal, for participant 1, and run: + +``` +cargo run --bin participant --features redpallas +``` + +And then: + +- Paste the Secret Share printed during key generation (or Key Package if you + used DKG). +- Copy the SigningCommitments line and paste into the Coordinator CLI. + +Do the same for participant 2. + +You should be at the Coordinator CLI. Paste the Randomizer generated by the +signer before and copy the Signing Package line that it was printed by the +Coordinator CLI before the Randomizer prompt. + +Switch to participant 1 and: + +- Paste the Signing Package +- Paste the Randomizer printed by the signer before. +- Copy the SignatureShare line and paste it into the Coordinator CLI. + +Do the same for participant 2. + +You should be at the Coordinator CLI. It has just printed the final +FROST-generated signature. Hurrah! Copy it (just the hex value). + +Go back to the signer and paste the signature. It will write the raw signed +transaction to the file you specified. + +## Broadcasting the transaction + +Go back to Ywallet and return to its main screen. In the menu, select "Advanced" +and "Broadcast". Select the raw signed transaction file you have just generated. + +That's it! You just sent a FROST-signed Zcash transaction.