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

Fixes for less-than instructions: LT32Chip STARK constraints and handling instructions with second operand immediate #166

Merged
merged 12 commits into from
May 6, 2024

Conversation

tess-eract
Copy link
Collaborator

@tess-eract tess-eract commented May 1, 2024

The LT32 instructions support a mode ilt a b c in which operand b is an immediate value and operand c is a memory address offset from fp. All other instructions which support an immediate mode put the immediate value in operand c, and the CPUChip STARK constraints were enforcing this assumption for all bus instructions.

This fixes Issue #131. A minimal example of the bug is the following .val assembly:

imm32 -4, 0, 0, 0, 3
ilt -8, 3, -4
stop

Separately, the STARK constraints for the LT32Chip were incorrect, e.g. in picking out the most significant byte in which the two arguments differ. This PR fixes them and adds comprehensive test coverage for the LT32 and LTE32 instructions.

basic/tests/test_prover.rs Outdated Show resolved Hide resolved
alu_u32/src/lt/stark.rs Outdated Show resolved Hide resolved
// output should be 1 if is_lte & input_1 == input_2
let all_flag_sum = flag_sum + local.byte_flag[3];
builder
.when(local.is_lte)
Copy link
Collaborator

Choose a reason for hiding this comment

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

Check multiplicity in case of dummy row

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I think this might not be necessary: each of the constraints asserted here passes when the row is all zeros. (each of them either only applies when some flag is nonzero or asserts that the values of two columns are equal). The test_left_imm_ops test in basic/tests/test_prover.rs sends 10 operations to the LT32Chip, so this test includes 6 dummy rows.

builder.when(local.byte_flag[i]).assert_eq(
AB::Expr::from_canonical_u32(256) + local.input_1[i] - local.input_2[i],
bit_comp.clone(),
);

// ensure that when the n-th byte flag is set, the n-th bytes are actually different
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

This constraint fixes a soundness gap: otherwise, a malicious prover could e.g. set input_1 = [0, 0, 1, 0], input_2 = [0, 0, 1, 1], and set the byte_flag's to [0, 0, 1, 0]. Then the other constraints would have the result depend on the comparison of the 3rd byte (which is equal), when in fact the 4th byte determines the correct value of the comparison.

@tess-eract tess-eract merged commit 611dd97 into main May 6, 2024
2 checks passed
@tess-eract tess-eract deleted the dorebell-issue-131 branch May 6, 2024 19:43
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.

2 participants