fixing weak safety bug in template Random: using Num2Bits_strict instead of Num2Bits #4
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Potential safety bug in Random template:
The template Random (perlin.circom) presents a safety vulnerability that may affect to the behavior of the circuit. The template do not satisfy the weak safety property (https://www.techrxiv.org/articles/preprint/CIRCOM_A_Robust_and_Scalable_Language_for_Building_Complex_Zero-Knowledge_Circuits/19374986/1, https://0xparc.org/blog/ecne) as it accepts multiple outputs for a single input.
This template receives three inputs x, y, z and calls to the component MiMCSponge to generate a random output mimc.outs that then uses to generate a value between [0, 15].
However, the template contains a call to NumBits(254) that is potentially unsafe as for any input value in between [0, 7059779437489773633646340506914701874769131765994106666166191815402473914367] the circuit Num2Bits(254) accepts two outputs for that input.
For example, the circuit Num2Bits(254) accepts for the input in = 3 the possible outputs:
as both of them are binary representations of the value 3 (in the second case it corresponds to the binary representation of the value p + 3 with p being the prime value in which the field is defined).
This way, the Random template accepts both the outputs 3 and 4, which is potentially dangerous.
In order to fix this issue, we substitute the call to Num2Bits(254) by a call to Num2Bits_strict(). This second template adds a call to AliasCheck that ensures that the template only accepts outputs that correspond with the binary representation of a number x such that x <= p-1. This way, in the previous case the second possible solution Out2 is not valid as it represents the number p + 3.