HAVEGE Programming Interface

HAVEGE provides two methods for generating high-quality random numbers, depending upon your needs.

General usage

int ndrand() : high-performance high-quality random numbers for current usage.

ndrand() outperforms usual rand() and random() generators. ndrand() has been optimized for distribution quality and throughput. The internal state of data variables is not, intentionally, completely hidden from the outside world.

Therefore, ndrand() should not be used for cryptographic applications.

Cryptographic usage

int crypto_ndrand() : high-performance high-quality random numbers for cryptography.

cryptondrand() produces several megabytes of unpredictable random numbers per cycle.

Each 1 Mbyte sequence of cryptondrand() results is the exclusive-OR of the previous sequence with 32 consecutive 1 Mbyte sequences of a ndrand()-like function results. Each of these 33 individual sequences are already high quality random number sequences. Collection of a 1 Mbyte sequence spans over several tens of operating system interrupts. The 31 intermediate sequences are hidden from the outside world. Hiding a single intermediate sequence is sufficient to ensure irreproducibility.

Note for Linux kernel module:

/dev/hrandom0 is the device file abstraction of ndrand ().
/dev/hrandom1
is the device file abstraction of crypto_ndrand ().
 

Instructions for integrating HAVEGE

One could use the following interfaces for integrating HAVEGE into a C or C++ project:

  • Static and dynamic libraries for Linux and Windows systems;
  • Kernel module for Linux systems.

Below, we describe simple examples that could be used as a base for your own code. Some headers are omitted for a comprehension purpose. You can get the complete source code in the download section.

Static Library (Unix/Linux, Cygwin and Darwin)

Source code: st_test.c

#include <stdio.h>
#include <havege.h>  /* HAVEGE header file */ 

void
main (int argc, char *argv[])
{
     int random;
     random = ndrand ();        /* high-throughput HAVEGE random number generator */
     random = crypto_ndrand (); /* HAVEGE rng tuned for cryptography purpose */
}

Compilation and linkage

$ gcc -c st_test.c
$ gcc -static -o st_test st_test.o -L/install_directory/lib -lhavege

"install_directory" is your HAVEGE installation directory. You need to specify the 'static' flag to gcc, else your program will likely be linked against the dynamic version of HAVEGE library.

Dynamic Library (Unix/Linux)

This example shows the runtime loading of libhavege through POSIX dlopen API.

Cygwin and Darwin users, please refer to the appropriate documentation for runtime loading of DLLs and modules through POSIX dlopen/dlclose/dlsym API or Windows LoadLibrary/FreeLibrary/GetProcAddress API or GNU libltdl.

Source code: dl_test.c (only the usage ndrand() is described)

#include <stdio.h>
#include <dlfcn.h> /* define dlopen() API */ 

#define SONAME "libhavege.so"
void
main (int argc, char *argv[])
{
     int (*ndrand)(void);
     void *handle;

     /* 1. load the shared library */
     handle = dlopen (SONAME, RTLD_LAZY);
     
     if (!handle) {
         fprintf (stderr, "%s", dlerror()); exit(1);
     }

     /* 2. get HAVEGE symbols */
     ndrand = dlsym(handle, "ndrand");
     if (dlerror() != NULL) {
       fprintf (stderr, "%s", dlerror()); exit(1);
     }

     /* 3. generate random numbers */
     random = ndrand ();

     /* 4. unload shared library */
     dlclose(handle);
}

Compilation and linkage

$ gcc -c dl_test.c
$ gcc -o dl_test dl_test.o -ldl -L/install_directory/lib -lhavege

"install_directory" is your HAVEGE installation directory. libdl (-ldl) is the dynamic linking library.

Running the program

In order to run 'dl_test', you must set up your LD_LIBRARY_PATH using the following syntax; depending on your shell version:

$ setenv LD_LIBRARY_PATH $(LD_LIBRARY_PATH):install_directory/lib

$ export LD_LIBRARY_PATH=$(LD_LIBRARY_PATH):install_directory/lib

A nice tutorial describing how to build and use static and dynamic libraries for Unix/Linux systems can be found at: http://users.actcom.co.il/~choo/lupg/tutorials/libraries/unix-c-libraries.html

Linux module

Source code: hrandom_test.c (only hrandom0 is described)

#include <stdio.h>
#include <sys/stat.h>
#include <sys/types.h>
#include <stdlib.h>
#include <fcntl.h>
#include <unistd.h>
#include <errno.h>

/* assuming this is the path to hrandom0 */
#define HRANDOM0 "/dev/hrandom0"
#define _32MB 32000*1024
static int pool [_32MB];

int
main (int argc, char *argv[])
{
    int fd, err;
    /* open hrandom in read-only mode */
    fd = open (HRANDOM0, O_RDONLY);
    if (fd == ENODEV) {
       fprintf (stderr, "cannot find: %s.\n", HRANDOM0);
       exit (1);
    }

    /* get random data from HRANDOM0 */
    err = read (fd, pool, _32MB);
    if (err != _32MB) {
      fprintf (stderr, "cannot read %d bytes from %s.\n",
           _32MB, HRANDOM0);
      exit (1) ;
    }
}

Compilation and linkage

$ gcc -c hrandom_test.c
$ gcc -o hrandom_test hrandom_test.o