1
0
mirror of https://github.com/taigrr/arduinolibs synced 2025-01-18 04:33:12 -08:00

Register the noise sources with RNG at setup time

This commit is contained in:
Rhys Weatherley 2015-03-25 19:35:44 +10:00
parent fd38b7e127
commit 067e8ac177
6 changed files with 52 additions and 23 deletions

View File

@ -103,7 +103,9 @@ TransistorNoiseSource noise(A1);
\endcode \endcode
Then in the setup() function we call \link RNGClass::begin() RNG.begin()\endlink Then in the setup() function we call \link RNGClass::begin() RNG.begin()\endlink
to start the random number generator running: to start the random number generator running and call
\link RNGClass::addNoiseSource() RNG.addNoiseSource()\endlink to register
all of the application's noise sources:
\code \code
void setup() { void setup() {
@ -111,6 +113,9 @@ void setup() {
// "MyApp 1.0" and load the previous seed from EEPROM address 500. // "MyApp 1.0" and load the previous seed from EEPROM address 500.
RNG.begin("MyApp 1.0", 500); RNG.begin("MyApp 1.0", 500);
// Add the noise source to the list of sources known to RNG.
RNG.addNoiseSource(noise);
// ... // ...
} }
\endcode \endcode
@ -128,6 +133,7 @@ void setup() {
RNG.begin("MyApp 1.0", 500); RNG.begin("MyApp 1.0", 500);
RNG.stir(serial_number, sizeof(serial_number)); RNG.stir(serial_number, sizeof(serial_number));
RNG.stir(mac_address, sizeof(mac_address)); RNG.stir(mac_address, sizeof(mac_address));
RNG.addNoiseSource(noise);
... ...
} }
\endcode \endcode
@ -147,18 +153,14 @@ fills up, a save will be automatically forced.
To use the random number generator properly, there are some regular tasks To use the random number generator properly, there are some regular tasks
that must be performed every time around the application's main loop(). that must be performed every time around the application's main loop().
Newly accumulated noise must be mixed in with Newly accumulated noise must be mixed in and auto-saves must be performed
\link RNGClass::stir() RNG.stir()\endlink and the on a regular basis. The \link RNGClass::loop() RNG.loop()\endlink
\link RNGClass::loop() RNG.loop()\endlink function must be called to function takes care of these tasks for us:
perform auto-saves:
\code \code
void loop() { void loop() {
// ... // ...
// If the noise source has accumulated new entropy, then stir it in.
RNG.stir(noise);
// Perform regular housekeeping on the random number generator. // Perform regular housekeeping on the random number generator.
RNG.loop(); RNG.loop();

View File

@ -70,20 +70,20 @@
* // Stir in the Ethernet MAC address. * // Stir in the Ethernet MAC address.
* RNG.stir(mac_address, sizeof(mac_address)); * RNG.stir(mac_address, sizeof(mac_address));
* *
* // Add the noise source to the list of sources known to RNG.
* RNG.addNoiseSource(noise);
*
* // ... * // ...
* } * }
* \endcode * \endcode
* *
* The application should regularly call stir() to mix in new data from * The application should regularly call loop() to stir in new data
* the noise source and also regularly call loop(): * from the registered noise sources and to periodically save the seed:
* *
* \code * \code
* void loop() { * void loop() {
* // ... * // ...
* *
* // If the noise source has accumulated new entropy, then stir it in.
* RNG.stir(noise);
*
* // Perform regular housekeeping on the random number generator. * // Perform regular housekeeping on the random number generator.
* RNG.loop(); * RNG.loop();
* *
@ -170,6 +170,7 @@ RNGClass::RNGClass()
, firstSave(1) , firstSave(1)
, timer(0) , timer(0)
, timeout(3600000UL) // 1 hour in milliseconds , timeout(3600000UL) // 1 hour in milliseconds
, count(0)
{ {
} }
@ -197,7 +198,7 @@ RNGClass::~RNGClass()
* additional entropy data from noise sources to initialize the random * additional entropy data from noise sources to initialize the random
* number generator properly. * number generator properly.
* *
* \sa stir(), save() * \sa addNoiseSource(), stir(), save()
*/ */
void RNGClass::begin(const char *tag, int eepromAddress) void RNGClass::begin(const char *tag, int eepromAddress)
{ {
@ -234,6 +235,25 @@ void RNGClass::begin(const char *tag, int eepromAddress)
save(); save();
} }
/**
* \brief Adds a noise source to the random number generator.
*
* \param source The noise source to add, which will be polled regularly
* by loop() to accumulate noise-based entropy from the source.
*
* RNG supports a maximum of four noise sources. If the application needs
* more than that then the application must poll the noise sources itself by
* calling NoiseSource::stir() directly.
*
* \sa loop(), begin()
*/
void RNGClass::addNoiseSource(NoiseSource &source)
{
#define MAX_NOISE_SOURCES (sizeof(noiseSources) / sizeof(noiseSources[0]))
if (count < MAX_NOISE_SOURCES)
noiseSources[count++] = &source;
}
/** /**
* \brief Sets the amount of time between automatic seed saves. * \brief Sets the amount of time between automatic seed saves.
* *
@ -485,6 +505,10 @@ void RNGClass::save()
*/ */
void RNGClass::loop() void RNGClass::loop()
{ {
// Stir in the entropy from all registered noise sources.
for (uint8_t posn = 0; posn < count; ++posn)
noiseSources[posn]->stir();
// Save the seed if the auto-save timer has expired. // Save the seed if the auto-save timer has expired.
if ((millis() - timer) >= timeout) if ((millis() - timer) >= timeout)
save(); save();

View File

@ -35,6 +35,7 @@ public:
~RNGClass(); ~RNGClass();
void begin(const char *tag, int eepromAddress); void begin(const char *tag, int eepromAddress);
void addNoiseSource(NoiseSource &source);
void setAutoSaveTime(uint16_t minutes); void setAutoSaveTime(uint16_t minutes);
@ -60,6 +61,8 @@ private:
uint16_t firstSave : 1; uint16_t firstSave : 1;
unsigned long timer; unsigned long timer;
unsigned long timeout; unsigned long timeout;
NoiseSource *noiseSources[4];
uint8_t count;
void rekey(); void rekey();
}; };

View File

@ -76,15 +76,15 @@
* // "MyApp 1.0" and load the previous seed from EEPROM address 500. * // "MyApp 1.0" and load the previous seed from EEPROM address 500.
* RNG.begin("MyApp 1.0", 500); * RNG.begin("MyApp 1.0", 500);
* *
* // Add the noise source to the list of sources known to RNG.
* RNG.addNoiseSource(noise);
*
* // ... * // ...
* } * }
* *
* void loop() { * void loop() {
* // ... * // ...
* *
* // If the noise source has accumulated new entropy, then stir it in.
* RNG.stir(noise);
*
* // Perform regular housekeeping on the random number generator. * // Perform regular housekeeping on the random number generator.
* RNG.loop(); * RNG.loop();
* *

View File

@ -56,15 +56,15 @@
* // "MyApp 1.0" and load the previous seed from EEPROM address 500. * // "MyApp 1.0" and load the previous seed from EEPROM address 500.
* RNG.begin("MyApp 1.0", 500); * RNG.begin("MyApp 1.0", 500);
* *
* // Add the noise source to the list of sources known to RNG.
* RNG.addNoiseSource(noise);
*
* // ... * // ...
* } * }
* *
* void loop() { * void loop() {
* // ... * // ...
* *
* // If the noise source has accumulated new entropy, then stir it in.
* RNG.stir(noise);
*
* // Perform regular housekeeping on the random number generator. * // Perform regular housekeeping on the random number generator.
* RNG.loop(); * RNG.loop();
* *

View File

@ -29,6 +29,9 @@ void setup() {
// Initialize the random number generator. // Initialize the random number generator.
RNG.begin(RNG_APP_TAG, RNG_EEPROM_ADDRESS); RNG.begin(RNG_APP_TAG, RNG_EEPROM_ADDRESS);
// Add the noise source to the list of sources known to RNG.
RNG.addNoiseSource(noise);
startTime = millis(); startTime = millis();
} }
@ -58,9 +61,6 @@ void loop() {
Serial.println("calibrating"); Serial.println("calibrating");
} }
// If the noise source has accumulated new entropy, then stir it in.
RNG.stir(noise);
// Perform regular housekeeping on the random number generator. // Perform regular housekeeping on the random number generator.
RNG.loop(); RNG.loop();