├── .dockerignore ├── .gitignore ├── .gitmodules ├── .vimspector.json ├── Dockerfile ├── LICENSE ├── MP-SPDZ ├── .clang-format ├── Functions │ ├── add.mpc │ ├── bench │ │ ├── AES.mpc │ │ ├── BIT_AND.mpc │ │ ├── Input.mpc │ │ ├── Int_Compare.mpc │ │ ├── Int_Division.mpc │ │ ├── Int_Multiplication.mpc │ │ ├── LeNet.mpc │ │ ├── LogReg.mpc │ │ ├── PrivateSetIntersection.mpc │ │ ├── Reveal.mpc │ │ ├── SecureAuction.mpc │ │ ├── SecureMax.mpc │ │ ├── SecureMean.mpc │ │ ├── SecureMin.mpc │ │ └── VGG.mpc │ ├── int_test.mpc │ ├── int_test_32.mpc │ ├── mul.mpc │ ├── mul_fix.mpc │ └── tutorial.mpc ├── Input │ ├── Input-P0-0-0 │ ├── Input-P0-0-1 │ ├── Input-P0-0-2 │ ├── Input-P0-0-3 │ ├── Input-P1-0-0 │ └── PUB-INPUT ├── lib │ ├── Constants.hpp │ ├── Machine.hpp │ ├── Program.hpp │ ├── Shares │ │ ├── CIntSet.hpp │ │ ├── CInteger.hpp │ │ ├── DataSet.hpp │ │ └── Integer.hpp │ └── help │ │ ├── Conv.hpp │ │ ├── Input.hpp │ │ └── Util.hpp └── requirements.txt ├── Makefile ├── README.md ├── config.h ├── core ├── arch │ ├── AVX.h │ ├── AVX512.h │ ├── BOOL.h │ ├── DATATYPE.h │ ├── SSE.h │ └── STD.h ├── crypto │ ├── aes │ │ ├── AES.h │ │ ├── AES_BS.h │ │ ├── AES_BS_SHORT.h │ │ └── AES_SSL.h │ └── sha │ │ ├── SHA_256.h │ │ ├── SHA_256_arm.h │ │ └── SHA_256_x86.h ├── cuda │ ├── Makefile │ ├── conv_cutlass_int.cu │ ├── conv_cutlass_int.h │ ├── gemm_cutlass_int.cu │ ├── gemm_cutlass_int.h │ └── include │ │ ├── conv2d_NHWC.cuh │ │ ├── gemm.cuh │ │ ├── transform.cuh │ │ └── utils.cuh ├── include │ └── pch.h ├── init.hpp ├── microbenchmarks │ ├── ortho_test.cpp │ ├── throughputs.cpp │ └── throughputs_openSSL.cpp ├── networking │ ├── buffers.h │ ├── client.hpp │ ├── packer.hpp │ ├── server.hpp │ ├── socket.hpp │ └── sockethelper.h ├── ssl_certificates │ ├── server.crt │ └── server.key └── utils │ ├── CircuitDetails.h │ ├── CircuitInfo.hpp │ ├── print.hpp │ ├── randomizer.h │ ├── timing.hpp │ └── xorshift.h ├── datatypes ├── Additive_Share.hpp ├── XOR_Share.hpp ├── float_fixed_converter.hpp ├── k_bitset.hpp ├── k_clear.hpp └── k_sint.hpp ├── log.txt ├── main.cpp ├── measurements ├── configs │ ├── artifacts │ │ ├── hpmpc │ │ │ ├── ARTIFACT_EVALUATION.md │ │ │ ├── figure1 │ │ │ │ ├── README.md │ │ │ │ ├── figure1_multiplication.conf │ │ │ │ └── figure1_scalar_product.conf │ │ │ ├── figure10 │ │ │ │ ├── README.md │ │ │ │ ├── figure10a_aes_latency.conf │ │ │ │ ├── figure10b_mult_throughput.conf │ │ │ │ └── figure10c_vector_matrix.conf │ │ │ ├── figure29 │ │ │ │ ├── README.md │ │ │ │ ├── figure29_runtime_Trio_Quad.conf │ │ │ │ └── figure29_runtime_baseline.conf │ │ │ ├── figure9 │ │ │ │ ├── README.md │ │ │ │ ├── figure9_bits_per_register.conf │ │ │ │ └── figure9_num_processes.conf │ │ │ ├── machines.json │ │ │ ├── run_all_experiments.sh │ │ │ ├── run_all_on_remote_servers.py │ │ │ ├── run_with_tmux_grid.sh │ │ │ ├── table10 │ │ │ │ ├── README.md │ │ │ │ ├── table10_aes-3PC.conf │ │ │ │ ├── table10_aes-4PC.conf │ │ │ │ ├── table10_aes-PRE-3PC.conf │ │ │ │ └── table10_aes-PRE-4PC.conf │ │ │ ├── table6 │ │ │ │ ├── README.md │ │ │ │ └── table6_throughput.conf │ │ │ ├── table7 │ │ │ │ ├── README.md │ │ │ │ ├── table7_throughput_3PC_PRE0.conf │ │ │ │ ├── table7_throughput_3PC_PRE1.conf │ │ │ │ ├── table7_throughput_4PC_PRE0.conf │ │ │ │ └── table7_throughput_4PC_PRE1.conf │ │ │ ├── table8 │ │ │ │ ├── README.md │ │ │ │ ├── table8_throughput_3PC_PRE0.conf │ │ │ │ ├── table8_throughput_3PC_PRE1.conf │ │ │ │ ├── table8_throughput_4PC_PRE0.conf │ │ │ │ └── table8_throughput_4PC_PRE1.conf │ │ │ └── table9 │ │ │ │ ├── README.md │ │ │ │ ├── aes_bdw │ │ │ │ ├── table9_aes-3PC.conf │ │ │ │ ├── table9_aes-4PC.conf │ │ │ │ ├── table9_aes-PRE-3PC.conf │ │ │ │ └── table9_aes-PRE-4PC.conf │ │ │ │ ├── aes_lat │ │ │ │ ├── table9_aes1-3PC.conf │ │ │ │ ├── table9_aes1-4PC.conf │ │ │ │ ├── table9_aes1-PRE-3PC.conf │ │ │ │ └── table9_aes1-PRE-4PC.conf │ │ │ │ └── vector_prod20k │ │ │ │ ├── table9_dot-3PC.conf │ │ │ │ ├── table9_dot-4PC.conf │ │ │ │ ├── table9_dot-PRE-3PC.conf │ │ │ │ └── table9_dot-PRE-4PC.conf │ │ ├── pigeon │ │ │ ├── ARTIFACT_EVALUATION.md │ │ │ ├── figure1 │ │ │ │ ├── README.md │ │ │ │ ├── figure1_a.conf │ │ │ │ ├── figure1_b.conf │ │ │ │ ├── figure1_c.conf │ │ │ │ ├── figure1_d.conf │ │ │ │ ├── figure1c_16bits.conf │ │ │ │ └── figure1c_8bits.conf │ │ │ ├── figure3 │ │ │ │ ├── README.md │ │ │ │ ├── figure3CPU.conf │ │ │ │ └── figure3GPU.conf │ │ │ ├── figure6 │ │ │ │ ├── README.md │ │ │ │ ├── figure6_32bit.conf │ │ │ │ └── figure6_64bit.conf │ │ │ ├── machines.json │ │ │ ├── run_all_experiments.sh │ │ │ ├── run_all_experiments_16Core_VMS.sh │ │ │ ├── run_all_on_remote_servers.py │ │ │ ├── run_with_tmux_grid.sh │ │ │ ├── table4 │ │ │ │ ├── README.md │ │ │ │ └── table4.conf │ │ │ ├── table5 │ │ │ │ ├── README.md │ │ │ │ └── table5.conf │ │ │ ├── table6 │ │ │ │ ├── README.md │ │ │ │ ├── table6_cifar.conf │ │ │ │ └── table6_imagenet.conf │ │ │ ├── table7 │ │ │ │ ├── README.md │ │ │ │ └── table7.conf │ │ │ ├── table8 │ │ │ │ ├── README.md │ │ │ │ └── table8.conf │ │ │ └── table9 │ │ │ │ ├── README.md │ │ │ │ └── table9.conf │ │ └── truncation │ │ │ ├── ARTIFACT_EVALUATION.md │ │ │ ├── figure14 │ │ │ ├── figure14_32bit.conf │ │ │ └── figure14_weight_decay.conf │ │ │ ├── figure15 │ │ │ ├── figure15_16bit.conf │ │ │ └── figure15_32bit.conf │ │ │ ├── figure16 │ │ │ ├── figure16_32bit.conf │ │ │ └── figure16_64bit.conf │ │ │ ├── figure17 │ │ │ ├── figure17_32bit.conf │ │ │ └── figure17_64bit.conf │ │ │ ├── machines.json │ │ │ ├── plot_acc.py │ │ │ ├── run_all_experiments.sh │ │ │ ├── run_all_on_remote_servers.py │ │ │ ├── run_with_tmux_grid.sh │ │ │ ├── table5 │ │ │ └── table5_32bit.conf │ │ │ ├── table6 │ │ │ ├── table6_32bit.conf │ │ │ └── table6_64bit.conf │ │ │ └── table8 │ │ │ ├── table8_32bit.conf │ │ │ └── table8_64bit.conf │ ├── benchmarks │ │ ├── DATTYPE.conf │ │ ├── Multiprocesssing.conf │ │ ├── dot_fuse │ │ │ ├── DATTYPE.conf │ │ │ └── Multiprocesssing.conf │ │ ├── imagenetmodels.conf │ │ └── lenet.conf │ ├── gpu_tests │ │ └── test_cuda_matmul.conf │ ├── nn_tests │ │ ├── test_fractional_vs_accuracy_16.conf │ │ ├── test_fractional_vs_accuracy_32.conf │ │ ├── test_fractional_vs_accuracy_64.conf │ │ └── vgg16_accuracy.conf │ ├── trunc_speed │ │ ├── test_truncation_speed16.conf │ │ ├── test_truncation_speed32.conf │ │ └── test_truncation_speed64.conf │ └── unit_tests │ │ ├── test_all_primitives.conf │ │ ├── test_basic_primitives.conf │ │ └── test_basic_primitives_pre.conf ├── network_shaping │ ├── CMAN.json │ ├── LAN.json │ ├── Mixed.json │ ├── WAN1.json │ ├── WAN2.json │ └── shape_network.sh ├── parse_layers.py ├── parse_logs.py ├── run_config.py └── run_pretrained.py ├── programs ├── NN.hpp ├── benchmarks │ ├── AES_BS.hpp │ ├── bench_basic_primitives.hpp │ ├── bench_conv_alt.hpp │ ├── bench_helper.hpp │ ├── bench_nn.hpp │ ├── bench_rounds.hpp │ ├── bench_statistics.hpp │ └── bench_use_cases.hpp ├── functions │ ├── GEMM.hpp │ ├── Relu.hpp │ ├── adders │ │ ├── ppa.hpp │ │ ├── ppa_msb.hpp │ │ ├── ppa_msb_4_way.hpp │ │ ├── ppa_msb_unsafe.hpp │ │ ├── rca.hpp │ │ ├── rca_msb.hpp │ │ └── rca_msb_carry.hpp │ ├── comparisons.hpp │ ├── exact_truncation.hpp │ ├── intersect_bool.hpp │ ├── log_reg.hpp │ ├── max_min.hpp │ ├── mpspdz.hpp │ ├── prob_div.hpp │ ├── prob_truncation.hpp │ ├── search_bool.hpp │ └── share_conversion.hpp ├── mp-spdz_interpreter_template.hpp ├── tests │ ├── test_all.hpp │ ├── test_basic_primitives.hpp │ ├── test_comparisons.hpp │ ├── test_fixed_point_arithmetic.hpp │ ├── test_helper.hpp │ ├── test_mat_mul.hpp │ ├── test_multi_input.hpp │ └── test_truncation.hpp └── tutorials │ ├── YourFirstProgram.hpp │ ├── basic_tutorial.hpp │ ├── fixed_point_tutorial.hpp │ ├── matrix_operations_tutorial.hpp │ └── mixed_circuits_tutorial.hpp ├── protocol_executer.hpp ├── protocols ├── 2-PC │ └── aby2_dummy │ │ ├── aby2.hpp │ │ ├── aby2_init.hpp │ │ └── aby2_post.hpp ├── 3-PC │ ├── astra │ │ ├── astra-P_0_template.hpp │ │ ├── astra-P_1_template.hpp │ │ └── astra-P_2_template.hpp │ ├── ours │ │ ├── oecl-P_0-post_template.hpp │ │ ├── oecl-P_0_init_template.hpp │ │ ├── oecl-P_0_template.hpp │ │ ├── oecl-P_1_init_template.hpp │ │ ├── oecl-P_1_template.hpp │ │ ├── oecl-P_2_init_template.hpp │ │ └── oecl-P_2_template.hpp │ ├── replicated │ │ ├── replicated_init_template.hpp │ │ └── replicated_template.hpp │ └── sharemind │ │ ├── sharemind_init_template.hpp │ │ └── sharemind_template.hpp ├── 4-PC │ ├── fantastic │ │ ├── Fantastic_Four_template.hpp │ │ └── Fantastic_init_template.hpp │ ├── ours │ │ ├── oec-mal-P_0_init_template.hpp │ │ ├── oec-mal-P_0_template.hpp │ │ ├── oec-mal-P_1_init_template.hpp │ │ ├── oec-mal-P_1_template.hpp │ │ ├── oec-mal-P_2_init_template.hpp │ │ ├── oec-mal-P_2_template.hpp │ │ ├── oec-mal-P_3-post_template.hpp │ │ ├── oec-mal-P_3_init_template.hpp │ │ └── oec-mal-P_3_template.hpp │ └── tetrad │ │ ├── Tetrad-P_0_template.hpp │ │ ├── Tetrad-P_1_template.hpp │ │ ├── Tetrad-P_2_template.hpp │ │ └── Tetrad-P_3_template.hpp ├── Protocols.h ├── TTP │ ├── ttp_init_template.hpp │ └── ttp_template.hpp ├── generic_share.hpp ├── init_protocol_base.hpp └── live_protocol_base.hpp └── scripts ├── config.sh ├── export_nn_paths.sh ├── generate_ssl_certificates.sh ├── measure_connection.sh ├── run.sh ├── run_distributed.sh ├── run_locally.sh ├── split-roles-3-execute.sh ├── split-roles-3to4-execute.sh └── split-roles-4-execute.sh /.dockerignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | # Compiled Object files 4 | *.slo 5 | *.lo 6 | *.o 7 | *.obj 8 | *.out 9 | # Debugger config 10 | *.json 11 | #precompiled headers 12 | *.gch 13 | # macroflags 14 | *macro_flags 15 | # nn 16 | nn/ 17 | # log and csv files 18 | *.log 19 | *.log-config 20 | *.csv 21 | # MP-SPDZ directories 22 | Bytecodes 23 | Schedules 24 | #measurements 25 | measurements/logs/ 26 | #executables 27 | executables/ 28 | build/ 29 | #for now 30 | CMake* 31 | #git 32 | .git 33 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Prerequisites 2 | *.d 3 | # Compiled Object files 4 | *.slo 5 | *.lo 6 | *.o 7 | *.obj 8 | *.out 9 | # Debugger config 10 | # *.json 11 | #precompiled headers 12 | *.gch 13 | # macroflags 14 | *macro_flags 15 | # log and csv files 16 | *.log 17 | *.log-config 18 | *.csv 19 | # MP-SPDZ directories 20 | Bytecodes 21 | Schedules 22 | #measurements 23 | measurements/logs/ 24 | #executables 25 | executables/ 26 | build/ 27 | #for now 28 | CMake* 29 | #credentials 30 | machines.json 31 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "nn/Pygeon"] 2 | path = nn/Pygeon 3 | url = https://github.com/chart21/pygeon.git 4 | [submodule "nn/PIGEON"] 5 | path = nn/PIGEON 6 | url = https://github.com/chart21/flexNN.git 7 | branch = hpmpc 8 | -------------------------------------------------------------------------------- /.vimspector.json: -------------------------------------------------------------------------------- 1 | { 2 | "configurations":{ 3 | "Launch":{ 4 | "adapter": "vscode-cpptools", 5 | "configuration": { 6 | "request": "launch", 7 | "program": "executables/run-P0.o", 8 | "cwd": "~/workspace/tmp/hpmpc/", 9 | "externalConsole":true, 10 | "MiMode": "gdb", 11 | "args": [] 12 | } 13 | } 14 | } 15 | } 16 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:24.04 2 | 3 | # Install necessary packages 4 | RUN apt-get update && \ 5 | apt-get install -y --no-install-recommends gcc-12 g++-12 libeigen3-dev libssl-dev git vim ca-certificates python3 jq bc build-essential iproute2 iperf && \ 6 | update-alternatives --install /usr/bin/gcc gcc /usr/bin/gcc-12 100 --slave /usr/bin/g++ g++ /usr/bin/g++-12 && \ 7 | update-alternatives --install /usr/bin/cc cc /usr/bin/gcc 100 && \ 8 | update-alternatives --install /usr/bin/c++ c++ /usr/bin/g++ 100 && \ 9 | rm -rf /var/lib/apt/lists/* 10 | 11 | # Clone repositories and set up repository 12 | RUN git clone https://github.com/chart21/hpmpc && \ 13 | cd hpmpc && \ 14 | git submodule update --init --recursive 15 | 16 | WORKDIR /hpmpc 17 | 18 | ENTRYPOINT ["/bin/bash"] 19 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2022 Christopher Harth-Kitzerow 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | 23 | -------------------------------------------------------------------------------- /MP-SPDZ/.clang-format: -------------------------------------------------------------------------------- 1 | --- 2 | BasedOnStyle: LLVM 3 | IndentWidth: 4 4 | PointerAlignment: Left 5 | AccessModifierOffset: -2 6 | AlwaysBreakTemplateDeclarations: Yes 7 | ColumnLimit: 100 -------------------------------------------------------------------------------- /MP-SPDZ/Functions/add.mpc: -------------------------------------------------------------------------------- 1 | size = int(program.args[1]) 2 | a = sint.Array(size) 3 | b = sint.Array(size) 4 | c = sint.Array(size) 5 | 6 | a.input_from(0) 7 | b.input_from(1) 8 | c.input_from(2) 9 | 10 | result = a + b + c 11 | 12 | print_ln("%s", result.reveal()) 13 | -------------------------------------------------------------------------------- /MP-SPDZ/Functions/bench/AES.mpc: -------------------------------------------------------------------------------- 1 | from circuit import Circuit 2 | sb128 = sbits.get_type(128) 3 | key = sb128(0x2b7e151628aed2a6abf7158809cf4f3c) 4 | plaintext = sb128(0x6bc1bee22e409f96e93d7e117393172a) 5 | n = int(program.args[1]) 6 | aes128 = Circuit('aes_128') 7 | ciphertexts = aes128(sbitvec([key] * n), sbitvec([plaintext] * n)) 8 | ciphertexts.elements()[n - 1].reveal() 9 | -------------------------------------------------------------------------------- /MP-SPDZ/Functions/bench/BIT_AND.mpc: -------------------------------------------------------------------------------- 1 | size = int(program.args[1]) 2 | program.bit_length = 1 3 | player = 3 4 | 5 | datatype = sint 6 | 7 | inputs=datatype.Array(size) 8 | inputs=inputs.assign_all(1).get_vector() 9 | inputs=datatype.bit_and(inputs,inputs) 10 | #verification 11 | inputs[-1].reveal() 12 | -------------------------------------------------------------------------------- /MP-SPDZ/Functions/bench/Input.mpc: -------------------------------------------------------------------------------- 1 | size = int(program.args[1]) 2 | 3 | inputs = sint.Array(size) 4 | inputs.input_from(0) 5 | -------------------------------------------------------------------------------- /MP-SPDZ/Functions/bench/Int_Compare.mpc: -------------------------------------------------------------------------------- 1 | size = int(program.args[1]) 2 | program.bit_length = 32 3 | player = 3 4 | 5 | inputs=sint.Array(size) 6 | inputs.assign_all(0) 7 | 8 | for i in range(size): 9 | inputs[i] = inputs[i]=i 37 | a=comp.if_else(0,bids_quantity.get_vector()) 38 | for t in a: 39 | accumulatedSupply= accumulatedSupply+t 40 | this_z = accumulatedDemand-accumulatedSupply 41 | cond = abs(this_z)> cint(1), 19223372036854775803) 18 | 19 | test(~a, -9223372036854775799) 20 | test(a ^ b, 9) 21 | test(a | b, -1) 22 | test(a & b, -10) 23 | 24 | a = cint(9223372036854775807) 25 | b = cint(1) 26 | test(a + b, -9223372036854775808) 27 | 28 | a = cint(-9223372036854775808) 29 | test(a - b, 9223372036854775807) 30 | 31 | 32 | print_ln('----------------------------------------------------------------------------------') 33 | print_ln('RUNNING REGINT TESTS') 34 | a = regint(-10) 35 | b = regint(-1) 36 | 37 | test(a + b, -11) 38 | test(a - b, -9) 39 | test(a * b, 10) 40 | test(a // b, 10) 41 | test(a % regint(-3), -1) 42 | 43 | test(a << regint(20), -10485760) 44 | test(a >> regint(1), 19223372036854775803) 45 | 46 | test(a ^ b, 9) 47 | test(a | b, -1) 48 | test(a & b, -10) 49 | 50 | a = regint(9223372036854775807) 51 | b = regint(1) 52 | test(a + b, -9223372036854775808) 53 | 54 | a = regint(-9223372036854775808) 55 | test(a - b, 9223372036854775807) 56 | -------------------------------------------------------------------------------- /MP-SPDZ/Functions/int_test_32.mpc: -------------------------------------------------------------------------------- 1 | def test(actual, expected): 2 | print_ln('expected %s, got %s', expected, actual) 3 | 4 | print_ln('TESTS for R 32') 5 | print_ln('----------------------------------------------------------------------------------') 6 | print_ln('RUNNING CINT TESTS') 7 | a = cint(-10) 8 | b = cint(-1) 9 | 10 | test(a + b, -11) 11 | test(a - b, -9) 12 | test(a * b, 10) 13 | test(a // b, 10) 14 | test(a % cint(-3), -1) 15 | 16 | test(a << cint(20), -10485760) 17 | test(cint(20) >> cint(2), 5) 18 | 19 | test(~a, -2147483639) 20 | test(a ^ b, 9) 21 | test(a | b, -1) 22 | test(a & b, -10) 23 | 24 | a = cint(2147483647) 25 | b = cint(1) 26 | test(a + b, -2147483648) 27 | 28 | a = cint(-2147483648) 29 | test(a - b, 2147483647) 30 | 31 | print_ln('----------------------------------------------------------------------------------') 32 | print_ln('CHECK REGINT BITLENGTH') 33 | a = regint(4294967296) 34 | b = regint(2147483648) 35 | c = (a * b) - 1 36 | 37 | test(c, 9223372036854775807) 38 | 39 | print_ln('----------------------------------------------------------------------------------') 40 | print_ln('CHECK CINT BITLENGTH') 41 | 42 | a = cint(4294967296) 43 | b = cint(2147483648) 44 | c = (a * b) - 1 45 | 46 | test(c, -1) 47 | -------------------------------------------------------------------------------- /MP-SPDZ/Functions/mul.mpc: -------------------------------------------------------------------------------- 1 | size = int(program.args[1]) 2 | a = sint.Array(size) 3 | b = sint.Array(size) 4 | c = sint.Array(size) 5 | 6 | a.input_from(0) 7 | b.input_from(1) 8 | c.input_from(2) 9 | 10 | result = a * b * c 11 | 12 | print_ln("%s", result.reveal()) 13 | -------------------------------------------------------------------------------- /MP-SPDZ/Functions/mul_fix.mpc: -------------------------------------------------------------------------------- 1 | program.use_trunc_pr = True 2 | sfix.set_precision(7) 3 | 4 | size = int(program.args[1]) 5 | a = sfix.Array(size) 6 | b = sfix.Array(size) 7 | c = sfix.Array(size) 8 | 9 | a.input_from(0) 10 | b.input_from(1) 11 | c.input_from(2) 12 | 13 | result = a * b * c 14 | 15 | print_ln("%s", result.reveal()) 16 | -------------------------------------------------------------------------------- /MP-SPDZ/Input/Input-P0-0-0: -------------------------------------------------------------------------------- 1 | 20 0 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 19 18 20 2 | -4 -0.0625 3 4 5 10 2 3 4 5 3 | -------------------------------------------------------------------------------- /MP-SPDZ/Input/Input-P0-0-1: -------------------------------------------------------------------------------- 1 | -2 2 | -------------------------------------------------------------------------------- /MP-SPDZ/Input/Input-P0-0-2: -------------------------------------------------------------------------------- 1 | 20 2 | -------------------------------------------------------------------------------- /MP-SPDZ/Input/Input-P0-0-3: -------------------------------------------------------------------------------- 1 | 4 2 | -------------------------------------------------------------------------------- /MP-SPDZ/Input/Input-P1-0-0: -------------------------------------------------------------------------------- 1 | 1 22 2 | -------------------------------------------------------------------------------- /MP-SPDZ/Input/PUB-INPUT: -------------------------------------------------------------------------------- 1 | 0 2 | -------------------------------------------------------------------------------- /MP-SPDZ/lib/help/Util.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include "../../core/utils/print.hpp" 7 | 8 | namespace IR { 9 | 10 | enum class Level { 11 | WARNING, 12 | INFO, 13 | DEBUG, 14 | ERROR, 15 | }; 16 | 17 | template 18 | void log(Level level, Args... args) { 19 | std::ostringstream oss; 20 | switch (level) { 21 | case Level::DEBUG: 22 | oss << "\033[35mDEBUG\033[0m: "; 23 | ((oss << args), ...); 24 | oss << "\n"; 25 | break; 26 | case Level::WARNING: 27 | oss << "\033[33mWARNING\033[0m: "; 28 | ((oss << args), ...); 29 | oss << "\n"; 30 | break; 31 | case Level::INFO: 32 | oss << "\033[36mINFO\033[0m: "; 33 | ((oss << args), ...); 34 | oss << "\n"; 35 | break; 36 | case Level::ERROR: 37 | oss << "\033[31mERROR\033[0m: "; 38 | ((oss << args), ...); 39 | oss << "\n"; 40 | print(oss.str().c_str()); 41 | exit(EXIT_FAILURE); 42 | break; 43 | } 44 | print(oss.str().c_str()); 45 | } 46 | 47 | /** 48 | * return first bits from num 49 | * @param num 50 | * @param bits number of bits to keep 51 | * @return returns first `bits` bits from `num` 52 | */ 53 | inline uint64_t mask(const uint64_t& num, const uint64_t& bits) { 54 | return bits < (64) ? (num & ((1lu << bits) - 1)) : num; 55 | } 56 | 57 | inline uint64_t div_ceil(const uint64_t& a, const uint64_t& b) { 58 | return a == 0lu ? 0lu : 1lu + ((a - 1lu) / b); 59 | } 60 | 61 | } // namespace IR 62 | -------------------------------------------------------------------------------- /MP-SPDZ/requirements.txt: -------------------------------------------------------------------------------- 1 | numpy==1.26.4 2 | torch==2.3.0 3 | -------------------------------------------------------------------------------- /core/arch/BOOL.h: -------------------------------------------------------------------------------- 1 | /* ******************************************** *\ 2 | * 3 | * 4 | * DATATYPE: the base type of every value. 5 | * SDATATYPE: the signed version of DATATYPE. 6 | \* ******************************************** */ 7 | 8 | /* Including headers */ 9 | #pragma once 10 | #include "../../config.h" 11 | #include "../include/pch.h" 12 | 13 | #ifndef BOOL 14 | #define BOOL 15 | #endif 16 | #ifndef BITS_PER_REG 17 | #define BITS_PER_REG 1 18 | #endif 19 | /* Defining 0 and 1 */ 20 | #define ZERO false 21 | #define ONES true 22 | 23 | #define SET_ALL_ONE() true 24 | #define SET_ALL_ZERO() false 25 | 26 | #define AND(a, b) ((a) && (b)) 27 | #define OR(a, b) ((a) || (b)) 28 | #define XOR(a, b) ((a) ^ (b)) 29 | #define ANDN(a, b) (!(a) && (b)) 30 | #define NOT(a) (!(a)) 31 | 32 | /* #define ADD(a,b,c) ((a) + (b)) */ 33 | /* #define SUB(a,b,c) ((a) - (b)) */ 34 | 35 | #define MUL_SIGNED(a, b, c) AND(a, b) 36 | #define ADD_SIGNED(a, b, c) XOR(a, b) 37 | #define SUB_SIGNED(a, b, c) XOR(a, b) 38 | 39 | #define FUNC_AND std::bit_and() 40 | #define FUNC_OR std::bit_or() 41 | #define FUNC_XOR std::bit_xor() 42 | #define FUNC_NOT std::bit_not() 43 | #define FUNC_ADD32 std::bit_xor() 44 | #define FUNC_SUB32 std::bit_xor() 45 | #define FUNC_MUL32 std::bit_and() 46 | #define FUNC_ADD64 std::bit_xor() 47 | #define FUNC_SUB64 std::bit_xor() 48 | #define FUNC_MUL64 std::bit_and() 49 | 50 | #define SHIFT_RIGHT8 SET_ZERO 51 | #define SHIFT_RIGHT16 SET_ZERO 52 | #define SHIFT_RIGHT32 SET_ZERO 53 | #define SHIFT_RIGHT64 SET_ZERO 54 | #define SHIFT_LOG_RIGHT8 SET_ZERO 55 | #define SHIFT_LOG_RIGHT16 SET_ZERO 56 | #define SHIFT_LOG_RIGHT32 SET_ZERO 57 | #define SHIFT_LOG_RIGHT64 SET_ZERO 58 | #define SHIFT_LEFT8 SET_ZERO 59 | #define SHIFT_LEFT16 SET_ZERO 60 | #define SHIFT_LEFT32 SET_ZERO 61 | #define SHIFT_LEFT64 SET_ZERO 62 | #define SHIFT_RIGHT8F SET_ZERO 63 | #define SHIFT_RIGHT16F SET_ZERO 64 | #define SHIFT_RIGHT32F SET_ZERO 65 | #define SHIFT_RIGHT64F SET_ZERO 66 | #define SHIFT_LOG_RIGHT8F SET_ZERO 67 | #define SHIFT_LOG_RIGHT16F SET_ZERO 68 | #define SHIFT_LOG_RIGHT32F SET_ZERO 69 | #define SHIFT_LOG_RIGHT64F SET_ZERO 70 | #define SHIFT_LOG_RIGHT8F SET_ZERO 71 | #define SHIFT_LOG_RIGHT16F SET_ZERO 72 | #define SHIFT_LOG_RIGHT32F SET_ZERO 73 | #define SHIFT_LOG_RIGHT64F SET_ZERO 74 | 75 | template 76 | bool SET_ZERO(bool value) 77 | { 78 | return false; 79 | } 80 | 81 | bool SET_ZERO(bool value, int n) 82 | { 83 | return false; 84 | } 85 | 86 | #ifndef DATATYPE 87 | #define DATATYPE bool 88 | #endif 89 | 90 | #define PROMOTE(x) (SET_ALL_ONE()) 91 | 92 | #define ORTHOGONALIZE(in, out) orthogonalize(in, out) 93 | #define UNORTHOGONALIZE(in, out) unorthogonalize(in, out) 94 | 95 | #define ALLOC(size) malloc(size * sizeof(bool)) 96 | 97 | void orthogonalize_boolean(UINT_TYPE* num, bool* out) 98 | { 99 | for (int i = 0; i < BITLENGTH; i++) 100 | { 101 | out[BITLENGTH - i - 1] = *num & 1; 102 | *num /= 2; 103 | } 104 | } 105 | 106 | // convert bool array to uint number 107 | void unorthogonalize_boolean(bool* arr, UINT_TYPE* num) 108 | { 109 | UINT_TYPE tmp; 110 | for (int i = 0; i < BITLENGTH; i++) 111 | { 112 | tmp = arr[i]; 113 | *num |= tmp << (BITLENGTH - i - 1); 114 | } 115 | } 116 | 117 | void orthogonalize_arithmetic(UINT_TYPE* num, bool* out, int bitlength) 118 | { 119 | for (int i = 0; i < bitlength; i++) 120 | { 121 | out[bitlength - i - 1] = *num & 1; 122 | *num /= 2; 123 | } 124 | } 125 | 126 | void unorthogonalize_arithmetic(const bool* arr, UINT_TYPE* num, int bitlength) 127 | { 128 | UINT_TYPE tmp; 129 | for (int i = 0; i < bitlength; i++) 130 | { 131 | tmp = arr[i]; 132 | *num |= tmp << (bitlength - i - 1); 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /core/arch/DATATYPE.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../config.h" 3 | #ifndef RUNTIME 4 | #define RUNTIME 5 | #endif 6 | #ifndef ORTHO 7 | #define ORTHO 8 | #endif 9 | #define US 10 | 11 | #if DATTYPE == 1 12 | #include "BOOL.h" 13 | #elif DATTYPE == 8 14 | #include "STD.h" 15 | #elif DATTYPE == 16 16 | #include "STD.h" 17 | #elif DATTYPE == 32 18 | #include "STD.h" 19 | #elif DATTYPE == 64 20 | #include "STD.h" 21 | #elif DATTYPE == 128 22 | #include "SSE.h" 23 | #elif DATTYPE == 256 24 | #include "AVX.h" 25 | #elif DATTYPE == 512 26 | #include "AVX512.h" 27 | #else 28 | printf("Datatype not supported \n"); 29 | exit(1); 30 | #endif 31 | 32 | #if FUNCTION_IDENTIFIER != 2 && FUNCTION_IDENTIFIER != 412 && FUNCTION_IDENTIFIER != 413 && FUNCTION_IDENTIFIER != 414 33 | // workaround to benchmark some functions easier 34 | 35 | void orthogonalize_arithmetic(UINT_TYPE* in, DATATYPE* out) 36 | { 37 | orthogonalize_arithmetic(in, out, BITLENGTH); 38 | } 39 | 40 | void unorthogonalize_arithmetic(DATATYPE* in, UINT_TYPE* out) 41 | { 42 | unorthogonalize_arithmetic(in, out, BITLENGTH); 43 | } 44 | 45 | void orthogonalize_arithmetic_full(UINT_TYPE* in, DATATYPE* out) 46 | { 47 | orthogonalize_arithmetic(in, out, DATTYPE); 48 | } 49 | 50 | void unorthogonalize_arithmetic_full(DATATYPE* in, UINT_TYPE* out) 51 | { 52 | unorthogonalize_arithmetic(in, out, DATTYPE); 53 | } 54 | 55 | #endif 56 | 57 | #if BITLENGTH == 8 58 | #define OP_ADD FUNC_ADD8 59 | #define OP_SUB FUNC_SUB8 60 | #define OP_MULT FUNC_MUL8 61 | /* #define OP_TRUNC SHIFT_RIGHT8 */ 62 | #define OP_SHIFT_LEFT SHIFT_LEFT8 63 | #define OP_SHIFT_RIGHT SHIFT_RIGHT8 64 | #define OP_SHIFT_LOG_RIGHT SHIFT_LOG_RIGHT8 65 | #define OP_SHIFT_LOG_RIGHTF SHIFT_LOG_RIGHT8F 66 | #elif BITLENGTH == 16 67 | #define OP_ADD FUNC_ADD16 68 | #define OP_SUB FUNC_SUB16 69 | #define OP_MULT FUNC_MUL16 70 | #define OP_SHIFT_LEFT SHIFT_LEFT16 71 | #define OP_SHIFT_RIGHT SHIFT_RIGHT16 72 | #define OP_SHIFT_LOG_RIGHT SHIFT_LOG_RIGHT16 73 | #define OP_SHIFT_LOG_RIGHTF SHIFT_LOG_RIGHT16F 74 | #elif BITLENGTH == 32 75 | #define OP_ADD FUNC_ADD32 76 | #define OP_SUB FUNC_SUB32 77 | #define OP_MULT FUNC_MUL32 78 | /* #define OP_TRUNC SHIFT_RIGHT32 */ 79 | #define OP_SHIFT_LEFT SHIFT_LEFT32 80 | #define OP_SHIFT_RIGHT SHIFT_RIGHT32 81 | #define OP_SHIFT_LOG_RIGHT SHIFT_LOG_RIGHT32 82 | #define OP_SHIFT_LOG_RIGHTF SHIFT_LOG_RIGHT32F 83 | #elif BITLENGTH == 64 84 | #define OP_ADD FUNC_ADD64 85 | #define OP_SUB FUNC_SUB64 86 | #define OP_MULT FUNC_MUL64 87 | #define OP_SHIFT_LEFT SHIFT_LEFT64 88 | #define OP_SHIFT_RIGHT SHIFT_RIGHT64 89 | #define OP_SHIFT_LOG_RIGHT SHIFT_LOG_RIGHT64 90 | #define OP_SHIFT_LOG_RIGHTF SHIFT_LOG_RIGHT64F 91 | #endif 92 | 93 | /* #define OP_TRUNC OP_SHIFT_RIGHT */ 94 | /* #define OP_TRUNC2 OP_SHIFT_RIGHT<1> */ 95 | /* #define OP_TRUNCF OP_SHIFT_RIGHT */ 96 | #define OP_TRUNC OP_SHIFT_LOG_RIGHT 97 | #define OP_TRUNC2 OP_SHIFT_LOG_RIGHT<1> 98 | #define OP_TRUNCF OP_SHIFT_LOG_RIGHTF 99 | 100 | DATATYPE TRUNC2(DATATYPE x) 101 | { 102 | // Create a mask with lower k bits set to 1 103 | 104 | x = OP_TRUNC(x); 105 | UINT_TYPE maskValue = (UINT_TYPE(1) << (BITLENGTH - FRACTIONAL)) - 1; 106 | DATATYPE mask = PROMOTE(maskValue); // Set all elements to maskValue 107 | // Apply the mask using bitwise AND 108 | return FUNC_AND(x, mask); 109 | } 110 | 111 | DATATYPE TRUNC3(DATATYPE x) 112 | { 113 | // Create a mask with lower k bits set to 1 114 | 115 | x = OP_SUB(SET_ALL_ZERO(), OP_TRUNC(x)); 116 | UINT_TYPE maskValue = (UINT_TYPE(1) << (BITLENGTH - FRACTIONAL)) - 1; 117 | DATATYPE mask = PROMOTE(maskValue); // Set all elements to maskValue 118 | // Apply the mask using bitwise AND 119 | return OP_SUB(SET_ALL_ZERO(), FUNC_AND(x, mask)); 120 | } 121 | 122 | #define FUNC_TRUNC OP_TRUNC 123 | 124 | #if DATTYPE == 1 125 | #if COMPRESS == 1 126 | #define BOOL_COMPRESS 127 | #define NEW(var) new (std::align_val_t(sizeof(uint64_t))) var; // align variables for packing/unpacking 128 | #else 129 | #define NEW(var) new var; 130 | #endif 131 | #endif 132 | -------------------------------------------------------------------------------- /core/crypto/aes/AES_SSL.h: -------------------------------------------------------------------------------- 1 | #ifndef __AES_NI_H__ 2 | #define __AES_NI_H__ 3 | #include "openssl/aes.h" 4 | #include 5 | #include 6 | // macros 7 | 8 | #define AES_DATTYPE 512 9 | #define AES_TYPE uint8_t 10 | 11 | #define DO_ENC_BLOCK(m, k) \ 12 | do \ 13 | { \ 14 | int out_len; \ 15 | EVP_EncryptUpdate(k, m, &out_len, m, 64); \ 16 | } while (0) 17 | #endif 18 | 19 | void AES_enc(uint8_t m[], EVP_CIPHER_CTX* ctx) 20 | { 21 | int out_len; 22 | EVP_EncryptUpdate(ctx, m, &out_len, m, 64); 23 | } 24 | 25 | // Function to handle errors 26 | void handleErrors() 27 | { 28 | ERR_print_errors_fp(stderr); 29 | abort(); 30 | } 31 | 32 | // Initialize the AES ECB context with the given key 33 | void initialize_aes_ecb_context(const uint8_t* key, EVP_CIPHER_CTX* ctx) 34 | { 35 | // Create and initialize the context 36 | 37 | // Initialize the operation (1 for encryption, 0 for decryption) 38 | if (1 != EVP_EncryptInit_ex(ctx, EVP_aes_128_ecb(), NULL, (const unsigned char*)key, NULL)) 39 | { 40 | handleErrors(); 41 | } 42 | } 43 | static void aes_load_enc(uint8_t* enc_key, EVP_CIPHER_CTX* ctx) 44 | { 45 | initialize_aes_ecb_context(enc_key, ctx); 46 | } 47 | -------------------------------------------------------------------------------- /core/cuda/Makefile: -------------------------------------------------------------------------------- 1 | # User-specified options 2 | arch ?= sm_89 3 | CUDA_PATH ?= /home/usr/local/cuda 4 | CUTLASS_PATH ?= /home/ubuntu/cutlass 5 | #replace with e.g. make arch=sm_52 CUDA_PATH=/opt/cuda CUTLASS_PATH=/home/christopher/workspace/cutlass 6 | 7 | # Derived variables 8 | NVCC=$(CUDA_PATH)/bin/nvcc 9 | NVCCOPTs= -arch=$(arch) --expt-relaxed-constexpr -std=c++20 10 | CUDALIB=$(CUDA_PATH)/lib64 11 | 12 | BIN_DIR=bin 13 | TARGETS= $(BIN_DIR)/gemm_cutlass_int.o $(BIN_DIR)/conv_cutlass_int_NCHW.o $(BIN_DIR)/conv_cutlass_int_CHWN.o 14 | 15 | CUTLASSINC=$(CUTLASS_PATH)/include 16 | CUTTOOLINC=$(CUTLASS_PATH)/tools/util/include 17 | CUTLASSLIB=$(CUTLASS_PATH)/build/tools/library/ 18 | 19 | OPTION= -Iinclude/ -I$(CUTLASSINC) -I$(CUTTOOLINC) 20 | 21 | JUNK=$(TARGETS) a.out 22 | 23 | all: $(TARGETS) 24 | 25 | $(BIN_DIR)/gemm_cutlass_int.o: gemm_cutlass_int.cu | $(BIN_DIR) 26 | $(NVCC) $< $(NVCCOPTs) $(OPTION) -o $@ -c -Xptxas -O3 27 | 28 | $(BIN_DIR)/conv_cutlass_int_NCHW.o: conv_cutlass_int.cu | $(BIN_DIR) 29 | $(NVCC) $< $(NVCCOPTs) $(OPTION) -o $@ -c -Xptxas -O3 -DPIGEON_LAYOUT=\"NCHW\" 30 | 31 | $(BIN_DIR)/conv_cutlass_int_CHWN.o: conv_cutlass_int.cu | $(BIN_DIR) 32 | $(NVCC) $< $(NVCCOPTs) $(OPTION) -o $@ -c -Xptxas -O3 -DPIGEON_LAYOUT=\"CHWN\" 33 | 34 | $(BIN_DIR): 35 | mkdir -p $(BIN_DIR) 36 | 37 | clean: 38 | rm -rf $(JUNK) $(BIN_DIR) 39 | 40 | -------------------------------------------------------------------------------- /core/cuda/conv_cutlass_int.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | template 5 | void conv2d_cutlass(const Type* X, 6 | const Type* W, 7 | Type* Y, 8 | int batchSize, 9 | int inh, 10 | int inw, 11 | int din, 12 | int dout, 13 | int wh, 14 | int ww, 15 | int padding, 16 | int stride, 17 | int dilation = 1); 18 | -------------------------------------------------------------------------------- /core/cuda/gemm_cutlass_int.cu: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | template 9 | void gemm_cutlass(int M, int N, int K, Type* X, Type* W, Type* Y) 10 | { 11 | Type *x, *w, *y; 12 | cudaMalloc((void**)&x, M * K * sizeof(Type)); // Matrix X has M rows and K columns 13 | cudaMalloc((void**)&w, K * N * sizeof(Type)); // Matrix W has K rows and N columns 14 | cudaMalloc((void**)&y, M * N * sizeof(Type)); // Matrix Y has M rows and N columns 15 | 16 | cudaMemcpy(x, X, M * K * sizeof(Type), cudaMemcpyHostToDevice); 17 | cudaMemcpy(w, W, K * N * sizeof(Type), cudaMemcpyHostToDevice); 18 | cudaMemcpy(y, Y, M * N * sizeof(Type), cudaMemcpyHostToDevice); 19 | 20 | gpu::gemm(M, N, K, x, true, w, true, y, true); // true means that the matrix is in row-major order 21 | 22 | cudaMemcpy(Y, y, M * N * sizeof(Type), cudaMemcpyDeviceToHost); 23 | 24 | cudaFree(x); 25 | cudaFree(w); 26 | cudaFree(y); 27 | } 28 | 29 | // forward declare the function for different integer Testtypes 30 | // UINT8 and UINT16 are not supported by all architectures 31 | // template void gemm_cutlass(int M, int N, int K, uint8_t *X, uint8_t *W, uint8_t *Y); 32 | template void gemm_cutlass(int M, 33 | int N, 34 | int K, 35 | uint16_t* X, 36 | uint16_t* W, 37 | uint16_t* Y); // INT8 and INT16 are not supported by some architectures 38 | template void gemm_cutlass(int M, int N, int K, uint32_t* X, uint32_t* W, uint32_t* Y); 39 | template void gemm_cutlass(int M, int N, int K, uint64_t* X, uint64_t* W, uint64_t* Y); 40 | -------------------------------------------------------------------------------- /core/cuda/gemm_cutlass_int.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | 4 | template 5 | void gemm_cutlass(int M, int N, int K, Type* X, Type* W, Type* Y); 6 | -------------------------------------------------------------------------------- /core/cuda/include/gemm.cuh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | // #include 14 | using RowMajor = cutlass::layout::RowMajor; 15 | using ColumnMajor = cutlass::layout::ColumnMajor; 16 | 17 | template 18 | using CutlassGemmNNN = cutlass::gemm::device::Gemm; 19 | template 20 | using CutlassGemmTNN = cutlass::gemm::device::Gemm; 21 | template 22 | using CutlassGemmNTN = cutlass::gemm::device::Gemm; 23 | template 24 | using CutlassGemmTTN = cutlass::gemm::device::Gemm; 25 | 26 | template 27 | using CutlassGemmNNT = cutlass::gemm::device::Gemm; 28 | template 29 | using CutlassGemmTNT = cutlass::gemm::device::Gemm; 30 | template 31 | using CutlassGemmNTT = cutlass::gemm::device::Gemm; 32 | template 33 | using CutlassGemmTTT = cutlass::gemm::device::Gemm; 34 | 35 | template typename CutlassGemm> 36 | cudaError_t CutlassGemmOp(int M, int N, int K, T alpha, T const* A, int lda, T const* B, int ldb, T beta, T* C, int ldc) 37 | { 38 | 39 | CutlassGemm gemm_operator; 40 | 41 | typename CutlassGemm::Arguments args({M, N, K}, {A, lda}, {B, ldb}, {C, ldc}, {C, ldc}, {alpha, beta}); 42 | 43 | cutlass::Status status = gemm_operator(args); 44 | CUTLASS_CHECK(status); 45 | 46 | return status == cutlass::Status::kSuccess ? cudaSuccess : cudaErrorUnknown; 47 | } 48 | 49 | namespace gpu 50 | { 51 | 52 | template 53 | void gemm(int M, int N, int K, T const* A, bool transpose_a, T const* B, bool transpose_b, T* C, bool transpose_c) 54 | { 55 | 56 | if (transpose_c) 57 | { 58 | if (transpose_a) 59 | { 60 | if (transpose_b) 61 | { 62 | CutlassGemmOp(M, N, K, (T)1, A, K, B, N, (T)0, C, N); 63 | } 64 | else 65 | { 66 | CutlassGemmOp(M, N, K, (T)1, A, K, B, K, (T)0, C, N); 67 | } 68 | } 69 | else 70 | { 71 | if (transpose_b) 72 | { 73 | CutlassGemmOp(M, N, K, (T)1, A, M, B, N, (T)0, C, N); 74 | } 75 | else 76 | { 77 | CutlassGemmOp(M, N, K, (T)1, A, M, B, K, (T)0, C, N); 78 | } 79 | } 80 | } 81 | else 82 | { 83 | if (transpose_a) 84 | { 85 | if (transpose_b) 86 | { 87 | CutlassGemmOp(M, N, K, (T)1, A, K, B, N, (T)0, C, M); 88 | } 89 | else 90 | { 91 | CutlassGemmOp(M, N, K, (T)1, A, K, B, K, (T)0, C, M); 92 | } 93 | } 94 | else 95 | { 96 | if (transpose_b) 97 | { 98 | CutlassGemmOp(M, N, K, (T)1, A, M, B, N, (T)0, C, M); 99 | } 100 | else 101 | { 102 | CutlassGemmOp(M, N, K, (T)1, A, M, B, K, (T)0, C, M); 103 | } 104 | } 105 | } 106 | cudaDeviceSynchronize(); 107 | } 108 | 109 | } // namespace gpu 110 | -------------------------------------------------------------------------------- /core/cuda/include/transform.cuh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "cutlass/cutlass.h" 3 | #include "cutlass/layout/tensor.h" 4 | #include "cutlass/numeric_types.h" 5 | #include "cutlass/tensor_coord.h" 6 | #include "cutlass/tensor_ref.h" 7 | #include 8 | #include 9 | 10 | // macro for transpose only 11 | #define TILE_DIM 64 12 | #define BLOCK_ROWS 16 13 | 14 | template 15 | void nchw_to_nhwc_(T* output, const T* input, const int n, const int h, const int w, const int c) 16 | { 17 | 18 | dim3 grid((h * w + 31) / 32, (c + 31) / 32, n); 19 | dim3 block(32, 8); 20 | cutlass::nchw_to_nhwc_kernel<<>>(output, input, n, h, w, c); 21 | } 22 | 23 | template 24 | __global__ void transposeGPUcoalescing(T* matTran, const T* matIn, const int nx, const int ny) 25 | { 26 | __shared__ T tile[TILE_DIM][TILE_DIM]; 27 | int x = blockIdx.x * TILE_DIM + threadIdx.x; 28 | int y = blockIdx.y * TILE_DIM + threadIdx.y; // <- threadIdx.y only between 0 and 7 29 | // Load matrix into tile 30 | // Every Thread loads in this case 4 elements into tile. 31 | int i; 32 | for (i = 0; i < TILE_DIM; i += BLOCK_ROWS) 33 | { 34 | if (x < nx && (y + i) < ny) 35 | { 36 | tile[threadIdx.y + i][threadIdx.x] = matIn[(y + i) * nx + x]; 37 | } 38 | } 39 | __syncthreads(); 40 | x = blockIdx.y * TILE_DIM + threadIdx.x; 41 | y = blockIdx.x * TILE_DIM + threadIdx.y; 42 | for (i = 0; i < TILE_DIM; i += BLOCK_ROWS) 43 | { 44 | if (x < ny && (y + i) < nx) 45 | { 46 | matTran[(y + i) * ny + x] = tile[threadIdx.x][threadIdx.y + i]; // <- multiply by m, non-squared! 47 | } 48 | } 49 | } 50 | 51 | template 52 | void transpose(T* output, const T* input, const int cols, const int rows) 53 | { 54 | 55 | int x = cols; 56 | int y = rows; 57 | 58 | if (cols % TILE_DIM) 59 | x += (TILE_DIM - (cols % TILE_DIM)); 60 | if (rows % TILE_DIM) 61 | y += (TILE_DIM - (rows % TILE_DIM)); 62 | 63 | dim3 dimGrid(x / TILE_DIM, y / TILE_DIM, 1); 64 | dim3 dimBlock(TILE_DIM, BLOCK_ROWS, 1); 65 | 66 | transposeGPUcoalescing<<>>(output, input, cols, rows); 67 | } 68 | 69 | template 70 | void chwn_to_nhwc_(T* output, const T* input, const int n, const int h, const int w, const int c) 71 | { 72 | 73 | T* buf; 74 | int size = n * c * h * w; 75 | cudaMalloc((void**)&buf, sizeof(T) * size); 76 | int rows = c * h * w; 77 | int cols = n; 78 | // chwn -> nchw 79 | transpose(buf, input, cols, rows); 80 | // nchw -> nhwc 81 | nchw_to_nhwc_(output, buf, n, h, w, c); 82 | cudaFree(buf); 83 | } 84 | 85 | // old approach 86 | // template 87 | // void chwn_to_nhwc_( 88 | // T *output, 89 | // const T *input, 90 | // const int n, 91 | // const int h, 92 | // const int w, 93 | // const int c) { 94 | // 95 | // int newN = 1; 96 | // int newC = c*h*w; 97 | // int newH = 1; 98 | // int newW = n; 99 | // 100 | // T* buf; 101 | // int size = n*c*h*w; 102 | // cudaMalloc((void**) &buf, sizeof(T)*size); 103 | // 104 | // nchw_to_nhwc_(buf, input, newN, newH, newW, newC); 105 | // nchw_to_nhwc_(output, buf, n, h, w, c); 106 | // 107 | // cudaFree(buf); 108 | //} 109 | 110 | template 111 | void nhwc_to_nchw_(T* output, const T* input, const int n, const int h, const int w, const int c) 112 | { 113 | 114 | dim3 grid((c + 31) / 32, (h * w + 31) / 32, n); 115 | dim3 block(32, 8); 116 | cutlass::nhwc_to_nchw_kernel<<>>(output, input, n, h, w, c); 117 | } 118 | 119 | template 120 | void nhwc_to_chwn_(T* output, const T* input, const int n, const int h, const int w, const int c) 121 | { 122 | 123 | int newN = c; 124 | int newC = n; 125 | 126 | chwn_to_nhwc_(output, input, newN, h, w, newC); 127 | } 128 | -------------------------------------------------------------------------------- /core/cuda/include/utils.cuh: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #define CUTLASS_CHECK(status) \ 4 | { \ 5 | cutlass::Status error = status; \ 6 | if (error != cutlass::Status::kSuccess) \ 7 | { \ 8 | std::cerr << "Got cutlass error: " << cutlassGetStatusString(error) << " at: " << __LINE__ << std::endl; \ 9 | } \ 10 | } 11 | -------------------------------------------------------------------------------- /core/include/pch.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | #include 15 | #include 16 | #include 17 | #include 18 | #include 19 | #include 20 | #include 21 | #include 22 | #include 23 | #include 24 | #include 25 | #include 26 | #include 27 | #include 28 | #include 29 | #include 30 | #include 31 | #include 32 | #include 33 | #include 34 | #include 35 | #include 36 | -------------------------------------------------------------------------------- /core/init.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "include/pch.h" 3 | #include "networking/buffers.h" 4 | #include "networking/client.hpp" 5 | #include "networking/server.hpp" 6 | #include "utils/print.hpp" 7 | #include "utils/randomizer.h" 8 | 9 | #if LIVE == 1 && INIT == 0 && NO_INI == 0 10 | #include "core/utils/CircuitInfo.hpp" 11 | #endif 12 | 13 | struct timespec i1, p1, p2, l1, l2; 14 | 15 | int modulo(int x, int N) 16 | { 17 | return (x % N + N) % N; 18 | } 19 | 20 | void init_srng(uint64_t link_id, uint64_t link_seed) 21 | { 22 | #if RANDOM_ALGORITHM == 0 23 | UINT_TYPE gen_seeds[DATTYPE]; 24 | for (int i = 0; i < DATTYPE; i++) 25 | { 26 | gen_seeds[i] = link_seed * (i + 1); // replace with independant seeds in the future 27 | } 28 | orthogonalize_boolean(gen_seeds, srng[link_id]); 29 | 30 | #elif RANDOM_ALGORITHM == 1 31 | UINT_TYPE gen_keys[11][DATTYPE * 128 / BITLENGTH]; 32 | for (int i = 0; i < 11; i++) 33 | { 34 | for (int j = 0; j < DATTYPE * 128 / BITLENGTH; j++) 35 | { 36 | gen_keys[i][j] = link_seed * ((i + 1) * j); // replace with independant seeds in the future 37 | } 38 | } 39 | for (int i = 0; i < 11; i++) 40 | { 41 | for (int j = 0; j < DATTYPE * 128 / BITLENGTH; j++) 42 | orthogonalize_boolean(gen_keys[i] + j, key[link_id][i] + j); 43 | } 44 | 45 | #elif RANDOM_ALGORITHM == 2 46 | srand(link_seed); 47 | alignas(AES_DATTYPE / 8) uint64_t counter[AES_DATTYPE / 64]; 48 | #if USE_SSL_AES == 1 49 | for (int j = 0; j < 64; j++) 50 | aes_counter[link_id][j] = 51 | rand() % 256 | 52 | rand() % 53 | 256; // generate random 8-bit number, to stay consistent with other approaches, 2 times rand is used 54 | #else 55 | for (int j = 0; j < AES_DATTYPE / 64; j++) 56 | counter[j] = ((uint64_t)rand() << 32) | rand(); // generate random 64-bit number 57 | 58 | #if defined(__AVX512F__) && defined(__VAES__) 59 | aes_counter[link_id] = _mm512_set_epi64( 60 | counter[7], counter[6], counter[5], counter[4], counter[3], counter[2], counter[1], counter[0]); 61 | #elif defined(__AVX2__) && defined(__VAES__) 62 | aes_counter[link_id] = _mm256_set_epi64x(counter[3], counter[2], counter[1], counter[0]); 63 | #elif defined(__AES__) 64 | aes_counter[link_id] = _mm_set_epi64x(counter[1], counter[0]); 65 | #endif 66 | #endif 67 | 68 | alignas(AES_DATTYPE / 8) uint8_t seed[AES_DATTYPE / 8]; 69 | for (int i = 0; i < AES_DATTYPE / 8; i++) 70 | { 71 | /* seed[link_id][i] = rand() % 256; */ 72 | seed[i] = rand() % 256; // 73 | /* seed[j][i] = 10; */ 74 | } 75 | #if USE_SSL_AES == 1 76 | key_schedule[link_id] = EVP_CIPHER_CTX_new(); 77 | if (!key_schedule[link_id]) 78 | handleErrors(); 79 | #endif 80 | aes_load_enc(seed, key_schedule[link_id]); 81 | 82 | #endif 83 | init_buffers(link_id); 84 | #if MAL == 1 85 | 86 | // Ensure all players have the same initial state 87 | /* initial state */ 88 | uint32_t state[8] = { 89 | 0x6a09e667, 0xbb67ae85, 0x3c6ef372, 0xa54ff53a, 0x510e527f, 0x9b05688c, 0x1f83d9ab, 0x5be0cd19}; 90 | 91 | for (int i = 0; i < num_players - 1; i++) 92 | { 93 | for (int j = 0; j < 8; j++) 94 | hash_val[i][j] = state[j]; 95 | } 96 | 97 | #endif 98 | } 99 | 100 | void init_muetexes() 101 | { 102 | pthread_mutex_init(&mtx_connection_established, NULL); 103 | pthread_mutex_init(&mtx_start_communicating, NULL); 104 | pthread_mutex_init(&mtx_send_next, NULL); 105 | pthread_cond_init(&cond_successful_connection, NULL); 106 | pthread_cond_init(&cond_start_signal, NULL); 107 | pthread_cond_init(&cond_send_next, NULL); 108 | } 109 | -------------------------------------------------------------------------------- /core/networking/buffers.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../include/pch.h" 3 | #include "sockethelper.h" 4 | int player_id; 5 | sender_args sending_args[num_players]; 6 | receiver_args receiving_args[num_players]; 7 | 8 | #if PRE == 1 9 | sender_args sending_args_pre[num_players]; 10 | receiver_args receiving_args_pre[num_players]; 11 | #endif 12 | 13 | uint64_t total_send[num_players - 1] = {0}; 14 | uint64_t total_recv[num_players - 1] = {0}; 15 | #if PRE == 1 16 | uint64_t total_send_pre[num_players - 1] = {0}; 17 | uint64_t total_recv_pre[num_players - 1] = {0}; 18 | #endif 19 | 20 | int rounds; 21 | int rb; 22 | int sb; 23 | int send_count[num_players] = {0}; 24 | int share_buffer[num_players] = {0}; // TODO: move to protocol layer 25 | int send_count_pre[num_players] = {0}; 26 | int share_buffer_pre[num_players] = {0}; // TODO: move to protocol layer 27 | int reveal_buffer[num_players] = {0}; 28 | int total_comm; 29 | int* elements_per_round; 30 | int input_length[num_players] = {0}; 31 | int reveal_length[num_players] = {0}; 32 | DATATYPE* player_input; 33 | #if num_players == 4 34 | #define player_multiplier 2 35 | #else 36 | #define player_multiplier 1 37 | #endif 38 | #if MAL == 1 39 | DATATYPE* verify_buffer[num_players * player_multiplier]; // Verify buffer for each player 40 | uint64_t verify_buffer_index[num_players * player_multiplier] = {0}; 41 | 42 | #if DATTTYPE > 32 43 | alignas(sizeof(DATATYPE)) uint32_t hash_val[num_players * player_multiplier][8]; // Hash value for each player 44 | #else 45 | uint32_t hash_val[num_players * player_multiplier][8]; // Hash value for each player 46 | #endif 47 | uint64_t elements_to_compare[num_players * player_multiplier] = {0}; 48 | #endif 49 | #if PRE == 1 && HAS_POST_PROTOCOL == 1 // Store preprocessed-output to get the correct results during post-processing 50 | DATATYPE* preprocessed_outputs; 51 | uint64_t preprocessed_outputs_index = 0; 52 | #endif 53 | uint64_t num_generated[num_players * player_multiplier] = {0}; 54 | 55 | int use_srng_for_inputs = 1; 56 | 57 | int current_phase = 0; // Keeping track of current pahse 58 | int process_offset = 0; // offsets the starting input for each process, base port must be multiple of 1000 to work 59 | 60 | #if TRUNC_DELAYED == 1 61 | bool delayed = false; // For delayed truncation 62 | bool isReLU = false; // For ReLU truncation 63 | #endif 64 | 65 | #if TRUNC_APPROACH > 0 66 | bool all_positive = false; // for slack-based optiimzation 67 | #endif 68 | 69 | -------------------------------------------------------------------------------- /core/networking/client.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../include/pch.h" 3 | 4 | #ifndef BOOL_COMPRESS 5 | #define DTYPE DATATYPE 6 | #else 7 | #define DTYPE uint8_t 8 | #endif 9 | #include "socket.hpp" 10 | #include "sockethelper.h" 11 | 12 | void client_signal_connection_established(int player_count) 13 | { 14 | pthread_mutex_lock(&mtx_connection_established); 15 | num_successful_connections += 1; 16 | if (num_successful_connections == 2 * (player_count - 1)) 17 | { 18 | pthread_cond_signal(&cond_successful_connection); // signal main thread that all threads have connected 19 | } 20 | pthread_mutex_unlock(&mtx_connection_established); 21 | 22 | pthread_mutex_lock(&mtx_start_communicating); 23 | while (num_successful_connections != -1) 24 | { // wait for start signal from main thread 25 | pthread_cond_wait(&cond_start_signal, &mtx_start_communicating); 26 | } 27 | pthread_mutex_unlock(&mtx_start_communicating); 28 | } 29 | 30 | void signal_all_data_received_in_round(int& rounds, int player_count) 31 | { 32 | pthread_mutex_lock(&mtx_data_received); 33 | sockets_received[rounds] += 1; 34 | if (sockets_received[rounds] == player_count - 1) 35 | { 36 | pthread_mutex_lock(&mtx_receive_next); // Mutex probably neccessary if one thread is alrady one round further 37 | receiving_rounds += 1; // increase global receiving_rounds 38 | pthread_cond_signal(&cond_receive_next); // signal main thread that receiving is finished 39 | pthread_mutex_unlock(&mtx_receive_next); 40 | } 41 | pthread_mutex_unlock(&mtx_data_received); 42 | rounds += 1; 43 | } 44 | 45 | void* receiver(void* threadParameters) 46 | { 47 | Socket client; 48 | client.Connect(((receiver_args*)threadParameters)->ip, ((receiver_args*)threadParameters)->port); 49 | #if PRINT == 1 50 | printf("P%i: Receiving Socket connected to Player %i \n", 51 | ((receiver_args*)threadParameters)->player_id, 52 | ((receiver_args*)threadParameters)->connected_to); 53 | #endif 54 | client_signal_connection_established(((receiver_args*)threadParameters)->player_count); 55 | 56 | int rounds = 0; 57 | while (rounds < ((receiver_args*)threadParameters)->rec_rounds) 58 | { 59 | // Allocate new memory for received data, check correctness 60 | ((receiver_args*)threadParameters)->received_elements[rounds] = 61 | NEW(DATATYPE[((receiver_args*)threadParameters)->elements_to_rec[rounds]]); 62 | 63 | if (((receiver_args*)threadParameters)->elements_to_rec[rounds] > 0) // should data be received in this round? 64 | { 65 | #ifndef BOOL_COMPRESS 66 | int64_t elements_to_rec = ((receiver_args*)threadParameters)->elements_to_rec[rounds]; 67 | elements_to_rec = elements_to_rec * sizeof(DATATYPE); 68 | #endif 69 | #ifdef BOOL_COMPRESS 70 | int64_t elements_to_rec = (((receiver_args*)threadParameters)->elements_to_rec[rounds] + 7) / 8; 71 | uint8_t* rec_buffer = new (std::align_val_t(sizeof(uint64_t))) uint8_t[elements_to_rec]; 72 | unpack(rec_buffer, 73 | ((receiver_args*)threadParameters)->received_elements[rounds], 74 | ((receiver_args*)threadParameters)->elements_to_rec[rounds]); 75 | delete[] rec_buffer; 76 | #endif 77 | client.Receive_all(((char*)((receiver_args*)threadParameters)->received_elements[rounds]), 78 | &elements_to_rec); 79 | #if PRINT == 1 80 | printf("P%i: Received %li bytes from player %i in round %i out of %i \n", 81 | PARTY, 82 | elements_to_rec, 83 | ((receiver_args*)threadParameters)->connected_to, 84 | rounds + 1, 85 | ((receiver_args*)threadParameters)->rec_rounds); 86 | #endif 87 | } 88 | // If all sockets received, signal main_thread 89 | signal_all_data_received_in_round(rounds, ((receiver_args*)threadParameters)->player_count); 90 | } 91 | /* client.Close_Context(); */ 92 | pthread_exit(NULL); 93 | } 94 | -------------------------------------------------------------------------------- /core/networking/packer.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../include/pch.h" 3 | 4 | #ifdef __BMI2__ 5 | #include 6 | #include 7 | 8 | void pack(bool* orig, uint8_t* dest, size_t l) 9 | { 10 | size_t s = 0; 11 | for (size_t i = 0; i < l; i += 8) 12 | { 13 | bool* address = &orig[i]; 14 | dest[s] = _pext_u64(*((uint64_t*)address), 0x0101010101010101ULL); 15 | s += 1; 16 | } 17 | } 18 | 19 | void unpack(uint8_t* orig, bool* dest, size_t l) 20 | { 21 | size_t s = 0; 22 | for (size_t i = 0; i < l; i += 8) 23 | { 24 | dest[i] = _pdep_u64(orig[s], 0x0101010101010101ULL); 25 | s += 1; 26 | } 27 | } 28 | 29 | #else 30 | 31 | uint8_t pack8bools(bool* a) 32 | { 33 | uint64_t t; 34 | memcpy(&t, a, sizeof t); // strict-aliasing & alignment safe load 35 | return 0x8040201008040201ULL * t >> 56; 36 | // bit order: a[0]<<7 | a[1]<<6 | ... | a[7]<<0 on little-endian 37 | // for a[0] => LSB, use 0x0102040810204080ULL on little-endian 38 | } 39 | 40 | void unpack8bools(uint8_t b, bool* a) 41 | { 42 | // on little-endian, a[0] = (b>>7) & 1 like printing order 43 | auto MAGIC = 0x8040201008040201ULL; // for opposite order, byte-reverse this 44 | auto MASK = 0x8080808080808080ULL; 45 | uint64_t t = ((MAGIC * b) & MASK) >> 7; 46 | memcpy(a, &t, sizeof t); // store 8 bytes without UB 47 | } 48 | 49 | void pack(bool* orig, uint8_t* dest, size_t l) 50 | { 51 | size_t s = 0; 52 | for (size_t i = 0; i < l; i += 8) 53 | { 54 | dest[s] = pack8bools(&orig[i]); 55 | s += 1; 56 | } 57 | } 58 | void unpack(uint8_t* orig, bool* dest, size_t l) 59 | { 60 | size_t s = 0; 61 | for (size_t i = 0; i < l; i += 8) 62 | { 63 | unpack8bools(orig[s], &dest[i]); 64 | s += 1; 65 | } 66 | } 67 | 68 | /* void unpack(char* orig, bool* dest, size_t l) */ 69 | /* { */ 70 | /* for(size_t i = 0; i < l; i++) */ 71 | /* { */ 72 | /* char mask = 1 << (i % 8); */ 73 | /* dest[i] = mask & orig[l/8]; */ 74 | /* } */ 75 | /* } */ 76 | 77 | /* void pack(bool* orig, char* dest, size_t l) */ 78 | /* { */ 79 | /* for(size_t i = 0; i < l; i++) */ 80 | /* { */ 81 | /* char mask = 1 << (i % 8); */ 82 | /* dest[i/8] += orig[i] * mask; */ 83 | /* } */ 84 | /* } */ 85 | #endif 86 | -------------------------------------------------------------------------------- /core/networking/server.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../include/pch.h" 3 | #include "socket.hpp" 4 | #include "sockethelper.h" 5 | 6 | #ifndef BOOL_COMPRESS 7 | #define DTYPE DATATYPE 8 | #else 9 | #define DTYPE uint8_t 10 | #endif 11 | 12 | void server_signal_connection_established(int player_count) 13 | { 14 | pthread_mutex_lock(&mtx_connection_established); 15 | num_successful_connections += 1; 16 | if (num_successful_connections == 2 * (player_count - 1)) 17 | { 18 | pthread_cond_signal(&cond_successful_connection); // signal main thread that all threads have connected 19 | /* printf("server %i \n",num_successful_connections); */ 20 | } 21 | pthread_mutex_unlock(&mtx_connection_established); 22 | /* printf("Player: Unlocked conn \n"); */ 23 | 24 | pthread_mutex_lock(&mtx_start_communicating); 25 | 26 | while (num_successful_connections != -1) 27 | { // wait for start signal from main thread 28 | pthread_cond_wait(&cond_start_signal, &mtx_start_communicating); 29 | } 30 | pthread_mutex_unlock(&mtx_start_communicating); 31 | } 32 | 33 | void* sender(void* threadParameters) 34 | { 35 | Socket server; 36 | server.Bind(((sender_args*)threadParameters)->port); 37 | server.Listen(2); 38 | Socket client = server.Accept(); 39 | #if PRINT == 1 40 | printf("P%i: Sending Socket connected to Player %i\n", PARTY, ((sender_args*)threadParameters)->connected_to); 41 | #endif 42 | server_signal_connection_established(((sender_args*)threadParameters)->player_count); 43 | // Send data to the client 44 | int rounds = 0; 45 | 46 | while (rounds < ((sender_args*)threadParameters)->send_rounds) // continue until all data is sent 47 | { 48 | pthread_mutex_lock(&mtx_send_next); 49 | while (rounds >= sending_rounds) 50 | pthread_cond_wait(&cond_send_next, 51 | &mtx_send_next); // make sure that there is new data to send, singaled by main 52 | pthread_mutex_unlock(&mtx_send_next); 53 | if (((sender_args*)threadParameters)->elements_to_send[rounds] > 0) 54 | { 55 | #ifndef BOOL_COMPRESS 56 | int64_t elements_to_send = ((sender_args*)threadParameters)->elements_to_send[rounds]; 57 | elements_to_send = elements_to_send * sizeof(DATATYPE); 58 | #else 59 | int64_t elements_to_send = (((sender_args*)threadParameters)->elements_to_send[rounds] + 7) / 8; 60 | uint8_t* send_buf = new (std::align_val_t(sizeof(uint64_t))) uint8_t[elements_to_send]; 61 | pack(((sender_args*)threadParameters)->sent_elements[rounds], 62 | send_buf, 63 | ((sender_args*)threadParameters)->elements_to_send[rounds]); 64 | #endif 65 | 66 | client.Send_all(((char*)((sender_args*)threadParameters)->sent_elements[rounds]), &elements_to_send); 67 | #if PRINT == 1 68 | printf("P%i: Sent %li bytes to player %i in round %i out of %i \n", 69 | PARTY, 70 | elements_to_send, 71 | ((sender_args*)threadParameters)->connected_to, 72 | rounds + 1, 73 | ((sender_args*)threadParameters)->send_rounds); 74 | #endif 75 | } 76 | free(((sender_args*)threadParameters)->sent_elements[rounds]); 77 | 78 | rounds += 1; 79 | } 80 | 81 | #if PRINT == 1 82 | printf("P%i: Closing connection to Player %i\n", PARTY, ((sender_args*)threadParameters)->connected_to); 83 | #endif 84 | /* client.Close_Context(); */ 85 | /* server.Close_Context(); */ 86 | pthread_exit(NULL); 87 | } 88 | -------------------------------------------------------------------------------- /core/networking/sockethelper.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../arch/DATATYPE.h" 3 | #include "../include/pch.h" 4 | 5 | pthread_mutex_t mtx_connection_established; 6 | pthread_mutex_t mtx_start_communicating; 7 | pthread_cond_t cond_successful_connection; 8 | pthread_cond_t cond_start_signal; 9 | int num_successful_connections = 0; 10 | 11 | // int sending_rounds = 0; 12 | int receiving_rounds = 0; 13 | pthread_mutex_t mtx_receive_next; 14 | pthread_cond_t cond_receive_next; 15 | 16 | std::vector sockets_received; 17 | pthread_mutex_t mtx_data_received; 18 | pthread_cond_t cond_data_received; 19 | 20 | int sending_rounds = 0; 21 | pthread_mutex_t mtx_send_next; 22 | pthread_cond_t cond_send_next; 23 | 24 | int sockets_sent = 0; 25 | pthread_mutex_t mtx_data_sent; 26 | pthread_cond_t cond_data_sent; 27 | 28 | typedef struct receiver_arguments 29 | { 30 | int player_count; 31 | int player_id; 32 | int connected_to; 33 | DATATYPE** received_elements; 34 | int inputs_size; // depricated 35 | std::string ip; 36 | int port; 37 | char* hostname; 38 | int rec_rounds; 39 | std::vector elements_to_rec; 40 | int total_rounds; // depricated 41 | // char *data; 42 | // char *length 43 | } receiver_args; 44 | 45 | typedef struct sender_arguments 46 | { 47 | DATATYPE** sent_elements; 48 | int inputs_size; // depricated 49 | int port; 50 | int player_id; 51 | int player_count; 52 | int connected_to; 53 | int send_rounds; 54 | std::vector elements_to_send; 55 | int total_rounds; // depricated 56 | #if PRE == 1 57 | uint64_t fetch_counter; // use to fetch sent in pre-processing round 58 | #endif 59 | 60 | // char *data; 61 | } sender_args; 62 | 63 | void client_signal_main() 64 | { 65 | 66 | pthread_mutex_lock(&mtx_connection_established); 67 | num_successful_connections += 1; 68 | if (num_successful_connections == 2 * num_players - 1) 69 | { 70 | pthread_cond_signal(&cond_successful_connection); // signal main thread that all threads have connected 71 | printf("client %i \n", num_successful_connections); 72 | } 73 | pthread_mutex_unlock(&mtx_connection_established); 74 | 75 | pthread_mutex_lock(&mtx_start_communicating); 76 | while (num_successful_connections != -1) 77 | { // wait for start signal from main thread 78 | pthread_cond_wait(&cond_start_signal, &mtx_start_communicating); 79 | } 80 | pthread_mutex_unlock(&mtx_start_communicating); 81 | } 82 | -------------------------------------------------------------------------------- /core/ssl_certificates/server.crt: -------------------------------------------------------------------------------- 1 | -----BEGIN CERTIFICATE----- 2 | MIIDEzCCAfsCFDB2ijH7r0k56dcAplDOwnLfEqQ3MA0GCSqGSIb3DQEBCwUAMEUx 3 | CzAJBgNVBAYTAkRFMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYDVQQKDBhJbnRl 4 | cm5ldCBXaWRnaXRzIFB0eSBMdGQwIBcNMjQwNTI3MTIwMjA2WhgPMjEyNDA1MDMx 5 | MjAyMDZaMEUxCzAJBgNVBAYTAkRFMRMwEQYDVQQIDApTb21lLVN0YXRlMSEwHwYD 6 | VQQKDBhJbnRlcm5ldCBXaWRnaXRzIFB0eSBMdGQwggEiMA0GCSqGSIb3DQEBAQUA 7 | A4IBDwAwggEKAoIBAQC19eZg9ieS2hcBh/O6mv98EMoyDljNdi0d3s/BNzzz4VZl 8 | xLmNE85MulNkM0tt0sR+FwH9KQUkxczlsNXgiT2SiPiyHJQA8gQANir2u0xN42Pp 9 | T/dJrnM1Tyl7gWLtQ2FsiAM/06E4VVfjeWVdDEJSY9UnML4HAcGZxGVZ3BUuPWgF 10 | JztJNXxPXmWp4643EXFGKw31czf3RfJM9vBuD/c9qzC27PzSrjeH94LOcKtAfuvz 11 | TnDixOaEj0ikVJ45t0IQOa2nbDf0fe+bJvepjFYmShoIi2aFB+GHoJy07eVWQQBJ 12 | j/+2BRio2/sNdfjjIunv3uIxxJPtiiFaN8bzsVk/AgMBAAEwDQYJKoZIhvcNAQEL 13 | BQADggEBACFqjeRxWSsphw/PLOj3yfNSJ+drLIRbo3BnUWANqSBj4Jez2ARGp1Ux 14 | nJ/FpRgyLX2w0q9opH8iMPuTbK0JF4bg6E6ewfw9cHR3SVcUgb+/Ist9KQGg3Vih 15 | LwgiP99SApyioi/NaboydKNWKabfqiQZlNx9jfRQzKiclajjMtcXDtjtbG6SYd7W 16 | kGobCM66sbmGh7E8XmRpWCD2IE95VdoW5+lZ0soeaE9FFiHqjYSD0ejxmZ6bzf9s 17 | DClUFwHcTl+SJegC/NPxa3b6POkXhlQDVCp117atpymPunCuYXTj1avAkasngSNJ 18 | XPC0zH+zzLP8Mv87frnl5Io5r+9lbK8= 19 | -----END CERTIFICATE----- 20 | -------------------------------------------------------------------------------- /core/ssl_certificates/server.key: -------------------------------------------------------------------------------- 1 | -----BEGIN PRIVATE KEY----- 2 | MIIEvQIBADANBgkqhkiG9w0BAQEFAASCBKcwggSjAgEAAoIBAQC19eZg9ieS2hcB 3 | h/O6mv98EMoyDljNdi0d3s/BNzzz4VZlxLmNE85MulNkM0tt0sR+FwH9KQUkxczl 4 | sNXgiT2SiPiyHJQA8gQANir2u0xN42PpT/dJrnM1Tyl7gWLtQ2FsiAM/06E4VVfj 5 | eWVdDEJSY9UnML4HAcGZxGVZ3BUuPWgFJztJNXxPXmWp4643EXFGKw31czf3RfJM 6 | 9vBuD/c9qzC27PzSrjeH94LOcKtAfuvzTnDixOaEj0ikVJ45t0IQOa2nbDf0fe+b 7 | JvepjFYmShoIi2aFB+GHoJy07eVWQQBJj/+2BRio2/sNdfjjIunv3uIxxJPtiiFa 8 | N8bzsVk/AgMBAAECggEABOqo4nF+8+oJBBq90bV9dhySshPkKg0UPqyLauTzXy2g 9 | DYOUIJqVO5/Z6qkI0+YFjC39TkS3pbI4jUj1cSnpgYD0+K8VVV80uiK8j3UpJH5N 10 | RVEf//GC8xZOqyPTCKaGRo34SdcN51KbBi5SDa0Wn65LOfyzAx0fiOhJysn2bTeM 11 | 4YTQhkcVMUf1TWB4Sip1dzbeCIE6GjEoeNJZnNXcD3ApO34QQwsur3M0eP2cNq2M 12 | mgLrybSjSw9KhJ36SmVzKckV2qsWiXRBMZ2+xySUXBgIBs7tEXcTGzW7Ek+zuLWG 13 | 9at2UMKTDipJr/n8hDmn1ZAG6rHZKYthYvLCuC2+QQKBgQDeiGX1cmDTF498zRtz 14 | VJtw4KS8Rxznjnz+gtDhzbWUfW+RMGbJnpOxS1TaA78nbo5Vl6/UUjlODU1cFF55 15 | ulFxARi8PvMd++iUAKjrH3g5y/fBVyfbZQUfXhUdo0GCjGnV22NgOqnMKxGurkD0 16 | ibu8DnTOKKPuM3kGPxJV25UufwKBgQDRU3QX1Ia4iZYC6G2vMP71JMipnnIUQg1b 17 | G69OhXGm0mqCfnVF9RTabTmYmKl8dCz5l8FWDAOoH1/D8/PkHL7od/l05rXipRRJ 18 | 0QzewKwewuG8uxTesv0DgzkBb6xVPH4W6OWep5XTdMDmGjNU11ebF3o/lwDpeIx6 19 | TXUlHC/1QQKBgG0EUT6/O+PuBONU7/++ETBpPQrno6dkzKM6nu4gArauBLwSBCj9 20 | wMj4aKctcrX0mVIhL4hKh7xPE/jqGaZ0unUr3lxKUnv77uKiuB4HmrRl0ggrlGEM 21 | ykelpZ6RXgSAmVClW7fGxWw6JT14LGYgG5JzWpGsozKMkNuYhnj9S8YtAoGAfRPY 22 | ssSTG4Fa2bH4mE42ilTIclHy6JfvUxlfzxN9rajda8wUVxDyvPG3EK9n1q20kg9T 23 | vw6+wJ6+omAKw6tJh67oqCmTVTI+xTzc691E+7yHFjbTaZ6aAJdQYMNRvjy/OwE+ 24 | 82Y/6HJDMTtGoNNrzYhhy813Bgq6JfpSnTISlgECgYEApEJLoycUPL4cYSwHh2Nl 25 | /CKEGWVYXLXFVQODmOzXzdkNj0/qWfJBrQ0wza89b2Fki4mQ2GWlO4ERlUtpwiJl 26 | +WXgfX5DrmLSnohk6XBq2jQdbHHcBQ8o8kTOL1Y48/hqGxAHsE2Apf7P+pOFykv1 27 | Nwt7vibBZQ2hfliKHeiCm1g= 28 | -----END PRIVATE KEY----- 29 | -------------------------------------------------------------------------------- /core/utils/CircuitDetails.h: -------------------------------------------------------------------------------- 1 | // TODO: change to vector or make somehow usable for more than 3 players 2 | #define RR \ 3 | int send_rounds[2] = { \ 4 | 8, \ 5 | 8, \ 6 | }; 7 | #define SR \ 8 | int rec_rounds[2] = { \ 9 | 8, \ 10 | 8, \ 11 | }; 12 | #define ETR \ 13 | int elements_to_rec[2][8] = { \ 14 | { \ 15 | 262144, \ 16 | 0, \ 17 | 0, \ 18 | 0, \ 19 | 0, \ 20 | 0, \ 21 | 0, \ 22 | 0, \ 23 | }, \ 24 | { \ 25 | 64, \ 26 | 0, \ 27 | 0, \ 28 | 0, \ 29 | 0, \ 30 | 0, \ 31 | 0, \ 32 | 0, \ 33 | }, \ 34 | }; 35 | #define ETS \ 36 | int elements_to_send[2][8] = { \ 37 | { \ 38 | 0, \ 39 | 0, \ 40 | 0, \ 41 | 0, \ 42 | 0, \ 43 | 0, \ 44 | 0, \ 45 | 1, \ 46 | }, \ 47 | { \ 48 | 0, \ 49 | 0, \ 50 | 0, \ 51 | 0, \ 52 | 0, \ 53 | 0, \ 54 | 0, \ 55 | 1, \ 56 | }, \ 57 | }; 58 | -------------------------------------------------------------------------------- /core/utils/randomizer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../include/pch.h" 3 | #include "../networking/buffers.h" 4 | #if RANDOM_ALGORITHM == 0 5 | #include "../utils/xorshift.h" 6 | #elif RANDOM_ALGORITHM == 1 7 | #include "../crypto/aes/AES_BS_SHORT.h" 8 | #elif RANDOM_ALGORITHM == 2 9 | #if USE_SSL_AES == 1 10 | #include "../crypto/aes/AES_SSL.h" 11 | EVP_CIPHER_CTX* key_schedule[num_players * player_multiplier]; 12 | alignas(DATTYPE / 8) unsigned char aes_counter[num_players * player_multiplier][64]; 13 | #else 14 | #include "../crypto/aes/AES.h" 15 | AES_TYPE key_schedule[num_players * player_multiplier][11]; 16 | AES_TYPE aes_counter[num_players * player_multiplier]; 17 | #endif 18 | #if AES_DATTYPE >= DATTYPE 19 | #define BUFFER_SIZE AES_DATTYPE / DATTYPE 20 | #else 21 | #define BUFFER_SIZE -DATTYPE / AES_DATTYPE 22 | #endif 23 | #endif 24 | 25 | #if RANDOM_ALGORITHM == 0 26 | DATATYPE srng[num_players * player_multiplier][64]{0}; 27 | #elif RANDOM_ALGORITHM == 1 28 | DATATYPE counter[num_players * player_multiplier][128]{0}; 29 | DATATYPE cipher[num_players * player_multiplier][128]{0}; 30 | DATATYPE key[num_players * player_multiplier][11][128]{0}; 31 | #endif 32 | 33 | void init_buffers(int link_id) 34 | { 35 | #if RANDOM_ALGORITHM == 0 36 | num_generated[link_id] = 64; 37 | #elif RANDOM_ALGORITHM == 1 38 | num_generated[link_id] = 128; 39 | #elif RANDOM_ALGORITHM == 2 40 | num_generated[link_id] = BUFFER_SIZE; 41 | #endif 42 | } 43 | 44 | DATATYPE getRandomVal(int link_id) 45 | { 46 | /* if(link_id == 5 || link_id == 6 ) */ 47 | /* return SET_ALL_ZERO(); */ 48 | #if RANDOM_ALGORITHM == 0 49 | if (num_generated[link_id] > 63) 50 | { 51 | num_generated[link_id] = 0; 52 | xor_shift(srng[link_id]); 53 | } 54 | num_generated[link_id] += 1; 55 | return srng[link_id][num_generated[link_id] - 1]; 56 | #elif RANDOM_ALGORITHM == 1 57 | if (num_generated[link_id] > 127) 58 | { 59 | num_generated[link_id] = 0; 60 | AES__(counter[link_id], key[link_id], cipher[link_id]); 61 | for (int i = 0; i < 128; i++) 62 | { 63 | counter[link_id][i] += 1; 64 | } 65 | } 66 | num_generated[link_id] += 1; 67 | return cipher[link_id][num_generated[link_id] - 1]; 68 | #elif RANDOM_ALGORITHM == 2 69 | #if BUFFER_SIZE > 1 70 | if (num_generated[link_id] >= BUFFER_SIZE) 71 | { 72 | AES_enc(aes_counter[link_id], key_schedule[link_id]); 73 | /* DO_ENC_BLOCK(aes_counter[link_id], key_schedule[link_id]); */ 74 | num_generated[link_id] = 0; 75 | } 76 | #if USE_SSL_AES == 1 77 | return ((DATATYPE*)aes_counter[link_id])[num_generated[link_id]++]; 78 | #else 79 | alignas(sizeof(AES_TYPE)) DATATYPE ret[BUFFER_SIZE]; 80 | MM_AES_STORE((AES_TYPE*)ret, aes_counter[link_id]); 81 | return ret[num_generated[link_id]++]; 82 | #endif 83 | #elif BUFFER_SIZE == 1 84 | /* DO_ENC_BLOCK(aes_counter[link_id], key_schedule[link_id]); */ 85 | AES_enc(aes_counter[link_id], key_schedule[link_id]); 86 | return ((DATATYPE*)aes_counter)[link_id]; 87 | #else 88 | DATATYPE ret; 89 | for (int i = 0; i > BUFFER_SIZE; i--) 90 | { 91 | AES_enc(aes_counter[link_id], key_schedule[link_id]); 92 | MM_AES_STORE(((AES_TYPE*)(&ret)) - i, aes_counter[link_id]); 93 | } 94 | return ret; 95 | #endif 96 | 97 | #endif 98 | } 99 | 100 | DATATYPE getRandomVal(int link_id1, int link_id2) 101 | { 102 | return getRandomVal(num_players * (link_id1 + 1) + link_id2); 103 | } 104 | -------------------------------------------------------------------------------- /core/utils/timing.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../include/pch.h" 3 | template 4 | auto funcTime(std::string printText, F func, Args&&... args) 5 | { 6 | std::chrono::high_resolution_clock::time_point t1 = std::chrono::high_resolution_clock::now(); 7 | func(std::forward(args)...); 8 | double time = 9 | std::chrono::duration_cast(std::chrono::high_resolution_clock::now() - t1).count(); 10 | std::cout << "---TIMING--- " << time / (1000000) << "s " << printText << '\n'; 11 | return time; 12 | } 13 | -------------------------------------------------------------------------------- /datatypes/float_fixed_converter.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../config.h" 3 | #include "../core/include/pch.h" 4 | #define DEBUG_MODE 5 | template 6 | struct FloatFixedConverter 7 | { 8 | static float_type fixed_to_float(INT_TYPE fixed_val, int frac_bits = fractional_bits) 9 | { 10 | #if TRUNC_THEN_MULT == 1 11 | const float_type scale = (UINT_TYPE(1) << frac_bits * 2); 12 | #else 13 | const float_type scale = (UINT_TYPE(1) << frac_bits); 14 | #endif 15 | return static_cast(fixed_val) / scale; 16 | } 17 | 18 | static INT_TYPE float_to_fixed(float_type float_val, int frac_bits = fractional_bits) 19 | { 20 | #if TRUNC_THEN_MULT == 1 21 | const float_type scale = (UINT_TYPE(1) << frac_bits * 2); 22 | float_val = float_val / (UINT_TYPE(1) << frac_bits); // variant with trunc then mult 23 | #else 24 | const float_type scale = (UINT_TYPE(1) << frac_bits); 25 | #endif 26 | // Check for overflow and underflow 27 | if (float_val >= (std::numeric_limits::max()) / scale) 28 | { // Modified check 29 | #if PRINT_IMPORTANT == 1 30 | std::cout << "Warning: Overflow occurred! -> clamping" << float_val << std::endl; 31 | #endif 32 | return std::numeric_limits::max(); 33 | } 34 | 35 | if (float_val <= std::numeric_limits::min() / scale) 36 | { 37 | #if PRINT_IMPORTANT == 1 38 | std::cout << "Warning: Underflow occurred! -> clamping" << std::endl; 39 | #endif 40 | return std::numeric_limits::min(); 41 | } 42 | 43 | return static_cast(std::round(float_val * scale)); 44 | } 45 | 46 | static UINT_TYPE int_to_twos_complement(INT_TYPE val) { return static_cast(val); } 47 | 48 | static INT_TYPE twos_complement_to_int(UINT_TYPE val) { return static_cast(val); } 49 | 50 | static UINT_TYPE float_to_ufixed(float_type float_val, int frac_bits = fractional_bits) 51 | { 52 | return int_to_twos_complement(float_to_fixed(float_val, frac_bits)); 53 | } 54 | 55 | static float_type ufixed_to_float(UINT_TYPE ufixed_val, int frac_bits = fractional_bits) 56 | { 57 | return fixed_to_float(twos_complement_to_int(ufixed_val), frac_bits); 58 | } 59 | }; 60 | 61 | template 62 | float_type fixedToFloat(UINT_TYPE val, int frac_bits = fractional) 63 | { 64 | return FloatFixedConverter::ufixed_to_float(val, frac_bits); 65 | } 66 | 67 | template 68 | UINT_TYPE floatToFixed(float_type val, int frac_bits = fractional) 69 | { 70 | return FloatFixedConverter::float_to_ufixed(val, frac_bits); 71 | } 72 | -------------------------------------------------------------------------------- /datatypes/k_clear.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../protocols/Protocols.h" 3 | template 4 | class clear_t 5 | { 6 | private: 7 | Datatype values[BITLENGTH]; 8 | 9 | public: 10 | // temporary constructor 11 | clear_t() {} 12 | 13 | clear_t(UINT_TYPE value) 14 | { 15 | for (int i = 0; i < BITLENGTH; i++) 16 | values[i] = PROMOTE(value); 17 | } 18 | 19 | clear_t(UINT_TYPE value[DATTYPE]) { init(value); } 20 | 21 | void init(UINT_TYPE value[DATTYPE]) 22 | { 23 | DATATYPE temp_d[BITLENGTH]; 24 | orthogonalize_arithmetic(value, temp_d); 25 | for (int i = 0; i < BITLENGTH; i++) 26 | values[i] = temp_d[i]; 27 | } 28 | 29 | void reveal_to_all(UINT_TYPE result[DATTYPE]) const { unorthogonalize_arithmetic(values, result); } 30 | }; 31 | -------------------------------------------------------------------------------- /main.cpp: -------------------------------------------------------------------------------- 1 | #include "config.h" 2 | #include "protocol_executer.hpp" 3 | 4 | int main(int argc, char* argv[]) 5 | { 6 | #if PROCESS_NUM > 1 7 | pid_t child_pid, wpid; 8 | int status = 0; 9 | for (int id = 0; id < PROCESS_NUM; id++) 10 | { 11 | if ((child_pid = fork()) == 0) 12 | { 13 | base_port += 14 | (num_players * (num_players - 1) * id) + SPLIT_ROLES_OFFSET * num_players * (num_players - 1) * 15 | PROCESS_NUM; // offsets the starting port for each process 16 | process_offset = 17 | ((base_port - BASE_PORT) / 18 | (num_players * 19 | (num_players - 20 | 1))); // offsets the starting input for each process, base port must be multiple of 1000 to work 21 | executeProgram(argc, argv, child_pid, PROCESS_NUM); // child code 22 | exit(0); 23 | } 24 | } 25 | while ((wpid = wait(&status)) > 0) 26 | ; // wait for all the child processes 27 | #else 28 | base_port += SPLIT_ROLES_OFFSET * num_players * (num_players - 1); // offsets the starting port for each process 29 | process_offset = 30 | ((base_port - BASE_PORT) / 31 | (num_players * 32 | (num_players - 33 | 1))); // offsets the starting input for each process, base port must be multiple of 1000 to work 34 | executeProgram(argc, argv, 0, 1); // child code 35 | #endif 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/figure1/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.3 14 | export IP3=10.10.94.3 15 | export PID=0 # replace with node id 16 | export DATTYPE=256 # replace with highest DATTYPE supported by your hardware 17 | ``` 18 | 19 | ## Network Shaping 20 | 21 | Make sure to apply the bandwidths from figure 1 for each run. 22 | 23 | ## Execution 24 | 25 | Run the following commands on each node. 26 | 27 | ### Execute 3PC Experiments 28 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes, e.g. by adding PROCESS_NUM=1 after --override. 29 | 30 | ```sh 31 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/figure1 -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override PROTOCOL=2 DATTYPE=$DATTYPE 32 | ``` 33 | 34 | ### Execute 4PC Experiments 35 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes, e.g. by adding PROCESS_NUM=1,2,4 after --override. 36 | 37 | ```sh 38 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/figure1 -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3-p $PID --override PROTOCOL=9 DATTYPE=$DATTYPE 39 | ``` 40 | 41 | ## Parse Results 42 | 43 | Run the following commands on each node. 44 | 45 | ```sh 46 | python3 measurements/parse_logs.py measurements/logs/ 47 | ``` 48 | 49 | ## Interpret Results 50 | 51 | Open the csv files after parsing results. Divide Runtime by PROCESS_NUM to get the time taken per process. 52 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/figure1/figure1_multiplication.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=2 2 | DATTYPE=256 3 | PROTOCOL=2,9 4 | NUM_INPUTS=30000 5 | BITLENGTH=32 6 | PROCESS_NUM=32 7 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/figure1/figure1_scalar_product.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=7 2 | DATTYPE=256 3 | PROTOCOL=2,9 4 | NUM_INPUTS=30000 5 | BITLENGTH=32 6 | PROCESS_NUM=32 7 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/figure10/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.3 14 | export IP3=10.10.94.3 15 | export PID=0 # replace with node id 16 | export DATTYPE=256 # replace with highest DATTYPE supported by your hardware 17 | epxort DATTYPES=1,8,16,32,64,128,256 # replace with all DATTYPES supported by your hardware 18 | ``` 19 | 20 | 21 | ## Execution 22 | 23 | Run the following commands on each node. 24 | 25 | ### Execute 3PC Experiments (1) 26 | ```sh 27 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/figure10/figure10a_aes_latency.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override DATTYPE=$DATTYPES PROTOCOL=2,5 28 | ``` 29 | 30 | ### Execute 4PC Experiments (1) 31 | ```sh 32 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/figure10/figure10b_aes_latency.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override DATTYPE=$DATTYPES PROTOCOL=9,10,12 33 | ``` 34 | 35 | ### Execute 4PC Experiments (2) 36 | 37 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of inputs and num processes, e.g. by adding PROCESS_NUM=4 NUM_INPUTS=1000 after --override. 38 | 39 | ```sh 40 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/figure10/figure10c_vector_matrix.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3-p $PID --override DATTYPE=$DATTYPE 41 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/figure10/figure10b_mult_throughput.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3-p $PID --override DATTYPE=$DATTYPE 42 | ``` 43 | 44 | ## Parse Results 45 | 46 | Run the following commands on each node. 47 | 48 | ```sh 49 | python3 measurements/parse_logs.py measurements/logs/ 50 | ``` 51 | 52 | ## Interpret Results 53 | 54 | Open the csv files after parsing results. The achieved throughput should be contained in the table. 55 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/figure10/figure10a_aes_latency.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=25 2 | DATTYPE=1 3 | PROTOCOL=2,5,9,10 4 | NUM_INPUTS=50 5 | PROCESS_NUM=1 6 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/figure10/figure10b_mult_throughput.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=1 2 | DATTYPE=256 3 | PROTOCOL=8,9,10,11,12 4 | NUM_INPUTS=10000000 5 | PROCESS_NUM=32 6 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/figure10/figure10c_vector_matrix.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=7 2 | DATTYPE=256 3 | PROTOCOL=8,9,10,11 4 | NUM_INPUTS=10000000 5 | PROCESS_NUM=32 6 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/figure29/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.3 14 | export IP3=10.10.94.3 15 | export PID=0 # replace with node id 16 | export DATTYPE=256 # replace with highest DATTYPE supported by your hardware 17 | ``` 18 | 19 | ## Network Shaping 20 | 21 | Make sure to apply the latencies from figure 29 for each run. 22 | 23 | ## Execution 24 | 25 | Run the following commands on each node. 26 | 27 | ### Execute 3PC Experiments 28 | 29 | ```sh 30 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/figure11/figure11_runtime_baseline.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override PROTOCOL=2 DATTYPE=$DATTYPE 31 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/figure11/figure11_runtime_Trio_Quad.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override PROTOCOL=5 DATTYPE=$DATTYPE 32 | ``` 33 | 34 | ### Execute 4PC Experiments 35 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes, e.g. by adding PROCESS_NUM=1 after --override. 36 | 37 | ```sh 38 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/figure11/runtime_baseline.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override PROTOCOL=9 DATTYPE=$DATTYPE 39 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/figure11/runtime_Trio_Quad.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override PROTOCOL=12 DATTYPE=$DATTYPE 40 | ``` 41 | 42 | ## Parse Results 43 | 44 | Run the following commands on each node. 45 | 46 | ```sh 47 | python3 measurements/parse_logs.py measurements/logs/ 48 | ``` 49 | 50 | ## Interpret Results 51 | 52 | Open the csv files after parsing results to obtain runtime. 53 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/figure29/figure29_runtime_Trio_Quad.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=8,9,10,11 2 | DATTYPE=32 3 | PROTOCOL=5,12 4 | NUM_INPUTS=50 5 | PROCESS_NUM=1 6 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/figure29/figure29_runtime_baseline.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=8 2 | DATTYPE=32 3 | PROTOCOL=2,9 4 | NUM_INPUTS=50 5 | PROCESS_NUM=1 6 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/figure9/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.4 14 | export IP3=10.10.94.5 15 | export PID=0 # replace with node id 16 | export DATTYPE=256 # replace with highest DATTYPE supported by your hardware 17 | epxort DATTYPES=1,8,16,32,64,128,256 # replace with all DATTYPES supported by your hardware 18 | ``` 19 | 20 | 21 | ## Execution 22 | 23 | Run the following commands on each node. 24 | 25 | 26 | ### Execute 4PC Experiments (1) 27 | ```sh 28 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/figure9/bits_per_register.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3-p $PID --override DATTYPE=$DATTYPES 29 | ``` 30 | 31 | ### Execute 4PC Experiments (2) 32 | 33 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes, e.g. by adding PROCESS_NUM=1,2,4 after --override. 34 | 35 | ```sh 36 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/figure9/num_processes.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3-p $PID --override DATTYPE=$DATTYPE 37 | ``` 38 | 39 | ## Parse Results 40 | 41 | Run the following commands on each node. 42 | 43 | ```sh 44 | python3 measurements/parse_logs.py measurements/logs/ 45 | ``` 46 | 47 | ## Interpret Results 48 | 49 | Open the csv files after parsing results. The achieved throughput should be contained in the table. 50 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/figure9/figure9_bits_per_register.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=1 2 | DATTYPE=1,8,16,32,64,128,256 3 | PROTOCOL=8,9,10 4 | NUM_INPUTS=10000000 5 | PROCESS_NUM=1 6 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/figure9/figure9_num_processes.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=1 2 | DATTYPE=256 3 | PROTOCOL=8,9,10 4 | NUM_INPUTS=10000000 5 | PROCESS_NUM=1,2,4,8,21,26,36,45 6 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/machines.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ip": "", 4 | "username": "", 5 | "password": "", 6 | "hostname": "" 7 | }, 8 | { 9 | "ip": "", 10 | "username": "", 11 | "password": "", 12 | "hostname": "" 13 | }, 14 | { 15 | "ip": "", 16 | "username": "", 17 | "password": "", 18 | "hostname": "" 19 | }, 20 | { 21 | "ip": "", 22 | "username": "", 23 | "password": "", 24 | "hostname": "" 25 | } 26 | ] 27 | 28 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/run_all_on_remote_servers.py: -------------------------------------------------------------------------------- 1 | import json 2 | import paramiko 3 | import sys 4 | import threading 5 | 6 | # Load machine credentials from JSON file 7 | with open('machines.json') as f: 8 | machines = json.load(f) 9 | 10 | # Define commands to execute 11 | base_commands = """ 12 | cd hpmpc 13 | sudo chmod 777 measurements/logs 14 | rm -rf measurements/logs/* 15 | export MAX_BITWIDTH=$(lscpu | grep -i flags | grep -q "avx512" && echo 512 || (lscpu | grep -i flags | grep -q "avx2" && echo 256 || (lscpu | grep -i flags | grep -q "sse" && echo 128 || echo 64))) 16 | export SUPPORTED_BITWIDTHS=$(echo 1 8 16 32 64 128 256 512 | awk -v max="$MAX_BITWIDTH" '{for(i=1;i<=NF;i++) if($i<=max) printf $i (i 1: 64 | machine_index = int(sys.argv[1]) 65 | execute_commands_on_remote(machines[machine_index], machine_index) 66 | else: 67 | # Run in multi-threaded mode for all machines 68 | threads = [] 69 | for pid, machine in enumerate(machines): 70 | thread = threading.Thread(target=execute_commands_on_remote, args=(machine, pid)) 71 | threads.append(thread) 72 | thread.start() 73 | 74 | # Wait for all threads to complete 75 | for thread in threads: 76 | thread.join() 77 | 78 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/run_with_tmux_grid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | while getopts "g:R:" opt; do 4 | case $opt in 5 | g) g_value="$OPTARG" ;; 6 | R) R_value="$OPTARG" ;; 7 | *) echo "Invalid option: -$opt" >&2; exit 1 ;; 8 | esac 9 | done 10 | 11 | arg_string="" 12 | if [[ -n $g_value ]]; then 13 | arg_string+=" -g $g_value" 14 | fi 15 | if [[ -n $R_value ]]; then 16 | arg_string+=" -R $R_value" 17 | fi 18 | 19 | #if exists kill tmux session grid 20 | tmux kill-session -t grid 21 | 22 | # Start a new tmux session named 'grid' 23 | tmux new-session -d -s grid 24 | 25 | # Split the window into a 2x2 grid and run the Python script for each machine 26 | tmux send-keys "python3 run_all_on_remote_servers.py ${arg_string} 0" C-m # Machine 0 27 | tmux split-window -h 28 | tmux send-keys "python3 run_all_on_remote_servers.py ${arg_string} 1" C-m # Machine 1 29 | tmux split-window -v 30 | tmux send-keys "python3 run_all_on_remote_servers.py ${arg_string} 2" C-m # Machine 2 31 | tmux select-pane -t 0 32 | tmux split-window -v 33 | tmux send-keys "python3 run_all_on_remote_servers.py ${arg_string} 3" C-m # Machine 3 34 | 35 | # Adjust layout to ensure a 2x2 grid 36 | tmux select-layout tiled 37 | 38 | # Attach to the tmux session 39 | tmux attach -t grid 40 | 41 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table10/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.4 14 | export IP3=10.10.94.5 15 | export PID=0 # replace with node id 16 | export DATTYPE=256 # replace with highest DATTYPE supported by your hardware 17 | ``` 18 | 19 | ## Network Shaping 20 | 21 | Make sure to apply the bandwidths from table 10 for each run. 22 | 23 | ## Execution 24 | 25 | Run the following commands on each node. 26 | 27 | ### Execute Experiments 28 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes or input size, e.g. by adding PROCESS_NUM=1 NUM_INPUTS=1000 after --override. 29 | 30 | ### Execute 3PC Experiments 31 | 32 | ```sh 33 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table10/table10_aes-3PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID 34 | 35 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table10/table10_aes-PRE-3PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID 36 | ``` 37 | 38 | ### Execute 4PC Experiments 39 | ```sh 40 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table10/table10_aes-4PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID 41 | 42 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table10/table10_aes-PRE-4PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID 43 | ``` 44 | 45 | 46 | ## Parse Results 47 | 48 | Run the following commands on each node. 49 | 50 | ```sh 51 | python3 measurements/parse_logs.py measurements/logs/ 52 | ``` 53 | 54 | ## Interpret Results 55 | 56 | Open the csv files after parsing results to obtain throughput. 57 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table10/table10_aes-3PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=2,3,5,6 2 | FUNCTION_IDENTIFIER=25 3 | BITLENGTH=32 4 | PRE=0 5 | DATTYPE=256 6 | NUM_INPUTS=10000 7 | SPLITROLES=1 8 | PROCESS_NUM=6 9 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table10/table10_aes-4PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=7,8,9,10,11,12 2 | FUNCTION_IDENTIFIER=25 3 | BITLENGTH=32 4 | PRE=0 5 | DATTYPE=256 6 | NUM_INPUTS=10000 7 | SPLITROLES=3 8 | PROCESS_NUM=6 9 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table10/table10_aes-PRE-3PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=3,5 2 | FUNCTION_IDENTIFIER=25 3 | BITLENGTH=32 4 | PRE=1 5 | DATTYPE=256 6 | NUM_INPUTS=10000 7 | SPLITROLES=1 8 | PROCESS_NUM=6 9 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table10/table10_aes-PRE-4PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=8,11,12 2 | FUNCTION_IDENTIFIER=25 3 | BITLENGTH=32 4 | PRE=1 5 | DATTYPE=256 6 | NUM_INPUTS=10000 7 | SPLITROLES=3 8 | PROCESS_NUM=6 9 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table6/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.4 14 | export IP3=10.10.94.5 15 | export PID=0 # replace with node id 16 | export DATTYPE=256 # replace with highest DATTYPE supported by your hardware 17 | ``` 18 | 19 | ## Execution 20 | 21 | Run the following commands on each node. 22 | 23 | ### Execute 3PC Experiments 24 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes or input size, e.g. by adding PROCESS_NUM=4 NUM_INPUTS=10000 after --override. 25 | 26 | ```sh 27 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table6/ -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override PROTOCOL=2,3,5 DATTYPE=$DATTYPE 28 | ``` 29 | 30 | ### Execute 4PC Experiments 31 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes or input size, e.g. by adding PROCESS_NUM=4 NUM_INPUTS=10000 after --override. 32 | 33 | ```sh 34 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table6/ -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override PROTOCOL=8,9,10,12 DATTYPE=$DATTYPE 35 | ``` 36 | 37 | ## Parse Results 38 | 39 | Run the following commands on each node. 40 | 41 | ```sh 42 | python3 measurements/parse_logs.py measurements/logs/ 43 | ``` 44 | 45 | ## Interpret Results 46 | 47 | Open the csv files after parsing results to obtain throughput. 48 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table6/table6_throughput.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=1 2 | DATTYPE=256 3 | PROTOCOL=2,3,5,8,9,10,12 4 | NUM_INPUTS=10000000 5 | PROCESS_NUM=32 6 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table7/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.4 14 | export IP3=10.10.94.5 15 | export PID=0 # replace with node id 16 | export DATTYPE=256 # replace with highest DATTYPE supported by your hardware 17 | ``` 18 | 19 | ## Execution 20 | 21 | Run the following commands on each node. 22 | 23 | ### Execute 3PC Experiments 24 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes or input size, e.g. by adding PROCESS_NUM=1 NUM_INPUTS=10000 after --override. 25 | 26 | ```sh 27 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table7/table7_throughput_3PC_PRE0.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override DATTYPE=$DATTYPE 28 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table7/table7_throughput_3PC_PRE1.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override DATTYPE=$DATTYPE 29 | ``` 30 | 31 | ### Execute 4PC Experiments 32 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes or input size, e.g. by adding PROCESS_NUM=4 NUM_INPUTS=10000 after --override. 33 | 34 | ```sh 35 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table7/table7_throughput_4PC_PRE0.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override DATTYPE=$DATTYPE 36 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table7/table7_throughput_4PC_PRE1.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override DATTYPE=$DATTYPE 37 | ``` 38 | 39 | ## Parse Results 40 | 41 | Run the following commands on each node. 42 | 43 | ```sh 44 | python3 measurements/parse_logs.py measurements/logs/ 45 | ``` 46 | 47 | ## Interpret Results 48 | 49 | Open the csv files after parsing results to obtain throughput. 50 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table7/table7_throughput_3PC_PRE0.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=2 2 | SPLITROLES=1 3 | PRE=0 4 | DATTYPE=256 5 | PROTOCOL=2,3,5 6 | NUM_INPUTS=10000000 7 | PROCESS_NUM=6 8 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table7/table7_throughput_3PC_PRE1.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=2 2 | SPLITROLES=1 3 | PRE=1 4 | DATTYPE=256 5 | PROTOCOL=3,5 6 | NUM_INPUTS=10000000 7 | PROCESS_NUM=6 8 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table7/table7_throughput_4PC_PRE0.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=2 2 | SPLITROLES=3 3 | PRE=0 4 | DATTYPE=256 5 | PROTOCOL=8,9,10,12 6 | NUM_INPUTS=10000000 7 | PROCESS_NUM=2 8 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table7/table7_throughput_4PC_PRE1.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=2 2 | SPLITROLES=3 3 | PRE=1 4 | DATTYPE=256 5 | PROTOCOL=8,12 6 | NUM_INPUTS=10000000 7 | PROCESS_NUM=2 8 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table8/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.4 14 | export IP3=10.10.94.5 15 | export PID=0 # replace with node id 16 | export DATTYPE=256 # replace with highest DATTYPE supported by your hardware 17 | ``` 18 | 19 | ## Execution 20 | 21 | Run the following commands on each node. 22 | 23 | ### Execute 3PC Experiments 24 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes or input size, e.g. by adding PROCESS_NUM=1 NUM_INPUTS=100 after --override. 25 | 26 | ```sh 27 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table8/table8_throughput_3PC_PRE0.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override DATTYPE=$DATTYPE 28 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table8/table8_throughput_3PC_PRE1.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override DATTYPE=$DATTYPE 29 | ``` 30 | 31 | ### Execute 4PC Experiments 32 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes or input size, e.g. by adding PROCESS_NUM=1 NUM_INPUTS=100 after --override. 33 | 34 | ```sh 35 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table8/table8_throughput_4PC_PRE0.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override DATTYPE=$DATTYPE 36 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table8/table8_throughput_4PC_PRE1.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override DATTYPE=$DATTYPE 37 | ``` 38 | 39 | ## Parse Results 40 | 41 | Run the following commands on each node. 42 | 43 | ```sh 44 | python3 measurements/parse_logs.py measurements/logs/ 45 | ``` 46 | 47 | ## Interpret Results 48 | 49 | Open the csv files after parsing results to obtain throughput. 50 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table8/table8_throughput_3PC_PRE0.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=25 2 | SPLITROLES=1 3 | PRE=0 4 | DATTYPE=256 5 | BITLENGTH=32 6 | PROTOCOL=2,3,5 7 | NUM_INPUTS=10000 8 | PROCESS_NUM=6 9 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table8/table8_throughput_3PC_PRE1.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=25 2 | SPLITROLES=1 3 | PRE=1 4 | DATTYPE=256 5 | BITLENGTH=32 6 | PROTOCOL=3,5 7 | NUM_INPUTS=10000 8 | PROCESS_NUM=6 9 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table8/table8_throughput_4PC_PRE0.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=25 2 | SPLITROLES=3 3 | PRE=0 4 | DATTYPE=256 5 | BITLENGTH=32 6 | PROTOCOL=8,9,10,12 7 | NUM_INPUTS=10000 8 | PROCESS_NUM=2 9 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table8/table8_throughput_4PC_PRE1.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=25 2 | SPLITROLES=3 3 | PRE=1 4 | DATTYPE=256 5 | BITLENGTH=32 6 | PROTOCOL=8,12 7 | NUM_INPUTS=10000 8 | PROCESS_NUM=2 9 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table9/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.4 14 | export IP3=10.10.94.5 15 | export PID=0 # replace with node id 16 | export DATTYPE=256 # replace with highest DATTYPE supported by your hardware 17 | ``` 18 | 19 | ## Network Shaping 20 | 21 | Make sure to apply the bandwidths/latencies from table 9 for each run. 22 | 23 | ## Execution 24 | 25 | Run the following commands on each node. 26 | 27 | ### Execute Experiments 28 | The experiments except aes_lat require a lot of processes and system RAM. If necessary, reduce the number of processes or input size, e.g. by adding PROCESS_NUM=1 NUM_INPUTS=1000 after --override. 29 | 30 | #### Execute 3PC Experiments 31 | 32 | ```sh 33 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table9/aes_bdw/table9_aes-3PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override DATTYPE=$DATTYPE 34 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table9/aes_bdw/table9_aes-PRE-3PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override DATTYPE=$DATTYPE 35 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table9/aes_lat/table9_aes1-3PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID 36 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table9/aes_lat/table9_aes1-PRE-3PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID 37 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table9/vector_prod20k/table9_dot-3PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override DATTYPE=$DATTYPE 38 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table9/vector_prod20k/table9_dot-PRE-3PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override DATTYPE=$DATTYPE 39 | ``` 40 | 41 | 42 | #### Execute 4PC Experiments 43 | 44 | ```sh 45 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table9/aes_bdw/table9_aes-4PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override DATTYPE=$DATTYPE 46 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table9/aes_bdw/table9_aes-PRE-4PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override DATTYPE=$DATTYPE 47 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table9/aes_lat/table9_aes1-4PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID 48 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table9/aes_lat/table9_aes1-PRE-4PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID 49 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table9/vector_prod20k/table9_dot-4PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override DATTYPE=$DATTYPE 50 | python3 measurements/run_config.py measurements/configs/artifacts/hpmpc/table9/vector_prod20k/table9_dot-PRE-4PC.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override DATTYPE=$DATTYPE 51 | ``` 52 | 53 | 54 | 55 | ## Parse Results 56 | 57 | Run the following commands on each node. 58 | 59 | ```sh 60 | python3 measurements/parse_logs.py measurements/logs/ 61 | ``` 62 | 63 | ## Interpret Results 64 | 65 | Open the csv files after parsing results to obtain runtime. 66 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table9/aes_bdw/table9_aes-3PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=2,5 2 | FUNCTION_IDENTIFIER=25 3 | BITLENGTH=32 4 | PRE=0 5 | DATTYPE=256 6 | NUM_INPUTS=1000 7 | PROCESS_NUM=8 8 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table9/aes_bdw/table9_aes-4PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=9,12 2 | FUNCTION_IDENTIFIER=25 3 | BITLENGTH=32 4 | PRE=0 5 | DATTYPE=256 6 | NUM_INPUTS=1000 7 | PROCESS_NUM=8 8 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table9/aes_bdw/table9_aes-PRE-3PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=5 2 | FUNCTION_IDENTIFIER=25 3 | BITLENGTH=32 4 | PRE=1 5 | DATTYPE=256 6 | NUM_INPUTS=1000 7 | PROCESS_NUM=8 8 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table9/aes_bdw/table9_aes-PRE-4PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=12 2 | FUNCTION_IDENTIFIER=25 3 | BITLENGTH=32 4 | PRE=1 5 | DATTYPE=256 6 | NUM_INPUTS=1000 7 | PROCESS_NUM=8 8 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table9/aes_lat/table9_aes1-3PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=2,5 2 | DATTYPE=1 3 | FUNCTION_IDENTIFIER=25 4 | BITLENGTH=32 5 | PRE=0 6 | NUM_INPUTS=1,50 7 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table9/aes_lat/table9_aes1-4PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=9,12 2 | DATTYPE=1 3 | FUNCTION_IDENTIFIER=25 4 | BITLENGTH=32 5 | PRE=0 6 | NUM_INPUTS=1,50 7 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table9/aes_lat/table9_aes1-PRE-3PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=5 2 | DATTYPE=1 3 | FUNCTION_IDENTIFIER=25 4 | BITLENGTH=32 5 | PRE=1 6 | NUM_INPUTS=1,50 7 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table9/aes_lat/table9_aes1-PRE-4PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=12 2 | DATTYPE=1 3 | FUNCTION_IDENTIFIER=25 4 | BITLENGTH=32 5 | PRE=1 6 | NUM_INPUTS=1,50 7 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table9/vector_prod20k/table9_dot-3PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=2,5 2 | FUNCTION_IDENTIFIER=7 3 | BITLENGTH=32 4 | PRE=0 5 | DATTYPE=256 6 | NUM_INPUTS=20000 7 | PROCESS_NUM=8 8 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table9/vector_prod20k/table9_dot-4PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=9,12 2 | FUNCTION_IDENTIFIER=7 3 | BITLENGTH=32 4 | PRE=0 5 | DATTYPE=256 6 | NUM_INPUTS=20000 7 | PROCESS_NUM=8 8 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table9/vector_prod20k/table9_dot-PRE-3PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=5 2 | FUNCTION_IDENTIFIER=7 3 | BITLENGTH=32 4 | PRE=1 5 | DATTYPE=256 6 | NUM_INPUTS=20000 7 | PROCESS_NUM=8 8 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/hpmpc/table9/vector_prod20k/table9_dot-PRE-4PC.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=12 2 | FUNCTION_IDENTIFIER=7 3 | BITLENGTH=32 4 | PRE=1 5 | DATTYPE=256 6 | NUM_INPUTS=20000 7 | PROCESS_NUM=8 8 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/figure1/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.3 14 | export IP3=10.10.94.3 15 | export PID=0 # replace with node id 16 | ``` 17 | 18 | ## Execution 19 | 20 | Run the following commands on each node. 21 | 22 | ### Execute 3PC Experiments 23 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes, e.g. by adding PROCESS_NUM=1 after --override. 24 | 25 | ```sh 26 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/figure1 -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override PROTOCOL=5 27 | ``` 28 | 29 | ### Execute 4PC Experiments 30 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes, e.g. by adding PROCESS_NUM=1,2,4 after --override. 31 | 32 | ```sh 33 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/figure1 -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3-p $PID --override PROTOCOL=9 34 | ``` 35 | 36 | ## Parse Results 37 | 38 | Run the following commands on each node. 39 | 40 | ```sh 41 | python3 measurements/parse_logs.py measurements/logs/ 42 | ``` 43 | 44 | ## Interpret Results 45 | 46 | Open the csv files after parsing results. The data contains the number of bits per registers (DATTYPE), Number of Cores (Threads), and throughput in MBit/s. 47 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/figure1/figure1_a.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=41 2 | DATTYPE=32,128,256 3 | PROTOCOL=5,12 4 | NUM_INPUTS=224 5 | BITLENGTH=32 6 | PROCESS_NUM=1 7 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/figure1/figure1_b.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=41 2 | DATTYPE=256 3 | PROTOCOL=5,12 4 | NUM_INPUTS=224 5 | BITLENGTH=32 6 | PROCESS_NUM=1,4,8,12,16,20,24,28,32,36,40 7 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/figure1/figure1_c.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=43 2 | DATTYPE=1,32,128,256 3 | PROTOCOL=5,12 4 | NUM_INPUTS=100352 5 | BITLENGTH=32 6 | PROCESS_NUM=1 7 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/figure1/figure1_d.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=43 2 | DATTYPE=256 3 | PROTOCOL=5,12 4 | NUM_INPUTS=100352 5 | BITLENGTH=32 6 | PROCESS_NUM=1,4,8,12,16,20,24,28,32,36,40 7 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/figure1/figure1c_16bits.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=43 2 | DATTYPE=16 3 | PROTOCOL=5,12 4 | NUM_INPUTS=100352 5 | BITLENGTH=16 6 | PROCESS_NUM=1 7 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/figure1/figure1c_8bits.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=43 2 | DATTYPE=8 3 | PROTOCOL=5,12 4 | NUM_INPUTS=100352 5 | BITLENGTH=8 6 | PROCESS_NUM=1 7 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/figure3/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.3 14 | export IP3=10.10.94.3 15 | export PID=0 # replace with node id 16 | ``` 17 | 18 | 19 | ## Execution 20 | 21 | Run the following commands on each node. This experiment requires a lot of processes and system RAM. If necessary, reduce the number of inputs and num processes, e.g. by adding PROCESS_NUM=1 after --override. 22 | 23 | ### Execute 3PC Experiments 24 | ```sh 25 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/figure3/figure3CPU.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override PROTOCOL=5 26 | ``` 27 | 28 | ### Execute 4PC Experiments 29 | ```sh 30 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/figure3/figure3CPU.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override PROTOCOL=12 31 | ``` 32 | 33 | ### Execute 3PC Experiments (GPU) 34 | 35 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/figure3/figure3GPU.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override PROTOCOL=5 36 | 37 | ### Execute 4PC Experiments (GPU) 38 | 39 | ```sh 40 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/figure3/figure3GPU.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override PROTOCOL=12 41 | ``` 42 | 43 | ## Parse Results 44 | 45 | Run the following commands on each node. 46 | 47 | ```sh 48 | python3 measurements/parse_logs.py measurements/logs/ 49 | ``` 50 | 51 | ## Interpret Results 52 | 53 | Open the csv files after parsing results. INTERLEAVE_COMM=0 and FUSE_DOT=0 refers to TILED, INTERLEAVE_COMM=1 and FUSE_DOT=1 refers to MPC-Friendly , The throughput is shown in MBit/s. 54 | 55 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/figure3/figure3CPU.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=46 2 | DATTYPE=256 3 | PROTOCOL=5,12 4 | NUM_INPUTS=1 5 | PROCESS_NUM=24 6 | FUSE_DOT=0,1 7 | INTERLEAVE_COMM=0,1 8 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/figure3/figure3GPU.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=46 2 | DATTYPE=256 3 | PROTOCOL=5,12 4 | NUM_INPUTS=1 5 | PROCESS_NUM=24 6 | USE_CUDA_GEMM=2 7 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/figure6/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.4 14 | export IP3=10.10.94.5 15 | export PID=0 # replace with node id 16 | ``` 17 | 18 | 19 | ## Execution 20 | 21 | Run the following commands on each node. 22 | 23 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes, e.g. and inputs, e.g. by adding PROCESS_NUM=1 and NUM_INPUTS=10,100 after --override. 24 | 25 | 26 | ```sh 27 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/figure6/ -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3-p $PID --override PROTOCOL=5 SPLITROLES=0,1 28 | ``` 29 | 30 | ### Execute 4PC Experiments 31 | 32 | 33 | ```sh 34 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/figure6/ -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3-p $PID --override PROTOCOL=12 SPLITROLES=0,3 35 | ``` 36 | 37 | ## Parse Results 38 | 39 | Run the following commands on each node. 40 | 41 | ```sh 42 | python3 measurements/parse_logs.py measurements/logs/ 43 | ``` 44 | 45 | ## Interpret Results 46 | 47 | Open the csv files after parsing results. The achieved throughput should be contained in the table. 48 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/figure6/figure6_32bit.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=37 2 | DATTYPE=32,256 3 | PROTOCOL=5,12 4 | NUM_INPUTS=10000,100000,1000000,10000000 5 | BITLENGTH=32 6 | PROCESS_NUM=1,4 7 | SPLITROLES=0,1,3 8 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/figure6/figure6_64bit.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=37 2 | DATTYPE=64,512 3 | PROTOCOL=5,12 4 | NUM_INPUTS=10000,100000,1000000,10000000 5 | BITLENGTH=64 6 | PROCESS_NUM=1,4 7 | SPLITROLES=0,1,3 8 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/machines.json: -------------------------------------------------------------------------------- 1 | [ 2 | { 3 | "ip": "", 4 | "username": "", 5 | "password": "", 6 | "hostname": "" 7 | }, 8 | { 9 | "ip": "", 10 | "username": "", 11 | "password": "", 12 | "hostname": "" 13 | }, 14 | { 15 | "ip": "", 16 | "username": "", 17 | "password": "", 18 | "hostname": "" 19 | }, 20 | { 21 | "ip": "", 22 | "username": "", 23 | "password": "", 24 | "hostname": "" 25 | } 26 | ] 27 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/run_with_tmux_grid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Parse -R and -g options 4 | EXTRA_ARGS=() 5 | 6 | while [[ $# -gt 0 ]]; do 7 | case $1 in 8 | -R|-g|-O) 9 | EXTRA_ARGS+=("$1" "$2") 10 | shift 2 11 | ;; 12 | *) 13 | echo "Usage: $0 [-R value] [-g value] [-O value]" 14 | exit 1 15 | ;; 16 | esac 17 | done 18 | 19 | # Function to build command and quote it safely 20 | build_cmd() { 21 | local machine_idx=$1 22 | local cmd=(python3 run_all_on_remote_servers.py -p "$machine_idx" "${EXTRA_ARGS[@]}") 23 | 24 | # Print command as a single string with proper quoting 25 | printf "%q " "${cmd[@]}" 26 | } 27 | 28 | # Kill existing tmux session if it exists 29 | tmux kill-session -t grid 2>/dev/null 30 | 31 | # Start a new tmux session named 'grid' 32 | tmux new-session -d -s grid 33 | 34 | # Split the window into a 2x2 grid and run the Python script for each machine 35 | tmux send-keys "$(build_cmd 0)" C-m # Machine 0 36 | tmux split-window -h 37 | tmux send-keys "$(build_cmd 1)" C-m # Machine 1 38 | tmux split-window -v 39 | tmux send-keys "$(build_cmd 2)" C-m # Machine 2 40 | tmux select-pane -t 0 41 | tmux split-window -v 42 | tmux send-keys "$(build_cmd 3)" C-m # Machine 3 43 | 44 | # Adjust layout to ensure a 2x2 grid 45 | tmux select-layout tiled 46 | 47 | # Attach to the tmux session 48 | tmux attach -t grid 49 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/table4/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.4 14 | export IP3=10.10.94.5 15 | export PID=0 # replace with node id 16 | ``` 17 | 18 | ## Execution 19 | 20 | Run the following commands on each node. 21 | 22 | ### Execute Experiments 23 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes or input size, e.g. by adding PROCESS_NUM=1 SPLITROLES=0 after --override. 24 | 25 | ### Execute 3PC Experiments 26 | 27 | ```sh 28 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/table4/table4.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override PROTOCOL=5 SPLITROLES=1 29 | ``` 30 | 31 | ### Execute 4PC Experiments 32 | ```sh 33 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/table4/table4.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override PROTOCOL=12 SPLITROLES=3 34 | ``` 35 | 36 | 37 | ## Parse Results 38 | 39 | Run the following commands on each node. 40 | 41 | ```sh 42 | python3 measurements/parse_logs.py measurements/logs/ 43 | ``` 44 | 45 | ## Interpret Results 46 | 47 | Open the csv files after parsing results to obtain throughput. The Function identifiers map to the following CNNS: 48 | -180: AlexNet (CIFAR-10) 49 | -171: ResNet50 (CIFAR-10) 50 | -174: VGG-16 (CIFAR-10) 51 | -176: ResNet50 (ImageNet) 52 | -179: VGG-16 (ImageNet) 53 | 54 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/table4/table4.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=5,12 2 | FUNCTION_IDENTIFIER=180,171,174,176,179 3 | BITLENGTH=32 4 | PRE=0 5 | DATTYPE=256 6 | NUM_INPUTS=1 7 | SPLITROLES=1,3 8 | PROCESS_NUM=4 9 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/table5/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.4 14 | export IP3=10.10.94.5 15 | export PID=0 # replace with node id 16 | ``` 17 | 18 | ## Execution 19 | 20 | Run the following commands on each node. 21 | 22 | ### Execute Experiments 23 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes or input size, e.g. by adding PROCESS_NUM=1 SPLITROLES=0 after --override. 24 | 25 | ### Execute 3PC Experiments 26 | 27 | ```sh 28 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/table5/table5.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override PROTOCOL=5 SPLITROLES=1 29 | ``` 30 | 31 | ### Execute 4PC Experiments 32 | ```sh 33 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/table5/table5.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override PROTOCOL=12 SPLITROLES=3 34 | ``` 35 | 36 | 37 | ## Parse Results 38 | 39 | Run the following commands on each node. 40 | 41 | ```sh 42 | python3 measurements/parse_logs.py measurements/logs/ 43 | ``` 44 | 45 | ## Interpret Results 46 | 47 | Open the csv files after parsing results to obtain throughput. The Function identifiers map to the following CNNS: 48 | -178: ResNet152 (ImageNet) 49 | -179: VGG-16 (ImageNet) 50 | 51 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/table5/table5.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=5,12 2 | FUNCTION_IDENTIFIER=178,179 3 | BITLENGTH=32 4 | PRE=0 5 | DATTYPE=256 6 | NUM_INPUTS=1 7 | SPLITROLES=1,3 8 | PROCESS_NUM=4 9 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/table6/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.4 14 | export IP3=10.10.94.5 15 | export PID=0 # replace with node id 16 | ``` 17 | 18 | ## Execution 19 | 20 | Run the following commands on each node. 21 | 22 | ### Execute Experiments 23 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes or input size, e.g. by adding PROCESS_NUM=1 SPLITROLES=0 after --override. 24 | 25 | ### Execute 3PC Experiments 26 | 27 | ```sh 28 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/table6/ -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override PROTOCOL=5 SPLITROLES=1 29 | ``` 30 | 31 | 32 | ## Parse Results 33 | 34 | Run the following commands on each node. 35 | 36 | ```sh 37 | python3 measurements/parse_logs.py measurements/logs/ 38 | ``` 39 | 40 | ## Interpret Results 41 | 42 | Open the csv files after parsing results to obtain throughput. The Function identifiers map to the following CNNS: 43 | -74: VGG-16 (CIFAR-10, RCA) 44 | -76: ResNet152 (ImageNet, RCA) 45 | -79: VGG-16 (ImageNet, RCA) 46 | -174: VGG-16 (CIFAR-10, PPA) 47 | -176: ResNet152 (ImageNet, PPA) 48 | -179: VGG-16 (ImageNet, PPA) 49 | -COMPRESS=1 -> 8 Key bits 50 | -PRE=1 -> Seperate online and preprocessing phase 51 | 52 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/table6/table6_cifar.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=5 2 | FUNCTION_IDENTIFIER=174,74 3 | BITLENGTH=32 4 | PRE=0,1 5 | COMPRESS=0,1 6 | DATTYPE=256 7 | NUM_INPUTS=1 8 | SPLITROLES=1 9 | PROCESS_NUM=4 10 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/table6/table6_imagenet.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=5 2 | FUNCTION_IDENTIFIER=176,179,76,79 3 | BITLENGTH=32 4 | PRE=0,1 5 | COMPRESS=0,1 6 | DATTYPE=256 7 | NUM_INPUTS=1 8 | SPLITROLES=1 9 | PROCESS_NUM=4 10 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/table7/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.4 14 | export IP3=10.10.94.5 15 | export PID=0 # replace with node id 16 | ``` 17 | 18 | ## Execution 19 | 20 | Run the following commands on each node. 21 | 22 | ### Execute Experiments 23 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes or input size, e.g. by adding PROCESS_NUM=1 SPLITROLES=0 after --override. 24 | 25 | ### Execute 3PC Experiments 26 | 27 | ```sh 28 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/table7/table7.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override PROTOCOL=5 SPLITROLES=1 29 | ``` 30 | 31 | ### Execute 4PC Experiments 32 | ```sh 33 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/table7/table7.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override PROTOCOL=12 SPLITROLES=3 34 | ``` 35 | 36 | 37 | ## Parse Results 38 | 39 | Run the following commands on each node. 40 | 41 | ```sh 42 | python3 measurements/parse_logs.py measurements/logs/ 43 | ``` 44 | 45 | ## Interpret Results 46 | 47 | Open the csv files after parsing results to obtain throughput. The Function identifiers map to the following CNNS: 48 | -180: AlexNet (CIFAR-10) 49 | -171: ResNet50 (CIFAR-10) 50 | -174: VGG-16 (CIFAR-10) 51 | -175: ResNet18 (ImageNet) 52 | -179: VGG-16 (ImageNet) 53 | 54 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/table7/table7.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=5,12 2 | FUNCTION_IDENTIFIER=180,171,174,175,179 3 | BITLENGTH=64 4 | PRE=0 5 | DATTYPE=512 6 | NUM_INPUTS=1 7 | SPLITROLES=1,3 8 | PROCESS_NUM=4 9 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/table8/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.4 14 | export IP3=10.10.94.5 15 | export PID=0 # replace with node id 16 | ``` 17 | 18 | ## Execution 19 | 20 | Run the following commands on each node. 21 | 22 | ### Execute Experiments 23 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes or input size, e.g. by adding PROCESS_NUM=1 SPLITROLES=0 after --override. 24 | 25 | ### Execute 3PC Experiments 26 | 27 | ```sh 28 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/table8/table8.conf -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override PROTOCOL=5 29 | ``` 30 | 31 | ### Execute 4PC Experiments 32 | ```sh 33 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/table8 -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override PROTOCOL=12 34 | ``` 35 | 36 | 37 | ## Parse Results 38 | 39 | Run the following commands on each node. 40 | 41 | ```sh 42 | python3 measurements/parse_logs.py measurements/logs/ 43 | ``` 44 | 45 | ## Interpret Results 46 | 47 | Open the csv files after parsing results to obtain throughput. The Function identifiers map to the following CNNS: 48 | -180: AlexNet (CIFAR-10) 49 | -170: ResNet18 (CIFAR-10) 50 | -171: ResNet50 (CIFAR-10) 51 | -174: VGG-16 (CIFAR-10) 52 | -175: ResNet18 (ImageNet) 53 | -179: VGG-16 (ImageNet) 54 | 55 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/table8/table8.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=5,12 2 | FUNCTION_IDENTIFIER=180,170,171,174,175,179 3 | BITLENGTH=32 4 | PRE=0 5 | DATTYPE=32 6 | NUM_INPUTS=1 7 | SPLITROLES=0 8 | PROCESS_NUM=1 9 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/table9/README.md: -------------------------------------------------------------------------------- 1 | # Instructions 2 | 3 | Run all commands from the root directory of the repository. 4 | 5 | ## Setup 6 | 7 | Run the following commands on each node. 8 | 9 | ```sh 10 | export ITERATIONS=1 # replace with number of repeated executions you want to run 11 | export IP0=10.10.94.2 # replace with your IPs 12 | export IP1=10.10.94.3 13 | export IP2=10.10.94.4 14 | export IP3=10.10.94.5 15 | export PID=0 # replace with node id 16 | ``` 17 | 18 | ## Execution 19 | 20 | Run the following commands on each node. 21 | 22 | ### Execute Experiments 23 | This experiment requires a lot of processes and system RAM. If necessary, reduce the number of processes or input size, e.g. by adding PROCESS_NUM=1 SPLITROLES=0 after --override. 24 | 25 | ### Execute 3PC Experiments 26 | 27 | ```sh 28 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/table9 -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -p $PID --override PROTOCOL=5 29 | ``` 30 | 31 | ### Execute 4PC Experiments 32 | ```sh 33 | python3 measurements/run_config.py measurements/configs/artifacts/pigeon/table9 -i $ITERATIONS -a $IP0 -b $IP1 -c $IP2 -d $IP3 -p $PID --override PROTOCOL=12 34 | ``` 35 | 36 | 37 | ## Parse Results 38 | 39 | Run the following commands on each node. 40 | 41 | ```sh 42 | python3 measurements/parse_logs.py measurements/logs/ 43 | ``` 44 | 45 | ## Interpret Results 46 | 47 | Open the csv files after parsing results to obtain throughput. The Function identifiers map to the following CNNS: 48 | -180: AlexNet (CIFAR-10) 49 | -170: ResNet18 (CIFAR-10) 50 | -171: ResNet50 (CIFAR-10) 51 | -174: VGG-16 (CIFAR-10) 52 | -175: ResNet18 (ImageNet) 53 | -179: VGG-16 (ImageNet) 54 | 55 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/pigeon/table9/table9.conf: -------------------------------------------------------------------------------- 1 | PROTOCOL=5,12 2 | FUNCTION_IDENTIFIER=180,170,171,174,175,179 3 | BITLENGTH=64 4 | PRE=0 5 | DATTYPE=64 6 | NUM_INPUTS=1 7 | SPLITROLES=0 8 | PROCESS_NUM=1 9 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/truncation/figure14/figure14_32bit.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=171 2 | MODELOWNER=P_0 3 | DATAOWNER=P_1 4 | PROTOCOL=5 5 | BITLENGTH=32 6 | DATTYPE=32 7 | NUM_INPUTS=128 8 | FRACTIONAL=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=1 11 | TRUNC_THEN_MULT=0 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/truncation/figure14/figure14_weight_decay.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=171 2 | MODELOWNER=P_0 3 | DATAOWNER=P_1 4 | PROTOCOL=5 5 | BITLENGTH=32 6 | DATTYPE=32 7 | NUM_INPUTS=128 8 | FRACTIONAL=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=1 11 | TRUNC_THEN_MULT=0 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/truncation/figure15/figure15_16bit.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=182 2 | MODELOWNER=P_0 3 | DATAOWNER=P_1 4 | PROTOCOL=5 5 | BITLENGTH=16 6 | DATTYPE=16 7 | NUM_INPUTS=128 8 | FRACTIONAL=1,2,3,4,5,6,7 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=1 11 | TRUNC_THEN_MULT=0 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/truncation/figure15/figure15_32bit.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=182 2 | MODELOWNER=P_0 3 | DATAOWNER=P_1 4 | PROTOCOL=5 5 | BITLENGTH=32 6 | DATTYPE=256 7 | NUM_INPUTS=16 8 | FRACTIONAL=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=1 11 | TRUNC_THEN_MULT=0 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/truncation/figure16/figure16_32bit.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=171 2 | MODELOWNER=P_0 3 | DATAOWNER=P_1 4 | PROTOCOL=5 5 | BITLENGTH=32 6 | DATTYPE=256 7 | NUM_INPUTS=16 8 | FRACTIONAL=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=1 11 | TRUNC_THEN_MULT=0 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/truncation/figure16/figure16_64bit.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=171 2 | MODELOWNER=P_0 3 | DATAOWNER=P_1 4 | PROTOCOL=5 5 | BITLENGTH=64 6 | DATTYPE=64 7 | NUM_INPUTS=128 8 | FRACTIONAL=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=1 11 | TRUNC_THEN_MULT=0 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/truncation/figure17/figure17_32bit.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=186 2 | MODELOWNER=P_0 3 | DATAOWNER=P_1 4 | PROTOCOL=5 5 | BITLENGTH=32 6 | DATTYPE=256 7 | NUM_INPUTS=16 8 | FRACTIONAL=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=1 11 | TRUNC_THEN_MULT=0 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/truncation/figure17/figure17_64bit.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=186 2 | MODELOWNER=P_0 3 | DATAOWNER=P_1 4 | PROTOCOL=5 5 | BITLENGTH=64 6 | DATTYPE=64 7 | NUM_INPUTS=128 8 | FRACTIONAL=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=1 11 | TRUNC_THEN_MULT=0 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/truncation/machines.json: -------------------------------------------------------------------------------- 1 | [ 2 | ] 3 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/truncation/run_with_tmux_grid.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Parse -R and -g options 4 | EXTRA_ARGS=() 5 | 6 | while [[ $# -gt 0 ]]; do 7 | case $1 in 8 | -R|-g|--setup) 9 | EXTRA_ARGS+=("$1" "$2") 10 | shift 2 11 | ;; 12 | *) 13 | echo "Usage: $0 [-R value] [-g value] [--setup value]" 14 | exit 1 15 | ;; 16 | esac 17 | done 18 | 19 | # Function to build command and quote it safely 20 | build_cmd() { 21 | local machine_idx=$1 22 | local cmd=(python3 run_all_on_remote_servers.py -p "$machine_idx" "${EXTRA_ARGS[@]}") 23 | 24 | # Print command as a single string with proper quoting 25 | printf "%q " "${cmd[@]}" 26 | } 27 | 28 | # Kill existing tmux session if it exists 29 | tmux kill-session -t grid 2>/dev/null 30 | 31 | # Start a new tmux session named 'grid' 32 | tmux new-session -d -s grid 33 | 34 | # Split the window into a 2x2 grid and run the Python script for each machine 35 | tmux send-keys "$(build_cmd 0)" C-m # Machine 0 36 | tmux split-window -h 37 | tmux send-keys "$(build_cmd 1)" C-m # Machine 1 38 | tmux split-window -v 39 | tmux send-keys "$(build_cmd 2)" C-m # Machine 2 40 | tmux select-pane -t 0 41 | tmux split-window -v 42 | tmux send-keys "$(build_cmd 3)" C-m # Machine 3 43 | 44 | # Adjust layout to ensure a 2x2 grid 45 | tmux select-layout tiled 46 | 47 | # Attach to the tmux session 48 | tmux attach -t grid 49 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/truncation/table5/table5_32bit.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=174 2 | MODELOWNER=P_0 3 | DATAOWNER=P_1 4 | PROTOCOL=5 5 | BITLENGTH=32 6 | DATTYPE=256 7 | NUM_INPUTS=16 8 | FRACTIONAL=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=1 11 | TRUNC_THEN_MULT=0 12 | MSB0_OPT=0,1 13 | AVG_OPT=0,1 14 | SRNG_SEED=0 15 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/truncation/table6/table6_32bit.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=186 2 | MODELOWNER=-1 3 | DATAOWNER=-1 4 | PROTOCOL=5 5 | BITLENGTH=32 6 | DATTYPE=32 7 | NUM_INPUTS=1 8 | FRACTIONAL=10 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=0,1 11 | TRUNC_THEN_MULT=0 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/truncation/table6/table6_64bit.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=186 2 | MODELOWNER=-1 3 | DATAOWNER=-1 4 | PROTOCOL=5 5 | BITLENGTH=64 6 | DATTYPE=64 7 | NUM_INPUTS=1 8 | FRACTIONAL=10 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=0,1 11 | TRUNC_THEN_MULT=0 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/truncation/table8/table8_32bit.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=171,174,186 2 | MODELOWNER=-1 3 | DATAOWNER=-1 4 | PROTOCOL=5 5 | BITLENGTH=32 6 | DATTYPE=32 7 | NUM_INPUTS=1 8 | FRACTIONAL=10 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=1 11 | TRUNC_THEN_MULT=0 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/artifacts/truncation/table8/table8_64bit.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=171,174,186 2 | MODELOWNER=-1 3 | DATAOWNER=-1 4 | PROTOCOL=5 5 | BITLENGTH=64 6 | DATTYPE=64 7 | NUM_INPUTS=1 8 | FRACTIONAL=10 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=1 11 | TRUNC_THEN_MULT=0 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/benchmarks/DATTYPE.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=1 2 | PROTOCOL=1,2,3,4,5,6,7,8,9,10,11,12 3 | DATTYPE=1,8,16,32,64,128,256,512 4 | BITLENGTH=32 5 | PRE=0 6 | NUM_INPUTS=100 7 | -------------------------------------------------------------------------------- /measurements/configs/benchmarks/Multiprocesssing.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=1 2 | PROTOCOL=1,2,3,4,5,6,7,8,9,10,11,12 3 | PROCESS_NUM=1,4,8,12,16,20,24,28,32,36,40,44,48 4 | DATTYPE=512 5 | BITLENGTH=32 6 | PRE=0 7 | NUM_INPUTS=100 8 | -------------------------------------------------------------------------------- /measurements/configs/benchmarks/dot_fuse/DATTYPE.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=47 2 | PROTOCOL=5,12 3 | PROCESS_NUM=1 4 | DATTYPE=32,128,256 5 | BITLENGTH=32 6 | PRE=0 7 | NUM_INPUTS=224 8 | -------------------------------------------------------------------------------- /measurements/configs/benchmarks/dot_fuse/Multiprocesssing.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=47 2 | PROTOCOL=5,12 3 | PROCESS_NUM=1,4,8,12,16,20,24,28,32 4 | DATTYPE=256 5 | BITLENGTH=32 6 | PRE=0 7 | NUM_INPUTS=224 8 | -------------------------------------------------------------------------------- /measurements/configs/benchmarks/imagenetmodels.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=175,176,177,178,179 2 | MODELOWNER=-1 3 | DATAOWNER=-1 4 | PROTOCOL=5 5 | BITLENGTH=32 6 | DATTYPE=256 7 | NUM_INPUTS=1 8 | FRACTIONAL=5 9 | TRUNC_APPROACH=0 10 | TRUNC_DELAYED=0 11 | TRUNC_THEN_MULT=0 12 | -------------------------------------------------------------------------------- /measurements/configs/benchmarks/lenet.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=182 2 | MODELOWNER=-1 3 | DATAOWNER=-1 4 | PROTOCOL=5 5 | BITLENGTH=32 6 | DATTYPE=32 7 | NUM_INPUTS=1 8 | FRACTIONAL=5 9 | TRUNC_APPROACH=0 10 | TRUNC_DELAYED=0 11 | TRUNC_THEN_MULT=0 12 | -------------------------------------------------------------------------------- /measurements/configs/gpu_tests/test_cuda_matmul.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=57 2 | PROTOCOL=5,12 3 | DATTYPE=32 4 | BITLENGTH=32 5 | PRE=0 6 | USE_CUDA_GEMM=1,3 7 | -------------------------------------------------------------------------------- /measurements/configs/nn_tests/test_fractional_vs_accuracy_16.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=174 2 | MODELOWNER=P_0 3 | DATAOWNER=P_1 4 | PROTOCOL=5,12 5 | BITLENGTH=16 6 | DATTYPE=16 7 | NUM_INPUTS=128 8 | FRACTIONAL=1,2,3,4,5,6,7 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=0,1 11 | TRUNC_THEN_MULT=0,1 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/nn_tests/test_fractional_vs_accuracy_32.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=174 2 | MODELOWNER=P_0 3 | DATAOWNER=P_1 4 | PROTOCOL=5 5 | BITLENGTH=32 6 | DATTYPE=256 7 | NUM_INPUTS=16 8 | FRACTIONAL=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=0,1 11 | TRUNC_THEN_MULT=0,1 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/nn_tests/test_fractional_vs_accuracy_64.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=174 2 | MODELOWNER=P_0 3 | DATAOWNER=P_1 4 | PROTOCOL=5 5 | BITLENGTH=64 6 | DATTYPE=64 7 | NUM_INPUTS=128 8 | FRACTIONAL=1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30,31 9 | TRUNC_APPROACH=0,1,2,3,4 10 | TRUNC_DELAYED=0,1 11 | TRUNC_THEN_MULT=0,1 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/nn_tests/vgg16_accuracy.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=174 2 | MODELOWNER=P_0 3 | DATAOWNER=P_1 4 | PROTOCOL=5 5 | BITLENGTH=32 6 | DATTYPE=32 7 | NUM_INPUTS=100 8 | FRACTIONAL=5 9 | TRUNC_APPROACH=0 10 | TRUNC_DELAYED=0 11 | TRUNC_THEN_MULT=0 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/trunc_speed/test_truncation_speed16.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=70,71,74,80,81,82,85,86 2 | MODELOWNER=-1 3 | DATAOWNER=-1 4 | PROTOCOL=5,12 5 | BITLENGTH=16 6 | DATTYPE=16 7 | NUM_INPUTS=1,8 8 | PROCESS_NUM=1,16 9 | FRACTIONAL=3 10 | TRUNC_APPROACH=0,1,2,3,4 11 | TRUNC_DELAYED=0,1 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/trunc_speed/test_truncation_speed32.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=70,71,74,80,81,82,85,86 2 | MODELOWNER=-1 3 | DATAOWNER=-1 4 | PROTOCOL=5,12 5 | BITLENGTH=32 6 | DATTYPE=32 7 | NUM_INPUTS=1,8 8 | PROCESS_NUM=1,16 9 | FRACTIONAL=5 10 | TRUNC_APPROACH=0,1,2,3,4 11 | TRUNC_DELAYED=0,1 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/trunc_speed/test_truncation_speed64.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=70,71,74,80,81,82,85,86 2 | MODELOWNER=-1 3 | DATAOWNER=-1 4 | PROTOCOL=5,12 5 | BITLENGTH=64 6 | DATTYPE=64 7 | NUM_INPUTS=1,8 8 | PROCESS_NUM=1,16 9 | FRACTIONAL=14 10 | TRUNC_APPROACH=0,1,2,3,4 11 | TRUNC_DELAYED=0,1 12 | SRNG_SEED=0 13 | -------------------------------------------------------------------------------- /measurements/configs/unit_tests/test_all_primitives.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=60 2 | PROTOCOL=5,11,12 3 | DATTYPE=32 4 | BITLENGTH=32 5 | PRE=1 6 | -------------------------------------------------------------------------------- /measurements/configs/unit_tests/test_basic_primitives.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=54 2 | PROTOCOL=1,2,3,4,5,6,7,9,10,11,12 3 | DATTYPE=32 4 | BITLENGTH=32 5 | PRE=0 6 | -------------------------------------------------------------------------------- /measurements/configs/unit_tests/test_basic_primitives_pre.conf: -------------------------------------------------------------------------------- 1 | FUNCTION_IDENTIFIER=54 2 | PROTOCOL=5,8,11,12 3 | DATTYPE=32 4 | BITLENGTH=32 5 | PRE=1 6 | -------------------------------------------------------------------------------- /measurements/network_shaping/CMAN.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "CMAN", 3 | "latencies": [ 4 | [2.318, 1.244, 1.432], 5 | [2.394, 1.088, 2.020], 6 | [1.232, 1.091, 1.883], 7 | [1.418, 2.054, 1.892] 8 | ], 9 | "bandwidth": [ 10 | [137, 1532, 417], 11 | [139, 1144, 312], 12 | [1550, 1023, 602], 13 | [444, 389, 609] 14 | ] 15 | } 16 | 17 | -------------------------------------------------------------------------------- /measurements/network_shaping/LAN.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "LAN", 3 | "latencies": [ 4 | [0.304, 0.302, 0.291], 5 | [0.295, 0.285, 0.267], 6 | [0.304, 0.296, 0.178], 7 | [0.296, 0.265, 0.178] 8 | ], 9 | "bandwidth": [ 10 | [4880, 4870, 4890], 11 | [4940, 4920, 4940], 12 | [4790, 4800, 4810], 13 | [4900, 4890, 4910] 14 | ] 15 | } 16 | 17 | -------------------------------------------------------------------------------- /measurements/network_shaping/Mixed.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "Mixed", 3 | "latencies": [ 4 | [288.559, 89.244, 194.322], 5 | [291.132, 32.761, 204.447], 6 | [81.114, 35.041, 122.331], 7 | [193.446, 209.191, 127.073] 8 | ], 9 | "bandwidth": [ 10 | [113, 698, 271], 11 | [114, 875, 205], 12 | [681, 869, 582], 13 | [276, 207, 540] 14 | ] 15 | } 16 | 17 | -------------------------------------------------------------------------------- /measurements/network_shaping/WAN1.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WAN1", 3 | "latencies": [ 4 | [192.586, 49.311, 111.300], 5 | [186.628, 32.764, 164.242], 6 | [44.119, 34.772, 124.315], 7 | [103.893, 174.102, 120.835] 8 | ], 9 | "bandwidth": [ 10 | [143, 774, 541], 11 | [149, 868, 285], 12 | [790, 866, 201], 13 | [544, 260, 198] 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /measurements/network_shaping/WAN2.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "WAN2", 3 | "latencies": [ 4 | [91.451, 258.290, 276.367], 5 | [91.434, 165.687, 196.220], 6 | [253.818, 165.691, 101.163], 7 | [276.253, 196.132, 112.510] 8 | ], 9 | "bandwidth": [ 10 | [320, 121, 110], 11 | [341, 180, 154], 12 | [115, 186, 270], 13 | [109, 155, 271] 14 | ] 15 | } 16 | -------------------------------------------------------------------------------- /programs/benchmarks/bench_helper.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../datatypes/XOR_Share.hpp" 3 | // if placed after a function, gurantees that all parties have finished computation and communication 4 | template 5 | void dummy_reveal() 6 | { 7 | using S = XOR_Share; 8 | S dummy; 9 | dummy.prepare_reveal_to_all(); 10 | Share::communicate(); 11 | dummy.complete_reveal_to_all(); 12 | } 13 | -------------------------------------------------------------------------------- /programs/functions/adders/ppa.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../../datatypes/k_bitset.hpp" 3 | #include "../../../protocols/Protocols.h" 4 | 5 | template 6 | class PPA 7 | { 8 | using Bitset = sbitset_t; 9 | 10 | private: 11 | Bitset& a; 12 | Bitset& b; 13 | Bitset& sum; 14 | Bitset G; 15 | Bitset P; 16 | int level; 17 | int startPos; 18 | int step_length; 19 | 20 | public: 21 | // constructor 22 | 23 | void prepare_step() 24 | { 25 | startPos = 1 << level; 26 | step_length = 1 << (level + 1); 27 | bool first = true; 28 | for (int i = k - startPos; i >= 0; i -= step_length) 29 | { 30 | int lowWire = i + 1; 31 | int endPos = std::max(i - startPos + 1, 0); 32 | for (int curWire = i; curWire >= endPos; --curWire) 33 | { 34 | 35 | if (curWire < k - 1) 36 | { 37 | G[curWire] = (P[curWire] & G[lowWire]) ^ G[curWire]; 38 | } 39 | 40 | if (!first) 41 | { 42 | P[curWire] = P[lowWire] & P[curWire]; 43 | } 44 | } 45 | first = false; 46 | } 47 | } 48 | 49 | void complete_Step() 50 | { 51 | bool first = true; 52 | for (int i = k - startPos; i >= 0; i -= step_length) 53 | { 54 | int lowWire = i + 1; 55 | int endPos = std::max(i - startPos + 1, 0); 56 | for (int curWire = i; curWire >= endPos; --curWire) 57 | { 58 | 59 | if (curWire < k - 1) 60 | { 61 | G[curWire].complete_and(); 62 | } 63 | 64 | if (!first) 65 | { 66 | P[curWire].complete_and(); 67 | } 68 | } 69 | first = false; 70 | } 71 | level++; 72 | } 73 | 74 | void step() 75 | { 76 | const int log2k = std::ceil(std::log2(k)); 77 | switch (level) 78 | { 79 | case -2: 80 | for (int i = 1; i < k; ++i) 81 | { 82 | P[i] = a[i] ^ b[i]; 83 | G[i] = a[i] & b[i]; 84 | } 85 | P[0] = a[0] ^ b[0]; 86 | level++; 87 | break; 88 | case -1: 89 | for (int i = 1; i < k; ++i) 90 | G[i].complete_and(); 91 | level++; 92 | prepare_step(); 93 | break; 94 | default: 95 | complete_Step(); 96 | prepare_step(); 97 | break; 98 | case log2k - 1: 99 | complete_Step(); 100 | sum[BITLENGTH - 1] = P[k - 1]; 101 | for (int i = 0; i < k - 1; ++i) 102 | { 103 | sum[i] = (a[i] ^ b[i]) ^ G[i + 1]; 104 | } 105 | 106 | level = -3; 107 | break; 108 | } 109 | } 110 | 111 | PPA(Bitset& x0, Bitset& x1, Bitset& y0) : a(x0), b(x1), sum(y0) { level = -2; } 112 | 113 | int get_rounds() { return level; } 114 | 115 | int get_total_rounds() { return std::ceil(std::log2(k)) + 1; } 116 | 117 | bool is_done() { return level == -3; } 118 | }; 119 | -------------------------------------------------------------------------------- /programs/functions/adders/ppa_msb.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../../datatypes/k_bitset.hpp" 3 | #include "../../../protocols/Protocols.h" 4 | 5 | template 6 | class PPA_MSB 7 | { 8 | using Bitset = sbitset_t; 9 | 10 | private: 11 | Bitset& a; 12 | Bitset& b; 13 | Share& msb; 14 | Bitset G; 15 | Bitset P; 16 | int level; 17 | int startPos; 18 | int step_length; 19 | 20 | public: 21 | // constructor 22 | 23 | void prepare_step() 24 | { 25 | startPos = 1 << level; 26 | step_length = 1 << (level + 1); 27 | bool first = true; 28 | for (int i = startPos; i < k; i += step_length) 29 | { 30 | int lowWire = k - i; 31 | int curWire = std::max(lowWire - startPos, 1); 32 | 33 | if (curWire != lowWire) 34 | { 35 | // G1 = G1 ^ P_1 & G0 36 | G[curWire] = (P[curWire] & G[lowWire]) ^ G[curWire]; 37 | 38 | if (!first) 39 | { 40 | 41 | // P_1 = P_1 & P_0 42 | P[curWire] = P[lowWire] & P[curWire]; 43 | } 44 | 45 | first = false; 46 | } 47 | } 48 | } 49 | 50 | void complete_Step() 51 | { 52 | bool first = true; 53 | for (int i = startPos; i < k; i += step_length) 54 | { 55 | int lowWire = k - i; 56 | int curWire = std::max(lowWire - startPos, 1); 57 | 58 | if (curWire != lowWire) 59 | { 60 | // G1 = G1 ^ P_1 & G0 61 | G[curWire].complete_and(); 62 | 63 | if (!first) 64 | { 65 | 66 | // P_1 = P_1 & P_0 67 | P[curWire].complete_and(); 68 | } 69 | 70 | first = false; 71 | } 72 | } 73 | level++; 74 | } 75 | 76 | void step() 77 | { 78 | const int log2k = std::ceil(std::log2(k)); 79 | switch (level) 80 | { 81 | case -2: 82 | P[0] = a[0] ^ b[0]; 83 | for (int i = 1; i < k; ++i) 84 | { 85 | P[i] = a[i] ^ b[i]; 86 | /* G[i - 1] = a[i - 1] & b[i - 1]; */ 87 | G[i] = a[i] & b[i]; // possibly wrong and above is correct 88 | } 89 | level++; 90 | break; 91 | case -1: 92 | for (int i = 1; i < k; ++i) 93 | // G[i - 1].complete_and(); 94 | G[i].complete_and(); // possibly wrong and above is correct 95 | 96 | level++; 97 | prepare_step(); 98 | break; 99 | default: 100 | complete_Step(); 101 | prepare_step(); 102 | break; 103 | case log2k - 1: 104 | complete_Step(); 105 | msb = a[0] ^ b[0] ^ G[1]; 106 | level = -3; 107 | break; 108 | } 109 | } 110 | 111 | PPA_MSB(Bitset& x0, Bitset& x1, Share& y0) : a(x0), b(x1), msb(y0) { level = -2; } 112 | 113 | int get_rounds() { return level; } 114 | 115 | int get_total_rounds() { return std::ceil(std::log2(k)) + 1; } 116 | 117 | bool is_done() { return level == -3; } 118 | }; 119 | -------------------------------------------------------------------------------- /programs/functions/adders/ppa_msb_unsafe.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../../datatypes/k_bitset.hpp" 3 | #include "../../../protocols/Protocols.h" 4 | 5 | template 6 | class PPA_MSB_Unsafe 7 | { 8 | using Bitset = sbitset_t; 9 | 10 | private: 11 | Bitset& a; 12 | Bitset& b; 13 | Share& msb; 14 | int level; 15 | int startPos; 16 | int step_length; 17 | 18 | public: 19 | // constructor 20 | 21 | void prepare_step() 22 | { 23 | startPos = 1 << level; 24 | step_length = 1 << (level + 1); 25 | bool first = true; 26 | for (int i = startPos; i < k; i += step_length) 27 | { 28 | int lowWire = k - i; 29 | int curWire = std::max(lowWire - startPos, 1); 30 | 31 | if (curWire != lowWire) 32 | { 33 | // G1 = G1 ^ P_1 & G0 34 | b[curWire] = (a[curWire] & b[lowWire]) ^ b[curWire]; 35 | 36 | if (!first) 37 | { 38 | 39 | // P_1 = P_1 & P_0 40 | a[curWire] = a[lowWire] & a[curWire]; 41 | } 42 | 43 | first = false; 44 | } 45 | } 46 | } 47 | 48 | void complete_Step() 49 | { 50 | bool first = true; 51 | for (int i = startPos; i < k; i += step_length) 52 | { 53 | int lowWire = k - i; 54 | int curWire = std::max(lowWire - startPos, 1); 55 | 56 | if (curWire != lowWire) 57 | { 58 | // G1 = G1 ^ P_1 & G0 59 | b[curWire].complete_and(); 60 | 61 | if (!first) 62 | { 63 | 64 | // P_1 = P_1 & P_0 65 | a[curWire].complete_and(); 66 | } 67 | 68 | first = false; 69 | } 70 | } 71 | level++; 72 | } 73 | 74 | void step() 75 | { 76 | const int log2k = std::ceil(std::log2(k)); 77 | switch (level) 78 | { 79 | case -2: 80 | a[0] = a[0] ^ b[0]; 81 | msb = a[0]; 82 | for (int i = 1; i < k; ++i) 83 | { 84 | Share tmp = a[i] ^ b[i]; 85 | tmp = a[i] ^ b[i]; 86 | /* G[i - 1] = a[i - 1] & b[i - 1]; */ 87 | b[i] = a[i] & b[i]; // possibly wrong and above is correct 88 | a[i] = tmp; 89 | } 90 | level++; 91 | break; 92 | case -1: 93 | for (int i = 1; i < k; ++i) 94 | // G[i - 1].complete_and(); 95 | b[i].complete_and(); // possibly wrong and above is correct 96 | 97 | level++; 98 | prepare_step(); 99 | break; 100 | default: 101 | complete_Step(); 102 | prepare_step(); 103 | break; 104 | case log2k - 1: 105 | complete_Step(); 106 | msb = msb ^ b[1]; 107 | level = -3; 108 | break; 109 | } 110 | } 111 | 112 | PPA_MSB_Unsafe(Bitset& x0, Bitset& x1, Share& y0) : a(x0), b(x1), msb(y0) { level = -2; } 113 | 114 | int get_rounds() { return level; } 115 | 116 | int get_total_rounds() { return std::ceil(std::log2(k)) + 1; } 117 | 118 | bool is_done() { return level == -3; } 119 | }; 120 | -------------------------------------------------------------------------------- /programs/functions/adders/rca.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../../datatypes/k_bitset.hpp" 3 | #include "../../../protocols/Protocols.h" 4 | 5 | template 6 | class BooleanAdder 7 | { 8 | using Bitset = sbitset_t; 9 | 10 | private: 11 | int r; 12 | Bitset& x; 13 | Bitset& y; 14 | Bitset& z; 15 | Share carry_last; 16 | Share carry_this; 17 | 18 | public: 19 | // constructor 20 | 21 | BooleanAdder() { r = k; } 22 | 23 | BooleanAdder(Bitset& x0, Bitset& x1, Bitset& y0) : x(x0), y(x1), z(y0) { r = k; } 24 | 25 | void set_values(Bitset& x0, Bitset& x1, Bitset& y0) 26 | { 27 | x = x0; 28 | y = x1; 29 | z = y0; 30 | } 31 | 32 | int get_rounds() { return r; } 33 | 34 | int get_total_rounds() { return k; } 35 | 36 | bool is_done() { return r == 0; } 37 | 38 | void step() 39 | { 40 | r -= 1; 41 | switch (r) 42 | { 43 | case k - 1: // special case for lsbs 44 | z[k - 1] = x[k - 1] ^ y[k - 1]; 45 | carry_last = x[k - 1] & y[k - 1]; 46 | break; 47 | case k - 2: 48 | carry_last.complete_and(); // get carry from lsb 49 | update_z(); 50 | prepare_carry(); 51 | break; 52 | case 0: 53 | complete_carry(); 54 | update_z(); // no need to prepare another carry 55 | break; 56 | default: 57 | complete_carry(); // get carry from previous round 58 | update_z(); // update bit 59 | prepare_carry(); // prepare carry for next round 60 | break; 61 | } 62 | } 63 | 64 | void prepare_carry() { carry_this = (carry_last ^ x[r]) & (carry_last ^ y[r]); } 65 | 66 | void complete_carry() 67 | { 68 | carry_this.complete_and(); 69 | carry_this = carry_this ^ carry_last; 70 | carry_last = carry_this; 71 | } 72 | 73 | void update_z() { z[r] = x[r] ^ y[r] ^ carry_last; } 74 | }; 75 | -------------------------------------------------------------------------------- /programs/functions/adders/rca_msb.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../../datatypes/k_bitset.hpp" 3 | #include "../../../protocols/Protocols.h" 4 | 5 | template 6 | class BooleanAdder_MSB 7 | { 8 | using Bitset = sbitset_t; 9 | 10 | private: 11 | int r; 12 | Bitset& x; 13 | Bitset& y; 14 | Share& z; 15 | Share carry_last; 16 | Share carry_this; 17 | 18 | public: 19 | // constructor 20 | 21 | BooleanAdder_MSB() { r = k; } 22 | 23 | BooleanAdder_MSB(Bitset& x0, Bitset& x1, Share& y0) : x(x0), y(x1), z(y0) { r = k; } 24 | 25 | void set_values(Bitset& x0, Bitset& x1, Share& y0) 26 | { 27 | x = x0; 28 | y = x1; 29 | z = y0; 30 | } 31 | 32 | int get_rounds() { return r; } 33 | 34 | int get_total_rounds() { return k; } 35 | 36 | bool is_done() { return r == 0; } 37 | 38 | void step() 39 | { 40 | r -= 1; 41 | switch (r) 42 | { 43 | case k - 1: // special case for lsbs 44 | carry_last = x[k - 1] & y[k - 1]; 45 | break; 46 | case k - 2: 47 | carry_last.complete_and(); // get carry from lsb 48 | prepare_carry(); 49 | break; 50 | case 0: 51 | complete_carry(); 52 | update_z(); // final value, no need to prepare another carry 53 | break; 54 | default: 55 | complete_carry(); // get carry from previous round 56 | prepare_carry(); // prepare carry for next round 57 | break; 58 | } 59 | } 60 | 61 | void prepare_carry() { carry_this = (carry_last ^ x[r]) & (carry_last ^ y[r]); } 62 | 63 | void complete_carry() 64 | { 65 | carry_this.complete_and(); 66 | carry_this = carry_this ^ carry_last; 67 | carry_last = carry_this; 68 | } 69 | 70 | void update_z() { z = x[0] ^ y[0] ^ carry_last; } 71 | }; 72 | -------------------------------------------------------------------------------- /programs/functions/adders/rca_msb_carry.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../../datatypes/k_bitset.hpp" 3 | #include "../../../protocols/Protocols.h" 4 | 5 | template 6 | class BooleanAdder_MSB_Carry 7 | { 8 | using Bitset = sbitset_t; 9 | 10 | private: 11 | int r; 12 | Bitset& x; 13 | Bitset& y; 14 | Share carry_last; 15 | Share carry_this; 16 | Share msb; 17 | 18 | public: 19 | // constructor 20 | 21 | BooleanAdder_MSB_Carry() { r = k; } 22 | 23 | BooleanAdder_MSB_Carry(Bitset& x0, Bitset& x1) : x(x0), y(x1) { r = k; } 24 | 25 | #if TRUNC_DELAYED == 1 26 | Share get_msb() { return msb; } 27 | 28 | void update_msb() { msb = x[0] ^ y[0] ^ carry_last; } 29 | #endif 30 | void set_values(Bitset& x0, Bitset& x1) 31 | { 32 | x = x0; 33 | y = x1; 34 | } 35 | 36 | int get_rounds() { return r; } 37 | 38 | Share get_carry() { return carry_this; } 39 | 40 | int get_total_rounds() { return k; } 41 | 42 | bool is_done() { return r == -1; } 43 | 44 | template 2), int>::type = 0> 45 | void step() 46 | { 47 | r -= 1; 48 | 49 | switch (r) 50 | { 51 | case k - 1: // special case for lsbs 52 | carry_last = x[k - 1] & y[k - 1]; 53 | break; 54 | case k - 2: 55 | carry_last.complete_and(); // get carry from lsb 56 | prepare_carry(); 57 | break; 58 | case 0: 59 | complete_carry(); 60 | #if TRUNC_DELAYED == 1 61 | update_msb(); 62 | #endif 63 | prepare_carry(); 64 | break; 65 | case -1: 66 | complete_carry(); // get final carry 67 | break; 68 | default: 69 | complete_carry(); // get carry from previous round 70 | prepare_carry(); // prepare carry for next round 71 | break; 72 | } 73 | } 74 | 75 | template ::type = 0> 76 | void step() 77 | { 78 | r -= 1; 79 | 80 | switch (r) 81 | { 82 | case k - 1: // special case for lsbs 83 | carry_last = x[k - 1] & y[k - 1]; 84 | break; 85 | case k - 2: 86 | carry_last.complete_and(); // get carry from lsb 87 | #if TRUNC_DELAYED == 1 88 | update_msb(); 89 | #endif 90 | prepare_carry(); 91 | break; 92 | case -1: 93 | complete_carry(); // get final carry 94 | break; 95 | default: 96 | complete_carry(); // get carry from previous round 97 | prepare_carry(); // prepare carry for next round 98 | break; 99 | } 100 | } 101 | 102 | template ::type = 0> 103 | void step() 104 | { 105 | r -= 1; 106 | 107 | switch (r) 108 | { 109 | case k - 1: // special case for lsbs 110 | carry_last = x[k - 1] & y[k - 1]; 111 | break; 112 | case k - 2: 113 | carry_last.complete_and(); // get carry from lsb 114 | carry_this = carry_last; 115 | #if TRUNC_DELAYED == 1 116 | msb = x[0] ^ y[0]; 117 | #endif 118 | break; 119 | } 120 | } 121 | 122 | void prepare_carry() { carry_this = (carry_last ^ x[r]) & (carry_last ^ y[r]); } 123 | 124 | void complete_carry() 125 | { 126 | carry_this.complete_and(); 127 | carry_this = carry_this ^ carry_last; 128 | carry_last = carry_this; 129 | } 130 | }; 131 | -------------------------------------------------------------------------------- /programs/functions/comparisons.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "share_conversion.hpp" 3 | 4 | template 5 | void LTZ(sint_t>* val, sint_t>* result, const int len) 6 | { 7 | using S = XOR_Share; 8 | using A = Additive_Share; 9 | using Bitset = sbitset_t; 10 | using sint = sint_t; 11 | S* y = new S[len]; 12 | get_msb_range<0, k - m, Datatype, Share>(val, y, len); 13 | 14 | for (int i = 0; i < len; i++) 15 | { 16 | y[i].prepare_bit2a(result[i].get_share_pointer()); 17 | } 18 | delete[] y; 19 | Share::communicate(); 20 | for (int i = 0; i < len; i++) 21 | { 22 | result[i].complete_bit2a(); 23 | } 24 | } 25 | 26 | template 27 | void EQZ(sint_t>* val, sint_t>* result, const int len) 28 | { 29 | using S = XOR_Share; 30 | using A = Additive_Share; 31 | using Bitset = sbitset_t; 32 | using sint = sint_t; 33 | 34 | Share::communicate(); 35 | S* y = new S[len]; 36 | S* y_check = new S[len]; 37 | auto val_check = new sint[len]; 38 | for (int i = 0; i < len; i++) 39 | { 40 | val_check[i] = val[i] - sint(1); 41 | } 42 | get_msb_range(val, y, len); 43 | get_msb_range(val_check, y_check, len); 44 | for (int i = 0; i < len; i++) 45 | { 46 | y[i] = y[i] ^ y_check[i]; 47 | } 48 | 49 | delete[] y_check; 50 | 51 | for (int i = 0; i < len; i++) 52 | { 53 | y[i].prepare_bit2a(result[i].get_share_pointer()); 54 | } 55 | delete[] y; 56 | Share::communicate(); 57 | for (int i = 0; i < len; i++) 58 | { 59 | result[i].complete_bit2a(); 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /programs/functions/intersect_bool.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../datatypes/XOR_Share.hpp" 3 | #include "../../datatypes/k_bitset.hpp" 4 | template 5 | void intersect_bool(const sbitset_t>* a, 6 | const sbitset_t>* b, 7 | sbitset_t>* result, 8 | const int len_a, 9 | const int len_b) 10 | { 11 | using S = XOR_Share; 12 | using Bitset = sbitset_t; 13 | auto tmp = new Bitset[len_a * len_b]; 14 | 15 | assert(len_a <= len_b); 16 | for (int i = 0; i < len_a; i++) 17 | for (int j = 0; j < len_b; j++) 18 | tmp[i * len_b + j] = ~(a[i] ^ b[j]); // vals[i] == element 19 | 20 | for (int k = BITLENGTH >> 1; k > 0; k = k >> 1) 21 | { 22 | for (int i = 0; i < k; i++) 23 | { 24 | int j = i * 2; 25 | for (int s = 0; s < len_a; s++) 26 | { 27 | for (int t = 0; t < len_b; t++) 28 | tmp[s * len_b + t][i] = 29 | tmp[s * len_b + t][j] & 30 | tmp[s * len_b + t][j + 1]; // Only if all bits of the comparison are 1, the result should be 1 31 | } 32 | } 33 | 34 | Protocol::communicate(); 35 | 36 | for (int i = 0; i < k; i++) 37 | { 38 | for (int s = 0; s < len_a; s++) 39 | { 40 | for (int t = 0; t < len_b; t++) 41 | tmp[s * len_b + t][i].complete_and(); 42 | } 43 | } 44 | 45 | Protocol::communicate(); 46 | } 47 | 48 | auto intersect = new S[len_a]; 49 | 50 | for (int i = 0; i < len_a; i++) 51 | { 52 | intersect[i] = SET_ALL_ZERO(); 53 | for (int j = 1; j < len_b; j++) 54 | intersect[i] = 55 | intersect[i] ^ 56 | tmp[i * len_b + j] 57 | [0]; // intersect is 1 if element has been found in any of the comparisons (assumes no duplicates) 58 | } 59 | 60 | for (int i = 0; i < len_a; i++) 61 | for (int k = 0; k < BITLENGTH; k++) 62 | result[i][k] = a[i][k] & intersect[i]; // store element as a result if it has been found, otherwise 0 63 | Protocol::communicate(); 64 | for (int i = 0; i < len_a; i++) 65 | for (int k = 0; k < BITLENGTH; k++) 66 | result[i][k].complete_and(); 67 | 68 | delete[] tmp; 69 | delete[] intersect; 70 | } 71 | -------------------------------------------------------------------------------- /programs/functions/prob_div.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../config.h" 3 | #include "../../datatypes/float_fixed_converter.hpp" 4 | 5 | template 6 | void prepare_prob_div(T& out, const int denominator, const int frac_bits = FRACTIONAL) 7 | { 8 | #if TRUNC_APPROACH == 0 || TRUNC_APPROACH == 4 9 | #if TRUNC_APPROACH == 0 10 | out = 11 | out.prepare_mult_public_fixed(FloatFixedConverter::float_to_ufixed( 12 | 1 / FLOATTYPE(denominator), frac_bits), 13 | frac_bits); 14 | #elif TRUNC_APPROACH == 4 15 | /* if(frac_bits <= FRACTIONAL / 2) */ 16 | out = 17 | out.prepare_mult_public_fixed(FloatFixedConverter::float_to_ufixed( 18 | 1 / FLOATTYPE(denominator), frac_bits), 19 | frac_bits); 20 | /* else */ 21 | /* out = out.mult_public(FloatFixedConverter::float_to_ufixed(1/float(denominator),frac_bits)); */ 23 | #endif 24 | #else 25 | out = out.mult_public(FloatFixedConverter::float_to_ufixed( 26 | 1 / FLOATTYPE(denominator), frac_bits)); 27 | #endif 28 | } 29 | 30 | template 31 | void complete_prob_div(T& out, const int len, const int denominator, const int frac_bits = FRACTIONAL) 32 | { 33 | 34 | #if TRUNC_APPROACH == 0 || TRUNC_APPROACH == 4 35 | #if TRUNC_APPROACH == 0 36 | for (int i = 0; i < len; i++) 37 | out[i].complete_public_mult_fixed(); 38 | #elif TRUNC_APPROACH == 4 39 | /* if (frac_bits <= FRACTIONAL / 2) */ 40 | /* { */ 41 | for (int i = 0; i < len; i++) 42 | out[i].complete_public_mult_fixed(); 43 | /* } */ 44 | /* else */ 45 | /* trunc_2k_in_place(out, len, true, frac_bits); */ 46 | #endif 47 | #else 48 | #if TRUNC_APPROACH == 1 49 | trunc_2k_in_place(out, len, all_positive, frac_bits); 50 | #elif TRUNC_APPROACH == 2 51 | trunc_exact_in_place(out, len, frac_bits); 52 | #elif TRUNC_APPROACH == 3 53 | trunc_exact_opt_in_place(out, len, all_positive, frac_bits); 54 | #endif 55 | #endif 56 | } 57 | -------------------------------------------------------------------------------- /programs/functions/prob_truncation.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../datatypes/Additive_Share.hpp" 3 | template 4 | static void trunc_2k_in_place(T* val, const int len, bool isPositive = false, int fractional_bits = FRACTIONAL) 5 | { 6 | 7 | #if MSB0_OPT == 1 8 | if (!isPositive) 9 | #endif 10 | for (int i = 0; i < len; i++) 11 | val[i] = val[i] + T((UINT_TYPE(1) << (BITLENGTH - 1))); // add 2^l-1 to gurantee positive number 12 | T* r_msb = new T[len]; 13 | T* r_mk2 = new T[len]; 14 | T* c = new T[len]; 15 | T* c_prime = new T[len]; 16 | T::communicate(); 17 | for (int i = 0; i < len; i++) 18 | { 19 | val[i].prepare_trunc_2k_inputs(r_mk2[i], r_msb[i], c[i], c_prime[i], fractional_bits); 20 | } 21 | T::communicate(); 22 | for (int i = 0; i < len; i++) 23 | { 24 | val[i].complete_trunc_2k_inputs(r_mk2[i], r_msb[i], c[i], c_prime[i]); 25 | } 26 | T::communicate(); 27 | T* b = new T[len]; 28 | for (int i = 0; i < len; i++) 29 | b[i].prepare_XOR(r_msb[i], c[i]); 30 | T::communicate(); 31 | for (int i = 0; i < len; i++) 32 | { 33 | b[i].complete_XOR(r_msb[i], c[i]); 34 | b[i] = b[i].mult_public(UINT_TYPE(1) << (BITLENGTH - fractional_bits - 1)); 35 | } 36 | T::communicate(); 37 | delete[] c; 38 | 39 | for (int i = 0; i < len; i++) 40 | { 41 | val[i] = c_prime[i] + b[i] - r_mk2[i]; 42 | } 43 | 44 | #if MSB0_OPT == 1 45 | if (!isPositive) 46 | #endif 47 | for (int i = 0; i < len; i++) 48 | val[i] = 49 | val[i] - 50 | T((UINT_TYPE(1) << (BITLENGTH - fractional_bits - 1))); // substract 2^l-1 to reverse previous addition 51 | 52 | delete[] r_mk2; 53 | delete[] r_msb; 54 | delete[] c_prime; 55 | delete[] b; 56 | } 57 | 58 | template 59 | static void trunc_pr_in_place(T* val, const int len) 60 | { 61 | for (int i = 0; i < len; i++) 62 | { 63 | val[i] *= UINT_TYPE(1); 64 | /* val[i].prepare_trunc_share(); // Worth to try out */ 65 | } 66 | T::communicate(); 67 | for (int i = 0; i < len; i++) 68 | { 69 | val[i].complete_public_mult_fixed(); 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /programs/functions/search_bool.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../datatypes/k_bitset.hpp" 3 | #include "../../protocols/Protocols.h" 4 | #include "../../protocols/XOR_Share.hpp" 5 | #define FUNCTION search 6 | #define RESULTTYPE DATATYPE 7 | 8 | void print_result(DATATYPE* var) 9 | { 10 | printf("P%i: Result: ", PARTY); 11 | uint8_t v8val[sizeof(DATATYPE)]; 12 | std::memcpy(v8val, var, sizeof(v8val)); 13 | for (uint i = sizeof(DATATYPE); i > 0; i--) 14 | std::cout << std::bitset(v8val[i - 1]); 15 | printf("\n"); 16 | } 17 | 18 | template 19 | void search(/*outputs*/ DATATYPE* found) 20 | { 21 | using S = XOR_Share; 22 | using Bitset = sbitset_t; 23 | 24 | /* S (*dataset)[BITLENGTH] = new S [NUM_INPUTS][BITLENGTH]; */ 25 | /* S *element = new S[BITLENGTH]; */ 26 | Bitset* dataset = new Bitset[NUM_INPUTS]; 27 | Bitset element; 28 | 29 | /* Share (*dataset)[BITLENGTH] = (Share ((*)[BITLENGTH])) new Share[((int) NUM_INPUTS)*BITLENGTH]; */ 30 | /* Share* element = new Share[BITLENGTH]; */ 31 | 32 | for (int i = 0; i < NUM_INPUTS; i++) 33 | dataset[i].template prepare_receive_from(); 34 | 35 | element.template prepare_receive_from(); 36 | 37 | Protocol::communicate(); 38 | 39 | for (int i = 0; i < NUM_INPUTS; i++) 40 | dataset[i].template complete_receive_from(); 41 | 42 | element.template complete_receive_from(); 43 | 44 | for (int i = 0; i < NUM_INPUTS; i++) 45 | { 46 | dataset[i] = ~(dataset[i] ^ element); 47 | } 48 | 49 | for (int k = BITLENGTH >> 1; k > 0; k = k >> 1) 50 | { 51 | for (int i = 0; i < k; i++) 52 | { 53 | int j = i * 2; 54 | for (int s = 0; s < NUM_INPUTS; s++) 55 | { 56 | dataset[s][i] = dataset[s][j] & dataset[s][j + 1]; 57 | } 58 | } 59 | 60 | Protocol::communicate(); 61 | 62 | for (int i = 0; i < k; i++) 63 | { 64 | for (int s = 0; s < NUM_INPUTS; s++) 65 | { 66 | dataset[s][i].complete_and(); 67 | } 68 | } 69 | 70 | Protocol::communicate(); 71 | } 72 | 73 | for (int i = 1; i < NUM_INPUTS; i++) 74 | { 75 | dataset[0][0] = dataset[i][0] ^ dataset[0][0]; 76 | } 77 | 78 | dataset[0][0].prepare_reveal_to_all(); 79 | 80 | Protocol::communicate(); 81 | 82 | *found = dataset[0][0].complete_reveal_to_all(); 83 | 84 | Protocol::communicate(); 85 | } 86 | -------------------------------------------------------------------------------- /programs/mp-spdz_interpreter_template.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../MP-SPDZ/lib/Machine.hpp" 4 | #include "../MP-SPDZ/lib/Shares/CInteger.hpp" 5 | #include "../MP-SPDZ/lib/Shares/Integer.hpp" 6 | #include "../datatypes/k_bitset.hpp" 7 | #include "../datatypes/k_sint.hpp" 8 | #include "../protocols/Additive_Share.hpp" 9 | #include "../protocols/Protocols.h" 10 | #include "../protocols/XOR_Share.hpp" 11 | #include "../utils/print.hpp" 12 | #include 13 | 14 | #if FUNCTION_IDENTIFIER == 0 // replace with actual number 15 | #define FUNCTION example // replace with function name 16 | #endif 17 | 18 | // Boilerplate 19 | #define RESULTTYPE DATATYPE 20 | void generateElements() {} 21 | 22 | #if FUNCTION_IDENTIFIER == 0 23 | 24 | template 25 | void example(DATATYPE* res) 26 | { 27 | using cint = IR::CInteger; 28 | using int_t = IR::Integer; 29 | 30 | using S = XOR_Share; 31 | 32 | using A = Additive_Share; 33 | 34 | IR::Machine m(""); // replace with actual path 35 | m.run(); 36 | } 37 | 38 | #endif 39 | -------------------------------------------------------------------------------- /programs/tests/test_all.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #define FUNCTION test_all 3 | #include "test_basic_primitives.hpp" 4 | #include "test_comparisons.hpp" 5 | #include "test_fixed_point_arithmetic.hpp" 6 | #include "test_mat_mul.hpp" 7 | #include "test_multi_input.hpp" 8 | #include "test_truncation.hpp" 9 | 10 | template 11 | void test_all(DATATYPE* res) 12 | { 13 | std::vector test_names = {"Basic Primitives", 14 | "Comparisons", 15 | "Fixed Point Arithmetic", 16 | "Matrix Multiplication", 17 | "Multi Input Operations", 18 | "Truncation"}; 19 | std::vector test_results; 20 | test_results.push_back(test_basic_primitives(res)); 21 | test_results.push_back(test_comparisons(res)); 22 | test_results.push_back(test_fixed_point_arithmetic(res)); 23 | test_results.push_back(test_mat_mul(res)); 24 | test_results.push_back(test_multi_input(res)); 25 | test_results.push_back(test_truncation(res)); 26 | for (int i = 0; i < test_results.size(); i++) 27 | { 28 | if (test_results[i]) 29 | { 30 | print_online("All tests in the category " + test_names[i] + " passed!"); 31 | } 32 | else 33 | { 34 | print_online("Some tests in the category " + test_names[i] + " failed!"); 35 | } 36 | } 37 | } 38 | -------------------------------------------------------------------------------- /programs/tests/test_helper.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../datatypes/Additive_Share.hpp" 3 | const float epsilon = 0.8; 4 | template 5 | void test_function(int& num_tests, int& num_passed, std::string name, FUNC f) 6 | { 7 | print_online("Testing " + name + " ..."); 8 | num_tests++; 9 | if (f()) 10 | { 11 | num_passed++; 12 | print_online(name + " Passed!") 13 | } 14 | else 15 | { 16 | print_online(name + " Failed!") 17 | } 18 | } 19 | 20 | void print_stats(int num_tests, int num_passed) 21 | { 22 | print_online("Passed " + std::to_string(num_passed) + " out of " + std::to_string(num_tests) + " tests."); 23 | } 24 | 25 | void print_compare(int expected, int got) 26 | { 27 | print_online("Expected: " + std::to_string(expected) + " Got: " + std::to_string(got)); 28 | } 29 | 30 | void print_compare(float expected, float got, float epsilon) 31 | { 32 | print_online("Expected: " + std::to_string(expected) + " Got: " + std::to_string(got) + 33 | " Epsilon: " + std::to_string(epsilon)); 34 | } 35 | 36 | template 37 | void reveal_and_store(T share[], UINT_TYPE output[][DATTYPE / BITLENGTH], const int len) 38 | { 39 | for (int i = 0; i < len; i++) 40 | { 41 | DATATYPE temp; 42 | share[i].prepare_reveal_to_all(); 43 | T::communicate(); 44 | temp = share[i].complete_reveal_to_all(); 45 | unorthogonalize_arithmetic(&temp, &output[i][0], 1); 46 | } 47 | } 48 | -------------------------------------------------------------------------------- /programs/tutorials/YourFirstProgram.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | // === Include the predefined datatypes that you need === 4 | #include "../../datatypes/Additive_Share.hpp" // Additive_Share is a datatype that stores secret shares in the arithmetic domain 5 | // ... 6 | // === Include the predefined functions that you need === 7 | #include "../functions/GEMM.hpp" 8 | // ... 9 | 10 | // === Define the main entry point and resulttype of your program === 11 | #define FUNCTION YourFirstProgram // define your main entry point 12 | #define RESULTTYPE \ 13 | DATATYPE // Each main function should define this to make a result accessible after the MPC protocol has finished 14 | 15 | // === Start writing your program === 16 | template // Share is defined by the MPC protocol specified in config.h 17 | void YourFirstProgram( 18 | DATATYPE* res) // The main entry pint needs to define a result pointer, DATATYPE is specified in config.h 19 | { 20 | using A = Additive_Share; 21 | // ... 22 | // Your code goes here 23 | } 24 | -------------------------------------------------------------------------------- /programs/tutorials/fixed_point_tutorial.hpp: -------------------------------------------------------------------------------- 1 | #include "../../datatypes/Additive_Share.hpp" 2 | #include "../../datatypes/XOR_Share.hpp" 3 | #include "../../datatypes/float_fixed_converter.hpp" 4 | #include "../functions/prob_div.hpp" // The functions directory contains multiple high-level MPC primitives 5 | #define RESULTTYPE \ 6 | DATATYPE // Each main function should define this to make a result accessible after the MPC protocol has finished 7 | #define FUNCTION Fixed_Point_Tutorial // define your main entry point 8 | 9 | template 10 | void Fixed_Point_Tutorial(DATATYPE* res) 11 | { 12 | using A = Additive_Share; 13 | const int vectorization_factor = DATTYPE / BITLENGTH; 14 | 15 | //---------------------------------// 16 | // Secret Sharing 17 | UINT_TYPE fixed_point_value = FloatFixedConverter::float_to_ufixed( 18 | 3.5f); // Plaintext fixed point value with FRACTIONAL bits of precision, defined in config.h 19 | A fixed_point_secret; 20 | fixed_point_secret.template prepare_receive_from( 21 | PROMOTE(fixed_point_value)); // After conversion, fixed point values can ban be treated as integers 22 | Share::communicate(); 23 | fixed_point_secret.template complete_receive_from(); 24 | 25 | //---------------------------------// 26 | // Fixed Point Operations 27 | 28 | A result = fixed_point_secret + fixed_point_secret; // Addition 29 | result = result - fixed_point_secret; // Subtraction 30 | 31 | // Fixed Point Multiplication 32 | result = result.prepare_dot(fixed_point_secret); // Local dot product computation 33 | result.mask_and_send_dot(); // Mask and Send Dot Product, applies truncation 34 | Share::communicate(); 35 | result.complete_mult(); // Complete multiplication with truncation 36 | 37 | // Multiplication with public fixed point values 38 | UINT_TYPE public_fixed_point_value = 39 | FloatFixedConverter::float_to_ufixed(2.5f); 40 | result = result.prepare_mult_public_fixed( 41 | public_fixed_point_value); // While public integer values can be multiplied without communication, multiplying 42 | // a secret with a public fixed point values requires communication 43 | Share::communicate(); 44 | result.complete_public_mult_fixed(); // Complete multiplication with a public fixed point value 45 | // Division with public values 46 | UINT_TYPE reciprocal = FloatFixedConverter::float_to_ufixed( 47 | 1 / 2.5f); // simply invert the fixed point value and multiply 48 | result = result.prepare_mult_public_fixed(reciprocal); 49 | Share::communicate(); 50 | result.complete_public_mult_fixed(); 51 | 52 | //---------------------------------// 53 | // Reveal the result 54 | UINT_TYPE output_vectorized[vectorization_factor]; 55 | float converted_output[vectorization_factor]; 56 | DATATYPE output; 57 | result.prepare_reveal_to_all(); 58 | Share::communicate(); 59 | output = result.complete_reveal_to_all(); 60 | unorthogonalize_arithmetic(&output, output_vectorized, 1); 61 | for (int i = 0; i < vectorization_factor; i++) 62 | converted_output[i] = FloatFixedConverter::ufixed_to_float( 63 | output_vectorized[i]); // Convert the fixed point value back to a floating point value 64 | } 65 | -------------------------------------------------------------------------------- /programs/tutorials/matrix_operations_tutorial.hpp: -------------------------------------------------------------------------------- 1 | #include "../../datatypes/Additive_Share.hpp" 2 | #include "../../datatypes/XOR_Share.hpp" 3 | #include "../../datatypes/float_fixed_converter.hpp" 4 | #include "../functions/GEMM.hpp" 5 | 6 | #define RESULTTYPE DATATYPE 7 | #define FUNCTION Matrix_Operations_Tutorial 8 | 9 | template 10 | void Matrix_Operations_Tutorial(DATATYPE* res) 11 | { 12 | using A = Additive_Share; 13 | using S = XOR_Share; 14 | const int vectorization_factor = DATTYPE / BITLENGTH; 15 | //---------------------------------// 16 | // The ABG programming model 17 | // The Framework switches between arithemtic vectorization for arithemtic operations and Bitslicing for boolean 18 | // operations. For matrix operations we also provide support for GPU acceleration.This feature is optional and can 19 | // be enabled by setting USE_CUDA_GEMM to > 0. 20 | 21 | const int m = 3; 22 | const int k = 2; 23 | const int n = 1; 24 | float x[m * k] = {3.2, 5.4, 7.6, 11.8, 2.1, 4.3}; 25 | float w[k * n] = {2.1, 4.3}; 26 | float y[m * n] = {0}; 27 | auto X = new A[m * k]; 28 | for (int i = 0; i < m * k; i++) 29 | { 30 | X[i] = A(FloatFixedConverter::float_to_ufixed(x[i])); 31 | } 32 | auto W = new A[k * n]; 33 | for (int i = 0; i < k * n; i++) 34 | { 35 | W[i] = A(FloatFixedConverter::float_to_ufixed(w[i])); 36 | } 37 | 38 | auto Y = new A[m * n]{A(0)}; 39 | 40 | Share::communicate(); 41 | 42 | prepare_GEMM(X, W, Y, m, n, k, false); // automatically uses CPU or GPU depending on the configuration 43 | Share::communicate(); 44 | complete_GEMM(Y, m * n); 45 | } 46 | -------------------------------------------------------------------------------- /protocols/2-PC/aby2_dummy/aby2_init.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../generic_share.hpp" 3 | #include 4 | template 5 | class ABY2_init 6 | { 7 | private: 8 | public: 9 | ABY2_init() {} 10 | 11 | template 12 | ABY2_init mult_public(const Datatype b, func_mul MULT) const 13 | { 14 | return ABY2_init(); 15 | } 16 | 17 | // Fake triple: 18 | Datatype getFakeBeaverShare() const 19 | { 20 | #if PRE == 1 && HAS_POST_PROTOCOL == 1 21 | store_output_share_(); 22 | #endif 23 | return SET_ALL_ZERO(); 24 | } 25 | 26 | void getFakeRandomVal() const 27 | { 28 | #if PRE == 1 && HAS_POST_PROTOCOL == 1 29 | store_output_share_(); 30 | #endif 31 | } 32 | 33 | // P_i shares mx - lxi, P_j sets lxj to 0 34 | template 35 | void prepare_receive_from(Datatype val, func_add ADD, func_sub SUB) 36 | { 37 | if constexpr (id == PSELF) 38 | { 39 | getFakeRandomVal(); 40 | send_to_(PNEXT); 41 | } 42 | } 43 | 44 | template 45 | void complete_receive_from(func_add ADD, func_sub SUB) 46 | { 47 | if constexpr (id != PSELF) 48 | receive_from_(id); 49 | } 50 | 51 | template 52 | ABY2_init Add(ABY2_init b, func_add ADD) const 53 | { 54 | return ABY2_init(); 55 | } 56 | 57 | void prepare_reveal_to_all() const 58 | { 59 | #if PRE == 0 60 | send_to_(PNEXT); 61 | #else 62 | pre_send_to_(PNEXT); 63 | #endif 64 | } 65 | 66 | template 67 | Datatype complete_Reveal(func_add ADD, func_sub SUB) const 68 | { 69 | /* #if PRE == 1 && HAS_POST_PROTOCOL == 1 */ 70 | /* store_output_share_(); */ 71 | /* #endif */ 72 | #if PRE == 0 73 | receive_from_(PNEXT); 74 | #else 75 | pre_receive_from_(PNEXT); 76 | #endif 77 | return SET_ALL_ZERO(); 78 | } 79 | 80 | template 81 | ABY2_init prepare_mult(ABY2_init b, func_add ADD, func_sub SUB, func_mul MULT) const 82 | { 83 | ABY2_init c; 84 | getFakeRandomVal(); 85 | getFakeBeaverShare(); 86 | send_to_(PNEXT); 87 | return c; 88 | } 89 | 90 | template 91 | void complete_mult(func_add ADD, func_sub SUB) 92 | { 93 | receive_from_(PPREV); 94 | } 95 | 96 | ABY2_init public_val(Datatype a) { return ABY2_init(); } 97 | 98 | ABY2_init Not() const { return ABY2_init(); } 99 | 100 | static void send() { send_(); } 101 | static void receive() { receive_(); } 102 | static void communicate() { communicate_(); } 103 | 104 | static void finalize(std::string* ips) { finalize_(ips); } 105 | 106 | static void finalize(std::string* ips, receiver_args* ra, sender_args* sa) { finalize_(ips, ra, sa); } 107 | }; 108 | -------------------------------------------------------------------------------- /protocols/2-PC/aby2_dummy/aby2_post.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../generic_share.hpp" 3 | #include 4 | template 5 | class ABY2_POST_Share 6 | { 7 | private: 8 | Datatype m; 9 | Datatype l; 10 | 11 | public: 12 | ABY2_POST_Share() {} 13 | ABY2_POST_Share(Datatype l) { this->l = l; } 14 | ABY2_POST_Share(Datatype x, Datatype l) 15 | { 16 | this->m = x; 17 | this->l = l; 18 | } 19 | 20 | template 21 | ABY2_POST_Share mult_public(const Datatype b, func_mul MULT) const 22 | { 23 | return ABY2_POST_Share(MULT(m, b), MULT(l, b)); 24 | } 25 | 26 | // Fake triple: 27 | Datatype getFakeBeaverShare(Datatype al, Datatype bl) const { return retrieve_output_share(); } 28 | 29 | Datatype getFakeRandomVal(int id) const { return retrieve_output_share(); } 30 | 31 | // P_i shares mx - lxi, P_j sets lxj to 0 32 | template 33 | void prepare_receive_from(Datatype val, func_add ADD, func_sub SUB) 34 | { 35 | if constexpr (id == PSELF) 36 | { 37 | l = getFakeRandomVal(id); 38 | m = ADD(val, l); 39 | send_to_live(PNEXT, m); 40 | } 41 | else 42 | l = SET_ALL_ZERO(); 43 | } 44 | 45 | template 46 | void complete_receive_from(func_add ADD, func_sub SUB) 47 | { 48 | if constexpr (id != PSELF) 49 | m = receive_from_live(id); 50 | } 51 | 52 | template 53 | ABY2_POST_Share Add(ABY2_POST_Share b, func_add ADD) const 54 | { 55 | return ABY2_POST_Share(ADD(m, b.m), ADD(l, b.l)); 56 | } 57 | 58 | void prepare_reveal_to_all() const {} 59 | 60 | template 61 | Datatype complete_Reveal(func_add ADD, func_sub SUB) const 62 | { 63 | return SUB(m, ADD(pre_receive_from_live(PNEXT), l)); 64 | } 65 | 66 | template 67 | ABY2_POST_Share prepare_mult(ABY2_POST_Share b, func_add ADD, func_sub SUB, func_mul MULT) const 68 | { 69 | ABY2_POST_Share c; 70 | Datatype lalb = getFakeBeaverShare(l, b.l); // Fake triple 71 | c.l = getFakeRandomVal(PSELF); // get new mask 72 | Datatype msg = ADD(ADD(ADD(MULT(m, b.l), MULT(l, b.m)), lalb), c.l); 73 | send_to_live(PNEXT, msg); 74 | c.m = SUB(MULT(m, b.m), msg); 75 | return c; 76 | } 77 | 78 | template 79 | void complete_mult(func_add ADD, func_sub SUB) 80 | { 81 | Datatype msg = receive_from_live(PPREV); 82 | m = SUB(m, msg); 83 | } 84 | 85 | ABY2_POST_Share public_val(Datatype a) { return ABY2_POST_Share(a, SET_ALL_ZERO()); } 86 | 87 | ABY2_POST_Share Not() const { return ABY2_POST_Share(NOT(m), l); } 88 | 89 | static void send() { send_live(); } 90 | 91 | static void receive() { receive_live(); } 92 | 93 | static void communicate() { communicate_live(); } 94 | }; 95 | -------------------------------------------------------------------------------- /protocols/3-PC/astra/astra-P_1_template.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../generic_share.hpp" 3 | template 4 | class ASTRA1_Share 5 | { 6 | Datatype mv; 7 | Datatype lv; 8 | 9 | public: 10 | ASTRA1_Share() {} 11 | ASTRA1_Share(Datatype a, Datatype b) 12 | { 13 | mv = a; 14 | lv = b; 15 | } 16 | 17 | ASTRA1_Share public_val(Datatype a) { return ASTRA1_Share(a, SET_ALL_ZERO()); } 18 | 19 | ASTRA1_Share Not() const { return ASTRA1_Share(NOT(mv), lv); } 20 | 21 | template 22 | ASTRA1_Share Add(ASTRA1_Share b, func_add ADD) const 23 | { 24 | return ASTRA1_Share(ADD(mv, b.mv), lv); 25 | } 26 | 27 | template 28 | ASTRA1_Share prepare_mult(ASTRA1_Share b, func_add ADD, func_sub SUB, func_mul MULT) const 29 | { 30 | ASTRA1_Share c; 31 | Datatype yz1 = getRandomVal(P_0); // yz1 32 | Datatype yxy1 = getRandomVal(P_0); 33 | c.mv = SUB(ADD(yz1, yxy1), ADD(MULT(mv, b.lv), MULT(b.mv, lv))); 34 | c.lv = yz1; 35 | send_to_live(P_2, c.mv); 36 | return c; 37 | } 38 | template 39 | ASTRA1_Share prepare_dot(const ASTRA1_Share b, func_add ADD, func_sub SUB, func_mul MULT) const 40 | { 41 | ASTRA1_Share c; 42 | c.mv = ADD(MULT(mv, b.lv), MULT(b.mv, lv)); 43 | return c; 44 | } 45 | 46 | template 47 | void mask_and_send_dot(func_add ADD, func_sub SUB) 48 | { 49 | Datatype yz1 = getRandomVal(P_0); // yz1 50 | Datatype yxy1 = getRandomVal(P_0); 51 | mv = SUB(ADD(yz1, yxy1), mv); 52 | lv = yz1; 53 | send_to_live(P_2, mv); 54 | } 55 | 56 | template 57 | void complete_mult(func_add ADD, func_sub SUB) 58 | { 59 | // a.p2 already set in last round 60 | mv = ADD(mv, receive_from_live(P_2)); 61 | } 62 | 63 | void prepare_reveal_to_all() const {} 64 | 65 | template 66 | Datatype complete_Reveal(func_add ADD, func_sub SUB) const 67 | { 68 | return SUB(mv, receive_from_live(P_0)); 69 | } 70 | 71 | template 72 | void prepare_receive_from(Datatype val, func_add ADD, func_sub SUB) 73 | { 74 | if constexpr (id == P_0) 75 | { 76 | lv = getRandomVal(P_0); 77 | } 78 | else if constexpr (id == P_1) // -> lv = lv2, lv1=0 79 | { 80 | lv = getRandomVal(P_0); 81 | mv = ADD(val, lv); 82 | send_to_live(P_2, mv); 83 | } 84 | } 85 | 86 | template 87 | ASTRA1_Share mult_public(const Datatype b, func_mul MULT) const 88 | { 89 | return ASTRA1_Share(MULT(mv, b), MULT(lv, b)); 90 | } 91 | 92 | template 93 | void complete_receive_from(func_add ADD, func_sub SUB) 94 | { 95 | if constexpr (id == P_0) 96 | { 97 | #if OPT_SHARE == 1 98 | mv = SET_ALL_ZERO(); // check options 99 | #else 100 | mv = receive_from_live(P_0); 101 | #endif 102 | } 103 | else if constexpr (id == P_2) 104 | { 105 | mv = receive_from_live(P_2); 106 | lv = SET_ALL_ZERO(); 107 | } 108 | } 109 | 110 | static void send() { send_live(); } 111 | 112 | static void receive() { receive_live(); } 113 | 114 | static void communicate() { communicate_live(); } 115 | }; 116 | -------------------------------------------------------------------------------- /protocols/3-PC/replicated/replicated_init_template.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../generic_share.hpp" 3 | template 4 | class Replicated_init 5 | { 6 | public: 7 | Replicated_init() {} 8 | 9 | template 10 | void prepare_receive_from(Datatype val, func_add ADD, func_sub SUB) 11 | { 12 | if constexpr (id == PSELF) 13 | { 14 | send_to_(PNEXT); 15 | send_to_(PPREV); 16 | } 17 | } 18 | 19 | template 20 | void complete_receive_from(func_add ADD, func_sub SUB) 21 | { 22 | if constexpr (id != PSELF) 23 | receive_from_(id); 24 | } 25 | Replicated_init public_val(Datatype a) { return Replicated_init(); } 26 | 27 | template 28 | Replicated_init mult_public(const Datatype b, func_mul MULT) const 29 | { 30 | return Replicated_init(); 31 | } 32 | 33 | Replicated_init Not() const { return Replicated_init(); } 34 | 35 | template 36 | Replicated_init Add(Replicated_init b, func_add ADD) const 37 | { 38 | return Replicated_init(); 39 | } 40 | 41 | template 42 | Replicated_init prepare_dot(const Replicated_init b, func_add ADD, func_sub SUB, func_mul MULT) const 43 | { 44 | return Replicated_init(); 45 | } 46 | 47 | template 48 | void mask_and_send_dot(func_add ADD, func_sub SUB) 49 | { 50 | send_to_(PNEXT); 51 | } 52 | 53 | template 54 | Replicated_init prepare_mult(Replicated_init b, func_add ADD, func_sub SUB, func_mul MULT) const 55 | { 56 | send_to_(PNEXT); 57 | return Replicated_init(); 58 | } 59 | 60 | template 61 | void complete_mult(func_add ADD, func_sub SUB) 62 | { 63 | receive_from_(PPREV); 64 | } 65 | 66 | void prepare_reveal_to_all() const { send_to_(PNEXT); } 67 | 68 | template 69 | Datatype complete_Reveal(func_add ADD, func_sub SUB) const 70 | { 71 | receive_from_(PPREV); 72 | Datatype result; 73 | return result; 74 | } 75 | 76 | static void send() { send_(); } 77 | static void receive() { receive_(); } 78 | static void communicate() { communicate_(); } 79 | 80 | static void finalize(std::string* ips) { finalize_(ips); } 81 | }; 82 | -------------------------------------------------------------------------------- /protocols/3-PC/sharemind/sharemind_init_template.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | template 3 | class Sharemind_init 4 | { 5 | public: 6 | Sharemind_init() {} 7 | 8 | template 9 | Sharemind_init Add(const Sharemind_init b, func_add ADD) const 10 | { 11 | return Sharemind_init(); 12 | } 13 | 14 | Sharemind_init public_val(const Datatype a) { return Sharemind_init(); } 15 | 16 | Sharemind_init Not() const { return Sharemind_init(); } 17 | 18 | template 19 | Sharemind_init prepare_mult(const Sharemind_init b, func_add ADD, func_sub SUB, func_mul MULT) const 20 | { 21 | send_to_(PNEXT); 22 | send_to_(PPREV); 23 | return Sharemind_init(); 24 | } 25 | 26 | template 27 | void complete_mult(func_add ADD, func_sub SUB, func_mul MULT) 28 | { 29 | receive_from_(PNEXT); 30 | receive_from_(PPREV); 31 | } 32 | 33 | void prepare_reveal_to_all() const 34 | { 35 | for (int t = 0; t < num_players - 1; t++) 36 | send_to_(t); 37 | } 38 | 39 | template 40 | Sharemind_init mult_public(const Datatype b, func_mul MULT) const 41 | { 42 | return Sharemind_init(); 43 | } 44 | 45 | template 46 | Datatype complete_Reveal(func_add ADD, func_sub SUB) const 47 | { 48 | for (int t = 0; t < num_players - 1; t++) 49 | receive_from_(t); 50 | return SET_ALL_ZERO(); 51 | } 52 | 53 | template 54 | void prepare_receive_from(Datatype val, func_add ADD, func_sub SUB) 55 | { 56 | } 57 | 58 | template 59 | void complete_receive_from(func_add ADD, func_sub SUB) 60 | { 61 | } 62 | 63 | static void send() { send_(); } 64 | static void receive() { receive_(); } 65 | static void communicate() { communicate_(); } 66 | 67 | static void finalize(std::string* ips) { finalize_(ips); } 68 | 69 | static void finalize(std::string* ips, receiver_args* ra, sender_args* sa) { finalize_(ips, ra, sa); } 70 | }; 71 | -------------------------------------------------------------------------------- /protocols/3-PC/sharemind/sharemind_template.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #include "../../generic_share.hpp" 3 | 4 | template 5 | class Sharemind_Share 6 | { 7 | private: 8 | Datatype val; 9 | Datatype helper; 10 | 11 | public: 12 | Sharemind_Share() {} 13 | Sharemind_Share(Datatype v, Datatype helper) : val(v), helper(helper) {} 14 | Sharemind_Share(Datatype v) : val(v){}; 15 | 16 | template 17 | Sharemind_Share Add(Sharemind_Share b, func_add ADD) const 18 | { 19 | return Sharemind_Share(ADD(val, b.val), ADD(helper, b.helper)); 20 | } 21 | 22 | template 23 | Sharemind_Share mult_public(const Datatype b, func_mul MULT) const 24 | { 25 | return Sharemind_Share(MULT(val, b), MULT(helper, b)); 26 | } 27 | 28 | Sharemind_Share public_val(Datatype a) 29 | { 30 | #if PARTY == 0 31 | return Sharemind_Share(a, SET_ALL_ZERO()); 32 | #else 33 | return Sharemind_Share(SET_ALL_ZERO(), SET_ALL_ZERO()); 34 | #endif 35 | } 36 | 37 | Sharemind_Share Not() const { return Sharemind_Share(NOT(val), helper); } 38 | 39 | template 40 | Datatype reshare(Datatype a, func_add ADD, func_sub SUB) const 41 | { 42 | Datatype u[3]; 43 | u[PPREV] = getRandomVal(PPREV); 44 | u[PNEXT] = getRandomVal(PNEXT); 45 | u[2] = SUB(u[PPREV], u[PNEXT]); 46 | u[2] = ADD(a, u[2]); 47 | return u[2]; 48 | } 49 | 50 | template 51 | Sharemind_Share prepare_mult(Sharemind_Share b, func_add ADD, func_sub SUB, func_mul MULT) const 52 | { 53 | Datatype u = reshare(val, ADD, SUB); 54 | Datatype v = reshare(b.val, ADD, SUB); 55 | send_to_live(PNEXT, u); 56 | send_to_live(PPREV, v); 57 | Sharemind_Share c; 58 | c.val = MULT(u, v); 59 | c.helper = v; 60 | return c; 61 | } 62 | 63 | template 64 | void complete_mult(func_add ADD, func_sub SUB, func_mul MULT) 65 | { 66 | 67 | Datatype u_p = receive_from_live(PPREV); 68 | Datatype v_n = receive_from_live(PNEXT); 69 | Datatype v_i = helper; 70 | val = ADD(val, ADD(MULT(u_p, v_i), MULT(u_p, v_n))); 71 | } 72 | 73 | void prepare_reveal_to_all() const 74 | { 75 | for (int t = 0; t < num_players - 1; t++) 76 | send_to_live(t, val); 77 | } 78 | 79 | template 80 | Datatype complete_Reveal(func_add ADD, func_sub SUB) const 81 | { 82 | Datatype result = val; 83 | for (int t = 0; t < num_players - 1; t++) 84 | result = ADD(result, receive_from_live(t)); 85 | return result; 86 | } 87 | 88 | template 89 | void prepare_receive_from(Datatype v, func_add ADD, func_sub SUB) 90 | { 91 | if constexpr (id == PSELF) 92 | val = SUB(v, ADD(getRandomVal(PPREV), getRandomVal(PNEXT))); 93 | else 94 | val = getRandomVal(id); 95 | } 96 | 97 | template 98 | void complete_receive_from(func_add ADD, func_sub SUB) const 99 | { 100 | } 101 | 102 | static void send() { send_live(); } 103 | 104 | static void receive() { receive_live(); } 105 | 106 | static void communicate() { communicate_live(); } 107 | }; 108 | -------------------------------------------------------------------------------- /protocols/generic_share.hpp: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include "../core/arch/DATATYPE.h" 4 | #include "../core/networking/buffers.h" 5 | #include "../core/networking/sockethelper.h" 6 | #include "../core/utils/randomizer.h" 7 | #if INIT == 1 8 | #include "init_protocol_base.hpp" 9 | #endif 10 | #if LIVE == 1 11 | #include "live_protocol_base.hpp" 12 | #endif 13 | #if USE_CUDA_GEMM > 0 14 | #include "../core/cuda/gemm_cutlass_int.h" 15 | #endif 16 | #if USE_CUDA_GEMM == 2 || USE_CUDA_GEMM == 4 17 | #include "../core/cuda/conv_cutlass_int.h" 18 | #endif 19 | -------------------------------------------------------------------------------- /scripts/export_nn_paths.sh: -------------------------------------------------------------------------------- 1 | export MODEL_DIR="." 2 | export DATA_DIR="." 3 | export MODEL_FILE="nn/Pygeon/models/pretrained/vgg16_cifar_standard.bin" 4 | export SAMPLES_FILE="nn/Pygeon/data/datasets/CIFAR-10_standard_test_images.bin" 5 | export LABELS_FILE="nn/Pygeon/data/datasets/CIFAR-10_standard_test_labels.bin" 6 | -------------------------------------------------------------------------------- /scripts/generate_ssl_certificates.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | # Directory to store the SSL certificates 4 | CERT_DIR="ssl_certificates" 5 | 6 | # Create the directory if it doesn't exist 7 | mkdir -p $CERT_DIR 8 | 9 | # Generate a new private key without password protection 10 | openssl genpkey -algorithm RSA -out $CERT_DIR/server.key 11 | 12 | # Generate a certificate signing request (CSR) 13 | openssl req -new -key $CERT_DIR/server.key -out $CERT_DIR/server.csr -subj "/C=DE/ST=Some-State/O=Internet Widgits Pty Ltd" 14 | 15 | # Sign the certificate 16 | openssl x509 -req -days 36500 -in $CERT_DIR/server.csr -signkey $CERT_DIR/server.key -out $CERT_DIR/server.crt 17 | 18 | # Clean up the CSR 19 | rm $CERT_DIR/server.csr 20 | 21 | echo "New private key and certificate have been generated and saved in the $CERT_DIR directory." 22 | 23 | -------------------------------------------------------------------------------- /scripts/run.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | helpFunction() 3 | { 4 | echo "Script to run a n-PC protocol in a distributed setting" 5 | echo -e "\t-p Party number" 6 | echo -e "\t-a IP address of player 0 (if ip matches player_id can be empty)" 7 | echo -e "\t-b IP address of player 1 (if ip matches player_id can be empty)" 8 | echo -e "\t-c IP address of player 2 (if ip matches player_id can be empty)" 9 | echo -e "\t-d IP address of player 3 (if ip matches player_id can be empty)" 10 | echo -e "\t-n Number of players" 11 | echo -e "\t-g Number of GPUs to use" 12 | echo -e "\t-s SplitRoles Identifier" 13 | 14 | exit 1 # Exit script after printing help 15 | } 16 | 17 | while getopts "p:a:b:c:d:n:g:s:" opt 18 | do 19 | case "$opt" in 20 | p ) O_PARTY="$OPTARG" ;; 21 | a ) IP1="$OPTARG" ;; 22 | b ) IP2="$OPTARG" ;; 23 | c ) IP3="$OPTARG" ;; 24 | d ) IP4="$OPTARG" ;; 25 | n ) NUM_PLAYERS="$OPTARG" ;; 26 | g ) NUM_GPUS="$OPTARG" ;; 27 | s ) SPLIT_ROLES="$OPTARG" ;; 28 | ? ) helpFunction ;; # Print helpFunction in case parameter is non-existent 29 | esac 30 | done 31 | 32 | 33 | O_IP1="127.0.0.1" 34 | O_IP2="127.0.0.1" 35 | O_IP3="127.0.0.1" 36 | O_IP4="127.0.0.1" 37 | O_NUM_PLAYERS=3 38 | O_NUM_GPUS=0 39 | O_SPLIT_ROLES=0 40 | 41 | if [ ! -z "$IP1" ]; 42 | then 43 | O_IP1="$IP1" 44 | fi 45 | 46 | if [ ! -z "$IP2" ]; 47 | then 48 | O_IP2="$IP2" 49 | fi 50 | 51 | if [ ! -z "$IP3" ]; 52 | then 53 | O_IP3="$IP3" 54 | fi 55 | 56 | if [ ! -z "$IP4" ]; 57 | then 58 | O_IP4="$IP4" 59 | fi 60 | 61 | if [ ! -z "$NUM_PLAYERS" ]; 62 | then 63 | O_NUM_PLAYERS="$NUM_PLAYERS" 64 | fi 65 | 66 | if [ ! -z "$NUM_GPUS" ]; 67 | then 68 | O_NUM_GPUS="$NUM_GPUS" 69 | fi 70 | 71 | if [ ! -z "$SPLIT_ROLES" ]; 72 | then 73 | O_SPLIT_ROLES="$SPLIT_ROLES" 74 | fi 75 | 76 | #if O_SPLIT_ROLES is 0, then run the protocol with 3 players 77 | if [ "$O_SPLIT_ROLES" = "0" ]; then 78 | if [ "$O_PARTY" = "all" ] 79 | then 80 | scripts/run_locally.sh -n $O_NUM_PLAYERS 81 | else 82 | scripts/run_distributed.sh -p $O_PARTY -a $O_IP1 -b $O_IP2 -c $O_IP3 -d $O_IP4 83 | fi 84 | elif [ "$O_SPLIT_ROLES" = "1" ]; then 85 | scripts/split-roles-3-execute.sh -p $O_PARTY -a $O_IP1 -b $O_IP2 -c $O_IP3 -g $O_NUM_GPUS 86 | elif [ "$O_SPLIT_ROLES" = "2" ]; then 87 | scripts/split-roles-3to4-execute.sh -p $O_PARTY -a $O_IP1 -b $O_IP2 -c $O_IP3 -d $O_IP4 88 | elif [ "$O_SPLIT_ROLES" = "3" ]; then 89 | scripts/split-roles-4-execute.sh -p $O_PARTY -a $O_IP1 -b $O_IP2 -c $O_IP3 -d $O_IP4 90 | fi 91 | 92 | -------------------------------------------------------------------------------- /scripts/run_distributed.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | helpFunction() 3 | { 4 | echo "Script to run a n-PC protocol in a distributed setting" 5 | echo -e "\t-p Party number" 6 | echo -e "\t-a IP address of player 0 (if ip matches player_id can be empty)" 7 | echo -e "\t-b IP address of player 1 (if ip matches player_id can be empty)" 8 | echo -e "\t-c IP address of player 2 (if ip matches player_id can be empty)" 9 | echo -e "\t-d IP address of player 3 (if ip matches player_id can be empty)" 10 | 11 | exit 1 # Exit script after printing help 12 | } 13 | 14 | while getopts "p:a:b:c:d:" opt 15 | do 16 | case "$opt" in 17 | p ) O_PARTY="$OPTARG" ;; 18 | a ) IP1="$OPTARG" ;; 19 | b ) IP2="$OPTARG" ;; 20 | c ) IP3="$OPTARG" ;; 21 | d ) IP4="$OPTARG" ;; 22 | ? ) helpFunction ;; # Print helpFunction in case parameter is non-existent 23 | esac 24 | done 25 | 26 | 27 | O_IP1="127.0.0.1" 28 | O_IP2="127.0.0.1" 29 | O_IP3="127.0.0.1" 30 | O_IP4="127.0.0.1" 31 | 32 | if [ ! -z "$IP1" ]; 33 | then 34 | O_IP1="$IP1" 35 | fi 36 | 37 | if [ ! -z "$IP2" ]; 38 | then 39 | O_IP2="$IP2" 40 | fi 41 | 42 | if [ ! -z "$IP3" ]; 43 | then 44 | O_IP3="$IP3" 45 | fi 46 | 47 | if [ ! -z "$IP4" ]; 48 | then 49 | O_IP4="$IP4" 50 | fi 51 | 52 | 53 | 54 | if [ "$O_PARTY" = "0" ] 55 | then 56 | ./executables/run-P0.o $O_IP2 $O_IP3 $O_IP4 57 | elif [ "$O_PARTY" = "1" ] 58 | then 59 | ./executables/run-P1.o $O_IP1 $O_IP3 $O_IP4 60 | elif [ "$O_PARTY" = "2" ] 61 | then 62 | ./executables/run-P2.o $O_IP1 $O_IP2 $O_IP4 63 | elif [ "$O_PARTY" = "3" ] 64 | then 65 | ./executables/run-P3.o $O_IP1 $O_IP2 $O_IP3 66 | fi 67 | -------------------------------------------------------------------------------- /scripts/run_locally.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | helpFunction() 3 | { 4 | echo "Script to run n players locally after compiling." 5 | echo -e "\t-f Executable to run" 6 | echo -e "\t-n num_players" 7 | exit 1 # Exit script after printing help 8 | } 9 | 10 | while getopts "f:n:" opt 11 | do 12 | case "$opt" in 13 | f ) FUNCTION="$OPTARG" ;; 14 | n ) NUM_PLAYERS="$OPTARG" ;; 15 | ? ) helpFunction ;; # Print helpFunction in case parameter is non-existent 16 | esac 17 | done 18 | 19 | if [ -z "$FUNCTION" ] 20 | then 21 | FUNCTION="run" 22 | fi 23 | 24 | if [ -z "$NUM_PLAYERS" ] 25 | then 26 | echo "Please specify number of players with -n" 27 | exit 1 28 | fi 29 | 30 | for (( i=0; i<$NUM_PLAYERS; i++ )) 31 | do 32 | ./executables/"$FUNCTION"-P"$i".o & 33 | done 34 | 35 | wait 36 | --------------------------------------------------------------------------------