mirror of https://github.com/zcash/zips.git
[ZIP ???] Whitelisted Transparent Programs
This commit is contained in:
parent
a78a1291fa
commit
26b80bf3c2
|
@ -0,0 +1,282 @@
|
||||||
|
::
|
||||||
|
|
||||||
|
ZIP: XXX
|
||||||
|
Title: Whitelisted Transparent Programs
|
||||||
|
Owners: Jack Grigg <jack@electriccoin.co>
|
||||||
|
Credits: James Prestwich <james@summa.one>
|
||||||
|
Zaki Manian <zaki@manian.org>
|
||||||
|
Daira Hopwood <daira@electriccoin.co>
|
||||||
|
Sean Bowe <sean@electriccoin.co>
|
||||||
|
The BIP 141 authors
|
||||||
|
Status: Draft
|
||||||
|
Category: Consensus
|
||||||
|
Created: 2019-07-01
|
||||||
|
License: MIT
|
||||||
|
|
||||||
|
|
||||||
|
Terminology
|
||||||
|
===========
|
||||||
|
|
||||||
|
The key words "MUST" and "MAY" in this document are to be interpreted as described in
|
||||||
|
RFC 2119. [#RFC2119]_
|
||||||
|
|
||||||
|
The term "network upgrade" in this document is to be interpreted as described in ZIP 200
|
||||||
|
[#zip-0200]_.
|
||||||
|
|
||||||
|
The term "Sapling" in this document is to be interpreted as described in ZIP 205
|
||||||
|
[#zip-0205]_.
|
||||||
|
|
||||||
|
Abstract
|
||||||
|
========
|
||||||
|
|
||||||
|
This proposal defines a modification to the consensus rules that enables whitelisted
|
||||||
|
complex forms of transparent output predicates ("transparent programs") to be deployed
|
||||||
|
in network upgrades, while ensuring that a transaction's ID is non-malleable if the
|
||||||
|
transaction uses any transparent programs.
|
||||||
|
|
||||||
|
|
||||||
|
Motivation
|
||||||
|
==========
|
||||||
|
|
||||||
|
Zcash transactions have three types of outputs: Sapling shielded outputs, Sprout shielded
|
||||||
|
outputs, and transparent outputs. All three can by design be "encumbered" by a spending
|
||||||
|
key - a user creating a transaction that spends the output must prove that they have
|
||||||
|
access to the spending key controlling the output. For Sprout shielded outputs this was
|
||||||
|
part of the zero-knowledge proof; for transparent and Sapling shielded outputs, the user
|
||||||
|
creates a signature with the spending key.
|
||||||
|
|
||||||
|
In some situations, more complex predicates are required. Zcash does not yet have any form
|
||||||
|
of shielded programmability, and thus users rely on the script system inherited from
|
||||||
|
Bitcoin to encumber transparent outputs. But even this is insufficient as-is for some
|
||||||
|
desired use cases. In particular, the Bolt protocol [#zip-draft-bolt]_ requires a custom
|
||||||
|
opcode, because the script system does not have the necessary primitives; this requires a
|
||||||
|
change to the consensus rules.
|
||||||
|
|
||||||
|
Additionally, some off-chain protocols require that transaction IDs be non-malleable in
|
||||||
|
order to be secure. Zcash transaction IDs are currently malleable in several ways:
|
||||||
|
|
||||||
|
- The ``scriptSig`` field of transparent inputs is not part of the data that is hashed for
|
||||||
|
signing (as the signature is placed in that field), but is part of the data that is
|
||||||
|
hashed to produce the transaction ID. An adversary can modify this field in a variety of
|
||||||
|
ways that do not functionally alter it, but change its binary representation. This is
|
||||||
|
the core transaction malleability problem that Bitcoin mitigated with their Segregated
|
||||||
|
Witness soft fork [#bip-0141]_ (for transactions that opt-in to SegWit-only inputs).
|
||||||
|
|
||||||
|
- The Ed25519 signature ``joinSplitSig`` is malleable. The known sources of malleability
|
||||||
|
are:
|
||||||
|
|
||||||
|
- The y-coordinate of the R component of the signature is not required to be canonical.
|
||||||
|
- There are equivalent points for R because its order may be greater than the subgroup
|
||||||
|
order ``ell``.
|
||||||
|
|
||||||
|
These malleability sources correspond to the verification process in ``libsodium``. Note
|
||||||
|
that the public key ``joinSplitPubKey`` is also not required to be canonical, but this
|
||||||
|
is not a source of malleability because the public key is hashed as given in the
|
||||||
|
transaction when verifying the signature.
|
||||||
|
|
||||||
|
- RedJubjub signatures, as currently enforced by the consensus rules, are malleable. This
|
||||||
|
is because the signature verification algorithm [#redjubjub]_ multiplies through by the
|
||||||
|
cofactor before the identity check (which ensures that the single and batch verification
|
||||||
|
algorithms agree on the set of valid signatures). An adversary can modify the signature
|
||||||
|
by adding a nonzero point of small order to R, leaving the signature valid but altering
|
||||||
|
its binary representation.
|
||||||
|
|
||||||
|
- TODO: Upon further investigation, it looks like RedJubjub is not actually malleable
|
||||||
|
for the above reason. We are analysing this and will update the proposal when we are
|
||||||
|
certain. It is also possible that Ed25519 might also be non-malleable for a similar
|
||||||
|
reason, but verifying this would require very careful inspection of libsodium; it is
|
||||||
|
simpler to just exclude them.
|
||||||
|
|
||||||
|
Shielded programmability and a full transaction ID malleability fix would both require
|
||||||
|
significant changes across the ecosystem. In the interim, we propose in this ZIP the
|
||||||
|
simplest possible change to the consensus rules that addresses the above concerns with a
|
||||||
|
minimal impact on the existing ecosystem.
|
||||||
|
|
||||||
|
|
||||||
|
Conventions
|
||||||
|
===========
|
||||||
|
|
||||||
|
We use the following notation as defined in the Zcash protocol specification
|
||||||
|
[#spec-notation]_, reproduced here for convenience:
|
||||||
|
|
||||||
|
- length(*S*) means the length of (number of elements in) *S*.
|
||||||
|
|
||||||
|
- { *a* .. *b* } means the set or type of integers from *a* through *b* inclusive.
|
||||||
|
|
||||||
|
- *a* || *b* means the concatenation of sequences *a* then *b*.
|
||||||
|
|
||||||
|
We reproduce the following conversion function from ZIP 32 [#zip-0032]_:
|
||||||
|
|
||||||
|
- I2LEOSP\ :sub:`l`\ (*k*) is the byte sequence *S* of length *l*/8 representing in little-endian order the
|
||||||
|
integer *k* in range {0..2\ :sup:`l`\ -1}.
|
||||||
|
|
||||||
|
We also define the following helper notation for scripts:
|
||||||
|
|
||||||
|
- PUSHDATA(*S*) is a data push of the byte sequence *S* using the standard script data
|
||||||
|
push encoding:
|
||||||
|
|
||||||
|
- I2LEOSP\ :sub:`8`\ (length(*S*)) || *S* if length(*S*) < ``PUSHDATA1``.
|
||||||
|
- ``PUSHDATA1`` || I2LEOSP\ :sub:`8`\ (length(*S*)) || *S* if length(*S*) <= ``0xff``.
|
||||||
|
- ``PUSHDATA2`` || I2LEOSP\ :sub:`16`\ (length(*S*)) || *S* if length(*S*) <= ``0xffff``.
|
||||||
|
- ``PUSHDATA4`` || I2LEOSP\ :sub:`32`\ (length(*S*)) || *S* otherwise.
|
||||||
|
|
||||||
|
|
||||||
|
Specification
|
||||||
|
=============
|
||||||
|
|
||||||
|
Transparent program
|
||||||
|
-------------------
|
||||||
|
|
||||||
|
A transparent program is defined by four properties:
|
||||||
|
|
||||||
|
- A 1-byte program type.
|
||||||
|
- A byte sequence ``predicate`` containing a prefix-free encoding describing the
|
||||||
|
predicate.
|
||||||
|
- A non-malleable byte sequence ``witness`` containing a prefix-free encoding of evidence
|
||||||
|
satisfying the predicate.
|
||||||
|
- A deterministic verification algorithm ``verify_program`` that takes as arguments
|
||||||
|
``predicate``, ``witness``, and a context object providing deterministic public
|
||||||
|
information about the transaction as well as the block chain (up to and including the
|
||||||
|
block that the transaction is mined in). It returns ``true`` if the predicate is
|
||||||
|
satisfied, and ``false`` otherwise.
|
||||||
|
|
||||||
|
ZIPs that define a new transparent program must completely specify all four of these
|
||||||
|
properties.
|
||||||
|
|
||||||
|
Program types ``{0xfd..0xff}`` are reserved for future extensions to this schema.
|
||||||
|
|
||||||
|
The lengths of ``predicate`` and ``witness`` are not required to be constant length, but
|
||||||
|
MUST be solely determined by the program type.
|
||||||
|
|
||||||
|
Encoding in transactions
|
||||||
|
------------------------
|
||||||
|
|
||||||
|
A new script opcode ``PROGRAM`` is introduced that redefines the existing ``NOP10``
|
||||||
|
opcode.
|
||||||
|
|
||||||
|
To create an encumbered transparent output, its ``scriptPubKey`` is set to exactly the
|
||||||
|
following:
|
||||||
|
|
||||||
|
PROGRAM PUSHDATA(type || predicate)
|
||||||
|
|
||||||
|
When spending an encumbered transparent output, the ``scriptSig`` of the input is set to
|
||||||
|
exactly the following:
|
||||||
|
|
||||||
|
PROGRAM PUSHDATA(type || witness)
|
||||||
|
|
||||||
|
To a script parser unaware of the ``PROGRAM`` opcode, this results in the following stack,
|
||||||
|
which would be interpreted as an "anyone can spend" output:
|
||||||
|
|
||||||
|
PUSHDATA(type || witness) PUSHDATA(type || predicate)
|
||||||
|
|
||||||
|
TODO: Alternatively, we could enforce that the script fails-closed for old script
|
||||||
|
interpreters, by requiring that ``scriptSig`` include a ``RETURN`` opcode.
|
||||||
|
|
||||||
|
Consensus rules
|
||||||
|
---------------
|
||||||
|
|
||||||
|
Once the TODO network upgrade activates, the following new consensus rules are enforced:
|
||||||
|
|
||||||
|
- The ``PROGRAM`` opcode MUST NOT be present anywhere in ``scriptPubKey`` or ``scriptSig``
|
||||||
|
except at the beginning.
|
||||||
|
|
||||||
|
- If a transparent output's ``scriptPubKey`` begins with ``PROGRAM``, then the remaining
|
||||||
|
bytes MUST be exactly a single data push operation. The first byte of the pushed data
|
||||||
|
MUST be a whitelisted program type, and the data push length MUST equal
|
||||||
|
``1 + length(predicate)``.
|
||||||
|
|
||||||
|
- If a transparent input's ``scriptSig`` begins with ``PROGRAM``, then the remaining bytes
|
||||||
|
MUST be exactly a single data push operation. The first byte of the pushed data MUST be
|
||||||
|
a whitelisted program type, and the data push length MUST equal ``1 + length(witness)``.
|
||||||
|
|
||||||
|
- If a transparent input's ``scriptSig`` contains a transparent program, then:
|
||||||
|
|
||||||
|
- The UTXO it is spending MUST contain a transparent program of the same type in its
|
||||||
|
``scriptPubKey``.
|
||||||
|
- ``verify_program(predicate, witness, context)`` MUST return ``true``.
|
||||||
|
|
||||||
|
- If any transparent output begins with ``PROGRAM``, then the transaction MUST be
|
||||||
|
non-malleable. Specifically:
|
||||||
|
|
||||||
|
- ``vin`` MUST NOT contain transparent inputs where ``scriptSig`` does not begin with
|
||||||
|
``PROGRAM``.
|
||||||
|
|
||||||
|
- TODO: An alternative is to instead require that ``vin`` MUST be empty.
|
||||||
|
|
||||||
|
- ``vJoinSplit`` MUST be empty.
|
||||||
|
|
||||||
|
- The verification equation for RedJubjub signatures is altered to remove the cofactor
|
||||||
|
multiplication. Implementations MUST NOT use batch verification [#batch-verification]_
|
||||||
|
to verify RedJubjub signatures in transactions containing ``PROGRAM``.
|
||||||
|
|
||||||
|
Rationale
|
||||||
|
=========
|
||||||
|
|
||||||
|
Placing the transparent program information into ``scriptPubKey`` and ``scriptSig`` via
|
||||||
|
a new opcode enables this functionality without requiring a transaction format change.
|
||||||
|
This greatly simplifies deployment, as no parsers need to be updated, and script
|
||||||
|
verification engines that don't care about program inputs require minimal changes.
|
||||||
|
Alternatives were considered where the transparent program information was attached to
|
||||||
|
shielded spends and outputs, or to new program-specific transparent inputs and outputs;
|
||||||
|
both of these were excluded because the implementation complexity cost was not worth the
|
||||||
|
benefits, given that this ZIP is intended as a short-term transparent solution.
|
||||||
|
|
||||||
|
The consensus rule permitting ``vin`` to contain transparent programs if any transparent
|
||||||
|
output is encumbered, allows a transparent program to be funded by another transparent
|
||||||
|
program, but not by any transparent address.
|
||||||
|
|
||||||
|
The RedJubjub verification algorithm is only altered for transactions containing the
|
||||||
|
``PROGRAM`` opcode for two reasons: it allows batch verification for non-program
|
||||||
|
transactions, and if a security vulnerability were discovered in this change, programs can
|
||||||
|
be disabled without affecting general Sapling transactions.
|
||||||
|
|
||||||
|
|
||||||
|
Security and Privacy Considerations
|
||||||
|
===================================
|
||||||
|
|
||||||
|
This ZIP removes all sources of malleability that are currently present in the transaction
|
||||||
|
format, for transactions containing a ``PROGRAM`` opcode. However, the ``predicate`` and
|
||||||
|
``witness`` byte sequences are treated here as opaque, and ``witness`` is not part of any
|
||||||
|
signed data (as it is stored in the ``scriptSig`` field). It is the responsibility of
|
||||||
|
``verify_program`` to enforce the following:
|
||||||
|
|
||||||
|
- ``witness`` MUST be non-malleable: any malleation MUST cause ``verify_program`` to
|
||||||
|
return ``false``.
|
||||||
|
- The output of ``verify_program(predicate, witness, context)`` MUST be deterministic.
|
||||||
|
|
||||||
|
ZIPs defining new program types MUST include a section explaining how any potential
|
||||||
|
sources of malleability are handled.
|
||||||
|
|
||||||
|
|
||||||
|
Reference Implementation
|
||||||
|
========================
|
||||||
|
|
||||||
|
TBD
|
||||||
|
|
||||||
|
|
||||||
|
Acknowledgements
|
||||||
|
================
|
||||||
|
|
||||||
|
James Prestwich made the observation that the initial draft design could be simplified by
|
||||||
|
using the ``scriptPubKey`` and ``scriptSig`` fields with a dedicated ``PROGRAM`` opcode.
|
||||||
|
This in turn was influenced by BIP 141. The handler semantics of ``verify_program`` were
|
||||||
|
suggested by Zaki Manian, drawing on the design of Cosmos. Daira Hopwood and Sean Bowe
|
||||||
|
gave useful feedback on an early draft of this ZIP, and helped to analyse the various
|
||||||
|
sources of transaction ID malleability.
|
||||||
|
|
||||||
|
We would also like to thank the numerous other individuals who participated in discussions
|
||||||
|
at Zcon1 that led to this ZIP.
|
||||||
|
|
||||||
|
|
||||||
|
References
|
||||||
|
==========
|
||||||
|
|
||||||
|
.. [#RFC2119] `Key words for use in RFCs to Indicate Requirement Levels <https://tools.ietf.org/html/rfc2119>`_
|
||||||
|
.. [#zip-0200] `ZIP 200: Network Upgrade Activation Mechanism <https://github.com/zcash/zips/blob/master/zip-0200.rst>`_
|
||||||
|
.. [#zip-0205] `ZIP 205: Deployment of the Sapling Network Upgrade <https://github.com/zcash/zips/blob/master/zip-0205.rst>`_
|
||||||
|
.. [#zip-draft-bolt] `Draft ZIP: Add support for Blind Off-chain Lightweight Transactions (Bolt) protocol <https://github.com/zcash/zips/pull/216>`_
|
||||||
|
.. [#bip-0141] `BIP 141: Segregated Witness (Consensus layer) <https://github.com/bitcoin/bips/blob/master/bip-0141.mediawiki>`_
|
||||||
|
.. [#redjubjub] `Section 5.4.6: RedDSA and RedJubjub. Zcash Protocol Specification, Version 2019.0.2 [Overwinter+Sapling] <https://github.com/zcash/zips/blob/master/protocol/protocol.pdf>`_
|
||||||
|
.. [#spec-notation] `Section 2: Notation. Zcash Protocol Specification, Version 2019.0.2 [Overwinter+Sapling] <https://github.com/zcash/zips/blob/master/protocol/protocol.pdf>`_
|
||||||
|
.. [#zip-0032] `ZIP 32: Shielded Hierarchical Deterministic Wallets <https://github.com/zcash/zips/blob/master/zip-0032.rst>`_
|
||||||
|
.. [#batch-verification] `Section B.1: RedDSA batch verification. Zcash Protocol Specification, Version 2019.0.2 [Overwinter+Sapling] <https://github.com/zcash/zips/blob/master/protocol/protocol.pdf>`_
|
Loading…
Reference in New Issue