Remco Bloemen
/
EntropySource
Use your mbed and it\'s noisy analog inputs as a hardware random number generator!
EntropyPool.cpp
- Committer:
- Remco
- Date:
- 2011-06-20
- Revision:
- 0:dda0a8c4ac0c
File content as of revision 0:dda0a8c4ac0c:
#include <EntropyPool.h> extern "C" void mbed_mac_address(char *mac); EntropyPool::EntropyPool() : SHA256() , e(0) , timer() { // Seed with MAC, but do not add entropy char mac[6]; mbed_mac_address(mac); append(mac, 6); // Start the timer timer.start(); } char* EntropyPool::produce(int bytes) { // Make sure the entropy pool is full while(e < 256) gather(); // Mix the pool process_chunk(); // Output a word at a time, maintaining at least // 128 bits entropy int num_words = (bytes + 3) / 4; unsigned int* out = new unsigned int[num_words]; for(int i = 0; i < num_words; ++i) { out[i] = hash[i % 8]; e -= 32; if(e < 128) { // Refill the entropy pool while(e < 256) gather(); process_chunk(); } } return reinterpret_cast<char*>(out); } void EntropyPool::gather() { // The following default sources are of poor quality // In a thight loop they would be highly predictable // Yet it is still far better than nothing, and to prevent // complete stall, I'll assume these add two bits of entropy e += 2; // Real time clock time_t tvalue = time(0); append(reinterpret_cast<char*>(&tvalue), sizeof(time_t)); // Ticker unsigned int value = timer.read_us(); append(reinterpret_cast<char*>(&value), 4); // Number of bytes appended so far append(reinterpret_cast<char*>(&length), 4); // Call user function gatherer.call(); if(e > 256) e = 256; } void EntropyPool::gatherAnalogNoise(AnalogIn& in, int entropy) { unsigned short value = in.read_u16(); // Only the least significant bits change due to noise // But the last four bits are repetitions of the first four append(reinterpret_cast<char*>(&value), 2); e += entropy; }