-
Notifications
You must be signed in to change notification settings - Fork 172
[ZIP 308] Sprout to Sapling Migration #197
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
13 commits
Select commit
Hold shift + click to select a range
fb1d0e6
WIP: Sprout->Sapling migration ZIP.
daira 5a6d585
Completed draft (with open questions) of ZIP 308.
daira 7a66cf8
Formatting improvements for ZIP 308.
daira 232234e
Additional formatting improvements for ZIP 308.
daira b69910c
Address review comments.
daira f825dfe
Resolve an ambiguity concerning fees.
daira be04f70
Resolve a TODO.
daira 3ef1646
Address review comments.
daira d84390b
Addressed comments in pairing with Eirik and Simon.
daira 5986a2e
Change exponent range to 6..8.
daira 192907b
Fix rST errors.
daira 4e0d11f
ZIP 308: update a sentence that depended on the exponent range.
daira 4e748c8
ZIP 308: fix typos.
daira File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,380 @@ | ||
| :: | ||
|
|
||
| ZIP: 308 | ||
| Title: Sprout to Sapling Migration | ||
| Author: Daira Hopwood <daira@z.cash> | ||
| Eirik Ogilvie-Wigley <eirik@z.cash> | ||
| Category: RPC/Wallet | ||
| Created: 2018-11-27 | ||
| License: MIT | ||
|
|
||
|
|
||
| Terminology | ||
| =========== | ||
|
|
||
| The key words "MUST", "MUST NOT", "SHOULD", and "MAY" in this document are to | ||
| be interpreted as described in RFC 2119. [#RFC2119]_ | ||
|
|
||
| The terms below are to be interpreted as follows: | ||
|
|
||
| Sprout protocol | ||
| Code-name for the Zcash shielded protocol at launch. | ||
| Sapling protocol | ||
| Code-name for the Zcash shielded protocol added by the second Zcash network | ||
| upgrade, also known as Network Upgrade 1. | ||
|
|
||
|
|
||
| Abstract | ||
| ======== | ||
|
|
||
| This proposal describes privacy-preserving procedures to migrate funds from | ||
| Sprout to Sapling z-addresses; and supporting RPC operations to enable, | ||
| disable, and monitor the migration process. | ||
|
|
||
|
|
||
| Motivation | ||
| ========== | ||
|
|
||
| Zcash Sapling [#zip-0205]_ introduces significant efficiency improvements | ||
| relative to the previous iteration of the Zcash shielded protocol, Sprout. | ||
| These improvements will pave the way for broad mobile, exchange and vendor | ||
| adoption of shielded addresses. | ||
|
|
||
| Therefore, we anticipate that users will want to migrate all their shielded | ||
| funds from Sprout to Sapling. | ||
|
|
||
| The Zcash consensus rules prohibit direct transfers from Sprout to Sapling | ||
| z-addresses, unless the amount is revealed by sending it through the | ||
| "transparent value pool" [#transparent-value-pool]_. The primary motivation | ||
| for this is to allow detection of any overall inflation of the Zcash monetary | ||
| base, due to exploitation of possible vulnerabilities in the shielded | ||
| protocols or their implementation, or a compromise of the Sprout multi-party | ||
| computation. (It is not necessary for Sprout -> Sapling transfers to go via | ||
| a t-address.) | ||
|
|
||
| Since the exposure of the migrated amount potentially compromises the privacy | ||
| of users, we wish to define a way to perform the migration that mitigates | ||
| this privacy leak as far as possible. This can be done by hiding individual | ||
| migration transactions among those of all users that are doing the migration | ||
| at around the same time. | ||
|
|
||
| The security analysis of migration strategies is quite subtle; the more | ||
| obvious potential strategies can leak a lot of information. | ||
|
|
||
|
|
||
| Requirements | ||
| ============ | ||
|
|
||
| Migration is performed "in the background" by a ``zcashd`` (or equivalent) | ||
| node. It does not significantly interfere with concurrent usage of the node, | ||
| other than possibly increasing the latency of some other shielded operations. | ||
|
|
||
| It is possible to enable or disable migration at any time. | ||
|
|
||
| All shielded funds in Sprout z-addresses will eventually be transferred to | ||
| Sapling z-addresses, provided the node is working. | ||
|
|
||
| It should take a "reasonable" length of time to complete the transfer; | ||
| less than a month for amounts up to 1000 ZEC. | ||
|
|
||
| The design should mitigate information leakage via timing information and | ||
| transaction data, including | ||
|
|
||
| * linkage of particular z-addresses or users, and the amounts held; | ||
| * information about the distribution of amounts of individual notes. | ||
|
|
||
| The design and implementation is stateless, to the extent practical. | ||
|
|
||
| Visibility is provided for the wallet/node user into the progress of the | ||
| migration. | ||
|
|
||
| There is sufficient information available to debug failed transactions that | ||
| are part of the migration. | ||
|
|
||
| The design recovers from failed operations to the extent possible. | ||
daira marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| The total amount sent by each user is obscured, to the extent practical. | ||
|
|
||
|
|
||
| Non-requirements | ||
| ================ | ||
|
|
||
| There is no requirement or assumption of network layer anonymity. (Users may, | ||
| but are not expected to, configure Tor.) | ||
|
|
||
| The migration procedure does not have to provably leak no information. | ||
|
|
||
| There is no need to preserve individual note values (i.e. notes can be | ||
| consolidated). | ||
|
|
||
| Migration txns need only be hidden among themselves, rather than among all | ||
| kinds of transaction. | ||
|
|
||
| A small amount (less than 0.01 ZEC) can be left unmigrated if this helps with | ||
| privacy. | ||
|
|
||
| It is not required to support the case of single wallet being used by multiple | ||
| users whose funds should be kept distinct. | ||
|
|
||
|
|
||
| Specification | ||
| ============= | ||
|
|
||
| There are two main aspects to a strategy for selecting migration transactions: | ||
|
|
||
| * how many transactions are sent, and when; | ||
| * the amount sent in each transaction. | ||
|
|
||
|
|
||
| Transaction schedule | ||
| -------------------- | ||
|
|
||
| When migration is enabled, a node will send up to 5 transactions for inclusion | ||
| in each block with height a multiple of 500 (that is, they are sent immediately | ||
| after seeing a block with height 499, modulo 500). Up to the limit of 5, as | ||
| many transactions are sent as are needed to migrate the remaining funds | ||
| (possibly with a remainder less than 0.01 ZEC left unmigrated). | ||
|
|
||
| TODO: if we change the target block interval, 500 might need to be changed. | ||
|
|
||
| The migration transactions to be sent in a particular batch can take | ||
| significant time to generate, and this time depends on the speed of the user's | ||
| computer. If they were generated only after a block is seen at the target | ||
| height minus 1, then this could leak information. Therefore, for target | ||
| height N, implementations SHOULD start generating the transactions at around | ||
| height N-5. Each migration transaction SHOULD specify an anchor at height N-10 | ||
| for each Sprout JoinSplit description. | ||
daira marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| Open questions: | ||
|
|
||
| * does this reliably give sufficient time to generate the transactions? | ||
| * what happens to a batch if the anchor is invalidated -- should it be | ||
| regenerated, or cancelled? | ||
|
|
||
| Rationale for transaction schedule | ||
| '''''''''''''''''''''''''''''''''' | ||
|
|
||
| Privacy is increased when the times at which to send transactions are | ||
| coordinated between nodes. We choose to send a batch of transactions at each | ||
| coordinated time. Sending multiple transactions in each batch ensures that: | ||
daira marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| * less information about balances is leaked; | ||
| * it is easier to finish in a reasonable length of time. | ||
|
|
||
| The choice of 500 blocks as the batch interval ensures that each batch occurs | ||
| at a different time of day, which may help to mitigate problems with the | ||
| availability of nodes being correlated with the local time-of-day. | ||
|
|
||
| Simulation shows that the migration process will typically complete reasonably | ||
| quickly even if the amount to be migrated is large: | ||
|
|
||
| +-----------+--------------------------------------------+ | ||
| | | Time in days to complete migration | | ||
| | Amount +-----------------+--------+-----------------+ | ||
| | | 10th-percentile | median | 90th-percentile | | ||
| +===========+=================+========+=================+ | ||
| | 1 ZEC| 1.01 | 1.50 | 2.33 | | ||
| +-----------+-----------------+--------+-----------------+ | ||
| | 10 ZEC| 1.65 | 2.46 | 3.45 | | ||
| +-----------+-----------------+--------+-----------------+ | ||
| | 100 ZEC| 2.54 | 3.99 | 5.83 | | ||
| +-----------+-----------------+--------+-----------------+ | ||
| | 1000 ZEC| 9.86 | 12.52 | 15.54 | | ||
| +-----------+-----------------+--------+-----------------+ | ||
| | 10000 ZEC| 89.23 | 97.01 | 105.05 | | ||
| +-----------+-----------------+--------+-----------------+ | ||
|
|
||
| The simulation also depends on the amounts sent as specified in the next | ||
| section. It includes the time spent waiting for the first batch to be sent. | ||
|
|
||
| The code used for this simulation is at [#migration-simulator]_. | ||
|
|
||
|
|
||
| How much to send in each transaction | ||
daira marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ------------------------------------ | ||
|
|
||
| If the remaining amount to be migrated is less than 0.01 ZEC, end the migration. | ||
|
|
||
| Otherwise, the amount to send in each transaction is chosen according to the | ||
| following distribution: | ||
|
|
||
| 1. Choose an integer exponent uniformly in the range 6 to 8 inclusive. | ||
| 2. Choose an integer mantissa uniformly in the range 1 to 99 inclusive. | ||
| 3. Calculate amount := (mantissa * 10:sup:`exponent`) zatoshi. | ||
| 4. If amount is greater than the amount remaining to send, repeat from step 1. | ||
|
|
||
| Implementations MAY optimize this procedure by selecting the exponent and | ||
| mantissa based on the amount remaining to avoid repetition, but the resulting | ||
| distribution MUST be identical. | ||
|
|
||
| The amount chosen *includes* the 0.0001 ZEC fee for this transaction, i.e. | ||
| the value of the Sapling output will be 0.0001 ZEC less. | ||
|
|
||
| Rationale for how much to send | ||
| '''''''''''''''''''''''''''''' | ||
|
|
||
| Suppose that a user has an amount to migrate that is a round number of ZEC. | ||
| Then, a potential attack would be to find some subset of all the migration | ||
| transactions that sum to a round number of ZEC, and infer that all of those | ||
| transactions are from the same user. If amounts sent were a random multiple | ||
| of 1 zatoshi, then the resulting knapsack problem would be likely to have a | ||
| unique solution and be practically solvable for the number of transactions | ||
| involved. The chosen distribution of transaction amounts mitigates this | ||
| potential vulnerability by ensuring that there will be many solutions for sets | ||
| of transactions, including "incorrect" solutions (that is, solutions that mix | ||
| transactions from different users, contrary to the supposed adversary's | ||
| inference). | ||
|
|
||
| Making the chosen amount inclusive of the fee avoids leaving any unmigrated | ||
| funds at the end, in the case where the original amount to migrate was a | ||
| multiple of 0.01 ZEC. | ||
|
|
||
|
|
||
| Other design decisions | ||
daira marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| ---------------------- | ||
|
|
||
| We assume use of the normal wallet note selection algorithm and change | ||
| handling. Change is sent back to the default address, which is the z-address | ||
| of the first selected Sprout note. The number of JoinSplits will therefore be | ||
| the same as for a normal transaction sending the same amount with the same | ||
| wallet state. Only the ``vpub_out`` of the last JoinSplit will be nonzero. | ||
| There will always be exactly one Sapling Output. | ||
|
|
||
| The expiry height MUST be chosen as for other transactions. | ||
|
|
||
| The fee for each migration transaction MUST be 0.0001 ZEC. This fee is taken | ||
| from the funds to be migrated. | ||
|
|
||
| Some wallets by default add a "developer fee" to each transaction, directed | ||
| to the developer(s) of the wallet. This is typically implemented by adding | ||
| the developer address as an explicit output, so if migration transactions are | ||
| generated internally by ``zcashd``, they will not include the developer fee. | ||
| We strongly recommend *not* patching the ``zcashd`` code to add the developer | ||
| fee output to migration transactions, because doing so partitions the anonymity | ||
| set between users of that wallet and other users. | ||
|
|
||
| There MUST NOT be any transparent inputs or outputs, or Sapling Spends, in a | ||
| migration transaction. | ||
|
|
||
| The ``lock_time`` field MUST be set to 0 (unused). | ||
|
|
||
| A node SHOULD treat migration transactions in the same way as transactions | ||
| submitted over the RPC interface. | ||
|
|
||
|
|
||
| Open questions | ||
| -------------- | ||
|
|
||
| The above strategy has several "magic number" parameters: | ||
|
|
||
| * the interval between batches (500 blocks) | ||
daira marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| * the maximum number of transactions in a batch (5) | ||
| * the distribution of exponents (uniform integer in 6..8) | ||
| * the distribution of mantissae (uniform integer in 1..99). | ||
|
|
||
| These have been chosen by guesswork. Should we change any of them? | ||
|
|
||
| In particular, if the amount to migrate is large, then this strategy can | ||
| result in fairly large amounts (up to 99 ZEC, worth USD ~6700 at time of | ||
| writing) transferred in each transaction. This leaks the fact that the | ||
| transaction was sent by a user who has at least that amount. | ||
|
|
||
| The strategy does not migrate any remaining fractional amount less than | ||
| 0.01 ZEC (worth USD ~0.50 at time of writing). Is this reasonable? | ||
|
|
||
| In deciding the amount to send in each transaction, the strategy does not | ||
| take account of the values of individual Sprout notes, only the total amount | ||
| remaining to migrate. Can a strategy that is sensitive to individual note | ||
| values improve privacy? | ||
daira marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| An adversary may attempt to interfere with the view of the block chain seen | ||
| by a subset of nodes that are performing migrations, in order to cause those | ||
| nodes to send migration batches at a different time, so that they may be | ||
| distinguished. Is there anything further we can do to mitigate this | ||
| vulnerability? | ||
daira marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
|
|
||
| RPC calls | ||
| --------- | ||
|
|
||
| Nodes MUST maintain a boolean state variable during their execution, to | ||
| determine whether migration is enabled. The default when a node starts, is | ||
| set by a configuration option:: | ||
|
|
||
| -migration=0/1 | ||
|
|
||
| The destination z-address can optionally be set by another option:: | ||
|
|
||
| -migrationdestaddress=<zaddr> | ||
|
|
||
| If this option is not present then the migration destination address is | ||
| the address for Sapling account 0, with the default diversifier [#zip-0032]_. | ||
|
|
||
| The state variable can also be set for a running node using the following | ||
| RPC method:: | ||
|
|
||
| setmigration true/false | ||
|
|
||
| It is intentional that the only option associated with the migration is the | ||
| destination z-address. Other options could potentially distinguish users. | ||
|
|
||
|
|
||
| Nodes MUST also support the following RPC call to return the current status of | ||
| the migration:: | ||
|
|
||
| getmigrationstatus | ||
|
|
||
| Returns:: | ||
|
|
||
| { | ||
| "enabled": true|false, | ||
| "destination_address": "zaddr", | ||
| "unmigrated_amount": nnn.n, | ||
| "unconfirmed_migrated_amount": nnn.n, | ||
| "confirmed_migrated_amount": nnn.n, | ||
| "confirmed_migration_transactions": nnn, | ||
daira marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| "time_started": ttt, // Unix timestamp | ||
| "migration_txids": [txids] | ||
| } | ||
daira marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| The ``destination_address`` field MAY be omitted if the ``-migrationaddress`` | ||
| parameter is not set and no default address has yet been generated. | ||
|
|
||
| The values of ``unmigrated_amount`` and ``migrated_amount`` MUST take into | ||
| account failed transactions, that were not mined within their expiration | ||
| height. | ||
|
|
||
| ``migration_txids`` is a list of strings representing transaction IDs of all | ||
| known migration transactions involving this wallet, as lowercase hexadecimal | ||
| in RPC byte order. A given transaction is defined as a migration transaction | ||
| iff it has: | ||
|
|
||
| * one or more Sprout JoinSplits with nonzero vpub_new field; and | ||
| * no Sapling Spends, and; | ||
| * one or more Sapling Outputs. | ||
|
|
||
| Note: it is possible that manually created transactions involving this | ||
| wallet will be recognized as migration transactions and included in ``txids``. | ||
|
|
||
| The value of ``time_started`` is the earliest Unix timestamp of any known | ||
| migration transaction involving this wallet; if there is no such transaction, | ||
| then the field is absent. | ||
|
|
||
| A transaction is ``confirmed`` iff it has 10 confirmations. | ||
| TODO: subject to change, if the recommended number of confirmations changes. | ||
|
|
||
|
|
||
| Support in zcashd | ||
| ================= | ||
|
|
||
| TODO (point to the PR). | ||
|
|
||
|
|
||
| References | ||
| ========== | ||
|
|
||
| .. [#transparent-value-pool] `Zcash Protocol Specification, Version 2018.0-beta-33 [Overwinter+Sapling]; sections 3.4, 4.11 and 4.12 <https://github.com/zcash/zips/blob/master/protocol/protocol.pdf>`_ | ||
| .. [#RFC2119] `Key words for use in RFCs to Indicate Requirement Levels <https://tools.ietf.org/html/rfc2119>`_ | ||
| .. [#zip-0032] `ZIP 32: Shielded Hierarchical Deterministic Wallets <https://github.com/zcash/zips/blob/master/zip-0032.rst>`_ | ||
| .. [#zip-0205] `ZIP 205: Deployment of the Sapling Network Upgrade <https://github.com/zcash/zips/blob/master/zip-0205.rst>`_ | ||
| .. [#migration-simulator] `Sprout -> Sapling migration simulation <https://github.com/daira/zcash-migration>`_ | ||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.