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

Verified Bedrock2 code for Number-Theoretic Transform #1997

Open
wants to merge 8 commits into
base: master
Choose a base branch
from

Conversation

atrieu
Copy link
Contributor

@atrieu atrieu commented Dec 31, 2024

The PR is still in a bit of a rough state, but I'm opening it to see if there is interest in adding it.

The Number-Theoretic Transform is a technique to accelerate polynomial multiplications used in recent lattice-based cryptography for PQC.

This PR defines:

  • a theory of polynomials and its Chinese Remainder Theorem in Polynomial.v
  • definition of the NTT in CyclotomicDecomposition.v which defines an homomorphism from a type Pquotl (cyclotomic_decomposition n 0) to Pquotl (cyclotomic_decomposition n k) where Pquotl ql is defined as Pquotl (ql: list P): Type := { pl: list P | List.Forall2 (fun p q => Peq p (Pmod p q)) pl ql }, and cyclotomic_decomposition n i is the i-th layer decomposition of X^n + 1. It also defines various optimizations for the NTT.
  • lower-level Gallina code of the NTT in RupicolaNTT.v
  • verified Bedrock2 code in BedrockNTT.v, I initially tried to automatically synthesize the code using Rupicola, but ended up doing the proof manually
  • Bedrock2 code for Barrett and Montgomery Reduction when the field element fits in one word in RupicolaBarrettReduction.v and RupicolaMontgomeryArithmetic.v
  • examples using all the above to synthesize C code of the (inverse) NTT for MLKEM and MLDSA in MLKEM.v and MLDSA.v.

I believe the C code should look like what someone would write after reading the NIST standards with no other reference. In terms of performance, this is slower than the handwritten C reference implementations for Kyber/Dilithium which use a so-called centered signed representation for field elements, and delay reduction of the coefficients to the end of the NTT instead of systematically doing it at each step like the synthesised code.

@andres-erbsen
Copy link
Contributor

andres-erbsen commented Feb 6, 2025

In principle, I am interested in theory of polynomials and NTTs, as well as a Bedrock2 implementation. The main reason I have not undertaken it myself is simply the amount of work I expect it to take. Already polynomial CRT is impressive, let alone the rest of the PR.

FYI, there is another exploration of NTT in Bedrock2 by @lukaszobernig at master...lukaszobernig:fiat-crypto:ntt#diff-2ba131d0bae59c3f1d7bf36175bb93917df54b968bb82545a3ad793cbecee00f

As for what to merge, and in what shape, I think the main considerations are that (1) I want to only merge things I can see myself recommending, either for use or study and (2) it would be really cool to have something on NTTs, and fiat-crypto seems like a good place for this work to live. In that spirit, let me raise some high-level questions

  • I am unsure about cyclotomic deomposition as a central abstraction. Relations in terms of evaluation at roots of unity seem more appealing to me. The file is also over 2k lines, and while some of it is generic, I have not managed to read through it. Do you think a more direct use of polynomial remainer arithmetic understood in terms of its effect on polynomial evaluation would work here? I know Lukas's branch doesn't do the all-but-last-layer NTT yet, but I am hopeful it could be adapted -- please take a look at it and share what you think.
  • Whether to use our own polynomials or math-comp is something I could go either way on. What I like about math-comp is that it defines one canonical notion of polynomials for each field, not a technical abstraction. At the same time, it seems desirable to have most of the operations be defined in terms of other operations in a manner that is blind to the representation. I believe a compromise could be found here, and what you define does look attractive. But perhaps a higher-level question is, are you looking to polish up and then maintain a new polynomial library? Doing this myself had already been on my mind for whenever ZmodZ is off my plate.
  • Bedrock2 code would be very nice to have. Ideally it would have a relatively direct proof in terms of tail-recursion interpretation of the loop and algebraic properties, as opposed to mirroring a Gallina definition, but either would be acceptable.
  • Concrete examples on standard algorithms are very appealing, and the instantiation structure looks reasonable.
  • For word-sized reductions, I would have naively thought what we have in https://github.com/mit-plv/fiat-crypto/tree/master/src/Arithmetic/BarrettReduction and https://github.com/mit-plv/fiat-crypto/tree/master/src/Arithmetic/MontgomeryReduction is close enough to be usable for proving bedrock2 code directly? Is there a serious incompatibility?
  • I am separately trying to make up my mind about what to do with Rupicola; it seems that the main authors are not working on that repository anymore and I'm wondering how much to build new stuff on it. Do you think using Rupicola has been helpful and worthwhile here?

Overall, this is an ambitious and impressive project. I would like to get something like this in, but it would require a fair bit of work and more tight collaboration between us. Please let me know what you think; we could also do a call if that sounds helpful to you.

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.

2 participants