Provided by: libbobcat-dev_6.07.01-2_amd64 

NAME
FBB::DiffieHellman - Diffie-Hellman PKI, computing shared keys
SYNOPSIS
#include <bobcat/diffiehellman>
Linking option: -lbobcat -lcrypto
DESCRIPTION
The class FBB::DiffieHellman computes shared keys (shared secrets) using the Diffie-Hellman (1976)
algorithm. The Diffie-Hellman algorithm uses public and private information, providing a public key
infrastructure (PKI). The public information consists of a prime (e.g., a prime number consisting of 1024
bits), a generator (for which the value 5 is commonly used), and (using ** to represent the power
operator on integral values) the value generator ** private mod prime, where private is a randomly
selected large number, which is the private information.
The Diffie-Hellman algorithm is commonly used to compute a shared key which can be used to encrypt
information sent between two parties. One party, which in this man-page is called the initiator, computes
the prime and defines the generator. The prime is computed by FBB::DiffieHellman’s first constructor,
while the generator is passed to this constructor as one of its arguments. For the generator the value 5
is often used.
Next the initiator passes its public information, consisting of the prime, the generator, and the value
pow(generator, private) mod prime to the other party, which in this man-page is called the peer. The
public information is written in binairy, big-endian form to file using the member save. The initiator
may optionally save the private information to a separate file as well.
The peer thereupon receives the initiator’s public information. The initialor’s public information is
read by a FBB::DiffieHellman constructor either expecting the name of a file or a std::istream
containining the initiator’s public information.
Having obtained the prime and generator, the peer’s public (and, optionally, private information) is
saved by also calling save. This results, among other things, in the value pow(generator, private) mod
prime, but now using the peer’s private information.
At this point the peer is already able to compute the shared key. The key is returned by calling the key
member, which returns the shared key as a series of bytes stored in a std::string.
Before the initiator can compute the shared key the peer’s generator ** private mod prime value must be
available. The peer sends the saved public data to the initiator. The initiator then passes the peer’s
public data either by file name or by std::istream to the key member, returning the shared key.
Perfect Forward Secrecy and Ephemeral Diffie Hellman
If the initiator and peer decide not to save their private information Perfect Forward Secrecy and
Ephemeral Diffie Hellman may be obtained. Here, the procedure is applied as follows:
o Initiator and peer have agreed upon and securely exchanged a long-lasting common secret, which may
be used in combination with, e.g., symmetric encryption methods.
o Applying the abovementioned procedure, the private information is never saved on file.
Consequently, the shared key, once computed, cannot be reconstructed anymore.
o The value generator ** private mod prime is not sent to either peer or initiator `in the clear’,
but encrypted using the long-lasting common secret. As the current implementation saves all public
information on file, it’s probably easiest to encrypt the file containing the public information.
o The recipients, having received the other party’s encrypted public information, decrypt it using
the long-lasting shared secret and compute the the shared key.
o As the secret information is not kept, the shared key cannot be reconstructed, while a
Man-In-The-Middle attack is prevented by only exchanging encrypted public information.
o The shared key can now be used to encrypt a communication session
Document encryption using Diffie Hellman
As with PKI in general, the Diffie Hellman key exchange method itself is not normally used for encrypting
documents. Instead, it is usually used to exchange the key that is used for symmetric encryption methods
like 3DES and CBC. These symmetric encryption methods are available through, e.g., Bobcats’ EncryptBuf,
DecryptBuf, and ISymCryptStream classes.
NAMESPACE
FBB
All constructors, members, operators and manipulators, mentioned in this man-page, are defined in the
namespace FBB.
INHERITS FROM
-
CONSTRUCTORS
o DiffieHellman(size_t primeLength = 1024, size_t generator = 5, bool progress = false):
This constructor computes a prime of the specified length, and initializes the public information
with the indicated generator. The prime length must at least be 1024 or an FBB::Exception is
thrown. If progress is true, the progress of the prime construction process is shown to std::cout
by a series of dots, minuses and plusses. Generating a suitable prime may fail, resulting in an
FBB::Exception being thrown. Unless the generator is specified as 2 or 5 the warning cannot check
the validity of generator ... is inserted into the mstream(3bobcat)’s wmsg object. A warning is
also inserted if the provided generator is not a generator for the computed prime.
This constructor should be called by the initiator to start the Diffie-Hellman shared key
computation procedure.
o DiffieHellman(FBB::BigInt const &prime, size_t generator = 5, bool progress = false):
Alternatively, this constructor can be used by the initiator after separately having constructed
the prime to use. The prime must at least be 1024 bits long.
o DiffieHellman(std::string const &initiatorPublicFileName):
This constructor should be called by the peer, after having received the initiator’s public info.
It makes the initiator’s public information available to the peer, after which the peer’s public
and private information can be computed.
o DiffieHellman(std::stream &initiatorPublicStream):
This constructor acts like the previous constructor, expecting a std::istream rather than a file
name. It should be called by the peer, after having received the initiator’s public info. It makes
the initiator’s public information available to the peer, after which the peer’s public and
private information can be computed.
o DiffieHellman(std::string const &initiatorPublicFileName, std::string const
&initiatorPrivateFileName):
Unless the initiator’s DiffieHellman object is still available, this constructor should again be
called by the initiator, to load the initiator’s public and private data.
o DiffieHellman(std::stream &initiatorPublicStream, std::stream &initiatorPrivateStream):
This constructor acts like the previous constructor, expecting std::istreams rather than file
names. It should be called by the initiator, to load the initiator’s public and private info.
Copy and move constructors (and assignment operators) are available.
MEMBER FUNCTIONS
o std::string key() const:
This member should be called by the peer. It returns the shared key. If the key cannot be
computed, or if the key is not resistant to the small group attack (i.e., if the key equals 1, or
is at least equal to the public prime value, or if key ** ((prime - 1) / 2) mod prime != 1), then
an FBB::Exception is thrown.
o std::string key(std::string const &peerPublicFileName) const:
This member should be called by the initiator. It skips the data referring to the prime and
generator found in peerPublicFileName and then reads the peer’s generator ** private mod prime
value. If this value cannot be read or if the key is not resistant to the small group attack (cf.
the description of the previous key member) then an FBB::Exception is thrown. It returns the
shared key.
o std::string key(std::istream const &peerPublicStream) const:
This member should be called by the initiator. It acts like the previous key member, reading the
peer’s generator ** private mod prime value from peerPublicStream. It returns the shared key.
o void save(std::string const &basename):
This member should be called by the initiator. It saves the public information on the file
’basename’.pub. The information is written in binary, big-endian format, using the following
organization:
- the size of the prime in bytes;
- the prime’s bytes;
- the size of the generator in bytes;
- the generator’s bytes;
- the size of the public info (generator ** private mod prime) in bytes;
- the public info’s bytes.
In addition the private information is written to the file ’basename’.sec in binary, big-endian
format, using the following organization:
- the size of the private information in bytes;
- the private information bytes.
EXAMPLE
When called without arguments, the example program generates Diffie-Hellman parameters writing the
initiator’s public and private information to, respectively, init.pub and init.sec.
When called with one argument, init.pub is read, and the peer’s public and private information is written
to, respectively, peer.pub and peer.sec. Next, the (peer’s) shared key is written to peerkey.
When called with two arguments, init.pub and init.sec are read, as well as the peer’s public information
(on the file peer.pub). Next, the (initiator’s) shared key is written to initkey.
The files peerkey and initkey should be identical.
#include <fstream>
#include <iostream>
#include <bobcat/exception>
#include <bobcat/diffiehellman>
using namespace FBB;
using namespace std;
int main(int argc, char **argv)
try
{
if (argc == 1)
{
cout << "1: create prime and generator, write to ’params’\n"
"2: create secret and public parts, arg 2: 0 or 1,\n"
" write secret and public parts to <arg 2>.sec and "
"<arg 2>.pub\n"
"3: create common key arg 2: 0 or 1,\n"
" 0: write common0 using 0.pub, 0.sec and 1.pub\n"
" 1: write common1 using 1.pub, 1.sec and 0.pub\n"
;
return 0;
}
switch (*argv[1]) // using generator == 5
{
case ’1’:
{
ofstream out = Exception::factory<ofstream>("params");
out << hex << DiffieHellman::prime(1024, true, true) << ’\n’;
}
break;
case ’2’:
{
char *nr = argv[2];
if (nr == 0 || "01"s.find(*nr) == string::npos)
throw Exception{} << "mode ’2’ needs 0 or 1 as 2nd argument";
ifstream in = Exception::factory<ifstream>("params");
BigInt prime;
in >> hex >> prime;
DiffieHellman dh{ prime };
dh.save(nr);
}
break;
case ’3’:
{
char *nr = argv[2];
if (nr == 0 || "01"s.find(*nr) == string::npos)
throw Exception{} << "mode ’3’ needs 0 or 1 as 2nd argument";
DiffieHellman dh{ nr + ".pub"s, nr + ".sec"s };
cout << "common key computed by " << nr << ":\n" <<
hex << dh.key((nr[0] == ’0’ ? ’1’ : ’0’) + ".pub"s) << ’\n’;
}
break;
default:
throw Exception{} << "undefined action `" << *argv[1] <<’\’’;
}
}
catch (std::exception const &exc)
{
std::cout << exc.what() << ’\n’;
}
FILES
bobcat/diffiehellman - defines the class interface
SEE ALSO
bobcat(7), bigint(3bobcat), ecdh(3bobcat), isymcryptstream(3bobcat), osymcryptstream(3bobcat)
BUGS
None Reported.
BOBCAT PROJECT FILES
o https://fbb-git.gitlab.io/bobcat/: gitlab project page;
Debian Bobcat project files:
o libbobcat6: debian package containing the shared library, changelog and copyright note;
o libbobcat-dev: debian package containing the static library, headers, manual pages, and developer
info;
BOBCAT
Bobcat is an acronym of `Brokken’s Own Base Classes And Templates’.
COPYRIGHT
This is free software, distributed under the terms of the GNU General Public License (GPL).
AUTHOR
Frank B. Brokken (f.b.brokken@rug.nl).
libbobcat-dev_6.07.01 2005-2025 FBB::DiffieHellman(3bobcat)