Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fix Random function II #496

Open
wants to merge 13 commits into
base: master
Choose a base branch
from
Open

Fix Random function II #496

wants to merge 13 commits into from

Conversation

plybrd
Copy link

@plybrd plybrd commented Jul 16, 2021

Hi,

I am included a function which returns an array of random bytes. This work is based on the work of @Kongduino and resolves the issue #394.
To get real random bytes one have to follow the guidelines given in Application Note AN1200.24 from Semtech.
See Chapter 4 of Random Number Generation for Cryptography.

There is a setup described in this Application Note to be done before starting collecting random bits. These setup is done in function random(uint8 *, size_t) which then calls random0() to actually collect the random bytes.

The setup can be done in two ways:

  • using the LoRa API or
  • writing directly to the registers

Using the API will set some fancy values for sending or receiving but which are not needed for just measuring the RssiWideband for collecting random bits. Writing directly to the registers will reduce much of the overhead due to setup for random number generations. But for review you will find both ways in the pull request:

  • Setting "#define RANDOMUSEAPI" will use the API
  • Unsetting "#define RANDOMUSEAPI" will write directly to the registers

There is one imported behavior of random(uint8 *, size_t). This function will memory the state before setup for random number generation and will reset to this state back at end. This is hidden for users of the library.

The old function random(byte) is still there and works now as expected.

@Kongduino
Copy link

I have done this in my Lorandom library – part of which has been included here. Not sure fillRandom was in the lib when this was done:

void fillRandom(unsigned char *x, size_t len) {
  setupLoRandom();
  size_t i;
  for (i = 0; i < len; i++) {
    x[i] = getLoRandomByte();
  }
  resetLoRa();
}

https://github.com/Kongduino/LoRandom/blob/master/src/LoRandom.h#L69-L77

Anyway sounds like a good idea – I use this in my own code, filling up a 256-byte buffer to speed things up.

@plybrd
Copy link
Author

plybrd commented Jul 18, 2021

I added just a small example for the use of random().

@Kongduino Many Thanks to figure out how to generate real random numbers with Semtech SX1276. I did not check your header file for a simple reason. For using it I would have to change Sandeepmistry's famous LoRa library anyway. So it is just simpler to add a correct random function to sandeepmistry/arduino-LoRa and ask for commit. By the way your function getLoRandomByte() just returns even numbers: 0 2 4 6 ... No odd numbers! So the function does not return really a random BYTE (Please compare to function LoRaClass::random0() in this commit.). Still much better then the original function which just returns the wide band RSSI measurement and especially these numbers of the original function random() are not even distributed.

@Kongduino
Copy link

Let me check on my end – I did some testing when I wrote it and it SEEMED it was working properly. Thanks for the feedback!

@Kongduino
Copy link

Thanks @plybrd there was indeed a bug – and thanks to you I was able to fix it. https://github.com/Kongduino/LoRandom/blob/master/src/LoRandom.h#L45-L51

https://github.com/Kongduino/LoRandom/blob/master/Fixed.png

Odd and even numbers now... :-)

 - Added basic von Neumann extractor
 - Improved setup
   - waits until current package (if any) is send
   - disables all interrupts

rssi_wideband():
 - Function which returns the RSSI wideband messurement
@plybrd
Copy link
Author

plybrd commented Aug 4, 2021

Using just the LSB of a RSSI wideband maeassurement gives random numbers but they are still quite biased. You get more '1' bits then '0'. This explains the uneven curves in the following histogram. The more '1' bits are in a random number value the more often you get the number. The cureves are for 20, 50, 200, 1000, ... samples. The more samples you have the better shows the bias up.

Histogram: as AN1200.24 Chapter 4

In the new code for random() I use a basic von Neumann extractor (see at Wikipedia). This extractor is whitening some LSBs of RSSI wide-band measurements for each random byte. The histogram of the random number values from the improved function shows now the behavior of real random numbers:

Histogram: as AN1200.24 Chapter 4 with basic von Neumann extractor

Further the improved function takes care if a packet is just to go over the air. It waits until the transmit is finished before setting up for random number generation.

In general you can not receive a wanted packet after setting up for random number generation. This is because of the fact that bandwidth, spreading factor, and coding rate is changed. For this reason I disable the interrupt IRQ_RX_DONE so no accidental receive will disturb us. In fact all interrupts on the SX127# will be disabled to be on the sure side. After finishing the collection of random numbers all the interrupts are restored to the previous state.

I tried to add all the ideas found in PR #150, #190, and #395. It's look like there is much bother about the original random() which just returns a wide-band RSSI measurement. And this is NOT in any way a random number.

To give the expert the possibility to make his own, improved random function I added the function rssi_wideband().

@plybrd plybrd changed the title add function random(uint8_t *buffer, size_t size) Fix Random function II Aug 5, 2021
@Kongduino
Copy link

Any update on this? You really need to fix the random() function...

@plybrd
Copy link
Author

plybrd commented Jan 28, 2023

Please rename the corrupt random() to rssi_wideband()

This library with a correct random() can be found here.

@rforro
Copy link

rforro commented Dec 21, 2023

Please just merge this PR.

@plybrd
Copy link
Author

plybrd commented Jan 2, 2024

I would if I could. @rforro You can use my fork at plybrd/arduino-LoRa.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants