-
Notifications
You must be signed in to change notification settings - Fork 843
Soundness Bug: Modulo Gadget #996
Comments
I have a quick failure case but it looks like the test case failed for a different reason diff --git a/zkevm-circuits/src/evm_circuit/util/math_gadget/modulo.rs b/zkevm-circuits/src/evm_circuit/util/math_gadget/modulo.rs
index 2c4979645..800add4bb 100644
--- a/zkevm-circuits/src/evm_circuit/util/math_gadget/modulo.rs
+++ b/zkevm-circuits/src/evm_circuit/util/math_gadget/modulo.rs
@@ -142,6 +142,15 @@ mod tests {
}
}
+ #[test]
+ fn test_soundness_problem() {
+ try_test!(
+ ModGadgetTestContainer<Fr>,
+ vec![Word::from(2).pow(Word::from(255)), Word::from(3), Word::from(0)],
+ false,
+ );
+ }
+
#[test] |
Did quick test and the error with different reason from my side is as below
which is happened on this line https://github.com/privacy-scaling-explorations/zkevm-circuits/blob/main/zkevm-circuits/src/evm_circuit/util/math_gadget/mul_add_words.rs#L128 However, tried to change Back to reported question, hi @kcharbo3 may I confirm, seems checking |
Right now the test is failing because
d_hi > (t2 + (t3 << 64) + c_hi + carry_lo by 1. In terms of a, k, n, r: a_hi > (k*n)_hi + r_hi where k=a/n .I think this is fine since this example should be false anyways? I think in any instance where the inputs result in a true statement, we won't run into this underflow issue. I think saturating_sub could be used here if you want to prevent this underflow (this is what MulAddWords512 uses). The test passes if you do this.
On another note, this test doesn't actually test when the prover can manipulate k right? And yes good catch! k*n + r must be less than 256 bits. |
Yes it's right! thanks for the explanations Although original case error, however yes Tks for catch this issue! I raised a pull request to fix it. |
Great! Since this issue is already public and the fix request has been made, can I add this issue to the zk-bug-tracker repo? Totally understand if not or I should wait until the fix has been committed. https://github.com/0xPARC/zk-bug-tracker |
Hi @kcharbo3, feel free to add the issue to the zk-bug-tracker repo before or after the fix is committed. |
fixed in #999 |
The Modulo gadget assigns
k
toa / n
. However,k
is not actually constrained toa / n
. Any prover can substitute their own values fork
as long as it is<256 bits
.zkevm-circuits/zkevm-circuits/src/evm_circuit/util/math_gadget/modulo.rs
Line 72 in 9400c62
If the prover can submit their own values for
k
(< 256 bits), they can prove an inaccurate modulo operation.Take the following values for example:
n = 3
k = 2^255
r = 0
a = 2^255
The statement
0 = 2^255mod3
is false. But this statement will prove successfully in the circuit. This is because the MulAddWord gadget is done over the 256 bit field. So this is the constraint that is checked (which is true in this case):3 * 2^255 + 0 = 2^255 (mod 2^256)
.But I don't think this should suffice for proving
0 = 2^255mod3
(as 2^255 is not divisible by 3) So there is a whole set of values that will break this modulo operation if the prover is allowed to choose their ownk
value. To prevent this, another constraint needs to be added onk
(ideally so thatk*n < 256 bits
).In slightly more formal terms:
Let
k, n, r, a < 256 bits
.The current constraint
kn + r = a mod2^256
implies there exists some integerj
such thatkn + r = a + j2^256
.So this can be rewritten as
(kn - j2^256) + r = a
. (Note that the MulAddWord gadget allows for products greater than 256 bits)Since we are trying to prove
r=amodn
, then there must exist some integerh
such thathn + r = a
.Therefore if
r=amodn
is true, then we must be able to write(kn - j2^256)
as an integer multiple ofn
. So,n
must dividej * 2^256
. But this requirement is never explicitly constrained in the circuit.So the prover can manipulate
k
andj
to satisfy(kn - j2^256) + r = a
with aj * 2^256
value that is not divisible byn
. So in this case,r=amodn
is false but the circuit has still "proved" it to be true.The text was updated successfully, but these errors were encountered: