Sorry, last version was still sending output to stdout. This one is writing directly to /dev/urandom /* Public Domain, please append your contributions, respectfully. Version 1.0 - Sylvain Saucier (sylvain%sysau.com@localhost) - Original author Slight variation to make this program reseed urandom from userspace in NetBSD. The use case for this would be during an installation on a machine without proper hardware entropy sources. */ #include <stdint.h> #include <stdio.h> #include <pthread.h> #include <stdlib.h> #include <unistd.h> typedef struct { volatile uint64_t * s_output; volatile uint64_t * s_input; pthread_t thread; } _C4_node; typedef struct { volatile uint64_t shared_io[3]; _C4_node t[3]; long num_threads; } _C4_state; int C4_hash_algo(volatile uint64_t * in, volatile uint64_t * out) { uint64_t acc = 1; uint64_t primes[128] = {2, 3, 5, 7, 11, 13, 17, 19, 23, 29, 31, 37, 41, 43, 47, 53, 59, 61, 67, 71, 73, 79, 83, 89, 97, 101, 103, 107, 109, 113, 127, 131, 137, 139, 149, 151, 157, 163, 167, 173, 179, 181, 191, 193, 197, 199, 211, 223, 227, 229, 233, 239, 241, 251, 257, 263, 269, 271, 277, 281, 283, 293, 307, 311, 313, 317, 331, 337, 347, 349, 353, 359, 367, 373, 379, 383, 389, 397, 401, 409, 419, 421, 431, 433, 439, 443, 449, 457, 461, 463, 467, 479, 487, 491, 499, 503, 509, 521, 523, 541, 547, 557, 563, 569, 571, 577, 587, 593, 599, 601, 607, 613, 617, 619, 631, 641, 643, 647}; for (int bit = 0; bit < 64; bit++) { * in = ( * in << 13) | ( * in >> (64 - 13)); acc = (acc << bit) | (acc >> (64 - bit)); acc *= primes[(2 * bit) + (1 & * in)];* out += acc ^ * in; }* out ^= acc; return 0; } void * C4_main(void * raw) { _C4_node * self__C4_state = (_C4_node * ) raw; while (1) { C4_hash_algo(self__C4_state -> s_output, self__C4_state -> s_input); } return NULL; } void init(_C4_state * s, long _numt) { for (int thr = 0; thr < _numt; thr++) { s -> num_threads = _numt; s -> shared_io[thr] = 0; s -> t[thr].s_output = & (s -> shared_io[thr]); s -> t[thr].s_input = & (s -> shared_io[(thr + 1) % _numt]); pthread_create( & (s -> t[thr].thread), NULL, & C4_main, & (s -> t[thr])); } } int main(int argc, const char * argv[]) { uint64_t out; _C4_state state; long nproc = sysconf(_SC_NPROCESSORS_ONLN); size_t buf_len = 1024; char* userinput[buf_len]; if ( nproc < 2 ) { fprintf(stderr, "Insufficient number of cores to sustain synthetic chaos effect.\n"); exit(EXIT_FAILURE); }; init( & state, nproc > 2 ? 2 : nproc); //It is better to drive two theads simultaneously than three threads on two cores. FILE* urandom = fopen("/dev/urandom", "a"); if ( urandom == NULL ) { fprintf(stderr, "Cannot open /dev/urandom.\n"); exit(EXIT_FAILURE); } for ( int x = 0 ; x < 4 ; x++ ) { //Obtain 256 bits of entropy usleep(1000); //I observed decorrelation using 5 microseconds, 1 milliseconds should be good enough to provide last resort entropy. out = 0; // do not reuse old entropy. for (int thr = 0; thr < state.num_threads; thr++) { out ^= state.shared_io[thr]; } if ( fwrite( & out, sizeof(uint64_t), 1, urandom) != 1 ) { fprintf(stderr, "/dev/urandom write error.\n"); exit(EXIT_FAILURE); } } fclose(urandom); exit(EXIT_SUCCESS); }
Attachment:
signature.asc
Description: Message signed with OpenPGP