This topic contains 10 replies, has 4 voices, and was last updated by  redneonglow 10 months ago.

Viewing 11 posts - 1 through 11 (of 11 total)
  • Author
  • #1993


    Hello all,

    I have written a library encapsulating operations for TrueRNG devices, and a binary pgm which is only a shell interface for that library.
    You may download the package at

    Please notice that the testing was far from exhaustive. Comments are welcome.



    #1994 Staff

    This is great, thanks Denis!



    Thank you for your work. I’m trying to test your library but without succes. I know some c++ but lack skills in compiling and linking. I couldn’t successfully build a simple program dynamically or statically linking.
    I’m trying with gcc, under Ubuntu.
    Here is the code main.cpp:

    #include <cstdlib>
    #include "truerng.h"
    #include <iostream>
    using namespace std;
    int main(int argc, char** argv) {
        unsigned int nb_bytes =10;
        unsigned char buf[(nb_bytes)];
        int rc;
        //rc = truerng(buf, sizeof(buf));
        rc = truerng_bytes(TRUERNG_PATH_DEFAULT, TRUERNG_ID_ANY, TRUERNG_ID_ANY, TRUERNG_SERIAL_ANY, buf, sizeof(buf));
       for (int i=0;i<nb_bytes;i++) cout << buf[i];
        return 0;

    Trying to link statically I get:

    g++ -Wl,-static libtruerng.a main.o -o trng 
    /usr/bin/ld: cannot find -lgcc_s
    /usr/bin/ld: cannot find -lgcc_s
    collect2: error: ld returned 1 exit status

    Trying to link dynamically I get:

    g++  -ltruerng main.cpp -o trng 
    main.cpp: In function ‘int main(int, char**)’:
    main.cpp:28:114: warning: deprecated conversion from string constant to ‘char*’ [-Wwrite-strings]
        rc = truerng_bytes(TRUERNG_PATH_DEFAULT, TRUERNG_ID_ANY, TRUERNG_ID_ANY, TRUERNG_SERIAL_ANY, buf, sizeof(buf));
    /tmp/ccRtZRGs.o: In function 
    main.cpp:(.text+0xaf): undefined reference to 'truerng_bytes(char*, unsigned short, unsigned short, char*, unsigned char*, unsigned long)'
    collect2: error: ld returned 1 exit status

    All the files (truerng.h, main.cpp, libtruerng.a,, are in the same folder.

    I tried to understand the compiling and linking of the binary pgm “truerng” but it seems too complicated for my skills. Is there a simple way to compile and link my example, without using makefile and libtool?


    • This reply was modified 2 years, 1 month ago by  ekinox777.
    • This reply was modified 2 years, 1 month ago by  ekinox777.
    • This reply was modified 2 years, 1 month ago by  ekinox777.


    Hello Mihai,

    Short answer (long answer below):

    0/ I assume you have built the package with libudev. If not, please look at the configure output transcript and
    replace below “-ludev” with the flags found by “configure”.

    1/ in your file “main.cpp”, replace
    #include “truerng.h”

    // tell the C++ compiler we are using C code:
    extern "C" {
    #include "truerng.h"

    2.a/ link with static library ( in the directory):
    g++ -Wno-write-strings -o main main.cpp ./libtruerng.a -ludev

    2.b/ link with static library ( removed from the directory):
    g++ -Wno-write-strings -o main main.cpp -L. -ltruerng -ludev

    2.c/ link with shared library:
    g++ -Wno-write-strings -Wl,-rpath=pwd-o main main.cpp -Lpwd-ltruerng -ludev

    Explainations (long answer): It seems to me that you have several issues, which I will discuss separately.

    A/ You write your program in C++
    The library is written in C, not in C++. So the fundamental problem is to call an external function written in a foreign language.
    The basic principle is to tell the C++ main pgm that the library is in C.
    This is why you should apply step 1/ above.

    B/ warning: deprecated conversion from string constant to ‘char*’
    This is because the prototypes are declared with “char *” and the compiler wants “const char *”.
    I admit I should have done that :(
    The easy solution is to add an option telling the compiler to shut up because you know what you’re doing.
    Use -Wno-write-strings when compiling.

    C/ linking with dynamic versus static library
    You should put the “-ltruerng” option *after* “main”; because the linker goes from left to right for unresolved symbols.
    I recommend to link with the static lib, which is easier for testing. So either you build the package
    with “./configure … –disable-shared”, or you “rm*”, or you explicitly use the static library filepath.

    D/ the output of your main program
    When you call “./main”, you should see 10 “scrambled” characters, since the main pgm prints directly the random characters.
    You may prefer to pipe the output into “od(1)” in order to have a human-readable output:
    ./main | od -x

    E/ I warmly recommend using a Makefile. This permit encapsulating flags, and easy modification.
    Indeed, a Makefile is an integral part of your testing procedure. Here is a proposal:

    PROG =		main
    CXXFLAGS =	-Wno-write-strings
    LOADLIBES =	./libtruerng.a
    LDLIBS =	-ludev
    .PHONY:		all check clean
    all: $(PROG)
    check: all
    	./$(PROG) | od -x
    	$(RM) $(PROG).o $(PROG) $(PROG).core core

    Best regards,




    Thank you for your help!
    The linking is working now without errors.

    Regarding libudev:
    I built the library without libudev or libusb.
    When I try to build the library WITH libudev “make all” works w/o errors but “make check” fails.
    when running the binary file I get this error:

    mihai@bhairava:~/Soft/TrueRNG/truerng-2.0$ src.bin/truerng --list
    lt-truerng: truerng_open.c:196: truerng_libudev: Assertion 'Serial_found != NULL' failed.
    Aborted (core dumped)

    Built without libudev or libusb I get no errors, but it is unable to detect ids and serial:

    mihai@bhairava:~/Soft/TrueRNG/truerng-2.0$ src.bin/truerng --list
    file path : /dev/TrueRNG
    idVendor  : <unknown>
    idProduct : <unknown>
    Product   : <unknown>
    Serial    : <unknown>
    state     : ON
    mode      : NORMAL  300 baud

    Perhaps it is because I use a TrueRNG v3(?)

    Anyway, I can use now the library. , which seems to give a higher bitrate than using /dev/random (via rng-tools).

    gratefully yours,



    Using this library I get an output speed of ~406kbs, while using /dev/random (enabling truerng through rng-tool) I get only ~80kbs. (without truerng the speed of /dev/random is very low, ~3-4 bytes/s).
    Why there is such a big diference? Why does entropy pool not use all available output of TrueRNG?



    Hello Mihai,

    Thanks for your feedback.

    The “assertion failed” problem is concerning; the only way I see to fix this is to have a V3 device to play with.
    If the friendly staff at UBLD are reading this, I declare myself volunteer to adapt this package to the V3 device <wink> <wink>.

    Also, I have put the C++ compatibility in my TODO list.

    With regards to the difference of throughput
    – I did not write “True”put :) — the explanation is not simple. In order to really understand the reason, you should understand the code of the Linux /dev/random driver.
    In a nutshell, Linux adds entropy into the pool *when needed*. It has its own whitening, and does not assume the entropy pool is fast, verbose, and really “random”; i.e. it does not assume there is a TRNG available.
    In order to solve this issue, one may write a kernel-resident driver for TrueRNG devices, in the same spirit than the specific OpenBSD driver for the AleaII device (

    Best regards,


    #2038 Staff

    Denis, e-mail us directly and we’ll help you out.



    Hello all,

    The package truerng-2.1 is now available at

    It fixes several bugs raised by Mihai in earlier postings:
    1/ the library is now C++ compatible
    2/ “char *” replaced by “const char *” in function prototypes where needed.
    3/ supporting V3 model, fully tested.
    4/ generation of the shared library is now disabled by default.

    With regards to the V3 model, I discovered with great surprise that it does not have a built-in unique serial number. This raises the question on how to uniquely identify a specific device if several V3 are plugged-in. A promising approach is to use the USB “busnum:devnum”, and I have put this on my TODO list for a forthcoming version 3.0 of the package.

    I have tested the package with 2 TrueRNG devices plugged-in: one TrueRNGpro and one V3 dongle. This showed that the udev rules provided by UBLD do not permit to handle correctly several devices; the /dev/TrueRNG soft link being unique.
    Therefore, I propose to modify the file 99-TrueRNG.rules with:
    SYMLINK+="TrueRNG TrueRNG.%n"
    and 99-TrueRNGpro.rules with:
    SYMLINK+="TrueRNG TrueRNGpro.%n"

    This permits /dev/TrueRNG to be always created, pointing to any TrueRNG device, thus being used by rng-tools. Another unique soft link is also created, permitting access to a specific device. Here is a listing of my own system:

    $ ls -ld /dev/TrueRNG* /dev/ttyACM*
    lrwxrwxrwx 1 root root         7 Mar  7 20:57 /dev/TrueRNG -> ttyACM1
    lrwxrwxrwx 1 root root         7 Mar  7 20:57 /dev/TrueRNG.1 -> ttyACM1
    lrwxrwxrwx 1 root root         7 Mar  7 11:33 /dev/TrueRNGpro.0 -> ttyACM0
    crw-rw---- 1 root dialout 166, 0 Mar  7 11:33 /dev/ttyACM0
    crw-rw---- 1 root dialout 166, 1 Mar  7 20:57 /dev/ttyACM1

    Best regards,




    Hello random ppls,

    The package truerng-3.0 is now available at

    It now takes into account the USB bus:dev number to select a specific device. It can also provide a listing of all connected devices.
    Testing and feedback are welcome.





    Since I bought the Pro model I’ve been editing my favorite old Roguelikes to use /dev/random via getrandom() as that will allow me to use something else instead of/together with /dev/TrueRNG. However, the Web instructions to change the mode of TrueRNG Pro don’t seem to work at all for me, while your program does. Thank you!

Viewing 11 posts - 1 through 11 (of 11 total)

You must be logged in to reply to this topic.