aboutsummaryrefslogtreecommitdiffstats
path: root/cipher/elgamal.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--cipher/elgamal.c65
1 files changed, 44 insertions, 21 deletions
diff --git a/cipher/elgamal.c b/cipher/elgamal.c
index 63ec06f57..4252b48d1 100644
--- a/cipher/elgamal.c
+++ b/cipher/elgamal.c
@@ -60,10 +60,10 @@ test_keys( ELG_public_key *pk, ELG_secret_key *sk, unsigned nbits )
mpi_set_bytes( test, nbits, get_random_byte, 0 );
- elg_encrypted( out1_a, out1_b, test, pk );
- elg_decrypted( out2, out1_a, out1_b, sk );
+ elg_encrypt( out1_a, out1_b, test, pk );
+ elg_decrypt( out2, out1_a, out1_b, sk );
if( mpi_cmp( test, out2 ) )
- log_fatal("ElGamal operation: encrypted, decrypted failed\n");
+ log_fatal("ElGamal operation: encrypt, decrypt failed\n");
elg_sign( out1_a, out1_b, test, sk );
if( !elg_verify( out1_a, out1_b, test, pk ) )
@@ -95,9 +95,10 @@ gen_k( MPI p )
if( DBG_CIPHER )
fputc('.', stderr);
mpi_set_bytes( k, nbits, get_random_byte, 1 );
- mpi_set_bit( k, nbits-1 ); /* make sure it's high (really needed?) */
- if( mpi_cmp( k, p_1 ) >= 0 )
- continue; /* is not smaller than (p-1) */
+ if( !(mpi_cmp( k, p_1 ) < 0) ) /* check: k < (p-1) */
+ continue; /* no */
+ if( !(mpi_cmp_ui( k, 0 ) > 0) ) /* check: k > 0 */
+ continue; /* no */
if( mpi_gcd( temp, k, p_1 ) )
break; /* okay, k is relatively prime to (p-1) */
}
@@ -117,17 +118,27 @@ void
elg_generate( ELG_public_key *pk, ELG_secret_key *sk, unsigned nbits )
{
MPI p; /* the prime */
+ MPI p_min1;
MPI g;
MPI x; /* the secret exponent */
MPI y;
-
- p = generate_public_prime( nbits );
- /* FIXME: check wether we shall assert that (p-1)/2 is also prime
- * Schneier votes against it
+ MPI temp;
+
+ p = NULL;
+ p_min1 = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
+ temp = mpi_alloc( (nbits+BITS_PER_MPI_LIMB-1)/BITS_PER_MPI_LIMB );
+ /*do {*/
+ mpi_free(p);
+ /* FIXME!!!! Should generate a strong prime */
+ p = generate_public_prime( nbits );
+ mpi_sub_ui(p_min1, p, 1);
+ /*} while if( mpi_gcd( temp, k, p_1 ) )*/
+
+
+ g = mpi_alloc_set_ui(3); /* fixme: 3 is bad (but better than 2)*/
+ /* select a random number which has these properties:
+ * 0 < x < p-1
*/
- g = mpi_alloc_set_ui(3);
-
- /* select a random number */
x = mpi_alloc_secure( nbits/BITS_PER_MPI_LIMB );
if( DBG_CIPHER )
log_debug("choosing a random x ");
@@ -135,8 +146,7 @@ elg_generate( ELG_public_key *pk, ELG_secret_key *sk, unsigned nbits )
if( DBG_CIPHER )
fputc('.', stderr);
mpi_set_bytes( x, nbits, get_random_byte, 1 ); /* fixme: should be 2 */
- mpi_set_bit( x, nbits-1 ); /* make sure it's high (needed?) */
- } while( mpi_cmp( x, p ) >= 0 ); /* x must be smaller than p */
+ } while( !( mpi_cmp_ui( x, 0 )>0 && mpi_cmp( x, p_min1 )<0 ) );
y = mpi_alloc(nbits/BITS_PER_MPI_LIMB);
mpi_powm( y, g, x, p );
@@ -149,7 +159,6 @@ elg_generate( ELG_public_key *pk, ELG_secret_key *sk, unsigned nbits )
log_mpidump("elg x= ", x );
}
-
/* copy the stuff to the key structures */
pk->p = mpi_copy(p);
pk->g = mpi_copy(g);
@@ -161,6 +170,9 @@ elg_generate( ELG_public_key *pk, ELG_secret_key *sk, unsigned nbits )
/* now we can test our keys (this should never fail!) */
test_keys( pk, sk, nbits - 64 );
+
+ mpi_free( p_min1 );
+ mpi_free( temp );
}
@@ -182,7 +194,7 @@ elg_check_secret_key( ELG_secret_key *sk )
void
-elg_encrypted(MPI a, MPI b, MPI input, ELG_public_key *pkey )
+elg_encrypt(MPI a, MPI b, MPI input, ELG_public_key *pkey )
{
MPI k;
@@ -212,7 +224,7 @@ elg_encrypted(MPI a, MPI b, MPI input, ELG_public_key *pkey )
void
-elg_decrypted(MPI output, MPI a, MPI b, ELG_secret_key *skey )
+elg_decrypt(MPI output, MPI a, MPI b, ELG_secret_key *skey )
{
MPI t1 = mpi_alloc_secure( mpi_get_nlimbs( skey->p ) );
@@ -288,13 +300,24 @@ int
elg_verify(MPI a, MPI b, MPI input, ELG_public_key *pkey )
{
int rc;
- MPI t1 = mpi_alloc( mpi_get_nlimbs(a) );
- MPI t2 = mpi_alloc( mpi_get_nlimbs(a) );
-
+ MPI t1;
+ MPI t2;
+
+ if( !(mpi_cmp_ui( a, 0 ) > 0 && mpi_cmp( a, pkey->p ) < 0) )
+ return 0; /* assertion 0 < a < p failed */
+
+ t1 = mpi_alloc( mpi_get_nlimbs(a) );
+ t2 = mpi_alloc( mpi_get_nlimbs(a) );
+ /* t1 = (y^a mod p) * (a^b mod p) mod p
+ * fixme: should be calculated by a call which evalutes
+ * t1 = y^a * a^b mod p
+ * direct.
+ */
mpi_powm( t1, pkey->y, a, pkey->p );
mpi_powm( t2, a, b, pkey->p );
mpi_mulm( t1, t1, t2, pkey->p );
+ /* t2 = g ^ input mod p */
mpi_powm( t2, pkey->g, input, pkey->p );
rc = !mpi_cmp( t1, t2 );