Closed hdevalence closed 10 months ago
@hdevalence I've been looking over the divstep
fiat-crypto operation that's referenced from this paper, and the auto-generated input bounds seem ambiguous. The Input bounds for divstep are clearly related to how the cryptographic operation is optimized, but it's not entirely clear what these inputs are supposed to represent in relation to a FpNonMontgomeryDomainFieldElement
that we'd like to perform the inversion on. This might be helpful?
Additionally, I'm questioning in what context we'd need to perform an expensive inversion operation at all? Per this fiat-crypto paper, the author states "To allow for fast computations, I implemented and verified inversion-free addition formulas for each family of curves."
I'm questioning in what context we'd need to perform an inversion operation
Even when using inversion-free addition operations, there still needs to be at least one inversion at the end. The sense in which they're "inversion-free" is that they don't need to do an inversion on every operation, and instead use projective coordinates (akin to fractions) to avoid doing an inversion to the very end.
We need to have inversion to be able to implement the arkworks traits, at least, and it's generally useful to provide all of the primitive operations of field arithmetic. In our specific case, we'll also eventually need to be able to do inverse square roots; we have a custom implementation of this in the decaf377
crate already, which we could port or adapt later. That code is relatively well understood (at least by @redshiftzero, who wrote it), the current gap is being able to do plain inversions using the generated fiat-crypto code.
(I haven't looked into the links you posted yet, but wanted to clarify that part about why we'd like to do inversion first).
It looks like we want to be implementing Algorithm 2, plugging in the generated divstep
as DIVSTEPS
; maybe we can figure out the out1
, out2
, .... parameters by looking at the definition of DIVSTEPS
, for instance out1
could be n
, since it's small and is only used with small values in Algorithm 2.
@TalDerei I asked @tarcieri, who pointed to https://github.com/RustCrypto/elliptic-curves/blob/master/primeorder/src/field.rs#L506-L559 ; we could copy the inside of that macro into our implementation.
Looks good, the example https://github.com/mit-plv/fiat-crypto/blob/master/inversion/c/inversion_template.c also references the Bernstein-Yang paper.
Done in #67
The wrapper types added in #64 don't include inversion. The fiat-generated code has methods that seem to be intended to be used to implement inversion (
divstep
etc, as seen incargo doc --open
). We'll need to figure out how to use these:Fq::inv(&self) -> Option<Fq>
(returningNone
ifself == 0
) orFq::inv(&self) -> Fq
(returning0
ifself == 0
), whichever is convenient to implement.{u32, u64}::{Fp, Fq, Fr}
.