Proper Random Number Generator

In ruiTop.h the void randomSeed(unsigned long seed); function is described thus:

randomSeed() initializes the pseudo-random number generator, causing it to start at an arbitrary point in its random sequence. This sequence, while very long, and random, is always the same.

Which means this is not random. Considering that the SX1262 has a TRNG functionality, it would be much safer – and simpler – to build the sequence on the fly from the RANDOM_NUMBER_GENERATORBASEADDR register of the SX1262. And when you reach the end, just refill. See Sx1262LoRandom for an example of how it’s done. There may even be, ahem, a similar proposal in Jira, for all I know…

FWIW, the nRF52040 also has TRNG through its CC310 module – yes, there’s code available too :slight_smile: – but using the SX1262 would be cross-platform.

And this would be the perfect case to add readRegister() / writeRegister() functions to the API, so that users can take advantage of functionalities not present in the API…

1 Like

… better late than never …

I don’t know the details of the TRNG functions on the SX1262 or the nRF52040, but I have used similar functions on other devices. It’s usually a single bit structure in the silicon that is designed to be inherently (electrically) noisy. The downside is that they are slow, like milliseconds per bit. They are great for initialising the PRNG and then off you go with a very fast sequence of numbers that look random.

If you only use part of a 32 bit PRNG sequence, say the least significant 16 bits and keep the upper 16 bits just as internal state for the generator, it’s very hard for anyone to guess where you are up to in the overall sequence. Good PRNGs like the Mersenne Twister have a lot of state so you can make it effectively impossible for anyone to guess where the sequence is up to. I’m not at all worried that the sequence is not truely random.

My take on this is to choose a PRNG where you want to be on the complexity vs security tradeoff, initialise it with the slow TRNG generated bitstream, and you’re good to go.

BTW I totally agree that the API could do with some low level access functions. I’m sure this could be done in a restrictive way that would prevent reverse engineering the RUI code. The RUI environment is great until you hit up against a limitation (or a bug) and then you are absolutely stuck.

1 Like

Thanks for this. That’s indeed how TRNG works in Semtech chips – in older SX127x chips you had to read the Wideband RSSI register and extract the LSB – possibly applying a von Neumann extractor to the stream of incoming bits. The SX126x chips do it for you and supply 32 random bits at a time. I haven’t looked much into the CC310, but since it is tightly linked to the nRF52840, one could assume it has to do with noise from the 2.4 GHz antenna.

The inconvenient with LoRa TRNG is that you have to put the chip in a specific mode, continuous receive, for it to work properly. And you probably don’t want to do that TOO often when your module is in operation. Which is why in my 2 LoRandom libraries for SX127x and SX126x I implemented a function that fills up a buffer (I normally use 256 bytes, but any amount could do). You fill 'er up, and keep an index. When the tank runs low, you go to the station again… Much much much better than a static sequence.

There are a few places in RUI3 that use static stuff where they shouldn’t (static IV for AES, for instance), and I have wondered for a while whether it was lack of care or ignorance – or both. The fact that you are the only one who responded to this message is kind of telling, I would say…

This is somewhat of an aside, but I have a perhaps more charitable take. I think the more likely situation is that the sw/dev team is a (small) handful of people that are working there way through a mountain of issues that keeps getting bigger.

Software is always hard. My project has 6 PCBs, 4 of them are complicated, and the RAK subset is just one of those. Each “complicated” board is about 4 pages of schematic and took me about a week to layout and route. Each board then went through two or three revisions as I tried to load it and found I couldn’t get parts in the packages that were available only a month before. Then I wrote and tested driver software for months and months. Largely this is down to my dislike of using stock driver libraries so it’s my own fault, but even putting that aside, software takes longer than hardware. This is especially so of low level drivers that are fighting a bunch of real-time restrictions and a godzillion error corner cases.

For example, when I found that I couldn’t get call-backs from Serial comms under RUI3 I had to completely restructure how two of my boards synchronised. That was a few thousand lines of code.

Sorry, this isn’t meant to be a rant, but I have the feeling that your thread is not just about random numbers. It’s also about RUI3 limitations. RUI3 is a great framework and I want to keep working with it, but it’s RAK’s IP and closed, and it’s a long way from finished.

1 Like