# Rate-Limit-Nullifier V2
*The idea was proposed by Lev Soukhanov [@levs57](https://twitter.com/levs57)*
## RLN V1
[Current RLN circuit](https://github.com/Rate-Limiting-Nullifier/rln-circuits/blob/master/circuits/rln-base.circom) uses first-degree polynomial for shares generation (and slashing). Therefore, there is a limit - one message per epoch.
There have been attempts to make schemes in which the message limit per epoch is greater than one. For example [N-RLN scheme](https://hackmd.io/zOk-bQ2GSgaJ1t1bI7zrWQ?view). But this approach is very problematic, cause the bigger the limit - the more complicated is the circuit (more R1CS, etc.).
## Update to V2
Instead of using higher degree polynomials we can just add additional input to hash-function (for `a1` coefficient generation) - counter.
So, for the epoch limit `n`, the scheme will be:
* `A(X) = a_0 + a_1 * x`, where
* `a_0` - secret generated by user
* `a_1` - `Hash(a_0, external_nullifier, k)`, where `1 <= `k` <= n`
* `internal_nullifier = Hash(a_1)`
Only thing we need to check is that the `k` parameter is in the range from 1 to `n = epoch limit`. Therefore user won't be able to use `k > n`, and if user uses same `k` twice they'll be slashed.
Thus, the scheme remains as simple as it was while at the same time providing more flexibility.
### Additional info
There are also other cool features that come along with using this scheme:
* Internal nullifier value is different for different messages during the epoch (so it's more anonymous)
* It's more secure and resistant to algebraic attacks (which could arise in N-RLN scheme linked above)
### Different Rate-Limits
By using this scheme we can create circuit, that will allow us to use different rate-limits for different users, for example based on their stake.
We can do that by commiting to not only our secret, but our secret and limit:
1. Registry (map) is stored on a smart-contract, where keys are public keys (`pubkey = Hash(privkey)`) of users and values are some metadata (for example `limit` number or stake amount);
2. Merkle tree, where leaves = `Hash(pubkey, limit)`
For example, the possible limit is 1000 (`n` = 1000), and each message costs 0.001 ETH (so you will have 1000 messages limit if you stake 1 ETH).
So, when you join app you attach the amount of stake you want and also send the `pubkey` and `commitment = Hash(pubkey, limit)`, and zk-proof that the limit (public input for the circuit) you set for yourself is correct.
Signalling will use other circuit, where your `limit` is private input, and the counter `k` is checked that it's in the range from 1 to `limit`.