/** * \brief Mix in fresh data from the TRNG when rand() is called. */ void RNGClass::mixTRNG() { #if defined(RNG_DUE_TRNG) // Mix in 12 words from the Due's TRNG. for (int posn = 0; posn < 12; ++posn) { // According to the documentation the TRNG should produce a new // 32-bit random value every 84 clock cycles. If it still hasn't // produced a value after 200 iterations, then assume that the // TRNG is not producing output and stop. int counter; for (counter = 0; counter < 200; ++counter) { if ((REG_TRNG_ISR & TRNG_ISR_DATRDY) != 0) break; } if (counter >= 200) break; block[posn + 4] ^= REG_TRNG_ODATA; } #elif defined(RNG_WORD_TRNG) // Read 12 words from the TRNG and XOR them into the state. for (uint8_t index = 4; index < 16; ++index) block[index] ^= RNG_WORD_TRNG_GET(); #elif defined(RNG_WATCHDOG) // Read the pending 32 bit buffer from the WDT interrupt and mix it in. cli(); if (outBits >= 32) { uint32_t value = hash; hash = 0; outBits = 0; sei(); // Final steps of the Jenkin's one-at-a-time hash function. // https://en.wikipedia.org/wiki/Jenkins_hash_function value += leftShift3(value); value ^= rightShift11(value); value += leftShift15(value); // XOR the word with the state. block[4] ^= value; } else { sei(); } #endif }
int main(){ char str[50]; sprintf(str,"abcdefghijk"); printf("The origin str is :%s\tlen is :%d\n",str,strlen(str)); printf("\n"); leftShift1(str,2); printf("The leftShift1 str is :%s\n",str); leftShift1(str,-2); printf("The leftShift1 str is :%s\n",str); leftShift1(str,3); printf("The leftShift1 str is :%s\n",str); leftShift1(str,strlen(str) - 3); printf("The leftShift1 str is :%s\n",str); printf("\n"); leftShift2(str,strlen(str),3); printf("The leftShift2 str is :%s\n",str); leftShift2(str,strlen(str),strlen(str) - 3); printf("The leftShift2 str is :%s\n",str); leftShift2(str + 2,strlen(str) - 2,2); printf("The leftShift2 str is :%s\n",str); leftShift2(str + 2,strlen(str) - 2,strlen(str) - 2 - 2); printf("The leftShift2 str is :%s\n",str); printf("\n"); leftShift3(str,strlen(str),3); printf("The leftShift3 str is :%s\n",str); leftShift3(str,strlen(str),strlen(str) - 3); printf("The leftShift3 str is :%s\n",str); leftShift3(str + 2,strlen(str) - 2,2); printf("The leftShift3 str is :%s\n",str); leftShift3(str + 2,strlen(str) - 2,strlen(str) - 2 - 2); printf("The leftShift3 str is :%s\n",str); printf("\n"); leftShift4(str,strlen(str),3); printf("The leftShift4 str is :%s\n",str); leftShift4(str,strlen(str),strlen(str) - 3); printf("The leftShift4 str is :%s\n",str); leftShift4(str + 2,strlen(str) - 2,2); printf("The leftShift4 str is :%s\n",str); leftShift4(str + 2,strlen(str) - 2,strlen(str) - 2 - 2); printf("The leftShift4 str is :%s\n",str); printf("\n"); leftShift5(str,strlen(str),3); printf("The leftShift5 str is :%s\n",str); leftShift5(str,strlen(str),strlen(str) - 3); printf("The leftShift5 str is :%s\n",str); leftShift5(str + 2,strlen(str) - 2,2); printf("The leftShift5 str is :%s\n",str); leftShift5(str + 2,strlen(str) - 2,strlen(str) - 2 - 2); printf("The leftShift5 str is :%s\n",str); printf("\n"); leftShift6(str,strlen(str),3); printf("The leftShift6 str is :%s\n",str); leftShift6(str,strlen(str),strlen(str) - 3); printf("The leftShift6 str is :%s\n",str); leftShift6(str + 2,strlen(str) - 2,2); printf("The leftShift6 str is :%s\n",str); leftShift6(str + 2,strlen(str) - 2,strlen(str) - 2 - 2); printf("The leftShift6 str is :%s\n",str); printf("\n"); return 0; }
/** * \brief Run periodic housekeeping tasks on the random number generator. * * This function must be called on a regular basis from the application's * main "loop()" function. */ void RNGClass::loop() { // Stir in the entropy from all registered noise sources. for (uint8_t posn = 0; posn < count; ++posn) noiseSources[posn]->stir(); #if defined(RNG_DUE_TRNG) // If there is data available from the Arudino Due's TRNG, then XOR // it with the state block and increase the entropy credit. We don't // call stir() yet because that will seriously slow down the system // given how fast the TRNG is. Instead we save up the XOR'ed TRNG // data until the next rand() call and then hash it to generate the // desired output. // // The CPU documentation claims that the TRNG output is very good so // this should only make the pool more and more random as time goes on. // However there is a risk that the CPU manufacturer was pressured by // government or intelligence agencies to insert a back door that // generates predictable output. Or the manufacturer was overly // optimistic about their TRNG design and it is actually flawed in a // way they don't realise. // // If you are concerned about such threats, then make sure to mix in // data from other noise sources. By hashing together the TRNG with // the other noise data, rand() should produce unpredictable data even // if one of the sources is actually predictable. if ((REG_TRNG_ISR & TRNG_ISR_DATRDY) != 0) { block[4 + trngPosn] ^= REG_TRNG_ODATA; if (++trngPosn >= 12) trngPosn = 0; if (credits < RNG_MAX_CREDITS) { // Credit 1 bit of entropy for the word. The TRNG should be // better than this but it is so fast that we want to collect // up more data before passing it to the application. ++credits; } trngPending = 1; } #elif defined(RNG_WORD_TRNG) // Read a word from the TRNG and XOR it into the state. block[4 + trngPosn] ^= RNG_WORD_TRNG_GET(); if (++trngPosn >= 12) trngPosn = 0; if (credits < RNG_MAX_CREDITS) { // Credit 1 bit of entropy for the word. The TRNG should be // better than this but it is so fast that we want to collect // up more data before passing it to the application. ++credits; } trngPending = 1; #elif defined(RNG_WATCHDOG) // Read the 32 bit buffer from the WDT interrupt. cli(); if (outBits >= 32) { uint32_t value = hash; hash = 0; outBits = 0; sei(); // Final steps of the Jenkin's one-at-a-time hash function. // https://en.wikipedia.org/wiki/Jenkins_hash_function value += leftShift3(value); value ^= rightShift11(value); value += leftShift15(value); // Credit 1 bit of entropy for each byte of input. It can take // between 30 and 40 seconds to accumulate 256 bits of credit. credits += 4; if (credits > RNG_MAX_CREDITS) credits = RNG_MAX_CREDITS; // XOR the word with the state. Stir once we accumulate 48 bytes, // which happens about once every 6.4 seconds. block[4 + trngPosn] ^= value; if (++trngPosn >= 12) { trngPosn = 0; trngPending = 0; stir(0, 0, 0); } else { trngPending = 1; } } else { sei(); } #endif // Save the seed if the auto-save timer has expired. if ((millis() - timer) >= timeout) save(); }