feat: add automatic non-native witness element limb constraining #446
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Resolves #348.
High-level idea for automatic constraining of the elements. We add a flag
internal
for theElement
type whereinternal=true
indicates that this Element came as an output ofField
methods (which we set in the methods). We ensure in the methods that we always set the flag.If the
Element
comes from elsewhere (usually usingNewElement
), then potentially the limbs of that value are not constrained to benbBits
bits wide. However, the value may already be constrained elsewhere (but we do not want to keep the state inElement
itself, as it could be modifying the witness).We add a table of constrained limbs in
Field
type, indexed by limb variables (usingHashCode
onLinearExpression
/Term
). If we constrain an element, then for every limb we store its key in the map to prevent constraining the Element constraining the limb later again.We also add a pre-condition to every
Field
method which performs this conditional bit-width enforcing.Seems to be working with minimal overhead as we ever store only witness element hashes in the table and there are usually only a small number. Will have to check if makes sense to add some probabilistic filter in front of the map, but subjectively there wasn't a noticeable performance diff for large circuits (nonnative ECDSA).
Still WIP:
Element
. Have to unify and give more descriptive names. For example, want to leaveNewElement
only for witness creation (with input types which make sense i.e. integer-like) and for everywhere else want to have private methods (to prevent users accidentally creating internal elements).EnforceWidth
is not necessary anymore because is done automatically)Elements
are created so thatinternal
flag is consistent.