-
Notifications
You must be signed in to change notification settings - Fork 809
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 error checking and bytecode circuit #403
Fix error checking and bytecode circuit #403
Conversation
ed9d468
to
9b9c7d5
Compare
9b9c7d5
to
a4fe6d9
Compare
Good catch! And it seems there were indeed silent errors on the bytecode circuit tests! Probably the |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The change looks good! It's a nice catch!
Before approving, I would like that the tests that are now failing are fixed.
The NotEnoughRowsAvaliable
err suggests that the k
param passed to the MockProver in the run
fn is lower than what's actually required. My suggestion is to make these values bigger so that they fit the size requirements.
Wondering if anything else wrong there, I'm running the test, with only one byte of code and one million rows
fails with
|
The error definition in Halo2 is quite clear: /// `k` is too small for the given circuit.
NotEnoughRowsAvailable {
/// The current value of `k` being used.
current_k: u32,
}, Is it possible that you're passing more |
I think this fixes the |
Sorry we didn't update earlier here @therealyingtong. |
While reviewing the
|
thanks for reviewing. :)
Yes, you're right!
As I understood well the test code, the idea was to deliver more unrolled code to the circuit that can handle (and this fails with a BTW, I saw your previous comment about witnessing unqueried values, and I was checking if it works in a way do you said. Just for curiosity why do removed this comment? |
I had previously asked why we witnessed I deleted it because I was going to try and figure it out from privacy-scaling-explorations/zkevm-specs#151, but I'm still in the process of doing that. |
I think I see why we're currently catching a panic for the |
It's already being constrained in both the start/continue cases so should be fine I think?
Oh right I forgot about that, I temporarily disabled that test because halo2 gave this internal error only when providing incorrect witness values in the test:
We'll need it on each row for external circuits using the data in lookups. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So just changing q_enable
from Selector
to a Fixed
column made it?
Could you explain why is that specifically? I'm really curious!
@@ -715,6 +716,7 @@ mod tests { | |||
|
|||
/// Tests a circuit with incomplete bytecode | |||
#[test] | |||
#[should_panic = "called `Result::unwrap()` on an `Err` value: NotEnoughRowsAvailable { current_k: 9 }"] |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If it's incomplete how can it panic due to NotEnoughRowsAvailable
??
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
AFAIU incomplete
here means that not all code can be processed, but probally there's another definition that I'm missing.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The goal of the test is to make sure that the circuit cannot contain partial bytecode because the bytecode hash is only verified at the last byte. So it's crucial the circuit contains all bytes. Modifying the test to catch the NotEnoughRowsAvailable
rows error doesn't really achieve this goal because that does not test the actual circuit, just the witness assignment. The better way to update the test would be to allow the witness to be successfully assigned, but let the circuit verification fail because the circuit should reject incomplete bytecodes. I think that was the behaviour before because the witness assignment always returned successful and assigned as many rows as possible (but there were not enough rows to assign the full bytecode).
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@Brechtpd, I see, thanks!
Yes, I can make the circuit failing as you said by not adding rows when assigning witness if they are going to overflow the table, and works,
341 if offset <= last_row_offset {
342 // Set the data for this row
343 self.set_row(
Nonetheless, I'm asking myself if creating witness that makes a circuit failing a good strategy for tests. Is not just better to fail with NotEnoughRowsAvailable
?
Anyway we are going to change how bytecode circuits works, so maybe we do not have to spend more time on this issue :)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Nonetheless, I'm asking myself if creating witness that makes a circuit failing a good strategy for tests. Is not just better to fail with NotEnoughRowsAvailable?
The main goal of the circuits is to reject incorrect data, and so the only way to really test that is to check if the circuit indeed cannot be verified with that data. The fact that halo2 library throws an error assigning the witness is actually not useful from a security pov because that is something a malicious prover can just work around by changing a bit of code when he generates the proof.
Anyway we are going to change how bytecode circuits works, so maybe we do not have to spend more time on this issue :)
Yeah true :), but I think the tests can remain the same because the change is just how the circuit does some of the constraints, and so the tests still need to test the same things.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main goal of the circuits is to reject incorrect data, and so the only way to really test that is to check if the circuit indeed cannot be verified with that data. The fact that halo2 library throws an error assigning the witness is actually not useful from a security pov because that is something a malicious prover can just work around by changing a bit of code when he generates the proof.
Super good information to keep in mind! Thanks!
Yeah true :), but I think the tests can remain the same because the change is just how the circuit does some of the constraints, and so the tests still need to test the same things.
Fixed in f33f782 (I hope!)
The MockProver requires any gate with a selector enabled to have all its referenced cells to be assigned. Fixed columns do not have this extra check. I also find this difference a bit strange (and impossible to achieve in certain scenario's) and made this issue: zcash/halo2#533. |
@miha-stopar I did not manually required your review, just the new automatic system assigned it to you! |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should follow @ed255 's approach mentioned here: #403 (comment)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm approving this PR following the conclusion at #403 (comment) and moving the discussion of negative tests to #400
@CPerezz does this seem OK to you? (as currently your review status is "requested changes")
697df60
to
7af5af6
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM.
Sorry for blocking on the merge of this.
Let's try to not forget the work left or tech-debt generated here by tracking this in #400
With
ok()
errors are turned into anOption
so the compiler do not check the result and also do not warns about unchecked result.It seems that this woke up test errors due to changes in the underlying halo2 in some moment ( see #407 (comment) ), so also applied @Brechtpd workaround.