#include static bool hydro_random_rbit(uint16_t x) { uint8_t x8; x8 = ((uint8_t) (x >> 8)) ^ (uint8_t) x; x8 = (x8 >> 4) ^ (x8 & 0xf); x8 = (x8 >> 2) ^ (x8 & 0x3); x8 = (x8 >> 1) ^ x8; return (bool) (x8 & 1); } static int hydro_random_init(void) { const char ctx[hydro_hash_CONTEXTBYTES] = { 'h', 'y', 'd', 'r', 'o', 'P', 'R', 'G' }; hydro_hash_state st; uint16_t ebits = 0; uint16_t tc; bool a, b; cli(); MCUSR = 0; WDTCSR |= _BV(WDCE) | _BV(WDE); WDTCSR = _BV(WDIE); sei(); hydro_hash_init(&st, ctx, NULL); while (ebits < 256) { delay(1); tc = TCNT1; hydro_hash_update(&st, (const uint8_t *) &tc, sizeof tc); a = hydro_random_rbit(tc); delay(1); tc = TCNT1; b = hydro_random_rbit(tc); hydro_hash_update(&st, (const uint8_t *) &tc, sizeof tc); if (a == b) { continue; } hydro_hash_update(&st, (const uint8_t *) &b, sizeof b); ebits++; } cli(); MCUSR = 0; WDTCSR |= _BV(WDCE) | _BV(WDE); WDTCSR = 0; sei(); hydro_hash_final(&st, hydro_random_context.state, sizeof hydro_random_context.state); hydro_random_context.counter = ~LOAD64_LE(hydro_random_context.state); return 0; } ISR(WDT_vect) { }