BigUInt poly_infty_norm_coeffmod(const BigPoly &poly, const BigUInt &modulus, const MemoryPoolHandle &pool) { if (modulus.is_zero()) { throw invalid_argument("modulus cannot be zero"); } if (!pool) { throw invalid_argument("pool is uninitialized"); } if (poly.is_zero()) { return BigUInt(); } int poly_coeff_count = poly.coeff_count(); int poly_coeff_bit_count = poly.coeff_bit_count(); int poly_coeff_uint64_count = divide_round_up(poly_coeff_bit_count, bits_per_uint64); Modulus mod(modulus.data(), modulus.uint64_count(), pool); BigUInt result(modulus.significant_bit_count()); util::poly_infty_norm_coeffmod(poly.data(), poly_coeff_count, poly_coeff_uint64_count, mod, result.data(), pool); return result; }
BigUInt BigUInt::operator +(const BigUInt& operand2) const { int result_bits = max(significant_bit_count(), operand2.significant_bit_count()) + 1; BigUInt result(result_bits); add_uint_uint(value_, uint64_count(), operand2.pointer(), operand2.uint64_count(), false, result.uint64_count(), result.pointer()); return result; }
friend BigUInt operator + (const BigUInt &left, const BigUInt &right) { BigUInt result; unsigned int i; if (left.m_data.size() > right.m_data.size()) { result.resize(left.m_data.size()); for (i=0; i < right.m_data.size(); ++i) { result.m_data[i] = left.m_data[i] + right.m_data[i]; } for (; i< left.m_data.size(); ++i) { result.m_data[i] = left.m_data[i]; } } else { result.resize(right.m_data.size()); for (i=0; i < left.m_data.size(); ++i) { result.m_data[i] = left.m_data[i] + right.m_data[i]; } for (; i< right.m_data.size(); ++i) { result.m_data[i] = right.m_data[i]; } } result.normalize(); return result; }
ChooserPoly ChooserEvaluator::multiply_plain(const ChooserPoly &operand, int plain_max_coeff_count, const BigUInt &plain_max_abs_value) { if (operand.max_coeff_count_ <= 0 || operand.comp_ == nullptr) { throw invalid_argument("operand is not correctly initialized"); } if (plain_max_coeff_count <= 0) { throw invalid_argument("plain_max_coeff_count must be positive"); } if (plain_max_abs_value.is_zero()) { return ChooserPoly(1, 0, new MultiplyPlainComputation(*operand.comp_, plain_max_coeff_count, plain_max_abs_value)); } if (operand.max_abs_value_.is_zero()) { return ChooserPoly(1, 0, new MultiplyPlainComputation(*operand.comp_, plain_max_coeff_count, plain_max_abs_value)); } uint64_t growth_factor = min(operand.max_coeff_count_, plain_max_coeff_count); int prod_bit_count = operand.max_abs_value_.significant_bit_count() + plain_max_abs_value.significant_bit_count() + get_significant_bit_count(growth_factor) + 1; int prod_uint64_count = divide_round_up(prod_bit_count, bits_per_uint64); Pointer prod_max_abs_value(allocate_zero_uint(prod_uint64_count, pool_)); ConstPointer wide_operand_max_abs_value(duplicate_uint_if_needed(operand.max_abs_value_.pointer(), operand.max_abs_value_.uint64_count(), prod_uint64_count, false, pool_)); multiply_uint_uint(&growth_factor, 1, plain_max_abs_value.pointer(), plain_max_abs_value.uint64_count(), prod_uint64_count, prod_max_abs_value.get()); ConstPointer temp_pointer(duplicate_uint_if_needed(prod_max_abs_value.get(), prod_uint64_count, prod_uint64_count, true, pool_)); multiply_uint_uint(wide_operand_max_abs_value.get(), prod_uint64_count, temp_pointer.get(), prod_uint64_count, prod_uint64_count, prod_max_abs_value.get()); return ChooserPoly(operand.max_coeff_count_ + plain_max_coeff_count - 1, BigUInt(prod_bit_count, prod_max_abs_value.get()), new MultiplyPlainComputation(*operand.comp_, plain_max_coeff_count, plain_max_abs_value)); }
BigUInt BigUInt::operator /(const BigUInt& operand2) const { int result_bits = significant_bit_count(); int operand2_bits = operand2.significant_bit_count(); if (operand2_bits == 0) { throw invalid_argument("operand2 must be positive"); } if (operand2_bits > result_bits) { BigUInt zero(result_bits); return zero; } BigUInt result(result_bits); BigUInt remainder(result_bits); MemoryPool pool; int uint64_count = divide_round_up(result_bits, bits_per_uint64); if (uint64_count > operand2.uint64_count()) { BigUInt operand2resized(result_bits); operand2resized = operand2; divide_uint_uint(value_, operand2resized.pointer(), uint64_count, result.pointer(), remainder.pointer(), pool); } else { divide_uint_uint(value_, operand2.pointer(), uint64_count, result.pointer(), remainder.pointer(), pool); } return result; }
BigUInt BigUInt::operator *(const BigUInt& operand2) const { int result_bits = significant_bit_count() + operand2.significant_bit_count(); BigUInt result(result_bits); multiply_uint_uint(value_, uint64_count(), operand2.pointer(), operand2.uint64_count(), result.uint64_count(), result.pointer()); return result; }
BigUInt BigUInt::operator -(const BigUInt& operand2) const { int result_bits = max(bit_count_, operand2.bit_count()); BigUInt result(result_bits); sub_uint_uint(value_, uint64_count(), operand2.pointer(), operand2.uint64_count(), false, result.uint64_count(), result.pointer()); filter_highbits_uint(result.pointer(), result.uint64_count(), result_bits); return result; }
int main(int argc, char **argv) { if (argc < 2) { cerr << "Error: Invalid argumets." << endl; cerr << "\nUsage:"<< endl; cerr << "\t" << argv[0] << " <in-filename> <out-filename>" << endl; return -1; } ifstream fin(argv[1], ifstream::in); //ofstream fout(argv[2], ofstream::out); int num_tests; fin >> num_tests; //fout << num_tests << endl; uint64_t total_time = 0; for (int i = 0; i < num_tests; ++i) { string op1_str, op2_str; fin >> op1_str >> op2_str; BigUInt op1(op1_str); BigUInt op2(op2_str); //fout << op1.ToString() << endl; //fout << op2.ToString() << endl; BigUInt sum; struct timeval tv_beg, tv_end; struct timezone tz; gettimeofday(&tv_beg, &tz); sum = op1 + op2; gettimeofday(&tv_end, &tz); total_time += GetTimeDifference(tv_beg, tv_end); string add_str; fin >> add_str; //fout << sum.ToString() << endl; if (!add_str.compare(sum.ToString())) { //cout << i << " : " << "Success: Addition" << endl; } else { cerr << i << " : " << "Failure: Addition" << endl; } } fin.close(); //fout.close(); cout << total_time << endl; return 0; }
static BigUInt multOffset(const BigUInt &left, int value, int offset) { BigUInt result; result.resize(offset + left.m_data.size()); for (unsigned int i=0; i < left.m_data.size(); ++i) { result.m_data[i+offset] = left.m_data[i] * value; } result.normalize(); return result; }
BigUInt BigUInt::operator %(const BigUInt& operand2) const { if (operand2.is_zero()) { throw invalid_argument("operand2 must be positive"); } MemoryPool pool; Modulus modulus(operand2.pointer(), operand2.uint64_count(), pool); int result_bits = significant_bit_count(); BigUInt result(result_bits); result = *this; int uint64_count = divide_round_up(result_bits, bits_per_uint64); modulo_uint_inplace(result.pointer(), uint64_count, modulus, pool); return result; }
BigPoly exponentiate_poly_polymod_coeffmod(const BigPoly &operand, const BigUInt &exponent, const BigPoly &poly_modulus, const BigUInt &coeff_modulus, const MemoryPoolHandle &pool) { BigPoly result(poly_modulus.coeff_count(), coeff_modulus.significant_bit_count()); exponentiate_poly_polymod_coeffmod(operand, exponent, poly_modulus, coeff_modulus, result, pool); return result; }
int main() { int i, len; char line[300]; while(scanf("%s", line) != EOF) { x.get_from_str(line); scanf("%s", line); y.get_from_str(line); r = x*y; println_biguint(r); x.reset(); y.reset(); } return 0; }
BigUInt BigUInt::operator |(const BigUInt& operand2) const { int result_bits = max(bit_count_, operand2.bit_count()); BigUInt result(result_bits); int uint64_count = result.uint64_count(); if (uint64_count != this->uint64_count()) { result = *this; or_uint_uint(result.pointer(), operand2.pointer(), uint64_count, result.pointer()); } else if (uint64_count != operand2.uint64_count()) { result = operand2; or_uint_uint(result.pointer(), value_, uint64_count, result.pointer()); } else { or_uint_uint(value_, operand2.pointer(), uint64_count, result.pointer()); } return result; }
ChooserPoly::ChooserPoly(int max_coeff_count, const BigUInt &max_abs_value) : max_coeff_count_(max_coeff_count), max_abs_value_(max_abs_value), comp_(new FreshComputation()) { if (max_coeff_count <= 0) { throw invalid_argument("max_coeff_count must be strictly positive"); } if (max_abs_value.is_zero()) { max_coeff_count_ = 1; } }
void poly_eval_poly_polymod_coeffmod(const BigPoly &poly_to_evaluate, const BigPoly &poly_to_evaluate_at, const BigPoly &poly_modulus, const BigUInt &coeff_modulus, BigPoly &destination, const MemoryPoolHandle &pool) { if (!pool) { throw invalid_argument("pool is uninitialized"); } if (poly_to_evaluate.significant_coeff_count() > poly_modulus.coeff_count() || poly_to_evaluate.significant_coeff_bit_count() > coeff_modulus.significant_bit_count()) { throw invalid_argument("poly_to_evaluate is not reduced"); } if (poly_to_evaluate_at.significant_coeff_count() > poly_modulus.coeff_count() || poly_to_evaluate_at.significant_coeff_bit_count() > coeff_modulus.significant_bit_count()) { throw invalid_argument("poly_to_evaluate_at is not reduced"); } int poly_to_eval_coeff_uint64_count = poly_to_evaluate.coeff_uint64_count(); int coeff_modulus_bit_count = coeff_modulus.significant_bit_count(); if (poly_to_evaluate.is_zero()) { destination.set_zero(); } if (poly_to_evaluate_at.is_zero()) { destination.resize(1, coeff_modulus_bit_count); modulo_uint(poly_to_evaluate.data(), poly_to_eval_coeff_uint64_count, Modulus(coeff_modulus.data(), coeff_modulus.uint64_count(), pool), destination.data(), pool); return; } ConstPointer poly_to_eval_ptr = duplicate_poly_if_needed(poly_to_evaluate, poly_modulus.coeff_count(), coeff_modulus.uint64_count(), false, pool); ConstPointer poly_to_eval_at_ptr = duplicate_poly_if_needed(poly_to_evaluate_at, poly_modulus.coeff_count(), coeff_modulus.uint64_count(), false, pool); destination.resize(poly_modulus.coeff_count(), coeff_modulus_bit_count); util::poly_eval_poly_polymod_coeffmod(poly_to_eval_ptr.get(), poly_to_eval_at_ptr.get(), PolyModulus(poly_modulus.data(), poly_modulus.coeff_count(), poly_modulus.coeff_uint64_count()), Modulus(coeff_modulus.data(), coeff_modulus.uint64_count(), pool), destination.data(), pool); }
ChooserPoly ChooserEvaluator::sub_plain(const ChooserPoly &operand, int plain_max_coeff_count, const BigUInt &plain_max_abs_value) { if (operand.max_coeff_count_ <= 0 || operand.comp_ == nullptr) { throw invalid_argument("operand is not correctly initialized"); } if (plain_max_coeff_count <= 0) { throw invalid_argument("plain_max_coeff_count must be positive"); } if (plain_max_abs_value.is_zero()) { return ChooserPoly(operand.max_coeff_count_, operand.max_abs_value_, new SubPlainComputation(*operand.comp_)); } if (operand.max_abs_value_.is_zero()) { return ChooserPoly(plain_max_coeff_count, plain_max_abs_value, new SubPlainComputation(*operand.comp_)); } return ChooserPoly(max(operand.max_coeff_count_, plain_max_coeff_count), operand.max_abs_value_ + plain_max_abs_value, new SubPlainComputation(*operand.comp_)); }
void exponentiate_poly_polymod_coeffmod(const BigPoly &operand, const BigUInt &exponent, const BigPoly &poly_modulus, const BigUInt &coeff_modulus, BigPoly &destination, const MemoryPoolHandle &pool) { if (operand.significant_coeff_count() > poly_modulus.coeff_count() || operand.significant_coeff_bit_count() > coeff_modulus.significant_bit_count()) { throw invalid_argument("operand is not reduced"); } if (exponent < 0) { throw invalid_argument("exponent must be a non-negative integer"); } if (operand.is_zero() && exponent == 0) { throw invalid_argument("undefined operation"); } if (!pool) { throw invalid_argument("pool is uninitialized"); } if (operand.is_zero()) { destination.set_zero(); return; } if (destination.coeff_bit_count() != coeff_modulus.significant_bit_count() || destination.coeff_count() != poly_modulus.coeff_count()) { destination.resize(poly_modulus.coeff_count(), coeff_modulus.significant_bit_count()); } ConstPointer operand_ptr = duplicate_poly_if_needed(operand, poly_modulus.coeff_count(), coeff_modulus.uint64_count(), false, pool); util::exponentiate_poly_polymod_coeffmod(operand_ptr.get(), exponent.data(), exponent.uint64_count(), PolyModulus(poly_modulus.data(), poly_modulus.coeff_count(), poly_modulus.coeff_uint64_count()), Modulus(coeff_modulus.data(), coeff_modulus.uint64_count(), pool), destination.data(), pool); }
BigUInt::BigUInt(const BigUInt& copy) : value_(nullptr), bit_count_(0), is_alias_(false) { resize(copy.bit_count()); operator =(copy); }
BigUInt exponentiate_uint_mod(const BigUInt &operand, const BigUInt &exponent, const BigUInt &modulus, const MemoryPoolHandle &pool) { BigUInt result(modulus.significant_bit_count()); exponentiate_uint_mod(operand, exponent, modulus, result, pool); return result; }
void poly_eval_uint_mod(const BigPoly &poly_to_evaluate, const BigUInt &value, const BigUInt &modulus, BigUInt &destination, const MemoryPoolHandle &pool) { if (poly_to_evaluate.significant_coeff_bit_count() > modulus.significant_bit_count()) { throw invalid_argument("poly_to_evaluate is not reduced"); } if (value.significant_bit_count() > modulus.significant_bit_count()) { throw invalid_argument("value is not reduced"); } if (!pool) { throw invalid_argument("pool is uninitialized"); } int poly_to_eval_coeff_uint64_count = poly_to_evaluate.coeff_uint64_count(); int modulus_bit_count = modulus.significant_bit_count(); if (poly_to_evaluate.is_zero()) { destination.set_zero(); } if (value.is_zero()) { destination.resize(modulus_bit_count); modulo_uint(poly_to_evaluate.data(), poly_to_eval_coeff_uint64_count, Modulus(modulus.data(), modulus.uint64_count(), pool), destination.data(), pool); return; } ConstPointer value_ptr = duplicate_uint_if_needed(value, modulus.uint64_count(), false, pool); destination.resize(modulus_bit_count); util::poly_eval_uint_mod(poly_to_evaluate.data(), poly_to_evaluate.coeff_count(), value_ptr.get(), Modulus(modulus.data(), modulus.uint64_count(), pool), destination.data(), pool); }
void exponentiate_uint_mod(const BigUInt &operand, const BigUInt &exponent, const BigUInt &modulus, BigUInt &destination, const MemoryPoolHandle &pool) { if (operand.significant_bit_count() > modulus.significant_bit_count()) { throw invalid_argument("operand is not reduced"); } if (operand.is_zero() && exponent == 0) { throw invalid_argument("undefined operation"); } if (!pool) { throw invalid_argument("pool is uninitialized"); } if (operand.is_zero()) { destination.set_zero(); return; } if (destination.bit_count() != modulus.significant_bit_count()) { destination.resize(modulus.significant_bit_count()); } ConstPointer operand_ptr = duplicate_uint_if_needed(operand, modulus.uint64_count(), false, pool); util::exponentiate_uint_mod(operand_ptr.get(), exponent.data(), exponent.uint64_count(), Modulus(modulus.data(), modulus.uint64_count(), pool), destination.data(), pool); }