diff options
Diffstat (limited to 'cipher/elgamal.c')
-rw-r--r-- | cipher/elgamal.c | 63 |
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); } |