How secure is libgcrypt's Elgamal implementation of encryption (how different it is from textbook Elgamal), and how can I tweak padding and other preprocessing actions?

For example, I know that usign RSA I can use this S-expression to the function gcry_pk_encrypt:

  (flags pkcs1)
  (value BLOCK))

And I can use oaep or pss instead of "pkcs1". But what do I use with Elgamal? I can encrypt and decrypt using Elgamal, using

  (value BLOCK))

but then I have no idea if raw Elgamal was used or if it's actually DHAES or some padded-Elgamal variant.

What is the proper way to use Elgamal in libgcrypt, and what options can I pass? Or would it be better to switch to RSA?

edit: I think that what I wanted to ask is "what is the intended use of Elgamal as implemented in libgcrypt?"

  • 2
    $\begingroup$ Unless you have a specific need for Elgamal, I'd suggest using RSA. $\endgroup$
    – mikeazo
    Jul 23, 2012 at 1:57

1 Answer 1


I took the world's shortest look at the code, so please don't hold me to any of this. But it seems that the implementation is textbook. You provide a block of data, it gets encoded to an integer in the range 1,...,p-1 and then encrypted using standard Elgamal without padding.

There's does not seem** to be an encoding to the subgroup of quadratic residues, and this implementation is /not/ CCA secure. These probably aren't going to kill you if you're encrypting a large random key, but they're definitely not the right way to encrypt.

Rather than hacking Elgamal, I'd say you're better off encrypting with RSA-OAEP.

In the long term, libgcrypt should implement a secure KEM/DEM for Elgamal encryption. DHAES would be a great example. Alternatively the authors should give a proper (non-textbook) Elgamal implementation with a group encoding and protections against adaptive-chosen ciphertext attacks.

(Elgamal seems to be the forgotten primitive. pycrypto has the exact same problems. Nobody loves Elgamal, which is too bad because it's a great encryption scheme.)

** A footnote: I didn't look deeply into the encoding function (below), so I admit I could be wrong about this point. But I don't see anything obvious. Here's the code:

init_encoding_ctx (&ctx, PUBKEY_OP_ENCRYPT, gcry_pk_get_nbits (s_pkey)); rc = sexp_data_to_mpi (s_data, &data, &ctx);


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.