Browse Source

updated to do some benchmarking in addition to normal testing

tristangurtler 3 years ago
parent
commit
a11851e0a1
1 changed files with 460 additions and 78 deletions
  1. 460 78
      bgn2/src/main.cpp

+ 460 - 78
bgn2/src/main.cpp

@@ -1,115 +1,497 @@
 #include <iostream>
+#include <random>
+#include <chrono>
 
 #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;
 
-    Scalar test0(0);
-    Scalar test1(1);
-    Scalar test3(3);
-    Scalar test5(5);
-    Scalar test6(6);
-    Scalar test10(10);
-    Scalar test15(15);
-    Scalar test30(30);
+    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);
+    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;
 
-    std::cout << "Scalar test value (0): " << test0 << std::endl;
-    std::cout << "Scalar test value (1): " << test1 << std::endl;
-    std::cout << "Scalar test value (3): " << test3 << std::endl;
-    std::cout << "Scalar test value (5): " << test5 << std::endl;
+    CurveBipoint curveX, curveY, curveSum, curveOne;
+    TwistBipoint twistX, twistY, twistSum, twistOne;
+    Quadripoint quadXA, quadXB, quadYA, quadYB,
+        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;
-    TwistBipoint encrypted5, encrypted10;
-    Quadripoint encrypted15, encrypted30;
+    quadSumAA = system.homomorphic_addition(quadXA, quadYA);
+    quadSumAB = system.homomorphic_addition(quadXA, quadYB);
+    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);
-    system.encrypt(encrypted1, test1);
-    system.encrypt(encrypted3, test3);
-    system.encrypt(encrypted5, test5);
+    decrypted = system.decrypt(twistSum);
+    retval = retval && (decrypted == testSum);
 
-    std::cout << "Performing additions" << std::endl;
+    decrypted = system.decrypt(quadSumAA);
+    retval = retval && (decrypted == testSum);
 
-    encrypted6 = system.homomorphic_addition(encrypted3, encrypted3);
-    encrypted10 = system.homomorphic_addition(encrypted5, encrypted5);
+    decrypted = system.decrypt(quadSumAB);
+    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);
-    std::cout << "Decryption of point at infinity (0): ";
-    if (decrypted == test0)
-        std::cout << "PASS" << std::endl;
-    else
-        std::cout << "FAIL" << std::endl;
+    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<CurveBipoint> encYs(NUM_RUNS_PER_TEST);
+    vector<CurveBipoint> encSums(NUM_RUNS_PER_TEST);
     
-    decrypted = system.decrypt(encrypted1);
-    std::cout << "Decryption of generator (1):         ";
-    if (decrypted == test1)
-        std::cout << "PASS" << std::endl;
-    else
-        std::cout << "FAIL" << std::endl;
+    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 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);
-    std::cout << "Memoization:                         ";
-    if (decrypted == test1)
-        std::cout << "PASS" << std::endl;
+    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)));
+
+    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
-        std::cout << "FAIL" << std::endl;
+        cout << "FAIL" << endl;
     
-    decrypted = system.decrypt(encrypted3);
-    std::cout << "Decryption of normal point in G (3): ";
-    if (decrypted == test3)
-        std::cout << "PASS" << std::endl;
+    cout << "test_GeneratorPoint: ";
+    if (testDecrypt(1))
+        cout << "PASS" << endl;
     else
-        std::cout << "FAIL" << std::endl;
+        cout << "FAIL" << endl;
 
-    decrypted = system.decrypt(encrypted5);
-    std::cout << "Decryption of normal point in H (5): ";
-    if (decrypted == test5)
-        std::cout << "PASS" << std::endl;
+    int randomPoint = distribution(generator);
+    cout << "test_RandomPoint (" << randomPoint << "): ";
+    if (testDecrypt(randomPoint))
+        cout << "PASS" << endl;
     else
-        std::cout << "FAIL" << std::endl;
+        cout << "FAIL" << endl;
 
-    decrypted = system.decrypt(encrypted6);
-    std::cout << "Addition in G:                       ";
-    if (decrypted == test6)
-        std::cout << "PASS" << std::endl;
-    else
-        std::cout << "FAIL" << std::endl;
+    cout << "test_CurveEncryptSpeed (" << NUM_RUNS_PER_TEST << " runs): ";
+    cout << testCurveEncryptSpeed(generator) << " seconds" << endl;
 
-    decrypted = system.decrypt(encrypted10);
-    std::cout << "Addition in H:                       ";
-    if (decrypted == test10)
-        std::cout << "PASS" << std::endl;
-    else
-        std::cout << "FAIL" << std::endl;
+    cout << "test_TwistEncryptSpeed (" << NUM_RUNS_PER_TEST << " runs): ";
+    cout << testTwistEncryptSpeed(generator) << " seconds" << endl;
+
+    cout << "test_CurveDecryptSpeed (" << NUM_RUNS_PER_TEST << " runs): ";
+    cout << testCurveDecryptSpeed(generator) << " seconds" << 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);
-    std::cout << "Multiplication (G by H):             ";
-    if (decrypted == test15)
-        std::cout << "PASS" << std::endl;
+    int addX = distribution(generator);
+    int addY = distribution(generator);
+    cout << "test_Addition (" << addX << ", " << addY << "): ";
+    if (testAddition(addX, addY))
+        cout << "PASS" << endl;
     else
-        std::cout << "FAIL" << std::endl;
+        cout << "FAIL" << endl;
 
-    decrypted = system.decrypt(encrypted30);
-    std::cout << "Addition in G_T:                     ";
-    if (decrypted == test30)
-        std::cout << "PASS" << std::endl;
+    cout << "test_CurveAdditionSpeed (" << NUM_RUNS_PER_TEST << " runs): ";
+    cout << testCurveAdditionSpeed(generator) << " seconds" << 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
-        std::cout << "FAIL" << std::endl;
+        cout << "FAIL" << endl;
+
+    cout << "test_MultiplicationSpeed (" << NUM_RUNS_PER_TEST << " runs): ";
+    cout << testMultiplicationSpeed(generator) << " seconds" << endl;
 
     return 0;
 }