5.2 KiB
title, name, status, category, tags, editor, contributors
| title | name | status | category | tags | editor | contributors |
|---|---|---|---|---|---|---|
| MULTI-MESSAGE_ID-BURN RLN | Multi-message_id burn feature RLN | raw | Standards Track | Ugur Sen [ugur@status.im](mailto:ugur@status.im) |
Abstract
This document specifies multi-message_id burn RLN which the users
can use their multiple message rights at once unlike previous versions of RLN
that require a separate execution per message_id.
Motivation
RLN is a decentralized rate-limiting mechanism designed for anonymous networks.
In RLNv2, the latest version of the protocol, users can apply arbitrary rate limits
by defining a specific limit over the message_id.
However, this version does not support the simultaneous exercise
of multiple messaging rights under a single message_id.
In other words, if a user needs to consume multiple message_id units,
they must compute separate proofs for each one.
This lack of flexibility creates an imbalance: users sending signals
of significantly different sizes still consume only one message_id per proof.
While computing multiple proofs is a trivial workaround,
it is neither computationally efficient nor manageable for high-throughput applications.
Multiple burning refers to the mechanism where a fixed number of message_id units are processed
within the circuit to generate multiple corresponding nullifiers inside a single cryptographic proof.
This multiple burning feature may unlock the usage of RLN for big signals
such as large messages or complex transactions, by validating their resource consumption in a single proof.
This document specifies the mechanism that allows users to burn multiple message_id units
at once by slightly modifying the existing RLNv2 circuit.
Format Specification
The key words “MUST”, “MUST NOT”, “REQUIRED”, “SHALL”, “SHALL NOT”, “SHOULD”, “SHOULD NOT”, “RECOMMENDED”, “MAY”, and “OPTIONAL” in this document are to be interpreted as described in 2119.
Recap of RLNv2
Since the multi-message_id RLN is achieved by modifying the existing RLNv2 protocol, it is helpful to first recap RLNv2. Note that this modification only affects the signaling section; the remaining sections—registration, verification, and slashing—remain identical to RLNv2.
RLNv2 Registration
RLN-Diff introduces per-user rate limits. Therefore, id_commitment must depend on
user_message_limit, where
0 ≤ user_message_limit ≤ message_limit.
The user submits the same identity_secret_hash as in
32/RLN-V1, i.e.
poseidonHash(identity_secret), together with user_message_limit to a server or
smart contract.
The verifier computes
rate_commitment = poseidonHash(identity_secret_hash, user_message_limit),
which is inserted as a leaf in the membership Merkle tree.
RLNv2 Signalling
For proof generation, the user need to submit the following fields to the circuit:
{
identity_secret: identity_secret_hash,
path_elements: Merkle_proof.path_elements,
identity_path_index: Merkle_proof.indices,
x: signal_hash,
message_id: message_id,
external_nullifier: external_nullifier,
user_message_limit: message_limit
}
Calculating output
The output [y, internal_nullifier] is calculated in the following way:
a_0 = identity_secret_hash;
a_1 = poseidonHash([a0, external_nullifier, message_id]);
y = a_0 + x * a_1;
internal_nullifier = poseidonHash([a_1]);
RLNv2 Verification/slashing
Verification and slashing in both subprotocols remain the same as in 32/RLN-V1.
The only difference that may arise is the message_limit check in RLN-Same,
since it is now a public input of the Circuit.
Multi-message_id Burn RLN (Multi-burn RLN)
The multi-burn protocol follows previous versions by comprising registration, signaling, and verification/slashing sections.
Since the registration and verification/slashing mechanisms remain unchanged, this section focuses exclusively on the modifications to the signaling process.
Multi-burn RLN Signalling
The multi-burn RLN signalling section consists of the proving of the circuit as follows:
Circuit parameters
Public Inputs
xexternal_nullifieri
Private Inputs
identity_secret_hashpath_elementsidentity_path_indexmessage_id []user_message_limit
Outputs
y []rootinternal_nullifiers []
The output (root, y [], internal_nullifiers []) is calculated in the following way:
a_0 = identity_secret_hash;
a_1i = poseidonHash([a0, external_nullifier, message_id [i]]);
y_i = a_0 + x * a_1i;
internal_nullifiers_i = poseidonHash([a_1i]);
where 0 ≤ i ≤ max_out, max_out is a new parameter that is fixed for a application.
max_out is arranged the requirements of the application.
To define this fixed number makes the circuit is flexiable with a single circuit that is maintable.
Since the user is free to burn arbitrary number of message_id at once up to max_out.
Note that within a given epoch, the external_nullifier MUST be identical for all messages,
as it is computed deterministically from the epoch value and the rln_identifier as follows:
external_nullifier = poseidonHash([epoch, rln_identifier]);