diff --git a/README.md b/README.md index 7be4b52..04f8e72 100644 --- a/README.md +++ b/README.md @@ -1,5 +1,5 @@ > [!CAUTION] -> Following implementation of FrodoPIR private information retrieval scheme is designed from scratch, having zero third-party dependencies. It's not yet audited, avoid using it in production! +> Following implementation of FrodoPIR private information retrieval scheme is designed from scratch, having zero third-party dependencies. As it's not yet audited, you are advised to exercise caution, in case you plan to use it in production! # frodoPIR FrodoPIR: Simple, Scalable, Single-Server Private Information Retrieval @@ -22,8 +22,8 @@ To paint a more practical picture, imagine, we have a database with $2^{20}$ (~1 Machine Type | Machine | Kernel | Compiler | Memory Read Speed --- | --- | --- | --- | --- -aarch64 server | AWS EC2 `m8g.8xlarge` | `Linux 6.8.0-1018-aws aarch64` | `GCC 13.2.0` | 28.25 GB/s -x86_64 server | AWS EC2 `m7i.8xlarge` | `Linux 6.8.0-1018-aws x86_64` | `GCC 13.2.0` | 10.33 GB/s +aarch64 server | AWS EC2 `m8g.8xlarge` | `Linux 6.8.0-1021-aws aarch64` | `GCC 13.2.0` | 28.25 GB/s +x86_64 server | AWS EC2 `m7i.8xlarge` | `Linux 6.8.0-1021-aws x86_64` | `GCC 13.2.0` | 10.33 GB/s and this implementation of FrodoPIR is compiled with specified compiler, while also passing `-O3 -march=native -flto` compiler optimization flags. @@ -32,16 +32,16 @@ and this implementation of FrodoPIR is compiled with specified compiler, while a Step | `(a)` Time Taken on `aarch64` server | `(b)` Time Taken on `x86_64` server | Ratio `a / b` :-- | --: | --: | --: -`server_setup` | 41 seconds | 60.1 seconds | 0.68 +`server_setup` | 46.7 seconds | 67.7 seconds | 0.68 `client_setup` | 21.7 seconds | 20.5 seconds | 1.05 `client_preprocess_query` | 39.4 milliseconds | 65.6 milliseconds | 0.6 `client_query` | 146 microseconds | 454 microseconds | 0.32 -`server_respond` | 41.6 milliseconds | 150 milliseconds | 0.27 +`server_respond` | 18.1 milliseconds | 30.8 milliseconds | 0.58 `client_process_response` | 782 microseconds | 1257 microseconds | 0.62 So, bandwidth of the `server_respond` algorithm, which needs to traverse through the whole processed database, is -- (a) For `aarch64` server: 24.03 GB/s -- (b) For `x86_64` server: 6.66 GB/s +- (a) For `aarch64` server: 55.24 GB/s +- (b) For `x86_64` server: 32.46 GB/s Here I'm maintaining a zero-dependency, header-only C++20 library implementation of FrodoPIR scheme, supporting all parameter sets, as suggested in table 5 of https://ia.cr/2022/981. Using this library is very easy, follow [here](#usage). @@ -50,7 +50,7 @@ Here I'm maintaining a zero-dependency, header-only C++20 library implementation ```bash $ g++ --version -g++ (Ubuntu 14-20240412-0ubuntu1) 14.0.1 20240412 (experimental) [master r14-9935-g67e1433a94f] +g++ (Ubuntu 14.2.0-4ubuntu2) 14.2.0s ``` - System development utility programs such as `make` and `cmake`. @@ -77,11 +77,14 @@ make release_ubsan_test -j # Run tests with UndefinedBehaviourSanitizer enabled, ``` ```bash -PASSED TESTS (4/4): - 162 ms: build/test/test.out FrodoPIR.MatrixOperations - 3256 ms: build/test/test.out FrodoPIR.ClientQueryCacheStateTransition - 7399 ms: build/test/test.out FrodoPIR.ParsingDatabaseAndSerializingDatabaseMatrix - 66962 ms: build/test/test.out FrodoPIR.PrivateInformationRetrieval +PASSED TESTS (7/7): + 3 ms: build/test/test.out FrodoPIR.RowVectorMatrixMultiplicationWorks + 15 ms: build/test/test.out FrodoPIR.MatrixSerializationWorks + 20 ms: build/test/test.out FrodoPIR.MatrixTranspositionWorks + 123 ms: build/test/test.out FrodoPIR.MatrixMultiplicationWorks + 2447 ms: build/test/test.out FrodoPIR.ClientQueryCacheStateTransition + 5112 ms: build/test/test.out FrodoPIR.ParsingDatabaseAndSerializingDatabaseMatrix + 44540 ms: build/test/test.out FrodoPIR.PrivateInformationRetrieval ``` > [!NOTE] @@ -100,8 +103,8 @@ make perf -j # If you have built google-benchmark library with libPFM supp > [!CAUTION] > You must put all the CPU cores on **performance** mode before running benchmark program, follow guide @ https://github.com/google/benchmark/blob/main/docs/reducing_variance.md. -- **On AWS EC2 Instance `m8g.8xlarge`**: Benchmark result in JSON format @ [bench_result_on_Linux_6.8.0-1018-aws_aarch64_with_g++_13](./bench_result_on_Linux_6.8.0-1018-aws_aarch64_with_g++_13.json). -- **On AWS EC2 Instance `m7i.8xlarge`**: Benchmark result in JSON format @ [bench_result_on_Linux_6.8.0-1018-aws_x86_64_with_g++_13](./bench_result_on_Linux_6.8.0-1018-aws_x86_64_with_g++_13.json). +- **On AWS EC2 Instance `m8g.8xlarge`**: Benchmark result in JSON format @ [bench_result_on_Linux_6.8.0-1021-aws_aarch64_with_g++_13](./bench_result_on_Linux_6.8.0-1021-aws_aarch64_with_g++_13.json). +- **On AWS EC2 Instance `m7i.8xlarge`**: Benchmark result in JSON format @ [bench_result_on_Linux_6.8.0-1021-aws_x86_64_with_g++_13](./bench_result_on_Linux_6.8.0-1021-aws_x86_64_with_g++_13.json). > [!NOTE] > More about AWS EC2 instances @ https://aws.amazon.com/ec2/instance-types. @@ -129,6 +132,17 @@ popd - Now that we've all the dependencies to use FrodoPIR header-only library, let's run our [example](./examples/frodoPIR.cpp) program, by issuing `make example`. ```bash -Original database row bytes : bf71e04189fff486c062cf1e814bedfc2205422807da319d4ac6f5a956d63e48 -PIR decoded database row bytes : bf71e04189fff486c062cf1e814bedfc2205422807da319d4ac6f5a956d63e48 +FrodoPIR: +Number of entries in Index Database : 65536 +Size of each database entry : 1.0KB +DB size : 64.0MB +Encoded DB matrix element bit length : 10 +Encoded DB matrix dimension : 65536 x 820 +Seed size : 16.0B +Hint download size : 5.5MB +Query vector size : 256.0KB +Response vector size : 3.2KB + +Original database row bytes : 86ec860911c1ba1b573ffb956f2e75c65a61de75328cf5e7a3ca061b2114be2d42ae1515eb013b34dc1be335790800ebf3f44025c08121cd36ef6e57b504f82e1a0495665e5bad163b93a07665c0a8675916701150b40c7f46dfdd540c26ac2ada284bdd3c360960f4a24cc37235f7473ddbe5be50d0be3c9f15a933071a974d1aa5cad19b476d482444bcf5bbf5391546b7e95448a7e4c9351de85b4771878812b060c6f62bce6727cd5821e371a71ccb62a2e527d2e8b1b800dbe1e424bcea7cfc641e44c9b17768efef1c0b3cf166dd466e02b68c2f4ba61e0f20904a67654f61d773b955b163d769b75c9cc2760ad8d1aa40e473d526cd86a21d46c5d646877949c571fbaf06171eac7bbe0f7a27b371947fbd73682e5adcc7df8acd9c780e1378d7834d8e5479427f01793c3d130cffa6d5a6ecc39cbcb3303a960013caf51d0de7cd2146d282a0187ef131251cde7043ab071b89804e9abfe4f5636ed812c0199e0e60834025bb9df35cd46b7bd0019ff93fe565841faf45e4e4250164454b8115c3f66bdda1e430c696821e098a4b48451e0122f34c961101432f7ef1f7de6b46d0f19e79fdd2a434c0f2c63b820231d3fcaf6e364ef0b94e36e4abeda1c2fe2ad6a7fc89b7e881343018929e05cb402594a6570791931debf1b167adbc58f128765166e815d4a9a5c8f3bd2fdf4741cd257336481caa686d6765f87afa1ea58a17f3e43d10679aa88a521586a8d93a7cadfca9df4418c2c1653792d09fe632f61d833994122ce7ca0b73ade3dbed7fdd599ef29d9c9c33cd5be455e8358d0d6e6da309b4ec25be5e82340644ccca23cbc1ef2489507deaa14e5c5cca45aa02a3833f6638eeed8dcf25718369513c68b1386b857790c6c9f69c274c65fc69362d5d0fc93749f6312cb38a04399c31a34d0799ba2c4d24ce07ead41bbcaeee0dbc525321fb81dea05c42c281c14c26559f6dda984c54fbbf364771172a49e5c9140ff95408956d0c415b335cef278d264822224d2d56bec651fafe99921cbc1aab39f1fd5b3f159054afad396cae5804894520e96e2c31dd3163e6e90415390f7c0b8485f670ba5fb98ce8f8e0387a73365254721a13070b6c8680be50f06ff06f0493a903da0eda0ef92ca8d503fe8364eca1401103fa0b3e9929809bb19dd0af6ea3a7133a0c6aff7aa401872b969a18d5081ffa69f0065921c7a35c91f7be6e639705d72f8baac41e44b842bef2d59105925bcc637b5bf80984b2b5b841ebece3f99c51fcc8b328f8f0c879643b3f28628f60c929421c895e6b13a152fe836e213c0e2c9382a4fe504cb7b41947c48eed3eb540d804999deba1d056171f333396265abe42f8e8f9a8ac60f48ed3017920d757aa1aa22c0b001f575eb16cb69812108b65e62530979431493737af23ce6e28d7bcbc585a451b9b780a +PIR decoded database row bytes : 86ec860911c1ba1b573ffb956f2e75c65a61de75328cf5e7a3ca061b2114be2d42ae1515eb013b34dc1be335790800ebf3f44025c08121cd36ef6e57b504f82e1a0495665e5bad163b93a07665c0a8675916701150b40c7f46dfdd540c26ac2ada284bdd3c360960f4a24cc37235f7473ddbe5be50d0be3c9f15a933071a974d1aa5cad19b476d482444bcf5bbf5391546b7e95448a7e4c9351de85b4771878812b060c6f62bce6727cd5821e371a71ccb62a2e527d2e8b1b800dbe1e424bcea7cfc641e44c9b17768efef1c0b3cf166dd466e02b68c2f4ba61e0f20904a67654f61d773b955b163d769b75c9cc2760ad8d1aa40e473d526cd86a21d46c5d646877949c571fbaf06171eac7bbe0f7a27b371947fbd73682e5adcc7df8acd9c780e1378d7834d8e5479427f01793c3d130cffa6d5a6ecc39cbcb3303a960013caf51d0de7cd2146d282a0187ef131251cde7043ab071b89804e9abfe4f5636ed812c0199e0e60834025bb9df35cd46b7bd0019ff93fe565841faf45e4e4250164454b8115c3f66bdda1e430c696821e098a4b48451e0122f34c961101432f7ef1f7de6b46d0f19e79fdd2a434c0f2c63b820231d3fcaf6e364ef0b94e36e4abeda1c2fe2ad6a7fc89b7e881343018929e05cb402594a6570791931debf1b167adbc58f128765166e815d4a9a5c8f3bd2fdf4741cd257336481caa686d6765f87afa1ea58a17f3e43d10679aa88a521586a8d93a7cadfca9df4418c2c1653792d09fe632f61d833994122ce7ca0b73ade3dbed7fdd599ef29d9c9c33cd5be455e8358d0d6e6da309b4ec25be5e82340644ccca23cbc1ef2489507deaa14e5c5cca45aa02a3833f6638eeed8dcf25718369513c68b1386b857790c6c9f69c274c65fc69362d5d0fc93749f6312cb38a04399c31a34d0799ba2c4d24ce07ead41bbcaeee0dbc525321fb81dea05c42c281c14c26559f6dda984c54fbbf364771172a49e5c9140ff95408956d0c415b335cef278d264822224d2d56bec651fafe99921cbc1aab39f1fd5b3f159054afad396cae5804894520e96e2c31dd3163e6e90415390f7c0b8485f670ba5fb98ce8f8e0387a73365254721a13070b6c8680be50f06ff06f0493a903da0eda0ef92ca8d503fe8364eca1401103fa0b3e9929809bb19dd0af6ea3a7133a0c6aff7aa401872b969a18d5081ffa69f0065921c7a35c91f7be6e639705d72f8baac41e44b842bef2d59105925bcc637b5bf80984b2b5b841ebece3f99c51fcc8b328f8f0c879643b3f28628f60c929421c895e6b13a152fe836e213c0e2c9382a4fe504cb7b41947c48eed3eb540d804999deba1d056171f333396265abe42f8e8f9a8ac60f48ed3017920d757aa1aa22c0b001f575eb16cb69812108b65e62530979431493737af23ce6e28d7bcbc585a451b9b780a ``` diff --git a/bench_result_on_Linux_6.8.0-1018-aws_aarch64_with_g++_13.json b/bench_result_on_Linux_6.8.0-1021-aws_aarch64_with_g++_13.json similarity index 76% rename from bench_result_on_Linux_6.8.0-1018-aws_aarch64_with_g++_13.json rename to bench_result_on_Linux_6.8.0-1021-aws_aarch64_with_g++_13.json index 2188b52..c4129e8 100644 --- a/bench_result_on_Linux_6.8.0-1018-aws_aarch64_with_g++_13.json +++ b/bench_result_on_Linux_6.8.0-1021-aws_aarch64_with_g++_13.json @@ -1,7 +1,7 @@ { "context": { - "date": "2024-12-28T21:23:15+00:00", - "host_name": "ip-172-31-40-23", + "date": "2025-01-30T18:29:56+00:00", + "host_name": "ip-172-31-33-238", "executable": "./build/benchmark/bench.out", "num_cpus": 32, "mhz_per_cpu": 2000, @@ -32,8 +32,8 @@ "num_sharing": 32 } ], - "load_avg": [1.50293,5.55029,4.2666], - "library_version": "v1.9.1-7-gf4f93b55", + "load_avg": [0.564453,0.424316,0.258301], + "library_version": "v1.9.1-22-g4a805f9f", "library_build_type": "release", "json_schema_version": 1 }, @@ -49,10 +49,10 @@ "aggregate_name": "mean", "aggregate_unit": "time", "iterations": 10, - "real_time": 3.9925165333329460e+01, - "cpu_time": 6.3726014743336543e+02, + "real_time": 4.2021894766670201e+01, + "cpu_time": 6.9257139073332235e+02, "time_unit": "ms", - "items_per_second": 2.5081792857200931e+01 + "items_per_second": 2.3934192807420402e+01 }, { "name": "frodoPIR/client_prepare_query/1.0M/1.0KB/process_time/real_time_median", @@ -65,10 +65,10 @@ "aggregate_name": "median", "aggregate_unit": "time", "iterations": 10, - "real_time": 3.9428932833364648e+01, - "cpu_time": 6.3644382533326893e+02, + "real_time": 4.0325259333333939e+01, + "cpu_time": 6.6409102850002455e+02, "time_unit": "ms", - "items_per_second": 2.5362326978039896e+01 + "items_per_second": 2.4798387263546196e+01 }, { "name": "frodoPIR/client_prepare_query/1.0M/1.0KB/process_time/real_time_stddev", @@ -81,10 +81,10 @@ "aggregate_name": "stddev", "aggregate_unit": "time", "iterations": 10, - "real_time": 1.6125749607232762e+00, - "cpu_time": 7.1376189923740156e+00, + "real_time": 3.4686336665367881e+00, + "cpu_time": 5.8783588281181224e+01, "time_unit": "ms", - "items_per_second": 9.6131011311936077e-01 + "items_per_second": 1.8487936113054173e+00 }, { "name": "frodoPIR/client_prepare_query/1.0M/1.0KB/process_time/real_time_cv", @@ -97,10 +97,10 @@ "aggregate_name": "cv", "aggregate_unit": "percentage", "iterations": 10, - "real_time": 4.0389938207146293e-02, - "cpu_time": 1.1200479146737094e-02, + "real_time": 8.2543485623307628e-02, + "cpu_time": 8.4877297947492172e-02, "time_unit": "ms", - "items_per_second": 3.8327009500174966e-02 + "items_per_second": 7.7244869972478425e-02 }, { "name": "frodoPIR/client_prepare_query/1.0M/1.0KB/process_time/real_time_min", @@ -113,10 +113,10 @@ "aggregate_name": "min", "aggregate_unit": "time", "iterations": 10, - "real_time": 3.8703760999851511e+01, - "cpu_time": 6.2781006466684630e+02, + "real_time": 3.8095967666701355e+01, + "cpu_time": 6.2896234266645479e+02, "time_unit": "ms", - "items_per_second": 2.3014775393862671e+01 + "items_per_second": 2.0664050845815805e+01 }, { "name": "frodoPIR/client_prepare_query/1.0M/1.0KB/process_time/real_time_max", @@ -129,10 +129,10 @@ "aggregate_name": "max", "aggregate_unit": "time", "iterations": 10, - "real_time": 4.3450347999775360e+01, - "cpu_time": 6.5108480199978658e+02, + "real_time": 4.8393221999958769e+01, + "cpu_time": 8.1385444866661305e+02, "time_unit": "ms", - "items_per_second": 2.5837282325194096e+01 + "items_per_second": 2.6249497289291138e+01 }, { "name": "frodoPIR/client_process_response/1.0M/1.0KB/process_time/real_time_mean", @@ -145,10 +145,10 @@ "aggregate_name": "mean", "aggregate_unit": "time", "iterations": 10, - "real_time": 7.8090946424774870e+02, - "cpu_time": 8.0746796928444030e+02, + "real_time": 7.3292912239632346e+02, + "cpu_time": 7.5450624688642176e+02, "time_unit": "us", - "items_per_second": 1.2805965334369371e+03 + "items_per_second": 1.3644888597402280e+03 }, { "name": "frodoPIR/client_process_response/1.0M/1.0KB/process_time/real_time_median", @@ -161,10 +161,10 @@ "aggregate_name": "median", "aggregate_unit": "time", "iterations": 10, - "real_time": 7.8182788267095111e+02, - "cpu_time": 8.0990541073587633e+02, + "real_time": 7.3155591406385645e+02, + "cpu_time": 7.5340230209993331e+02, "time_unit": "us", - "items_per_second": 1.2790541780576900e+03 + "items_per_second": 1.3669496286393673e+03 }, { "name": "frodoPIR/client_process_response/1.0M/1.0KB/process_time/real_time_stddev", @@ -177,10 +177,10 @@ "aggregate_name": "stddev", "aggregate_unit": "time", "iterations": 10, - "real_time": 4.5027471602798688e+00, - "cpu_time": 5.2637712459413617e+00, + "real_time": 6.6481378059426515e+00, + "cpu_time": 6.8076877982695070e+00, "time_unit": "us", - "items_per_second": 7.3913324583263789e+00 + "items_per_second": 1.2305282622870163e+01 }, { "name": "frodoPIR/client_process_response/1.0M/1.0KB/process_time/real_time_cv", @@ -193,10 +193,10 @@ "aggregate_name": "cv", "aggregate_unit": "percentage", "iterations": 10, - "real_time": 5.7660296954108146e-03, - "cpu_time": 6.5188607426818366e-03, + "real_time": 9.0706421709734475e-03, + "cpu_time": 9.0227056785313672e-03, "time_unit": "us", - "items_per_second": 5.7717885886268208e-03 + "items_per_second": 9.0182360486349804e-03 }, { "name": "frodoPIR/client_process_response/1.0M/1.0KB/process_time/real_time_min", @@ -209,10 +209,10 @@ "aggregate_name": "min", "aggregate_unit": "time", "iterations": 10, - "real_time": 7.7431111174254954e+02, - "cpu_time": 7.9895858656954499e+02, + "real_time": 7.2302704687388086e+02, + "cpu_time": 7.4405874479073952e+02, "time_unit": "us", - "items_per_second": 1.2696702420890394e+03 + "items_per_second": 1.3400587438256166e+03 }, { "name": "frodoPIR/client_process_response/1.0M/1.0KB/process_time/real_time_max", @@ -225,10 +225,10 @@ "aggregate_name": "max", "aggregate_unit": "time", "iterations": 10, - "real_time": 7.8760607821654526e+02, - "cpu_time": 8.1343163141324544e+02, + "real_time": 7.4623594272082983e+02, + "cpu_time": 7.6852349479850091e+02, "time_unit": "us", - "items_per_second": 1.2914705534181842e+03 + "items_per_second": 1.3830741247144965e+03 }, { "name": "frodoPIR/client_query/1.0M/1.0KB/process_time/real_time_mean", @@ -241,10 +241,10 @@ "aggregate_name": "mean", "aggregate_unit": "time", "iterations": 10, - "real_time": 1.4632338859939574e+02, - "cpu_time": 1.4536611707847919e+02, + "real_time": 1.5217092363637084e+02, + "cpu_time": 1.5093806813279721e+02, "time_unit": "us", - "items_per_second": 6.8343138995613162e+03 + "items_per_second": 6.5718727656188248e+03 }, { "name": "frodoPIR/client_query/1.0M/1.0KB/process_time/real_time_median", @@ -257,10 +257,10 @@ "aggregate_name": "median", "aggregate_unit": "time", "iterations": 10, - "real_time": 1.4611767615776205e+02, - "cpu_time": 1.4514521185376253e+02, + "real_time": 1.5249544989163039e+02, + "cpu_time": 1.5126177566419565e+02, "time_unit": "us", - "items_per_second": 6.8437994073933678e+03 + "items_per_second": 6.5575727323596566e+03 }, { "name": "frodoPIR/client_query/1.0M/1.0KB/process_time/real_time_stddev", @@ -273,10 +273,10 @@ "aggregate_name": "stddev", "aggregate_unit": "time", "iterations": 10, - "real_time": 6.8974454570460442e-01, - "cpu_time": 7.0049948304714815e-01, + "real_time": 1.1102475291993252e+00, + "cpu_time": 1.1380808994737646e+00, "time_unit": "us", - "items_per_second": 3.2167828184744451e+01 + "items_per_second": 4.7987123433555034e+01 }, { "name": "frodoPIR/client_query/1.0M/1.0KB/process_time/real_time_cv", @@ -289,10 +289,10 @@ "aggregate_name": "cv", "aggregate_unit": "percentage", "iterations": 10, - "real_time": 4.7138366074407122e-03, - "cpu_time": 4.8188635503620672e-03, + "real_time": 7.2960556633827351e-03, + "cpu_time": 7.5400521124496340e-03, "time_unit": "us", - "items_per_second": 4.7068116357384835e-03 + "items_per_second": 7.3018947787003357e-03 }, { "name": "frodoPIR/client_query/1.0M/1.0KB/process_time/real_time_min", @@ -305,10 +305,10 @@ "aggregate_name": "min", "aggregate_unit": "time", "iterations": 10, - "real_time": 1.4517221555633742e+02, - "cpu_time": 1.4417925391133895e+02, + "real_time": 1.5051882571117625e+02, + "cpu_time": 1.4924021675271081e+02, "time_unit": "us", - "items_per_second": 6.7806030483116738e+03 + "items_per_second": 6.4971579388290338e+03 }, { "name": "frodoPIR/client_query/1.0M/1.0KB/process_time/real_time_max", @@ -321,10 +321,10 @@ "aggregate_name": "max", "aggregate_unit": "time", "iterations": 10, - "real_time": 1.4747950777755580e+02, - "cpu_time": 1.4652825798175826e+02, + "real_time": 1.5391345099119255e+02, + "cpu_time": 1.5272538446736817e+02, "time_unit": "us", - "items_per_second": 6.8883704513824623e+03 + "items_per_second": 6.6436872283262064e+03 }, { "name": "frodoPIR/client_setup/1.0M/1.0KB/process_time/real_time_mean", @@ -337,10 +337,10 @@ "aggregate_name": "mean", "aggregate_unit": "time", "iterations": 10, - "real_time": 2.1699243396499969e+04, - "cpu_time": 2.1699423265500085e+04, + "real_time": 2.1608095721100017e+04, + "cpu_time": 2.1608214780397975e+04, "time_unit": "ms", - "items_per_second": 4.6084617167700341e-02 + "items_per_second": 4.6278984538061875e-02 }, { "name": "frodoPIR/client_setup/1.0M/1.0KB/process_time/real_time_median", @@ -353,10 +353,10 @@ "aggregate_name": "median", "aggregate_unit": "time", "iterations": 10, - "real_time": 2.1700397071499992e+04, - "cpu_time": 2.1700647451500117e+04, + "real_time": 2.1602379445000679e+04, + "cpu_time": 2.1602356456995039e+04, "time_unit": "ms", - "items_per_second": 4.6082106400449636e-02 + "items_per_second": 4.6291202047407332e-02 }, { "name": "frodoPIR/client_setup/1.0M/1.0KB/process_time/real_time_stddev", @@ -369,10 +369,10 @@ "aggregate_name": "stddev", "aggregate_unit": "time", "iterations": 10, - "real_time": 2.6329415063775777e+01, - "cpu_time": 2.6440872789243151e+01, + "real_time": 1.9436399109827299e+01, + "cpu_time": 1.9435104723319629e+01, "time_unit": "ms", - "items_per_second": 5.5905302845782917e-05 + "items_per_second": 4.1604300532343644e-05 }, { "name": "frodoPIR/client_setup/1.0M/1.0KB/process_time/real_time_cv", @@ -385,10 +385,10 @@ "aggregate_name": "cv", "aggregate_unit": "percentage", "iterations": 10, - "real_time": 1.2133794060313937e-03, - "cpu_time": 1.2185057854178778e-03, + "real_time": 8.9949615924960543e-04, + "cpu_time": 8.9943130058806628e-04, "time_unit": "ms", - "items_per_second": 1.2131011665420901e-03 + "items_per_second": 8.9898905405165995e-04 }, { "name": "frodoPIR/client_setup/1.0M/1.0KB/process_time/real_time_min", @@ -401,10 +401,10 @@ "aggregate_name": "min", "aggregate_unit": "time", "iterations": 10, - "real_time": 2.1651607409999997e+04, - "cpu_time": 2.1651434255996719e+04, + "real_time": 2.1585325969000223e+04, + "cpu_time": 2.1585528249997878e+04, "time_unit": "ms", - "items_per_second": 4.5972635833568747e-02 + "items_per_second": 4.6196033637535446e-02 }, { "name": "frodoPIR/client_setup/1.0M/1.0KB/process_time/real_time_max", @@ -417,10 +417,10 @@ "aggregate_name": "max", "aggregate_unit": "time", "iterations": 10, - "real_time": 2.1752070158000606e+04, - "cpu_time": 2.1752476713001670e+04, + "real_time": 2.1646880072999920e+04, + "cpu_time": 2.1646953036994091e+04, "time_unit": "ms", - "items_per_second": 4.6185947355490135e-02 + "items_per_second": 4.6327769218595563e-02 }, { "name": "frodoPIR/server_respond/1.0M/1.0KB/process_time/real_time_mean", @@ -433,10 +433,10 @@ "aggregate_name": "mean", "aggregate_unit": "time", "iterations": 10, - "real_time": 4.1820076466683538e+01, - "cpu_time": 9.5676291396618285e+02, + "real_time": 1.8213729162516760e+01, + "cpu_time": 5.2394258366230144e+02, "time_unit": "ms", - "items_per_second": 2.3917886723951693e+01 + "items_per_second": 5.4926636245555187e+01 }, { "name": "frodoPIR/server_respond/1.0M/1.0KB/process_time/real_time_median", @@ -449,10 +449,10 @@ "aggregate_name": "median", "aggregate_unit": "time", "iterations": 10, - "real_time": 4.1614897833369469e+01, - "cpu_time": 9.6190188666757126e+02, + "real_time": 1.8073985562523376e+01, + "cpu_time": 5.2274780224934148e+02, "time_unit": "ms", - "items_per_second": 2.4029858199690633e+01 + "items_per_second": 5.5328144722508448e+01 }, { "name": "frodoPIR/server_respond/1.0M/1.0KB/process_time/real_time_stddev", @@ -465,10 +465,10 @@ "aggregate_name": "stddev", "aggregate_unit": "time", "iterations": 10, - "real_time": 6.9606530678727074e-01, - "cpu_time": 1.7567485453933710e+01, + "real_time": 3.9603304790159793e-01, + "cpu_time": 1.0083647367975832e+01, "time_unit": "ms", - "items_per_second": 3.9570174529764623e-01 + "items_per_second": 1.1753129626795007e+00 }, { "name": "frodoPIR/server_respond/1.0M/1.0KB/process_time/real_time_cv", @@ -481,10 +481,10 @@ "aggregate_name": "cv", "aggregate_unit": "percentage", "iterations": 10, - "real_time": 1.6644285845383362e-02, - "cpu_time": 1.8361377931246443e-02, + "real_time": 2.1743655259606070e-02, + "cpu_time": 1.9245710660683923e-02, "time_unit": "ms", - "items_per_second": 1.6544176743733183e-02 + "items_per_second": 2.1397868921467226e-02 }, { "name": "frodoPIR/server_respond/1.0M/1.0KB/process_time/real_time_min", @@ -497,10 +497,10 @@ "aggregate_name": "min", "aggregate_unit": "time", "iterations": 10, - "real_time": 4.0791841333278477e+01, - "cpu_time": 9.2624341166811064e+02, + "real_time": 1.7815946499922575e+01, + "cpu_time": 5.1000429437499406e+02, "time_unit": "ms", - "items_per_second": 2.3187754299665102e+01 + "items_per_second": 5.2914016211718121e+01 }, { "name": "frodoPIR/server_respond/1.0M/1.0KB/process_time/real_time_max", @@ -513,10 +513,10 @@ "aggregate_name": "max", "aggregate_unit": "time", "iterations": 10, - "real_time": 4.3126211666579671e+01, - "cpu_time": 9.8237872766427859e+02, + "real_time": 1.8898584375051541e+01, + "cpu_time": 5.4261105787463748e+02, "time_unit": "ms", - "items_per_second": 2.4514706061679739e+01 + "items_per_second": 5.6129490510332744e+01 }, { "name": "frodoPIR/server_setup/1.0M/1.0KB/process_time/real_time_mean", @@ -529,10 +529,10 @@ "aggregate_name": "mean", "aggregate_unit": "time", "iterations": 10, - "real_time": 4.0912393570000226e+01, - "cpu_time": 5.3568066655379664e+02, + "real_time": 4.6691210067399972e+01, + "cpu_time": 4.6439428130610105e+02, "time_unit": "s", - "items_per_second": 2.4446034485958407e-02 + "items_per_second": 2.1417465963582322e-02 }, { "name": "frodoPIR/server_setup/1.0M/1.0KB/process_time/real_time_median", @@ -545,10 +545,10 @@ "aggregate_name": "median", "aggregate_unit": "time", "iterations": 10, - "real_time": 4.1026158523000959e+01, - "cpu_time": 5.4018009618199721e+02, + "real_time": 4.6729977840499942e+01, + "cpu_time": 4.6399599382800079e+02, "time_unit": "s", - "items_per_second": 2.4374707450132437e-02 + "items_per_second": 2.1399539492284896e-02 }, { "name": "frodoPIR/server_setup/1.0M/1.0KB/process_time/real_time_stddev", @@ -561,10 +561,10 @@ "aggregate_name": "stddev", "aggregate_unit": "time", "iterations": 10, - "real_time": 5.1859529217746292e-01, - "cpu_time": 2.2024005207246368e+01, + "real_time": 1.3384959975342262e-01, + "cpu_time": 3.5212218030977880e+00, "time_unit": "s", - "items_per_second": 3.1237292303748704e-04 + "items_per_second": 6.1449027829965899e-05 }, { "name": "frodoPIR/server_setup/1.0M/1.0KB/process_time/real_time_cv", @@ -577,10 +577,10 @@ "aggregate_name": "cv", "aggregate_unit": "percentage", "iterations": 10, - "real_time": 1.2675750473756993e-02, - "cpu_time": 4.1114056530980984e-02, + "real_time": 2.8666980264638086e-03, + "cpu_time": 7.5823969950586196e-03, "time_unit": "s", - "items_per_second": 1.2778061129583670e-02 + "items_per_second": 2.8691082285108873e-03 }, { "name": "frodoPIR/server_setup/1.0M/1.0KB/process_time/real_time_min", @@ -593,10 +593,10 @@ "aggregate_name": "min", "aggregate_unit": "time", "iterations": 10, - "real_time": 3.9878972296000939e+01, - "cpu_time": 4.8225091007999436e+02, + "real_time": 4.6493668398999944e+01, + "cpu_time": 4.5984872505399835e+02, "time_unit": "s", - "items_per_second": 2.4066337032260517e-02 + "items_per_second": 2.1333792955395257e-02 }, { "name": "frodoPIR/server_setup/1.0M/1.0KB/process_time/real_time_max", @@ -609,10 +609,10 @@ "aggregate_name": "max", "aggregate_unit": "time", "iterations": 10, - "real_time": 4.1551815661000546e+01, - "cpu_time": 5.6110159870900679e+02, + "real_time": 4.6873990110000705e+01, + "cpu_time": 4.7153490338800475e+02, "time_unit": "s", - "items_per_second": 2.5075871879985230e-02 + "items_per_second": 2.1508304989363014e-02 } ] } diff --git a/bench_result_on_Linux_6.8.0-1018-aws_x86_64_with_g++_13.json b/bench_result_on_Linux_6.8.0-1021-aws_x86_64_with_g++_13.json similarity index 76% rename from bench_result_on_Linux_6.8.0-1018-aws_x86_64_with_g++_13.json rename to bench_result_on_Linux_6.8.0-1021-aws_x86_64_with_g++_13.json index 2ad5fa9..6f2065c 100644 --- a/bench_result_on_Linux_6.8.0-1018-aws_x86_64_with_g++_13.json +++ b/bench_result_on_Linux_6.8.0-1021-aws_x86_64_with_g++_13.json @@ -1,10 +1,10 @@ { "context": { - "date": "2024-12-30T18:42:29+00:00", - "host_name": "ip-172-31-36-55", + "date": "2025-01-30T17:38:59+00:00", + "host_name": "ip-172-31-23-209", "executable": "./build/benchmark/bench.out", "num_cpus": 32, - "mhz_per_cpu": 2400, + "mhz_per_cpu": 3318, "cpu_scaling_enabled": false, "caches": [ { @@ -32,8 +32,8 @@ "num_sharing": 32 } ], - "load_avg": [0.627441,0.337891,0.195312], - "library_version": "v1.9.1-7-gf4f93b55", + "load_avg": [1.30908,0.835449,0.362305], + "library_version": "v1.9.1-22-g4a805f9f", "library_build_type": "release", "json_schema_version": 1 }, @@ -49,10 +49,10 @@ "aggregate_name": "mean", "aggregate_unit": "time", "iterations": 10, - "real_time": 6.5214085950015033e+01, - "cpu_time": 1.4031952754000488e+03, + "real_time": 6.7678517099966484e+01, + "cpu_time": 1.4597920767000235e+03, "time_unit": "ms", - "items_per_second": 1.5340150621014537e+01 + "items_per_second": 1.4782242314645572e+01 }, { "name": "frodoPIR/client_prepare_query/1.0M/1.0KB/process_time/real_time_median", @@ -65,10 +65,10 @@ "aggregate_name": "median", "aggregate_unit": "time", "iterations": 10, - "real_time": 6.5609765250030705e+01, - "cpu_time": 1.3985987092501091e+03, + "real_time": 6.7512266749929495e+01, + "cpu_time": 1.4594821692505775e+03, "time_unit": "ms", - "items_per_second": 1.5241634193791899e+01 + "items_per_second": 1.4812169054342327e+01 }, { "name": "frodoPIR/client_prepare_query/1.0M/1.0KB/process_time/real_time_stddev", @@ -81,10 +81,10 @@ "aggregate_name": "stddev", "aggregate_unit": "time", "iterations": 10, - "real_time": 1.3575666750758473e+00, - "cpu_time": 3.2852183999131235e+01, + "real_time": 1.5129360081779855e+00, + "cpu_time": 1.6261936087248319e+01, "time_unit": "ms", - "items_per_second": 3.2243932628011590e-01 + "items_per_second": 3.2342353364976917e-01 }, { "name": "frodoPIR/client_prepare_query/1.0M/1.0KB/process_time/real_time_cv", @@ -97,10 +97,10 @@ "aggregate_name": "cv", "aggregate_unit": "percentage", "iterations": 10, - "real_time": 2.0817077404356912e-02, - "cpu_time": 2.3412410642392686e-02, + "real_time": 2.2354745242766771e-02, + "cpu_time": 1.1139898857383665e-02, "time_unit": "ms", - "items_per_second": 2.1019306410095147e-02 + "items_per_second": 2.1879193072713729e-02 }, { "name": "frodoPIR/client_prepare_query/1.0M/1.0KB/process_time/real_time_min", @@ -113,10 +113,10 @@ "aggregate_name": "min", "aggregate_unit": "time", "iterations": 10, - "real_time": 6.3005408499975601e+01, - "cpu_time": 1.3546537115003048e+03, + "real_time": 6.5820811499975207e+01, + "cpu_time": 1.4382737085006738e+03, "time_unit": "ms", - "items_per_second": 1.4906470394967050e+01 + "items_per_second": 1.4065880844364646e+01 }, { "name": "frodoPIR/client_prepare_query/1.0M/1.0KB/process_time/real_time_max", @@ -129,10 +129,10 @@ "aggregate_name": "max", "aggregate_unit": "time", "iterations": 10, - "real_time": 6.7084961999967163e+01, - "cpu_time": 1.4658868904998599e+03, + "real_time": 7.1094018999929176e+01, + "cpu_time": 1.4927152499994918e+03, "time_unit": "ms", - "items_per_second": 1.5871653304182406e+01 + "items_per_second": 1.5192763158205315e+01 }, { "name": "frodoPIR/client_process_response/1.0M/1.0KB/process_time/real_time_mean", @@ -145,10 +145,10 @@ "aggregate_name": "mean", "aggregate_unit": "time", "iterations": 10, - "real_time": 1.2556421499954242e+03, - "cpu_time": 2.4409652850727075e+03, + "real_time": 9.5530776413962212e+02, + "cpu_time": 1.1559881075638637e+03, "time_unit": "us", - "items_per_second": 7.9692035573177839e+02 + "items_per_second": 1.0470280007790177e+03 }, { "name": "frodoPIR/client_process_response/1.0M/1.0KB/process_time/real_time_median", @@ -161,10 +161,10 @@ "aggregate_name": "median", "aggregate_unit": "time", "iterations": 10, - "real_time": 1.2567576874829456e+03, - "cpu_time": 2.4211864564449570e+03, + "real_time": 9.5106238276583042e+02, + "cpu_time": 1.1538258515868399e+03, "time_unit": "us", - "items_per_second": 7.9576666055393412e+02 + "items_per_second": 1.0514562323412738e+03 }, { "name": "frodoPIR/client_process_response/1.0M/1.0KB/process_time/real_time_stddev", @@ -177,10 +177,10 @@ "aggregate_name": "stddev", "aggregate_unit": "time", "iterations": 10, - "real_time": 3.3609910765168721e+01, - "cpu_time": 8.2183406367893156e+01, + "real_time": 1.5532583931235271e+01, + "cpu_time": 4.8174406415136403e+01, "time_unit": "us", - "items_per_second": 2.1388687862674374e+01 + "items_per_second": 1.6738445878293440e+01 }, { "name": "frodoPIR/client_process_response/1.0M/1.0KB/process_time/real_time_cv", @@ -193,10 +193,10 @@ "aggregate_name": "cv", "aggregate_unit": "percentage", "iterations": 10, - "real_time": 2.6767109375303470e-02, - "cpu_time": 3.3668404409710903e-02, + "real_time": 1.6259245987835520e-02, + "cpu_time": 4.1673790673036802e-02, "time_unit": "us", - "items_per_second": 2.6839178732025289e-02 + "items_per_second": 1.5986626781556535e-02 }, { "name": "frodoPIR/client_process_response/1.0M/1.0KB/process_time/real_time_min", @@ -209,10 +209,10 @@ "aggregate_name": "min", "aggregate_unit": "time", "iterations": 10, - "real_time": 1.1997765999979038e+03, - "cpu_time": 2.3396891002448683e+03, + "real_time": 9.4099914485923364e+02, + "cpu_time": 1.1029991651443636e+03, "time_unit": "us", - "items_per_second": 7.6518854303394039e+02 + "items_per_second": 1.0164879106166710e+03 }, { "name": "frodoPIR/client_process_response/1.0M/1.0KB/process_time/real_time_max", @@ -225,10 +225,10 @@ "aggregate_name": "max", "aggregate_unit": "time", "iterations": 10, - "real_time": 1.3068674499947974e+03, - "cpu_time": 2.5783706876609358e+03, + "real_time": 9.8377953102593381e+02, + "cpu_time": 1.2538283242410498e+03, "time_unit": "us", - "items_per_second": 8.3348850111074614e+02 + "items_per_second": 1.0627002218472712e+03 }, { "name": "frodoPIR/client_query/1.0M/1.0KB/process_time/real_time_mean", @@ -241,10 +241,10 @@ "aggregate_name": "mean", "aggregate_unit": "time", "iterations": 10, - "real_time": 4.5408198525277692e+02, - "cpu_time": 4.5262125229503283e+02, + "real_time": 4.7177428911622673e+02, + "cpu_time": 4.7028321182273322e+02, "time_unit": "us", - "items_per_second": 2.2023489889620701e+03 + "items_per_second": 2.1198031139091754e+03 }, { "name": "frodoPIR/client_query/1.0M/1.0KB/process_time/real_time_median", @@ -257,10 +257,10 @@ "aggregate_name": "median", "aggregate_unit": "time", "iterations": 10, - "real_time": 4.5417128525461794e+02, - "cpu_time": 4.5270823386836594e+02, + "real_time": 4.7215538434937451e+02, + "cpu_time": 4.7067653767520653e+02, "time_unit": "us", - "items_per_second": 2.2018275118281654e+03 + "items_per_second": 2.1179486908055605e+03 }, { "name": "frodoPIR/client_query/1.0M/1.0KB/process_time/real_time_stddev", @@ -273,10 +273,10 @@ "aggregate_name": "stddev", "aggregate_unit": "time", "iterations": 10, - "real_time": 3.2797978838219235e+00, - "cpu_time": 3.2669561555505786e+00, + "real_time": 4.1163308549058044e+00, + "cpu_time": 4.0876202884778170e+00, "time_unit": "us", - "items_per_second": 1.5922958573861042e+01 + "items_per_second": 1.8519668567601606e+01 }, { "name": "frodoPIR/client_query/1.0M/1.0KB/process_time/real_time_cv", @@ -289,10 +289,10 @@ "aggregate_name": "cv", "aggregate_unit": "percentage", "iterations": 10, - "real_time": 7.2229200680492441e-03, - "cpu_time": 7.2178585052852838e-03, + "real_time": 8.7252123523240601e-03, + "cpu_time": 8.6918269368683916e-03, "time_unit": "us", - "items_per_second": 7.2299888226912048e-03 + "items_per_second": 8.7365040866692004e-03 }, { "name": "frodoPIR/client_query/1.0M/1.0KB/process_time/real_time_min", @@ -305,10 +305,10 @@ "aggregate_name": "min", "aggregate_unit": "time", "iterations": 10, - "real_time": 4.4936050960586726e+02, - "cpu_time": 4.4798240457730100e+02, + "real_time": 4.6500550003848628e+02, + "cpu_time": 4.6359158157082732e+02, "time_unit": "us", - "items_per_second": 2.1814510115684407e+03 + "items_per_second": 2.0901016964942996e+03 }, { "name": "frodoPIR/client_query/1.0M/1.0KB/process_time/real_time_max", @@ -321,10 +321,10 @@ "aggregate_name": "max", "aggregate_unit": "time", "iterations": 10, - "real_time": 4.5841047756603541e+02, - "cpu_time": 4.5692838144672203e+02, + "real_time": 4.7844561902288632e+02, + "cpu_time": 4.7679579883875630e+02, "time_unit": "us", - "items_per_second": 2.2253846936329519e+03 + "items_per_second": 2.1505121980648291e+03 }, { "name": "frodoPIR/client_setup/1.0M/1.0KB/process_time/real_time_mean", @@ -337,10 +337,10 @@ "aggregate_name": "mean", "aggregate_unit": "time", "iterations": 10, - "real_time": 2.0512468286999683e+04, - "cpu_time": 2.0511923185002528e+04, + "real_time": 2.1057507193400215e+04, + "cpu_time": 2.1056606011099942e+04, "time_unit": "ms", - "items_per_second": 4.8750891252366632e-02 + "items_per_second": 4.7489375707263852e-02 }, { "name": "frodoPIR/client_setup/1.0M/1.0KB/process_time/real_time_median", @@ -353,10 +353,10 @@ "aggregate_name": "median", "aggregate_unit": "time", "iterations": 10, - "real_time": 2.0507694414499838e+04, - "cpu_time": 2.0507203660010418e+04, + "real_time": 2.1039507258000413e+04, + "cpu_time": 2.1038653379997413e+04, "time_unit": "ms", - "items_per_second": 4.8762187739471802e-02 + "items_per_second": 4.7529636353411883e-02 }, { "name": "frodoPIR/client_setup/1.0M/1.0KB/process_time/real_time_stddev", @@ -369,10 +369,10 @@ "aggregate_name": "stddev", "aggregate_unit": "time", "iterations": 10, - "real_time": 2.2805044356356241e+01, - "cpu_time": 2.2819299521719408e+01, + "real_time": 6.2402558564833825e+01, + "cpu_time": 6.2426873159921740e+01, "time_unit": "ms", - "items_per_second": 5.4119505611677893e-05 + "items_per_second": 1.4014049178682410e-04 }, { "name": "frodoPIR/client_setup/1.0M/1.0KB/process_time/real_time_cv", @@ -385,10 +385,10 @@ "aggregate_name": "cv", "aggregate_unit": "percentage", "iterations": 10, - "real_time": 1.1117650024989696e-03, - "cpu_time": 1.1124895172386342e-03, + "real_time": 2.9634352248680161e-03, + "cpu_time": 2.9647167794759305e-03, "time_unit": "ms", - "items_per_second": 1.1101234094679374e-03 + "items_per_second": 2.9509861879567427e-03 }, { "name": "frodoPIR/client_setup/1.0M/1.0KB/process_time/real_time_min", @@ -401,10 +401,10 @@ "aggregate_name": "min", "aggregate_unit": "time", "iterations": 10, - "real_time": 2.0488918811999611e+04, - "cpu_time": 2.0488282952996087e+04, + "real_time": 2.0984151461000693e+04, + "cpu_time": 2.0983314779005013e+04, "time_unit": "ms", - "items_per_second": 4.8621852162448069e-02 + "items_per_second": 4.7146214984855044e-02 }, { "name": "frodoPIR/client_setup/1.0M/1.0KB/process_time/real_time_max", @@ -417,10 +417,10 @@ "aggregate_name": "max", "aggregate_unit": "time", "iterations": 10, - "real_time": 2.0566884137999295e+04, - "cpu_time": 2.0566376808987116e+04, + "real_time": 2.1210610445000384e+04, + "cpu_time": 2.1209789956992608e+04, "time_unit": "ms", - "items_per_second": 4.8806870151407722e-02 + "items_per_second": 4.7655012491618375e-02 }, { "name": "frodoPIR/server_respond/1.0M/1.0KB/process_time/real_time_mean", @@ -433,10 +433,10 @@ "aggregate_name": "mean", "aggregate_unit": "time", "iterations": 10, - "real_time": 1.5168371969994044e+02, - "cpu_time": 3.7251060584021616e+03, + "real_time": 3.0715859640022245e+01, + "cpu_time": 8.8429085359995975e+02, "time_unit": "ms", - "items_per_second": 6.6035287884434375e+00 + "items_per_second": 3.2566186991417730e+01 }, { "name": "frodoPIR/server_respond/1.0M/1.0KB/process_time/real_time_median", @@ -449,10 +449,10 @@ "aggregate_name": "median", "aggregate_unit": "time", "iterations": 10, - "real_time": 1.4983296799937307e+02, - "cpu_time": 3.7114892490062630e+03, + "real_time": 3.0809809700076585e+01, + "cpu_time": 8.8639989070070442e+02, "time_unit": "ms", - "items_per_second": 6.6742494686788287e+00 + "items_per_second": 3.2457198658145806e+01 }, { "name": "frodoPIR/server_respond/1.0M/1.0KB/process_time/real_time_stddev", @@ -465,10 +465,10 @@ "aggregate_name": "stddev", "aggregate_unit": "time", "iterations": 10, - "real_time": 6.6271355623665427e+00, - "cpu_time": 6.1930959537676095e+01, + "real_time": 5.6096585549001876e-01, + "cpu_time": 1.0005562396841054e+01, "time_unit": "ms", - "items_per_second": 2.7660581971827214e-01 + "items_per_second": 5.9131524183599193e-01 }, { "name": "frodoPIR/server_respond/1.0M/1.0KB/process_time/real_time_cv", @@ -481,10 +481,10 @@ "aggregate_name": "cv", "aggregate_unit": "percentage", "iterations": 10, - "real_time": 4.3690486859606893e-02, - "cpu_time": 1.6625287593621058e-02, + "real_time": 1.8263068722943691e-02, + "cpu_time": 1.1314786708590594e-02, "time_unit": "ms", - "items_per_second": 4.1887576866833462e-02 + "items_per_second": 1.8157337301779392e-02 }, { "name": "frodoPIR/server_respond/1.0M/1.0KB/process_time/real_time_min", @@ -497,10 +497,10 @@ "aggregate_name": "min", "aggregate_unit": "time", "iterations": 10, - "real_time": 1.4335545199992339e+02, - "cpu_time": 3.6456296899996232e+03, + "real_time": 2.9759062399898539e+01, + "cpu_time": 8.6413804299954791e+02, "time_unit": "ms", - "items_per_second": 5.9992879925079716e+00 + "items_per_second": 3.1352013180423516e+01 }, { "name": "frodoPIR/server_respond/1.0M/1.0KB/process_time/real_time_max", @@ -513,10 +513,10 @@ "aggregate_name": "max", "aggregate_unit": "time", "iterations": 10, - "real_time": 1.6668644699984725e+02, - "cpu_time": 3.8247328340075910e+03, + "real_time": 3.1895878400064248e+01, + "cpu_time": 8.9785094600229058e+02, "time_unit": "ms", - "items_per_second": 6.9756677269625884e+00 + "items_per_second": 3.3603209219501800e+01 }, { "name": "frodoPIR/server_setup/1.0M/1.0KB/process_time/real_time_mean", @@ -529,10 +529,10 @@ "aggregate_name": "mean", "aggregate_unit": "time", "iterations": 10, - "real_time": 6.0564851884100065e+01, - "cpu_time": 1.1526428564858986e+03, + "real_time": 6.7972896044900338e+01, + "cpu_time": 1.2042952963337011e+03, "time_unit": "s", - "items_per_second": 1.6520707863408726e-02 + "items_per_second": 1.4713000686602801e-02 }, { "name": "frodoPIR/server_setup/1.0M/1.0KB/process_time/real_time_median", @@ -545,10 +545,10 @@ "aggregate_name": "median", "aggregate_unit": "time", "iterations": 10, - "real_time": 6.0147048195000025e+01, - "cpu_time": 1.1355560841019978e+03, + "real_time": 6.7734174828000505e+01, + "cpu_time": 1.2047041670360049e+03, "time_unit": "s", - "items_per_second": 1.6626054261070396e-02 + "items_per_second": 1.4763606044040593e-02 }, { "name": "frodoPIR/server_setup/1.0M/1.0KB/process_time/real_time_stddev", @@ -561,10 +561,10 @@ "aggregate_name": "stddev", "aggregate_unit": "time", "iterations": 10, - "real_time": 1.5467945133903964e+00, - "cpu_time": 4.2368848606022695e+01, + "real_time": 6.6667770198128984e-01, + "cpu_time": 3.7335639282634654e+00, "time_unit": "s", - "items_per_second": 4.1257304571858881e-04 + "items_per_second": 1.4211578808680787e-04 }, { "name": "frodoPIR/server_setup/1.0M/1.0KB/process_time/real_time_cv", @@ -577,10 +577,10 @@ "aggregate_name": "cv", "aggregate_unit": "percentage", "iterations": 10, - "real_time": 2.5539474881411745e-02, - "cpu_time": 3.6758002157922569e-02, + "real_time": 9.8079931968899428e-03, + "cpu_time": 3.1002063527357021e-03, "time_unit": "s", - "items_per_second": 2.4973085241243555e-02 + "items_per_second": 9.6591980870505949e-03 }, { "name": "frodoPIR/server_setup/1.0M/1.0KB/process_time/real_time_min", @@ -593,10 +593,10 @@ "aggregate_name": "min", "aggregate_unit": "time", "iterations": 10, - "real_time": 5.8931253856000694e+01, - "cpu_time": 1.1040201909600000e+03, + "real_time": 6.7257376491999821e+01, + "cpu_time": 1.1972470501310017e+03, "time_unit": "s", - "items_per_second": 1.5801547594166025e-02 + "items_per_second": 1.4358960396645507e-02 }, { "name": "frodoPIR/server_setup/1.0M/1.0KB/process_time/real_time_max", @@ -609,10 +609,10 @@ "aggregate_name": "max", "aggregate_unit": "time", "iterations": 10, - "real_time": 6.3284940544001074e+01, - "cpu_time": 1.2344782337650104e+03, + "real_time": 6.9642924861998836e+01, + "cpu_time": 1.2089161019849998e+03, "time_unit": "s", - "items_per_second": 1.6968924544580596e-02 + "items_per_second": 1.4868257612143833e-02 } ] } diff --git a/examples/frodoPIR.cpp b/examples/frodoPIR.cpp index 2bb0839..35c153c 100644 --- a/examples/frodoPIR.cpp +++ b/examples/frodoPIR.cpp @@ -20,6 +20,21 @@ to_hex(std::span bytes) return ss.str(); } +const auto format_bytes = [](size_t bytes) -> std::string { + const char* suffixes[] = { "B", "KB", "MB", "GB" }; + int index = 0; + double size = static_cast(bytes); + + while (size >= 1024 && index < 3) { + size /= 1024; + index++; + } + + std::ostringstream oss; + oss << std::fixed << std::setprecision(1) << size << suffixes[index]; + return oss.str(); +}; + // Compile with // g++ -std=c++20 -Wall -Wextra -pedantic -O3 -march=native -I include -I sha3/include -I RandomShake/include examples/frodoPIR.cpp int @@ -27,7 +42,7 @@ main() { // Parameter setup for instantiating FrodoPIR constexpr size_t db_entry_count = 1ul << 16; - constexpr size_t db_entry_byte_len = 32; + constexpr size_t db_entry_byte_len = 1024; constexpr size_t mat_element_bitlen = 10; // Database, query and response byte length @@ -37,6 +52,18 @@ main() constexpr size_t query_byte_len = frodoPIR_vector::row_vector_t::get_byte_len(); constexpr size_t response_byte_len = frodoPIR_vector::row_vector_t::get_byte_len(); + std::cout << "FrodoPIR:\n"; + std::cout << "Number of entries in Index Database : " << db_entry_count << "\n"; + std::cout << "Size of each database entry : " << format_bytes(db_entry_byte_len) << "\n"; + std::cout << "DB size : " << format_bytes(db_byte_len) << "\n"; + std::cout << "Encoded DB matrix element bit length : " << mat_element_bitlen << "\n"; + std::cout << "Encoded DB matrix dimension : " << db_entry_count << " x " << parsed_db_column_count << "\n"; + std::cout << "Seed size : " << format_bytes(frodoPIR_server::SEED_BYTE_LEN) << "\n"; + std::cout << "Hint download size : " << format_bytes(pub_matM_byte_len) << "\n"; + std::cout << "Query vector size : " << format_bytes(query_byte_len) << "\n"; + std::cout << "Response vector size : " << format_bytes(response_byte_len) << "\n"; + std::cout << "\n"; + // Database, query and response memory allocation std::array::digits> seed_μ{}; std::vector db_bytes(db_byte_len, 0); diff --git a/include/frodoPIR/internals/matrix/matrix.hpp b/include/frodoPIR/internals/matrix/matrix.hpp index 16d2de0..b338ebc 100644 --- a/include/frodoPIR/internals/matrix/matrix.hpp +++ b/include/frodoPIR/internals/matrix/matrix.hpp @@ -1,5 +1,6 @@ #pragma once #include "frodoPIR/internals/utility/csprng.hpp" +#include "frodoPIR/internals/utility/force_inline.hpp" #include "frodoPIR/internals/utility/utils.hpp" #include "sha3/shake128.hpp" #include @@ -177,17 +178,16 @@ struct matrix_t const size_t spawnable_num_threads = std::max(min_num_threads, hw_hinted_max_num_threads); const size_t total_num_elements = rows * cols; - const size_t num_elements_per_thread = total_num_elements / spawnable_num_threads; - const size_t num_elements_distributed = num_elements_per_thread * spawnable_num_threads; - const size_t remaining_num_elements = total_num_elements - num_elements_distributed; + const size_t num_elements_per_thread = (total_num_elements + (spawnable_num_threads - 1)) / spawnable_num_threads; std::vector threads; threads.reserve(spawnable_num_threads); - // Let's first spawn N -number of threads s.t. each of them will have equal many rows to work on. + // Let's spawn N -number of threads s.t. each of first (N-1) of them will have equal many elements to work on, + // while the last one might have lesser many elements to process. for (size_t t_idx = 0; t_idx < spawnable_num_threads; t_idx++) { const size_t e_idx_begin = t_idx * num_elements_per_thread; - const size_t e_idx_end = e_idx_begin + num_elements_per_thread; + const size_t e_idx_end = std::min(e_idx_begin + num_elements_per_thread, total_num_elements); auto thread = std::thread([=, this, &rhs, &res]() { for (size_t e_idx = e_idx_begin; e_idx < e_idx_end; e_idx++) { @@ -198,16 +198,6 @@ struct matrix_t threads.push_back(std::move(thread)); } - // Finally, remaining rows, if any, are processed by "this" parent thread. - if (remaining_num_elements > 0) { - const size_t final_thread_e_idx_begin = num_elements_distributed; - const size_t final_thread_e_idx_end = final_thread_e_idx_begin + remaining_num_elements; - - for (size_t e_idx = final_thread_e_idx_begin; e_idx < final_thread_e_idx_end; e_idx++) { - res[e_idx] = (*this)[e_idx] + rhs[e_idx]; - } - } - // Now we wait until all of spawned threads finish their job. std::ranges::for_each(threads, [](auto& handle) { handle.join(); }); @@ -234,19 +224,18 @@ struct matrix_t constexpr size_t distributable_work_count = std::max(rows, rhs_cols); constexpr bool if_distribute_across_row = rows >= rhs_cols; - const size_t num_work_per_thread = distributable_work_count / spawnable_num_threads; - const size_t num_work_distributed = num_work_per_thread * spawnable_num_threads; - const size_t remaining_num_work = distributable_work_count - num_work_distributed; + const size_t num_work_per_thread = (distributable_work_count + (spawnable_num_threads - 1)) / spawnable_num_threads; std::vector threads; threads.reserve(spawnable_num_threads); - // Let's first spawn N -number of threads s.t. each of them will have equal many rows to work on. + // Let's spawn N -number of threads s.t. each of first (N-1) of them will have equal many rows/ cols to work on, + // while the last one might have lesser many rows/ cols to process. for (size_t t_idx = 0; t_idx < spawnable_num_threads; t_idx++) { if constexpr (if_distribute_across_row) { // If there are more (or equal many) rows than columns, it's better to distribute computation of rows. const size_t r_idx_begin = t_idx * num_work_per_thread; - const size_t r_idx_end = r_idx_begin + num_work_per_thread; + const size_t r_idx_end = std::min(r_idx_begin + num_work_per_thread, distributable_work_count); auto thread = std::thread([=, this, &rhs, &res]() { for (size_t r_idx = r_idx_begin; r_idx < r_idx_end; r_idx++) { @@ -262,7 +251,7 @@ struct matrix_t } else { // If there are more columns, it's better to distribute computation of columns across threads. const size_t c_idx_begin = t_idx * num_work_per_thread; - const size_t c_idx_end = c_idx_begin + num_work_per_thread; + const size_t c_idx_end = std::min(c_idx_begin + num_work_per_thread, distributable_work_count); auto thread = std::thread([=, this, &rhs, &res]() { for (size_t r_idx = 0; r_idx < rows; r_idx++) { @@ -278,31 +267,63 @@ struct matrix_t } } - // Finally, remaining rows, if any, are processed by "this" parent thread. - if (remaining_num_work > 0) { - if constexpr (if_distribute_across_row) { - const size_t final_thread_r_idx_begin = num_work_distributed; - const size_t final_thread_r_idx_end = final_thread_r_idx_begin + remaining_num_work; + // Now we wait until all of spawned threads finish their job. + std::ranges::for_each(threads, [](auto& handle) { handle.join(); }); - for (size_t r_idx = final_thread_r_idx_begin; r_idx < final_thread_r_idx_end; r_idx++) { - for (size_t k = 0; k < cols; k++) { - for (size_t c_idx = 0; c_idx < rhs_cols; c_idx++) { - res[{ r_idx, c_idx }] += (*this)[{ r_idx, k }] * rhs[{ k, c_idx }]; - } - } - } - } else { - const size_t final_thread_c_idx_begin = num_work_distributed; - const size_t final_thread_c_idx_end = final_thread_c_idx_begin + remaining_num_work; + return res; + } + + // Given a matrix of dimension m x n, returns a transposed matrix of dimension n x m. + forceinline matrix_t transpose() const + { + matrix_t res{}; + + for (size_t r_idx = 0; r_idx < cols; r_idx++) { + for (size_t c_idx = 0; c_idx < rows; c_idx++) { + res[{ r_idx, c_idx }] = (*this)[{ c_idx, r_idx }]; + } + } + + return res; + } + + // Given one row vector A ( of length cols ) and a transposed matrix B ( of dimension rhs_rows x rhs_cols ) s.t. cols == rhs_cols, + // this routine can be used for multiplying them over Zq, resulting into a row vector (C) of length rhs_rows. + // + // This vector matrix multiplication collects inspiration from + // https://github.com/itzmeanjan/ChalametPIR/blob/7b4fcae6dfaefeffa93458dbdd48a5b408beff71/src/pir_internals/matrix.rs#L63-L77, + // so that server-respond function can enjoy better memory bandwidth. + template + requires((rows == 1) && (cols == rhs_cols)) + forceinline matrix_t row_vector_x_transposed_matrix(const matrix_t& rhs) const + { + matrix_t res{}; - for (size_t r_idx = 0; r_idx < rows; r_idx++) { + constexpr size_t min_num_threads = 1; + const size_t hw_hinted_max_num_threads = std::thread::hardware_concurrency(); + const size_t spawnable_num_threads = std::max(min_num_threads, hw_hinted_max_num_threads); + + constexpr size_t distributable_work_count = rhs_rows; + const size_t num_work_per_thread = (distributable_work_count + (spawnable_num_threads - 1)) / spawnable_num_threads; + + std::vector threads; + threads.reserve(spawnable_num_threads); + + // Let's spawn N -number of threads s.t. each of first (N-1) of them will have equal many cols to work on, + // while the last one might have lesser many cols to process. + for (size_t t_idx = 0; t_idx < spawnable_num_threads; t_idx++) { + const size_t c_idx_begin = t_idx * num_work_per_thread; + const size_t c_idx_end = std::min(c_idx_begin + num_work_per_thread, distributable_work_count); + + auto thread = std::thread([=, this, &rhs, &res]() { + for (size_t c_idx = c_idx_begin; c_idx < c_idx_end; c_idx++) { for (size_t k = 0; k < cols; k++) { - for (size_t c_idx = final_thread_c_idx_begin; c_idx < final_thread_c_idx_end; c_idx++) { - res[{ r_idx, c_idx }] += (*this)[{ r_idx, k }] * rhs[{ k, c_idx }]; - } + res[{ 0, c_idx }] += (*this)[{ 0, k }] * rhs[{ c_idx, k }]; } } - } + }); + + threads.push_back(std::move(thread)); } // Now we wait until all of spawned threads finish their job. diff --git a/include/frodoPIR/server.hpp b/include/frodoPIR/server.hpp index 79e9a61..83f29f7 100644 --- a/include/frodoPIR/server.hpp +++ b/include/frodoPIR/server.hpp @@ -29,7 +29,7 @@ struct server_t // Type aliases. using pub_mat_A_t = frodoPIR_matrix::matrix_t; using pub_mat_M_t = frodoPIR_matrix::matrix_t; - using parsed_db_t = frodoPIR_matrix::matrix_t; + using parsed_db_transposed_mat_t = frodoPIR_matrix::matrix_t; using query_t = frodoPIR_vector::row_vector_t; // Constructor(s) @@ -55,20 +55,20 @@ struct server_t const auto D = frodoPIR_serialization::parse_db_bytes(db_bytes); const auto M = A * D; - return { server_t(D), M }; + return { server_t(D.transpose()), M }; } // Given byte serialized client query, this routine can be used for responding back to it, producing byte serialized server response. constexpr void respond(std::span query_bytes, std::span response_bytes) const { const auto b_tilda = query_t::from_le_bytes(query_bytes); - const auto c_tilda = b_tilda * this->D; + const auto c_tilda = b_tilda.row_vector_x_transposed_matrix(this->D); c_tilda.to_le_bytes(response_bytes); } private: - parsed_db_t D{}; + parsed_db_transposed_mat_t D{}; }; } diff --git a/tests/test_matrix_operations.cpp b/tests/test_matrix_operations.cpp index bcb35b9..e0059d3 100644 --- a/tests/test_matrix_operations.cpp +++ b/tests/test_matrix_operations.cpp @@ -1,11 +1,35 @@ #include "frodoPIR/internals/matrix/matrix.hpp" +#include "frodoPIR/internals/matrix/vector.hpp" #include #include #include #include #include -TEST(FrodoPIR, MatrixOperations) +TEST(FrodoPIR, MatrixMultiplicationWorks) +{ + constexpr size_t λ = 128; + constexpr size_t rows = 1024; + constexpr size_t cols = rows + 1; + + std::array::digits> μ{}; + auto μ_span = std::span(μ); + + csprng::csprng_t csprng; + csprng.generate(μ_span); + + auto A = frodoPIR_matrix::matrix_t::template generate<λ>(μ_span); + + auto I = frodoPIR_matrix::matrix_t::identity(); + auto AI = A * I; + EXPECT_EQ(A, AI); + + auto I_prime = frodoPIR_matrix::matrix_t::identity(); + auto IA = I_prime * A; + EXPECT_EQ(A, IA); +} + +TEST(FrodoPIR, MatrixSerializationWorks) { constexpr size_t λ = 128; constexpr size_t rows = 1024; @@ -25,22 +49,43 @@ TEST(FrodoPIR, MatrixOperations) auto A = frodoPIR_matrix::matrix_t::template generate<λ>(μ_span); A.to_le_bytes(matA_bytes_span); - { - auto A_prime = frodoPIR_matrix::matrix_t::from_le_bytes(matA_bytes_span); - EXPECT_EQ(A, A_prime); - } + auto A_prime = frodoPIR_matrix::matrix_t::from_le_bytes(matA_bytes_span); + EXPECT_EQ(A, A_prime); +} - { - auto I = frodoPIR_matrix::matrix_t::identity(); - auto AI = A * I; +TEST(FrodoPIR, RowVectorMatrixMultiplicationWorks) +{ + constexpr size_t λ = 128; + constexpr size_t cols = 1024; - EXPECT_EQ(A, AI); - } + std::array::digits> μ{}; + auto μ_span = std::span(μ); + + csprng::csprng_t csprng; + csprng.generate(μ_span); + + auto row_vector = frodoPIR_vector::row_vector_t::template generate<λ>(μ_span); + auto I = frodoPIR_matrix::matrix_t::identity(); - { - auto I_prime = frodoPIR_matrix::matrix_t::identity(); - auto IA = I_prime * A; + auto row_vector_prime = row_vector.row_vector_x_transposed_matrix(I); + EXPECT_EQ(row_vector, row_vector_prime); +} + +TEST(FrodoPIR, MatrixTranspositionWorks) +{ + constexpr size_t λ = 128; + constexpr size_t rows = 1024; + constexpr size_t cols = rows + 1; + + std::array::digits> μ{}; + auto μ_span = std::span(μ); + + csprng::csprng_t csprng; + csprng.generate(μ_span); + + auto A = frodoPIR_matrix::matrix_t::template generate<λ>(μ_span); + auto A_transposed = A.transpose(); + auto A_transposed_transposed = A_transposed.transpose(); - EXPECT_EQ(A, IA); - } + EXPECT_EQ(A, A_transposed_transposed); }