From 238d00275e318eaf21994b42a596784d68a08a98 Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Mon, 23 Mar 2020 16:31:39 +0000 Subject: [PATCH 1/3] ZIP 221: strengthen caveat about FlyClient security in chains with rapid difficulty adjustment. Signed-off-by: Daira Hopwood --- zip-0221.html | 5 +++-- zip-0221.rst | 8 ++++++-- 2 files changed, 9 insertions(+), 4 deletions(-) diff --git a/zip-0221.html b/zip-0221.html index a6882c16..0842df2f 100644 --- a/zip-0221.html +++ b/zip-0221.html @@ -586,10 +586,11 @@ License: MIT

Given the performance of BLAKE2b, we expect this validation cost to be negligible. However, it seems prudent to benchmark potential MMR implementations during the implementation process. Should the validation cost be higher than expected, there are several potential mitigations, e.g. holding recently seen nodes in memory after a reorg.

Generally, header commitments have no impact on privacy. However, FlyClient has additional security and privacy implications. Because FlyClient is a motivating factor for this ZIP, it seems prudent to include a brief overview. A more in-depth security analysis of FlyClient should be performed before designing a FlyClient-based light client ecosystem for Zcash.

FlyClient, like all light clients, requires a connection to a light client server. That server may collect information about client requests, and may use that information to attempt to deanonymize clients. However, because FlyClient proofs are non-interactive and publicly verifiable, they could be shared among many light clients after the initial server interaction.

-

FlyClient proofs are probabilistic. When properly constructed, there is negligible probability that a dishonest chain commitment will be accepted by the verifier. The security analysis assumes adversary mining power is bounded by a known fraction of combined mining power of honest nodes, and cannot drop or tamper with messages between client and full nodes. It also assumes the client is connected to at least one full node and knows the genesis block. However, these security properties have not been examined closely in chain models with rapidly adjusting difficulty.

+

FlyClient proofs are probabilistic. When properly constructed, there is negligible probability that a dishonest chain commitment will be accepted by the verifier. The security analysis assumes adversary mining power is bounded by a known fraction of combined mining power of honest nodes, and cannot drop or tamper with messages between client and full nodes. It also assumes the client is connected to at least one full node and knows the genesis block.

+

In addition, 2 only analyses these security properties in chain models with slowly adjusting difficulty, such as Bitcoin. It leaves their analysis in chains with rapidly adjusting difficulty –such as Zcash or Ethereum– as an open problem, and states that the FlyClient protocol provides only heuristic security guarantees in that case.

Deployment

-

This proposal will be deployed with the Heartwood network upgrade. 9

+

This proposal will be deployed with the Heartwood network upgrade. 9

Additional Reading

    diff --git a/zip-0221.rst b/zip-0221.rst index 2b0be90c..bec6ad11 100644 --- a/zip-0221.rst +++ b/zip-0221.rst @@ -711,8 +711,12 @@ probability that a dishonest chain commitment will be accepted by the verifier. security analysis assumes adversary mining power is bounded by a known fraction of combined mining power of honest nodes, and cannot drop or tamper with messages between client and full nodes. It also assumes the client is connected to at least one full node -and knows the genesis block. However, these security properties have not been examined -closely in chain models with rapidly adjusting difficulty. +and knows the genesis block. + +In addition, [#FlyClient]_ only analyses these security properties in chain models with +slowly adjusting difficulty, such as Bitcoin. It leaves their analysis in chains with +rapidly adjusting difficulty –such as Zcash or Ethereum– as an open problem, and states +that the FlyClient protocol provides only heuristic security guarantees in that case. Deployment From 7196ab330c9c8981df4fb77a7ec80b5c2e84ed16 Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Tue, 24 Mar 2020 14:51:29 +0000 Subject: [PATCH 2/3] ZIP 221: update the discussion of difficulty adjustment in security considerations, per @str4d's review. Signed-off-by: Daira Hopwood --- zip-0221.html | 2 +- zip-0221.rst | 12 +++++++++--- 2 files changed, 10 insertions(+), 4 deletions(-) diff --git a/zip-0221.html b/zip-0221.html index 0842df2f..7aef4120 100644 --- a/zip-0221.html +++ b/zip-0221.html @@ -587,7 +587,7 @@ License: MIT

    Generally, header commitments have no impact on privacy. However, FlyClient has additional security and privacy implications. Because FlyClient is a motivating factor for this ZIP, it seems prudent to include a brief overview. A more in-depth security analysis of FlyClient should be performed before designing a FlyClient-based light client ecosystem for Zcash.

    FlyClient, like all light clients, requires a connection to a light client server. That server may collect information about client requests, and may use that information to attempt to deanonymize clients. However, because FlyClient proofs are non-interactive and publicly verifiable, they could be shared among many light clients after the initial server interaction.

    FlyClient proofs are probabilistic. When properly constructed, there is negligible probability that a dishonest chain commitment will be accepted by the verifier. The security analysis assumes adversary mining power is bounded by a known fraction of combined mining power of honest nodes, and cannot drop or tamper with messages between client and full nodes. It also assumes the client is connected to at least one full node and knows the genesis block.

    -

    In addition, 2 only analyses these security properties in chain models with slowly adjusting difficulty, such as Bitcoin. It leaves their analysis in chains with rapidly adjusting difficulty –such as Zcash or Ethereum– as an open problem, and states that the FlyClient protocol provides only heuristic security guarantees in that case.

    +

    In addition, 2 only analyses these security properties in chain models with slowly adjusting difficulty, such as Bitcoin. That paper leaves their analysis in chains with rapidly adjusting difficulty –such as Zcash or Ethereum– as an open problem, and states that the FlyClient protocol provides only heuristic security guarantees in that case. However, as mentioned in FlyClient Requirements and Recommendations, additional commitments allowing light clients to reason about application of the difficulty adjustment algorithm were added in discussion with an author of the FlyClient paper. The use of these fields has not been analysed in the academic security literature. It would be possible to update them in a future network upgrade if further security analysis were to find any deficiencies.

Deployment

This proposal will be deployed with the Heartwood network upgrade. 9

diff --git a/zip-0221.rst b/zip-0221.rst index bec6ad11..a0ab45cf 100644 --- a/zip-0221.rst +++ b/zip-0221.rst @@ -714,9 +714,15 @@ client and full nodes. It also assumes the client is connected to at least one f and knows the genesis block. In addition, [#FlyClient]_ only analyses these security properties in chain models with -slowly adjusting difficulty, such as Bitcoin. It leaves their analysis in chains with -rapidly adjusting difficulty –such as Zcash or Ethereum– as an open problem, and states -that the FlyClient protocol provides only heuristic security guarantees in that case. +slowly adjusting difficulty, such as Bitcoin. That paper leaves their analysis in chains +with rapidly adjusting difficulty –such as Zcash or Ethereum– as an open problem, and +states that the FlyClient protocol provides only heuristic security guarantees in that +case. However, as mentioned in `FlyClient Requirements and Recommendations`_, additional +commitments allowing light clients to reason about application of the difficulty adjustment +algorithm were added in discussion with an author of the FlyClient paper. The use of these +fields has not been analysed in the academic security literature. It would be possible to +update them in a future network upgrade if further security analysis were to find any +deficiencies. Deployment From e0c2123b05839b9c61cc8f057d491294ca2b9b65 Mon Sep 17 00:00:00 2001 From: Daira Hopwood Date: Tue, 24 Mar 2020 14:53:50 +0000 Subject: [PATCH 3/3] ZIP 221: change the pseudocode so that CONSENSUS_BRANCH_ID doesn't look as though it's a constant. Signed-off-by: Daira Hopwood --- zip-0221.html | 17 +++++++++-------- zip-0221.rst | 17 +++++++++-------- 2 files changed, 18 insertions(+), 16 deletions(-) diff --git a/zip-0221.html b/zip-0221.html index 7aef4120..9d9222b8 100644 --- a/zip-0221.html +++ b/zip-0221.html @@ -334,11 +334,8 @@ License: MIT

Once the MMR has been generated, we produce hashChainHistoryRoot, which we define as the BLAKE2b-256 digest of the serialization of the root node.

Tree nodes and hashing (pseudocode)

-
CONSENSUS_BRANCH_ID: bytes = b''
-
-
-def H(msg: bytes) -> bytes:
-    return blake2b256(msg, personalization=b'ZcashHistory' + CONSENSUS_BRANCH_ID)
+                
def H(msg: bytes, consensusBranchId: bytes) -> bytes:
+    return blake2b256(msg, personalization=b'ZcashHistory' + consensusBranchId)
 
 class ZcashMMRNode():
     # leaf nodes have no children
@@ -358,6 +355,8 @@ License: MIT
nLatestHeight: int nSaplingTxCount: int # number of Sapling transactions in block + consensusBranchId: bytes + @classmethod def from_block(Z, block: ZcashBlock) -> ZcashMMRNode: '''Create a leaf node from a block''' @@ -374,7 +373,8 @@ License: MIT
nSubTreeTotalWork=calculate_work(block.nBits), nEarliestHeight=block.height, nLatestHeight=block.height, - nSaplingTxCount=block.sapling_tx_count) + nSaplingTxCount=block.sapling_tx_count, + consensusBranchId=block.consensusBranchId) def serialize(self) -> bytes: '''serializes a node''' @@ -408,11 +408,12 @@ License: MIT nSubTreeTotalWork=left_child.nSubTreeTotalWork + right_child.nSubTreeTotalWork, nEarliestHeight=left_child.nEarliestHeight, nLatestHeight=right_child.nLatestHeight, - nSaplingTxCount=left_child.nSaplingTxCount + right_child.nSaplingTxCount) + nSaplingTxCount=left_child.nSaplingTxCount + right_child.nSaplingTxCount, + consensusBranchId=left_child.consensusBranchId) def make_root_commitment(root: ZcashMMRNode) -> bytes: '''Makes the root commitment for a blockheader''' - return H(root.serialize()) + return H(root.serialize(), root.consensusBranchId)

Incremental push and pop (pseudocode)

With each new block diff --git a/zip-0221.rst b/zip-0221.rst index a0ab45cf..a927baac 100644 --- a/zip-0221.rst +++ b/zip-0221.rst @@ -341,11 +341,8 @@ Tree nodes and hashing (pseudocode) .. code-block:: python - CONSENSUS_BRANCH_ID: bytes = b'' - - - def H(msg: bytes) -> bytes: - return blake2b256(msg, personalization=b'ZcashHistory' + CONSENSUS_BRANCH_ID) + def H(msg: bytes, consensusBranchId: bytes) -> bytes: + return blake2b256(msg, personalization=b'ZcashHistory' + consensusBranchId) class ZcashMMRNode(): # leaf nodes have no children @@ -365,6 +362,8 @@ Tree nodes and hashing (pseudocode) nLatestHeight: int nSaplingTxCount: int # number of Sapling transactions in block + consensusBranchId: bytes + @classmethod def from_block(Z, block: ZcashBlock) -> ZcashMMRNode: '''Create a leaf node from a block''' @@ -381,7 +380,8 @@ Tree nodes and hashing (pseudocode) nSubTreeTotalWork=calculate_work(block.nBits), nEarliestHeight=block.height, nLatestHeight=block.height, - nSaplingTxCount=block.sapling_tx_count) + nSaplingTxCount=block.sapling_tx_count, + consensusBranchId=block.consensusBranchId) def serialize(self) -> bytes: '''serializes a node''' @@ -415,11 +415,12 @@ Tree nodes and hashing (pseudocode) nSubTreeTotalWork=left_child.nSubTreeTotalWork + right_child.nSubTreeTotalWork, nEarliestHeight=left_child.nEarliestHeight, nLatestHeight=right_child.nLatestHeight, - nSaplingTxCount=left_child.nSaplingTxCount + right_child.nSaplingTxCount) + nSaplingTxCount=left_child.nSaplingTxCount + right_child.nSaplingTxCount, + consensusBranchId=left_child.consensusBranchId) def make_root_commitment(root: ZcashMMRNode) -> bytes: '''Makes the root commitment for a blockheader''' - return H(root.serialize()) + return H(root.serialize(), root.consensusBranchId) Incremental push and pop (pseudocode) -------------------------------------