#include "tomcrypt.h"
#ifdef LTC_MDH
static
int
_dh_groupsize_to_keysize(
int
groupsize)
{
if
(groupsize <= 0) {
return
0;
}
else
if
(groupsize <= 192) {
return
30;
}
else
if
(groupsize <= 256) {
return
40;
}
else
if
(groupsize <= 384) {
return
52;
}
else
if
(groupsize <= 512) {
return
60;
}
else
if
(groupsize <= 768) {
return
67;
}
else
if
(groupsize <= 1024) {
return
77;
}
else
{
return
0;
}
}
int
dh_generate_key(prng_state *prng,
int
wprng, dh_key *key)
{
unsigned
char
*buf;
unsigned
long
keysize;
int
err, max_iterations = LTC_PK_MAX_RETRIES;
LTC_ARGCHK(key != NULL);
LTC_ARGCHK(ltc_mp.name != NULL);
if
((err = prng_is_valid(wprng)) != CRYPT_OK) {
return
err;
}
keysize = _dh_groupsize_to_keysize(mp_unsigned_bin_size(key->prime));
if
(keysize == 0) {
err = CRYPT_INVALID_KEYSIZE;
goto
freemp;
}
buf = XMALLOC(keysize);
if
(buf == NULL) {
err = CRYPT_MEM;
goto
freemp;
}
key->type = PK_PRIVATE;
do
{
if
(prng_descriptor[wprng].read(buf, keysize, prng) != keysize) {
err = CRYPT_ERROR_READPRNG;
goto
freebuf;
}
if
((err = mp_read_unsigned_bin(key->x, buf, keysize)) != CRYPT_OK) {
goto
freebuf;
}
if
((err = mp_exptmod(key->base, key->x, key->prime, key->y)) != CRYPT_OK) {
goto
freebuf;
}
err = dh_check_pubkey(key);
}
while
(err != CRYPT_OK && max_iterations-- > 0);
freebuf:
zeromem(buf, keysize);
XFREE(buf);
freemp:
if
(err != CRYPT_OK) dh_free(key);
return
err;
}
#endif /* LTC_MDH */