37549c84b6
* adds RateLimitProof protobuf message * updates fields case * more clarification * minor * fixes missing Relay in RLN-Relay * addresses comments * moves refs above the copyright notice |
||
---|---|---|
.. | ||
README.md |
README.md
slug | title | name | status | tags | editor |
---|---|---|---|---|---|
17 | 17/WAKU-RLN-RELAY | Waku v2 RLN Relay | raw | waku-core | Sanaz Taheri <sanaz@status.im> |
The current specification embodies the details of the spam-protected version of relay
protocol empowered by Rate Limiting Nullifiers (RLN).
The security objective is to control the number of PubSub messages that each peer can publish per epoch where epoch is a system design parameter, regardless of the published topic.
Protocol identifier*: /vac/waku/waku-rln-relay/2.0.0-alpha1
Motivation
In open p2p messaging networks, one big problem is spam-resistance. Existing solutions, such as Whisper’s proof of work, are insufficient, especially for heterogeneous nodes. Other reputation-based approaches might not be desirable, due to issues around arbitrary exclusion and privacy.
We augment the relay
protocol with a novel, light, and effective spam prevention mechanism which also suits the resource-constrained nodes.
Flow
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. 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.
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 proof
.
At a high level, the proof
is a zero-knowledge proof signifying that the publishing peer is a registered member, and she has not exceeded the messaging rate at the given epoch
.
The proof
is embedded inside the data
field of the PubSub message, which, in the 11/WAKU2-RELAY protocol, corresponds to the 14/WAKU2-MESSAGE.
The proof generation relies on the knowledge of two pieces of private information i.e., sk
and authPath
.
authPath
is the information by which one can prove its membership in the group.
To construct authPath
, peers need to locally store a Merkle tree out of the group members public keys.
Peers need to keep the tree updated with the recent state of the group.
Further inputs to the proof generation which are public are tree's root
, epoch
and payload||contentTopic
where payload
and contentTopic
come from the WakuMessage
.
The tree root
can be obtained from the locally maintained Merkle tree.
The proof generation results in the following data items which are encoded inside the proof
:
share_x
share_y
nullifier
zkSNARKs
The preceding values as well as the tree root
(based on which the proof is generated) are encoded inside the proof
as |zkSNARKs<256>|root<32>|epoch<32>|share_x<32>|share_y<32>|nullifier<32>|
.
The numbers enclosed in angle brackets indicate the bit length of the corresponding data item.
The tuple of (nullifier
, share_x
, share_y
) can be seen as partial disclosure of peer's sk
for the intended epoch
.
Given two such tuples with identical nullifier
but distinct share_x
, share_y
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 group and attempts the proof using her updated authPath
.
Routing
Upon the receipt of a PubSub message, the routing peer needs to extract and parse the proof
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 proof
is valid and the message is not spam.
If both checks are passed successfully, then the message is relayed.
If proof
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
In order to enable local spam detection and slashing, routing peers MUST record the nullifier
, share_x
, and share_y
of any incoming message conditioned that it is not spam and has valid proof.
To do so, the peer should follow the following steps.
- The routing peer first verifies the
zkSNARKs
and drops the message if not verified. - Otherwise, it checks whether a message with an identical
nullifier
has already been relayed.- If such message exists and its
share_x
andshare_y
components are different from the incoming message, then slashing takes place (if theshare_x
andshare_y
fields of the previously relayed message is identical to the incoming message, then the message is a duplicate and shall be dropped). - If none found, then the message gets relayed.
- If such message exists and its
An overview of slashing procedure is provided in Figure 2.
Security Considerations
Payloads
Payloads are protobuf messages implemented using protocol buffers v3.
Nodes MAY extend the 14/WAKU2-MESSAGE with a proof
field to indicate that their message is not a spam.
syntax = "proto3";
message RateLimitProof {
bytes proof = 1;
bytes merkle_root = 2;
bytes epoch = 3;
bytes share_x = 4;
bytes share_y = 5;
bytes nullifier = 6;
}
message WakuMessage {
bytes payload = 1;
string contentTopic = 2;
uint32 version = 3;
double timestamp = 4;
+ RateLimitProof rate_limit_proof = 21;
}
WakuMessage
rate_limit_proof
holds the information required to prove that the message owner has not exceeded the message rate limit.
RateLimitProof
The proof
field is an array of 256 bytes and carries the zkSNARK proof as explained in the Publishing process.
The proof asserts that:
- The message publisher is the current member of the group i.e., her/his identity commitment key is part of the membership group Merkle tree with the root
merkleRoot
. share_x
andshare_y
are correctly computed.- The
nullifier
is constructed correctly.
Other fields of the RateLimitProof
message are the public inputs to the rln circuit and used for the generation of the proof
.
The merkleRoot
is an array of 32 bytes which holds the root of membership group Merkle tree at the time of publishing the message.
The epoch
is an array of 32 bytes that represents the epoch in which the message is published.
share_x
and share_y
are shares of the user's identity key.
These shares are created using Shamir secret sharing scheme.
share_x
is an array of 32 bytes and contains the hash of the WakuMessage
's payload
concatenated with its contentTopic
.
share_y
is also an array of 32 bytes which is calculated using Shamir secret sharing scheme.
The nullifier
is an internal nullifier which allows specifying whether two messages are published by the same publisher during the same epoch
.
It is an array of 32 bytes.
References
- RLN documentation
- Public inputs to the rln circuit
- Shamir secret sharing scheme used in RLN
- RLN internal nullifier
Copyright
Copyright and related rights waived via CC0.