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

LessThan circuits and padding #14

Merged
merged 26 commits into from
Nov 15, 2024

Conversation

Antonio95
Copy link
Contributor

This PR adds two example circuits to verify a < b, where a is a private witness held by the prover and b is a public constant fixed at set-up. The two circuits rely on a fixed bit length that a is supposed to fit in (when regarded as an unsigned integer, even though in reality it lies in some finite field).

  • The circuit LessThanCircuitSafe performs the aforementioned bit length verification on a.
  • The circuit LessThanCircuitUnsafe does not. This leads to constraint savings when the circuit is used as a component in a larger circuit which already ensures the bit length meets the required bound.

In the course of writing the examples, we encountered the issue that the existing Spartan machinery did not pad the matrices to power-of-two row and column lengths, as necessitated by the proof system. This caused compilation errors in our examples. Since it seemed like a good idea for this need for padding to be abstracted away from the user, we have implemented padding in the Spartan internals - that is the other significant contribution in this PR. Note that a R1CSShape method .pad() already existed here, but after some experimentation we convinced ourselves that it could not be used to pad the circuit in the cases where it was necessary.

Other minor changes:

  • The aforementioned circuits are accompanied by meaningful tests (in the example code) that try edge cases and also showcase the different execution outcomes of the safe and unsafe variants for some inputs.
  • We have removed the <F> generic on the existing CubicCircuit example, which in turn allowed us to remove the PhantomData therein and didn't require any further code modifications.
  • A section on how to run Rust examples (which the new circuits are) has been added to the README.

Cesar Descalzo Blanco and others added 15 commits March 14, 2024 14:31
Fix tabulation

Add missing import
Fix random `Fp` slice creation

Fix formatting
Remove unnecessary `PhantomData`
Co-authored-by: Antonio Mejías Gil <[email protected]>

Progress until 08/03
Co-authored-by: Antonio Mejías Gil <[email protected]>

constructing range check, wip

working on padding

println nightmare, issue apparently fixed

Remove redundant padding. Fix import.

code cleanup

further cleanup

found better way to fix padding

the 'better way' to fix padding actually broke other tests - reverted

This reverts commit d4727ba.

moved example to examples folder, refactored, tested many cases
@Antonio95
Copy link
Contributor Author

@microsoft-github-policy-service agree company="Hungry Cats Studio"

@Antonio95 Antonio95 force-pushed the antonio-cesar/less-than branch from 377bb0e to b38a771 Compare March 19, 2024 12:10
Cesar Descalzo Blanco and others added 7 commits March 19, 2024 13:49
Remove unnecessary `PhantomData`
Co-authored-by: Antonio Mejías Gil <[email protected]>

Progress until 08/03
Co-authored-by: Antonio Mejías Gil <[email protected]>

constructing range check, wip

working on padding

println nightmare, issue apparently fixed

Remove redundant padding. Fix import.

code cleanup

further cleanup

found better way to fix padding

the 'better way' to fix padding actually broke other tests - reverted

This reverts commit d4727ba.

moved example to examples folder, refactored, tested many cases
@Antonio95 Antonio95 force-pushed the antonio-cesar/less-than branch from b38a771 to 900e34c Compare March 19, 2024 12:50
@Antonio95
Copy link
Contributor Author

@srinathsetty Have you had a chance to look at this? No rush. Happy to discuss anything.

@srinathsetty
Copy link
Contributor

Hi @Antonio95 this looks great! thanks!

We can merge this once we fix conflicts with main. Could you please rebase?

@Antonio95
Copy link
Contributor Author

Hi @srinathsetty , thanks a lot for taking a look! I have now merged (instead of rebasing, I hope that's okay - let me know otherwise).

It seems that unuseds are no longer allowed and this results in some compilation errors coming from the bellpepper crate inside Spartan2. Moving unused from deny to allow fixes this and makes all tests and the one example pass. I hope you have a better grasp of what's going on :)

@srinathsetty
Copy link
Contributor

Hi @Antonio95! thanks! Yes, indeed. I think we can remove unused: fn pow2(self) -> usize;

For bellpepper methods, it seems like we need those methods and the parameters. In Nova codebase (where this code originated originally and intended to be expanded to hash-based commitment schemes here), we used allow with usused.

@Antonio95
Copy link
Contributor Author

That seems like a good way to go about things, @srinathsetty . Let me know if you want me to remove the pow2 myself and/or do anything else.

@srinathsetty
Copy link
Contributor

That seems like a good way to go about things, @srinathsetty . Let me know if you want me to remove the pow2 myself and/or do anything else.

Yes, let's remove unused methods.

@Antonio95
Copy link
Contributor Author

Hey @srinathsetty! I have addressed the problematic unused:

  • The method pow2 has been removed.
  • In addition to that, the contents of two of the variants of NamedObject were never read, which resulted in an error due to the same deny(unused). I'm referring to A and B in:
enum NamedObject {
  Constraint(A),
  Var(B),
  Namespace,
}

These errors also occur in the main branch, which does not compile right now due to them. My approach has been to remove the two fields, following your suggestion from the last comment (which referred to methods and not structures/fields, though). Have a look at the changes in the last commit and see if that looks okay. The two removed fields were actually being set at one point in the code, but deny(unused) requires fields to be read.

Another possibility that I see is to #![allow(dead_code)] (maintaining the deny(unused)). Note that deny(unused) implies deny(dead_code) unless the latter is explicitly allowed.

@srinathsetty
Copy link
Contributor

This looks great, thank you!

@Antonio95
Copy link
Contributor Author

Just fixed the clippy warning which made the last build fail

@srinathsetty srinathsetty merged commit a6d6041 into microsoft:main Nov 15, 2024
2 checks passed
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.

4 participants