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

Activate custom gates in JS and add rangeCheck64 gadget #1176

Merged
merged 23 commits into from
Oct 16, 2023

Conversation

mitschabaude
Copy link
Collaborator

@mitschabaude mitschabaude commented Oct 11, 2023

closes #1172

bindings: o1-labs/o1js-bindings#179

This PR

  • adds logic to the Wasm bindings to infer feature flags from a verifier index
    => makes Kimchi verification work for proofs that use custom gates
  • dynamically passes the right feature flags to Pickles.compile based on the gates used in a circuit
    => makes Pickles proofs work with custom gates
  • to test that this works, exposes the rangeCheck0 gate to JS, and wraps it in a 64-bit range check gadget
  • uses that gadget in UInt64, which is very well covered by existing tests

TODOs:

  • understand performance impact on example zkapps and possibly remove custom gate from UInt64 again, or move it behind a customization flag
  • changelog and documentation about the new gate

UPDATE
Following internal discussion, I didn't use the rangeCheck64 gate in UInt64 for now. Thus, there is no more test in this PR that everything works (but CI for a previous commit shows it working)
However, there is now a follow-up PR which exposes the new gate directly (for advanced users), and also adds a unit test: #1181

@mitschabaude mitschabaude changed the title Active custom gates in JS and add rangeCheck64 gadget Activate custom gates in JS and add rangeCheck64 gadget Oct 11, 2023
Base automatically changed from merge-main-develop to develop October 11, 2023 12:32
@mitschabaude mitschabaude changed the base branch from develop to merge-develop-back October 11, 2023 15:53
Copy link
Contributor

@MartinMinkov MartinMinkov 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! 🎉

src/lib/gadgets/range-check.ts Show resolved Hide resolved
lookup: false,
runtimeTables: false,
};
for (let gate of gates) {
Copy link
Contributor

Choose a reason for hiding this comment

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

nit: This is a superficial suggestion, but you could add some type safety here instead of the switch statement

const gateTypeToFlagKey: Record<GateType, keyof FeatureFlags> = {
  RangeCheck0: 'rangeCheck0',
  RangeCheck1: 'rangeCheck1',
  ForeignFieldAdd: 'foreignFieldAdd',
  ForeignFieldMul: 'foreignFieldMul',
  Xor16: 'xor',
  Rot64: 'rot',
  Lookup: 'lookup',
  ...
};
  
for (let gate of gates) {
  const flagKey = gateTypeToFlagKey[gate.type];
  if (flagKey) {
    flags[flagKey] = true;
  }
};

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

fwiw I think the switch statement is perfectly type-safe
image

but your suggestion is definitely less spaghetti-like than the long switch statement

Copy link
Collaborator Author

@mitschabaude mitschabaude Oct 13, 2023

Choose a reason for hiding this comment

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

I went with the object approach. This is the type signature you need to encode that some but not all gate types cause a feature flag to be set (same as the switch statement with the default branch):

const gateToFlag: Partial<Record<GateType, keyof FeatureFlags>> = {
  RangeCheck0: 'rangeCheck0',
  RangeCheck1: 'rangeCheck1',
  // ...

x.value,
[0, FieldVar[0], FieldVar[0], x52, x40, x28, x16],
[0, x14, x12, x10, x8, x6, x4, x2, x0],
// not using compact mode
Copy link
Contributor

Choose a reason for hiding this comment

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

// not using compact mode
why not? 😅

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 is just a different "mode" of the gate which is used in specific circumstances (when combining this with other gates to do a 2x88 + 1x88-bit range check where the 2x88-bit value is what is called "compact")

Base automatically changed from merge-develop-back to main October 16, 2023 15:50
@mitschabaude mitschabaude merged commit 1b37aa4 into main Oct 16, 2023
13 checks passed
@mitschabaude mitschabaude deleted the feature/range-check-64-develop branch October 16, 2023 18: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.

Set feature flags in Pickles and Kimchi depending on custom gates used
3 participants