Compute the modular exponentiation of base^exponent using
algorithms design to avoid side channels and timing measurement
Modulo need to be odd otherwise the normal fast modular exponentiation
is used.
With an odd modulo the work is done in C, four bits of exponent at a time:
four squarings and one multiplication by a small power of the base, taken
from a table of sixteen which is read by touching every entry and keeping
one of them with a mask. So each group of four bits costs the same five
multiplications and the same sixteen reads whatever those bits are, and
nothing branches on the exponent or indexes memory with it.
What the exponent still shows is its length: it is rounded up to a whole
64-bit word and every bit of that is walked over, so its value is hidden
but its size is not. The mpz_powm_sec of GMP, which GHC stopped
offering in integer-gmp 1.1 and which this replaces, hides exactly as much.
The base is taken to be public -- in this library it is a ciphertext, a
public value from a peer, or a generator -- and is reduced modulo the
modulus in the ordinary way first.
Hiding the exponent has a price: against the windowed exponentiation of
GMP, which is what this function used to end up calling, a 2048-bit
modulus costs somewhat over twice as much.