Skip to content

fix: uint64_ct tests in stdlib#15582

Merged
suyash67 merged 8 commits into
merge-train/barretenbergfrom
sb/uint64-fix
Jul 24, 2025
Merged

fix: uint64_ct tests in stdlib#15582
suyash67 merged 8 commits into
merge-train/barretenbergfrom
sb/uint64-fix

Conversation

@suyash67

@suyash67 suyash67 commented Jul 8, 2025

Copy link
Copy Markdown
Contributor

The stdlib::uint module was only being tested for uint32_ct. This PR makes the tests also run for uint8_ct, uint16_ct, uint64_ct.

The tests were failing for uint64_ct because the XOR and AND lookup tables only supported 32-bit inputs. If we attempted to input more than 32-bits, it naturally led to the error message1:

'C++ exception with description "Last key slice greater than 4" thrown in the test body."'

We slice the 64-bit number in 6-bit slices, starting from the least significant slice:

image

such that the most-significant slice is 4 bits. Since we allowed only 32-bit XOR and AND lookup tables, it read the first 5 slices $(a_0, \dots, a_4)$, i.e., 30 bits, and when it needs to read $a_5$ slice, obviously the remainder $r = (a \gg 30)$ is greater than the allowed value of the last slice (i.e., $r > 4$).

Solution: simply added a 64-bit multi-table for XOR and AND operation of two 64-bit numbers. Note that we still use the 6-bit basic table repeated 10-times and a new 4-bit table for the last slice. Hence, one 64-bit XOR and AND operation would cost 11 lookup gates.

resolves AztecProtocol/barretenberg#1229

Footnotes

  1. Side note: the comment in the code noted the error message as C++ exception with description "Last key slice greater than 64" thrown in the test body because it was referring to an error before the bug in uint32 table was fixed.

@suyash67 suyash67 marked this pull request as ready for review July 8, 2025 12:42
@AztecBot AztecBot force-pushed the merge-train/barretenberg branch from 42b65c1 to 8369b3f Compare July 8, 2025 14:03
@fcarreiro fcarreiro removed their request for review July 8, 2025 14:15
@ludamad ludamad force-pushed the merge-train/barretenberg branch from 2abe998 to 3330e1c Compare July 8, 2025 14:33
Base automatically changed from merge-train/barretenberg to next July 9, 2025 20:59
@suyash67 suyash67 changed the base branch from next to merge-train/barretenberg July 10, 2025 12:50
MultiTableId::UINT32_XOR, field_t<Builder>(*this), field_t<Builder>(other), true);
if constexpr (std::is_same_v<Native, uint64_t>) {
// use the 64-bit XOR lookup
lookup = plookup_read<Builder>::get_lookup_accumulators(

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I'd add a static assert here or in class definition to ensure that 32-bit and 64-bit uints are the only available options

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Well for uint8_ct, uin16_ct, uint32_ct the 32-bit lookup works fine. So previously everything for these three types worked. But uint64_ct operations obviously failed with 32-bit lookup tables. Adding this explanation with examples for clarity.

Base automatically changed from merge-train/barretenberg to next July 14, 2025 14:40
@suyash67 suyash67 changed the base branch from next to merge-train/barretenberg July 14, 2025 19:19
Base automatically changed from merge-train/barretenberg to next July 15, 2025 05:41
@suyash67 suyash67 changed the base branch from next to merge-train/barretenberg July 15, 2025 12:16
@suyash67 suyash67 requested a review from Rumata888 July 15, 2025 14:49
Base automatically changed from merge-train/barretenberg to next July 16, 2025 16:20
@suyash67 suyash67 changed the base branch from next to merge-train/barretenberg July 22, 2025 13:10
Base automatically changed from merge-train/barretenberg to next July 22, 2025 23:47
@suyash67 suyash67 changed the base branch from next to merge-train/barretenberg July 23, 2025 13:29
Base automatically changed from merge-train/barretenberg to next July 24, 2025 04:15

@Rumata888 Rumata888 left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No security problems, but we might be wasting gates

* @details Given a uint_ct a and a constant const_b, this allows to create a
* uint_ct b having a desired relation to a (either >. = or <).
*/
static uint_native impose_comparison(uint_native const_a,

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Maybe this function need a slightly better explanation, since you touched it. It's not clear why we have pairs of values

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

have a rework/cleanup of tests in next PR.

// so when looking them up in the lookup tables, we need to ensure that the values are range-constrained
// to the appropriate bit-size. This is done by using the `field_t<Builder>` operator, which normalizes
// (i.e., creates range constraint on the accumulators) before looking them up in the tables.
const field_t<Builder> key_left = field_t<Builder>(*this);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

I looked at the normalize function and all it does is perform the range constraint (I thought that it might be removing top bits). If that is the case, won't the multitable automatically constrain the value? If that's the case, we are wasting gates here

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

Good point, I think you are right. We don't need to range-constrain as the lookup constraint should fail if we pass a value greater than the permissible multi-table input range (verified this for confirming my own understanding). Corrected the comment, and avoided the normalize() call in converting to field_t.

@suyash67 suyash67 changed the base branch from next to merge-train/barretenberg July 24, 2025 21:19
@suyash67 suyash67 merged commit 8640c46 into merge-train/barretenberg Jul 24, 2025
4 checks passed
@suyash67 suyash67 deleted the sb/uint64-fix branch July 24, 2025 21:40
github-merge-queue Bot pushed a commit that referenced this pull request Jul 25, 2025
See
[merge-train-readme.md](https://github.com/AztecProtocol/aztec-packages/blob/next/.github/workflows/merge-train-readme.md).

BEGIN_COMMIT_OVERRIDE
feat(bbapi): CIVC end to end (#15777)
fix: `uint64_ct` tests in stdlib (#15582)
END_COMMIT_OVERRIDE

---------

Co-authored-by: AztecBot <tech@aztecprotocol.com>
Co-authored-by: ludamad <adam.domurad@gmail.com>
Co-authored-by: Claude <noreply@anthropic.com>
Co-authored-by: Suyash Bagad <suyash@aztecprotocol.com>
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