-
Notifications
You must be signed in to change notification settings - Fork 391
Conversation
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.
one high level idea. is it possible to swap the a & b in the SHR and SHL to reuse most part of the constraints? e.g.
SHR: a >> shift = b
SHL: a << shift = b <=> b >> shift = a
Yes. I think it makes sense. Will give a try. Thanks. |
I don't think this is correct. E.g. for |
Updated to merge both opcode |
zkevm-circuits/src/evm_circuit/execution/mul_div_mod_shl_shr.rs
Outdated
Show resolved
Hide resolved
zkevm-circuits/src/evm_circuit/execution/mul_div_mod_shl_shr.rs
Outdated
Show resolved
Hide resolved
"overflow == 0 for opcode DIV, MOD and SHR", | ||
(is_div.clone() + is_mod.clone() + is_shr.clone()) * mul_add_words.overflow(), | ||
); | ||
|
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 you're still missing the power of 2 lookup conditions for SHL and SHR?
You can check that pop2 < 256 by checking that the value fits into the first byte with by constraining that RLC(pop2) == pop2.cells[0] btw.
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.
It seems that there is no need to lookup Pow2 table. Since I calculated divisor = 1 << shf0
(if shf0 < 256) in function assign_exec_step
directly (not sperated to low and high bytes). What do you think?
And I added another contraint to check pop1 == pop1.cells[0]
for opcode SHL and SHR. Thanks.
cb.require_zero(
"pop1 == pop1.cells[0] when divisor != 0 for opcode SHL and SHR",
(is_shl.clone() + is_shr.clone())
* (1.expr() - divisor_is_zero.expr())
* (pop1.expr() - pop1.cells[0].expr()),
);
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.
we definately need to add the lookup constraint here.
My model is that configure
adds the constraints for the circuit and assign_exec_step
generates a witness that satisfies those constraints. If you don't have enough constraints, then there can be multiple witnesses that satisfy them. In this case, without the lookup constraint, replacing line 177 with 5.expr()
or many other expressions could still allow the constraints to all be satisfied.
zkevm-circuits/src/evm_circuit/execution/mul_div_mod_shl_shr.rs
Outdated
Show resolved
Hide resolved
and sperate the word array to `quotient`, `divisor`, `remiander` and `dividend`.
"overflow == 0 for opcode DIV, MOD and SHR", | ||
(is_div.clone() + is_mod.clone() + is_shr.clone()) * mul_add_words.overflow(), | ||
); | ||
|
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.
we definately need to add the lookup constraint here.
My model is that configure
adds the constraints for the circuit and assign_exec_step
generates a witness that satisfies those constraints. If you don't have enough constraints, then there can be multiple witnesses that satisfy them. In this case, without the lookup constraint, replacing line 177 with 5.expr()
or many other expressions could still allow the constraints to all be satisfied.
Hi @z2trillion , according to code review, I sperated And I added two constraints to lookup Could you help review the code again? Thanks a lot. |
pop1: util::Word<F>, | ||
/// For opcode SHL and SHR, it is `shift[0]` if `shift[0]` is less than 128, | ||
/// and 0 otherwise. | ||
shf_lo: Cell<F>, |
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.
Lookups can have up to three values in them:
pub(crate) enum Lookup<F> {
/// Lookup to fixed table, which contains serveral pre-built tables such as
/// range tables or bitwise tables.
Fixed {
/// Tag to specify which table to lookup.
tag: Expression<F>,
/// Values that must satisfy the pre-built relationship.
values: [Expression<F>; 3],
},
...
I think a more direct (and easier to understand) approach would be to have
values = [
input,
if input < 128 {1 << input} else {0},
if input < 128 {0} else {1 << (input -128)}
]
You can then directly lookup up shift_hi and shift_lo without needing to use the divisor_lo_is_zero
and divisor_hi_is_zero
gadgets.
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.
Updated Pow2
table and fixed to lookup (shf0, divisor_lo, divisor_hi)
in this table.
Hi @z2trillion , please have review again when you have time. Thanks.
Thanks for code review. Moved to upstream privacy-scaling-explorations#578. |
Spec: scroll-tech/zkevm-specs#43
Summary
Integrate both opcode
SHL
andSHR
intomul_div_mod
(rename tomul_div_mod_shl_shr
).Consider
SHL
asMUL
(a * (1 << shift) = b
) andSHR
asDIV
(a // (1 << shift) = b
).