Skip to content

Conversation

str4d
Copy link
Collaborator

@str4d str4d commented Jan 8, 2018

No description provided.

@str4d
Copy link
Collaborator Author

str4d commented Jan 9, 2018

WRT replay protection, we decided in a meeting today that the branch ID in the transaction's block serialization format would be used for replay protection, so its presence in the personalization field is no longer specifically needed for replay protection. But we will leave it there because it is good practice to personalize the hash function over the desired domain (in our case, the branch "epoch" as referred to in #128).

2. hashPrevouts (32-byte hash)
3. hashSequence (32-byte hash)
4. hashOutputs (32-byte hash)
5. hashJoinSplits (32-byte hash)
Copy link
Collaborator Author

@str4d str4d Jan 9, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(in reply to str4d@3d29239#r26720276)

@daira I was thinking that we might end up having separate hashes for input and output Sapling circuits, ie:

5. hashJoinSplits (32-byte hash)
6. hashShieldedInputs (32-byte hash)
7. hashShieldedOutputs (32-byte hash)

I'm not sure whether we need this kind of flexibility though, in the way that it is useful for the different transparent sighash types (because I expect we'd want to implement those in a zero-knowledge way, which doing inside a visible signature would not be).

Note that we will need to have another ZIP with a newer SigHash specification anyway when we address transaction malleability.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We discussed this in a pairing, and decided that we don't need to add anything for Sapling in advance; we can conditionally add it to the algorithm (gated on transaction version) when we add Sapling.


2: ``hashPrevouts``
```````````````````
* If the ``ANYONECANPAY`` flag is not set, ``hashPrevouts`` is the double SHA256 of the serialization of all
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(in reply to str4d@3d29239#r26723101)

@daira these are the inner hashes. Do we want to change these to BLAKE2 as well? And if so, we should personalize them too.

5: ``hashJoinSplits``
`````````````````````
* If ``vjoinsplits`` is non-empty, ``hashJoinSplits`` is the double SHA256 of the serialization of all
JoinSplits concatenated with the joinSplitPubKey;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(in reply to str4d@3d29239#r26723268)

@daira I don't think we want this encoded as in a transaction:

  • The transaction uses a std::vector encoding for vin, vout, and vjoinsplit, whereas the other hash* in this proposal (of data from vin and vout) use simple concatenation. We should follow the latter here for consistency with vjoinsplit.
  • In Sprout we serialized a "null" joinSplitSig. I see no need to do that here.

inside CTxOuts);

* If sighash type is ``SINGLE`` and the input index is smaller than the number of outputs, ``hashOutputs`` is
the double SHA256 of the output amount with ``scriptPubKey`` of the same index as the input;
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(in reply to str4d@3d29239#r26723147)

@daira agreed, the wording from BIP 143 isn't clear. It means the same serialization as the first case, but only of the output corresponding to the input signature being created (instead of the whole vout).

#. ``SINGLE`` does not commit to the input index. When ``ANYONECANPAY`` is not set, the semantics are
unchanged since ``hashPrevouts`` and ``outpoint`` together implictly commit to the input index. When
``SINGLE`` is used with ``ANYONECANPAY``, omission of the index commitment allows permutation of the
input-output pairs, as long as each pair is located at an equivalent index.
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

(in reply to str4d@3d29239#r26723093)

@daira I don't think there's any security issue. It just allows shuffling of the order of transparent input/output pairs, in the same way Sapling will allow shuffling of the order of input circuits and output circuits (not in pairs).

Title: Transaction Signature Verification for Overwinter
Author: Jack Grigg <jack@z.cash>
Daira Hopwood <daira@z.cash>
Credits: Johnson Lau <jl2012@xbt.hk>
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should also credit BitcoinABC because they inspired ticket #2584 by writing up a spec https://github.com/Bitcoin-UAHF/spec/blob/master/uahf-technical-spec.md and https://github.com/Bitcoin-ABC/bitcoin-abc/blob/master/doc/abc/replay-protected-sighash.md demonstrating how to extract the relevant bits from BIP 143 etc.

4. hashSequence (32-byte hash)
5. hashOutputs (32-byte hash)
6. hashJoinSplits (32-byte hash)
7. nLockTime of the transaction (8-byte little endian)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nLockTime is uint32_t

5. hashOutputs (32-byte hash)
6. hashJoinSplits (32-byte hash)
7. nLockTime of the transaction (8-byte little endian)
8. nExpiryTime of the transaction (8-byte little endian)
Copy link
Contributor

@bitcartel bitcartel Jan 17, 2018

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rename to nExpiryHeight. Also both nLockTime and nExpiryHeight are uint32_t so 4-byte little endian, not 8-byte.


"ZcashSigHash" || BLOCK_BRANCH_ID

``BLOCK_BRANCH_ID`` is the ``BRANCH_ID`` for the epoch of the transaction's parent block. [#ZIP-activation-mechanism]_
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we think of terminology that better clarifies the different identifiers? e.g. FAMILY_BRANCH_ID (I think family, e.g. Zcash or some clone) whereas EPOCH_ID (epoch makes me think of time so then I start thinking that the ID will expire, makes me less confident/comfortable for some reason).

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Above comment is probably not relevant given recent discussion.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Decided to name it CONSENSUS_BRANCH_ID to match usage in the code.

@daira
Copy link
Collaborator

daira commented Jan 25, 2018

The BLAKE2b personalization field for the inner hashes should be "Zcash_Inner_Hash".

zkbot added a commit to zcash/zcash that referenced this pull request Feb 8, 2018
Overwinter SignatureHash

Implements zcash/zips#129.

Includes code cherry-picked from the following upstream PRs:

- bitcoin/bitcoin#7276
- bitcoin/bitcoin#7976
- bitcoin/bitcoin#8118
- bitcoin/bitcoin#8149
  - Only amount validation and SignatureHash commits.
- bitcoin/bitcoin#6915
  - Only the rework of `mempool.check()` calls that the next PR depends on.
- bitcoin/bitcoin#8346
- bitcoin/bitcoin#8524

Part of  #2254. Closes #1408 and #2584.
A new transaction digest algorithm is defined, but only applicable from the Overwinter upgrade block height
[#ZIP0000]_::
BLAKE2b-256 of the serialization of:
1. nVersion of the transaction (4-byte little endian)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Referred to in the transaction format zip as header. you could break this into compontents fOverwintered flag and nVersion.

[#ZIP0000]_::
BLAKE2b-256 of the serialization of:
1. nVersion of the transaction (4-byte little endian)
2. nVersionBranch of the transaction (4-byte little endian)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Now: nVersionGroupId

c. value of the output spent by this input (8-byte little endian)
d. nSequence of the input (4-byte little endian)

The BLAKE2b-256 personalization field is set to::
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add link/reference to blake2

* Transaction creators MUST specify the epoch they want their transaction to be mined in. Across a network
upgrade, this means that if a transaction is not mined before the activation height, it will never be mined.

* Transaction validators MUST NOT use ``nVersionBranch`` as the ``BLOCK_BRANCH_ID``: while these are both a
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

WIth nVersionGroupId, this bullet point is rendundant and could be removed.

Field definitions
-----------------

The items 1, 7, 9, 10a, 10d have the same meaning as the original algorithm. [#wiki-checksig]_
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Item 1 is now the header and not nversion.


The items 1, 7, 9, 10a, 10d have the same meaning as the original algorithm. [#wiki-checksig]_

2: ``nVersionBranch``
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nVersionGroupId - so this section should be reworked.

The ``BRANCH_ID`` of the epoch in which the transaction format corresponding to ``nVersion`` was introduced.
[#ZIP-overwinter-tx-format]_

3: ``hashPrevouts``
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So most of this document here is the same as BIP143 and this should be made clearer at start of ZIP.
It would be helpful if we clearly labelled which sections are Zcash only, which are pure BIP143 and which are BIP143+ZcashModification This will help folk who are familiar with that BIP.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Added a note about this being based on BIP 143. Note that none of the document is pure BIP 143 anymore, so while some code reuse is possible, it will likely be of the copy-paste form (e.g. hashPrevouts now uses BLAKE2b, not SHA256d, so a function for calculating that can't trivially be reused).

JoinSplits (in their canonical transaction serialization format) concatenated with the joinSplitPubKey;

* Note that the JoinSplit proofs are included in the signature hash, as with v1 and v2 transactions. In a
future transaction digest algorithm, the proofs will likely be omitted as authentication data, in the same
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Remove "In a future..." as not relevant to current spec.


* Otherwise, ``hashJoinSplits`` is a ``uint256`` of ``0x0000......0000``.

8: ``nExpiryTime``
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

nExpiryHeight


8: ``nExpiryTime``
``````````````
The block height or time at which the transaction becomes unilaterally invalid, and can never be mined.
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Only block height, not time.
The last block height a transaction can be valid.

@bitcartel
Copy link
Contributor

Added extra review comments, seems to be broken up by Github into two sections above.

@str4d
Copy link
Collaborator Author

str4d commented Feb 9, 2018

@bitcartel addressed your comments.

@str4d str4d requested review from bitcartel and daira February 9, 2018 16:15
-----

When generating ``hashPrevouts``, ``hashSequence``, ``hashOutputs``, and ``hashJoinSplits``, the BLAKE2b-256
personalization field is set to ``Zcash_Inner_Hash``.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is there a specific reason for sharing the personalization field across all 4 input types? It seems better to domain separate these different input types if possible. (To be clear I don't see any specific problem caused by this, and perhaps using a single string allows some optimization I've missed - but if so, maybe the text should mention said optimization.)

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, let's change these to:

  • ZcashPrevoutHash
  • ZcashSequencHash [spelling intended]
  • ZcashOutputsHash
  • ZcashJSplitsHash

@daira daira changed the title Overwinter signature hashing ZIP [ZIP 143] Transaction Signature Verification for Overwinter Feb 16, 2018
Credits: Johnson Lau <jl2012@xbt.hk>
Pieter Wuille <pieter.wuille@gmail.com>
Bitcoin-ABC
Category: Process
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Category: Consensus


There are 4 ECDSA signature verification codes in the original Zcash script system: ``CHECKSIG``,
``CHECKSIGVERIFY``, ``CHECKMULTISIG``, ``CHECKMULTISIGVERIFY`` ("sigops"). According to the sighash type
(``ALL``, ``NONE``, or ``SINGLE``, possibly modified by ``ANYONECANPAY``), a transaction digest is generated
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is rst not Markdown, so single backticks for monospace throughout the document.

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Per http://docutils.sourceforge.net/docs/user/rst/quickref.html#inline-markup double backticks is an inline literal rendered as monospace, while single backticks are interpreted text, which could be for explicit descriptive markup like program identifiers. Markdown is single ticks for code.

The new algorithm MUST be used for signatures created over the Overwinter transaction format.
[#ZIP-overwinter-tx-format]_ Combined with the new consensus rule that v1 and v2 transaction formats will be
invalid from the Overwinter upgrade, [#ZIP-overwinter-tx-format]_ this effectively means that all transactions
signatures from the Overwinter activation height will use the new algorithm. [#ZIP0000]_
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

What is #ZIP0000 intended to reference?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think I planned to link to whichever ZIP contained the activation heights.

transaction. Therefore, data hashing grows in O(n\ :sup:`2`) as the number of sigops in a transaction
increases. While a 1 MB block would normally take 2 seconds to verify with an average computer in 2015, a
1MB transaction with 5569 sigops may take 25 seconds to verify. This could be fixed by optimizing the digest
algorithm by introducing some reusable “midstate”, so the time complexity becomes O(n). [#quadratic]_
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Non-ASCII quotes are used here, plain ASCII quotes elsewhere (e.g. "cold wallet"). Unicode is allowed in ZIPs, but consistency is preferable. I would suggest just using plain quotes.

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This wording leaves questions in a reader's mind: what is "midstate"? Does the proposal adopted in this ZIP use midstate?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is the same wording as in BIP 143, so I'm fine leaving it as-is, unless you have an alternative suggestion.

7. nLockTime of the transaction (4-byte little endian)
8. nExpiryHeight of the transaction (4-byte little endian)
9. sighash type of the signature (4-byte little endian)
10. If we are serializing an input (ie. this is not a JoinSplit signature hash):
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/ie./i.e./

{'Z','c','a','s','h','O','u','t','p','u','t','s','H','a','s','h'};
const unsigned char ZCASH_JOINSPLITS_HASH_PERSONALIZATION[16] =
{'Z','c','a','s','h','J','S','p','l','i','t','s','H','a','s','h'};

Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Add a comment that the default values are zeros.

hashJoinSplits = ss.GetHash();
}

uint32_t leConsensusBranchId = htole32(consensusBranchId);
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Aside: I've never really liked htole32 and friends; they seem to me to be making a type error that is then compensated for by another type error at the memcpy. (Does not block.)

-----

The ``hashPrevouts``, ``hashSequence``, ``hashOutputs``, and ``hashJoinSplits`` calculated in an earlier
verification may be reused in other inputs of the same transaction, so that the time complexity of the whole
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

s/may/can/

Deployment
==========

This proposal is deployed with the Overwinter network upgrade.
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Reference ZIP 201 for the activation heights.

Example
=======

TBC
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

An example is not needed to merge this, but please file a ticket to add one.

zkbot added a commit to zcash/zcash that referenced this pull request Feb 19, 2018
Overwinter SignatureHash

Implements zcash/zips#129.

Includes code cherry-picked from the following upstream PRs:

- bitcoin/bitcoin#7276
- bitcoin/bitcoin#7976
- bitcoin/bitcoin#8118
- bitcoin/bitcoin#8149
  - Only amount validation and SignatureHash commits.
- bitcoin/bitcoin#6915
  - Only the rework of `mempool.check()` calls that the next PR depends on.
- bitcoin/bitcoin#8346
- bitcoin/bitcoin#8524

Part of #2074 and #2254. Closes #1408 and #2584.
@str4d
Copy link
Collaborator Author

str4d commented Feb 20, 2018

In zcash/zcash#2584 (comment) @daira wrote:

Let's call it "Replay-Protected Scalable Lightweight-wallet-friendly hashing" or "RPSL hashing".

Do you still want this?

Copy link
Collaborator

@daira daira left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ACK

@daira daira mentioned this pull request Mar 2, 2018
@daira daira merged commit ed7cef7 into zcash:master Mar 2, 2018
@str4d str4d deleted the 2584-zip-143 branch November 3, 2022 09:37
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants