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).