fixing weak safety bug in template Modulo: adding Num2Bits check #5
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 Modulo template:
The template Modulo (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) as it accepts multiple outputs for a given input.
This template receives two inputs dividend, divisor and computes the outputs remainder and quotient expressing the result of the integer division of this values: that is, dividend = divisor * quotient + remainder with 0 <= remainder < divisor.
The template uses a call to the component LessThan(divisor_bits) to ensure that the second condition (0 <= remainder < divisor) is satisfied, but do not ensure that the conditions of the LessThan(divisor_bits) template are satisfied. The template LessThan(divisor_bits) has the expected behavior (i.e. out = in[0] < in[1]) when in[0] and in[1] are values that can be expressed using divisor_bits bits, which is not guaranteed in this case.
For example, the constraints in Modulo() for the inputs dividend = -8, divisor = 5 are satisfied by the following pairs of outputs:
In order to fix this issue, we add an extra check forcing the signal remainder to be expressed using divisor_bits. We use the template Num2Bits(divisor_bits) to perform this check. The previous solution Out2 is not valid as remainder needs 254-bits to be expressed.