Adds the sequence diagram of rln relay (#264)

* adds the registration image

* Updates the registration seq diagram with more descriotions

* WIP: the message verification diagram

* fixes some spacing issues

* minor

* adds the routing and publishing figure

* minor

* fixes a format issue

* adds nullifier map init for all the relay nodes

* removes box borders

* returns the borders

* fixes spacing issues

* Feature/add json rpc api spec (#265)

* Minor improvements; added polling for latest messages

* internalNullifier -> nullifier, and edits on the msc figures

* edits the slash part

* updates spacing of the rln-relay figure

* edits on entities

* Update waku-rln-relay.md

* adds references to the figures in the text

* minor

* adds one more relay node to the registration fig

* Add Admin API (#267)

* Add Admin API

* Update assets/rln-relay/rln-relay.msc

Co-authored-by: Oskar Thorén <ot@oskarthoren.com>

* changes the width of figure 2

* some spacing edits and file headers

* adds the registration image

* Updates the registration seq diagram with more descriotions

* WIP: the message verification diagram

* fixes some spacing issues

* minor

* adds the routing and publishing figure

* minor

* fixes a format issue

* adds nullifier map init for all the relay nodes

* removes box borders

* returns the borders

* fixes spacing issues

* internalNullifier -> nullifier, and edits on the msc figures

* edits the slash part

* updates spacing of the rln-relay figure

* edits on entities

* Update waku-rln-relay.md

* adds references to the figures in the text

* minor

* adds one more relay node to the registration fig

* Update assets/rln-relay/rln-relay.msc

Co-authored-by: Oskar Thorén <ot@oskarthoren.com>

* changes the width of figure 2

* some spacing edits and file headers

Co-authored-by: Hanno Cornelius <68783915+jm-clius@users.noreply.github.com>
Co-authored-by: Oskar Thorén <ot@oskarthoren.com>
This commit is contained in:
Sanaz Taheri Boshrooyeh 2020-12-06 20:52:31 -08:00 committed by GitHub
parent 9463537ccc
commit 92e81376fa
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 101 additions and 8 deletions

View File

@ -0,0 +1,43 @@
# Sequence diagram for RLN Relay protocol (publishing,routing, and slashing)
msc {
hscale="1",
wordwraparcs=true;
a [label=" "],
b [label=" "],
c [label=" "],
d [label=" "],
e [label=" "];
a rbox a [label="Relay Node: Publisher"],
b rbox b [label="Relay Node: Router"],
c rbox c [label="Relay Node"],
d rbox d [label="Relay Node"],
e note e [label="Membership Contract"];
|||;
b box b [label=" \n nullifierMap= [(nullifier, shareX, shareY)...] \n \n Initialize an empty map of the received nullifiers \n "],
c box c [label=" \n nullifierMap= [(nullifier, shareX, shareY)...] \n \n Initialize an empty map of the received nullifiers \n "],
d box d [label=" \n nullifierMap= [(nullifier, shareX, shareY)...] \n \n Initialize an empty map of the received nullifiers \n "];
|||;
...,
a -> a [label="Keep track of epoch"],
b -> b [label="Keep track of epoch"],
c -> c [label="Keep track of epoch"],
d -> d [label="Keep track of epoch"];
a box a [label=" \n Message: the intended message \n \n epoch: the current epoch \n "];
a box a [label=" \n A(x) = sk + H(sk, epoch)x \n \n shareX = H(message), shareY = A(shareX) \n \n nullifier = H(H(sk,epoch)) \n "];
a box a [label=" \n zkProof: generate the proof using zkSNARK \n "];
|||;
a => b [label="Message, epoch, proofBundle:(shareX, shareY, nullifier, zkProof) \n "];
b box b [label="1. If the received epoch is far from the current epoch"];
b -x c [label="Do not relay"];
b box b [label=" \n 2. If verification of zkProof failed \n "];
b -x c [label="Do not relay"];
b box b [label=" \n 3. If identical nullifier exists in the nullifierMap, \n \n extract the publisher sk \n "];
b -x c [label="Do not relay"];
b => e [label="Slash the publisher: Unlbock the deposit associated with sk"];
e => b [label="x ETH"];
b box b [label=" \n 4. If none of 1-3 happens, update the nullifierMap \n "];
b => c [label="Relay"];
b => d [label="Relay"];
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 122 KiB

View File

@ -0,0 +1,32 @@
# Sequence diagram for RLN Relay protocol (registration)
msc {
hscale = "2";
d [label = " "], a [label = " "],b [label = " "];
a rbox a [label="Relay Node A"],
b note b [label="Membership Contract"],
d rbox d [label = "Relay Node B"];
|||;
a box a [ label=" \n Generate sk,pk \n "] ;
a=>b [ label = " \n Register(pk, x ETH) \n " ] ;
|||;
b box b [label=" \n Insert pk as a leaf to the tree \n \n index: The index of the inserted leaf \n \n root: The updated tree root \n \n authPath: The authentication path \n "];
|||;
b=>a [ label = "index, root, authPath"];
|||;
..., ---;
... [ label = "Other relay nodes register and the membership tree gets updatetd" ];
..., ---;
a=>b [ label = "getRoot()" ] ;
b box b [label=" \n root: Get the current root\n "];
b=>a [ label = "root"];
..., --- [ label = " " ];
a=>b [ label = "getAuthPath(index)" ] ;
b box b [label=" \n authPath: Calculate the authentication path of the leaf with the given index and based on the current tree\n "];
b=>a [ label = "authPath"];
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 70 KiB

View File

@ -38,7 +38,7 @@ TODO: Fill in more
# Flow # Flow
## SetUp and Registration ## SetUp and Registration
A peer willing to publish a message is required to register. Registration is moderated through a smart contract deployed on the Ethereum blockchain. The state of the contract contains the list of registered members (realized by a Merkle Tree). A peer willing to publish a message is required to register. Registration is moderated through a smart contract deployed on the Ethereum blockchain. The state of the contract contains the list of registered members (realized by a Merkle Tree). An overview of registration is illustrated in Figure 1.
For the registration, a peer creates a transaction that sends x (TODO to be specified) ETH to the contract. The peer who has the "private key" `sk` associated with that deposit would be able to withdraw x ETH by providing valid proof. Note that `sk` is initially only known by the owning peer however it may get exposed to other peers in case the owner attempts spamming the system i.e., sending more than one message per epoch. For the registration, a peer creates a transaction that sends x (TODO to be specified) ETH to the contract. The peer who has the "private key" `sk` associated with that deposit would be able to withdraw x ETH by providing valid proof. Note that `sk` is initially only known by the owning peer however it may get exposed to other peers in case the owner attempts spamming the system i.e., sending more than one message per epoch.
@ -51,6 +51,16 @@ Once registered, the peer obtains the root of the tree (after the registration o
TODO: To specify the details of protobuf messages for the interaction with the contract TODO: To specify the details of protobuf messages for the interaction with the contract
<!-- diagram -->
<p align="center">
<img src="../../../assets/rln-relay/rln-relay.png" />
<br />
Figure 1: Registration.
</p>
TODO: the function calls in this figure as well as messages are subject to change
## Publishing ## Publishing
In order to publish at a given `epoch`, the publishing peer proceeds based on the regular relay protocol. However, in order to protect against spamming, each PubSub message must carry a `proofBundle`. At a high level, the `proofBundle` is a zero-knowledge proof (TODO: to clarify what a zero-knowledge proof means) signifying that the publishing peer is a registered member, and she has not exceeded the messaging rate at the given `epoch`. In order to publish at a given `epoch`, the publishing peer proceeds based on the regular relay protocol. However, in order to protect against spamming, each PubSub message must carry a `proofBundle`. At a high level, the `proofBundle` is a zero-knowledge proof (TODO: to clarify what a zero-knowledge proof means) signifying that the publishing peer is a registered member, and she has not exceeded the messaging rate at the given `epoch`.
@ -60,11 +70,11 @@ The `proofBundle` is embedded inside the `data` field of the PubSub message, whi
The proof generation relies on the knowledge of `sk` and `authPath` (that is why they should be permanently and privately stored by the owning peer). Further inputs to the proof generation are `root`, `epoch` and `payload||contentTopic` where `payload` and `contentTopic` come from the `WakuMessage` (TODO: the inputs of the proof generation may change). The proof generation results in the following data items which are included as part of the `ProofBundle`: The proof generation relies on the knowledge of `sk` and `authPath` (that is why they should be permanently and privately stored by the owning peer). Further inputs to the proof generation are `root`, `epoch` and `payload||contentTopic` where `payload` and `contentTopic` come from the `WakuMessage` (TODO: the inputs of the proof generation may change). The proof generation results in the following data items which are included as part of the `ProofBundle`:
1. `shareX` 1. `shareX`
2. `shareY` 2. `shareY`
3. `internalNullifier` 3. `nullifier`
4. `zkProof` 4. `zkProof`
The tuple of (`internalNullifier`, `shareX`, `ShareY`) can be seen as partial disclosure of peer's `sk` for the intended `epoch`. Given two such tuples with identical `internalNullifier` but distinct `shareX`, `ShareY` results in full disclosure of peer's `sk` and hence burning the associated deposit. Note that the `internalNullifier` is a deterministic value derived from `sk` and `epoch` therefore any two messages issued by the same peer (i.e., sing the same `sk`) for the same `epoch` are guaranteed to have identical `internalNullifier`s. The tuple of (`nullifier`, `shareX`, `ShareY`) can be seen as partial disclosure of peer's `sk` for the intended `epoch`. Given two such tuples with identical `nullifier` but distinct `shareX`, `ShareY` results in full disclosure of peer's `sk` and hence burning the associated deposit. Note that the `nullifier` is a deterministic value derived from `sk` and `epoch` therefore any two messages issued by the same peer (i.e., sing the same `sk`) for the same `epoch` are guaranteed to have identical `nullifier`s.
Note that the `authPath` of each peer depends on the current status of the registration tree (hence changes when new peers register). As such, it is recommended (and necessary for anonymity) that the publisher updates her `authPath` based on the latest status of the tree and attempts the proof using her updated `authPath`. Note that the `authPath` of each peer depends on the current status of the registration tree (hence changes when new peers register). As such, it is recommended (and necessary for anonymity) that the publisher updates her `authPath` based on the latest status of the tree and attempts the proof using her updated `authPath`.
@ -72,21 +82,29 @@ Note that the `authPath` of each peer depends on the current status of the regis
## Routing ## Routing
Upon the receipt of a PubSub message, the routing peer needs to extract and parse the `proofBundle` from the `data` field. If the `epoch` attached to the message has a non-reasonable gap (TODO: the gap should be defined) with the routing peer's current `epoch` then the message must be dropped (this is to prevent a newly registered peer spamming the system by messaging for all the past epochs). Upon the receipt of a PubSub message, the routing peer needs to extract and parse the `proofBundle` from the `data` field. If the `epoch` attached to the message has a non-reasonable gap (TODO: the gap should be defined) with the routing peer's current `epoch` then the message must be dropped (this is to prevent a newly registered peer spamming the system by messaging for all the past epochs).
Furthermore, the routing peers MUST check whether the `proofBundle` is valid and the message is not spam. If both checks are passed successfully, then the message is relayed. If `proofBundle` is invalid then the message is dropped. If spamming is detected, the publishing peer gets slashed. Furthermore, the routing peers MUST check whether the `proofBundle` is valid and the message is not spam. If both checks are passed successfully, then the message is relayed. If `proofBundle` is invalid then the message is dropped. If spamming is detected, the publishing peer gets slashed. An overview of routing procedure is depicted in Figure 2.
### Spam Detection and Slashing ### Spam Detection and Slashing
In order to enable local spam detection and slashing, routing peers MUST record the `internalNullifier`, `shareX`, and `shareY` of any incoming message conditioned that it is not spam and has valid proof. To do so, the peer should follow the following steps. In order to enable local spam detection and slashing, routing peers MUST record the `nullifier`, `shareX`, and `shareY` of any incoming message conditioned that it is not spam and has valid proof. To do so, the peer should follow the following steps.
1. The routing peer first verifies the `zkProof` and drops the message if not verified. 1. The routing peer first verifies the `zkProof` and drops the message if not verified.
2. Otherwise, it checks whether a message with an identical `internalNullifier` has already been relayed. 2. Otherwise, it checks whether a message with an identical `nullifier` has already been relayed.
1. If such message exists and its `shareX` and `shareY` components are different from the incoming message, then slashing takes place (if the `shareX` and `shareY` fields of the previously relayed message is identical to the incoming message, then the message is a duplicate and shall be dropped). 1. If such message exists and its `shareX` and `shareY` components are different from the incoming message, then slashing takes place (if the `shareX` and `shareY` fields of the previously relayed message is identical to the incoming message, then the message is a duplicate and shall be dropped).
2. If none found, then the message gets relayed. 2. If none found, then the message gets relayed.
An overview of slashing procedure is provided in Figure 2.
TODO: may shorten or delete the Spam detection and slashing process TODO: may shorten or delete the Spam detection and slashing process
TODO: may consider [validator functions](https://github.com/libp2p/specs/tree/master/pubsub#topic-validation) or [extended validators](https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md#extended-validators) for the spam detection TODO: may consider [validator functions](https://github.com/libp2p/specs/tree/master/pubsub#topic-validation) or [extended validators](https://github.com/libp2p/specs/blob/master/pubsub/gossipsub/gossipsub-v1.1.md#extended-validators) for the spam detection
<p align="center">
<img src="../../../assets/rln-relay/rln-message-verification.png" />
<br />
Figure 2: Publishing, Routing and Slashing workflow.
</p>
TODO: the function calls in this figure as well as messages are subject to change
# Security Considerations # Security Considerations
TODO: add discussion about the anonymity (e.g., the `StrictNoSign` policy) TODO: add discussion about the anonymity (e.g., the `StrictNoSign` policy)
@ -111,7 +129,7 @@ message WakuMessage {
message ProofBundle { message ProofBundle {
int64 epoch = 1; // indicating the intended epoch of the message int64 epoch = 1; // indicating the intended epoch of the message
// TODO shareX and shareY // TODO shareX and shareY
bytes internalNullifier = 2; bytes nullifier = 2;
bytes root = 3; // TODO may be removed and added as part of zkProof bytes root = 3; // TODO may be removed and added as part of zkProof
// TODO zkProof // TODO zkProof
} }