book: add Zcash chapter (#505)
* book: add Zcash chapter * Update book/src/zcash.md Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com> --------- Co-authored-by: Deirdre Connolly <durumcrustulum@gmail.com>
This commit is contained in:
parent
4ee0d32867
commit
fcb25b2888
|
@ -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)
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
# Technical Details
|
|
@ -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.
|
||||
|
Binary file not shown.
After Width: | Height: | Size: 187 KiB |
|
@ -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)
|
||||
```
|
|
@ -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.
|
Loading…
Reference in New Issue