fix(rln): nullifierlog vulnerability (#2855)

This commit is contained in:
Alvaro Revuelta 2024-06-28 09:25:10 +02:00 committed by GitHub
parent 7b97c8003c
commit dad054d6b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
1 changed files with 17 additions and 12 deletions

View File

@ -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()
@ -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
@ -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 currentEpoch = fromEpoch(rlnPeer.getCurrentEpoch())
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)
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)