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

Draft of ZenIP 42205 for a cross-sidechain communication protocol #23

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
165 changes: 165 additions & 0 deletions zenip-42205.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@

# ZenIP-42205

ZenIP: 42205
Title: Cross-sidechain communication protocol
Owner: Paolo Cappelletti, <[email protected]>
Discussions-To: Paolo Cappelletti, <[email protected]>
Comments-URI: https://horizen.global/invite/discord
Status: Draft
Type: Consensus
Created: 2023-01-18
License: MIT

## Table of Contents

- [ZenIP-42205](#zenip-42205)
- [Terminology](#terminology)
- [Abstract](#abstract)
- [Motivation](#motivation)
- [Requirements](#requirements)
- [Specification](#specification)
- [References](#references)


## Terminology

The key words "MUST", "SHOULD", "SHOULD NOT", "MAY", "RECOMMENDED",
"OPTIONAL", and "REQUIRED" in this document are to be interpreted as
described in [RFC 2119](https://tools.ietf.org/html/rfc2119).

## Abstract

This ZenIP proposes the implementation of a cross-sidechain communication protocol, to exchange in a secure way arbitrary messages between two sidechains of the Horizen Ecosystem, as described in [[1]](#references).


## Motivation

There is a need for secure communications between blockchains such that data, including digital assets, can be transferred between them.

The definition of a communication protocol between sidechains will be the base layer on top of which we will be able to implement specific higher level applications, to enable the transfer of data between them.
For example, it will be possible to define a protocol allowing an application to transfer assets from one sidechain to another by transferring a message identifying the asset to be burnt in the sending sidechain and recreated with its properties in the receiving sidechain.

Inside the Horizen ecosystem, every sidechain is connected to the mainchain: the mainchain collects certificates from all the sidechains, and they contribute to the creation of a data structure (the sidechain commitment tree) representing all the state-changes happening in the sidechains that are relevant for the Mainchain [[2]](#references).
The Merkle root of this tree is shared among all the chains.
By leveraging this feature, and by defining a zero-knowledge proof of authenticity of each message with an “anchor” to this tree root, we will use the mainchain as a *trusted intermediary* between the two sidechains.

## Requirements

The messaging protocol is designed to be generic, not bound to a specific message format.

The messaging protocol is designed to not require any hard-fork on the mainchain: no changes on certificate data format.


## Specification

**Application flow**

The high-level flow will be implemented as described in [[1]](#references), and summarized here:
- one or more messages will be published in the sender sidechain.
- All the messages published inside each epoch will be collected in a Merkle tree, and the tree root will be included in a specific custom field inside every certificate of the epoch.
Furthermore, we require to insert in another specific custom field the reference to the previous epoch’s top quality certificate. This is used to identify the top-quality certificate of each epoch, that is the only relevant certificate for proof calculation and verification.
- A redeem message will be generated on the sender sidechain, containing a zkProof of authenticity of the message. It will be posted and verified on the receiving sidechain.

We will assume the sender sidechain is of non-ceasable type (this proposal does not cover any methods for exchanging messages from a ceased sidechain).

**Entity definition**

We define the following entities:

A *cross chain message* is a generic message to be exchanged between two sidechains.
It will be composed by the following attributes:
- `sendingScId: ByteArray`: identifier of the sending sidechain
- `receivingScId: ByteArray`: identifier of the receiving sidechain
- `msgType: Int`: Identifier of the type of message.
Note this has not to be unique, and will be meaningful only for the upper protocol established by the two sidechains
- `sender: ByteArray`: Address of the creator of the message in the sending sidechain
- `receiver: ByteArray`: Address of the receiver in the receiving sidechain
- `payload: ByteArray`: This is the body of the message exchanged.
Can be any kind of message, meaningful only for the upper protocol established by the two sidechains

We also define `msg_hash` as the Poseidon Hash of all the previous fields.

A *redeem message* “wraps” the previous cross chain message by adding also the zk-proof of its authenticity, and all the public inputs needed to verify it.
It will be composed by the following attributes:
- `message: CrossChainMessage`
Cross chain message to be redeemed (see previous entity)
- `certificateDataHash: ByteArray`
Certificate data hash of the certificate containing the message tree root where the message is committed in the sender sidechain
- `scCommitmentTreeRoot: ByteArray`
Sidechain commitment Merkle tree root where the above certificate was committed.
- `nextCertificateDataHash: ByteArray`
Certificate data hash of a next epoch certificate in the sender sidechain.
- `nextScCommitmentTreeRoot: ByteArray`
Sidechain commitment Merkle tree root where the above certificate was committed.
- `proof: ByteArray`
zk-proof of message authenticity.

**Certificate format**

Every sidechain that wants to act as “sender” MUST emit certificates with the following structure:
`N + M = 32 `

Where:
`M` = number of bit vector elements (not used by this specific application), where each bit represents the change of a particular leaf in the Merkle state tree.
`N` = number of certificate custom fields, all of them of fixed 32 bytes size.

A minimum amount of 3 custom fields will be required: fields at position 1 and 2 (0 based) will be reserved for this protocol.
- The custom field at position 1 MUST contain the root of a Merkle tree built with all the cross chain messages published in the epoch.
Each leaf of the Merkle tree is composed by `msg_hash`. Leaves will be valorized in order of message publication inside the sidechain.
We will refer to this root with `SC2SC_message_tree_root`
- The custom field at position 2 MUST contain the certificate data hash of the previous epoch’s top-quality certificate.

**Cryptographic components**

Every sidechain that wants to enable this protocol MUST use a cryptographic circuit, to allow the creation and verification of a SNARK proof of authenticity of the message. The proof will be included inside the redeem message.

Sender sidechain will be responsible for its creation, receiver sidechain for its verification.

Each proof MUST be generated for one and only one message.
The proof specification, for a message msg published in an epoch N, is as follows:

Public inputs:
- Sidechain commitment tree root of epoch N+1 (`next_sc_tx_commitment_root`)
- Sidechain commitment tree root of epoch N (`curr_sc_tx_commitment_root`)
- Hash of the message to be redeemed (`msg_hash`)

Witnesses:

- The ID of the SC (`sc_id`)
- A certificate for epoch N+1 (`next_cert`)
(can be any certificate, not mandatory to be the top-quality one)
- Merkle path of `next_cert` data hash inside the subtree of certificates for the SC at epoch N+1 (`next_cert_path`)
- Merkle root of the subtree of forward transfers for the SC at epoch N+1 (`next_fwt_root`)
- Merkle root of the subtree of backward transfers for the SC at epoch N+1 (`next_bt_root`)
- Merkle path of the SC commitment inside the SC commitment tree at epoch N+1 (`next_sc_comm_tree_path`)
- Top quality certificate for epoch N (`curr_cert`)
- Merkle path of `curr_cert` data hash inside the subtree of certificates for the SC at epoch N (`curr_cert_path`)
- Merkle root of the subtree of forward transfers for the SC at epoch N (`curr_fwt_root`)
- Merkle root of the subtree of backward transfers for the SC at epoch N (`curr_bt_root`)
- Sidechain creation transaction of the SC (`scc_tx`)
- Merkle path of the SC commitment inside the SC commitment tree at epoch N+1 (`curr_sc_comm_tree_path`)
- Merkle path of the message to be redeemed inside SC2SC_message_tree_root present in the custom field of `curr_cert` (`msg_path`)

Statements:
- `next_cert_root = ApplyMerklePath(H(next_cert), next_cert_path)`
- `curr_cert_root = ApplyMerklePath(H(curr_cert), curr_cert_path)`
- `next_sc_root = H(next_fwt_root, next_bt_root, next_cert_root, scc_tx, sc_id)`
- `curr_sc_root = H(curr_fwt_root, curr_bt_root, curr_cert_root, scc_tx, sc_id)`
- `VrfyMembership(next_sc_root , next_sc_comm_tree_path, next_sc_tx_commitment_root) == TRUE`
- `VrfyMembership(curr_sc_root , curr_sc_comm_tree_path, curr_sc_tx_commitment_root) == TRUE`
- `next_cert.previous_top_quality_hash == H(curr_cert)`
- `curr_cert.epoch == next_cert.epoch - 1`
- `VrfyMembership(msg_hash, msg_path, curr_cert.SC2SC_message_tree_root) == TRUE`

The circuit will assume the format previously described for the certificate custom fields (total size of custom fields + bit vector elements and fixed position of the relevant custom fields).

## References

[1] [Trustless Cross-chain Communication for Zendoo Sidechains (paper)
](https://arxiv.org/pdf/2209.03907.pdf)

[2] [Zendoo: a zk-SNARK Verifiable Cross-Chain Transfer Protocol Enabling Decoupled and Decentralized Sidechains](https://www.horizen.io/assets/files/Horizen-Sidechain-Zendoo-A_zk-SNARK-Verifiable-Cross-Chain-Transfer-Protocol.pdf)