- We were redundantly storing the `x_p` and `y_p` columns.
- `Config::add_incomplete` was redundantly copying.
Co-authored-by: therealyingtong <yingtong@z.cash>
Both variable-base scalar mul and Sinsemilla use double-and-add with
incomplete addition on a single row, but they do so in slightly
different ways. Some of these are intentional (needing to look up the
y-coordinate vs constrain it), while others are accidental (different
concrete signs in otherwise-identical constraints that make their ASTs
incompatible).
The new `DoubleAndAdd` helper struct extracts the logic that is common
to both implementations, specifically the helper definitions of `x_r`
and `Y_A`. In a future breaking change, we can refactor both gadgets to
share more of this logic, so we are defining the incomplete addition
logic in fewer places.
The new `EccInstructions` instructions, and the corresponding changes to
existing instructions, enable chips to choose when to witness or constrain
the scalars, and simplify scalar reuse (though reuse is not implemented
for `EccChip` yet).
`FixedPoint::mul` and `FixedPointShort::mul` now has the same API style
as `NonIdentityPoint::mul`.
We also set `resolver = "2"` on the workspace; this is the default for
the root package in Rust 2021, but as we use a virtual workspace we need
to explicitly set it instead.
There are two existing patterns for constructing a gate from a set of
constraints with a common selector:
- Create an iterator of constraints, where each constraint includes the
selector:
```
vec![
("foo", selector.clone() * foo),
("bar", selector.clone() * bar),
("baz", selector * bar),
]
```
This requires the user to write O(n) `selector.clone()` calls.
- Create an iterator of constraints, and then map the selector in:
```
vec![
("foo", foo),
("bar", bar),
("baz", bar),
].into_iter().map(move |(name, poly)| (name, selector.clone() * poly))
```
This looks cleaner overall, but the API is not as intuitive, and it
is messier when the constraints are named.
The `Constraints` struct provides a third, clearer API:
```
Constraints::with_selector(
selector,
vec![
("foo", foo),
("bar", bar),
("baz", bar),
],
)
```
This focuses on the structure of the constraints, and handles the
selector application for the user.
The published source code for each package needs to include the required
header file, and the path to that header file needs to be relative to
the package source (not the repository source). We therefore need to
have the header file present in each workspace package.
Closeszcash/halo2#506.