Skip to content
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

Implement LT & GT opcode #66

Merged
merged 14 commits into from
Sep 16, 2021
Merged

Implement LT & GT opcode #66

merged 14 commits into from
Sep 16, 2021

Conversation

scroll-dev
Copy link
Collaborator

@scroll-dev scroll-dev commented Sep 7, 2021

The design of LT & GT can refer to this doc.

This PR is ready for review. @han0110 @ChihChengLiang @miha-stopar

@scroll-dev scroll-dev changed the title [WIP] Implement LT & GT opcode Implement LT & GT opcode Sep 9, 2021
Copy link
Collaborator

@miha-stopar miha-stopar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nice work! I only have one consideration - we would need to have carry * (1 - carry) constraint too, right?

@gaswhat
Copy link
Contributor

gaswhat commented Sep 14, 2021

@miha-stopar Thanks. I think it is not necessary to check if carry belongs to [0, 1]. Since we already checked a bytes, b bytes, and c bytes are within [0, 255] range, the arithematic constraint with carry (e.g., line 157 in comparator.rs) should be enough to imply that carry can only be 0 or 1. Correct me if I miss something.

@miha-stopar
Copy link
Collaborator

@gaswhat My consideration is that one could set carry so big that rhs wraps around the field modulus so that rhs = lhs + field modulus, which would make the check below to pass. Wouldn't be that possible?

rhs = rhs + carry.expr() * exponent;
lt_constraints.push(lhs - rhs);

Copy link
Collaborator

@ChihChengLiang ChihChengLiang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Great work. I added some documentation suggestions and nitpicks.

zkevm-circuits/src/evm_circuit/op_execution/comparator.rs Outdated Show resolved Hide resolved
Comment on lines 162 to 164
// - a < b, a + c = b, result = 1, is_zero(sumc) = 0
// - a = b, a + c = b, result = 0, is_zero(sumc) = 1
// - a > b, a + c = b + 2^256, result = 0, is_zero(sumc) = 0
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Nitpick: Using minus sign for bullet points could be confusing sometimes.

Suggested change
// - a < b, a + c = b, result = 1, is_zero(sumc) = 0
// - a = b, a + c = b, result = 0, is_zero(sumc) = 1
// - a > b, a + c = b + 2^256, result = 0, is_zero(sumc) = 0
// a < b, a + c = b, result = 1, is_zero(sumc) = 0
// a = b, a + c = b, result = 0, is_zero(sumc) = 1
// a > b, a + c = b + 2^256, result = 0, is_zero(sumc) = 0

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated.

zkevm-circuits/src/evm_circuit/op_execution/comparator.rs Outdated Show resolved Hide resolved
Copy link
Collaborator

@ChihChengLiang ChihChengLiang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Agree with @miha-stopar that we should constrain the carry.
It is hard to find a falsifying example, but we couldn't see a way to justify that carry is binary.
At least for this particular check, it's easy to pass carry=(256^16)^(-1) that still satisfies the equation.

// a[15..0] + c[15..0] = carry * 256^16 + b[15..0] 

@miha-stopar
Copy link
Collaborator

Regarding the carry - I think it might be possible to set a > b and result = 1 (result 1 means a < b) following the next steps:

  • set a[i] > b[i] for 15 < i < 32 (makes a > b)
  • set c[0] = 1 (to avoid sum_c != 0 constraint to fail) and c[i] = 0 for i > 0
  • set carry = b[16] + b[17]*256 + ... b[31]*256^15 - a[16] - a[17]*256 - ... - a[31]*256^15 - 1 (this last 1 is for c[0])
  • in the previous steps we ensured that the second lhs - rhs constraint holds
  • if we chose carry in the third step to be carry * 256^16 < 256^16 (after wrapping over the field modulus), we can choose a[i], b[i], c[i] for i < 16 such that lhs = rhs + carry * 256^16 (we can just set b[i] and c[i] to 0 and set a[i] to be: a[0] + a[1]*256 + ... a[15]*256^15 = carry * 256^16 mod field_modulus)

It's difficult to find carry such that: carry * 256^16 < 256^16, but it might be possible and for this reason I think we should add a constraint for a carry to be 0 or 1.

@gaswhat
Copy link
Contributor

gaswhat commented Sep 16, 2021

@ChihChengLiang @miha-stopar Thanks for the thoughts on the carry check. I agree with that we should add a constraint for carry. And I've added it the new commits. Please take a look again. Thank you for your reviews.

Copy link
Collaborator

@ChihChengLiang ChihChengLiang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank @gaswhat for the update. The commented issues are all addressed. Waiting for a final look from @miha-stopar.

Copy link
Collaborator

@miha-stopar miha-stopar left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks great to me!

@ChihChengLiang ChihChengLiang added the T-opcode Type: opcode-related and focused PR/Issue label Oct 8, 2021
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
T-opcode Type: opcode-related and focused PR/Issue
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

5 participants