It took me a while to figure out how to do this too.
The key is that both DH objects need to be initialized
with the same Generator and Modulus, here is some
sample code, which you should be able to extrapolate
to a two machine scenario:
AutoSeededRandomPool asrp;
DH dh(dynamic_cast<RandomNumberGenerator&>(asrp),
128);
Integer iPrime, iGenerator;
if (dh.AccessGroupParameters().GetValue("Modulus",
iPrime))
{
if
(dh.AccessGroupParameters().GetValue("SubgroupGenerator",
iGenerator))
{
// important line is here
DH dhB(iPrime, iGenerator);
SecByteBlock privA(dh.PrivateKeyLength());
SecByteBlock pubA(dh.PublicKeyLength());
SecByteBlock privB(dhB.PrivateKeyLength());
SecByteBlock pubB(dhB.PublicKeyLength());
SecByteBlock val1(dh.AgreedValueLength());
SecByteBlock val2(dhB.AgreedValueLength());
dh.GenerateKeyPair(rndPoolA, privA, pubA);
dhB.GenerateKeyPair(rndPoolB, privB, pubB);
if (!dh.Agree(val1, privA, pubB))
{
cout << "First agreement failed" << endl;
return 0;
}
if (!dhB.Agree(val2, privB, pubA))
{
cout << "Second agreement failed" << endl;
return 0;
}
}
--- James Vanns <[EMAIL PROTECTED]> wrote:
> I am having trouble getting to processes (running on
> different machines)
> to agree on a value using their Diffie-Hellman keys.
>
> Do the different DH objects need the same
> RandomNumber objects? I send
> their public keys over the network and try to
> Agree() them with the
> opposite private key (as in the crypto++ example).
> However, this always
> fails. The only thing I can see that's different is
> that I am using a
> different PRNG object (obviously, as they're on
> different machines!).
>
> Also can you explain what this does (well, I know
> what memset does), and
> more importantly why the specific values:
>
> Line 198 in validat2.cpp
>
> memset(val1.begin(), 0x10, val1.size());
> memset(val2.begin(), 0x11, val2.size());
>
> The code I'm using (or a snippet of as I don't want
> to swamp the list)
> is:
>
> string data;
> // Setup the pseudo random number generator
> AutoSeededRandomPool *arng = new
> AutoSeededRandomPool;
> RandomNumberGenerator &rng =
> *dynamic_cast<RandomNumberGenerator *>
> (arng);
>
> // declare a diffie-hellman object
> DH dh (rng, 128);
>
> // declare the local validation and public-private
> key pair
> SecByteBlock local_validate (dh.AgreedValueLength
> ());
> SecByteBlock local_public_key (dh.PublicKeyLength
> ());
> SecByteBlock local_private_key (dh.PrivateKeyLength
> ());
>
> // clear the validation object
> fill (local_validate.begin (), local_validate.end
> (), 0x11);
>
> // generate the public-private key pair
> dh.GenerateKeyPair (rng, local_private_key,
> local_public_key);
>
> delete arng;
>
> // encode the local public key to a hexed-string
> StringSource (local_public_key, true, new HexEncoder
> (new StringSink
> (data)));
> cout << "Local public key: " << data << endl;
>
> // connect to the server
> JClientSocket c ("eeyore", 50000);
>
> // send the local public key
> c << data;
> // clear the string
> data.clear ();
> // receive the server's public key
> c >> data;
>
> cout << "Foreign public key: " << data << endl;
>
> // decode the hexed-string to the foreign public key
> SecByteBlock foreign_public_key (dh.PublicKeyLength
> ());
> StringSource (foreign_public_key, true, new
> HexDecoder (new StringSink
> (data)));
>
> // clear the string
> data.clear ();
>
> // agreement method with the local private and the
> foreign public key
> if (!dh.Agree (local_validate, local_private_key,
> foreign_public_key)) {
> cout << "Key agreement failed." << endl;
> return 1;
> }
>
> The server has similar code (this is the client)
>
> Regards
>
> Jim
>
> --
> James Vanns BSc (Hons) MCP
> Linux Systems Administrator
> Senior Software Engineer (Linux / C & C++)
> Canterbury Christ Church University College
> Public Key:
>
http://pgp.mit.edu:11371/pks/lookup?op=get&search=0x24045370
>