-
Couldn't load subscription status.
- Fork 253
Rework ConstraintSystem API to improve ergonomics
#186
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
Conversation
|
I love the direction, it's going to be great not having to namespace - and potentially using, e.g. AddAssign and MulAssign, traits! Debuggability is an issue - I've been using that heavily when things fail. Maybe each gadget can define a namespace format as part of its type? |
|
If gadgets interact, which sounds likely with ops traits, then you might want |
One approach to solve this could be to have an environment variable (maybe |
Hmm good point. Is comparing via |
|
Yeah, that seems nice. Another thing I commonly use is extracting a
variable to check for expected value, which I think this wouldn't solve,
right?
…On Sun, Apr 12, 2020, 23:56 Pratyush Mishra ***@***.***> wrote:
Debuggability is an issue - I've been using that heavily when things fail.
Maybe each gadget can define a namespace format as part of its type?
One approach to solve this could be to have an environment variable (maybe
R1CS_DEBUG) which, upon constraint_generation, and when running in
"prover_mode", checks that constraints are satisfied as they are generated,
so that you get an immediate error. This could also be controlled by a
runtime variable that is false by default, but which users can set to be
true when they want to debug.
—
You are receiving this because you were mentioned.
Reply to this email directly, view it on GitHub
<#186 (comment)>, or
unsubscribe
<https://github.com/notifications/unsubscribe-auth/AA23MGFM6RJ5BMJVECYNVALRMITIPANCNFSM4MGRNWEQ>
.
|
ConstraintSystem API to improve ergonomics
|
You want pointer comparisons here:
|
It could be augmented to print out the value of the assignment during the assignment process, but that would only print out the value of the lowest-level assignments. I think a better solution is as follows. Create macros Furthermore, we can also create a macro that works with the (new version of the) |
|
k
Love this, this should be enough and even better than the current situation. How about making it an option of TestConstraintSystem? |
|
I like the idea of being able to get rid of the
I think this is a great idea and I agree with @kobigurk that this could even be better than the current situation. |
|
Your Are all those I'd favor I suspect prover time would take some small performance hit here, and prover code size would increase, due to namespace handling. These We might not care about prover time or code size here, but you'd suck all that complexity from four types across three distinct crates into I'd think |
|
As I understand it, you want gadgets that (a) interact with multiple variable etc, but whose (2) arguments consist solely of variables, without passing any separate All variables must capture roughly a We've two design choices here, either
If If we do In either case, our namespace method We cannot however place an In this case, I suppose the In the We can simplify As a rule, trait objects are second class citizens in Rust, so you're almost surely better off avoiding them even if it requires adding |
|
I'd think the simplest approach goes: First, all Also where Second, your variables become You'd still like |
|
@burdges (Man I wish GH had a threaded conversations feature)
Thanks for looking into this; maybe I'll just remove the
You mean in
Maybe we can add a
From my experience with implementing these structs in |
All the
You could do either Alternatively, you could move
I'd sure this works but sounds worse for CI. It's also plausible some network would dynamically build constraint systems and do trusted setups, which makes this worse. Also, you could keep Any gadget would invoke
I'd think that abstraction sounds worthwhile regardless :) but several options exist. In #186 (comment) you've some Are there situations in which you build two related proofs concurrently? MPC in the Head? Could one do large RSA exponents with residue number systems run across several distinct curves over the same basefield?
Cool
I agree the |
Ooh this is a very nice idea, to implement |
|
One could add or I've some questions: Why is In this draft, |
|
It's worth asking if this |
8f5393f to
1f691a4
Compare
|
If I understand, you're now passing the |
|
Hmm the PR isn't anywhere near ready yet, but the idea is that high-level variables (eg: FieldGadgets, UInt8, etc.) carry a |
7211a53 to
c764d5f
Compare
c848a94 to
2feb187
Compare
29c6283 to
a191fc0
Compare
| let y = -d_eight + &(f * &(e + &e - &x)); | ||
| let e2 = e.double(); | ||
| let x = g - &e2.double(); | ||
| let y = -d_eight + &(f * &(e2 - &x)); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Can we move this to the syntax that relies on Copy?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I need to figure out why it doesn't automatically find impl Add/Sub/Mul<Self> for Self
45df18a to
1bf9ecb
Compare
3c77d79 to
5fc64e1
Compare
This would be necessary if, in another crate, one wants to implement operators.
|
Could the first two initial miscellaneous fix commits be cherry-picked into another PR, and added separately to master? (This PR should be rebaseable onto the new master then) That way the fixes are in master, and this PR has fewer different concepts to review. (Also would it make sense to do the same for the bit iteration infrastructure?) |
* `to_bits` -> `to_bits_le` * `BitIterator` -> `BitIteratorLE` + `BitIteratorBE` * `found_one`/`seen_one` -> `BitIteratorBE::without_leading_zeros`
69099c3 to
fd2df01
Compare
|
In the new API, it seems that computing the inverse of zero will still lead to an error. This would cause some trouble in writing the constraint system and indexing. As discussed in this issue: #251 Can we change the implementation so that if the inverse does not exist, the |
04e6337 to
afbbe6d
Compare
|
Saw a small typo on https://github.com/scipr-lab/zexe/blob/constraint-system-api/r1cs-std/src/fields/fp/mod.rs#L357 I think it is little-endian. |
afbbe6d to
29087cf
Compare
29087cf to
0c75a85
Compare
4264000 to
ac5f9aa
Compare
Currently the API for writing constraints in
r1cs-coreis very generic:ConstraintSystemis a trait that downstream users can implement and customize, and it must be threaded throughout the gadget interfaces inr1cs-stdand beyond. It also requires users to explicitly set namespaces, which, together with the previous point, makes constraint-generating code very verbose, and often obscures (relatively simple) logic.In this (WIP) PR I'm trying out a different and hopefully more ergonomic approach. The high-level diff is as follows:
The
ConstraintSystemtrait is replaced with a singleConstraintSystemstruct that is meant to be used for all purposes: generating constraints in a SNARK setup, generating witnesses during proving, debugging, etc. This leads to the following changes:Rc<RefCell<ConstraintSystem<F>>>in gadgets that represent variables, such asFieldGadget. This means that we no longer have to pass&mut CSto every function that could possibly generate a constraint, and furthermore means that we can overload arithmetic operators for these gadgets.cs.ns(|| "blah")whenever we need to create a constraint. Note that if one wants to explicitly create a namespace, one can still invokecs.enter_namespace()and thencs.leave_namespace().LinearCombination, users don't explicitly generate one themselves. Instead, they register the linear combination with aConstraintSystemby doingcs.new_lc(my_lc), and get back aVariable::SymbolicLcin return.ConstraintSystemenables a centralized implementation of (optional) optimizations such asOne concern is the debuggability of constraints generated under this new API because namespacing is automatic. Suggestions would be appreciated. Maybe compiler techniques would be a good starting point here.
Looking for feedback on the initial design. Note that the scope of the PR is massive, because we need to re-architect the
r1cs-std,crypto-primitivesanddpccrates =/.CC @kobigurk @gakonst @paberr @ValarDragon
TODOs:
ConstraintSystemRefswhen two different gadgets interact, and figure out the appropriate mechanism for checking equality (ReworkConstraintSystemAPI to improve ergonomics #186 (comment))