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

Constraints for MULH & MULHSU #536

Closed
wants to merge 28 commits into from
Closed

Constraints for MULH & MULHSU #536

wants to merge 28 commits into from

Conversation

vivekvpandya
Copy link
Contributor

@vivekvpandya vivekvpandya commented Aug 16, 2023

Discussion explaining constraints: https://github.com/orgs/0xmozak/discussions/538

@vivekvpandya vivekvpandya changed the title Constraints for MULH Constraints for MULH & MULHSU Aug 17, 2023
@vivekvpandya
Copy link
Contributor Author

This also contains fixes from https://github.com/0xmozak/mozak-vm/pull/539/files. So first we need to merge https://github.com/0xmozak/mozak-vm/pull/539/files to main.

circuits/src/cpu/mul.rs Outdated Show resolved Hide resolved
@vivekvpandya vivekvpandya requested a review from sai-deng August 18, 2023 08:17
circuits/src/cpu/stark.rs Outdated Show resolved Hide resolved
circuits/src/cpu/mul.rs Outdated Show resolved Hide resolved
circuits/src/cpu/mul.rs Outdated Show resolved Hide resolved
}

// Make sure res_when_prod_negative is computed correctly.
Copy link
Contributor

Choose a reason for hiding this comment

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

In the doc, you mentioned "for case where result is 0 but any one operand has negative value, destination = 0, low_32_bits = 0, high_32_bits = 0 sign of product is negative so it needs 2's complement."
Why do we need sign of product be positive? We only need the correct destination value, right?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yes we need only correct destination value.
when result is zero but product sign is negative then in field (0xFFFF_FFFF - high_limb + 1) becomes 0x1_0000_0000, if we ignore anything above 32 bits it gives correct answer but that is not possible in field.
So I have to handle that as special case.

Copy link
Contributor

@sai-deng sai-deng Aug 21, 2023

Choose a reason for hiding this comment

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

Just wondering if you change the constraints to

    //   if product is zero:
    //     destination == 0 (which is same as high_limb)
    //   else
    //     if product has negative sign:
    //       destination == 2's complement of high_limb
    //     else
    //       destination == high_limb

Will the constraints be simpler?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

it will be still degree 4 constraint. To make it degree 3 I have to create column res_when_not_zero, which is analogous to res_when_negative.
So which one you prefer @sai-deng ?

&[],
&[(6, a as u32), (7, b)],
);
let (res, _overflow) = i64::from(a).overflowing_mul(i64::from(b));
Copy link
Collaborator

Choose a reason for hiding this comment

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

You can just use wrapping_mul in this case?

@@ -23,8 +23,8 @@ use crate::cpu::stark::is_binary;
///
/// TODO: range check these two linear combinations of columns:
/// ```ignore
/// lv.op1_full_range() + lv.is_signed() * CpuState::<P>::shifted(31);
/// lv.op2_full_range() + lv.is_signed() * CpuState::<P>::shifted(31);
/// lv.op1_full_range() + lv.is_op1_signed() * CpuState::<P>::shifted(31);
Copy link
Collaborator

Choose a reason for hiding this comment

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

Just implement the TODO instead of fixing it up?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

just curious why its not implemented on main? Anything is missing for implementation and this PR add that part?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Also I think this comment is wrong or I am not understanding it correctly.
op1_full_range() = op1_value - op1_sign_bit * shifted(32)
so here should be checking op1_value == op1_full_range() + op1_sign_bit() * shifted(32) right?
the comment uses shifted(31) that seems incorrect.

@vivekvpandya
Copy link
Contributor Author

Closing this as #556 is already in main.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants