Conversation
- update test vectors paths from "/15/" to "/18" - change various variable names, field names from "prep", "prepare" to "verifier", "verify" We still have lots and lots of things throughout the crate called "prepare" that should be "verify". This commit deliberately only deals with the test vector code to keep the diff smaller.
d303f46 to
73033c5
Compare
Update the implementation of fully linear proofs to do polynomial
multiplications and evaluations in the Lagrange basis, using algorithms
from Faz25 ([1]), as specified in draft-irtf-cfrg-vdaf-18 ([2]).
The most important changes are in:
- `flp::Flp::{prove, query, decide}`
- `flp::ProveShimGadget`
- `flp::QueryShimGadget`
- `flp::gadgets::Mul`
- `flp::gadgets::PolyEval`
Since we no longer need to precompute a multiplicative inverse,
`flp::Gadgets::Mul` is no longer generic over `FieldElement`, and
removing that generic parameter is reflected in a number of places in
the codebase.
Finally, in order to avoid an unnecessary copy, we make minor changes to
the interfaces in `mod polynomial`:
- `poly_mul_lagrange` now writes output to a provided output buffer
instead of allocating and returning `Vec<F>`
- `double_evaluations` (which returns its output as `Vec<F>`) is renamed
`get_double_evaluations` (matching the convention set in `mod ntt`)
and we add `double_evaluations` which writes output to a provided
buffer.
[1]: https://eprint.iacr.org/2025/1727.pdf
[2]: https://datatracker.ietf.org/doc/html/draft-irtf-cfrg-vdaf-18#name-polynomial-evaluation
Closes #1394
73033c5 to
73a3cd5
Compare
src/benchmarked.rs
Outdated
There was a problem hiding this comment.
In the Rhizomes world, we just always do the NTT and don't bother with the NTT threshold stuff.
| // assert!(polynomials[0].as_ref().len().is_power_of_two()); | ||
| // assert_eq!(roots.len(), poly_len, "incorrect number of roots provided"); | ||
| assert!(polynomials[0].as_ref().len().is_power_of_two()); | ||
| let roots = nth_root_powers(poly_len); |
There was a problem hiding this comment.
In the previous PR, we discussed the possibility of precomputing roots of unity and passing them in here. I'm open to re-introducing the roots function argument but would point out that since poly_eval_lagrange_batched is internal to the crate, we can change it freely in the future without breaking SemVer promises, should we choose to build such an optimization.
There was a problem hiding this comment.
We have #1392 to generally change "prepare" to "verify", which will be a big messy diff that stomps on a great many lines. I chose to jump the gun in this particular area because the test vectors we need to move to for draft-irtf-cfrg-vdaf-18 use a new encoding that discusses verify_init and verifier_shares and so on. So I felt it made sense to take just this bite of the whole meal.
| let mut p_doubled = double_evaluations(p)?; | ||
| double_evaluations(output, p)?; | ||
|
|
||
| for (p_element, q_element) in p_doubled.iter_mut().zip(double_evaluations(q)?) { |
There was a problem hiding this comment.
I think we could do even better if we had a version of double_evaluations that returns an iterator, and the same idea could be applied to a few things in polynomial or ntt, but, well, you have to stop somewhere.
There was a problem hiding this comment.
This file isn't currently used in tests
There was a problem hiding this comment.
Ouch, sloppy of me. I double checked that all other test vectors do get exercised.
There was a problem hiding this comment.
Fortunately you already had the HigherDegree type in place. I moved it to a new module flp::types::higher_degree so it's easier to use from prio3_test.
src/flp.rs
Outdated
| == Self::Field::one() | ||
| // polynomial at any of these points would be a privacy violation, since these | ||
| // points were used by the prover to construct the wire polynomials. | ||
| if r.pow( |
There was a problem hiding this comment.
Since the query randomness is no longer needed to construct query shim gadgets, we could split apart the zipped iterators here, and move this check to a separate loop.
There was a problem hiding this comment.
We still need to zip gadgets and query rand together so we can compute each gadget's wire poly length in the query randomness check, but I agree that two separate iterators is easier to read.
src/flp.rs
Outdated
| /// Input wire values recorded during successive evaluations of this gadget. Indexed by wire | ||
| /// number and number of calls. i.e., `wire_values[i][j]` is the value of the `i`-th input wire | ||
| /// during the `j`-th invocation of this gadget. |
There was a problem hiding this comment.
This description is off by one, as wire_values[i][0] is reserved for a seed value from the prover randomness.
src/flp.rs
Outdated
| /// Input wire values recorded during successive evaluations of this gadget. Indexed by wire | ||
| /// number and number of calls. i.e., `wire_values[i][j]` is the value of the `i`-th input wire | ||
| /// during the `j`-th invocation of this gadget. |
There was a problem hiding this comment.
See above, wire_values[i][0] is a randomly chosen seed value.
Don't be discouraged by the size of the diff! It's mostly test vectors. The first commit contains only test vector updates for draft-irtf-cfrg-vdaf-18. The functional changes are all in the second commit:
Update the implementation of fully linear proofs to do polynomial multiplications and evaluations in the Lagrange basis, using algorithms from Faz25 (1), as specified in draft-irtf-cfrg-vdaf-18 (2).
The most important changes are in:
flp::Flp::{prove, query, decide}flp::ProveShimGadgetflp::QueryShimGadgetflp::gadgets::Mulflp::gadgets::PolyEvalSince we no longer need to precompute a multiplicative inverse,
flp::Gadgets::Mulis no longer generic overFieldElement, and removing that generic parameter is reflected in a number of places in the codebase.Finally, in order to avoid an unnecessary copy, we make minor changes to the interfaces in
mod polynomial:poly_mul_lagrangenow writes output to a provided output buffer instead of allocating and returningVec<F>double_evaluations(which returns its output asVec<F>) is renamedget_double_evaluations(matching the convention set inmod ntt) and we adddouble_evaluationswhich writes output to a provided buffer.Closes #1394