aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--cipher/elgamal.c63
1 files changed, 49 insertions, 14 deletions
diff --git a/cipher/elgamal.c b/cipher/elgamal.c
index 5143ecc8c..2ec52179a 100644
--- a/cipher/elgamal.c
+++ b/cipher/elgamal.c
@@ -31,6 +31,11 @@
#include "cipher.h"
#include "elgamal.h"
+/* Blinding is used to mitigate side-channel attacks. You may undef
+ this to speed up the operation in case the system is secured
+ against physical and network mounted side-channel attacks. */
+#define USE_BLINDING 1
+
typedef struct {
MPI p; /* prime */
MPI g; /* group generator */
@@ -372,25 +377,55 @@ do_encrypt(MPI a, MPI b, MPI input, ELG_public_key *pkey )
static void
decrypt(MPI output, MPI a, MPI b, ELG_secret_key *skey )
{
- MPI t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
+ MPI t1, t2, r;
+ unsigned int nbits = mpi_get_nbits (skey->p);
+
+ mpi_normalize (a);
+ mpi_normalize (b);
+
+ t1 = mpi_alloc_secure (mpi_nlimb_hint_from_nbits (nbits));
+#ifdef USE_BLINDING
+
+ t2 = mpi_alloc_secure (mpi_nlimb_hint_from_nbits (nbits));
+ r = mpi_alloc (mpi_nlimb_hint_from_nbits (nbits));
+
+ /* We need a random number of about the prime size. The random
+ number merely needs to be unpredictable; thus we use level 0. */
+ randomize_mpi (r, nbits, 0);
+
+ /* t1 = r^x mod p */
+ mpi_powm (t1, r, skey->x, skey->p);
+ /* t2 = (a * r)^-x mod p */
+ mpi_mulm (t2, a, r, skey->p);
+ mpi_powm (t2, t2, skey->x, skey->p);
+ mpi_invm (t2, t2, skey->p);
+ /* t1 = (t1 * t2) mod p*/
+ mpi_mulm (t1, t1, t2, skey->p);
- mpi_normalize (a);
- mpi_normalize (b);
+ mpi_free (r);
+ mpi_free (t2);
+
+#else /*!USE_BLINDING*/
+
+ /* output = b/(a^x) mod p */
+ mpi_powm (t1, a, skey->x, skey->p);
+ mpi_invm (t1, t1, skey->p);
+
+#endif /*!USE_BLINDING*/
+
+ mpi_mulm (output, b, t1, skey->p);
- /* output = b/(a^x) mod p */
- mpi_powm( t1, a, skey->x, skey->p );
- mpi_invm( t1, t1, skey->p );
- mpi_mulm( output, b, t1, skey->p );
#if 0
- if( DBG_CIPHER ) {
- log_mpidump("elg decrypted x= ", skey->x);
- log_mpidump("elg decrypted p= ", skey->p);
- log_mpidump("elg decrypted a= ", a);
- log_mpidump("elg decrypted b= ", b);
- log_mpidump("elg decrypted M= ", output);
+ if (DBG_CIPHER)
+ {
+ log_mpidump("elg decrypted x= ", skey->x);
+ log_mpidump("elg decrypted p= ", skey->p);
+ log_mpidump("elg decrypted a= ", a);
+ log_mpidump("elg decrypted b= ", b);
+ log_mpidump("elg decrypted M= ", output);
}
#endif
- mpi_free(t1);
+ mpi_free (t1);
}