Provided by: libbobcat-dev_6.04.00-1ubuntu3_amd64 bug

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 "../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;

       o      bobcat_6.04.00-x.dsc: detached signature;

       o      bobcat_6.04.00-x.tar.gz: source archive;

       o      bobcat_6.04.00-x_i386.changes: change log;

       o      libbobcat1_6.04.00-x_*.deb: debian package containing the libraries;

       o      libbobcat1-dev_6.04.00-x_*.deb: debian package containing the libraries, headers and manual pages;

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.04.00                               2005-2023                        FBB::DiffieHellman(3bobcat)