HORIZON HASKELLDocslts/ghc-10.0.x8174fa42026-10-11Search names, modules, packages, or :: a typeCtrl K

GHC 10.0.0.20260917 · lts/ghc-10.0.x · 8174fa4 · 2026-10-11

Modulecrypton-2.1.7Haskell2010

Crypto.PubKey.ElGamal

ElGamal encryption and signature over the multiplicative group of integers modulo a prime, reusing the parameters of Crypto.PubKey.DH.

These are raw primitives, not a scheme. The encryption here is textbook ElGamal: it applies no padding, so it is malleable by construction -- multiplying a ciphertext's second component by t multiplies the plaintext by t -- and it is not IND-CCA secure. A message is an Integer below the modulus rather than a byte string, and nothing here maps one to the other. Use it to build a scheme that adds those, or prefer Crypto.PubKey.RSA.OAEP or Crypto.PubKey.ECIES where a scheme is what is wanted.

The signature primitive is likewise raw, and an ephemeral value must never be reused between signatures: two signatures under the same k reveal the private key.

What is kept from the clock, and what is not

Every exponentiation with a secret exponent is expSafe. Decryption inverts the shared secret by Fermat's little theorem rather than by the extended Euclidean algorithm, whose steps follow the bits it is given. sign cannot do that -- k is inverted modulo p-1, which is even -- so it blinds instead: the algorithm is handed k times a fresh random unit, and the blinder is divided out afterwards. signWith, having no randomness of its own, hands it k.

What is left is the Integer arithmetic around all of that, whose cost follows the size of the numbers. See Crypto.PubKey.DSA for the same note at more length.

  • 6 types
  • 8 values
  • Packagecrypton-2.1.7
  • Exports14
  • LanguageHaskell2010
  • LicenceBSD-3-Clause AND MIT AND ISC
  • SourceElGamal.hs
datadata Params
#

Represent Diffie Hellman parameters namely P (prime), and G (generator).

Instances5Eq, Data, Read, Show, NFData
  • Eq ParamsDefined in crypton-2.1.7 · Crypto.PubKey.DH
  • Data ParamsDefined in crypton-2.1.7 · Crypto.PubKey.DH
  • Read ParamsDefined in crypton-2.1.7 · Crypto.PubKey.DH
  • Show ParamsDefined in crypton-2.1.7 · Crypto.PubKey.DH
  • NFData ParamsDefined in crypton-2.1.7 · Crypto.PubKey.DH
newtypenewtype PublicNumber
#

Represent Diffie Hellman public number Y.

Instances8Enum, Eq, Num, Ord, Read, Real, …
newtypenewtype PrivateNumber
#

Represent Diffie Hellman private number X.

Instances9Enum, Eq, Num, Ord, Read, Real, …

Generation

2 declarations

Encryption and decryption with no scheme

3 declarations

encrypt with a specified ephemeral key

The ephemeral key must lie in [1, p-2] and must never be reused: zero would leave the message unmasked, and a repeat lets anyone who learns one plaintext recover the other. A message must be below the modulus, or decryption would return it reduced.

Signature primitives

2 declarations
valuesignWith
  1. :: (ByteArrayAccess msg, HashAlgorithm hash)
  2. => Integer

    ephemeral value k, in [1, p-2] and coprime with p-1

  3. -> Params

    DH params (p,g)

  4. -> PrivateNumber

    DH private key

  5. -> hash

    collision resistant hash algorithm

  6. -> msg

    message to sign

  7. -> Maybe Signature
#

sign a message with an explicit ephemeral value

k has to lie in [1, p-2] and be coprime with p-1. Nothing says the value handed in cannot be used: either it fails one of those two conditions, or it is one of the few that produce a second component of zero. Either way the answer is to draw another k, which is what sign does.

k is an ephemeral private key. It has to be drawn uniformly at random, kept secret, and used for one signature only: the private number follows from a signature and its k, and equally from two signatures made with the same k. None of that is visible to this function, which is why it takes k from the caller and checks only what it can.

Verification primitives

1 declaration