penumbra-zone / decaf377

decaf377 is a prime-order group designed for use in SNARKs over BLS12-377
https://protocol.penumbra.zone/main/crypto/decaf377.html
12 stars 12 forks source link

Implement inversion for fiat-generated code #65

Closed hdevalence closed 10 months ago

hdevalence commented 10 months ago

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 in cargo doc --open). We'll need to figure out how to use these:

TalDerei commented 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."

hdevalence commented 10 months ago

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).

hdevalence commented 10 months ago

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.

hdevalence commented 10 months ago

@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.

TalDerei commented 10 months ago

Looks good, the example https://github.com/mit-plv/fiat-crypto/blob/master/inversion/c/inversion_template.c also references the Bernstein-Yang paper.

redshiftzero commented 10 months ago

Done in #67