/** * Generate a truly random KUID within given `kuid'. */ void kuid_random_fill(kuid_t *kuid) { struct sha1 entropy; bigint_t bk, be; /* * Entropy collection is slow but we generate our KUID only at startup * and when none was present (nodes reuse their KUID from session to * session to reuse as much of their previous routing table as possible). * * The aim is to obtain the most random KUID to ensure that among all * the peers in the Kademlia network, KUIDs are unique and uniformly * distributed in the KUID space. */ entropy_collect(&entropy); /* slow */ random_strong_bytes(kuid->v, KUID_RAW_SIZE); /* * Combine the two random numbers by adding them. * * It's slightly better than XOR-ing the two since the propagation * of the carry bit diffuses the randomness (entropy remains the same). */ STATIC_ASSERT(sizeof kuid->v == sizeof entropy.data); bigint_use(&bk, kuid->v, sizeof kuid->v); bigint_use(&be, entropy.data, sizeof entropy.data); (void) bigint_add(&bk, &be); }
/** * Add entropy from previous calls. */ static G_GNUC_COLD void entropy_merge(sha1_t *digest) { bigint_t older, newer; /* * These big integers operate on the buffer space from ``digest'' and * ``entropy_previous'' directly. */ bigint_use(&older, &entropy_previous, SHA1_RAW_SIZE); bigint_use(&newer, digest, SHA1_RAW_SIZE); bigint_add(&newer, &older); bigint_copy(&older, &newer); }