looking for lightweight TRNG

Hi everyone,

I'm looking for a lightweight True Random Number Generator for a NodeMCU 12e. I was using this code for an earlier version of the IDE, but now it throws an error.

unsigned long x1 = 123456789,
              y1 = 234567891,
              z1 = 345678912,
              w1 = 456789123,
              c1 = 0;
                
unsigned long JKISS32 (int a, int b) {
  long t;
  y1 ^= y1 << 5; 
  y1 ^= y1 >> 7; 
  y1 ^= y1 << 22;
  t = z1 + w1 + c1; 
  z1 = w1; 
  c1 = t < 0; 
  w1 = t & 2147483647;
  x1 += 1411392427;
  //return (x1 + y1 + w1);
  return (x1 + y1 + w1) / (4294967294 / (b - a + 1)) + a ;
}

void SeedJKISS32 (const unsigned long newseed) {
  if (newseed != 0) {
    x1 = 123456789;
    y1 = newseed;
    z1 = 345678912;
    w1 = 456789123;
    c1 = 0;
  }
}

the error is "'long unsigned int y1' redeclared as different kind of symbol". Any help greatly appreciated

What is your definition of a true random number generator? The only TRNG are those which extract values from white noise. The closest you come to this on the Arduino is with analogRead from an unconnected analog pin.

I use the Two Least Sign algorithm with a von Neumann corrector.

Any help greatly appreciated

Please post a complete program that demonstrates the error

Thanks for the replies, i removed the code

unsigned long x1 = 123456789,
              y1 = 234567891,
              z1 = 345678912,
              w1 = 456789123,
              c1 = 0;

as it seems as if it was double declaring the variables. now i get a different error,

"invalid operands of types 'double(double)' and 'int' to binary 'operator<<'"

on this line

y1 ^= y1 << 5;

Again, this is code that worked with an earlier version of Arduino IDE, any ideas that could help?

Again, this is code that worked with an earlier version of Arduino IDE

Again, that is a snippet of code. Post the COMPLETE code.

Removing the declaration of y1 as an unsigned long now makes it look like y1 is declared somewhere as a double, and left shifting a double doesn't make sense.

That IS my complete code, I've copied and pasted it into a new file and it still throws that error. I'm looking to start a new project around it

unsigned long x1 = 123456789,
              y1 = 234567891,
              z1 = 345678912,
              w1 = 456789123,
              c1 = 0;
                
unsigned long JKISS32 (int a, int b) {
  long t;
  y1 ^= y1 << 5; 
  y1 ^= y1 >> 7; 
  y1 ^= y1 << 22;
  t = z1 + w1 + c1; 
  z1 = w1; 
  c1 = t < 0; 
  w1 = t & 2147483647;
  x1 += 1411392427;
  //return (x1 + y1 + w1);
  return (x1 + y1 + w1) / (4294967294 / (b - a + 1)) + a ;
}

void SeedJKISS32 (const unsigned long newseed) {
  if (newseed != 0) {
    x1 = 123456789;
    y1 = newseed;
    z1 = 345678912;
    w1 = 456789123;
    c1 = 0;
  }
}

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

Even this code alone returns the error "'long unsigned int y1' redeclared as different kind of symbol"

unsigned long x1 = 123456789;
unsigned long y1 = 234567891;
unsigned long z1 = 345678912;
unsigned long w1 = 456789123;
unsigned long c1 = 0;

void setup() {
  // put your setup code here, to run once:

}

void loop() {
  // put your main code here, to run repeatedly:

}

Even this code alone returns the error "'long unsigned int y1' redeclared as different kind of symbol"

Compiles OK for me

Sketch uses 444 bytes (1%) of program storage space. Maximum is 30720 bytes.
Global variables use 9 bytes (0%) of dynamic memory, leaving 2039 bytes for local variables. Maximum is 2048 bytes.

Windows 10
IDE 1.8.5
Arduino Nano

Thanks for the reply, but i figured it out: for some reason it was the variable name y1 was causing the errors, now fixed by turning it to yy

Just out of interest try a sketch that simply prints y1 and sizeof(y1);

Which Arduino board are you using ?

The full error messages give the reason. In hardware/esp8266/2.4.1/tools/sdk/libc/xtensa-lx106-elf/include/math.h:475:15: error: previous declaration of 'double y1(double)'
extern double y1 _PARAMS((double));

So the math.h for the NodeMCU is declaring a function called y1.

Build options changed, rebuilding all
sketch_aug25a:3: error: 'long unsigned int y1' redeclared as different kind of symbol
               y1 = 234567891,
               ^
In file included from /Users/john/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/cores/esp8266/Arduino.h:34:0,
                 from sketch/sketch_aug25a.ino.cpp:1:
/Users/john/Library/Arduino15/packages/esp8266/hardware/esp8266/2.4.1/tools/sdk/libc/xtensa-lx106-elf/include/math.h:475:15: error: previous declaration of 'double y1(double)'
 extern double y1 _PARAMS((double));
               ^
/Users/john/Documents/Arduino/sketch_aug25a/sketch_aug25a.ino: In function 'long unsigned int JKISS32(int, int)':
sketch_aug25a:11: error: invalid operands of types 'double(double)' and 'int' to binary 'operator<<'
   y1 ^= y1 << 5;
               ^
sketch_aug25a:12: error: invalid operands of types 'double(double)' and 'int' to binary 'operator>>'
   y1 ^= y1 >> 7;
               ^
sketch_aug25a:13: error: invalid operands of types 'double(double)' and 'int' to binary 'operator<<'
   y1 ^= y1 << 22;
               ^
/Users/john/Documents/Arduino/sketch_aug25a/sketch_aug25a.ino:20:16: warning: pointer to a function used in arithmetic [-Wpointer-arith]
   return (x1 + y1 + w1) / (4294967294 / (b - a + 1)) + a ;
                ^
/Users/john/Documents/Arduino/sketch_aug25a/sketch_aug25a.ino:20:21: warning: pointer to a function used in arithmetic [-Wpointer-arith]
   return (x1 + y1 + w1) / (4294967294 / (b - a + 1)) + a ;
                     ^
sketch_aug25a:20: error: invalid operands of types 'double (*)(double)' and 'long long int' to binary 'operator/'
   return (x1 + y1 + w1) / (4294967294 / (b - a + 1)) + a ;
                                                    ^
/Users/john/Documents/Arduino/sketch_aug25a/sketch_aug25a.ino: In function 'void SeedJKISS32(long unsigned int)':
sketch_aug25a:28: error: assignment of function 'double y1(double)'
     y1 = newseed;
        ^
sketch_aug25a:28: error: cannot convert 'const long unsigned int' to 'double(double)' in assignment
/Users/john/Documents/Arduino/sketch_aug25a/sketch_aug25a.ino: In function 'long unsigned int JKISS32(int, int)':
/Users/john/Documents/Arduino/sketch_aug25a/sketch_aug25a.ino:21:1: warning: control reaches end of non-void function [-Wreturn-type]
 }
 ^
exit status 1
'long unsigned int y1' redeclared as different kind of symbol

Thanks for all the replies, it works now! Until next time

On an ESP8266, why not just fetch the random number from address 0x3FF20E44?

johnwasser:
On an ESP8266, why not just fetch the random number from address 0x3FF20E44?

ESP8266-Arduino-cryptolibs/esp8266-trng/esp8266-trng.h at master · CSSHL/ESP8266-Arduino-cryptolibs · GitHub

Would this be faster then my method? it's all about speed in this case. Also, how could I apply this method to a range of numbers? ex. a random number between 0 and 10

majinjeff:
Would this be faster then my method?

Yes. WAY faster. You get 32 random bits each memory read.

majinjeff:
Also, how could I apply this method to a range of numbers? ex. a random number between 0 and 10

The exact same way you do it with your PRNG. Take your random 32-bit number and do the division and addition to get the range you want.

This has bitten me before. It turns out that “y1” is a standard libc math function. (Also y0, j0, and a couple more that you wonder how they got such lousy names.)

If you work with Bessel functions, then it is quite obvious to want functions named something like j0, y1, etc. as these are centrally important. The authors should have used upper case (J0) in the names, though.

Yeah, well, given they wanted to add a relatively obscure math function, and given the choice between breaking the common style rule that says "uppercase names are for macros, not for function names", and breaking nearly every graphics program ever written, the obviously made the correct decision!

jremington:
The authors should have used upper case (J0) in the names, though.

I'm thinking they should have wrapped the pesky imps in a namespace.