2018-10-02 09:54:15 -07:00
|
|
|
::
|
|
|
|
|
|
|
|
ZIP: XXX
|
|
|
|
Title: Light Client Protocol for Payment Detection
|
|
|
|
Authors: George Tankersley <gtank@z.cash>
|
|
|
|
Jack Grigg <jack@z.cash>
|
|
|
|
Credits: Matthew Green <mgreen@z.cash>
|
|
|
|
Category: Standards Track
|
|
|
|
Created: 2018-09-17
|
|
|
|
License: MIT
|
|
|
|
|
|
|
|
|
|
|
|
Terminology
|
|
|
|
===========
|
|
|
|
|
|
|
|
The terms below are to be interpreted as follows:
|
|
|
|
|
|
|
|
Light client
|
2018-10-02 15:27:57 -07:00
|
|
|
A client that is not a full participant in the network of Zcash peers. It can send and
|
|
|
|
receive payments, but does not store or validate a copy of the blockchain.
|
2018-10-02 09:54:15 -07:00
|
|
|
|
|
|
|
Abstract
|
|
|
|
========
|
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
This proposal defines a protocol for a Zcash light client supporting Sapling shielded
|
|
|
|
transactions.
|
2018-10-02 09:54:15 -07:00
|
|
|
|
|
|
|
Motivation
|
|
|
|
==========
|
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
Currently a client that wishes to send or receive shielded payments must be a full node
|
|
|
|
participanting in the Zcash network. This requires an amount of available bandwidth,
|
|
|
|
space, and processing power that may be unsuitable for some classes of user. This light
|
|
|
|
client protocol addresses that need, and is appropriate for low-power,
|
|
|
|
bandwidth-conscious, or otherwise limited machines (such as mobile phones).
|
2018-10-02 09:54:15 -07:00
|
|
|
|
|
|
|
High-Level Design
|
|
|
|
=================
|
|
|
|
|
|
|
|
There are three logical components to a Zcash light client system:
|
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
- **Zcash node** that provides chain state and serves as a root of trust for the system.
|
2018-10-02 09:54:15 -07:00
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
- **Proxy server** that extracts blockchain data from zcashd to store and serve it in a
|
|
|
|
lower-bandwidth format.
|
2018-10-02 09:54:15 -07:00
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
- **Light client** that subscribes to the stream from a proxy server and uses that data to
|
|
|
|
update its own view of the chain state. The light client MAY be attached to a wallet
|
|
|
|
backend that will track particular Sapling notes.
|
2018-10-02 09:54:15 -07:00
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
.. figure:: arch.png
|
|
|
|
:align: center
|
|
|
|
:figclass: align-center
|
2018-10-02 09:54:15 -07:00
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
Outline of the light wallet architecture
|
2018-10-02 09:54:15 -07:00
|
|
|
|
|
|
|
Security Model
|
|
|
|
==============
|
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
In this model, we propose **payment detection privacy** as our main security goal. That
|
|
|
|
is, the proxy should not learn which transactions (received from the blockchain) are
|
|
|
|
addressed to a given light wallet. If we further assume network privacy (via Tor or
|
|
|
|
similar), the proxy should not be able to link different connections or queries as
|
|
|
|
deriving from the the same wallet.
|
2018-10-02 09:54:15 -07:00
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
In particular, the underlying Zcash node / proxy combination is assumed to be "honest but
|
|
|
|
curious" and is trusted to provide a correct view of the current best chain state and to
|
|
|
|
faithfully transmit queries and responses. Methods for weakening this assumption are
|
|
|
|
discussed in appendix FOO.
|
2018-10-02 09:54:15 -07:00
|
|
|
|
|
|
|
This ZIP does not address how to spend notes privately.
|
|
|
|
|
|
|
|
Compact Stream Format
|
|
|
|
=====================
|
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
A key observation in this protocol is that the current zcashd encrypted field is several
|
|
|
|
hundred bytes long, due to the inclusion of a transaction “memo”. The need to download
|
|
|
|
this entire field imposes a substantial bandwidth cost on each light wallets, which may be
|
|
|
|
a limited mobile device on a restricted-bandwidth plan. While more efficient techniques
|
|
|
|
can be developed in the future, for the moment we propose ignoring the memo field during
|
|
|
|
payment detection. Futhermore, we can also ignore any information that is not directly
|
|
|
|
relevant to a Sapling shielded transaction.
|
2018-10-02 09:54:15 -07:00
|
|
|
|
|
|
|
A **compact block** is a packaging of ONLY the data from a block needed to:
|
|
|
|
|
|
|
|
1. Detect a payment to your shielded Sapling address
|
|
|
|
2. Detect a spend of your shielded Sapling notes
|
|
|
|
3. Update your witnesses to generate new Sapling spend proofs.
|
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
A compact block and its component compact transactions are encoded on the wire using the
|
|
|
|
following Protocol Buffers [XXX] format:
|
2018-10-02 09:54:15 -07:00
|
|
|
|
|
|
|
.. code:: proto
|
|
|
|
|
|
|
|
message BlockID {
|
|
|
|
uint64 blockHeight = 1;
|
|
|
|
bytes blockHash = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
message CompactBlock {
|
|
|
|
BlockID id = 1;
|
|
|
|
repeated CompactTx vtx = 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
message CompactTx {
|
|
|
|
uint64 txIndex = 1;
|
|
|
|
bytes txHash = 2;
|
|
|
|
|
|
|
|
repeated CompactSpend spends = 3;
|
|
|
|
repeated CompactOutput outputs = 4;
|
|
|
|
}
|
|
|
|
|
|
|
|
message CompactSpend {
|
|
|
|
bytes nf = 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
message CompactOutput {
|
|
|
|
bytes cmu = 1;
|
|
|
|
bytes epk = 2;
|
|
|
|
bytes ciphertext = 3;
|
|
|
|
}
|
|
|
|
|
|
|
|
Encoding Details
|
|
|
|
----------------
|
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
``blockHash``, ``txHash``, ``nf``, ``cmu``, and ``epk`` are encoded as
|
|
|
|
specified in the Zcash Protocol Spec.
|
2018-10-02 09:54:15 -07:00
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
The output and spend descriptions are handled differently, as described in the following
|
|
|
|
sections.
|
2018-10-02 09:54:15 -07:00
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
Output Compression
|
|
|
|
------------------
|
2018-10-02 09:54:15 -07:00
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
In the normal Zcash protocol, the output ciphertext consists of the AEAD encrypted form of
|
2018-10-04 07:26:29 -07:00
|
|
|
a *note plaintext* [Note]:
|
2018-10-02 09:54:15 -07:00
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
+------------+----------+----------+-------------+-----------------------------------+
|
|
|
|
| 8-bit 0x01 | 88-bit d | 64-bit v | 256-bit rcm | memo (512 bytes) + tag (16 bytes) |
|
|
|
|
+------------+----------+----------+-------------+-----------------------------------+
|
2018-10-02 09:54:15 -07:00
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
A recipient detects their transactions by trial-decrypting this ciphertext. On a full node
|
|
|
|
that has the entire block chain, the primary cost is computational. For light clients
|
|
|
|
however, there is an additional bandwidth cost: every ciphertext on the block chain must
|
|
|
|
be received from the server (or network node) the light client is connected to. This
|
|
|
|
results in a total of 580 bytes per output that must be streamed to the client.
|
2018-10-02 09:54:15 -07:00
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
However, we don't need all of that just to detect payments. The first 52 bytes of the
|
|
|
|
ciphertext contain the contents and opening of the note commitment, which is all of the
|
|
|
|
data needed to spend the note and to verify that the note is spendable. If we ignore the
|
|
|
|
memo and the authentication tag, we're left with a 32-byte ephemeral key, the 32-byte note
|
|
|
|
commitment, and only the first 52 bytes of the ciphertext for each output needed to
|
|
|
|
decrypt, verify, and spend a note. This totals to 116 bytes per output, for an 80%
|
|
|
|
reduction in bandwidth use.
|
2018-10-02 09:54:15 -07:00
|
|
|
|
|
|
|
However, skipping the full ciphertext means that we can no longer calculate the
|
2018-10-02 15:27:57 -07:00
|
|
|
authentication tag for the entire ciphertext and will need to do something else to
|
|
|
|
validate the integrity of the decrypted note plaintext.
|
|
|
|
|
|
|
|
Since the note commitment is sent outside the ciphertext and is authenticated by the
|
|
|
|
binding signature over the entire transaction, it serves as an adequate check on the
|
|
|
|
validity of the decrypted plaintext (assuming you trust the entity assembling
|
|
|
|
transactions). We therefore recalculate the note commitment from the decrypted plaintext.
|
2018-10-04 07:26:29 -07:00
|
|
|
If the recalculated commitment matches the one in the output, we accept the note as valid
|
|
|
|
and spendable.
|
2018-10-02 15:27:57 -07:00
|
|
|
|
|
|
|
Spend Compression
|
|
|
|
-----------------
|
|
|
|
|
2018-10-04 07:26:29 -07:00
|
|
|
Recall that a full Sapling Spend description is 384 bytes long [Spend]:
|
2018-10-02 15:27:57 -07:00
|
|
|
|
|
|
|
+-------+--------------+-----------+
|
|
|
|
| Bytes | Name | Type |
|
|
|
|
+=======+==============+===========+
|
|
|
|
| 32 | cv | char[32] |
|
|
|
|
+-------+--------------+-----------+
|
|
|
|
| 32 | anchor | char[32] |
|
|
|
|
+-------+--------------+-----------+
|
|
|
|
| 32 | nullifier | char[32] |
|
|
|
|
+-------+--------------+-----------+
|
|
|
|
| 32 | rk | char[32] |
|
|
|
|
+-------+--------------+-----------+
|
|
|
|
| 192 | zkproof | char[192] |
|
|
|
|
+-------+--------------+-----------+
|
|
|
|
| 64 | spendAuthSig | char[64] |
|
|
|
|
+-------+--------------+-----------+
|
|
|
|
|
|
|
|
The only part necessary for detection is the nullifier, which allows a light client to
|
|
|
|
detect when one of its own notes has been spent. This means we only need to take 32 bytes
|
|
|
|
of each Spend, for a 90% improvement in bandwidth use.
|
2018-10-02 09:54:15 -07:00
|
|
|
|
|
|
|
Proxy operation
|
|
|
|
===============
|
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
The proxy's purpose is to provide a scalable and bandwidth-efficient interface between a
|
|
|
|
Zcash node and any number of light clients. It accomplishes this by parsing a blockwise
|
|
|
|
stream of transactions from the node and converting them into the compact format described
|
|
|
|
above.
|
|
|
|
|
2018-10-04 07:26:29 -07:00
|
|
|
The proxy offers the following API to clients:
|
2018-10-02 15:27:57 -07:00
|
|
|
|
2018-10-04 07:26:29 -07:00
|
|
|
.. code:: proto
|
|
|
|
|
|
|
|
service CompactTxStreamer {
|
|
|
|
rpc GetLatestBlock(ChainSpec) returns (BlockID) {}
|
|
|
|
rpc GetBlock(BlockID) returns (CompactBlock) {}
|
|
|
|
rpc GetBlockRange(RangeFilter) returns (stream CompactBlock) {}
|
|
|
|
rpc GetTransaction(TxFilter) returns (FullTransaction) {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Remember that proto3 fields are all optional.
|
|
|
|
|
|
|
|
// Someday we may want to specify e.g. a particular chain fork.
|
|
|
|
message ChainSpec {}
|
|
|
|
|
|
|
|
|
|
|
|
// A BlockID message contains identifiers to select a block: either a
|
|
|
|
// height or a hash.
|
|
|
|
message BlockID {
|
|
|
|
uint64 blockHeight = 1;
|
|
|
|
bytes blockHash = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
message RangeFilter {
|
|
|
|
BlockID start = 1;
|
|
|
|
BlockID end = 2;
|
|
|
|
}
|
|
|
|
|
|
|
|
// A TxFilter contains the information needed to identify a particular
|
|
|
|
// transaction: either a block and an index, or a direct transaction hash.
|
|
|
|
message TxFilter {
|
|
|
|
BlockID blockID = 1;
|
|
|
|
uint64 txIndex = 2;
|
|
|
|
bytes txHash = 3;
|
|
|
|
}
|
2018-10-02 15:27:57 -07:00
|
|
|
|
|
|
|
|
2018-10-02 09:54:15 -07:00
|
|
|
Client operation
|
|
|
|
================
|
|
|
|
|
|
|
|
Appendix FOO
|
|
|
|
============
|
|
|
|
|
|
|
|
You can require the proxy to give you all the block headers to validate.
|
|
|
|
|
|
|
|
Reference Implementation
|
|
|
|
========================
|
|
|
|
|
2018-10-02 15:27:57 -07:00
|
|
|
This proposal is supported by a set of libraries and reference code made available by the
|
|
|
|
Zcash Company.
|
2018-10-02 09:54:15 -07:00
|
|
|
|
|
|
|
[NOTE: 2018-09-17 WE HAVE NOT YET FINISHED OR RELEASED THESE.]
|
|
|
|
|
|
|
|
References
|
|
|
|
==========
|
|
|
|
|
2018-10-04 07:26:29 -07:00
|
|
|
[ZEC] Zcash Protocol Spec
|
|
|
|
|
2018-10-02 09:54:15 -07:00
|
|
|
[bipXXX] define a light client
|
2018-10-02 15:27:57 -07:00
|
|
|
|
2018-10-02 09:54:15 -07:00
|
|
|
[XXX] protobufs
|
2018-10-04 07:26:29 -07:00
|
|
|
|
|
|
|
[Note] [ZEC] Section 5.5
|
|
|
|
|
|
|
|
[Spend] [ZEC] Section 7.x
|
|
|
|
|
|
|
|
[Output] [ZEC] Section 7.x
|