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

Precomputed Lagrange #957

Merged

Conversation

danielmasny
Copy link
Collaborator

cleaned up version of Lagrange

Copy link
Member

@martinthomson martinthomson left a comment

Choose a reason for hiding this comment

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

I like the restructuring.


/// This function uses the `LagrangeTable` to evaluate `polynomial` on the specified output "x coordinates"
/// the "y coordinates" of the evaluation are multiplied to `result`
pub fn mult_result_by_evaluation(
Copy link
Member

Choose a reason for hiding this comment

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

Does this need to be public? It looks like it assumes a particular form for result that a caller isn't obligated to guarantee.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

There are some parts in the DZKP (within the provers computation) where I want to compute q(x')*p(x') for some x coordinate x' so it is convenient do use this function and pass q(x') as result which is mutated to q(x')*p(x'). There is the more general function eval for the general case.

Copy link
Collaborator

Choose a reason for hiding this comment

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

I would prefer not to embed this logic into the Lagrange module. I understand it might even be slightly more efficient this way - but it feels like we are violating an important separation of concerns.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I am fine with removing it since you seem to prefer it that way.

ipa-core/src/ff/prime_field.rs Outdated Show resolved Hide resolved
@akoshelev
Copy link
Collaborator

you seem to have added a flaky test, we need to fix it before we can check the coverage

thread 'protocol::ipa_prf::malicious_security::lagrange::test::test_lagrange_cannonical_using_from' panicked at ipa-core/src/protocol/ipa_prf/malicious_security/lagrange.rs:209:5:
Test failed: attempt to subtract with overflow.

@danielmasny
Copy link
Collaborator Author

The test failures were due to a debug assertion that had an error and should be fixed now.

Copy link

codecov bot commented Feb 20, 2024

Codecov Report

Attention: Patch coverage is 98.03922% with 3 lines in your changes are missing coverage. Please review.

Project coverage is 88.57%. Comparing base (030cfc7) to head (0a81a8e).
Report is 14 commits behind head on main.

Files Patch % Lines
...rc/protocol/ipa_prf/malicious_security/lagrange.rs 97.76% 3 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main     #957      +/-   ##
==========================================
- Coverage   89.64%   88.57%   -1.08%     
==========================================
  Files         182      159      -23     
  Lines       25705    21668    -4037     
==========================================
- Hits        23044    19192    -3852     
+ Misses       2661     2476     -185     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

ipa-core/src/ff/prime_field.rs Outdated Show resolved Hide resolved
ipa-core/src/ff/prime_field.rs Outdated Show resolved Hide resolved
/// The "x coordinates" of the input points are `x_0` to `x_(N-1)` are `F::ZERO` to `(N-1)*F::ONE`.
/// The `LagrangeTable` also specifies `M` "x coordinates" for the output points
/// The "x coordinates" of the output points are `x_N` to `x_(N+M-1)` are `N*F::ONE` to `(N+M-1)*F::ONE`.
pub struct LagrangeTable<F: Field, N: ArrayLength, M: ArrayLength> {
Copy link
Collaborator

Choose a reason for hiding this comment

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

I am surprised that it declares that it works over fields and not prime fields only.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Its more general this way. If you want to load something precomputed for a field for which we dont have invert implemented, e.g. from a file, you could. Invert is only needed to generate the denominator, otherwise we don't need inversion.

table: GenericArray<GenericArray<F, N>, M>,
}

impl<F, N> LagrangeTable<F, N, U1>
Copy link
Collaborator

Choose a reason for hiding this comment

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

why do we need this specialization?

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We can make it more general, however we won't need it. M is the amount of output x-coordinates and this implementation allows to generate a Lagrange table for a single output point using new(x_output, denominator). In the proofs, we need to evaluate the polynomials on a single x-coordinate r which is random. Otherwise we always evaluate polynomials at fixed x-coordinates N...N+M in which case we can just use the implementation of From(denominator) below

Comment on lines +255 to +256
}
}
Copy link
Collaborator

Choose a reason for hiding this comment

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

I'm not sure what is going on here... but it looks wrong....

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I just use the proptest macro here. I added a function since the formatting is not checked within macro calls.

let polynomial_monomial_form = MonomialFormPolynomial {
coefficients: GenericArray::<TestField, U8>::from_array(input_points),
};
// the canonical x coordinates are 0..15, the outputs use coordinates 8..15:
Copy link
Collaborator

Choose a reason for hiding this comment

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

I think there is an error in this comment. I think @danielmasny means:
the canonical x coordinates are 0..7, the outputs use coordinates 8..15

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes

Comment on lines +263 to +265
let x_coordinates_output = GenericArray::<_, U7>::generate(|i| {
TestField::try_from(u128::try_from(i).unwrap() + 8).unwrap()
});
Copy link
Collaborator

Choose a reason for hiding this comment

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

Honestly, I find the generics here(e.g. U7, U8) really confusing. I wish there was some better way.

Copy link
Collaborator

@benjaminsavage benjaminsavage left a comment

Choose a reason for hiding this comment

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

@danielmasny is out on paternity leave. How should we take this forward? Should I just land this PR as is and make a few minor changes in a follow up PR? That seems like the simplest approach. @martinthomson ?

@martinthomson
Copy link
Member

Forwards is a good direction to move and this code is close.

@benjaminsavage benjaminsavage merged commit c50e800 into private-attribution:main Mar 16, 2024
11 checks passed
@danielmasny danielmasny deleted the precomputed_lagrange branch May 30, 2024 17:55
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