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

fix(rln): nullifierlog vulnerability #2855

Merged
merged 5 commits into from
Jun 28, 2024
Merged
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
31 changes: 18 additions & 13 deletions waku/waku_rln_relay/rln_relay.nim
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,7 @@ proc updateLog*(
try:
# check if an identical record exists
if rlnPeer.nullifierLog[epoch].hasKeyOrPut(proofMetadata.nullifier, proofMetadata):
# the above condition could be `discarded` but it is kept for clarity, that slashing will
# the above condition could be `discarded` but it is kept for clarity, that slashing will
# be implemented here
# TODO: slashing logic
return ok()
Expand Down Expand Up @@ -279,8 +279,10 @@ proc validateMessageAndUpdateLog*(
if proofMetadataRes.isErr():
return MessageValidationResult.Invalid

# insert the message to the log (never errors)
discard rlnPeer.updateLog(msgProof.epoch, proofMetadataRes.get())
# insert the message to the log (never errors) only if the
# message is valid.
if isValidMessage == MessageValidationResult.Valid:
discard rlnPeer.updateLog(msgProof.epoch, proofMetadataRes.get())

return isValidMessage

Expand Down Expand Up @@ -308,22 +310,25 @@ proc appendRLNProof*(
let proof = rlnPeer.groupManager.generateProof(input, epoch, nonce).valueOr:
return err("could not generate rln-v2 proof: " & $error)


msg.proof = proof.encode().buffer
return ok()

proc clearNullifierLog*(rlnPeer: WakuRlnRelay) =
# clear the first MaxEpochGap epochs of the nullifer log
# if more than MaxEpochGap epochs are in the log
# note: the epochs are ordered ascendingly
if rlnPeer.nullifierLog.len().uint <= rlnPeer.rlnMaxEpochGap:
return

let countToClear = rlnPeer.nullifierLog.len().uint - rlnPeer.rlnMaxEpochGap
trace "clearing epochs from the nullifier log", count = countToClear
let epochsToClear = rlnPeer.nullifierLog.keys().toSeq()[0 ..< countToClear]
for epoch in epochsToClear:
rlnPeer.nullifierLog.del(epoch)
let currentEpoch = fromEpoch(rlnPeer.getCurrentEpoch())

var epochsToRemove: seq[Epoch] = @[]
for epoch in rlnPeer.nullifierLog.keys():
let epochInt = fromEpoch(epoch)

# clean all epochs that are +- rlnMaxEpochGap from the current epoch
if (currentEpoch+rlnPeer.rlnMaxEpochGap) <= epochInt or epochInt <= (currentEpoch-rlnPeer.rlnMaxEpochGap):
epochsToRemove.add(epoch)

for epochRemove in epochsToRemove:
trace "clearing epochs from the nullifier log", currentEpoch = currentEpoch, cleanedEpoch = fromEpoch(epochRemove)
rlnPeer.nullifierLog.del(epochRemove)

proc generateRlnValidator*(
wakuRlnRelay: WakuRLNRelay, spamHandler = none(SpamHandler)
Expand Down
Loading