BigInt operator /(const BigInt& l, const BigInt& r) { int carry_sign = l.sign * r.sign; BigInt result = l.abs(); BigInt rr = r.abs(); result /= rr; if ( result.size() > 1 ) { result.sign = carry_sign; } return result; }
BigInt BigInt::operator -(const BigInt& right) const { BigInt left = *this; if (left.sign != right.sign) { return left - (-right); } if (this->abs() >= right.abs()) { BigInt res = left; int carry = 0; for (int i = 0; i < right.number.size() || carry; ++i) { res.number[i] -= carry + (i < right.number.size() ? right.number[i] : 0); carry = res.number[i] < 0; if (carry) { res.number[i] += BigInt::base; } } res.RemoveZero(); return res; } else { return -(right - left); } }
void BigInt::operator +=(BigInt num) { if (_sign == SIGN_POSITIVE && num._sign == SIGN_NEGATIVE){ return (*this) -= num.abs(); } if (_sign == SIGN_NEGATIVE && num._sign == SIGN_POSITIVE){ (*this) = num - (*this).abs(); return; } BigInt num1 = getLength() >= num.getLength() ? (*this) : num; BigInt num2 = getLength() >= num.getLength() ? num : (*this); int carry = 0; for (auto digit = num1._number.rbegin(); digit != num1._number.rend(); ++digit){ if (num2.getLength() > 0){ (*digit) += num2._number.back(); num2._number.pop_back(); } (*digit) += carry; carry = 0; if (*digit >= 10){ (*digit) -= 10; if (digit == (num1._number.rend() - 1)){ num1._number.push_front(1); } else { carry = 1; } } } (*this) = num1; }
static BigInt gcd(const BigInt &a, const BigInt &b) { const BigInt zero("0"); BigInt big, small, tmp; BigInt absnum1_=a.abs(); BigInt absnum2_=b.abs(); big=max(absnum1_, absnum2_); small=min(absnum1_,absnum2_); tmp=big%small; while(tmp!=zero) { big=small; small=tmp; tmp=big%small; } return small; }
void BigInt::operator /=(BigInt num) { if (num == (*this)){ (*this) = 1; return; } if (2 * num.abs() > abs()){ (*this) = 0; return; } BigInt result = 0; BigInt currentDivident; BigInt partialResult; for (auto digit = _number.cbegin(); digit != _number.cend(); ++digit){ currentDivident._number.push_back(*digit); currentDivident._lTrim(); if (currentDivident < num){ continue; } for (int i = 1; i < 10; i++){ if (num * i >= currentDivident){ result._lTrim(); result._number.push_back(--i); currentDivident -= (i * num); break; } } std::cout << (std::string)currentDivident<<std::endl; } result._lTrim(); (*this) = result; }
void BigInt::operator -=(BigInt num) { if (num._sign == SIGN_NEGATIVE){ return (*this) += num.abs(); } if (_sign == SIGN_NEGATIVE){ *this = (*this).abs() + num; (*this)._sign = SIGN_NEGATIVE; return; } BigInt minuent = (*this) >= num ? (*this) : num; BigInt subtrahend = (*this) >= num ? num : (*this); int carry = 0; for (auto digit = minuent._number.rbegin(); digit != minuent._number.rend(); ++digit){ if (subtrahend.getLength() > 0){ (*digit) -= subtrahend._number.back(); subtrahend._number.pop_back(); } (*digit) -= carry; carry = 0; if (*digit < 0){ if (digit != minuent._number.rbegin() - 1){ (*digit) += 10; carry = 1; } else { (*digit) *= -1; minuent._sign = SIGN_NEGATIVE; } } } bool negative = (*this) < num; (*this) = minuent.copy(); if (negative && (*this) != 0){ _sign = SIGN_NEGATIVE; } _lTrim(); }
PointGFp operator*(const BigInt& scalar, const PointGFp& point) { const CurveGFp& curve = point.get_curve(); if(scalar.is_zero()) return PointGFp(curve); // zero point std::vector<BigInt> ws(9); if(scalar.abs() <= 2) // special cases for small values { byte value = scalar.abs().byte_at(0); PointGFp result = point; if(value == 2) result.mult2(ws); if(scalar.is_negative()) result.negate(); return result; } const size_t scalar_bits = scalar.bits(); #if 0 PointGFp x1 = PointGFp(curve); PointGFp x2 = point; size_t bits_left = scalar_bits; // Montgomery Ladder while(bits_left) { const bool bit_set = scalar.get_bit(bits_left - 1); if(bit_set) { x1.add(x2, ws); x2.mult2(ws); } else { x2.add(x1, ws); x1.mult2(ws); } --bits_left; } if(scalar.is_negative()) x1.negate(); return x1; #else const size_t window_size = 4; std::vector<PointGFp> Ps(1 << window_size); Ps[0] = PointGFp(curve); Ps[1] = point; for(size_t i = 2; i != Ps.size(); ++i) { Ps[i] = Ps[i-1]; Ps[i].add(point, ws); } PointGFp H(curve); // create as zero size_t bits_left = scalar_bits; while(bits_left >= window_size) { for(size_t i = 0; i != window_size; ++i) H.mult2(ws); const u32bit nibble = scalar.get_substring(bits_left - window_size, window_size); H.add(Ps[nibble], ws); bits_left -= window_size; } while(bits_left) { H.mult2(ws); if(scalar.get_bit(bits_left-1)) H.add(point, ws); --bits_left; } if(scalar.is_negative()) H.negate(); return H; #endif }