crypton-2.2.5: Cryptography Primitives
LicenseBSD-style
MaintainerVincent Hanquez <vincent@snarc.org>
Stabilityexperimental
PortabilityGood
Safe HaskellNone
LanguageHaskell2010

Crypto.Number.ModArithmetic

Description

Modular arithmetic on Integer.

What an Integer shows

An Integer is as long as its value needs, and every operation on one costs what that length says. A secret that happens to be short is multiplied, reduced and compared in fewer words than a full-length one, and the difference is there to be measured. expSafe and inverseSafe keep the value of an exponent or of a number being inverted out of the work they do, and that is as far as an Integer can be taken: hiding the length as well means a fixed-width representation, which is what the curve modules and expSafe itself use underneath.

Synopsis

Exceptions

Exponentiation

expSafe Source #

Arguments

:: Integer

base

-> Integer

exponent

-> Integer

modulo

-> Integer

result

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.

expFast Source #

Arguments

:: Integer

base

-> Integer

exponent

-> Integer

modulo

-> Integer

result

Compute the modular exponentiation of base^exponent using the fastest algorithm without any consideration for hiding parameters.

Use this function when all the parameters are public, otherwise expSafe should be preferred.

A short exponent on an odd modulus -- RSA verification, where the exponent is 65537 and comes out of the public key -- is walked a bit at a time in C, squaring at each step and multiplying where a bit is set, which reads the exponent and branches on it and is why this is not expSafe. That path is taken only where it is the faster of the two, which the C decides; everywhere else, and for every longer exponent, this is GMP's windowed exponentiation as it has always been.

Inverse computing

inverse :: Integer -> Integer -> Maybe Integer Source #

inverse computes the modular inverse as in g^(-1) mod m.

inverseSafe :: Integer -> Integer -> Maybe Integer Source #

inverseSafe computes the modular inverse without letting the number being inverted steer how long the work takes, which is what inverse does: the extended Euclidean algorithm takes a number of steps that follows the bits it is given, and a nonce inverted that way has been taken apart before by watching the steps go by.

The answer comes from a fixed number of division steps where the assembly for them is built, and from inverseFermat where it is not. Either way it is checked here by multiplying out: neither one says when the number has no inverse -- the first returns something that is not one and the second returns something that is not one either -- so the check is what makes this agree with inverse on every input, and inverse is asked when it fails. That fallback is reached only by parameters that are already broken.

The division steps cost about a twentieth of the exponentiation: on an Apple M4, inverting modulo the P-256 group order is 0.80 microseconds against 6.02, and modulo the P-521 one 2.05 against 63.2.

inverseCoprimes :: Integer -> Integer -> Integer Source #

Compute the modular inverse of two coprime numbers. This is equivalent to inverse except that the result is known to exists.

If the numbers are not defined as coprime, this function will raise a CoprimesAssertionError.

inverseFermat :: Integer -> Integer -> Integer Source #

Modular inverse using Fermat's little theorem. This works only when the modulus is prime but avoids side channels like in expSafe.

Squares

jacobi :: Integer -> Integer -> Maybe Integer Source #

Computes the Jacobi symbol (a/n). 0 ≤ a < n; n ≥ 3 and odd.

The Legendre and Jacobi symbols are indistinguishable exactly when the lower argument is an odd prime, in which case they have the same value.

See algorithm 2.149 in "Handbook of Applied Cryptography" by Alfred J. Menezes et al.

squareRoot :: Integer -> Integer -> Maybe Integer Source #

Modular square root of g modulo a prime p.

If the modulus is found not to be prime, the function will raise a ModulusAssertionError.

This implementation is variable time and should be used with public parameters only.