|
@@ -15,6 +15,11 @@
|
|
|
#include <iostream>
|
|
|
const std::vector<char> chars = {'0','1','2','3','4','5','6','7','8','9','A','B','C','D','E','F'};
|
|
|
const __uint128_t _m = ((__uint128_t)1) << 64;
|
|
|
+std::uint64_t _mulx_u64(std::uint64_t a, std::uint64_t b, std::uint64_t* hi){
|
|
|
+ __uint128_t r = a * b;
|
|
|
+ *hi = (r >> 64);
|
|
|
+ return r;
|
|
|
+}
|
|
|
template<typename T>
|
|
|
inline int signum(T t){
|
|
|
if(t < 0)return -1;
|
|
@@ -448,6 +453,9 @@ struct BigInt{
|
|
|
ret ^= o;
|
|
|
return ret;
|
|
|
}
|
|
|
+ inline BigInt& cut(size_t chunks){
|
|
|
+ while(size() > chunks)data.pop_front();
|
|
|
+ }
|
|
|
inline int bitDifference(const BigInt& o){
|
|
|
int pos1(0),pos2(0);
|
|
|
auto it1 = begin();
|
|
@@ -536,8 +544,8 @@ struct BigInt{
|
|
|
while(it1 != rend() && it2 != o.rend()){
|
|
|
carry = __builtin_uaddll_overflow(*it1, *it2 + carry, (unsigned long long*)(&(*it1)));
|
|
|
carry |= (*it2 + carry) == 0 && *it2;
|
|
|
- it1++;
|
|
|
- it2++;
|
|
|
+ ++it1;
|
|
|
+ ++it2;
|
|
|
}
|
|
|
while(it1 != rend() && carry){
|
|
|
carry = __builtin_uaddll_overflow(*it1, carry, (unsigned long long*)(&(*it1)));
|
|
@@ -608,6 +616,28 @@ struct BigInt{
|
|
|
if(o == 1){t = t.mult(odd);t.moda(mod);return t;}
|
|
|
}
|
|
|
}
|
|
|
+ inline BigInt multNew(const BigInt& o)const{
|
|
|
+ BigInt result(size() + o.size() + 1,0);
|
|
|
+ BigInt temp(size() + o.size() + 1,0);
|
|
|
+ int p = 0;
|
|
|
+ for(auto it1 = rbegin();it1 != rend();it1++){
|
|
|
+ auto it = temp.rbegin();
|
|
|
+ uint64_t carry = 0;
|
|
|
+ for(auto it2 = o.rbegin();it2 != o.rend();it2++){
|
|
|
+ uint64_t hi;
|
|
|
+ uint64_t lo = _mulx_u64(*it1, *it2, &hi);
|
|
|
+ bool ac = __builtin_uaddll_overflow(lo, carry, (unsigned long long*)(&(*(it++))));
|
|
|
+ carry = hi + ac;
|
|
|
+ }
|
|
|
+ if(carry)(*it) += carry;
|
|
|
+ temp.chunkshiftLeft(p++);
|
|
|
+ result.adda(temp);
|
|
|
+ temp.setZero();
|
|
|
+ }
|
|
|
+ result.trim();
|
|
|
+ return result;
|
|
|
+ }
|
|
|
+
|
|
|
inline BigInt mult(const BigInt& o)const{
|
|
|
BigInt result(size() + o.size() + 1,0);
|
|
|
BigInt temp(size() + o.size() + 1,0);
|
|
@@ -701,4 +731,5 @@ namespace std{
|
|
|
}
|
|
|
};
|
|
|
}
|
|
|
+const static BigInt secure_prime("25517712857249265246309662191040714920292930135958602873503082695880945015180270627160886016284304866241119009429935511497986916016509065559298646199688497746399172174316028774533924795864096565081478741603241830675436336762053778667047857025632695617746551090247164369324008907433218665135569658200641651876344533506145721941113011977317356006176781796659698883765657005845351846184505291996942442336931455986790727248315517902731173678888064950798931396279140373592203530274617983159864665935475637811846793653407441533829095478201308785445059955697867933027578011378694502392722655274554801068451419037021634697683");
|
|
|
#endif //BIGINT64_HPP
|