Skip to content
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

[ZIP ???] Whitelisted Transparent Programs #248

Draft
wants to merge 1 commit into
base: master
from

Conversation

@str4d
Copy link
Contributor

str4d commented Jul 3, 2019

No description provided.


PUSHDATA(type || witness) PUSHDATA(type || predicate)

TODO: Alternatively, we could enforce that the script fails-closed for old script

This comment has been minimized.

Copy link
@prestwich

prestwich Jul 3, 2019

worth noting that if old parsers handle it as anyone can spend that this is a restrictive (softfork) change

This comment has been minimized.

Copy link
@prestwich

prestwich Jul 3, 2019

If breaking old parsers fail is desirable, it would be elegant to repurpose OP_VERIF or OP_VERNOTIF rather than OP_NOP10. These currently cause evaluation to fail if present in a Script (even if in unexecuted branches).

- 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

This comment has been minimized.

Copy link
@prestwich

prestwich Jul 3, 2019

Currently, while a tx can become invalid (if an input is spent, or if it expires), a Script never can. This means Script validity can be evaluated and cached as soon as a tx is received. It would be nice to preserve this property for WTPs. Passing in the blockchain as part of the evaluation context prevents us from doing this though

This comment has been minimized.

Copy link
@str4d

str4d Jul 5, 2019

Author Contributor

Hmm, this is an interesting point. The reason for the context object was to enable logic like relative timelocks to just be part of the WTP. The way in which OP_CLTV and OP_CSV are implemented to ensure the Script never becomes invalid, is to have them operate on public transaction fields (nLocktime and nSequence), and then have those fields be contextually checked in the consensus rules.

The equivalent for WTPs would be to have an auxiliary byte sequence alongside witness, and two verification algorithms:

  • verify_auxiliary(auxiliary, context) - contextual, but requires minimal computation.
  • verify_program(predicate, auxiliary, witness) - potentially computation-heavy, but deterministic and cacheable.

The question then is whether it is okay for auxiliary to not be covered by the sighash (both nLocktime and nSequence are covered in SIGHASH_ALL mode, but the only place we can put arbitrary data is scriptSig which is never covered). I don't think it is, which means we'd need to commit to auxiliary somewhere. Given that we have not yet pulled in OP_CSV, we could repurpose nSequence ourselves, and have it contain a small digest of auxiliary (probably computed using BLAKE2b-32 for consistency with the rest of the protocol, though maybe that's overkill). Then the consensus rules can enforce nSequence contain this digest for transactions containing OP_PROGRAM.

Thoughts?

This comment has been minimized.

Copy link
@daira

daira Jul 5, 2019

Collaborator

Nothing prevents an implementation of the WTP verification from caching anything that it can validly cache. That is, it's possible to split WTP verification into noncontextual and contextual parts, just as an implementation detail, without any complication of the transaction format.

This comment has been minimized.

Copy link
@prestwich

prestwich Jul 5, 2019

without any complication of the transaction format.

This is very important to me as well :)

The reason for the context object was to enable logic like relative timelocks to just be part of the WTP.

I think that we could still do this elegantly by passing a context containing only limited information. For example, we could pass in the most recent block height, and the age of the transaction's parents, without passing in the entire history

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.

This comment has been minimized.

Copy link
@prestwich

prestwich Jul 3, 2019

This also allows incremental migration away from Script as part of the long-term migration from transparent addresses.

For example, it's trivial to make a program that replicates the current p2pkh Script semantics while removing malleability (and shaving a few bytes off every txn). So an intermediate step is to add programs for current t-addr use cases, and then deprecate the creation of new p2sh and p2pkh outputs

This comment has been minimized.

Copy link
@daira

daira Jul 5, 2019

Collaborator

This could even potentially allow you to still spend from such transparent programs after we remove script functionality altogether.

@ebfull

This comment has been minimized.

Copy link
Contributor

ebfull commented Jul 5, 2019

Unfortunately, it's insufficient for RedJubjub signatures to be non-malleable, or even checked to be canonical. The signer can produce many distinct signatures for the same message, and they are our adversary in this attack model.

@prestwich

This comment has been minimized.

Copy link

prestwich commented Jul 5, 2019

Unfortunately, it's insufficient for RedJubjub signatures to be non-malleable, or even checked to be canonical. The signer can produce many distinct signatures for the same message, and they are our adversary in this attack model.

Now that you bring it up, malleability may be a red herring. Can we just shortcut the entire "stored pre-signed transactions" process by encoding its rules into (one or more) verify_program WTPs acting as simple covenants? These would operate regardless of tx malleability.

Very rough sketch of Lightning (I would use Bolt, but I'm less familiar). Suppose we had 2 WTPs, open_channel and close_channel defined roughly as follows:

  1. open channel

    1. predicate contains 2 public keys, 1 for each party
    2. witness is defined as follows:
      1. 2 balances (1 for each party)
      2. a revocation digest
      3. 2 signatures (1 for each party) signing the above
    3. verify_program behaves as follows:
      1. check the signatures
      2. checks that 2 new outputs are created, with the specified balances, each paying a close_channel WTP containing the revocation hash and the respective pubkey
  2. close_channel

    1. predicate contains 1 pubkey, and the revocation hash
    2. witness is one of the following
      1. either a signature under the pubkey
      2. or the preimage of the digest, and a signature under the other pubkey
    3. verfy_program behaves as follows:
      1. If witness is of type 1, check the signature, and check that a relative timeout has elapsed
      2. if witness is of type 2, check the signature, and check the preimage

I don't believe this scheme is broken by malleability, as it enforce the rules via covenants rather than pre-signed txns.

@daira daira force-pushed the zcash:master branch 15 times, most recently from 4864dde to c333fe2 Aug 6, 2019
@daira

This comment has been minimized.

Copy link
Collaborator

daira commented Aug 8, 2019

Shall I mark this as an NU4 proposal?

@daira daira force-pushed the zcash:master branch from 0aef8ce to 2815bee Aug 24, 2019
@str4d str4d added the NU4 proposal label Sep 1, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
4 participants
You can’t perform that action at this time.