Browse Source

New buggy mult function

mawinkle 6 năm trước cách đây
mục cha
commit
52369f5516
2 tập tin đã thay đổi với 69 bổ sung13 xóa
  1. 33 2
      crypt/BigInt64.hpp
  2. 36 11
      test.cpp

+ 33 - 2
crypt/BigInt64.hpp

@@ -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

+ 36 - 11
test.cpp

@@ -3,6 +3,9 @@
 #include <xoshiro.hpp>
 #include <iostream>
 #include <chrono>
+#include <algorithm>
+#include <numeric>
+xoshiro_256 gen(42);
 unsigned long long nanoTime(){
 	using namespace std;
 	using namespace std::chrono;
@@ -26,18 +29,40 @@ std::ostream& operator<< <char>(std::ostream& out, std::vector<char> o){
 	}
 	return out;
 }
+unsigned long long multTest(size_t s){
+	BigInt a(gen,s);
+	BigInt b(gen,s);
+	std::vector<unsigned long long> times(0);
+	for(int o = 0;o < 4;o++){
+		auto t1 = nanoTime();
+		for(int i = 0;i < 1000;i++){
+			a = a.mult(b);
+			a.cut(s);
+		}
+		auto t2 = nanoTime();
+		times.push_back((t2 - t1));
+	}
+	std::sort(times.begin(), times.end());
+	/*for(auto t : times){
+		std::cout << t/1000 << ", ";
+	}*/
+	//std::cout << std::endl;
+	return std::accumulate(times.begin(), times.end(), 0ULL);
+}
 int main(){
-	xoshiro_256 gen(42);
-	BigInt a(364598273448762ULL);
-	BigInt b(gen, 31);
-	BigInt mod("25517712857249265246309662191040714920292930135958602873503082695880945015180270627160886016284304866241119009429935511497986916016509065559298646199688497746399172174316028774533924795864096565081478741603241830675436336762053778667047857025632695617746551090247164369324008907433218665135569658200641651876344533506145721941113011977317356006176781796659698883765657005845351846184505291996942442336931455986790727248315517902731173678888064950798931396279140373592203530274617983159864665935475637811846793653407441533829095478201308785445059955697867933027578011378694502392722655274554801068451419037021634697683");
-	std::cout << "\033[1;31mbold red text\n";
-	std::cout << "Modlänge" << (mod.end() - mod.begin()) << "\n";
-	std::cout << "(" << a.toString() << " ^ " << std::flush;
-	a = a.modPow(b, mod);
-	std::cout << "" << b.toString() << ")";
-	std::cout << " mod " << mod.toString() << "\n";
-	std::cout << " = " << a.toString() << "\n";
+	BigInt a(1000000000000ULL);
+	BigInt b(1000000000000ULL);
+	a = a.multNew(b);
+	std::cout << a.toString() << std::endl;
+	return 0;
+	multTest(50);
+	multTest(100);
+	multTest(200);
+	std::cout << multTest(50 ) / 1000 / 1000 << " ms" << std::endl;
+	std::cout << multTest(100) / 1000 / 1000 << " ms" << std::endl;
+	std::cout << multTest(200) / 1000 / 1000 << " ms" << std::endl;
+	std::cout << multTest(400) / 1000 / 1000 << " ms" << std::endl;
+	//std::cout << multTest(800) / 1000 / 1000 << " ms" << std::endl;
 }
 /*int mian(){
 	cppsocket sock("192.168.178.79", 80);