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

add gadgets to API surface, UInt32, UInt64, implement rot32 #1259

Merged
merged 62 commits into from
Dec 19, 2023

Conversation

Trivo25
Copy link
Member

@Trivo25 Trivo25 commented Nov 21, 2023

  • adds API support for the new bitwise gadgets to UInt32 and UInt64
  • implements divMod32 and addMod32
  • implements rotation32 using divMod32
  • refactors rangeCheckHelper into a gadget
  • implements leftShift32 based on divMod32

closes #958 #962 #1010

…ghtShift, and bitwise AND operations on UInt64 values using Gadgets module

The Gadgets module provides implementations for bitwise XOR, NOT, rotate, leftShift, rightShift, and bitwise AND operations on UInt64 values. These operations are useful for performing bitwise operations on UInt64 values in a circuit.

The following operations have been added:

- `xor(x: UInt64)`: Performs a bitwise XOR operation between the current UInt64 value and the provided UInt64 value `x`. Returns a new UInt64 value representing the result of the XOR operation.

- `not(checked = true)`: Performs a bitwise NOT operation on the current UInt64 value. If the `checked` parameter is set to `true`, the operation is implemented using the `Gadgets.xor` gadget with a second argument as an all one bitmask of the same length. If the `checked` parameter is set to `false`, the operation is implemented as a subtraction of the input from the all one bitmask. Returns a new UInt64 value representing the result of the NOT operation.

- `rotate(direction: 'left' | 'right' = 'left')`: Performs a bitwise rotation operation on the current UInt64 value. The `direction` parameter determines the direction of the rotation, with `'left'` indicating a left rotation and `'right'` indicating a right rotation. Returns a new UInt64 value representing the result of the rotation operation.

- `leftShift()`: Performs a bitwise left shift operation on the current UInt64 value. Returns a new UInt64 value representing the result of the left shift operation.

- `rightShift()`: Performs a bitwise right shift operation on the current UInt64 value. Returns a new UInt64 value representing the result of the right shift operation.

- `and(x: UInt64)`: Performs a bitwise AND operation between the current UInt64 value and the provided UInt64 value `x`. Returns a new UInt64 value representing the result of the AND operation.

These operations provide additional functionality for working with UInt64 values in circuits.
…to 'bits' to improve clarity

feat(int.ts): add documentation for the rotate, leftShift, rightShift, and and methods to improve code understanding and usage
… 'from' method instead of direct instantiation to improve clarity and consistency

feat(int.ts): add support for bitwise XOR operation on UInt32 elements to perform XOR operation between two UInt32 elements
feat(int.ts): add support for bitwise NOT operation on UInt32 elements to perform bitwise negation of a UInt32 element
feat(int.ts): add support for rotation operation on UInt32 elements to perform left and right rotation of bits in a UInt32 element
feat(int.ts): add support for left shift operation on UInt32 elements to perform left shift of bits in a UInt32 element
feat(int.ts): add support for right shift operation on UInt32 elements to perform right shift of bits in a UInt32 element
feat(int.ts): add support for bitwise AND operation on UInt32 elements to perform AND operation between two UInt32 elements
@Trivo25 Trivo25 marked this pull request as draft November 21, 2023 09:03
src/lib/gadgets/arithmetic.ts Show resolved Hide resolved
src/lib/gadgets/arithmetic.ts Outdated Show resolved Hide resolved
src/lib/gadgets/bitwise.ts Show resolved Hide resolved
src/lib/gadgets/range-check.ts Outdated Show resolved Hide resolved
Comment on lines +887 to 891
let xMinusYFits = Gadgets.isInRangeN(UInt32.NUM_BITS, xMinusY);
let yMinusXFits = Gadgets.isInRangeN(UInt32.NUM_BITS, yMinusX);
xMinusYFits.or(yMinusXFits).assertEquals(true);
// x <= y if y - x fits in 64 bits
return yMinusXFits;
Copy link
Collaborator

@mitschabaude mitschabaude Nov 29, 2023

Choose a reason for hiding this comment

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

this code proves that yMinusXFits is the boolean that indicates whether yMinusX in [0, 2^64).

note that it's not just returning Gadgets.isInRangeN(UInt32.NUM_BITS, yMinusX), which it could if the gadget would do what it promises.

the code here, by doing xMinusYFits.or(yMinusXFits).assertEquals(true), anchors the case that yMinusXFits = false to a specific other case (namely, xMinusYFits = true) in which we can definitely know that yMinusX can't be in range.

Comment on lines +109 to +112
* Checks whether the input value is in the range [0, 2^n). `n` must be a multiple of 16.
*
* This function proves that the provided field element can be represented with `n` bits.
* If the field element exceeds `n` bits, `Bool(false)` is returned and `Bool(true)` otherwise.
Copy link
Collaborator

@mitschabaude mitschabaude Nov 29, 2023

Choose a reason for hiding this comment

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

this is misleading, because it only proves that the result is in range if the return value of isInRangeN() is true. It doesn't prove that the result is not in range if the return value is false.

See my comment on where this is used: #1259 (comment)

So maybe better to rephrase the doccomment, or frame it as a helper function for now. I can follow up with some code that actually proves the full thing, which I think would also make the UInt64 comparison cheaper (currently the comparison calls rangeCheckHelper twice, but it can be done with one call)

Copy link
Collaborator

@mitschabaude mitschabaude left a comment

Choose a reason for hiding this comment

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

Left shift and right shift look good to me!

My only concern now is the misleading documentation of the isInRange() gadget that I requested :D But I think it can be just fixed in a follow-up where we make it do what it says, so approving!

src/lib/int.ts Outdated Show resolved Hide resolved
@mitschabaude
Copy link
Collaborator

Created a follow-up issue that doesn't need to be addressed here: #1286

@mitschabaude mitschabaude merged commit d68441b into main Dec 19, 2023
11 checks passed
@mitschabaude mitschabaude deleted the feature/gadgets-uint branch December 19, 2023 10:27
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.

Expose XOR
3 participants