/** Do the initialization - especially create a random seed and get your own PeerID * Must be called first. * Gets the name of this peer (for example "Ulrich Norbisrath's peer") and the public key */ F2FPeer * f2fInit( const F2FString myName, const F2FString myPublicKey ) { #define MAXBUFFERSIZE 1024 char buffer[MAXBUFFERSIZE+1]; // Buffer for concatenation of name and key buffer [MAXBUFFERSIZE]=0; // Make sure this is 0 terminated F2FSize buffersize; F2FWord32 seeds[ MT_STATE_SIZE ]; // First create the seed for the mersenne twister srand( time(NULL) ); // Initialize the poor randomizer of C itself // copy name and publickey in buffer (this copy should be secure) strncpy( buffer, myName, MAXBUFFERSIZE ); buffersize = strlen( buffer ); strncpy( buffer + buffersize, myPublicKey, MAXBUFFERSIZE - buffersize ); buffersize = strlen( buffer ); if (buffersize < 4) // not enough data to create seed { globalError = F2FErrNotEnoughSeed; return NULL; } // iterate over seed int seedCell; for (seedCell = 0; seedCell < MT_STATE_SIZE; ++seedCell) { // Xor a random number with a random 4 byte pair out of th ebuffer seeds[ seedCell ] = rand() ^ *( (F2FWord32 *) (buffer + ( rand()%(buffersize-3) ) ) ); } mts_seedfull( &randomnessState, seeds ); // activate the seed /* Create a new peer with random uid */ F2FPeer *newpeer = f2fPeerListNew( mts_lrand( &randomnessState ), mts_lrand( &randomnessState ) ); if (newpeer == NULL) { globalError = F2FErrListFull; return NULL; } /* initialize buffers */ sendBuffer.size = 0; /* Init was successfull */ initWasCalled = 1; myself = newpeer; myself->activeprovider = F2FProviderMyself; return newpeer; }
/** Return a random number from the seeded mersenne twister, but not 0 */ F2FWord32 f2fRandomNotNull() { F2FWord32 rand; while( (rand = mts_lrand( &randomnessState )) == 0); return rand; }
/** Return a random number from the seeded mersenne twister */ F2FWord32 f2fRandom() { return mts_lrand( &randomnessState ); }
static double calculate_sp( double fp, double shv, double var_A, double var_B, double var_D, double r, double s, double t, mt_state* state, int* lcounter ) { /* * Will there be a problem in case of equality? */ #if 0 assert((shv <= fp) && (r <= 1.0 && s <= 1.0 && t <= 1.0) && (r + s + t) <= 1.0); #endif double p_i[4] = {shv, shv, shv, shv}; double result_i[3]; double max; int index = 0; int old_index = 0; int i; uint32_t rand_n; int idx; /* * loop counter */ *lcounter = 0; max = GET_MAX(shv + var_A, shv * (1.0 + (var_B/100.0))); if (max < fp) { return max; } /* * max >= fp */ while (p_i[index] < fp) { old_index = index; index = (index + 1) % 4; p_i[index] = p_i[old_index] * (1.0 + var_D); (*lcounter)++; } #if 0 assert(p_i[index] >= fp); #endif /* * Fill the result_i array */ fprintf(stderr, "\nindex = %d\n", index); for (i = 0; i < 4; i ++) { fprintf(stderr, "%lf:", p_i[i]); } for (i = 0; i < 3; i++) { index = (index - 1 + 4) % 4; result_i[i] = p_i[index]; } fprintf(stderr, "\nfinal\n"); for (i = 0; i < 3; i ++) { fprintf(stderr, "%lf:", result_i[i]); } /* * result_i[0] contains the value closest to fp, and result_i[2] contains the value * farthest from fp */ rand_n = mts_lrand(state); rand_n %= RAND_RANGE; /* * r corresponds to result_i[2] i.e the one farthest from fp * s corresponds to result_i[1] * t corresponds to result_i[0] i.e the one closest to fp */ r *= RAND_RANGE; s *= RAND_RANGE; t *= RAND_RANGE; fprintf(stderr, "\nRand n = %u\n", rand_n); idx = get_idx(r, s, t, rand_n); //idx = get_idx(r, s, t, 109283442); return result_i[idx]; }
static double calculate_sp_O_1( double fp, double shv, double var_A, double var_B, double var_D, double r, double s, double t, mt_state* state, int* lcounter ) { /* * Will there be a problem in case of equality? */ #if 0 assert((shv <= fp) && (r <= 1.0 && s <= 1.0 && t <= 1.0) && (r + s + t) <= 1.0); #endif //double p_i[4] = {shv, shv, shv, shv}; /* * This shouldn't happen but I can't put an assertion here */ if (shv <= 0.0 || shv >= fp) { return fp; } double max; int i; uint32_t rand_n; int idx; /* * loop counter */ *lcounter = 0; max = GET_MAX(shv + var_A, shv * (1.0 + (var_B/100.0))); if (max < fp) { return max; } /* * max >= fp */ double result_i[3] = {shv, shv, shv}; double step = 1 + var_D; int32_t exponent = (int32_t) ceil(log(fp/shv)/log(step)) - 1; double p_n; if (exponent > 0) { fprintf(stderr, "\nexponent = %d, formula_output = %lf\n", exponent, log(fp/shv)/log(step)); p_n = shv * pow(step, exponent); } else { return shv; } fprintf(stderr, "\np_n = %lf\n", p_n); #if 0 while (p_n >= fp) { fprintf(stderr, "\nHi"); p_n /= step; (*lcounter)++; } #endif /* * Now p_n should be < fp */ i = 0; do { result_i[i] = p_n; p_n /= step; i++; } while (p_n > result_i[i] && i < 3); fprintf(stderr, "\nfinal2\n"); for (i = 0; i < 3; i ++) { fprintf(stderr, "%lf:", result_i[i]); } /* * result_i[0] contains the value closest to fp, and result_i[2] contains the value * farthest from fp */ rand_n = mts_lrand(state); rand_n %= RAND_RANGE; /* * r corresponds to result_i[2] i.e the one farthest from fp * s corresponds to result_i[1] * t corresponds to result_i[0] i.e the one closest to fp */ r *= RAND_RANGE; s *= RAND_RANGE; t *= RAND_RANGE; fprintf(stderr, "\nRand n = %u\n", rand_n); idx = get_idx(r, s, t, rand_n); //idx = get_idx(r, s, t, 109283442); return result_i[idx]; }
/* * Generate a uniform integer distribution on the open interval * [lower, upper). See comments above about RD_UNIFORM_THRESHOLD. If * we are above the threshold, this function is relatively expensive * because we may have to repeatedly draw random numbers to get a * one that works. */ int32_t rds_iuniform( mt_state * state, /* State of the MT PRNG to use */ int32_t lower, /* Lower limit of distribution */ int32_t upper) /* Upper limit of distribution */ { uint32_t range = upper - lower; /* Range of requested distribution */ if (range <= RD_UNIFORM_THRESHOLD) return lower + (int32_t)(mts_ldrand(state) * range); else { /* * Using the simple formula would produce too much bias. * Instead, draw numbers until we get one within the range. * To save time, we first calculate a mask so that we only * look at the number of bits we actually need. Since finding * the mask is expensive, we optionally do a bit of caching * here (note that the caching makes the code non-reentrant; * set MT_CACHING to turn on this misfeature). * * Incidentally, the astute reader will note that we use the * low-order bits of the PRNG output. If the PRNG were linear * congruential, using the low-order bits wouuld be a major * no-no. However, the Mersenne Twist PRNG doesn't have that * drawback. */ #ifdef MT_CACHING static uint32_t lastrange = 0; /* Range used last time */ static uint32_t rangemask = 0; /* Mask for range */ #else /* MT_CACHING */ uint32_t rangemask = 0; /* Mask for range */ #endif /* MT_CACHING */ register uint32_t ranval; /* Random value from mts_lrand */ #ifdef MT_CACHING if (range != lastrange) #endif /* MT_CACHING */ { /* * Range is different from last time, recalculate mask. * * A few iterations could be trimmed off of the loop if we * started rangemask at the next power of 2 above * RD_UNIFORM_THRESHOLD. However, I don't currently know * a formula for generating that value (though there is * probably one in HAKMEM). */ #ifdef MT_CACHING lastrange = range; #endif /* MT_CACHING */ for (rangemask = 1; rangemask < range && rangemask != 0; rangemask <<= 1) ; /* * If rangemask became zero, the range is over 2^31. In * that case, subtracting 1 from rangemask will produce a * full-word mask, which is what we need. */ rangemask -= 1; } /* * Draw random numbers until we get one in the requested range. */ do { ranval = mts_lrand(state) & rangemask; } while (ranval >= range); return lower + ranval; } }