diff --git a/cipher/ChangeLog b/cipher/ChangeLog index b1a8cb0d0..3448f7568 100644 --- a/cipher/ChangeLog +++ b/cipher/ChangeLog @@ -1,3 +1,8 @@ +2006-04-20 David Shaw + + * dsa.c (dsa2_generate): New function to generate a DSA key with a + variable sized q. + 2006-04-19 David Shaw * sha256.c (sha224_get_info, sha224_init): New init functions for diff --git a/cipher/dsa.c b/cipher/dsa.c index 967243e83..447cea941 100644 --- a/cipher/dsa.c +++ b/cipher/dsa.c @@ -1,5 +1,5 @@ /* dsa.c - DSA signature algorithm - * Copyright (C) 1998, 1999, 2000 Free Software Foundation, Inc. + * Copyright (C) 1998, 1999, 2000, 2003, 2006 Free Software Foundation, Inc. * * This file is part of GnuPG. * @@ -49,7 +49,8 @@ typedef struct { static MPI gen_k( MPI q ); static void test_keys( DSA_secret_key *sk, unsigned qbits ); static int check_secret_key( DSA_secret_key *sk ); -static void generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors ); +static void generate( DSA_secret_key *sk, unsigned nbits, unsigned qbits, + MPI **ret_factors ); static void sign(MPI r, MPI s, MPI input, DSA_secret_key *skey); static int verify(MPI r, MPI s, MPI input, DSA_public_key *pkey); @@ -168,20 +169,20 @@ test_keys( DSA_secret_key *sk, unsigned qbits ) * and an array with the n-1 factors of (p-1) */ static void -generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors ) +generate( DSA_secret_key *sk, unsigned nbits, unsigned qbits, + MPI **ret_factors ) { MPI p; /* the prime */ - MPI q; /* the 160 bit prime factor */ + MPI q; /* the prime factor */ MPI g; /* the generator */ MPI y; /* g^x mod p */ MPI x; /* the secret exponent */ MPI h, e; /* helper */ - unsigned qbits; byte *rndbuf; assert( nbits >= 512 && nbits <= 1024 ); + assert( qbits >= 160 ); - qbits = 160; p = generate_elg_prime( 1, nbits, qbits, NULL, ret_factors ); /* get q out of factors */ q = mpi_copy((*ret_factors)[0]); @@ -207,7 +208,6 @@ generate( DSA_secret_key *sk, unsigned nbits, MPI **ret_factors ) * is the secret part. */ if( DBG_CIPHER ) log_debug("choosing a random x "); - assert( qbits >= 160 ); x = mpi_alloc_secure( mpi_get_nlimbs(q) ); mpi_sub_ui( h, q, 1 ); /* put q-1 into h */ rndbuf = NULL; @@ -364,15 +364,22 @@ verify(MPI r, MPI s, MPI hash, DSA_public_key *pkey ) ************** interface ****************** *********************************************/ +/* DSA2 has a variable-sized q, which adds an extra parameter to the + pubkey generation. I'm doing this as a different function as it is + only called from one place and is thus cleaner than revamping the + pubkey_generate interface to carry an extra parameter which would + be meaningless for all algorithms other than DSA. */ + int -dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) +dsa2_generate( int algo, unsigned nbits, unsigned qbits, + MPI *skey, MPI **retfactors ) { DSA_secret_key sk; if( algo != PUBKEY_ALGO_DSA ) return G10ERR_PUBKEY_ALGO; - generate( &sk, nbits, retfactors ); + generate( &sk, nbits, qbits, retfactors ); skey[0] = sk.p; skey[1] = sk.q; skey[2] = sk.g; @@ -382,6 +389,13 @@ dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) } +int +dsa_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ) +{ + return dsa2_generate(algo,nbits,160,skey,retfactors); +} + + int dsa_check_secret_key( int algo, MPI *skey ) { diff --git a/include/ChangeLog b/include/ChangeLog index ecd354fb1..eaee0ddd3 100644 --- a/include/ChangeLog +++ b/include/ChangeLog @@ -1,3 +1,7 @@ +2006-04-20 David Shaw + + * cipher.h: Add dsa2_generate(); + 2006-04-19 David Shaw * cipher.h: Add SHA-224. diff --git a/include/cipher.h b/include/cipher.h index 5649f0fce..5b531ccd2 100644 --- a/include/cipher.h +++ b/include/cipher.h @@ -184,6 +184,8 @@ int pubkey_get_nsig( int algo ); int pubkey_get_nenc( int algo ); unsigned pubkey_nbits( int algo, MPI *pkey ); int pubkey_generate( int algo, unsigned nbits, MPI *skey, MPI **retfactors ); +int dsa2_generate( int algo, unsigned nbits, unsigned qbits, + MPI *skey, MPI **retfactors ); int pubkey_check_secret_key( int algo, MPI *skey ); int pubkey_encrypt( int algo, MPI *resarr, MPI data, MPI *pkey ); int pubkey_decrypt( int algo, MPI *result, MPI *data, MPI *skey );