void make_temper_bit(TemperingCalculatable<U>& rand, U mask, int param_pos, U pattern) { rand.setTemperingPattern(mask, pattern, param_pos); rand.setUpTempering(); }
/** *\japanese * テンパリングパラメータをひとつ探索する。 * * vビット精度均等分布次元をk(v)とする。vにおけるk(v)の理論的上限と * 実際のk(v)の差をd(v)とする。vを変化させたd(v)の和をΔで表す。 *<ol> * <li>v_bit から max_v_bit までのすべてのビットパターンを生成し</li> * <li>すべてのビットパターンについてk(v),d(v)をそれぞれ計算し</li> * <li>v-bit から max_v_bitまでのd(v)の和(Δ)の最も小さかったビッ * トパターンを選択する。</li> * <li>同じΔであればハミングウェイトの大きいビットパターンを選択する</li> *</ol> * なお、このメソッドは再帰する。 * * @param rand GF(2)疑似乱数生成器 * @param v_bit テンパリングパラメータを探索するビット範囲 * @param param_pos 何番目のテンパリングパラメータを探索しているか * @param max_v_bit このビットで探索をやめる * @param verbose true なら探索過程の情報を出力する * @return delta このテンパリングパラメータの設定結果によるΔ *\endjapanese * *\english * Search a tempering parameter. * * Search the best tempering parameter. Here, k(v) means dimension * of equi-distribution with v-bit accuracy, d(v) means the difference * between k(v) and the theoretical upper bound at v. Δ means * sum of d(v) for some vs. *<ol> * <li>Generates all bit patterns from v_bit to max_v_bit,</li> * <li>Calculates k(v) and d(v) for all bit patterns,</li> * <li>Select the bit pattern which gives the least Δ * for v = 1 to max_v_bit.</li> * <li>Select the bit pattern whose hamming weight is the largest for * the bit patterns whose Δs are same.</li> *</ol> * This method calls itself recursively. * * @param rand GF(2)-linear pseudo random number generator * @param v_bit start position bit of searching tempering parameter * @param param_pos index of tempering parameter * @param max_v_bit end position bit of searching tempering parameter * @param verbose if true, output redundant message. * @return delta Δ for v = 1 to max_v_bit for the * selected bit pattern. *\endenglish */ int search_best_temper(TemperingCalculatable<U>& rand, int v_bit, int param_pos, int max_v_bit, bool verbose) { using namespace std; int bitSize = rand.bitSize(); int delta; int min_delta = bitSize * bit_len; U min_pattern = 0; int size = max_v_bit - v_bit; U pattern; U mask = make_mask(v_bit, size); int length = bit_size<U>() / 4; for (int i = (1 << size) -1; i >= 0; i--) { if (lsb) { pattern = static_cast<U>(i) << v_bit; } else { pattern = static_cast<U>(i) << (bit_len - v_bit - size); } make_temper_bit(rand, mask, param_pos, pattern); delta = get_equidist(rand, bit_len); if (delta < min_delta) { if (verbose) { cout << "pattern change " << hex << min_pattern << ":" << pattern << endl; } min_delta = delta; min_pattern = pattern; } else if (delta == min_delta) { if (count_bit(min_pattern) < count_bit(pattern)) { if (verbose) { cout << "pattern change " << hex << min_pattern << ":" << pattern << endl; } min_pattern = pattern; } } } make_temper_bit(rand, mask, param_pos, min_pattern); if (verbose) { cout << dec << min_delta << ":" << hex << setw(length) << min_pattern << ":" << hex << setw(length) << mask << endl; } return min_delta; }
/** * 状態遷移パラメータとテンパリングパラメータを探索する。 * * @param lg テンパリングパラメータ計算可能な疑似乱数生成器 * @param st1 テンパリングパラメータ探索アルゴリズム * @param st2 テンパリングパラメータ探索アルゴリズム(LSB) * @param verbose 余分な情報を出力するフラグ * @param os 出力ストリーム * @param no_lsb LSBからのテンパリングをしない * @return 原始多項式を発見した */ bool search(TemperingCalculatable<T>& lg, AlgorithmTempering<T>& st1, AlgorithmTempering<T>& st2, bool verbose = false, std::ostream& os = std::cout, bool no_lsb = false) { using namespace NTL; using namespace std; using namespace std::tr1; out = &os; int veq[bit_size<T>()]; AlgorithmRecursionSearch<T> search(lg, *baseGenerator); int mexp = lg.bitSize(); bool found = false; for (int i = 0;; i++) { if (search.start(1000 * mexp)) { found = true; break; } if (verbose) { *out << "not found in " << (i + 1) * 10000 << endl; } } if (!found) { return false; } if (verbose) { time_t t = time(NULL); *out << "irreducible parameter is found at " << ctime(&t); } if (verbose) { *out << "count = " << search.getCount() << endl; *out << lg.getParamString() << endl; } poly = search.getMinPoly(); weight = NTL::weight(poly); if (verbose) { AlgorithmEquidistribution<T> sb(lg, bit_size<T>()); //print_binary(*out, poly); int delta = sb.get_all_equidist(veq); print_kv(veq, mexp, bit_size<T>()); *out << "delta = " << dec << delta << endl; } if (! no_lsb) { st2(lg, verbose); if (verbose) { if (st2.isLSBTempering()) { lg.setReverseOutput(); } AlgorithmEquidistribution<T> sc(lg, bit_size<T>()); delta = sc.get_all_equidist(veq); lg.resetReverseOutput(); time_t t = time(NULL); *out << "lsb tempering parameters are found at " << ctime(&t) << endl; print_kv(veq, mexp, bit_size<T>()); *out << "lsb delta = " << dec << delta << endl; } } st1(lg, verbose); AlgorithmEquidistribution<T> sc(lg, bit_size<T>()); delta = sc.get_all_equidist(veq); if (verbose) { time_t t = time(NULL); *out << "tempering parameters are found at " << ctime(&t) << endl; *out << lg.getParamString() << endl; print_kv(veq, mexp, bit_size<T>()); *out << "delta = " << dec << delta << endl; } return true; }