I was noticing that GLV decompositions operate on pairs of field elements and frequently performs the same operations on both field elements.
If we had a type like:
struct Pair<F: Field>(F, F)
...it could provide various arithmetic ops, even core::ops where applicable, that operate over both field elements in parallel in safe Rust.
You'd use it concretely as Pair(Scalar, Scalar) or Pair(FieldElement, FieldElement), and the SIMD arithmetic impls would likely be specific to one or the other, but they could otherwise provide a common API for operations that could potentially be performed in parallel on AVX-512, NEON, or SVE.
The main place I think this could be really interesting is in lincomb_vartime_glv_wnaf which calls into WnafBase::multiscalar_mul with pairs of WnafBase and WnafScalar, unfortunately I just moved k256 to using the wnaf crate and want to stabilize that ASAP which would preclude doing a more custom w-NAF implementation specifically for k256 like we have for scalar multiplication, though we could always stop using the wnaf crate and switch back to a vendored implementation (though k256 is currently the only consumer of the wnaf crate).
Alternatively we could do something like:
type FieldElementPair = (FieldElement, FieldElement);
type ScalarPair = (Scalar, Scalar);
...though I think that would preclude writing our own trait impls on the type aliases?
I was noticing that GLV decompositions operate on pairs of field elements and frequently performs the same operations on both field elements.
If we had a type like:
...it could provide various arithmetic ops, even
core::opswhere applicable, that operate over both field elements in parallel in safe Rust.You'd use it concretely as
Pair(Scalar, Scalar)orPair(FieldElement, FieldElement), and the SIMD arithmetic impls would likely be specific to one or the other, but they could otherwise provide a common API for operations that could potentially be performed in parallel on AVX-512, NEON, or SVE.The main place I think this could be really interesting is in
lincomb_vartime_glv_wnafwhich calls intoWnafBase::multiscalar_mulwith pairs ofWnafBaseandWnafScalar, unfortunately I just movedk256to using thewnafcrate and want to stabilize that ASAP which would preclude doing a more custom w-NAF implementation specifically fork256like we have for scalar multiplication, though we could always stop using thewnafcrate and switch back to a vendored implementation (thoughk256is currently the only consumer of thewnafcrate).Alternatively we could do something like:
...though I think that would preclude writing our own trait impls on the type aliases?