|
@@ -1,115 +1,497 @@
|
|
#include <iostream>
|
|
#include <iostream>
|
|
|
|
+#include <random>
|
|
|
|
+#include <chrono>
|
|
|
|
|
|
#include "BGN.hpp"
|
|
#include "BGN.hpp"
|
|
|
|
|
|
-int main(void)
|
|
+using namespace std;
|
|
|
|
+
|
|
|
|
+const size_t NUM_RUNS_PER_TEST = 100;
|
|
|
|
+const size_t MAX_VALUE_IN_TEST = 999;
|
|
|
|
+
|
|
|
|
+bool testDecrypt(int x)
|
|
|
|
+{
|
|
|
|
+ bool retval;
|
|
|
|
+
|
|
|
|
+ BGN system;
|
|
|
|
+
|
|
|
|
+ Scalar testVal(x);
|
|
|
|
+ Scalar one(1);
|
|
|
|
+ Scalar decrypted;
|
|
|
|
+
|
|
|
|
+ CurveBipoint curveEnc, curveOne;
|
|
|
|
+ TwistBipoint twistEnc, twistOne;
|
|
|
|
+ Quadripoint quadEncA, quadEncB;
|
|
|
|
+
|
|
|
|
+ system.encrypt(curveEnc, testVal);
|
|
|
|
+ system.encrypt(curveOne, one);
|
|
|
|
+ system.encrypt(twistEnc, testVal);
|
|
|
|
+ system.encrypt(twistOne, one);
|
|
|
|
+
|
|
|
|
+ quadEncA = system.homomorphic_multiplication(curveEnc, twistOne);
|
|
|
|
+ quadEncB = system.homomorphic_multiplication(curveOne, twistEnc);
|
|
|
|
+
|
|
|
|
+ decrypted = system.decrypt(curveEnc);
|
|
|
|
+ retval = (decrypted == testVal);
|
|
|
|
+
|
|
|
|
+ decrypted = system.decrypt(twistEnc);
|
|
|
|
+ retval = retval && (decrypted == testVal);
|
|
|
|
+
|
|
|
|
+ decrypted = system.decrypt(quadEncA);
|
|
|
|
+ retval = retval && (decrypted == testVal);
|
|
|
|
+
|
|
|
|
+ decrypted = system.decrypt(quadEncB);
|
|
|
|
+ retval = retval && (decrypted == testVal);
|
|
|
|
+
|
|
|
|
+ return retval;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+double testCurveEncryptSpeed(default_random_engine& generator)
|
|
|
|
+{
|
|
|
|
+ BGN system;
|
|
|
|
+
|
|
|
|
+ uniform_int_distribution<int> distribution(0, MAX_VALUE_IN_TEST);
|
|
|
|
+
|
|
|
|
+ vector<Scalar> testVals;
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ testVals.push_back(Scalar(distribution(generator)));
|
|
|
|
+
|
|
|
|
+ vector<CurveBipoint> encryptions(NUM_RUNS_PER_TEST);
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t0 = chrono::high_resolution_clock::now();
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ system.encrypt(encryptions[i], testVals[i]);
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now();
|
|
|
|
+ chrono::duration<double> time_span = chrono::duration_cast<chrono::duration<double>>(t1 - t0);
|
|
|
|
+
|
|
|
|
+ return time_span.count();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+double testTwistEncryptSpeed(default_random_engine& generator)
|
|
|
|
+{
|
|
|
|
+ BGN system;
|
|
|
|
+
|
|
|
|
+ uniform_int_distribution<int> distribution(0, MAX_VALUE_IN_TEST);
|
|
|
|
+
|
|
|
|
+ vector<Scalar> testVals;
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ testVals.push_back(Scalar(distribution(generator)));
|
|
|
|
+
|
|
|
|
+ vector<TwistBipoint> encryptions(NUM_RUNS_PER_TEST);
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t0 = chrono::high_resolution_clock::now();
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ system.encrypt(encryptions[i], testVals[i]);
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now();
|
|
|
|
+ chrono::duration<double> time_span = chrono::duration_cast<chrono::duration<double>>(t1 - t0);
|
|
|
|
+
|
|
|
|
+ return time_span.count();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+double testCurveDecryptSpeed(default_random_engine& generator)
|
|
{
|
|
{
|
|
BGN system;
|
|
BGN system;
|
|
|
|
|
|
- Scalar test0(0);
|
|
+ uniform_int_distribution<int> distribution(0, MAX_VALUE_IN_TEST);
|
|
- Scalar test1(1);
|
|
+
|
|
- Scalar test3(3);
|
|
+ vector<Scalar> testVals;
|
|
- Scalar test5(5);
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
- Scalar test6(6);
|
|
+ testVals.push_back(Scalar(distribution(generator)));
|
|
- Scalar test10(10);
|
|
|
|
- Scalar test15(15);
|
|
|
|
- Scalar test30(30);
|
|
|
|
|
|
|
|
|
|
+ vector<CurveBipoint> encryptions(NUM_RUNS_PER_TEST);
|
|
|
|
+ vector<Scalar> decryptions(NUM_RUNS_PER_TEST);
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ system.encrypt(encryptions[i], testVals[i]);
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t0 = chrono::high_resolution_clock::now();
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ decryptions[i] = system.decrypt(encryptions[i]);
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now();
|
|
|
|
+ chrono::duration<double> time_span = chrono::duration_cast<chrono::duration<double>>(t1 - t0);
|
|
|
|
+
|
|
|
|
+ return time_span.count();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+double testTwistDecryptSpeed(default_random_engine& generator)
|
|
|
|
+{
|
|
|
|
+ BGN system;
|
|
|
|
+
|
|
|
|
+ uniform_int_distribution<int> distribution(0, MAX_VALUE_IN_TEST);
|
|
|
|
+
|
|
|
|
+ vector<Scalar> testVals;
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ testVals.push_back(Scalar(distribution(generator)));
|
|
|
|
+
|
|
|
|
+ vector<TwistBipoint> encryptions(NUM_RUNS_PER_TEST);
|
|
|
|
+ vector<Scalar> decryptions(NUM_RUNS_PER_TEST);
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ system.encrypt(encryptions[i], testVals[i]);
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t0 = chrono::high_resolution_clock::now();
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ decryptions[i] = system.decrypt(encryptions[i]);
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now();
|
|
|
|
+ chrono::duration<double> time_span = chrono::duration_cast<chrono::duration<double>>(t1 - t0);
|
|
|
|
+
|
|
|
|
+ return time_span.count();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+double testQuadDecryptSpeed(default_random_engine& generator)
|
|
|
|
+{
|
|
|
|
+ BGN system;
|
|
|
|
+
|
|
|
|
+ uniform_int_distribution<int> distribution(0, MAX_VALUE_IN_TEST);
|
|
|
|
+
|
|
|
|
+ vector<Scalar> testVals;
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ testVals.push_back(Scalar(distribution(generator)));
|
|
|
|
+
|
|
|
|
+ Scalar one(1);
|
|
|
|
+
|
|
|
|
+ TwistBipoint oneEncryption;
|
|
|
|
+ vector<CurveBipoint> firstEncryptions(NUM_RUNS_PER_TEST);
|
|
|
|
+ vector<Quadripoint> realEncryptions(NUM_RUNS_PER_TEST);
|
|
|
|
+ vector<Scalar> decryptions(NUM_RUNS_PER_TEST);
|
|
|
|
+
|
|
|
|
+ system.encrypt(oneEncryption, one);
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ {
|
|
|
|
+ system.encrypt(firstEncryptions[i], testVals[i]);
|
|
|
|
+ realEncryptions[i] = system.homomorphic_multiplication(firstEncryptions[i], oneEncryption);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t0 = chrono::high_resolution_clock::now();
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ decryptions[i] = system.decrypt(realEncryptions[i]);
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now();
|
|
|
|
+ chrono::duration<double> time_span = chrono::duration_cast<chrono::duration<double>>(t1 - t0);
|
|
|
|
+
|
|
|
|
+ return time_span.count();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool testAddition(int x, int y)
|
|
|
|
+{
|
|
|
|
+ bool retval;
|
|
|
|
+
|
|
|
|
+ BGN system;
|
|
|
|
+
|
|
|
|
+ Scalar testX(x);
|
|
|
|
+ Scalar testY(y);
|
|
|
|
+ Scalar testSum(x + y);
|
|
|
|
+ Scalar one(1);
|
|
Scalar decrypted;
|
|
Scalar decrypted;
|
|
|
|
|
|
- std::cout << "Scalar test value (0): " << test0 << std::endl;
|
|
+ CurveBipoint curveX, curveY, curveSum, curveOne;
|
|
- std::cout << "Scalar test value (1): " << test1 << std::endl;
|
|
+ TwistBipoint twistX, twistY, twistSum, twistOne;
|
|
- std::cout << "Scalar test value (3): " << test3 << std::endl;
|
|
+ Quadripoint quadXA, quadXB, quadYA, quadYB,
|
|
- std::cout << "Scalar test value (5): " << test5 << std::endl;
|
|
+ quadSumAA, quadSumAB, quadSumBA, quadSumBB;
|
|
|
|
+
|
|
|
|
+ system.encrypt(curveX, testX);
|
|
|
|
+ system.encrypt(curveY, testY);
|
|
|
|
+ system.encrypt(curveOne, one);
|
|
|
|
+ system.encrypt(twistX, testX);
|
|
|
|
+ system.encrypt(twistY, testY);
|
|
|
|
+ system.encrypt(twistOne, one);
|
|
|
|
+
|
|
|
|
+ curveSum = system.homomorphic_addition(curveX, curveY);
|
|
|
|
+ twistSum = system.homomorphic_addition(twistX, twistY);
|
|
|
|
+
|
|
|
|
+ quadXA = system.homomorphic_multiplication(curveX, twistOne);
|
|
|
|
+ quadXB = system.homomorphic_multiplication(curveOne, twistX);
|
|
|
|
+ quadYA = system.homomorphic_multiplication(curveY, twistOne);
|
|
|
|
+ quadYB = system.homomorphic_multiplication(curveOne, twistY);
|
|
|
|
|
|
- CurveBipoint encrypted0, encrypted1, encrypted3, encrypted6;
|
|
+ quadSumAA = system.homomorphic_addition(quadXA, quadYA);
|
|
- TwistBipoint encrypted5, encrypted10;
|
|
+ quadSumAB = system.homomorphic_addition(quadXA, quadYB);
|
|
- Quadripoint encrypted15, encrypted30;
|
|
+ quadSumBA = system.homomorphic_addition(quadXB, quadYA);
|
|
|
|
+ quadSumBB = system.homomorphic_addition(quadXB, quadYB);
|
|
|
|
|
|
- std::cout << "Performing encryptions" << std::endl;
|
|
+ decrypted = system.decrypt(curveSum);
|
|
|
|
+ retval = (decrypted == testSum);
|
|
|
|
|
|
- system.encrypt(encrypted0, test0);
|
|
+ decrypted = system.decrypt(twistSum);
|
|
- system.encrypt(encrypted1, test1);
|
|
+ retval = retval && (decrypted == testSum);
|
|
- system.encrypt(encrypted3, test3);
|
|
|
|
- system.encrypt(encrypted5, test5);
|
|
|
|
|
|
|
|
- std::cout << "Performing additions" << std::endl;
|
|
+ decrypted = system.decrypt(quadSumAA);
|
|
|
|
+ retval = retval && (decrypted == testSum);
|
|
|
|
|
|
- encrypted6 = system.homomorphic_addition(encrypted3, encrypted3);
|
|
+ decrypted = system.decrypt(quadSumAB);
|
|
- encrypted10 = system.homomorphic_addition(encrypted5, encrypted5);
|
|
+ retval = retval && (decrypted == testSum);
|
|
|
|
|
|
- std::cout << "Performing multiplication" << std::endl;
|
|
+ decrypted = system.decrypt(quadSumBA);
|
|
|
|
+ retval = retval && (decrypted == testSum);
|
|
|
|
|
|
- encrypted15 = system.homomorphic_multiplication(encrypted3, encrypted5);
|
|
+ decrypted = system.decrypt(quadSumBB);
|
|
|
|
+ retval = retval && (decrypted == testSum);
|
|
|
|
|
|
- std::cout << "Performing L2 addition" << std::endl;
|
|
+ return retval;
|
|
|
|
+}
|
|
|
|
|
|
- encrypted30 = system.homomorphic_addition(encrypted15, encrypted15);
|
|
+double testCurveAdditionSpeed(default_random_engine& generator)
|
|
|
|
+{
|
|
|
|
+ BGN system;
|
|
|
|
|
|
- std::cout << "Performing decryptions" << std::endl;
|
|
+ uniform_int_distribution<int> distribution(0, MAX_VALUE_IN_TEST);
|
|
|
|
|
|
- decrypted = system.decrypt(encrypted0);
|
|
+ vector<Scalar> testXs;
|
|
- std::cout << "Decryption of point at infinity (0): ";
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
- if (decrypted == test0)
|
|
+ testXs.push_back(Scalar(distribution(generator)));
|
|
- std::cout << "PASS" << std::endl;
|
|
+
|
|
- else
|
|
+ vector<Scalar> testYs;
|
|
- std::cout << "FAIL" << std::endl;
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ testYs.push_back(Scalar(distribution(generator)));
|
|
|
|
+
|
|
|
|
+ vector<CurveBipoint> encXs(NUM_RUNS_PER_TEST);
|
|
|
|
+ vector<CurveBipoint> encYs(NUM_RUNS_PER_TEST);
|
|
|
|
+ vector<CurveBipoint> encSums(NUM_RUNS_PER_TEST);
|
|
|
|
|
|
- decrypted = system.decrypt(encrypted1);
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
- std::cout << "Decryption of generator (1): ";
|
|
+ {
|
|
- if (decrypted == test1)
|
|
+ system.encrypt(encXs[i], testXs[i]);
|
|
- std::cout << "PASS" << std::endl;
|
|
+ system.encrypt(encYs[i], testYs[i]);
|
|
- else
|
|
+ }
|
|
- std::cout << "FAIL" << std::endl;
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t0 = chrono::high_resolution_clock::now();
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ encSums[i] = system.homomorphic_addition(encXs[i], encYs[i]);
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now();
|
|
|
|
+ chrono::duration<double> time_span = chrono::duration_cast<chrono::duration<double>>(t1 - t0);
|
|
|
|
+
|
|
|
|
+ return time_span.count();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+double testTwistAdditionSpeed(default_random_engine& generator)
|
|
|
|
+{
|
|
|
|
+ BGN system;
|
|
|
|
+
|
|
|
|
+ uniform_int_distribution<int> distribution(0, MAX_VALUE_IN_TEST);
|
|
|
|
+
|
|
|
|
+ vector<Scalar> testXs;
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ testXs.push_back(Scalar(distribution(generator)));
|
|
|
|
+
|
|
|
|
+ vector<Scalar> testYs;
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ testYs.push_back(Scalar(distribution(generator)));
|
|
|
|
+
|
|
|
|
+ vector<TwistBipoint> encXs(NUM_RUNS_PER_TEST);
|
|
|
|
+ vector<TwistBipoint> encYs(NUM_RUNS_PER_TEST);
|
|
|
|
+ vector<TwistBipoint> encSums(NUM_RUNS_PER_TEST);
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ {
|
|
|
|
+ system.encrypt(encXs[i], testXs[i]);
|
|
|
|
+ system.encrypt(encYs[i], testYs[i]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t0 = chrono::high_resolution_clock::now();
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ encSums[i] = system.homomorphic_addition(encXs[i], encYs[i]);
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now();
|
|
|
|
+ chrono::duration<double> time_span = chrono::duration_cast<chrono::duration<double>>(t1 - t0);
|
|
|
|
+
|
|
|
|
+ return time_span.count();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+double testQuadAdditionSpeed(default_random_engine& generator)
|
|
|
|
+{
|
|
|
|
+ BGN system;
|
|
|
|
+
|
|
|
|
+ uniform_int_distribution<int> distribution(0, MAX_VALUE_IN_TEST);
|
|
|
|
|
|
- decrypted = system.decrypt(encrypted1);
|
|
+ vector<Scalar> testXs;
|
|
- std::cout << "Memoization: ";
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
- if (decrypted == test1)
|
|
+ testXs.push_back(Scalar(distribution(generator)));
|
|
- std::cout << "PASS" << std::endl;
|
|
+
|
|
|
|
+ vector<Scalar> testYs;
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ testYs.push_back(Scalar(distribution(generator)));
|
|
|
|
+
|
|
|
|
+ Scalar one(1);
|
|
|
|
+
|
|
|
|
+ TwistBipoint oneEncryption;
|
|
|
|
+ vector<CurveBipoint> firstEncXs(NUM_RUNS_PER_TEST);
|
|
|
|
+ vector<Quadripoint> realEncXs(NUM_RUNS_PER_TEST);
|
|
|
|
+ vector<CurveBipoint> firstEncYs(NUM_RUNS_PER_TEST);
|
|
|
|
+ vector<Quadripoint> realEncYs(NUM_RUNS_PER_TEST);
|
|
|
|
+ vector<Quadripoint> encSums(NUM_RUNS_PER_TEST);
|
|
|
|
+
|
|
|
|
+ system.encrypt(oneEncryption, one);
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ {
|
|
|
|
+ system.encrypt(firstEncXs[i], testXs[i]);
|
|
|
|
+ system.encrypt(firstEncYs[i], testYs[i]);
|
|
|
|
+ realEncXs[i] = system.homomorphic_multiplication(firstEncXs[i], oneEncryption);
|
|
|
|
+ realEncYs[i] = system.homomorphic_multiplication(firstEncYs[i], oneEncryption);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t0 = chrono::high_resolution_clock::now();
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ encSums[i] = system.homomorphic_addition(realEncXs[i], realEncYs[i]);
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now();
|
|
|
|
+ chrono::duration<double> time_span = chrono::duration_cast<chrono::duration<double>>(t1 - t0);
|
|
|
|
+
|
|
|
|
+ return time_span.count();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+bool testMultiplication(int x, int y)
|
|
|
|
+{
|
|
|
|
+ bool retval;
|
|
|
|
+
|
|
|
|
+ BGN system;
|
|
|
|
+
|
|
|
|
+ Scalar testX(x);
|
|
|
|
+ Scalar testY(y);
|
|
|
|
+ Scalar testProduct(x * y);
|
|
|
|
+ Scalar decrypted;
|
|
|
|
+
|
|
|
|
+ CurveBipoint curveX, curveY;
|
|
|
|
+ TwistBipoint twistX, twistY;
|
|
|
|
+ Quadripoint productA, productB;
|
|
|
|
+
|
|
|
|
+ system.encrypt(curveX, testX);
|
|
|
|
+ system.encrypt(curveY, testY);
|
|
|
|
+ system.encrypt(twistX, testX);
|
|
|
|
+ system.encrypt(twistY, testY);
|
|
|
|
+
|
|
|
|
+ productA = system.homomorphic_multiplication(curveX, twistY);
|
|
|
|
+ productB = system.homomorphic_multiplication(curveY, twistX);
|
|
|
|
+
|
|
|
|
+ decrypted = system.decrypt(productA);
|
|
|
|
+ retval = (decrypted == testProduct);
|
|
|
|
+
|
|
|
|
+ decrypted = system.decrypt(productB);
|
|
|
|
+ retval = retval && (decrypted == testProduct);
|
|
|
|
+
|
|
|
|
+ return retval;
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+double testMultiplicationSpeed(default_random_engine& generator)
|
|
|
|
+{
|
|
|
|
+ BGN system;
|
|
|
|
+
|
|
|
|
+ uniform_int_distribution<int> distribution(0, MAX_VALUE_IN_TEST);
|
|
|
|
+
|
|
|
|
+ vector<Scalar> testXs;
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ testXs.push_back(Scalar(distribution(generator)));
|
|
|
|
+
|
|
|
|
+ vector<Scalar> testYs;
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ testYs.push_back(Scalar(distribution(generator)));
|
|
|
|
+
|
|
|
|
+ vector<CurveBipoint> encXs(NUM_RUNS_PER_TEST);
|
|
|
|
+ vector<TwistBipoint> encYs(NUM_RUNS_PER_TEST);
|
|
|
|
+ vector<Quadripoint> encProducts(NUM_RUNS_PER_TEST);
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ {
|
|
|
|
+ system.encrypt(encXs[i], testXs[i]);
|
|
|
|
+ system.encrypt(encYs[i], testYs[i]);
|
|
|
|
+ }
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t0 = chrono::high_resolution_clock::now();
|
|
|
|
+
|
|
|
|
+ for (size_t i = 0; i < NUM_RUNS_PER_TEST; i++)
|
|
|
|
+ encProducts[i] = system.homomorphic_multiplication(encXs[i], encYs[i]);
|
|
|
|
+
|
|
|
|
+ chrono::high_resolution_clock::time_point t1 = chrono::high_resolution_clock::now();
|
|
|
|
+ chrono::duration<double> time_span = chrono::duration_cast<chrono::duration<double>>(t1 - t0);
|
|
|
|
+
|
|
|
|
+ return time_span.count();
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+int main(int argc, char *argv[])
|
|
|
|
+{
|
|
|
|
+ string seedStr("default");
|
|
|
|
+ if (argc > 1)
|
|
|
|
+ seedStr = argv[1];
|
|
|
|
+
|
|
|
|
+ seed_seq seed(seedStr.begin(), seedStr.end());
|
|
|
|
+ default_random_engine generator(seed);
|
|
|
|
+ uniform_int_distribution<int> distribution(0, MAX_VALUE_IN_TEST);
|
|
|
|
+
|
|
|
|
+ cout << "test_PointAtInfinity: ";
|
|
|
|
+ if (testDecrypt(0))
|
|
|
|
+ cout << "PASS" << endl;
|
|
else
|
|
else
|
|
- std::cout << "FAIL" << std::endl;
|
|
+ cout << "FAIL" << endl;
|
|
|
|
|
|
- decrypted = system.decrypt(encrypted3);
|
|
+ cout << "test_GeneratorPoint: ";
|
|
- std::cout << "Decryption of normal point in G (3): ";
|
|
+ if (testDecrypt(1))
|
|
- if (decrypted == test3)
|
|
+ cout << "PASS" << endl;
|
|
- std::cout << "PASS" << std::endl;
|
|
|
|
else
|
|
else
|
|
- std::cout << "FAIL" << std::endl;
|
|
+ cout << "FAIL" << endl;
|
|
|
|
|
|
- decrypted = system.decrypt(encrypted5);
|
|
+ int randomPoint = distribution(generator);
|
|
- std::cout << "Decryption of normal point in H (5): ";
|
|
+ cout << "test_RandomPoint (" << randomPoint << "): ";
|
|
- if (decrypted == test5)
|
|
+ if (testDecrypt(randomPoint))
|
|
- std::cout << "PASS" << std::endl;
|
|
+ cout << "PASS" << endl;
|
|
else
|
|
else
|
|
- std::cout << "FAIL" << std::endl;
|
|
+ cout << "FAIL" << endl;
|
|
|
|
|
|
- decrypted = system.decrypt(encrypted6);
|
|
+ cout << "test_CurveEncryptSpeed (" << NUM_RUNS_PER_TEST << " runs): ";
|
|
- std::cout << "Addition in G: ";
|
|
+ cout << testCurveEncryptSpeed(generator) << " seconds" << endl;
|
|
- if (decrypted == test6)
|
|
|
|
- std::cout << "PASS" << std::endl;
|
|
|
|
- else
|
|
|
|
- std::cout << "FAIL" << std::endl;
|
|
|
|
|
|
|
|
- decrypted = system.decrypt(encrypted10);
|
|
+ cout << "test_TwistEncryptSpeed (" << NUM_RUNS_PER_TEST << " runs): ";
|
|
- std::cout << "Addition in H: ";
|
|
+ cout << testTwistEncryptSpeed(generator) << " seconds" << endl;
|
|
- if (decrypted == test10)
|
|
+
|
|
- std::cout << "PASS" << std::endl;
|
|
+ cout << "test_CurveDecryptSpeed (" << NUM_RUNS_PER_TEST << " runs): ";
|
|
- else
|
|
+ cout << testCurveDecryptSpeed(generator) << " seconds" << endl;
|
|
- std::cout << "FAIL" << std::endl;
|
|
+
|
|
|
|
+ cout << "test_TwistDecryptSpeed (" << NUM_RUNS_PER_TEST << " runs): ";
|
|
|
|
+ cout << testTwistDecryptSpeed(generator) << " seconds" << endl;
|
|
|
|
+
|
|
|
|
+ cout << "test_QuadDecryptSpeed (" << NUM_RUNS_PER_TEST << " runs): ";
|
|
|
|
+ cout << testQuadDecryptSpeed(generator) << " seconds" << endl;
|
|
|
|
|
|
- decrypted = system.decrypt(encrypted15);
|
|
+ int addX = distribution(generator);
|
|
- std::cout << "Multiplication (G by H): ";
|
|
+ int addY = distribution(generator);
|
|
- if (decrypted == test15)
|
|
+ cout << "test_Addition (" << addX << ", " << addY << "): ";
|
|
- std::cout << "PASS" << std::endl;
|
|
+ if (testAddition(addX, addY))
|
|
|
|
+ cout << "PASS" << endl;
|
|
else
|
|
else
|
|
- std::cout << "FAIL" << std::endl;
|
|
+ cout << "FAIL" << endl;
|
|
|
|
|
|
- decrypted = system.decrypt(encrypted30);
|
|
+ cout << "test_CurveAdditionSpeed (" << NUM_RUNS_PER_TEST << " runs): ";
|
|
- std::cout << "Addition in G_T: ";
|
|
+ cout << testCurveAdditionSpeed(generator) << " seconds" << endl;
|
|
- if (decrypted == test30)
|
|
+
|
|
- std::cout << "PASS" << std::endl;
|
|
+ cout << "test_TwistAdditionSpeed (" << NUM_RUNS_PER_TEST << " runs): ";
|
|
|
|
+ cout << testTwistAdditionSpeed(generator) << " seconds" << endl;
|
|
|
|
+
|
|
|
|
+ cout << "test_QuadAdditionSpeed (" << NUM_RUNS_PER_TEST << " runs): ";
|
|
|
|
+ cout << testQuadAdditionSpeed(generator) << " seconds" << endl;
|
|
|
|
+
|
|
|
|
+ int multX = distribution(generator);
|
|
|
|
+ int multY = distribution(generator);
|
|
|
|
+ cout << "test_Multiplication (" << multX << ", " << multY << "): ";
|
|
|
|
+ if (testMultiplication(multX, multY))
|
|
|
|
+ cout << "PASS" << endl;
|
|
else
|
|
else
|
|
- std::cout << "FAIL" << std::endl;
|
|
+ cout << "FAIL" << endl;
|
|
|
|
+
|
|
|
|
+ cout << "test_MultiplicationSpeed (" << NUM_RUNS_PER_TEST << " runs): ";
|
|
|
|
+ cout << testMultiplicationSpeed(generator) << " seconds" << endl;
|
|
|
|
|
|
return 0;
|
|
return 0;
|
|
}
|
|
}
|