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