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

Refactor mul_fixed_short API to copy in (magnitude, sign) #145

Merged
merged 16 commits into from
Jul 19, 2021

Conversation

therealyingtong
Copy link
Contributor

@therealyingtong therealyingtong commented Jul 10, 2021

Documented in #146.

The value commitment integrity check in the Action circuit involves a fixed-base scalar mul [v_old - v_new] ValueCommitV, where v_net = v_old - v_new is a signed 64-bit value. v_net will be witnessed in the circuit as two cells: a magnitude and sign. These should be copied into the mul_fixed_short API. This means the magnitude can now be decomposed using a running sum, instead of being witnessed directly as bits.

This PR also inlines all witness_scalar_* APIs. A scalar is now directly witnessed in the region where it is used for multiplication, whereas previously it was witnessed separately and then copied in.

@therealyingtong therealyingtong marked this pull request as draft July 10, 2021 16:06
@codecov-commenter
Copy link

codecov-commenter commented Jul 10, 2021

Codecov Report

Merging #145 (fe95122) into main (f3c9b6c) will decrease coverage by 0.12%.
The diff coverage is 89.40%.

Impacted file tree graph

@@            Coverage Diff             @@
##             main     #145      +/-   ##
==========================================
- Coverage   86.60%   86.48%   -0.13%     
==========================================
  Files          64       62       -2     
  Lines        6359     6413      +54     
==========================================
+ Hits         5507     5546      +39     
- Misses        852      867      +15     
Impacted Files Coverage Δ
src/circuit/gadget/utilities.rs 95.19% <ø> (ø)
src/constants.rs 100.00% <ø> (ø)
...rcuit/gadget/ecc/chip/mul_fixed/base_field_elem.rs 79.57% <76.00%> (-1.95%) ⬇️
.../circuit/gadget/utilities/decompose_running_sum.rs 83.48% <83.48%> (ø)
src/circuit/gadget/ecc/chip/mul_fixed/short.rs 88.41% <89.94%> (-3.02%) ⬇️
...rc/circuit/gadget/ecc/chip/mul_fixed/full_width.rs 94.40% <92.15%> (-2.69%) ⬇️
src/circuit/gadget/ecc/chip.rs 88.78% <92.30%> (+2.11%) ⬆️
src/circuit/gadget/ecc/chip/mul_fixed.rs 86.91% <93.93%> (+0.22%) ⬆️
src/circuit/gadget/ecc.rs 87.50% <100.00%> (-0.53%) ⬇️
src/circuit/gadget/ecc/chip/mul.rs 85.08% <100.00%> (+1.01%) ⬆️
... and 6 more

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update f3c9b6c...fe95122. Read the comment docs.

@therealyingtong therealyingtong marked this pull request as ready for review July 12, 2021 04:17
@therealyingtong therealyingtong changed the title [WIP] Refactor mul_fixed_short API to copy in (magnitude, sign) Refactor mul_fixed_short API to copy in (magnitude, sign) Jul 12, 2021
@therealyingtong therealyingtong added this to the Core Sprint 2021-26 milestone Jul 12, 2021
@therealyingtong
Copy link
Contributor Author

therealyingtong commented Jul 15, 2021

For the purposes of Orchard, mul_fixed_base_field_elem() should only ever be used with the NullifierK base. We should introduce another FixedPointBaseField enum to separate these two APIs.

Edit: This is implemented in this PR 345832c.

Base automatically changed from ecc-mul to main July 15, 2021 10:16
This decomposes a field element into K-bit windows using a
running sum. Each step of the running sum is range-constrained.
In strict mode, the final output of the running sum is constrained
to be zero.

This helper asserts K <= 3.
Witness a scalar in the region where it is used for multiplication,
instead of witnessing it separately and then copying it in.
In the Orchard circuit, the short signed scalar is v_old - v_new,
which will be witnessed as two cells: a 64-bit magnitude, and a
sign that is +/- 1.
Check that a magnitude larger than 64 bits results in a constraint
failure.
Check that a sign other than +/- 1 results in a constrain failure.
In the Orchard protocol, only the NullifierK fixed base in used in
scalar multiplication with a base field element.

The mul_fixed_base_field_elem() API does not have to accept fixed
bases other than NullifierK; conversely, NullifierK does not have
to work with the full-width mul_fixed() API.
// Magnitude larger than 64 bits should fail
{
let circuit = MyCircuit {
magnitude: Some(pallas::Base::from_u128(1 << 64)),
Copy link
Contributor

@daira daira Jul 15, 2021

Choose a reason for hiding this comment

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

Test this for 1<<66 and 1<<254 as well. (Maybe also do all the test cases for both signs.)

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I realise that 1 << 66 would give the same failure as 1 << 64, because the "last window check" is on the running sum, which will be nonzero (even if the three-bit window itself is zero).

src/circuit/gadget/ecc.rs Outdated Show resolved Hide resolved
Copy link
Contributor

@daira daira left a comment

Choose a reason for hiding this comment

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

utACK with comments.

Co-authored-by: Daira Hopwood <daira@jacaranda.org>
src/circuit/gadget/utilities/decompose_running_sum.rs Outdated Show resolved Hide resolved
src/circuit/gadget/utilities/decompose_running_sum.rs Outdated Show resolved Hide resolved
src/circuit/gadget/utilities/decompose_running_sum.rs Outdated Show resolved Hide resolved
src/circuit/gadget/utilities/decompose_running_sum.rs Outdated Show resolved Hide resolved
src/circuit/gadget/utilities/decompose_running_sum.rs Outdated Show resolved Hide resolved
Comment on lines +89 to +91
scalar: &Self::Var,
base: &Self::Point,
) -> Result<Self::Point, Error>;
) -> Result<(Self::Point, Self::ScalarVar), Error>;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'm confused by this change. It looks like we are not witnessing scalar inside this instruction, but decomposing an existing witnessed scalar?

Comment on lines -122 to +99
scalar: &Self::ScalarFixed,
scalar: Option<C::Scalar>,
base: &Self::FixedPoints,
) -> Result<Self::Point, Error>;
) -> Result<(Self::Point, Self::ScalarFixed), Error>;
Copy link
Contributor

Choose a reason for hiding this comment

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

I'd personally prefer that we enable these same optimizations with something like zcash/halo2#334, but as discussed in a pairing I'm reasonably confident we could retrofit that API onto these changes without altering the circuit.

@@ -264,7 +264,7 @@ impl Config {
self.overflow_config
.overflow_check(layouter.namespace(|| "overflow check"), alpha, &zs)?;

Ok(result)
Ok((result, alpha))
Copy link
Contributor

Choose a reason for hiding this comment

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

Okay, now I'm really confused. If variable-base scalar mul is just passing alpha through, why even alter those APIs?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

My motivation was to make the mul API resemble the mul_fixed_* APIs.

src/circuit/gadget/ecc/chip/mul_fixed/short.rs Outdated Show resolved Hide resolved
src/circuit/gadget/ecc/chip/mul_fixed/short.rs Outdated Show resolved Hide resolved
These are now provided as inputs to the witness_decompose() and
copy_decompose() methods. This allows us to reuse the same config
for different word/window lengths, avoiding a duplicate constraint
creation.

Co-authored-by: Jack Grigg <jack@electriccoin.co>
therealyingtong and others added 2 commits July 18, 2021 00:09
The decompose_running_sum gadget in strict mode already enforces
this check.

Co-authored-by: Jack Grigg <jack@electriccoin.co>
Selectors previously used in the witness_scalar_* APIs, such as
q_scalar_fixed and q_scalar_fixed_short, are now removed. The
remaining selectors have been renamed for clarity.

The coordinates check for scalars decomposed using a running sum
has been moved into the mul_fixed.rs file, instead of being
duplicated in both mul_fixed::base_field_elem and mul_fixed::short.

The decompose_scalar_fixed() method is now only used in
mul_fixed::full_width, and has been moved there.
Co-authored-by: Jack Grigg <jack@electriccoin.co>
Copy link
Contributor

@str4d str4d left a comment

Choose a reason for hiding this comment

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

utACK 91b8ea2 after finishing the removal of duplicate coords-check gates.

src/circuit/gadget/ecc/chip/mul_fixed/short.rs Outdated Show resolved Hide resolved
The coordinate check for an element decomposed using a running sum
is enforced by mul_fixed::Config::running_sum_coords_gate().

Co-authored-by: Jack Grigg <jack@electriccoin.co>
@@ -69,14 +69,11 @@ impl Config {
.coords_check(meta, q_mul_fixed_running_sum, word)
});

// Check that we get z_85 = 0 as the final output of the three-bit decomposition running sum.
// Also check that the base field element is canonical.
// Check that the base field element is canonical.
Copy link
Contributor

@daira daira Jul 19, 2021

Choose a reason for hiding this comment

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

https://zcash.github.io/orchard/design/circuit/gadgets/ecc/fixed-base-scalar-mul.html#fixed-base-scalar-multiplication-using-base-field-element includes the z_85 = 0 constraint as part of the canonicity check. Update the book to reflect the implementation.

Copy link
Contributor Author

@therealyingtong therealyingtong Jul 19, 2021

Choose a reason for hiding this comment

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

z_85 = 0 is now constrained by the self.running_sum_config.copy_decompose() call in base_field_elem::Config::assign(), with strict = true.

I'll add a comment to this effect + update the book.

Copy link
Contributor

@str4d str4d Jul 19, 2021

Choose a reason for hiding this comment

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

@daira z_85 is constrained because we now use strict checks during scalar decomposition.

Copy link
Contributor

Choose a reason for hiding this comment

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

I don't see any uses of strict = false except in tests. Did I miss any? If not, why do we need the strict check to be optional?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

The updated book PR is at: #146.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

I chose to include the strict option for a more general helper API.

(Sidenote: For the lookup_range_check helper, we only ever use strict = false, so we could choose to not provide a strict = true option there.)

Copy link
Contributor

@daira daira Jul 19, 2021

Choose a reason for hiding this comment

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

I find the code more confusing to think about with the two options, and more work to review. I would prefer that we remove the ones we don't use in Orchard. (Does not have to be in this PR.)

Co-authored-by: Daira Hopwood <daira@jacaranda.org>
Copy link
Contributor

@str4d str4d left a comment

Choose a reason for hiding this comment

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

re-utACK c444dde

Copy link
Contributor

@str4d str4d left a comment

Choose a reason for hiding this comment

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

re-utACK 1b615a4

Copy link
Contributor

@daira daira left a comment

Choose a reason for hiding this comment

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

@str4d str4d merged commit cf4c78f into main Jul 19, 2021
@str4d str4d deleted the refactor-short-scalar branch July 19, 2021 11:49
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.

None yet

5 participants