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

Multiplication/exponentiation speed-ups #34

Open
fjarri opened this issue Sep 9, 2023 · 2 comments
Open

Multiplication/exponentiation speed-ups #34

fjarri opened this issue Sep 9, 2023 · 2 comments
Assignees
Labels
performance Making things faster
Milestone

Comments

@fjarri
Copy link
Member

fjarri commented Sep 9, 2023

Currently, most of the time in the signing protocol is spent in Montgomery exponentiation. Key refresh is split between exponentiation and prime number generation, but the latter is mainly exponentiation again (most of the time is spent in Miller-Rabin tests). So it would help a lot if the exponentiation performance is improved.

Possible avenues:

  1. Replace schoolbook multiplication with Karatsuba or Toom-Cook. This may start making a difference at our integer sizes (2048 bit). This has to be done within crypto-bigint, see Improve multiplication  RustCrypto/crypto-bigint#66
  2. Use wNAF exponentiation instead of the current fixed-window one (for the cases where the exponent is not secret). This has to be done within crypto-bigint.
  3. crypto-bigint's pow() supports exponents of arbitrary size (that is you can raise Uint<N> into Uint<M> power). We currently only raise Uint<N> to Uint<N>, and implement Uint<N>^Uint<2*N> and Uint<N>^Uint<4*N> by breaking the exponent in halves and exponentiating separately. If we could use the arbitrary size exponentiation, it could make this faster, because we would not have to calculate x^{2^N} separately to merge the halves - it's already calculated by the fixed window algorithm.
  4. In some places where we calculate x^y mod N we also know phi(N) (the totient), so we can instead calculate x^(y mod phi(N)) mod N. If y is large (of the order of N^2), this may be faster than direct exponentiation.
@fjarri fjarri added the performance Making things faster label Sep 9, 2023
@fjarri fjarri added this to the v1.0.0 milestone Nov 26, 2023
@fjarri
Copy link
Member Author

fjarri commented Dec 2, 2024

Item 3: arbitrary-sized exponent is available as of crypto-bigint 0.6. This can be addressed now, but some thought needs to be put into trait bounds.

@dvdplm
Copy link
Contributor

dvdplm commented Jan 6, 2025

Did some investigation of point 4; capturing that here.

  • The reason it's ok to reduce y modulo phi(N) is that x is overwhelmingly likely to be coprime to N (the only two factors of N are p and q, both primes), so we can apply Euler's x^(phi(N)) ≡ 1 mod N.
  • phi(N) is on the order of N - 2*sqrt(N) (why? N is the product of two numbers each close to sqrt(N) given how we search for our primes, so (p-1)(q-1) is roughly N - (p+q) ≈ N - 2sqrt(N)) which is the same magnitude as N
  • If y is large, on the order of N^2 or larger, reducing it mod phi(N) takes the exponent to be order N rather than N^2 at the cost of one extra reduction.
  • reducing y from order N^2 to just N translates into cutting the exponentiation cost by half (why? because log(N^2) ≈ 2*log(N))

I find it difficult to guesstimate just how much of a speedup 4) would give us, but it seems likely that it ends up faster.

I wrote an artificial benchmark today comparing "vanilla" exponentiation (x^y mod N) of 2048^4096-bit numbers with x^(y mod phi(N)) mod N and perhaps unsurprisingly the latter is 2x as fast. The question about how much of that speedup seeps through in the end? I.e. How many such exponentiations are actually doing in the hot path?

@dvdplm dvdplm self-assigned this Jan 15, 2025
@dvdplm dvdplm mentioned this issue Jan 22, 2025
5 tasks
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
performance Making things faster
Projects
None yet
Development

No branches or pull requests

2 participants