├── mpc_files └── Programs │ ├── cdf │ ├── cdf │ ├── cdf.sch │ └── cdf-0.bc │ ├── id3 │ ├── id3 │ ├── id3.sch │ ├── id3-0.bc │ └── id3.mpc │ ├── norm │ ├── norm │ ├── norm.sch │ ├── norm-0.bc │ └── norm.mpc │ ├── pca │ ├── pca │ ├── pca.sch │ ├── pca-0.bc │ └── pca.mpc │ ├── keygen │ ├── keygen │ ├── keygen.sch │ ├── keygen-0.bc │ └── keygen.mpc │ ├── kmeans │ ├── kmeans │ ├── kmeans.sch │ ├── kmeans-0.bc │ └── kmeans.mpc │ ├── decrypt │ ├── decrypt │ ├── decrypt.sch │ ├── decrypt-0.bc │ └── decrypt.mpc │ ├── histogram │ ├── histogram │ ├── histogram.sch │ ├── histogram-0.bc │ └── histogram.mpc │ ├── id3_iter │ ├── id3_iter │ ├── id3_iter.sch │ └── id3_iter-0.bc │ ├── vec_sum │ ├── vec_sum │ ├── vec_sum.sch │ ├── vec_sum-0.bc │ └── vec_sum.mpc │ ├── kmeans_iter │ ├── kmeans_iter │ ├── kmeans_iter.sch │ ├── kmeans_iter-0.bc │ └── kmeans_iter.mpc │ ├── naive_bayes │ ├── naive_bayes │ ├── naive_bayes.sch │ ├── naive_bayes-0.bc │ └── naive_bayes.mpc │ ├── perceptron │ ├── perceptron │ ├── perceptron.sch │ ├── perceptron-0.bc │ └── perceptron.mpc │ ├── simple_expm │ ├── simple_expm │ ├── simple_expm.sch │ ├── simple_expm-0.bc │ └── simple_expm.mpc │ ├── kmedian_iter │ └── kmedian_iter │ ├── logistic_iter │ ├── logistic_iter │ ├── logistic_iter.sch │ ├── logistic_iter-0.bc │ └── logistic_iter.mpc │ ├── simple_release │ ├── simple_release │ ├── simple_release.sch │ ├── simple_release-0.bc │ └── simple_release.mpc │ ├── sparseVector │ ├── sparseVector │ ├── sparseVector.sch │ ├── sparseVector-0.bc │ └── sparseVector.mpc │ ├── above_threshold │ ├── above_threshold │ ├── above_threshold.sch │ ├── above_threshold-0.bc │ └── above_threshold.mpc │ ├── countMeanSketch │ ├── countMeanSketch │ ├── countMeanSketch.sch │ ├── countMeanSketch-0.bc │ └── countMeanSketch.mpc │ ├── perceptron_iter │ ├── perceptron_iter │ ├── perceptron_iter.sch │ ├── perceptron_iter-0.bc │ └── perceptron_iter.mpc │ ├── count_mean_sketch │ ├── count_mean_sketch │ ├── count_mean_sketch.sch │ ├── count_mean_sketch-0.bc │ └── count_mean_sketch.mpc │ ├── kmedian_iter_medium │ ├── kmedian_iter_medium │ ├── kmedian_iter_medium.sch │ └── kmedian_iter_medium-0.bc │ ├── bag_filter_sum_noise │ ├── bag_filter_sum_noise │ ├── bag_filter_sum_noise.sch │ ├── bag_filter_sum_noise-0.bc │ └── bag_filter_sum_noise.mpc │ ├── test_new_threads │ ├── README.txt │ └── test_new_threads.mpc │ ├── test_empty_tape │ ├── README.txt │ └── test_empty_tape.mpc │ ├── mult_demo │ └── mult_demo.mpc │ ├── input_shares │ └── input_shares.mpc │ ├── test_crash │ └── test_crash.mpc │ ├── test_flex │ └── test_flex.mpc │ ├── test_mem_order │ └── test_mem_order.mpc │ ├── output_shares │ └── output_shares.mpc │ ├── mem_clear_demo │ └── mem_clear_demo.mpc │ ├── test_sqrt │ └── test_sqrt.mpc │ ├── test_threads │ └── test_threads.mpc │ ├── test_map_reduce │ └── test_map_reduce.mpc │ ├── test_float_vector │ └── test_float_vector.mpc │ ├── test_idle_threads │ └── test_idle_threads.mpc │ ├── do_nothing │ └── do_nothing.mpc │ ├── test_for_range_multithread │ └── test_for_range_multithread.mpc │ ├── restart_2 │ └── restart.mpc │ ├── restart_1 │ └── restart.mpc │ ├── lwe_test │ └── lwe_test.mpc │ ├── test_count │ └── test_count.mpc │ ├── test_lib │ └── test_lib.mpc │ ├── test_float_sorting │ └── test_float_sorting.mpc │ ├── tutorial │ └── tutorial.mpc │ ├── test_loop │ └── test_loop.mpc │ ├── test_array │ └── test_array.mpc │ ├── test_custom_array │ └── test_custom_array.mpc │ ├── IO_demo │ └── IO_demo.mpc │ ├── test_function │ └── test_function.mpc │ ├── lwe │ └── lwe.mpc │ ├── test_branch │ └── test_branch.mpc │ ├── test_branching │ └── test_branching.mpc │ ├── test_math │ └── test_math.mpc │ ├── ring_test │ └── ring_test.mpc │ ├── test_floatingpoint │ └── test_floatingpoint.mpc │ ├── test_vector │ └── test_vector.mpc │ └── test_comparison │ └── test_comparison.mpc ├── player.txt ├── total_costs ├── plot_all.sh ├── figures │ ├── bw-agg.pdf │ ├── comp-agg.pdf │ ├── scale-bw-agg.pdf │ ├── bw-participant.pdf │ ├── scale-comp-agg.pdf │ ├── comp-participant.pdf │ ├── comp-agg.plot │ ├── scale-comp-agg.plot │ ├── scale-bw-agg.plot │ ├── comp-participant.plot │ ├── bw-agg.plot │ └── bw-participant.plot ├── data │ ├── scale-comp-agg.data │ ├── honeycrisp.data │ ├── comp-agg.data │ ├── bw-participant.data │ ├── comp-participant.data │ ├── bw-agg.data │ └── scale-bw-agg.data └── data_explanations ├── .DS_Store ├── robustness ├── .DS_Store └── old_files │ ├── graph.py │ ├── ldpError.py │ └── ldpAttack.py ├── .gitmodules ├── source ├── benchmark_multi_shares_input.mpc ├── benchmark_multi_sint_input.mpc ├── genSetupOptions.sh ├── IO.h ├── lwe_test.mpc ├── benchStart.sh ├── testd.sh ├── keygen.mpc ├── benchmark.sh ├── run.sh ├── decrypt.mpc ├── Input_Output_File.h ├── lwe.mpc ├── norm.mpc ├── perceptronOld.mpc ├── perceptron.mpc ├── Input_Output_File.cpp └── ring_test.mpc ├── test ├── benchmark_multi_shares_input.mpc ├── benchmark_bits.mpc ├── benchmark_sint_input.mpc ├── benchmark_multi_sint_input.mpc ├── input_shares.mpc ├── completeTest.sh ├── incr.sh ├── output_shares.mpc ├── benchmark_triples.mpc ├── hi.sh ├── test0.sh ├── orange.sh ├── test1.sh ├── ec2.sh ├── testReconstruct.sh ├── benchmark.sh └── testd.sh ├── config ├── mamba.vim ├── modifyEvalPoints.sh ├── renameShares.sh ├── chooseSubset.py ├── genSetupOptions.sh ├── CONFIG.mine └── config.h ├── extra_files ├── laplace.py ├── dpComparison.py ├── ID3.py └── compressedCounting.py ├── depends.sh ├── Dockerfile ├── install.sh ├── SMtweaks ├── MSP.h └── ShareData.h └── README.md /mpc_files/Programs/cdf/cdf: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/id3/id3: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/norm/norm: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/pca/pca: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/keygen/keygen: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/kmeans/kmeans: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/decrypt/decrypt: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/histogram/histogram: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/id3_iter/id3_iter: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/vec_sum/vec_sum: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /player.txt: -------------------------------------------------------------------------------- 1 | 1 2 | 10000 3 | 100 4 | -------------------------------------------------------------------------------- /mpc_files/Programs/kmeans_iter/kmeans_iter: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/naive_bayes/naive_bayes: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/perceptron/perceptron: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/simple_expm/simple_expm: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/kmedian_iter/kmedian_iter: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/logistic_iter/logistic_iter: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/simple_release/simple_release: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/sparseVector/sparseVector: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/above_threshold/above_threshold: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/countMeanSketch/countMeanSketch: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/perceptron_iter/perceptron_iter: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/count_mean_sketch/count_mean_sketch: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/kmedian_iter_medium/kmedian_iter_medium: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /mpc_files/Programs/bag_filter_sum_noise/bag_filter_sum_noise: -------------------------------------------------------------------------------- 1 | -------------------------------------------------------------------------------- /total_costs/plot_all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | gnuplot figures/*.plot 3 | -------------------------------------------------------------------------------- /.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/.DS_Store -------------------------------------------------------------------------------- /mpc_files/Programs/test_new_threads/README.txt: -------------------------------------------------------------------------------- 1 | Tests spawning and joining threads 2 | 3 | -------------------------------------------------------------------------------- /robustness/.DS_Store: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/robustness/.DS_Store -------------------------------------------------------------------------------- /mpc_files/Programs/cdf/cdf.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | cdf-0 4 | 1 0 5 | 0 6 | ./compile.py ./Programs/cdf 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/id3/id3.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | id3-0 4 | 1 0 5 | 0 6 | ./compile.py Programs/id3 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/pca/pca.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | pca-0 4 | 1 0 5 | 0 6 | ./compile.py ./Programs/pca 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/norm/norm.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | norm-0 4 | 1 0 5 | 0 6 | ./compile.py Programs/norm 7 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "cps-fuzz"] 2 | path = cps-fuzz 3 | url = https://github.com/hengchu/cps-fuzz 4 | -------------------------------------------------------------------------------- /mpc_files/Programs/kmeans/kmeans.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | kmeans-0 4 | 1 0 5 | 0 6 | ./compile.py Programs/kmeans 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_empty_tape/README.txt: -------------------------------------------------------------------------------- 1 | Tests a corner case of empty threads doing nothing 2 | 3 | -------------------------------------------------------------------------------- /mpc_files/Programs/cdf/cdf-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/cdf/cdf-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/decrypt/decrypt.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | decrypt-0 4 | 1 0 5 | 0 6 | ./compile.py Programs/decrypt 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/id3/id3-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/id3/id3-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/keygen/keygen.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | keygen-0 4 | 1 0 5 | 0 6 | ./compile.py ./Programs/keygen/ 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/pca/pca-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/pca/pca-0.bc -------------------------------------------------------------------------------- /total_costs/figures/bw-agg.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/total_costs/figures/bw-agg.pdf -------------------------------------------------------------------------------- /mpc_files/Programs/id3_iter/id3_iter.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | id3_iter-0 4 | 1 0 5 | 0 6 | ./compile.py ./Programs/id3_iter 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/norm/norm-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/norm/norm-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/vec_sum/vec_sum.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | vec_sum-0 4 | 1 0 5 | 0 6 | ./compile.py ./Programs/vec_sum 7 | -------------------------------------------------------------------------------- /source/benchmark_multi_shares_input.mpc: -------------------------------------------------------------------------------- 1 | n = 1000 2 | 3 | for i in range(n): 4 | a = input_shares(i) 5 | 6 | print a -------------------------------------------------------------------------------- /test/benchmark_multi_shares_input.mpc: -------------------------------------------------------------------------------- 1 | n = 1000 2 | 3 | for i in range(n): 4 | a = input_shares(i) 5 | 6 | print a -------------------------------------------------------------------------------- /total_costs/figures/comp-agg.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/total_costs/figures/comp-agg.pdf -------------------------------------------------------------------------------- /mpc_files/Programs/histogram/histogram.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | histogram-0 4 | 1 0 5 | 0 6 | ./compile.py ./Programs/histogram 7 | -------------------------------------------------------------------------------- /total_costs/figures/scale-bw-agg.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/total_costs/figures/scale-bw-agg.pdf -------------------------------------------------------------------------------- /mpc_files/Programs/keygen/keygen-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/keygen/keygen-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/kmeans/kmeans-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/kmeans/kmeans-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/perceptron/perceptron.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | perceptron-0 4 | 1 0 5 | 0 6 | ./compile.py Programs/perceptron 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/simple_expm/simple_expm.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | simple_expm-0 4 | 1 0 5 | 0 6 | ./compile.py Programs/simple_expm 7 | -------------------------------------------------------------------------------- /total_costs/figures/bw-participant.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/total_costs/figures/bw-participant.pdf -------------------------------------------------------------------------------- /total_costs/figures/scale-comp-agg.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/total_costs/figures/scale-comp-agg.pdf -------------------------------------------------------------------------------- /mpc_files/Programs/decrypt/decrypt-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/decrypt/decrypt-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/id3_iter/id3_iter-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/id3_iter/id3_iter-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/kmeans_iter/kmeans_iter.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | kmeans_iter-0 4 | 1 0 5 | 0 6 | ./compile.py ./Programs/kmeans_iter 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/naive_bayes/naive_bayes.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | naive_bayes-0 4 | 1 0 5 | 0 6 | ./compile.py ./Programs/naive_bayes 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/sparseVector/sparseVector.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | sparseVector-0 4 | 1 0 5 | 0 6 | ./compile.py Programs/sparseVector 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/vec_sum/vec_sum-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/vec_sum/vec_sum-0.bc -------------------------------------------------------------------------------- /total_costs/figures/comp-participant.pdf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/total_costs/figures/comp-participant.pdf -------------------------------------------------------------------------------- /mpc_files/Programs/histogram/histogram-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/histogram/histogram-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/logistic_iter/logistic_iter.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | logistic_iter-0 4 | 1 0 5 | 0 6 | ./compile.py ./Programs/logistic_iter 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/perceptron/perceptron-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/perceptron/perceptron-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/simple_release/simple_release.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | simple_release-0 4 | 1 0 5 | 0 6 | ./compile.py Programs/simple_release/ 7 | -------------------------------------------------------------------------------- /test/benchmark_bits.mpc: -------------------------------------------------------------------------------- 1 | n = 64 2 | 3 | a = sint.Array(n) 4 | 5 | @for_range(n) 6 | def setA(i): 7 | a[i] = sint.get_random_int(1) 8 | 9 | -------------------------------------------------------------------------------- /config/mamba.vim: -------------------------------------------------------------------------------- 1 | if exists("b:current_syntax") 2 | finish 3 | endif 4 | 5 | set syntax=python 6 | 7 | let b:current_syntax = "frigate" 8 | 9 | -------------------------------------------------------------------------------- /mpc_files/Programs/above_threshold/above_threshold.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | above_threshold-0 4 | 1 0 5 | 0 6 | ./compile.py ./Programs/above_threshold 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/countMeanSketch/countMeanSketch.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | countMeanSketch-0 4 | 1 0 5 | 0 6 | ./compile.py Programs/countMeanSketch 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/kmeans_iter/kmeans_iter-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/kmeans_iter/kmeans_iter-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/naive_bayes/naive_bayes-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/naive_bayes/naive_bayes-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/perceptron_iter/perceptron_iter.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | perceptron_iter-0 4 | 1 0 5 | 0 6 | ./compile.py ./Programs/perceptron_iter 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/simple_expm/simple_expm-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/simple_expm/simple_expm-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/logistic_iter/logistic_iter-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/logistic_iter/logistic_iter-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/sparseVector/sparseVector-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/sparseVector/sparseVector-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/test_empty_tape/test_empty_tape.mpc: -------------------------------------------------------------------------------- 1 | def f(): 2 | pass 3 | 4 | program.join_tape(program.run_tape(program.new_tape(f), 0)) 5 | -------------------------------------------------------------------------------- /mpc_files/Programs/count_mean_sketch/count_mean_sketch.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | count_mean_sketch-0 4 | 1 0 5 | 0 6 | ./compile.py ./Programs/count_mean_sketch 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/simple_release/simple_release-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/simple_release/simple_release-0.bc -------------------------------------------------------------------------------- /test/benchmark_sint_input.mpc: -------------------------------------------------------------------------------- 1 | n = 1024 2 | 3 | a = sint.Array(n) 4 | 5 | @for_range(n) 6 | def setA(i): 7 | a[i] = sint.get_private_input_from(0) 8 | 9 | -------------------------------------------------------------------------------- /mpc_files/Programs/above_threshold/above_threshold-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/above_threshold/above_threshold-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/countMeanSketch/countMeanSketch-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/countMeanSketch/countMeanSketch-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/kmedian_iter_medium/kmedian_iter_medium.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | kmedian_iter_medium-0 4 | 1 0 5 | 0 6 | ./compile.py Programs/kmedian_iter_medium 7 | -------------------------------------------------------------------------------- /mpc_files/Programs/perceptron_iter/perceptron_iter-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/perceptron_iter/perceptron_iter-0.bc -------------------------------------------------------------------------------- /test/benchmark_multi_sint_input.mpc: -------------------------------------------------------------------------------- 1 | n = 1000 2 | 3 | a = sint(0) 4 | 5 | for i in range(n): 6 | a = a + sint.get_private_input_from(i%2) 7 | 8 | a.reveal_to(0) -------------------------------------------------------------------------------- /mpc_files/Programs/bag_filter_sum_noise/bag_filter_sum_noise.sch: -------------------------------------------------------------------------------- 1 | 1 2 | 1 3 | bag_filter_sum_noise-0 4 | 1 0 5 | 0 6 | ./compile.py ./Programs/bag_filter_sum_noise 7 | -------------------------------------------------------------------------------- /source/benchmark_multi_sint_input.mpc: -------------------------------------------------------------------------------- 1 | n = 1000 2 | 3 | a = sint(0) 4 | 5 | for i in range(n): 6 | a = a + sint.get_private_input_from(i%2) 7 | 8 | a.reveal_to(0) -------------------------------------------------------------------------------- /mpc_files/Programs/count_mean_sketch/count_mean_sketch-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/count_mean_sketch/count_mean_sketch-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/mult_demo/mult_demo.mpc: -------------------------------------------------------------------------------- 1 | @do_while 2 | def _(): 3 | for i in range(1000): 4 | sint(1) * sint(1) 5 | return regint(1) 6 | 7 | -------------------------------------------------------------------------------- /test/input_shares.mpc: -------------------------------------------------------------------------------- 1 | trip = [sint(), sint(), sint()] 2 | 3 | input_shares(1000, *trip) 4 | 5 | trip[0].reveal_to(0) 6 | trip[1].reveal_to(0) 7 | trip[2].reveal_to(0) 8 | -------------------------------------------------------------------------------- /mpc_files/Programs/kmedian_iter_medium/kmedian_iter_medium-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/kmedian_iter_medium/kmedian_iter_medium-0.bc -------------------------------------------------------------------------------- /mpc_files/Programs/bag_filter_sum_noise/bag_filter_sum_noise-0.bc: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/edoroth/orchard/HEAD/mpc_files/Programs/bag_filter_sum_noise/bag_filter_sum_noise-0.bc -------------------------------------------------------------------------------- /test/completeTest.sh: -------------------------------------------------------------------------------- 1 | # One run simulating all committee parties on one machine 2 | 3 | #$1 - number of parties 4 | #$2 - program name 5 | 6 | ./test0.sh $1 $1 1 7 | ./testd.sh $1 $2 8 | -------------------------------------------------------------------------------- /mpc_files/Programs/input_shares/input_shares.mpc: -------------------------------------------------------------------------------- 1 | trip = [sint(), sint(), sint()] 2 | 3 | input_shares(1000, *trip) 4 | 5 | trip[0].reveal_to(0) 6 | trip[1].reveal_to(0) 7 | trip[2].reveal_to(0) 8 | -------------------------------------------------------------------------------- /test/incr.sh: -------------------------------------------------------------------------------- 1 | #incr.sh 2 | j=$1 3 | 4 | sed -i "11s/.*/k = $j/" Programs/keygen/keygen.mpc 5 | ./test0.sh $((j+1)) $((j+1)) 1 6 | 7 | sed -i "8s/.*/k = $j/" Programs/decrypt/decrypt.mpc 8 | ./testd.sh $((j+1)) $((j+1)) 1 -------------------------------------------------------------------------------- /extra_files/laplace.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | N = 1000000 3 | ldp = [] 4 | gdp = [] 5 | s = np.random.laplace(0,1,N) 6 | val = sum(s) # all of the random noise 7 | ldp.append(val) 8 | gdp.append(val) 9 | print gdp 10 | print ldp 11 | -------------------------------------------------------------------------------- /config/modifyEvalPoints.sh: -------------------------------------------------------------------------------- 1 | N_2=$1 2 | SUBSET=$2 3 | EVAL_POINTS=$3 4 | 5 | for (( i=0; i< ${N_2}; i++ )) 6 | do 7 | j=$( sed $((${i} + 1))'q;d' ${SUBSET} ) 8 | xj=$( sed $((${j} + 1))'q;d' ${EVAL_POINTS} ) 9 | echo ${xj} 10 | done 11 | 12 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_crash/test_crash.mpc: -------------------------------------------------------------------------------- 1 | 2 | print_ln("Every one enter a value (these MUST be the same, otherwise an abort will occur)") 3 | d=cint.public_input() 4 | 5 | if_then(d) 6 | crash() 7 | else_then() 8 | crash() 9 | end_if() 10 | 11 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_flex/test_flex.mpc: -------------------------------------------------------------------------------- 1 | a = load_int_to_secret_vector(range(100)) 2 | b = load_int_to_secret_vector(range(100,200)) 3 | c = a * b 4 | test(c[1]) 5 | test(c[99]) 6 | d = Array(100,'s') 7 | d.assign(c) 8 | test(d[0]) 9 | test(d[42]) 10 | -------------------------------------------------------------------------------- /config/renameShares.sh: -------------------------------------------------------------------------------- 1 | N_2=$1 2 | DIR=$2 3 | SUBSET=$3 4 | 5 | for (( i=0; i< ${N_2}; i++ )) 6 | do 7 | j=$( sed $((${i} + 1))'q;d' ${SUBSET} ) 8 | sed 's/'${j}'/'${i}'/' ${DIR}/Player${j}_shareout.txt > ${DIR}/Player${i}_sharein.txt 9 | done 10 | 11 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_mem_order/test_mem_order.mpc: -------------------------------------------------------------------------------- 1 | n = 1000 2 | a = Array(n, 'c') 3 | for i in range(n): 4 | a[i] = i + 1 5 | test(a[0], 1) 6 | test(a[n-1], n) 7 | for i in range(n): 8 | a[i] = -i - 1 9 | test(a[0], -1) 10 | test(a[n-1], -n) 11 | -------------------------------------------------------------------------------- /total_costs/data/scale-comp-agg.data: -------------------------------------------------------------------------------- 1 | # Column 1: Algorithm 2 | # Column 2: Computation (cores) for aggregator (1 round) 3 | # Column 3: 3 rounds 4 | # Column 4: 20 rounds 5 | 6 | 1 0.446 1.35 8.92 7 | 2 4.46 13.5 89.2 8 | 3 44.6 135 892 #1.3 bil 9 | 4 446 1350 8920 10 | -------------------------------------------------------------------------------- /test/output_shares.mpc: -------------------------------------------------------------------------------- 1 | trip = sint.get_random_triple() 2 | a = trip[0] 3 | b = trip[1] 4 | 5 | a.reveal_to(1) 6 | b.reveal_to(1) 7 | 8 | a = (a==sint(0)) + sint(2) 9 | b = (b==sint(0)) + sint(3) 10 | c = a * b 11 | 12 | arr = [a, b, c] 13 | output_shares(1000, *arr) 14 | 15 | -------------------------------------------------------------------------------- /config/chooseSubset.py: -------------------------------------------------------------------------------- 1 | #!/bin/python 2 | 3 | import sys 4 | import random 5 | 6 | n1 = int(sys.argv[1]) # Superset size 7 | n2 = int(sys.argv[2]) # Subset size 8 | 9 | full = list(range(n1)) 10 | sub = random.sample(full, n2) 11 | sub.sort() 12 | 13 | for i in range(n2): 14 | print sub[i] 15 | -------------------------------------------------------------------------------- /mpc_files/Programs/output_shares/output_shares.mpc: -------------------------------------------------------------------------------- 1 | trip = sint.get_random_triple() 2 | a = trip[0] 3 | b = trip[1] 4 | 5 | a.reveal_to(1) 6 | b.reveal_to(1) 7 | 8 | a = (a==sint(0)) + sint(2) 9 | b = (b==sint(0)) + sint(3) 10 | c = a * b 11 | 12 | arr = [a, b, c] 13 | output_shares(1000, *arr) 14 | 15 | -------------------------------------------------------------------------------- /test/benchmark_triples.mpc: -------------------------------------------------------------------------------- 1 | n=128 2 | 3 | a = sint.Array(n) 4 | b = sint.Array(n) 5 | c = sint.Array(n) 6 | 7 | @for_range(n) 8 | def setA(i): 9 | a[i] = sint(i) 10 | 11 | @for_range(n) 12 | def setB(i): 13 | b[i] = sint(i) 14 | 15 | @for_range(n) 16 | def setC(i): 17 | c[i] = a[i] * b[i] 18 | 19 | -------------------------------------------------------------------------------- /test/hi.sh: -------------------------------------------------------------------------------- 1 | #hi.sh 2 | sudo yum update 3 | sudo yum install git 4 | sudo yum install docker 5 | 6 | git clone https://github.com/danxinnoble/honeycrisp.git 7 | cd honeycrisp 8 | sudo service docker start 9 | sudo docker build -t honeycrisp . 10 | sudo docker run -it honeycrisp 11 | 12 | cd SCALE-MAMBA 13 | 14 | ./incr.sh 14 -------------------------------------------------------------------------------- /mpc_files/Programs/mem_clear_demo/mem_clear_demo.mpc: -------------------------------------------------------------------------------- 1 | # Requires compiling with -M flag set 2 | 3 | a=sint(5) 4 | a.store_in_mem(3) 5 | b=sint.load_mem(3) 6 | print_ln("b = %s", b.reveal()) 7 | clear_memory() 8 | c= sint.load_mem(3) 9 | print_ln("c = %s", c.reveal()) 10 | clear_registers() 11 | print_ln("b = %s", b.reveal()) 12 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_sqrt/test_sqrt.mpc: -------------------------------------------------------------------------------- 1 | a = sfix(2) 2 | b = sint(36) 3 | c = sfix(25) 4 | d = sint(49) 5 | 6 | 7 | print_ln("test sqrt:") 8 | 9 | test(mpc_math.test_sqrt_no_param(a)) 10 | test(mpc_math.test_sqrt_param(b, 6, 0)) 11 | test(mpc_math.test_sqrt_no_param(c)) 12 | test(mpc_math.test_sqrt_param(d, 6, 0)) 13 | 14 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_threads/test_threads.mpc: -------------------------------------------------------------------------------- 1 | def f(): 2 | store_in_mem(reveal((get_arg() or 0) * sint(99)), get_arg()) 3 | 4 | t = MPCThread(f, 'f') 5 | 6 | for j in range(10): 7 | n = 7 8 | for i in range(n): 9 | arg = 10 * j + i 10 | t.start(arg) 11 | test_mem(arg * 99, arg) 12 | for i in range(n): 13 | t.join() 14 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_map_reduce/test_map_reduce.mpc: -------------------------------------------------------------------------------- 1 | def summer(x,y): 2 | return tuple(a + b for a,b in zip(x,y)) 3 | 4 | @map_reduce(10, 10, 999, lambda: cint(0), summer) 5 | def f(i): 6 | return cint(1) 7 | test(f(), 999) 8 | 9 | 10 | @map_sum(5, 5, 100, 2, cint) 11 | def f(i): 12 | return (cint(1), cint(2)) 13 | test(f()[0], 100) 14 | test(f()[1], 200) 15 | -------------------------------------------------------------------------------- /total_costs/data/honeycrisp.data: -------------------------------------------------------------------------------- 1 | # Column 2: bandwidth (decrypt) 2 | # Column 3: bandwidth (keygen) 3 | # Column 4: comp (decrypt) 4 | # column 5: comp (keygen) 5 | # bw (s) - agg 6 | # bw (r) - agg 7 | # comp - agg 8 | # bw - participant 9 | # comp -participant 10 | 11 | 0 1345.02 1900 104 176 1449134205014600 85000000000000 44.6 230 65552 1205388 54.06 7.83 0.320 61.91 12 | 13 | -------------------------------------------------------------------------------- /test/test0.sh: -------------------------------------------------------------------------------- 1 | N_1=$1 2 | N_2=$2 # where N_2 <= N1 3 | 4 | # Require THRESHOLD * 2 + 1 <= N2 5 | THRESHOLD=$3 6 | 7 | 8 | rm ./Data/* 9 | 10 | seq ${N_1} > ./Data/evalPoints.txt 11 | 12 | ./genSetupOptions.sh ${N_1} ${THRESHOLD} | ./Setup.x > /dev/null 13 | 14 | 15 | # the 2 is the number of output shares 16 | echo 'Running part 1' 17 | ./benchmark.sh ./Programs/keygen/ ${N_1} 2 18 | -------------------------------------------------------------------------------- /config/genSetupOptions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | N_PLAYERS=$1 4 | THRESHOLD=$2 # Require 2*THRESHOLD < N_PLAYERS 5 | 6 | echo 3 7 | echo RootCA 8 | 9 | echo $N_PLAYERS 10 | for (( i = 0; i < $N_PLAYERS; i++ )) 11 | do 12 | echo 127.0.0.1 13 | echo Player$i.crt 14 | done 15 | 16 | echo N 17 | echo N 18 | echo 2 19 | echo 300424569129657234489620267994584186881 20 | 21 | echo $THRESHOLD 22 | -------------------------------------------------------------------------------- /source/genSetupOptions.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | N_PLAYERS=$1 4 | THRESHOLD=$2 # Require 2*THRESHOLD < N_PLAYERS 5 | 6 | echo 3 7 | echo RootCA 8 | 9 | echo $N_PLAYERS 10 | for (( i = 0; i < $N_PLAYERS; i++ )) 11 | do 12 | echo 127.0.0.1 13 | echo Player$i.crt 14 | done 15 | 16 | echo N 17 | echo N 18 | echo 2 19 | echo 300424569129657234489620267994584186881 20 | 21 | echo $THRESHOLD 22 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_float_vector/test_float_vector.mpc: -------------------------------------------------------------------------------- 1 | sfloat.vlen = 8 # Length of mantissa in bits 2 | sfloat.plen = 5 # Length of exponent in bits 3 | sfloat.kappa = 4 # Statistical security parameter for floats 4 | 5 | test(sfloat(1, size=16) * sfloat(1, size=16)) 6 | test(sfloat(1, size=16) + sfloat(1, size=16)) 7 | test(sfloat(0, size=16) < sfloat(1, size=16)) 8 | test(sfloat(0.5, size=16) ** 5) 9 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_idle_threads/test_idle_threads.mpc: -------------------------------------------------------------------------------- 1 | def f(): 2 | a = cint(1) 3 | b = a + a 4 | 5 | thread = MPCThread(f, 'test') 6 | 7 | for i in range(100000): 8 | thread.start() 9 | thread.join() 10 | 11 | for i in range(10): 12 | thread.start() 13 | for i in range(10): 14 | thread.join() 15 | 16 | for i in range(100000): 17 | thread.start() 18 | thread.join() 19 | -------------------------------------------------------------------------------- /mpc_files/Programs/do_nothing/do_nothing.mpc: -------------------------------------------------------------------------------- 1 | n=1 2 | 3 | # Create some dummy threads to ensure we have multiple threads 4 | 5 | def f(): 6 | a = cint(1) 7 | b = a + a 8 | 9 | thread = MPCThread(f, 'test') 10 | 11 | for i in range(n): 12 | thread.start() 13 | for i in range(n): 14 | thread.join() 15 | 16 | print_ln("Player zero enter a private gfp number") 17 | a=sint.get_private_input_from(0) 18 | -------------------------------------------------------------------------------- /total_costs/data/comp-agg.data: -------------------------------------------------------------------------------- 1 | # Column 1: Algorithm 2 | # Column 2: Computation (cores) for aggregator 3 | # --- First pass at data --- 4 | 5 | 1 44.6 #CMS 6 | 2 44.6 #SV 7 | 3 446.0 #Perceptron 8 | 4 44.6 # ID3 9 | 5 223.0 # kmeans 10 | 6 44.6 # PCA 11 | 7 892.0 #NN 12 | 8 223.0 # kmedian 13 | 9 44.6 # bloom 14 | 10 89.2 # NB 15 | 11 44.6 # LogReg 16 | 12 44.6 # Hist 17 | 13 44.6 # CDF 18 | 14 44.6 # Range 19 | 20 | -------------------------------------------------------------------------------- /source/IO.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2017, The University of Bristol, Senate House, Tyndall Avenue, Bristol, BS8 1TH, United Kingdom. 3 | Copyright (c) 2018, COSIC-KU Leuven, Kasteelpark Arenberg 10, bus 2452, B-3001 Leuven-Heverlee, Belgium. 4 | 5 | All rights reserved 6 | */ 7 | #ifndef _IO 8 | #define _IO 9 | 10 | #include "Input_Output_Simple.h" 11 | #include "Input_Output_File.h" 12 | 13 | // #include "Input_Output_Galois.h" 14 | 15 | #endif 16 | -------------------------------------------------------------------------------- /config/CONFIG.mine: -------------------------------------------------------------------------------- 1 | ROOT = /root/SCALE-MAMBA 2 | OSSL = /root/openssl-1.1.0h 3 | 4 | # Debug flags 5 | # SH_DEBUG = Share debugging (for development only) 6 | # DEBUG = Checks for reads before writes on register access 7 | # DETERMINISTIC = Removes all randomness, gain for debugging 8 | 9 | MAX_MOD = 10 10 | 11 | #FLAGS = -DSH_DEBUG -DDEBUG -DMAX_MOD_SZ=$(MAX_MOD) -DDETERMINISTIC 12 | FLAGS = -DMAX_MOD_SZ=$(MAX_MOD) 13 | 14 | OPT = -O3 15 | 16 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_for_range_multithread/test_for_range_multithread.mpc: -------------------------------------------------------------------------------- 1 | @for_range_multithread(10, 10, 1000) 2 | def f(i): 3 | sint(0) * sint(0) 4 | cint(i).store_in_mem(i) 5 | test_mem(cint(i), i) 6 | 7 | program.malloc(1000, 'c') 8 | 9 | @for_range_multithread(10, 10, 1000, {regint:1}) 10 | def f(i, thread_mem): 11 | thread_mem[0] = i 12 | thread_mem[0].store_in_mem(i) 13 | test_mem(i, i) 14 | 15 | program.malloc(1000, 'r') 16 | -------------------------------------------------------------------------------- /test/orange.sh: -------------------------------------------------------------------------------- 1 | N_1=$1 2 | 3 | PROGRAM=$2 4 | 5 | # Require THRESHOLD * 2 + 1 <= N2 6 | #THRESHOLD=$3 7 | THRESHOLD=3 8 | VERBOSE=$3 9 | 10 | #( make clean ; make progs ) > /dev/null 11 | 12 | rm ./Data/* 13 | 14 | seq ${N_1} > ./Data/evalPoints.txt 15 | 16 | ./genSetupOptions.sh ${N_1} ${THRESHOLD} | ./Setup.x > /dev/null 17 | 18 | 19 | # the 2 is the number of output shares 20 | echo 'Running part 1' 21 | ./benchmark.sh ./Programs/$PROGRAM ${N_1} 2 $VERBOSE 22 | -------------------------------------------------------------------------------- /mpc_files/Programs/restart_2/restart.mpc: -------------------------------------------------------------------------------- 1 | 2 | # Write some data to file 3 | inp = [sint(1), sint(2), sint(3), sint(4)] 4 | output_shares(3000,*inp) 5 | 6 | print_ln("Player zero enter a number") 7 | a=sint.get_private_input_from(0) 8 | print_ln("Player one enter a number") 9 | b=sint.get_private_input_from(1) 10 | c=a*b 11 | print_ln("The product is being sent to player one") 12 | c.reveal_to(1) 13 | print_reg(reveal(a)) 14 | print_reg(reveal(b)) 15 | print_reg(reveal(c)) 16 | 17 | restart() 18 | -------------------------------------------------------------------------------- /mpc_files/Programs/pca/pca.mpc: -------------------------------------------------------------------------------- 1 | k = 39 2 | 3 | def laplace_fx(center, width): 4 | return center + sint.get_random_bit(width) 5 | 6 | orange_input_0 = sint.get_private_input_from(k) 7 | 8 | def anonymous_fun_3_(empty_closure_1_): 9 | """ 10 | empty_closure_1_: () 11 | """ 12 | def anonymous_fun_4_(orange_input_0_): 13 | """ 14 | orange_input_0_: Double 15 | """ 16 | return laplace_fx(cfix(1.0),orange_input_0_) 17 | return anonymous_fun_4_ 18 | 19 | anonymous_fun_3_(()) 20 | -------------------------------------------------------------------------------- /mpc_files/Programs/restart_1/restart.mpc: -------------------------------------------------------------------------------- 1 | sfloat.vlen = 8 # Length of mantissa in bits 2 | sfloat.plen = 5 # Length of exponent in bits 3 | sfloat.kappa = 4 # Statistical security parameter for floats 4 | 5 | a = [sfloat(i) for i in [-.03,2]] 6 | a[0], a[1] = cond_swap(a[0], a[1]) 7 | 8 | a = [sfloat(i) for i in [3,0]] 9 | a[0], a[1] = cond_swap(a[0], a[1]) 10 | 11 | import random 12 | random.seed(0) 13 | a = [sfloat(random.uniform(-100,100)) for i in range(8)] 14 | odd_even_merge_sort(a) 15 | 16 | restart() 17 | -------------------------------------------------------------------------------- /test/test1.sh: -------------------------------------------------------------------------------- 1 | N_1=$1 2 | N_2=$2 3 | THRESHOLD=$3 4 | 5 | python chooseSubset.py ${N_1} ${N_2} > ./Data/subset.txt 6 | echo 'Subset chosen:' 7 | cat ./Data/subset.txt 8 | 9 | ./renameShares.sh ${N_2} ./Data ./Data/subset.txt 10 | 11 | ./modifyEvalPoints.sh ${N_2} ./Data/subset.txt ./Data/evalPoints.txt > ./Data/evalPoints.txt.new 12 | rm ./Data/evalPoints.txt 13 | mv ./Data/evalPoints.txt.new ./Data/evalPoints.txt 14 | 15 | ./genSetupOptions.sh ${N_2} ${THRESHOLD} | ./Setup.x > /dev/null 16 | 17 | echo 'Running part 2' -------------------------------------------------------------------------------- /source/lwe_test.mpc: -------------------------------------------------------------------------------- 1 | execfile('/root/SCALE-MAMBA/Programs/lwe/lwe.mpc') 2 | 3 | # For use with n=8192, p=300424569129657234489620267994584186881 4 | w = cint(216409912179401900965416891955038263635)**8 5 | 6 | n=8192/8 7 | lgN = 13-3 8 | r = Ring(lgN, w) 9 | 10 | N = 1 11 | lgM = 20 12 | l = 4 13 | lwe = LWE(r, N, lgM, l) 14 | 15 | x = sint.Array(l) 16 | for i in range(l): 17 | x[i] = sint(i) 18 | 19 | [a, b, s] = lwe.key_gen() 20 | 21 | [u, v] = lwe.enc(a, b, x) 22 | 23 | x2 = lwe.dec(u, v, s) 24 | 25 | for i in range(l): 26 | x2[i].reveal_to(0) 27 | -------------------------------------------------------------------------------- /depends.sh: -------------------------------------------------------------------------------- 1 | #frigate install supporting mpir library 2 | wget http://mpir.org/mpir-3.0.0.tar.bz2 3 | tar -xvf mpir-3.0.0.tar.bz2 4 | rm mpir-3.0.0.tar.bz2 5 | cd mpir-3.0.0 6 | ./configure --enable-cxx 7 | make install 8 | cp .libs/* /usr/lib64/ 9 | 10 | # install openssl from source because apparently apt's version is not good 11 | # enough 12 | cd 13 | wget https://www.openssl.org/source/openssl-1.1.0h.tar.gz 14 | tar -xvf openssl-1.1.0h.tar.gz 15 | rm openssl-1.1.0h.tar.gz 16 | cd openssl-1.1.0h 17 | ./config 18 | make 19 | make install 20 | ldconfig 21 | 22 | -------------------------------------------------------------------------------- /mpc_files/Programs/lwe_test/lwe_test.mpc: -------------------------------------------------------------------------------- 1 | execfile('/root/SCALE-MAMBA/Programs/lwe/lwe.mpc') 2 | 3 | # For use with n=8192, p=300424569129657234489620267994584186881 4 | w = cint(216409912179401900965416891955038263635)**8 5 | 6 | n=8192/8 7 | lgN = 13-3 8 | r = Ring(lgN, w) 9 | 10 | N = 1 11 | lgM = 20 12 | l = 4 13 | lwe = LWE(r, N, lgM, l) 14 | 15 | x = sint.Array(l) 16 | for i in range(l): 17 | x[i] = sint(i) 18 | 19 | [a, b, s] = lwe.key_gen() 20 | 21 | [u, v] = lwe.enc(a, b, x) 22 | 23 | x2 = lwe.dec(u, v, s) 24 | 25 | for i in range(l): 26 | x2[i].reveal_to(0) 27 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_count/test_count.mpc: -------------------------------------------------------------------------------- 1 | program.options.dead_code_elimination = False 2 | 3 | @function_block 4 | def f(): 5 | @for_range(10) 6 | def f(i): 7 | sint.get_random_triple() 8 | sint.get_random_bit() 9 | @for_range_multithread(10, 10, 100) 10 | def h(i): 11 | sint.get_random_triple() 12 | 13 | @function_block 14 | def g(): 15 | if_then(regint(0)) 16 | sint.get_random_bit() 17 | else_then() 18 | @for_range(10) 19 | def h(i): 20 | f() 21 | sint.get_random_triple() 22 | sint.get_random_bit() 23 | end_if() 24 | 25 | g() 26 | g() 27 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_lib/test_lib.mpc: -------------------------------------------------------------------------------- 1 | zero = regint(0) 2 | shared_one = sint(1) 3 | # Arguments = location in memory 4 | mem_two = load_clear_mem(2) 5 | shared_mem_three = load_secret_mem(3) 6 | const_mem_zero = load_clear_mem(zero) 7 | shared_mem_zero = load_secret_mem(zero) 8 | # Stores zero to location 0 9 | store_in_mem(zero, 0) 10 | store_in_mem(shared_one, 0) 11 | store_in_mem(zero, zero) 12 | store_in_mem(shared_one, zero) 13 | one = reveal(shared_one) 14 | # x = get_input_from(0) 15 | # t1, t2, t3 = get_random_triple() 16 | # b = get_random_bit() 17 | # s1, s2 = get_random_square() 18 | # i1, i2 = get_random_inverse() 19 | -------------------------------------------------------------------------------- /test/ec2.sh: -------------------------------------------------------------------------------- 1 | # May need an update 2 | # Run on EC2 3 | #large 4 | ssh -i "id_rsa_new.pem" ec2-user@ec2-3-15-193-164.us-east-2.compute.amazonaws.com # replace with your ec2 instance(s) 5 | 6 | sudo yum update 7 | sudo yum install git 8 | sudo yum install docker 9 | 10 | git clone https://github.com/edoroth/orchard.git 11 | sudo service docker start 12 | sudo docker build -t orchard . 13 | sudo docker run -it orchard 14 | 15 | cd SCALE-MAMBA 16 | 17 | chmod 777 testd.sh 18 | 19 | #edit for different query you would like to test 20 | ./testd.sh 9 histogram # Decryption: 21 | 22 | 23 | 24 | 25 | -------------------------------------------------------------------------------- /total_costs/data/bw-participant.data: -------------------------------------------------------------------------------- 1 | # Column 1: Bar group (1..3) 2 | # Column 2: SNARK size (bytes) 3 | # Column 3: Ciphertext size (bytes) 4 | # Column 4: Total costs including sum verification size (bytes) 5 | 1 230 65536 1205388 # LogReg 6 | 2 230 65536 1205388 # CMS 7 | 3 2300 655360 12053880 # Perc 8 | 4 230 65536 1205388 #ID3 9 | 5 1150 327680 6026940 # k-means x5 10 | 6 230 65536 1205388 # PCA 11 | 7 4600 1310720 24107760 # NN x20 12 | 8 1150 327780 6026940 # kmedian x5 13 | 9 230 65536 1205388 #bloom 14 | 10 460 131072 2410776 # NB x2 for space 15 | 11 230 65536 1205388 #CMS 16 | 12 230 65536 1205388 #Hist 17 | 13 230 65536 1205388 #CDF 18 | 14 230 65536 1205388 #Range 19 | 20 | -------------------------------------------------------------------------------- /total_costs/data/comp-participant.data: -------------------------------------------------------------------------------- 1 | # Column 1: Bar group (1..3) 2 | # Column 2: SNARK computation time 3 | # Column 3: Encryption time 4 | # Column 4: Tree Verification time 5 | # Column 5: Total computation time (s) 6 | 1 54.06 7.83 0.320 61.91 #CMS 7 | 2 54.06 7.83 0.340 61.91 #SV 8 | 3 540.6 78.3 3.40 619.1 #Perc 9 | 4 54.06 7.83 0.340 61.91 #ID3 10 | 5 270.3 39.15 1.87 310.1 #k-means 11 | 6 54.06 7.83 0.320 61.91 #PCA 12 | 7 1080.6 156.6 7 1232.1 #NN 13 | 8 270.3 39.15 1.87 310.1 #kmedian 14 | 9 54.06 7.83 0.320 61.91 #bloom 15 | 10 108.06 15.66 0.7 123.21 #NB 16 | 11 54.06 7.83 0.320 61.91 #LogReg 17 | 12 54.06 7.83 0.320 61.91 #Hist 18 | 13 54.06 7.83 0.320 61.91 #CDF 19 | 14 54.06 7.83 0.320 61.91 #Range 20 | 21 | -------------------------------------------------------------------------------- /total_costs/data/bw-agg.data: -------------------------------------------------------------------------------- 1 | # Column 2: Bandwidth sent by aggregator (bytes) 2 | # Column 3: Bandwidth received by aggregator (bytes) 3 | 4 | 1 1449134205014600 85000000000000 #CMS 5 | 2 1449134205014600 85000000000000 #SV 6 | 3 14491342050146000 850000000000000 #Perc 7 | 4 1449134205014600 85000000000000 # ID3 8 | 5 7249134205014600 425000000000000 # kmeans 9 | 6 1449134205014600 85000000000000 # PCA 10 | 7 28991342050146000 1700000000000000 #NN 11 | 8 7249134205014600 425000000000000 # kmedian 12 | 9 1449134205014600 85000000000000 # bloom 13 | 10 2899134205014600 170000000000000 # NB 14 | 11 1449134205014600 85000000000000 # LogReg 15 | 12 1449134205014600 85000000000000 # Hist 16 | 13 1449134205014600 85000000000000 # CDF 17 | 14 1449134205014600 85000000000000 # Range 18 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_new_threads/test_new_threads.mpc: -------------------------------------------------------------------------------- 1 | def f(): 2 | sint(0) * sint(0) 3 | cint(get_arg()).store_in_mem(get_arg()) 4 | test_mem(cint(get_arg()), get_arg()) 5 | 6 | def make_tapes(n=10): 7 | return [program.new_tape(f) for i in range(n)] 8 | 9 | counter = 0 10 | def inc(): 11 | global counter 12 | counter += 1 13 | return counter 14 | 15 | def run_tapes(a): 16 | b = [program.run_tape(i, inc()) for i in a] 17 | for i in b: 18 | program.join_tape(i) 19 | 20 | for i in range(5): 21 | run_tapes(make_tapes()) 22 | 23 | a = make_tapes() 24 | 25 | for i in range(10): 26 | run_tapes(a) 27 | 28 | x = make_tapes(1)[0] 29 | 30 | for i in range(15): 31 | run_tapes([x for i in range(4)]) 32 | 33 | program.malloc(counter, 'c') 34 | -------------------------------------------------------------------------------- /total_costs/data/scale-bw-agg.data: -------------------------------------------------------------------------------- 1 | # Column 1: Algorithm 2 | # Column 2: Bytes sent for aggregator (1 round) 3 | # Column 3: Bytes received for aggregator (1 round) 4 | # Column 4: Bytes sent for aggregator (3 rounds) 5 | # Column 5: Bytes received for aggregator (3 rounds) 6 | # Column 6: Bytes sent for aggregator (20 rounds) 7 | # Column 7: Bytes received for aggregator (20 rounds) 8 | 9 | 1 14491342050146 850000000000 43500000000000 2550000000000 290000000000000 17000000000000 10 | 2 144913420501460 8500000000000 435000000000000 25500000000000 2900000000000000 170000000000000 11 | 3 1449134205014600 85000000000000 4350000000000000 255000000000000 29000000000000000 1700000000000000 #1.3bil 12 | 4 14491342050146000 850000000000000 43500000000000000 2550000000000000 290000000000000000 17000000000000000 13 | -------------------------------------------------------------------------------- /extra_files/dpComparison.py: -------------------------------------------------------------------------------- 1 | import matplotlib 2 | import matplotlib.pyplot as plt 3 | import numpy as np 4 | 5 | # Formatting 6 | 7 | font = { 8 | 'size' : 15} 9 | 10 | matplotlib.rc('font', **font) 11 | 12 | # Data for plotting 13 | t = np.arange(0, 10**9, 1000) 14 | ldp = np.sqrt(t) 15 | gdp = np.log(t/0.01) 16 | 17 | 18 | fig, ax = plt.subplots() 19 | ax.plot(t, ldp) 20 | ax.plot(t, gdp) 21 | 22 | ax.set(xlabel='Number of users (N)', ylabel='Error in Count', 23 | title='Comparison of LDP and GDP') 24 | #ax.grid() 25 | plt.yscale("log") 26 | plt.xscale("log") 27 | plt.xticks([pow(10,i) for i in range(3,10)]) 28 | plt.yticks([pow(10,i) for i in range(1,5)]) 29 | 30 | #fig.subplots_adjust(left=None, bottom=None, right=None, wspace=None, hspace=0.1) 31 | fig.subplots_adjust(bottom=0.2) 32 | fig.savefig("dpComparison.png") 33 | plt.show() 34 | -------------------------------------------------------------------------------- /source/benchStart.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PROG_NAME=$1 4 | N_PLAYERS=$2 5 | N_IO=$3 6 | 7 | echo 'Compiling' $PROG_NAME 8 | reqs=$(./compile.py $PROG_NAME | grep "Program requires:") 9 | 10 | echo $reqs 11 | 12 | N_TRIPLES=$(echo $reqs | grep -o \'triple\'\)..\[0-9\]* | grep -o \[0-9\]*) 13 | N_BITS=$(echo $reqs | grep -o \'bit\'\)..\[0-9\]* | grep -o \[0-9\]*) 14 | N_SQUARES=$(echo $reqs | grep -o \'square\'\)..\[0-9\]* | grep -o \[0-9\]*) 15 | 16 | if [[ $N_TRIPLES == '' ]] 17 | then 18 | N_TRIPLES=1 # 1 instead of 0 since 0 represents infinity 19 | fi 20 | 21 | if [[ $N_BITS == '' ]] 22 | then 23 | N_BITS=1 24 | fi 25 | 26 | if [[ $N_SQUARES == '' ]] 27 | then 28 | N_SQUARES=1 29 | fi 30 | 31 | echo 32 | echo 'Measuring the runtime and communication cost of' $PROG_NAME 33 | 34 | COMM_T0=$(cat /proc/net/dev | grep -o lo..\[0-9\]* | grep -o \[0-9\]*) 35 | -------------------------------------------------------------------------------- /robustness/old_files/graph.py: -------------------------------------------------------------------------------- 1 | import kmeans 2 | import geogr 3 | import json 4 | import ast 5 | 6 | f = open("geogrOut", "r") 7 | 8 | while 1: 9 | header = f.readline() 10 | if not header: break 11 | header = header.split() 12 | NUM_CLUSTERS=3 13 | EPSILON=float(header[2]) 14 | RANDOM_INIT=(header[1] == 'True') 15 | EXP=int(header[0]) 16 | 17 | print header 18 | f.readline() 19 | ft = ast.literal_eval(f.readline()) 20 | f.readline() 21 | ff_clip = ast.literal_eval(f.readline()) 22 | f.readline() 23 | tf_clip = ast.literal_eval(f.readline()) 24 | f.readline() 25 | ff = ast.literal_eval(f.readline()) 26 | f.readline() 27 | tf = ast.literal_eval(f.readline()) 28 | 29 | print 'graphing' 30 | geogr.produce_graph(ff, ff_clip, ft, tf, tf_clip, NUM_CLUSTERS, EPSILON, EXP, RANDOM_INIT) 31 | f.close() 32 | -------------------------------------------------------------------------------- /robustness/old_files/ldpError.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | 3 | N = 10**9 4 | epsilon = 0.1 5 | loc, scale = 0., 1/epsilon 6 | iters = 10 7 | 8 | ldp = [] 9 | gdp = [] 10 | for j in range(iters): 11 | val = sum(np.random.laplace(loc, scale, N)) # all of the random noise 12 | ldp.append(abs(val)) 13 | gdp.append(abs(np.random.laplace(loc, scale, 1))) 14 | 15 | #if (j % 10 == 0): 16 | print 'iter %d' % j 17 | 18 | print 'N=%d, iters=%d' % (N, iters) 19 | print 'ldp mean: %f' % np.mean(ldp) 20 | print "ldp 5-confidence: [%f %f] " % (np.percentile(ldp, 5), np.percentile(ldp, 95)) 21 | print 'ldp 25-confidence: [%f %f]' % (np.percentile(ldp, 25), np.percentile(ldp, 75)) 22 | print 'gdp mean: %f' % np.mean(gdp) 23 | print 'gdp 5-confidence: [%f %f]' % (np.percentile(gdp, 5), np.percentile(gdp, 95)) 24 | print 'gdp 25-confidence: [%f %f]' % (np.percentile(gdp, 25), np.percentile(gdp, 75)) 25 | 26 | 27 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_float_sorting/test_float_sorting.mpc: -------------------------------------------------------------------------------- 1 | sfloat.vlen = 8 # Length of mantissa in bits 2 | sfloat.plen = 5 # Length of exponent in bits 3 | sfloat.kappa = 4 # Statistical security parameter for floats 4 | 5 | a = [sfloat(i) for i in [-.03,2]] 6 | a[0], a[1] = cond_swap(a[0], a[1]) 7 | test(a[0]) 8 | test(a[1]) 9 | 10 | a = [sfloat(i) for i in [3,0]] 11 | a[0], a[1] = cond_swap(a[0], a[1]) 12 | test(a[0]) 13 | test(a[1]) 14 | 15 | import random 16 | random.seed(0) 17 | a = [sfloat(random.uniform(-100,100)) for i in range(8)] 18 | odd_even_merge_sort(a) 19 | test(a[0]) 20 | test(a[1]) 21 | test(a[2]) 22 | test(a[3]) 23 | test(a[4]) 24 | test(a[5]) 25 | test(a[6]) 26 | test(a[7]) 27 | 28 | a = [sfloat(random.uniform(-100,100)) for i in range(8)] 29 | chunky_odd_even_merge_sort(a) 30 | test(a[0]) 31 | test(a[1]) 32 | test(a[2]) 33 | test(a[3]) 34 | test(a[4]) 35 | test(a[5]) 36 | test(a[6]) 37 | test(a[7]) 38 | -------------------------------------------------------------------------------- /mpc_files/Programs/tutorial/tutorial.mpc: -------------------------------------------------------------------------------- 1 | # (C) 2017 University of Bristol. See License.txt 2 | # (C) 2018 KU Leuven. See License.txt 3 | 4 | def test(actual, expected): 5 | actual = actual.reveal() 6 | print_ln('expected %s, got %s', expected, actual) 7 | 8 | # cint: clear integers modulo p 9 | # sint: secret integers modulo p 10 | 11 | a = sint(1) 12 | b = cint(2) 13 | 14 | test(a + b, 3) 15 | test(a + a, 2) 16 | test(a * b, 2) 17 | test(a * a, 1) 18 | test(a - b, -1) 19 | test(a < b, 1) 20 | test(a <= b, 1) 21 | test(a >= b, 0) 22 | test(a > b, 0) 23 | test(a == b, 0) 24 | test(a != b, 1) 25 | 26 | clear_a = a.reveal() 27 | 28 | # arrays and loops 29 | 30 | a = Array(100, sint) 31 | 32 | @for_range(100) 33 | def f(i): 34 | a[i] = sint(i)**2 35 | 36 | test(a[99], 99**2) 37 | 38 | # conditional 39 | 40 | if_then(cint(0)) 41 | a[0] = 123 42 | else_then() 43 | a[0] = 789 44 | end_if() 45 | 46 | test(a[0], 789) 47 | -------------------------------------------------------------------------------- /source/testd.sh: -------------------------------------------------------------------------------- 1 | N_1=$1 2 | N_2=$2 # where N_2 <= N1 3 | 4 | # Require THRESHOLD * 2 + 1 <= N2 5 | THRESHOLD=$3 6 | 7 | 8 | python chooseSubset.py ${N_1} ${N_2} > ./Data/subset.txt 9 | echo 'Subset chosen:' 10 | cat ./Data/subset.txt 11 | 12 | ./renameShares.sh ${N_2} ./Data ./Data/subset.txt 13 | 14 | N_PLAYERS=$N_2 15 | 16 | ./genSetupOptions.sh ${N_2} ${THRESHOLD} | ./Setup.x > /dev/null 17 | 18 | 19 | perl -E 'print "1\n", "1\n", "1\n"' > Player$(($N_PLAYERS - 1))\_in.txt 20 | 21 | for i in `seq 8192` 22 | do 23 | echo "1" >> publicin.txt 24 | done 25 | 26 | for (( i = 0; i <= $(($N_PLAYERS - 2)); i++ )) 27 | do 28 | ./Player.x $i Programs/decrypt > /dev/null 2> /dev/null & 29 | done 30 | 31 | time ( cat publicin.txt | ./Player.x $(($N_PLAYERS - 1)) Programs/decrypt > /dev/null 2> /dev/null ) 32 | 33 | 34 | COMM_T1=$(cat /proc/net/dev | grep -o lo..\[0-9]\* | grep -o \[0-9\]*) 35 | echo 'Communication Cost (bytes):' $(($COMM_T1 - $COMM_T0)) -------------------------------------------------------------------------------- /mpc_files/Programs/test_loop/test_loop.mpc: -------------------------------------------------------------------------------- 1 | c1_addr = 1000 2 | c2_addr = 1001 3 | 4 | 5 | def basic(cond): 6 | cint(cond).print_reg() 7 | t1 = sint(1) * cond 8 | print_reg(reveal(t1)) 9 | 10 | t = t1*t1 11 | a = reveal(t) 12 | store_in_mem(a, cond-1) 13 | cond -= 1 14 | return cond 15 | 16 | def outer(c1): 17 | def inner(c2): 18 | s1 = sint(1) * c1 19 | s2 = sint(1) * c2 20 | t = s1 * s2 21 | store_in_mem(reveal(t), 5*c1 + c2) 22 | c2 -=1 23 | return c2 24 | 25 | c2 = regint(5) 26 | do_loop(c2, inner) 27 | c1 -= 1 28 | return c1 29 | 30 | 31 | # basic loop 32 | t = regint(5) 33 | do_loop(t, basic) 34 | for i in range(5): 35 | test_mem((i+1)**2, i) 36 | 37 | # nested loop 38 | c1 = regint(5) 39 | do_loop(c1, outer) 40 | 41 | 42 | for i in range(1, 6): 43 | for j in range(1, 6): 44 | test_mem(i*j, 5*i + j) 45 | 46 | 47 | #:mode=python: 48 | -------------------------------------------------------------------------------- /mpc_files/Programs/above_threshold/above_threshold.mpc: -------------------------------------------------------------------------------- 1 | k = 39 2 | 3 | def laplace_fx(center, width): 4 | return center + sint.get_random_bit(width) 5 | 6 | orange_input_0_ = sint.get_private_input_from(k) 7 | 8 | def anonymous_fun_3_(empty_closure_1_): 9 | """ 10 | empty_closure_1_: () 11 | """ 12 | def anonymous_fun_4_(orange_input_0_): 13 | """ 14 | orange_input_0_: Double 15 | """ 16 | above_thresh_result_0_ = laplace_fx(1.0,orange_input_0_) 17 | above_thresh_result_0_ = MemValue(cfix(above_thresh_result_0_)) 18 | def above_thresh_true_fun_0_(): 19 | skip 20 | def above_thresh_false_fun_0_(): 21 | above_thresh_result_0_.write(cfix(10.0)) 22 | if_statement(above_thresh_result_0_ - cfix(10.0) > cfix(1.0),above_thresh_true_fun_0_,above_thresh_false_fun_0_) 23 | above_thresh_result_0_ = above_thresh_result_0_.read() 24 | return above_thresh_result_0_ 25 | return anonymous_fun_4_ 26 | 27 | anonymous_fun_3_(()) 28 | -------------------------------------------------------------------------------- /mpc_files/Programs/naive_bayes/naive_bayes.mpc: -------------------------------------------------------------------------------- 1 | k = 39 2 | 3 | def laplace_fx(center, width): 4 | return center + sint.get_random_bit(width) 5 | 6 | orange_input_19_ = sint.get_private_input_from(k) 7 | orange_input_20_ = sint.get_private_input_from(k) 8 | 9 | def anonymous_fun_101_(empty_closure_21_): 10 | """ 11 | empty_closure_21_: () 12 | """ 13 | def anonymous_fun_102_(par_release_input_9_): 14 | """ 15 | par_release_input_9_: (Double,Double) 16 | """ 17 | def anonymous_fun_103_(orange_input_19_): 18 | """ 19 | orange_input_19_: Double 20 | """ 21 | return laplace_fx(cfix(1.0),orange_input_19_) 22 | def anonymous_fun_104_(orange_input_20_): 23 | """ 24 | orange_input_20_: Double 25 | """ 26 | return laplace_fx(cfix(1.0),orange_input_20_) 27 | return (anonymous_fun_103_(par_release_input_9_[0]),anonymous_fun_104_(par_release_input_9_[1])) 28 | return anonymous_fun_102_ 29 | 30 | anonymous_fun_101_(()) 31 | -------------------------------------------------------------------------------- /test/testReconstruct.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | N_1=$1 4 | N_2=$2 # where N_2 <= N1 5 | 6 | # Require THRESHOLD * 2 + 1 <= N2 7 | THRESHOLD=$3 8 | 9 | #( make clean ; make progs ) > /dev/null 10 | 11 | rm ./Data/* 12 | 13 | seq ${N_1} > ./Data/evalPoints.txt 14 | 15 | ./genSetupOptions.sh ${N_1} ${THRESHOLD} | ./Setup.x > /dev/null 16 | 17 | 18 | # the 2 is the number of output shares 19 | echo 'Running part 1' 20 | ./benchmark.sh ./Programs/output_shares/ ${N_1} 2 21 | 22 | python chooseSubset.py ${N_1} ${N_2} > ./Data/subset.txt 23 | echo 'Subset chosen:' 24 | cat ./Data/subset.txt 25 | 26 | ./renameShares.sh ${N_2} ./Data ./Data/subset.txt 27 | 28 | ./modifyEvalPoints.sh ${N_2} ./Data/subset.txt ./Data/evalPoints.txt > ./Data/evalPoints.txt.new 29 | rm ./Data/evalPoints.txt 30 | mv ./Data/evalPoints.txt.new ./Data/evalPoints.txt 31 | 32 | ./genSetupOptions.sh ${N_2} ${THRESHOLD} | ./Setup.x > /dev/null 33 | 34 | echo 'Running part 2' 35 | ./benchmark.sh ./Programs/input_shares/ ${N_2} 3 36 | echo 'Result:' 37 | cat ./Data/Player0_out.txt 38 | -------------------------------------------------------------------------------- /Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ubuntu:16.04 2 | WORKDIR /root 3 | RUN apt-get update && apt-get install -y \ 4 | bzip2 \ 5 | doxygen \ 6 | g++ \ 7 | gcc \ 8 | git \ 9 | gnuplot \ 10 | libgmp3-dev \ 11 | m4 \ 12 | make \ 13 | patch \ 14 | python \ 15 | python-tk \ 16 | python-pip \ 17 | tmux \ 18 | vim \ 19 | wget \ 20 | yasm \ 21 | && wget -qO- https://get.haskellstack.org/ | sh 22 | 23 | RUN pip install --upgrade pip 24 | RUN pip install numpy 25 | RUN pip install haversine 26 | RUN pip install matplotlib 27 | 28 | ADD source/ /root/source 29 | ADD config/ /root/config 30 | ADD depends.sh . 31 | RUN ["bash", "depends.sh"] 32 | 33 | ADD SMtweaks/ /root/SMtweaks 34 | ADD test/ /root/test 35 | ADD install.sh . 36 | RUN ["bash", "install.sh"] 37 | 38 | ADD mpc_files/Programs/ /root/SCALE-MAMBA/Programs 39 | 40 | ADD README.md . 41 | 42 | ADD robustness/ /root/robustness 43 | ADD total_costs /root/total_costs 44 | 45 | RUN git clone https://github.com/hengchu/cps-fuzz.git && \ 46 | cd cps-fuzz && \ 47 | stack run 48 | 49 | CMD ["/bin/bash"] 50 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_array/test_array.mpc: -------------------------------------------------------------------------------- 1 | for k in range(10): 2 | for t in cint, sint: 3 | a = Array(10, t) 4 | 5 | print len(a) 6 | 7 | for i,j in enumerate(a): 8 | a[i] = j + i 9 | 10 | a = Array(1, cint) 11 | a[0] = 1234 12 | b = Array(None, cint, a.address) 13 | test(b[0], 1234) 14 | 15 | M = Matrix(2, 3, cint) 16 | @for_range(2) 17 | def f(i): 18 | @for_range(3) 19 | def f(j): 20 | M[i][j] = 10 * i + j 21 | 22 | test(M[0][0], 0) 23 | test(M[0][1], 1) 24 | test(M[0][2], 2) 25 | test(M[1][0], 10) 26 | test(M[1][1], 11) 27 | #test(M[1][2], 12) 28 | 29 | a = Array(100, cint) 30 | a.assign(range(100)) 31 | test(a[-1], 99) 32 | test(a[:][99], 99) 33 | test(a[50:][0], 50) 34 | test(a[:50][49], 49) 35 | test(a[::3][33], 99) 36 | test(a[50::3][16], 98) 37 | test(a[:50:3][16], 48) 38 | 39 | b = Array(100, cint) 40 | b[:] = a 41 | test(b[99], 99) 42 | b.assign_all(0) 43 | b[50:] = a[:50] 44 | test(b[99], 49) 45 | b.assign_all(0) 46 | b[:50] = a[:50] 47 | test(b[49], 49) 48 | b.assign_all(0) 49 | b[::3] = a[:34] 50 | test(b[99], 33) 51 | test(b[1], 0) 52 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_custom_array/test_custom_array.mpc: -------------------------------------------------------------------------------- 1 | sfloat.vlen = 8 # Length of mantissa in bits 2 | sfloat.plen = 5 # Length of exponent in bits 3 | sfloat.kappa = 4 # Statistical security parameter for floats 4 | 5 | n = 5 6 | value_type = sint 7 | 8 | A = value_type.Array(n) 9 | B = value_type.Array(n) 10 | C = value_type.Array(n) 11 | 12 | for i in range(n): 13 | A[i] = A.value_type(i) 14 | B[i] = B.value_type(i) 15 | C[i] = A[i] * B[i] 16 | 17 | test(C[0]) 18 | test(C[1]) 19 | test(C[2]) 20 | test(C[3]) 21 | test(C[4]) 22 | 23 | value_type = sfix 24 | A = value_type.Array(n) 25 | B = value_type.Array(n) 26 | C = value_type.Array(n) 27 | 28 | for i in range(n): 29 | A[i] = A.value_type(i) 30 | B[i] = B.value_type(i) 31 | C[i] = A[i] * B[i] 32 | 33 | test(C[0]) 34 | test(C[1]) 35 | test(C[2]) 36 | test(C[3]) 37 | test(C[4]) 38 | 39 | value_type = sfloat 40 | A = value_type.Array(n) 41 | B = value_type.Array(n) 42 | C = value_type.Array(n) 43 | 44 | for i in range(n): 45 | A[i] = A.value_type(i) 46 | B[i] = B.value_type(i) 47 | C[i] = A[i] * B[i] 48 | 49 | test(C[0]) 50 | test(C[1]) 51 | test(C[2]) 52 | test(C[3]) 53 | test(C[4]) -------------------------------------------------------------------------------- /source/keygen.mpc: -------------------------------------------------------------------------------- 1 | # Calls API to generate key pair for LWE 2 | # Generates and distributes shares of secret keys to k committee members 3 | # Public key is revealed to all 4 | 5 | from Compiler import mpc_math 6 | 7 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 8 | execfile('/root/SCALE-MAMBA/Programs/lwe/lwe.mpc') 9 | 10 | 11 | k = 19 # Size of committee (total protocol is k+1) 12 | 13 | l = 1 # Message length 14 | nBitsN = 13 15 | N_ = 1 # Half-width of binomial distribution 16 | lgM = 15 17 | N = 4096 # Security parameter 18 | 19 | # w is chosen so that w^n = -1 (mod p) 20 | # where p is the size of the prime field 21 | w2048 = cint(1662636632232769309036) 22 | r = Ring(nBitsN, w2048) 23 | 24 | lwe = LWE(r, N_, lgM, l) 25 | 26 | # Generating key pair (a,b) is public, s is secret 27 | [a, b, s] = lwe.key_gen() 28 | 29 | # Reveal a public list to all 30 | def print_list(a): 31 | for k in range(len(a)): 32 | print a[k] 33 | 34 | # Revealing public key to all 35 | print_list(a) 36 | print_list(b) 37 | 38 | # Generating shares for secret key 39 | for i in range(N): 40 | output_shares(0, s[i]) 41 | -------------------------------------------------------------------------------- /total_costs/figures/comp-agg.plot: -------------------------------------------------------------------------------- 1 | set terminal pdf color size 15.4cm,3.8cm font "Helvetica, 7" 2 | set output "figures/comp-agg.pdf" 3 | set grid 4 | set border 15 5 | set style fill solid 1.00 border -1 6 | set datafile missing '-' 7 | set boxwidth 0.25 absolute 8 | set key right top reverse 9 | set lmargin 12 10 | set bmargin 8 11 | set tmargin 1 12 | set xlabel font "Helvetica, 12" 13 | set ylabel font "Helvetica, 12" 14 | set xtics font "Helvetica, 10" 15 | set ytics font "Helvetica, 12" 16 | set xlabel "Algorithm\n(b)" 17 | set xlabel offset 0, -2, 0 18 | set ylabel "Computation (cores)" offset -3 19 | #set xtics nomirror ("CMS" 1, "LogReg" 2, "NB" 3, "k-means" 4, "NN" 5) 20 | set xtics nomirror ("Hcrisp" 0, "CMS" 1, "SV" 2, "Perc*" 3, "ID3*" 4, "kmean" 5, "PCA" 6, "NN*" 7, "kmedian" 8, "bloom" 9, "NB*" 10, "LogReg*" 11, "Hist" 12, "CDF" 13, "Range" 14) 21 | set xtics offset 0, -1, 0 22 | set ytics 0,10,5000 nomirror 23 | set logscale y 24 | plot [-0.5:14.5][0.1:9000] \ 25 | "data/honeycrisp.data" using ($1):($8) lt 2 lw 3 pt 2 ps 0.7 lc rgb "blue" with boxes fill pattern 2 notitle,\ 26 | "data/comp-agg.data" using ($1):($2) lt 2 lw 3 pt 2 ps 0.7 lc rgb "blue" with boxes notitle 27 | -------------------------------------------------------------------------------- /mpc_files/Programs/keygen/keygen.mpc: -------------------------------------------------------------------------------- 1 | # Calls API to generate key pair for LWE 2 | # Generates and distributes shares of secret keys to k committee members 3 | # Public key is revealed to all 4 | 5 | from Compiler import mpc_math 6 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 7 | execfile('/root/SCALE-MAMBA/Programs/lwe/lwe.mpc') 8 | 9 | # Encryption parameters 10 | k = 9 #Committee members (total participants is k+1) 11 | d = 10 #Array size 12 | l = d #Message size 13 | nBitsN = 13 14 | N_ = 1 # Half-width of binomial distribution 15 | lgM = 15 16 | N = l # Security parameter 17 | 18 | # w is chosen so that w^n = -1 (mod p) 19 | # where p is the size of the prime field 20 | w2048 = cint(1662636632232769309036) 21 | r = Ring(nBitsN, w2048) 22 | 23 | lwe = LWE(r, N_, lgM, l) 24 | 25 | # Generating key pair (a,b) is public, s is secret 26 | [a, b, s] = lwe.key_gen() 27 | 28 | # Reveal a public list to all 29 | def print_list(a): 30 | for k in range(len(a)): 31 | print a[k] 32 | 33 | # Revealing public key to all 34 | print_list(a) 35 | print_list(b) 36 | 37 | # Generating shares for secret key 38 | for i in range(N): 39 | output_shares(0, s[i]) 40 | -------------------------------------------------------------------------------- /robustness/old_files/ldpAttack.py: -------------------------------------------------------------------------------- 1 | import matplotlib 2 | import matplotlib.pyplot as plt 3 | import numpy as np 4 | 5 | # Formatting 6 | 7 | font = { 8 | 'size' : 15} 9 | 10 | d1 = 1000 11 | d = 470000 # number of words in webster 12 | 13 | matplotlib.rc('font', **font) 14 | 15 | # Data for plotting 16 | t = np.arange(10**4, 10**9, 1000) 17 | ldp_sig = [min(np.sqrt(ti*d),ti) for ti in t] 18 | gdp_sig = t 19 | 20 | ldp_less = [max(1,0.25 * ti / np.sqrt(d)) for ti in t] 21 | gdp_less = 0.25 * t 22 | 23 | fig, ax = plt.subplots() 24 | ax.plot(t, ldp_less, label="LDP - 25%") 25 | ax.plot(t, gdp_less, label="GDP - 25% ") 26 | ax.plot(t, ldp_sig, label="LDP - 100%") 27 | ax.plot(t, gdp_sig, label="GDP - 100%") 28 | ax.legend() 29 | 30 | ax.set(xlabel='Number of users (N)', ylabel='Number of users required to corrupt', 31 | title='LDP vs. GDP Poisoning Attack') 32 | #ax.grid() 33 | plt.yscale("log") 34 | plt.xscale("log") 35 | plt.xticks([pow(10,i) for i in range(4,10)]) 36 | plt.yticks([pow(10,i) for i in range(0,10)]) 37 | 38 | #fig.subplots_adjust(left=None, bottom=None, right=None, wspace=None, hspace=0.1) 39 | fig.subplots_adjust(bottom=0.2) 40 | fig.savefig("ldpAttack.png") 41 | plt.show() 42 | -------------------------------------------------------------------------------- /total_costs/figures/scale-comp-agg.plot: -------------------------------------------------------------------------------- 1 | set terminal pdf color size 5.7cm,4.8cm font "Helvetica, 7" 2 | set output "figures/scale-comp-agg.pdf" 3 | set border 15 4 | set style fill solid 1.00 border -1 5 | set datafile missing '-' 6 | set boxwidth 0.25 absolute 7 | set key right bottom reverse 8 | set lmargin 14 9 | set bmargin 8 10 | set tmargin 1 11 | set grid 12 | set key font "Helvetica, 10" 13 | set xlabel font "Helvetica, 12" 14 | set ylabel font "Helvetica, 12" 15 | set xtics font "Helvetica, 10" 16 | set ytics font "Helvetica, 12" 17 | set xlabel "Number of Participants\n(b)" 18 | set xlabel offset 0, -2, 0 19 | set ylabel "Computation (cores)" offset -4 20 | set xtics nomirror ("1.3*10^7" 1, "1.3*10^8" 2, "1.3*10^9" 3, "1.3*10^{10}" 4) 21 | set xtics offset 0, -1, 0 22 | set ytics 0,10,10000 nomirror 23 | set logscale y 24 | plot [0.5:4.5][0.1:10000] \ 25 | "data/scale-comp-agg.data" using ($1):($2) lt 2 lw 3 pt 2 ps 0.7 lc rgb "blue" with linespoints title "1 round",\ 26 | "data/scale-comp-agg.data" using ($1):($3) lt 2 lw 3 pt 2 ps 0.7 lc rgb "red" with linespoints title "3 rounds",\ 27 | "data/scale-comp-agg.data" using ($1):($4) lt 2 lw 3 pt 2 ps 0.7 lc rgb "green" with linespoints title "20 rounds" 28 | 29 | -------------------------------------------------------------------------------- /total_costs/figures/scale-bw-agg.plot: -------------------------------------------------------------------------------- 1 | set terminal pdf color size 5.7cm,4.8cm font "Helvetica, 7" 2 | set output "figures/scale-bw-agg.pdf" 3 | set border 15 4 | set grid 5 | set style fill solid 1.00 border -1 6 | set datafile missing '-' 7 | set boxwidth 0.25 absolute 8 | set key bottom right 9 | set key font "Helvetica, 10" 10 | set lmargin 15 11 | set bmargin 8 12 | set tmargin 1 13 | set xlabel font "Helvetica, 12" 14 | set ylabel font "Helvetica, 12" 15 | set xtics font "Helvetica, 10" 16 | set ytics font "Helvetica, 12" 17 | set xlabel "Number of Participants\n(a)" 18 | set xlabel offset 0, -2, 0 19 | set ylabel "Traffic (TB sent)" offset -3 20 | set xtics nomirror ("1.3*10^7" 1, "1.3*10^8" 2, "1.3*10^9" 3, "1.3*10^{10}" 4) 21 | set xtics offset 0, -1, 0 22 | set ytics 0.1,10,1000000 nomirror 23 | set logscale y 24 | plot [0.5:4.5][0.1:1000000] \ 25 | "data/scale-bw-agg.data" using ($1):($2/(1024*1024*1024*1024)) lt 2 lw 3 pt 2 ps 0.7 lc rgb "blue" with linespoints title "1 round",\ 26 | "data/scale-bw-agg.data" using ($1):($4/(1024*1024*1024*1024)) lt 2 lw 3 pt 2 ps 0.7 lc rgb "red" with linespoints title "3 rounds",\ 27 | "data/scale-bw-agg.data" using ($1):($6/(1024*1024*1024*1024)) lt 2 lw 3 pt 2 ps 0.7 lc rgb "green" with linespoints title "20 rounds" 28 | -------------------------------------------------------------------------------- /mpc_files/Programs/IO_demo/IO_demo.mpc: -------------------------------------------------------------------------------- 1 | 2 | open_channel(1000) 3 | # Write some data to file 4 | outp = [sint(1), sint(2), sint(3), sint(4)] 5 | output_shares(1000,*outp) 6 | close_channel(1000) 7 | 8 | a=open_channel(2000) 9 | print_ln("Return Value From Open_Channel 2000 = %s",a) 10 | open_channel(3000) 11 | print_ln("Enter a single share from each player") 12 | inp=[sint()] 13 | input_shares(2000,*inp) 14 | output_shares(3000,*inp) 15 | close_channel(2000) 16 | close_channel(3000) 17 | 18 | open_channel(0) 19 | open_channel(1) 20 | open_channel(10) 21 | open_channel(20) 22 | 23 | for i in range(5): 24 | print_ln("Player zero enter a private gfp number") 25 | a=sint.get_private_input_from(0) 26 | print_ln("Player one enter a private gfp number") 27 | b=sint.get_private_input_from(1,13) 28 | c=a*b 29 | print_ln("The product is being sent to player one") 30 | c.reveal_to(1) 31 | c.reveal_to(1,25) 32 | print_reg(reveal(a)) 33 | print_reg(reveal(b)) 34 | print_reg(reveal(c)) 35 | 36 | print_ln("Every one enter two values (these MUST be the same, otherwise an abort will occur)") 37 | print_ln("The first input is a gfp element, the second is a regint value"); 38 | d=cint.public_input() 39 | e=regint.public_input(10) 40 | print_ln("Printing these values"); 41 | d.public_output() 42 | e.public_output(20) 43 | 44 | close_channel(0) 45 | close_channel(1) 46 | close_channel(10) 47 | close_channel(20) 48 | 49 | -------------------------------------------------------------------------------- /source/benchmark.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PROG_NAME=$1 4 | N_PLAYERS=$2 5 | N_IO=$3 6 | 7 | echo 'Compiling' $PROG_NAME 8 | reqs=$(./compile.py $PROG_NAME | grep "Program requires:") 9 | 10 | echo $reqs 11 | 12 | N_TRIPLES=$(echo $reqs | grep -o \'triple\'\)..\[0-9\]* | grep -o \[0-9\]*) 13 | N_BITS=$(echo $reqs | grep -o \'bit\'\)..\[0-9\]* | grep -o \[0-9\]*) 14 | N_SQUARES=$(echo $reqs | grep -o \'square\'\)..\[0-9\]* | grep -o \[0-9\]*) 15 | 16 | if [[ $N_TRIPLES == '' ]] 17 | then 18 | N_TRIPLES=1 # 1 instead of 0 since 0 represents infinity 19 | fi 20 | 21 | if [[ $N_BITS == '' ]] 22 | then 23 | N_BITS=1 24 | fi 25 | 26 | if [[ $N_SQUARES == '' ]] 27 | then 28 | N_SQUARES=1 29 | fi 30 | 31 | echo 32 | echo 'Measuring the runtime and communication cost of' $PROG_NAME 33 | 34 | COMM_T0=$(cat /proc/net/dev | grep -o lo..\[0-9\]* | grep -o \[0-9\]*) 35 | 36 | for (( i = 0; i <= $(($N_PLAYERS - 2)); i++ )) 37 | do 38 | ./Player.x -max ${N_TRIPLES},${N_SQUARES},${N_BITS} -maxI ${N_IO} $i $PROG_NAME > /dev/null 2> /dev/null & 39 | done 40 | 41 | time (./Player.x -max ${N_TRIPLES},${N_SQUARES},${N_BITS} -maxI ${N_IO} $(($N_PLAYERS - 1)) $PROG_NAME > /dev/null 2> /dev/null ) 42 | 43 | COMM_T1=$(cat /proc/net/dev | grep -o lo..\[0-9]\* | grep -o \[0-9\]*) 44 | if [[ $COMM_T0 != '' ]] 45 | then 46 | echo 'Communication Cost (bytes):' $(($COMM_T1 - $COMM_T0)) 47 | else 48 | echo 'Communication Cost (bytes):' $COMM_T1 49 | fi -------------------------------------------------------------------------------- /source/run.sh: -------------------------------------------------------------------------------- 1 | #Keygen 2 | 3 | ./test0.sh 30 30 12 4 | 5 | N_PLAYERS=$N_1 6 | 7 | for (( i = 0; i <= $(($N_PLAYERS - 2)); i++ )) 8 | do 9 | ./Player.x $i Programs/keygen > /dev/null 2> /dev/null & 10 | done 11 | 12 | time (./Player.x $(($N_PLAYERS - 1)) Programs/keygen > /dev/null 2> /dev/null ) 13 | 14 | COMM_T1=$(cat /proc/net/dev | grep -o lo..\[0-9]\* | grep -o \[0-9\]*) 15 | echo 'Communication Cost (bytes):' $(($COMM_T1 - $COMM_T0)) 16 | 17 | 18 | 19 | 20 | #DECRYPT: testd.sh 21 | N_1=$1 22 | N_2=$2 # where N_2 <= N1 23 | 24 | # Require THRESHOLD * 2 + 1 <= N2 25 | THRESHOLD=$3 26 | 27 | 28 | python chooseSubset.py ${N_1} ${N_2} > ./Data/subset.txt 29 | echo 'Subset chosen:' 30 | cat ./Data/subset.txt 31 | 32 | ./renameShares.sh ${N_2} ./Data ./Data/subset.txt 33 | 34 | N_PLAYERS=$N_2 35 | 36 | ./genSetupOptions.sh ${N_2} ${THRESHOLD} | ./Setup.x > /dev/null 37 | 38 | 39 | perl -E 'print "1\n", "1\n", "1\n"' > Player$(($N_PLAYERS - 1))\_in.txt 40 | 41 | for i in `seq 8192` 42 | do 43 | echo "1" >> publicin.txt 44 | done 45 | 46 | for (( i = 0; i <= $(($N_PLAYERS - 2)); i++ )) 47 | do 48 | ./Player.x $i Programs/decrypt > /dev/null 2> /dev/null & 49 | done 50 | 51 | time ( cat publicin.txt | ./Player.x $(($N_PLAYERS - 1)) Programs/decrypt > /dev/null 2> /dev/null ) 52 | 53 | 54 | COMM_T1=$(cat /proc/net/dev | grep -o lo..\[0-9]\* | grep -o \[0-9\]*) 55 | echo 'Communication Cost (bytes):' $(($COMM_T1 - $COMM_T0)) 56 | 57 | 58 | -------------------------------------------------------------------------------- /mpc_files/Programs/simple_expm/simple_expm.mpc: -------------------------------------------------------------------------------- 1 | import mpc_math 2 | def fun_comp(g, f): 3 | def inner(x): 4 | return g(f(x)) 5 | return inner 6 | 7 | 8 | # Exponential mechanism, returns one value 9 | # Assuming we have a list of quality scores 10 | def exp_mech(scores): 11 | 12 | new_array = sint.Array(max_size) 13 | # new_array = scores 14 | 15 | # keep a running sum of the cost array. 16 | sum = MemValue(sfix(0.0)) 17 | n = len(new_array) 18 | @for_range(n) 19 | def f(i): 20 | sum.write(sum + new_array[i]) 21 | 22 | # this should be (log(sum)) to get number of bits we should sample from. 23 | # def while_body(): 24 | # x.write(x+1) 25 | # return (x < sum) 26 | # 27 | # x = MemValue(sint(0)) 28 | # do_while(while_body) 29 | 30 | #TODO: should be log(ceil(sum)) 31 | N_bits = 5 32 | 33 | # sample random int w/i range of total sum of costs 34 | #a = sint.get_random_int(N_bits) 35 | a = sfloat(sint.get_random_int(N_bits)) 36 | 37 | # Go through running sum again and pull out correct sampled value 38 | tmp = MemValue(sfix(0.0)) 39 | @for_range(len(scores)) 40 | def check(i): 41 | if(a <= tmp): 42 | # Return this index 43 | return i 44 | else: 45 | tmp.write(tmp + scores[i]) 46 | 47 | return tmp 48 | 49 | 50 | exp_mech([1.0,2.0,3.0]) 51 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_function/test_function.mpc: -------------------------------------------------------------------------------- 1 | test(cint(-2)) 2 | 3 | @function_block 4 | def f(): 5 | test(cint(-1)) 6 | 7 | test(cint(-3)) 8 | f() 9 | test(cint(-4)) 10 | 11 | @function_block 12 | def f(): 13 | test(cint(1)) 14 | 15 | @function_block 16 | def g(): 17 | test(cint(2)) 18 | f() 19 | 20 | g() 21 | 22 | @function_block 23 | def f(i): 24 | test(i, 3) 25 | 26 | f(3) 27 | 28 | @function_block 29 | def f(): 30 | @for_range(5) 31 | def g(i): 32 | test(i, 4) 33 | 34 | f() 35 | 36 | @for_range(6) 37 | def f(i): 38 | @function_block 39 | def g(i): 40 | test(i, 5) 41 | g(i) 42 | 43 | @function_block 44 | def e(l,m): 45 | test(l * 100 + m, 406) 46 | 47 | e(-1,-1) 48 | 49 | @function_block 50 | def g(j): 51 | a = [cint(100) for i in range(100)] 52 | @for_range(7) 53 | def h(k): 54 | sum(a) 55 | e(j,k) 56 | 57 | g(-1) 58 | 59 | @for_range(5) 60 | def f(i): 61 | g(i) 62 | 63 | 64 | @function_block 65 | def f(): 66 | return cint(8) 67 | 68 | test(f(), 8) 69 | 70 | @function_block 71 | def f(): 72 | return (sint(9), cint(10)), sint(11) 73 | 74 | res = f() 75 | test(res[0][0], 9) 76 | test(res[0][1], 10) 77 | test(res[1], 11) 78 | 79 | 80 | @function_block 81 | def f(i=1): 82 | return i 83 | 84 | test(f(), 1) 85 | test(f(2), 2) 86 | 87 | 88 | class A: 89 | def __init__(self, x): 90 | self.x = MemValue(regint(x)) 91 | @method_block 92 | def f(self): 93 | return self.x 94 | 95 | test(A(12).f(), 12) 96 | test(A(13).f(), 13) 97 | -------------------------------------------------------------------------------- /test/benchmark.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | PROG_NAME=$1 4 | N_PLAYERS=$2 5 | N_IO=$3 6 | VERBOSE=$4 7 | 8 | echo 'Compiling' $PROG_NAME 9 | reqs=$(./compile.py $PROG_NAME | grep "Program requires:") 10 | 11 | echo $reqs 12 | 13 | N_TRIPLES=$(echo $reqs | grep -o \'triple\'\)..\[0-9\]* | grep -o \[0-9\]*) 14 | N_BITS=$(echo $reqs | grep -o \'bit\'\)..\[0-9\]* | grep -o \[0-9\]*) 15 | N_SQUARES=$(echo $reqs | grep -o \'square\'\)..\[0-9\]* | grep -o \[0-9\]*) 16 | 17 | if [[ $N_TRIPLES == '' ]] 18 | then 19 | N_TRIPLES=1 # 1 instead of 0 since 0 represents infinity 20 | fi 21 | 22 | if [[ $N_BITS == '' ]] 23 | then 24 | N_BITS=1 25 | fi 26 | 27 | if [[ $N_SQUARES == '' ]] 28 | then 29 | N_SQUARES=1 30 | fi 31 | 32 | echo 33 | echo 'Measuring the runtime and communication cost of' $PROG_NAME 34 | 35 | COMM_T0=$(cat /proc/net/dev | grep -o lo..\[0-9\]* | grep -o \[0-9\]*) 36 | 37 | for (( i = 0; i <= $(($N_PLAYERS - 2)); i++ )) 38 | do 39 | if [$VERBOSE != ''] 40 | then 41 | ./Player.x -max ${N_TRIPLES},${N_SQUARES},${N_BITS} -maxI ${N_IO} $i $PROG_NAME > /dev/null 2> /dev/null & 42 | else 43 | ./Player.x -max ${N_TRIPLES},${N_SQUARES},${N_BITS} -maxI ${N_IO} $i $PROG_NAME & 44 | fi 45 | done 46 | 47 | time (./Player.x -max ${N_TRIPLES},${N_SQUARES},${N_BITS} -maxI ${N_IO} $(($N_PLAYERS - 1)) $PROG_NAME > /dev/null 2> /dev/null ) 48 | 49 | COMM_T1=$(cat /proc/net/dev | grep -o lo..\[0-9]\* | grep -o \[0-9\]*) 50 | if [[ $COMM_T0 != '' ]] 51 | then 52 | echo 'Communication Cost (bytes):' $(($COMM_T1 - $COMM_T0)) 53 | else 54 | echo 'Communication Cost (bytes):' $COMM_T1 55 | fi 56 | 57 | -------------------------------------------------------------------------------- /source/decrypt.mpc: -------------------------------------------------------------------------------- 1 | from Compiler import mpc_math 2 | 3 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 4 | execfile('/root/SCALE-MAMBA/Programs/lwe/lwe.mpc') 5 | 6 | 7 | # Number of committee members (full protocol has k+1 users) 8 | k = 19 9 | 10 | l = 1 11 | nBitsN = 13 12 | N_ = 1 # Half-width of binomial distribution 13 | lgM = 31 14 | 15 | # w is chosen so that w^n = -1 (mod p) 16 | # where p is the size of the prime field 17 | w = cint(216409912179401900965416891955038263635)**8 18 | 19 | r = Ring(nBitsN, w) 20 | 21 | lwe = LWE(r, N_, lgM, l) 22 | 23 | # Length of messages 24 | N = 4096 25 | 26 | def encrypt(a, b, n): 27 | [u, v] = lwe.enc(a,b,n) 28 | return u 29 | 30 | def decrypt(enc_u, enc_v, s): 31 | return lwe.dec(enc_u, enc_v, s) 32 | 33 | 34 | # A provides encrypted aggregate data, threshold 35 | enc_u = cint.Array(N) 36 | enc_v = cint.Array(N) 37 | 38 | @for_range(N) 39 | def set_U(i): 40 | enc_u[i] = cint.public_input(k) 41 | 42 | @for_range(N) 43 | def set_V(i): 44 | enc_v[i] = cint.public_input(k) 45 | 46 | 47 | T = sint.get_private_input_from(k) 48 | delta = sint.get_private_input_from(k) 49 | 50 | s = sint.Array(N) 51 | #for i in range(N): 52 | @for_range(N) 53 | def copy(i): 54 | tmp = [sint()] 55 | input_shares(0, *tmp) 56 | s[i] = tmp[0] 57 | 58 | # Decrypts by using shares of secret key, noises, and compares to threshold. 59 | # Need to add appropriate noise to all elements 60 | z = decrypt(enc_u, enc_v, s)[0] + sint.get_random_bit() 61 | 62 | # Returns message if sufficiently far from delta, otherwise returns null. 63 | if (mpc_math.abs_fx(z - T) < delta): 64 | print_ln("0") 65 | else: 66 | print_ln("Text is %s", z.reveal_to[k]); 67 | -------------------------------------------------------------------------------- /mpc_files/Programs/decrypt/decrypt.mpc: -------------------------------------------------------------------------------- 1 | from Compiler import mpc_math 2 | 3 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 4 | execfile('/root/SCALE-MAMBA/Programs/lwe/lwe.mpc') 5 | 6 | 7 | # Number of committee members (full protocol has k+1 users) 8 | k = 9 9 | 10 | l = 1 11 | nBitsN = 13 12 | N_ = 1 # Half-width of binomial distribution 13 | lgM = 31 14 | 15 | # w is chosen so that w^n = -1 (mod p) 16 | # where p is the size of the prime field 17 | w = cint(216409912179401900965416891955038263635)**8 18 | 19 | r = Ring(nBitsN, w) 20 | 21 | lwe = LWE(r, N_, lgM, l) 22 | 23 | # Length of messages 24 | N = 4096 25 | 26 | def encrypt(a, b, n): 27 | [u, v] = lwe.enc(a,b,n) 28 | return u 29 | 30 | def decrypt(enc_u, enc_v, s): 31 | return lwe.dec(enc_u, enc_v, s) 32 | 33 | 34 | # A provides encrypted aggregate data, threshold 35 | enc_u = cint.Array(N) 36 | enc_v = cint.Array(N) 37 | 38 | @for_range(N) 39 | def set_U(i): 40 | enc_u[i] = cint.public_input(k) 41 | 42 | @for_range(N) 43 | def set_V(i): 44 | enc_v[i] = cint.public_input(k) 45 | 46 | 47 | T = sint.get_private_input_from(k) 48 | delta = sint.get_private_input_from(k) 49 | 50 | s = sint.Array(N) 51 | #for i in range(N): 52 | @for_range(N) 53 | def copy(i): 54 | tmp = [sint()] 55 | input_shares(0, *tmp) 56 | s[i] = tmp[0] 57 | 58 | # Decrypts by using shares of secret key, noises, and compares to threshold. 59 | # Need to add appropriate noise to all elements 60 | z = decrypt(enc_u, enc_v, s)[0] + sint.get_random_bit() 61 | 62 | # Returns message if sufficiently far from delta, otherwise returns null. 63 | if (mpc_math.abs_fx(z - T) < delta): 64 | print_ln("0") 65 | else: 66 | print_ln("Text is %s", z.reveal_to[k]); 67 | -------------------------------------------------------------------------------- /total_costs/figures/comp-participant.plot: -------------------------------------------------------------------------------- 1 | set terminal pdf color size 15.4cm,3.8cm font "Helvetica, 7" 2 | set output "figures/comp-participant.pdf" 3 | set border 15 4 | set grid 5 | set style fill solid 1.00 border -1 6 | set datafile missing '-' 7 | set boxwidth 0.25 absolute 8 | set key right top reverse 9 | #set style data boxes 10 | #set size 0.7,0.5 11 | set lmargin 11 12 | set bmargin 8 13 | set tmargin 1 14 | set xtics font "Helvetica, 12" 15 | set ytics font "Helvetica, 12" 16 | set xlabel font "Helvetica, 12" 17 | set ylabel font "Helvetica, 12" 18 | set key font "Helvetica, 12" 19 | set xlabel "Algorithm\n(b)" 20 | set xlabel offset 0, -1.5, 0 21 | set ylabel "Computation (min)" offset -3 22 | #set xtics nomirror ("CMS" 1, "LogReg" 2, "NB" 3, "k-means" 4, "NN" 5) 23 | set xtics nomirror ("Hcrisp" 0, "CMS" 1, "SV" 2, "Perc*" 3, "ID3*" 4, "kmean" 5, "PCA" 6, "NN*" 7, "kmedian" 8, "bloom" 9, "NB*" 10, "LogReg*" 11, "Hist" 12, "CDF" 13, "Range" 14) 24 | set xtics offset 0, -0.5, 0 25 | set ytics 1,5,25 nomirror 26 | #set ytics 40,10,60 nomirror 27 | set logscale y 28 | plot [-0.5:14.5][0.1:25] \ 29 | "data/honeycrisp.data" using ($1):($12+$13+$14)/60 lt 2 lw 3 pt 2 ps 0.7 lc rgb "red" with boxes fill pattern 2 notitle,\ 30 | "data/honeycrisp.data" using ($1):($12+$13)/60 lt 1 lw 3 pt 1 ps 0.7 lc rgb "purple" with boxes fill pattern 2 notitle,\ 31 | "data/honeycrisp.data" using ($1):($14)/60 lt 1 lw 3 pt 1 ps 0.7 lc rgb "green" with boxes fill pattern 2 notitle,\ 32 | "data/comp-participant.data" using ($1):($2+$3+$4)/60 lt 1 lc rgb "red" with boxes title "Encryption",\ 33 | "data/comp-participant.data" using ($1):($2+$4)/60 lt 1 lc rgb "purple" with boxes title "Proof gen.",\ 34 | "data/comp-participant.data" using ($1):($4)/60 lt 1 lc rgb "green" with boxes title "Other" 35 | 36 | 37 | -------------------------------------------------------------------------------- /total_costs/figures/bw-agg.plot: -------------------------------------------------------------------------------- 1 | set term pdfcairo font "Helvetica, 7" 2 | #set terminal pdf color size 15.4cm,3.8cm font "Helvetica, 7" 3 | set terminal pdf color size 15.4cm,3.8cm 4 | set output "figures/bw-agg.pdf" 5 | set border 15 6 | set grid 7 | set style fill solid 1.00 border -1 8 | set datafile missing '-' 9 | set boxwidth 0.25 absolute 10 | set key right top reverse 11 | set lmargin 16 12 | set bmargin 8 13 | set tmargin 1 14 | set key font "Helvetica, 12" 15 | set xlabel font "Helvetica, 12" 16 | set ylabel font "Helvetica, 12" 17 | set xtics font "Helvetica, 12" 18 | set ytics font "Helvetica, 12" 19 | set xlabel "Algorithm\n(a)" 20 | set xlabel offset 0, -2, 0 21 | set ylabel "Traffic (TB)" offset -4 22 | #set xtics nomirror ("CMS" 1, "LogReg" 2, "NB" 3, "k-means" 4, "NN" 5) 23 | set xtics nomirror ("Hcrisp" 0, "CMS" 1, "SV" 2, "Perc*" 3, "ID3*" 4, "kmean" 5, "PCA" 6, "NN*" 7, "kmedian" 8, "bloom" 9, "NB*" 10, "LogReg*" 11, "Hist" 12, "CDF" 13, "Range" 14) 24 | set xtics offset 0, -1, 0 25 | set ytics 10,10,100000 nomirror 26 | set logscale y 27 | plot [-0.5:14.5][0.08:800000] \ 28 | "data/honeycrisp.data" using ($1):($6)/(1024 * 1024 * 1024 * 1024) lt 2 lw 3 pt 2 ps 0.7 lc rgb "green" with boxes fill pattern 2 notitle,\ 29 | "data/honeycrisp.data" using ($1+0.25):($7)/(1024 * 1024 * 1024 * 1024) lt 1 lw 3 pt 1 ps 0.7 lc rgb "blue" with boxes fill pattern 2 notitle,\ 30 | "data/bw-agg.data" using ($1):($2/(1024 * 1024 * 1024 * 1024)) lt 2 lw 3 pt 2 ps 0.7 lc rgb "green" with boxes title "Sent",\ 31 | "data/bw-agg.data" using ($1)+0.25:($3/(1024 * 1024 * 1024 * 1024)) lt 2 lw 3 pt 2 ps 0.7 lc rgb "blue" with boxes title "Received",\ 32 | 33 | # FOR LINES 34 | #"data/bw-agg.data" using ($1):($2/(1024 * 1024 * 1024 * 1024)) lt 2 lw 3 pt 2 ps 0.7 lc rgb "green" with linespoints title "Sent",\ 35 | -------------------------------------------------------------------------------- /total_costs/figures/bw-participant.plot: -------------------------------------------------------------------------------- 1 | set terminal pdf color size 15.4cm,3.8cm font "Helvetica, 7" 2 | set output "figures/bw-participant.pdf" 3 | set border 15 4 | set grid 5 | set size 1.0,1.0 6 | set style fill solid 1.00 border -1 7 | set datafile missing '-' 8 | set boxwidth 0.25 absolute 9 | set key right top reverse 10 | #set style data boxes 11 | #set size 0.7,0.5 12 | set lmargin 11 13 | set bmargin 8 14 | set tmargin 1 15 | set key font "Helvetica, 12" 16 | set xlabel font "Helvetica, 12" 17 | set ylabel font "Helvetica, 12" 18 | set xtics font "Helvetica, 12" 19 | set ytics font "Helvetica, 12" 20 | set xlabel "Algorithm\n(a)" 21 | set ylabel "Traffic (MB)" offset -3 22 | set xtics nomirror ("Hcrisp" 0, "CMS" 1, "SV" 2, "Perc*" 3, "ID3*" 4, "kmean" 5, "PCA" 6, "NN*" 7, "kmedian" 8, "bloom" 9, "NB*" 10, "LogReg*" 11, "Hist" 12, "CDF" 13, "Range" 14) 23 | #set xtics nomirror ("CMS" 1, "LogReg" 2, "NB" 3, "k-means" 4, "NN" 5) 24 | set xtics offset 0, -0.5, 0 25 | set xlabel offset 0, -1.5, 0 26 | #set ytics nomirror 27 | set ytics 0.2, 5, 25 28 | set logscale y 29 | plot [-0.5:14.5][0.1:25] \ 30 | "data/honeycrisp.data" using ($1):($11)/(1024*1024) lt 2 lw 3 pt 2 ps 0.7 lc rgb "blue" with boxes fill pattern 2 notitle,\ 31 | "data/honeycrisp.data" using ($1):($9+$10)/(1024*1024) lt 1 lw 3 pt 1 ps 0.7 lc rgb "yellow" with boxes fill pattern 2 notitle,\ 32 | "data/honeycrisp.data" using ($1):($9)/(1024*1024) lt 1 lw 3 pt 1 ps 0.7 lc rgb "green" with boxes fill pattern 2 notitle,\ 33 | "data/bw-participant.data" using 1:(($4)/(1024*1024)) lt 1 lc rgb "blue" with boxes title "Sum Verif.",\ 34 | "data/bw-participant.data" using 1:(($2+$3)/(1024*1024)) lt 1 lc rgb "yellow" with boxes title "Ciphertexts",\ 35 | "data/bw-participant.data" using 1:(($2)/(1024*1024)) lt 1 lc rgb "green" with boxes title "Range Proofs" 36 | 37 | 38 | -------------------------------------------------------------------------------- /mpc_files/Programs/bag_filter_sum_noise/bag_filter_sum_noise.mpc: -------------------------------------------------------------------------------- 1 | k = 39 2 | 3 | import math 4 | import mpc_math 5 | def fun_comp(g, f): 6 | def inner(x): 7 | return g(f(x)) 8 | return inner 9 | 10 | def laplace_fx(center, width): 11 | return center + sint.get_random_bit(width) 12 | 13 | orange_input_0_ = sint.Array(2) 14 | orange_input_1_ = sint.Array(2) 15 | orange_input_2_ = sint.Array(2) 16 | @for_range(2) 17 | def set(i): 18 | orange_input_0_[i] = sint.get_private_input_from(k) 19 | orange_input_1_[i] = sint.get_private_input_from(k) 20 | orange_input_2_[i] = sint.get_private_input_from(k) 21 | 22 | 23 | def anonymous_fun_21_(): 24 | """ 25 | empty_closure_1_: () 26 | """ 27 | def anonymous_fun_22_(par_release_input_1_): 28 | """ 29 | par_release_input_1_: (((Double,Double),(Double,Double)),(Double,Double)) 30 | """ 31 | def anonymous_fun_23_(par_release_input_0_): 32 | """ 33 | par_release_input_0_: ((Double,Double),(Double,Double)) 34 | """ 35 | def anonymous_fun_24_(orange_input_0_): 36 | """ 37 | orange_input_0_: (Double,Double) 38 | """ 39 | return laplace_fx(cfix(1.0),orange_input_0_[0] + orange_input_0_[1]) 40 | def anonymous_fun_25_(orange_input_1_): 41 | """ 42 | orange_input_1_: (Double,Double) 43 | """ 44 | return laplace_fx(cfix(2.0),orange_input_1_[0] + orange_input_1_[1]) 45 | return (anonymous_fun_24_(par_release_input_0_[0]),anonymous_fun_25_(par_release_input_0_[1])) 46 | def anonymous_fun_26_(orange_input_2_): 47 | """ 48 | orange_input_2_: (Double,Double) 49 | """ 50 | return laplace_fx(cfix(3.0),orange_input_2_[0] + orange_input_2_[1]) 51 | return (anonymous_fun_23_(par_release_input_1_[0]),anonymous_fun_26_(par_release_input_1_[1])) 52 | return anonymous_fun_22_ 53 | 54 | anonymous_fun_21_() 55 | -------------------------------------------------------------------------------- /source/Input_Output_File.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2017, The University of Bristol, Senate House, Tyndall Avenue, Bristol, BS8 1TH, United Kingdom. 3 | Copyright (c) 2018, COSIC-KU Leuven, Kasteelpark Arenberg 10, bus 2452, B-3001 Leuven-Heverlee, Belgium. 4 | 5 | All rights reserved 6 | */ 7 | #ifndef _InputOutputFile 8 | #define _InputOutputFile 9 | 10 | /* A simple IO class which just uses standard 11 | * input/output to communicate values 12 | * 13 | * Whereas share values are input/output using 14 | * a steam, with either human or non-human form 15 | */ 16 | 17 | #include "Input_Output_Base.h" 18 | 19 | #include 20 | using namespace std; 21 | 22 | class Input_Output_File : public Input_Output_Base 23 | { 24 | istream *fin; 25 | ostream *fout; 26 | istream *fsharein; 27 | ostream *fshareout; 28 | 29 | bool human; // Only affects share output 30 | 31 | public: 32 | Input_Output_File() 33 | : Input_Output_Base() 34 | { 35 | ; 36 | } 37 | 38 | void init(istream &f_in, ostream &f_out, ifstream &f_sharein, ofstream &f_shareout, bool human_type) 39 | { 40 | fin = &f_in; 41 | fout = &f_out; 42 | fsharein = &f_sharein; 43 | fshareout = &f_shareout; 44 | human= human_type; 45 | } 46 | 47 | virtual long open_channel(unsigned int channel); 48 | virtual void close_channel(unsigned int channel); 49 | 50 | virtual gfp private_input_gfp(unsigned int channel); 51 | virtual void private_output_gfp(const gfp &output, unsigned int channel); 52 | 53 | virtual void public_output_gfp(const gfp &output, unsigned int channel); 54 | virtual gfp public_input_gfp(unsigned int channel); 55 | 56 | virtual void public_output_int(const long output, unsigned int channel); 57 | virtual long public_input_int(unsigned int channel); 58 | 59 | virtual void output_share(const Share &S, unsigned int channel); 60 | virtual Share input_share(unsigned int channel); 61 | 62 | virtual void trigger(Schedule &schedule); 63 | 64 | virtual void debug_output(const stringstream &ss); 65 | 66 | virtual void crash(unsigned int PC, unsigned int thread_num); 67 | }; 68 | 69 | #endif 70 | -------------------------------------------------------------------------------- /source/lwe.mpc: -------------------------------------------------------------------------------- 1 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 2 | 3 | 4 | class LWE(object): 5 | 6 | # In order for decryption to work, 7 | # N and m=2^lgM must be chosen appropriately. 8 | # Namely, if you wish to do t ciphertext additions 9 | # and p is the size of the SCALE-MAMBA field, then need: 10 | # t*2*N^2 < p / (2*m) 11 | def __init__(self, r, N, lgM, l): 12 | self.r = r # Ring used 13 | self.N = N # Half-width of binomial distributions 14 | # m = Modulus of ciphertext additions 15 | # Require p = 1 (mod 2m), and m to be a power of 2 16 | self.lgM = lgM 17 | self.m = 2 ** lgM # Plaintext modulus (size per element) 18 | self.l = l # Plaintext length (number of elements) 19 | return 20 | 21 | # Returns [a, b, s] 22 | # (a, b) is the public key, s is the secret key 23 | def key_gen(self): 24 | r = self.r 25 | N = self.N 26 | a = r.ringRandClear() 27 | s = r.ringBinom(N) 28 | e = r.ringBinom(N) 29 | b = r.reveal(r.ringAdd(r.ringMulFast(a, s), e)) 30 | 31 | res = [a, b, s] 32 | return res 33 | 34 | # z is plaintext (array) of l elems each modulo m 35 | # returns ciphertext [u, v] 36 | def enc(self, a, b, z): 37 | r = self.r 38 | N = self.N 39 | m = self.m 40 | e0 = r.ringBinom(N) 41 | e1 = r.ringBinom(N) 42 | e2 = r.ringBinom(N) 43 | 44 | # u = a*e0 + e1 (mod q) 45 | u = r.ringMulFast(a, e0) 46 | u = r.ringAdd(u, e1) 47 | 48 | # v = b*e0 + e2 + round(p/m)z (mod p) 49 | mthP = cint(-1)/cint(m) 50 | 51 | zMthP = r.zero() 52 | 53 | for i in range(0, len(z)): 54 | zMthP[i] = z[i] * mthP 55 | 56 | v = r.ringMulFast(b, e0) 57 | v = r.ringAdd(v, e2) 58 | v = r.ringAdd(v, zMthP) 59 | 60 | res = [r.reveal(u), r.reveal(v)] 61 | return res 62 | 63 | 64 | def dec(self, u, v, s): 65 | r = self.r 66 | lgM = self.lgM 67 | m = 1 << lgM 68 | clearM = cint(m) 69 | zNoisy = r.ringSub(v, r.ringMulFast(u, s)) 70 | halfMthP = cint(-1)/(2*m) 71 | z = sint.Array(self.l) 72 | @for_range(self.l) 73 | def round(i): 74 | zRangeI = zNoisy[i] + halfMthP 75 | zNotchesI = zRangeI * clearM 76 | z[i] = m - 1 - ((zNotchesI - 1) % m) 77 | 78 | return z 79 | 80 | 81 | -------------------------------------------------------------------------------- /mpc_files/Programs/lwe/lwe.mpc: -------------------------------------------------------------------------------- 1 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 2 | 3 | 4 | class LWE(object): 5 | 6 | # In order for decryption to work, 7 | # N and m=2^lgM must be chosen appropriately. 8 | # Namely, if you wish to do t ciphertext additions 9 | # and p is the size of the SCALE-MAMBA field, then need: 10 | # t*2*N^2 < p / (2*m) 11 | def __init__(self, r, N, lgM, l): 12 | self.r = r # Ring used 13 | self.N = N # Half-width of binomial distributions 14 | # m = Modulus of ciphertext additions 15 | # Require p = 1 (mod 2m), and m to be a power of 2 16 | self.lgM = lgM 17 | self.m = 2 ** lgM # Plaintext modulus (size per element) 18 | self.l = l # Plaintext length (number of elements) 19 | return 20 | 21 | # Returns [a, b, s] 22 | # (a, b) is the public key, s is the secret key 23 | def key_gen(self): 24 | r = self.r 25 | N = self.N 26 | a = r.ringRandClear() 27 | s = r.ringBinom(N) 28 | e = r.ringBinom(N) 29 | b = r.reveal(r.ringAdd(r.ringMulFast(a, s), e)) 30 | 31 | res = [a, b, s] 32 | return res 33 | 34 | # z is plaintext (array) of l elems each modulo m 35 | # returns ciphertext [u, v] 36 | def enc(self, a, b, z): 37 | r = self.r 38 | N = self.N 39 | m = self.m 40 | e0 = r.ringBinom(N) 41 | e1 = r.ringBinom(N) 42 | e2 = r.ringBinom(N) 43 | 44 | # u = a*e0 + e1 (mod q) 45 | u = r.ringMulFast(a, e0) 46 | u = r.ringAdd(u, e1) 47 | 48 | # v = b*e0 + e2 + round(p/m)z (mod p) 49 | mthP = cint(-1)/cint(m) 50 | 51 | zMthP = r.zero() 52 | 53 | for i in range(0, len(z)): 54 | zMthP[i] = z[i] * mthP 55 | 56 | v = r.ringMulFast(b, e0) 57 | v = r.ringAdd(v, e2) 58 | v = r.ringAdd(v, zMthP) 59 | 60 | res = [r.reveal(u), r.reveal(v)] 61 | return res 62 | 63 | 64 | def dec(self, u, v, s): 65 | r = self.r 66 | lgM = self.lgM 67 | m = 1 << lgM 68 | clearM = cint(m) 69 | zNoisy = r.ringSub(v, r.ringMulFast(u, s)) 70 | halfMthP = cint(-1)/(2*m) 71 | z = sint.Array(self.l) 72 | @for_range(self.l) 73 | def round(i): 74 | zRangeI = zNoisy[i] + halfMthP 75 | zNotchesI = zRangeI * clearM 76 | z[i] = m - 1 - ((zNotchesI - 1) % m) 77 | 78 | return z 79 | 80 | 81 | -------------------------------------------------------------------------------- /source/norm.mpc: -------------------------------------------------------------------------------- 1 | from Compiler import mpc_math 2 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 3 | execfile('/root/SCALE-MAMBA/Programs/lwe/lwe.mpc') 4 | 5 | 6 | # Number of committee members (full protocol has k+1 users) 7 | k = 19 8 | 9 | # Encryption parameters 10 | l = 1 11 | nBitsN = 13 12 | N_ = 1 # Half-width of binomial distribution 13 | lgM = 31 14 | 15 | # w is chosen so that w^n = -1 (mod p) 16 | # where p is the size of the prime field 17 | w = cint(216409912179401900965416891955038263635)**8 18 | r = Ring(nBitsN, w) 19 | lwe = LWE(r, N_, lgM, l) 20 | 21 | # Length of messages (array size) 22 | N = 4096 23 | 24 | # Basic encryption function 25 | def encrypt(a, b, n): 26 | [u, v] = lwe.enc(a,b,n) 27 | return u 28 | 29 | # Basic decryption function 30 | def decrypt(enc_u, enc_v, s): 31 | return lwe.dec(enc_u, enc_v, s) 32 | 33 | # Returns message if sufficiently far from delta, otherwise returns null. 34 | def threshold(query_result, T, delta): 35 | if ((query_result - T) < delta): 36 | print_ln("0") 37 | else: 38 | print_ln("Result is is %s", query_result.reveal_to[k]); 39 | 40 | # Noises encryption appropriately and decrypts 41 | # by using shares of secret key. Returns noised (decrypted) result, 42 | # after applying any additional orange zone computation. 43 | def decryptAndNoise(enc_u, enc_v, s, w): 44 | 45 | # Specific query goes here: 46 | # In this case, just return the only (first) element and add noise 47 | z = decrypt(enc_u, enc_v, s)[0] + sint.get_random_bit() 48 | return z 49 | 50 | # A provides encrypted aggregate data, threshold, delta 51 | enc_u = cint.Array(N) 52 | enc_v = cint.Array(N) 53 | 54 | @for_range(N) 55 | def set_U(i): 56 | enc_u[i] = cint.public_input(k) 57 | 58 | @for_range(N) 59 | def set_V(i): 60 | enc_v[i] = cint.public_input(k) 61 | 62 | T = sint.get_private_input_from(k) 63 | delta = sint.get_private_input_from(k) 64 | 65 | # A also may provide some additional state (specific to query) 66 | # In this case: none 67 | w = 0 68 | 69 | s = sint.Array(N) 70 | #for i in range(N): 71 | @for_range(N) 72 | def copy(i): 73 | tmp = [sint()] 74 | input_shares(0, *tmp) 75 | s[i] = tmp[0] 76 | 77 | # Decryption and main orange zone computation 78 | query_result = decryptAndNoise(enc_u, enc_v, s, w) 79 | 80 | # Final release 81 | threshold(query_result, T, delta) -------------------------------------------------------------------------------- /mpc_files/Programs/test_branch/test_branch.mpc: -------------------------------------------------------------------------------- 1 | program.bit_length = 16 2 | program.security = 8 3 | 4 | s = sint(35) 5 | t = sint(34) 6 | store_in_mem(s, 50) 7 | store_in_mem(t, 51) 8 | c0 = regint(0) #reveal(s < t) # 0 9 | c1 = regint(1) #reveal(t < s) # 1 10 | 11 | test(c0) 12 | test(c1) 13 | #print 'c0 =', c0.value 14 | #print 'c1 =', c1.value 15 | 16 | 17 | # basic if/else 18 | def if0(): 19 | a = cint(0) 20 | a += load_secret_mem(50) 21 | store_in_mem(reveal(a), 0) 22 | 23 | def else0(): 24 | a = cint(25) 25 | a += load_secret_mem(50) 26 | store_in_mem(reveal(a), 0) 27 | 28 | def if1(): 29 | a = cint(4) 30 | a += load_secret_mem(51) 31 | store_in_mem(reveal(a), 1) 32 | 33 | def else1(): 34 | a = cint(26) 35 | a += load_secret_mem(51) 36 | store_in_mem(reveal(a), 1) 37 | 38 | def if2(): 39 | a = cint(222) 40 | store_in_mem(a, 2) 41 | 42 | def else2(): 43 | a = cint(111) 44 | store_in_mem(a, 2) 45 | 46 | # c0 = False 47 | if_statement(c0, if0, else0) 48 | test_mem(60, 0) 49 | 50 | c = cint(8) 51 | store_in_mem(c,3) 52 | test_mem(8, 3) 53 | 54 | # c1 = True 55 | if_statement(c1, if1, else1) 56 | test_mem(38, 1) 57 | 58 | c = cint(9) 59 | store_in_mem(c,4) 60 | test_mem(9, 4) 61 | 62 | # nested if 63 | def outer(): 64 | a = cint(23) 65 | b = load_secret_mem(50)*a 66 | store_in_mem(b, 10) 67 | store_in_mem(reveal(b), 10) 68 | 69 | def innerif(): 70 | t = load_secret_mem(10) 71 | t = reveal(t*t + 11) 72 | store_in_mem(t, 11) 73 | def innerelse(): 74 | t = load_secret_mem(10) 75 | store_in_mem(reveal(t*t*t), 11) 76 | 77 | if_statement(regint(reveal(b)), innerif, innerelse) 78 | 79 | c = cint(19) 80 | store_in_mem(c,12) 81 | test_mem(19, 12) 82 | 83 | if_statement(c1, outer) 84 | t = 23*35 85 | test_mem(t, 10) 86 | test_mem(t*t + 11, 11) 87 | 88 | 89 | #def if_outer(): 90 | # a = cint(23) 91 | # b = reveal(s*a) 92 | # b -= 500 93 | # store_in_mem(b, 10) 94 | # def if_inner(): 95 | # # can't do this as inner function can't modify names in enclosing scope 96 | # b += 500 97 | # store_in_mem(b,10) 98 | # if_statement(b, if_inner) 99 | 100 | #if_statement(c1, if_outer) 101 | 102 | 103 | #:mode=python: 104 | -------------------------------------------------------------------------------- /test/testd.sh: -------------------------------------------------------------------------------- 1 | N_1=$1 2 | N_2=$1 # where N_2 <= N1 #eliminating for now, subset is a bit messed up 3 | 4 | PROGRAM=$2 5 | 6 | echo 'Modifying Program files accordingly...' 7 | 8 | sed -i "10s/.*/k = $(($N_1-1)) \#Committee members (total participants is k+1)/" Programs/keygen/keygen.mpc 9 | sed -i "1s/.*/k = $(($N_1-1)) \#Committee members (total participants is k+1)/" Programs/$PROGRAM/$PROGRAM.mpc 10 | 11 | # Require THRESHOLD * 2 + 1 <= N2 12 | THRESHOLD=2 13 | 14 | 15 | echo 'Running key-gen protocol...' 16 | ./test0.sh $N_1 $N_2 $THRESHOLD 17 | 18 | #rm publicin.txt 19 | 20 | echo 'Set up for protocol run...' 21 | 22 | python chooseSubset.py ${N_1} ${N_2} > ./Data/subset.txt 23 | echo 'Subset chosen:' 24 | cat ./Data/subset.txt 25 | 26 | ./renameShares.sh ${N_2} ./Data ./Data/subset.txt > /dev/null 27 | 28 | N_PLAYERS=$N_2 29 | 30 | ./genSetupOptions.sh ${N_2} ${THRESHOLD} | ./Setup.x > /dev/null 31 | 32 | echo 'Compiling' $PROGRAM 33 | reqs=$(./compile.py Programs/$PROGRAM | grep "Program requires:") 34 | 35 | # For norm: 36 | #perl -E 'print "1\n", "1\n", "1\n"' > ./Data/Player$(($N_PLAYERS - 1))\_in.txt 37 | 38 | FILE="/Data/Player$(($N_PLAYERS - 1))\_in.txt" 39 | if [ -f $FILE ]; then 40 | rm $FILE 41 | fi 42 | 43 | for i in `seq 500` 44 | #for i in `seq 16386` 45 | do 46 | echo "1" >> ./Data/Player$(($N_PLAYERS - 1))\_in.txt 47 | done 48 | 49 | #getting rid of public input 50 | #for i in `seq 8192` 51 | #do 52 | # echo "1" >> publicin.txt 53 | #done''' 54 | 55 | COMM_T0=$(cat /proc/net/dev | grep -o lo..\[0-9]\* | grep -o \[0-9\]*) 56 | 57 | for (( i = 0; i <= $(($N_PLAYERS - 2)); i++ )) 58 | do 59 | #cat publicin.txt | ./Player.x $i Programs/$4 & 60 | #./Player.x $i Programs/$PROGRAM > /dev/null 2> /dev/null & 61 | ./Player.x $i Programs/$PROGRAM & 62 | done 63 | 64 | echo $Program 'costs for n='$N_1 ':' 65 | 66 | time (./Player.x $(($N_PLAYERS - 1)) Programs/$PROGRAM > /dev/null 2> /dev/null ) 67 | #time ( cat publicin.txt | ./Player.x $(($N_PLAYERS - 1)) Programs/$4 > /dev/null 2> /dev/null ) 68 | #time ( ./Player.x $(($N_PLAYERS - 1)) Programs/$PROGRAM > /dev/null 2> /dev/null ) 69 | 70 | 71 | COMM_T1=$(cat /proc/net/dev | grep -o lo..\[0-9]\* | grep -o \[0-9\]*) 72 | 73 | if [[ $COMM_T0 != '' ]] 74 | then 75 | echo 'Communication Cost (bytes):' $(($COMM_T1 - $COMM_T0)) 76 | else 77 | echo 'Communication Cost (bytes):' $COMM_T1 78 | fi 79 | -------------------------------------------------------------------------------- /mpc_files/Programs/simple_release/simple_release.mpc: -------------------------------------------------------------------------------- 1 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 2 | execfile('/root/SCALE-MAMBA/Programs/lwe/lwe.mpc') 3 | 4 | 5 | # Number of committee members (full protocol has k+1 users) 6 | k = 9 7 | 8 | # Encryption parameters 9 | l = 1 10 | nBitsN = 13 11 | N_ = 1 # Half-width of binomial distribution 12 | lgM = 31 13 | 14 | # w is chosen so that w^n = -1 (mod p) 15 | # where p is the size of the prime field 16 | w = cint(216409912179401900965416891955038263635)**8 17 | r = Ring(nBitsN, w) 18 | lwe = LWE(r, N_, lgM, l) 19 | 20 | # Length of messages (array size) 21 | N = 4096 22 | 23 | # Basic encryption function 24 | def encrypt(a, b, n): 25 | [u, v] = lwe.enc(a,b,n) 26 | return u 27 | 28 | # Basic decryption function 29 | def decrypt(enc_u, enc_v, s): 30 | cenc_u = cint.Array(N) 31 | cenc_v = cint.Array(N) 32 | @for_range(N) 33 | def reveal(i): 34 | cenc_u[i] = enc_u[i].reveal() 35 | cenc_v[i] = enc_v[i].reveal() 36 | return lwe.dec(cenc_u, cenc_v, s) 37 | 38 | # Noises encryption appropriately and decrypts 39 | # by using shares of secret key. Returns noised (decrypted) result, 40 | # after applying any additional orange zone computation. 41 | def decryptAndNoise(enc_u, enc_v, s, w): 42 | 43 | # Specific query goes here: 44 | # In this case, just add noise and return vector 45 | result = sint.Array(N) 46 | z = decrypt(enc_u, enc_v, s) 47 | 48 | @for_range(N) 49 | def noise_z(i): 50 | result[i] = z[i] + sint.get_random_bit() 51 | return result 52 | 53 | # A provides encrypted aggregate data, threshold, delta 54 | enc_u = sint.Array(N) 55 | enc_v = sint.Array(N) 56 | 57 | @for_range(N) 58 | def set_U(i): 59 | enc_u[i] = sint.get_private_input_from(k) 60 | 61 | @for_range(N) 62 | def set_V(i): 63 | enc_v[i] = sint.get_private_input_from(k) 64 | 65 | 66 | T = sint.get_private_input_from(k) 67 | delta = sint.get_private_input_from(k) 68 | 69 | # A also may provide some additional state (specific to query) 70 | # In this case: none 71 | w = 0 72 | 73 | s = sint.Array(N) 74 | #for i in range(N): 75 | @for_range(N) 76 | def copy(i): 77 | tmp = [sint()] 78 | input_shares(0, *tmp) 79 | s[i] = tmp[0] 80 | 81 | # Decryption and main orange zone computation 82 | query_result = decryptAndNoise(enc_u, enc_v, s, w) 83 | 84 | # Final release 85 | @for_range(N) 86 | def q_reveal(i): 87 | query_result[i].reveal_to(k) 88 | -------------------------------------------------------------------------------- /mpc_files/Programs/perceptron_iter/perceptron_iter.mpc: -------------------------------------------------------------------------------- 1 | k = 39 2 | 3 | def laplace_fx(center, width): 4 | return center + sint.get_random_bit(width) 5 | 6 | def anonymous_fun_5_(empty_closure_1_): 7 | """ 8 | empty_closure_1_: () 9 | """ 10 | def anonymous_fun_6_(orange_input_0_): 11 | """ 12 | orange_input_0_: Double 13 | """ 14 | return laplace_fx(cfix(1.0),orange_input_0_) 15 | return anonymous_fun_6_ 16 | 17 | 18 | def anonymous_fun_32_(empty_closure_3_): 19 | """ 20 | empty_closure_3_: () 21 | """ 22 | def anonymous_fun_33_(par_release_input_3_): 23 | """ 24 | par_release_input_3_: (Double,(Double,(Double,(Double,Double)))) 25 | """ 26 | def anonymous_fun_34_(orange_input_1_): 27 | """ 28 | orange_input_1_: Double 29 | """ 30 | return laplace_fx(cfix(1.0),orange_input_1_) 31 | def anonymous_fun_35_(par_release_input_2_): 32 | """ 33 | par_release_input_2_: (Double,(Double,(Double,Double))) 34 | """ 35 | def anonymous_fun_36_(orange_input_2_): 36 | """ 37 | orange_input_2_: Double 38 | """ 39 | return laplace_fx(cfix(1.0),orange_input_2_) 40 | def anonymous_fun_37_(par_release_input_1_): 41 | """ 42 | par_release_input_1_: (Double,(Double,Double)) 43 | """ 44 | def anonymous_fun_38_(orange_input_3_): 45 | """ 46 | orange_input_3_: Double 47 | """ 48 | return laplace_fx(cfix(1.0),orange_input_3_) 49 | def anonymous_fun_39_(par_release_input_0_): 50 | """ 51 | par_release_input_0_: (Double,Double) 52 | """ 53 | def anonymous_fun_40_(orange_input_4_): 54 | """ 55 | orange_input_4_: Double 56 | """ 57 | return laplace_fx(cfix(1.0),orange_input_4_) 58 | def anonymous_fun_41_(orange_input_5_): 59 | """ 60 | orange_input_5_: Double 61 | """ 62 | return laplace_fx(cfix(1.0),orange_input_5_) 63 | return (anonymous_fun_40_(par_release_input_0_[0]),anonymous_fun_41_(par_release_input_0_[1])) 64 | return (anonymous_fun_38_(par_release_input_1_[0]),anonymous_fun_39_(par_release_input_1_[1])) 65 | return (anonymous_fun_36_(par_release_input_2_[0]),anonymous_fun_37_(par_release_input_2_[1])) 66 | return (anonymous_fun_34_(par_release_input_3_[0]),anonymous_fun_35_(par_release_input_3_[1])) 67 | return anonymous_fun_33_ 68 | 69 | 70 | anonymous_fun_5_(()) 71 | anonymous_fun_32_(()) 72 | -------------------------------------------------------------------------------- /mpc_files/Programs/norm/norm.mpc: -------------------------------------------------------------------------------- 1 | from Compiler import mpc_math 2 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 3 | execfile('/root/SCALE-MAMBA/Programs/lwe/lwe.mpc') 4 | 5 | 6 | # Number of committee members (full protocol has k+1 users) 7 | k = 39 8 | 9 | # Encryption parameters 10 | l = 100 #Message size 11 | nBitsN = 13 12 | N_ = 1 # Half-width of binomial distribution 13 | lgM = 31 14 | 15 | # w is chosen so that w^n = -1 (mod p) 16 | # where p is the size of the prime field 17 | w = cint(216409912179401900965416891955038263635)**8 18 | r = Ring(nBitsN, w) 19 | lwe = LWE(r, N_, lgM, l) 20 | 21 | # Length of messages (array size) 22 | N = 4096 23 | 24 | # Basic encryption function 25 | def encrypt(a, b, n): 26 | [u, v] = lwe.enc(a,b,n) 27 | return u 28 | 29 | # Basic decryption function 30 | def decrypt(enc_u, enc_v, s): 31 | cenc_u = cint.Array(N) 32 | cenc_v = cint.Array(N) 33 | @for_range(N) 34 | def reveal(i): 35 | cenc_u[i] = enc_u[i].reveal() 36 | cenc_v[i] = enc_v[i].reveal() 37 | return lwe.dec(cenc_u, cenc_v, s) 38 | 39 | # Returns message if sufficiently far from delta, otherwise returns null. 40 | def threshold(query_result, T, delta): 41 | if ((query_result - T) < delta): 42 | print_ln("0") 43 | else: 44 | print_ln("Result is is %s", query_result.reveal_to[k]); 45 | 46 | # Noises encryption appropriately and decrypts 47 | # by using shares of secret key. Returns noised (decrypted) result, 48 | # after applying any additional orange zone computation. 49 | def decryptAndNoise(enc_u, enc_v, s, w): 50 | 51 | # Specific query goes here: 52 | # In this case, just return the only (first) element and add noise 53 | z = decrypt(enc_u, enc_v, s)[0] + sint.get_random_bit() 54 | return z 55 | 56 | # A provides encrypted aggregate data, threshold, delta 57 | enc_u = sint.Array(N) 58 | enc_v = sint.Array(N) 59 | 60 | @for_range(N) 61 | def set_U(i): 62 | enc_u[i] = sint.get_private_input_from(k) 63 | 64 | @for_range(N) 65 | def set_V(i): 66 | enc_v[i] = sint.get_private_input_from(k) 67 | 68 | 69 | T = sint.get_private_input_from(k) 70 | delta = sint.get_private_input_from(k) 71 | 72 | # A also may provide some additional state (specific to query) 73 | # In this case: none 74 | w = 0 75 | 76 | s = sint.Array(N) 77 | #for i in range(N): 78 | @for_range(N) 79 | def copy(i): 80 | tmp = [sint()] 81 | input_shares(0, *tmp) 82 | s[i] = tmp[0] 83 | 84 | # Decryption and main orange zone computation 85 | query_result = decryptAndNoise(enc_u, enc_v, s, w) 86 | 87 | # Final release 88 | threshold(query_result, T, delta) 89 | -------------------------------------------------------------------------------- /mpc_files/Programs/logistic_iter/logistic_iter.mpc: -------------------------------------------------------------------------------- 1 | k = 39 2 | 3 | def laplace_fx(center, width): 4 | return center + sint.get_random_bit(width) 5 | 6 | orange_input_0_ = sint.get_private_input_from(k) 7 | 8 | def anonymous_fun_3_(empty_closure_1_): 9 | """ 10 | empty_closure_1_: () 11 | """ 12 | def anonymous_fun_4_(orange_input_0_): 13 | """ 14 | orange_input_0_: Double 15 | """ 16 | return laplace_fx(cfix(1.0),orange_input_0_) 17 | return anonymous_fun_4_ 18 | 19 | 20 | 21 | def anonymous_fun_45_(empty_closure_3_): 22 | """ 23 | empty_closure_3_: () 24 | """ 25 | def anonymous_fun_46_(par_release_input_3_): 26 | """ 27 | par_release_input_3_: (Double,(Double,(Double,(Double,Double)))) 28 | """ 29 | def anonymous_fun_47_(orange_input_1_): 30 | """ 31 | orange_input_1_: Double 32 | """ 33 | return laplace_fx(cfix(1.0),orange_input_1_) 34 | def anonymous_fun_48_(par_release_input_2_): 35 | """ 36 | par_release_input_2_: (Double,(Double,(Double,Double))) 37 | """ 38 | def anonymous_fun_49_(orange_input_2_): 39 | """ 40 | orange_input_2_: Double 41 | """ 42 | return laplace_fx(cfix(1.0),orange_input_2_) 43 | def anonymous_fun_50_(par_release_input_1_): 44 | """ 45 | par_release_input_1_: (Double,(Double,Double)) 46 | """ 47 | def anonymous_fun_51_(orange_input_3_): 48 | """ 49 | orange_input_3_: Double 50 | """ 51 | return laplace_fx(cfix(1.0),orange_input_3_) 52 | def anonymous_fun_52_(par_release_input_0_): 53 | """ 54 | par_release_input_0_: (Double,Double) 55 | """ 56 | def anonymous_fun_53_(orange_input_4_): 57 | """ 58 | orange_input_4_: Double 59 | """ 60 | return laplace_fx(cfix(1.0),orange_input_4_) 61 | def anonymous_fun_54_(orange_input_5_): 62 | """ 63 | orange_input_5_: Double 64 | """ 65 | return laplace_fx(cfix(1.0),orange_input_5_) 66 | return (anonymous_fun_53_(par_release_input_0_[0]),anonymous_fun_54_(par_release_input_0_[1])) 67 | return (anonymous_fun_51_(par_release_input_1_[0]),anonymous_fun_52_(par_release_input_1_[1])) 68 | return (anonymous_fun_49_(par_release_input_2_[0]),anonymous_fun_50_(par_release_input_2_[1])) 69 | return (anonymous_fun_47_(par_release_input_3_[0]),anonymous_fun_48_(par_release_input_3_[1])) 70 | return anonymous_fun_46_ 71 | 72 | anonymous_fun_3_(()) 73 | anonymous_fun_45_(()) 74 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_branching/test_branching.mpc: -------------------------------------------------------------------------------- 1 | a = cint(5) 2 | 3 | # From 20 to 30 step 2 4 | @for_range(20, 30, 2) 5 | def f(i): 6 | test(i) 7 | test(a) 8 | 9 | #range_loop(f, 10) 10 | #range_loop(f, 10, 20) 11 | #range_loop(f, 20, 30, 2) 12 | 13 | # Function f() returns whether you want to repeat (0=No,1=Yes) 14 | @do_while 15 | def f(): 16 | test(cint(123), 123) 17 | return regint(0) 18 | 19 | p_i = 0 20 | store_in_mem(0, p_i) 21 | 22 | @do_while 23 | def f(): 24 | i = regint.load_mem(p_i) 25 | store_in_mem(i + 1, p_i) 26 | return not_(and_(lambda: regint(1), lambda: i)) 27 | 28 | test(regint.load_mem(p_i), 2) 29 | 30 | @while_do(lambda x: x < 10, regint(1)) 31 | def f(i): 32 | test(i, 9) 33 | return i + 1 34 | 35 | store_in_mem(0, 0) 36 | @while_do(lambda x: x < 0, regint(1)) 37 | def f(i): 38 | store_in_mem(i, 0) 39 | return i + 1 40 | test(load_clear_mem(0), 0) 41 | 42 | store_in_mem(0, 0) 43 | @for_range(1, regint(0)) 44 | def f(i): 45 | store_in_mem(i, 0) 46 | test(load_clear_mem(0), 0) 47 | 48 | @for_range(20, 0, -3) 49 | def f(i): 50 | test(i, 2) 51 | 52 | @for_range(20, 0, regint(-7)) 53 | def f(i): 54 | test(i, 6) 55 | 56 | sfloat.vlen = 8 # Length of mantissa in bits 57 | sfloat.plen = 5 # Length of exponent in bits 58 | sfloat.kappa = 4 # Statistical security parameter for floats 59 | 60 | x = MemValue(0) 61 | y = MemFloat(0) 62 | one = sfloat(1) 63 | test(y + one) 64 | 65 | if_then(regint(1)) 66 | x.write(1) 67 | y.write(1) 68 | else_then() 69 | x.write(2) 70 | y.write(2) 71 | end_if() 72 | 73 | test(x.read(), 1) 74 | test(y.read(), 1) 75 | 76 | x.write(0) 77 | y.write(0) 78 | 79 | @for_range(5) 80 | def f(i): 81 | x.write(x + 1) 82 | y.iadd(sfloat(1)) 83 | 84 | test(x.read(), 5) 85 | test(y.read(), 5) 86 | 87 | @for_range(10) 88 | def f(i): 89 | @for_range(10) 90 | def f(i): 91 | test(a) 92 | 93 | @for_range_parallel(3, 10) 94 | def f(i): 95 | cint(i).store_in_mem(i) 96 | 97 | for i in range(10): 98 | test_mem(i, i) 99 | 100 | def summer(x,y): 101 | return tuple(a + b for a,b in zip(x,y)) 102 | 103 | @map_reduce_single(10, 99, lambda: cint(0), summer) 104 | def f(i): 105 | return cint(1) 106 | test(f(), 99) 107 | 108 | @for_range_parallel(3, regint(10)) 109 | def f(i): 110 | cint(10 + i).store_in_mem(10 + i) 111 | 112 | for i in range(10, 20): 113 | test_mem(i, i) 114 | 115 | @for_range_parallel(3, regint(1)) 116 | def f(i): 117 | cint(20 + i).store_in_mem(20 + i) 118 | 119 | test_mem(20, 20) 120 | -------------------------------------------------------------------------------- /mpc_files/Programs/countMeanSketch/countMeanSketch.mpc: -------------------------------------------------------------------------------- 1 | from Compiler import mpc_math 2 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 3 | execfile('/root/SCALE-MAMBA/Programs/lwe/lwe.mpc') 4 | 5 | #SIMPLE COUNT WITHOUT SPARSE VECTOR RELEASE 6 | 7 | 8 | 9 | # Encryption parameters 10 | k = 29 #Committee members (total participants is k+1) 11 | d = 1000 #Array size 12 | l = d # Message size 13 | nBitsN = 13 14 | N_ = 1 # Half-width of binomial distribution 15 | lgM = 31 16 | 17 | # w is chosen so that w^n = -1 (mod p) 18 | # where p is the size of the prime field 19 | w = cint(216409912179401900965416891955038263635)**8 20 | r = Ring(nBitsN, w) 21 | lwe = LWE(r, N_, lgM, l) 22 | 23 | # Length of messages (array size) 24 | N = l 25 | 26 | # Basic encryption function 27 | def encrypt(a, b, n): 28 | [u, v] = lwe.enc(a,b,n) 29 | return u 30 | 31 | # Basic decryption function 32 | def decrypt(enc_u, enc_v, s): 33 | cenc_u = cint.Array(N) 34 | cenc_v = cint.Array(N) 35 | @for_range(N) 36 | def reveal(i): 37 | cenc_u[i] = enc_u[i].reveal() 38 | cenc_v[i] = enc_v[i].reveal() 39 | return lwe.dec(cenc_u, cenc_v, s) 40 | 41 | # Returns message if sufficiently far from delta, otherwise returns null. 42 | def threshold(query_result, T, delta): 43 | if ((query_result - T) < delta): 44 | print_ln("0") 45 | else: 46 | print_ln("Result is is %s", query_result.reveal_to[k]); 47 | 48 | # Noises encryption appropriately and decrypts 49 | # by using shares of secret key. Returns noised (decrypted) result, 50 | # after applying any additional orange zone computation. 51 | def decryptAndNoise(enc_u, enc_v, s, w): 52 | 53 | # Specific query goes here: 54 | # In this case, just return the only (first) element and add noise 55 | z = decrypt(enc_u, enc_v, s)[0] + sint.get_random_bit() 56 | return z 57 | 58 | # A provides encrypted aggregate data, threshold, delta 59 | enc_u = sint.Array(N) 60 | enc_v = sint.Array(N) 61 | 62 | @for_range(N) 63 | def set_U(i): 64 | enc_u[i] = sint.get_private_input_from(k) 65 | 66 | @for_range(N) 67 | def set_V(i): 68 | enc_v[i] = sint.get_private_input_from(k) 69 | 70 | 71 | T = sint.get_private_input_from(k) 72 | delta = sint.get_private_input_from(k) 73 | 74 | # A also may provide some additional state (specific to query) 75 | # In this case: none 76 | w = 0 77 | 78 | s = sint.Array(N) 79 | @for_range(N) 80 | def copy(i): 81 | tmp = [sint()] 82 | input_shares(0, *tmp) 83 | s[i] = tmp[0] 84 | 85 | # Decryption and main orange zone computation 86 | query_result = decryptAndNoise(enc_u, enc_v, s, w) 87 | 88 | # Final release 89 | print_ln("Result is is %s", query_result.reveal()); 90 | -------------------------------------------------------------------------------- /mpc_files/Programs/sparseVector/sparseVector.mpc: -------------------------------------------------------------------------------- 1 | from Compiler import mpc_math 2 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 3 | execfile('/root/SCALE-MAMBA/Programs/lwe/lwe.mpc') 4 | 5 | #SPARSE VECTOR - THRESHOLD RELEASE OF NOISED VALUE 6 | 7 | 8 | # Encryption parameters 9 | nBitsN = 13 10 | k = 29 #Committee members (total participants is k+1) 11 | d = 1000 #Array size 12 | l = d # Message size 13 | N_ = 1 # Half-width of binomial distribution 14 | lgM = 31 15 | 16 | # w is chosen so that w^n = -1 (mod p) 17 | # where p is the size of the prime field 18 | w = cint(216409912179401900965416891955038263635)**8 19 | r = Ring(nBitsN, w) 20 | lwe = LWE(r, N_, lgM, l) 21 | 22 | # Length of messages (array size) 23 | N = l 24 | 25 | # Basic encryption function 26 | def encrypt(a, b, n): 27 | [u, v] = lwe.enc(a,b,n) 28 | return u 29 | 30 | # Basic decryption function 31 | def decrypt(enc_u, enc_v, s): 32 | cenc_u = cint.Array(N) 33 | cenc_v = cint.Array(N) 34 | @for_range(N) 35 | def reveal(i): 36 | cenc_u[i] = enc_u[i].reveal() 37 | cenc_v[i] = enc_v[i].reveal() 38 | return lwe.dec(cenc_u, cenc_v, s) 39 | 40 | # Returns message if sufficiently far from delta, otherwise returns null. 41 | def threshold(query_result, T, delta): 42 | if ((query_result - T) < delta): 43 | print_ln("0") 44 | else: 45 | print_ln("Result is is %s", query_result.reveal()); 46 | 47 | # Noises encryption appropriately and decrypts 48 | # by using shares of secret key. Returns noised (decrypted) result, 49 | # after applying any additional orange zone computation. 50 | def decryptAndNoise(enc_u, enc_v, s, w): 51 | 52 | # Specific query goes here: 53 | # In this case, just return the only (first) element and add noise 54 | z = decrypt(enc_u, enc_v, s)[0] + sint.get_random_bit() 55 | return z 56 | 57 | # A provides encrypted aggregate data, threshold, delta 58 | enc_u = sint.Array(N) 59 | enc_v = sint.Array(N) 60 | 61 | @for_range(N) 62 | def set_U(i): 63 | enc_u[i] = sint.get_private_input_from(k) 64 | 65 | @for_range(N) 66 | def set_V(i): 67 | enc_v[i] = sint.get_private_input_from(k) 68 | 69 | 70 | T = sint.get_private_input_from(k) 71 | delta = sint.get_private_input_from(k) 72 | 73 | # A also may provide some additional state (specific to query) 74 | # In this case: none 75 | w = 0 76 | 77 | s = sint.Array(N) 78 | #for i in range(N): 79 | @for_range(N) 80 | def copy(i): 81 | tmp = [sint()] 82 | input_shares(0, *tmp) 83 | s[i] = tmp[0] 84 | 85 | # Decryption and main orange zone computation 86 | query_result = decryptAndNoise(enc_u, enc_v, s, w) 87 | 88 | # Final release 89 | threshold(query_result, T, delta) 90 | -------------------------------------------------------------------------------- /install.sh: -------------------------------------------------------------------------------- 1 | # download SCALE-MAMBA 2 | cd 3 | git clone https://github.com/KULeuven-COSIC/SCALE-MAMBA.git 4 | cd SCALE-MAMBA 5 | git checkout -b v1.2 3722a85 6 | mv /root/config/CONFIG.mine . 7 | 8 | # Custom IO 9 | mv /root/source/Player.cpp ./src/ 10 | mv /root/source/IO.h ./src/Input_Output/ 11 | mv /root/source/Input_Output_File.cpp ./src/Input_Output/ 12 | mv /root/source/Input_Output_File.h ./src/Input_Output/ 13 | 14 | mv /root/config/config.h ./src/config.h 15 | 16 | # Allow for custom Shamir evaluation points 17 | mv /root/SMtweaks/MSP.cpp ./src/LSSS/ 18 | mv /root/SMtweaks/MSP.h ./src/LSSS/ 19 | mv /root/SMtweaks/ShareData.cpp ./src/LSSS/ 20 | mv /root/SMtweaks/ShareData.h ./src/LSSS/ 21 | mv /root/SMtweaks/Setup.cpp ./src/ 22 | 23 | mv /root/source/benchmark.sh . 24 | 25 | # Scripts to allow changes to sharing scheme 26 | mv /root/config/publicin.txt . 27 | mv /root/config/genSetupOptions.sh . 28 | mv /root/config/chooseSubset.py . 29 | mv /root/config/modifyEvalPoints.sh . 30 | mv /root/config/renameShares.sh . 31 | mv /root/test/testReconstruct.sh . 32 | mv /root/test/test0.sh . 33 | mv /root/test/testd.sh . 34 | mv /root/test/incr.sh . 35 | mv /root/test/completeTest.sh . 36 | 37 | 38 | make progs 39 | 40 | # set up certificate authority 41 | SUBJ="/CN=www.example.com" 42 | cd Cert-Store 43 | 44 | openssl genrsa -out RootCA.key 4096 45 | openssl req -new -x509 -days 1826 -key RootCA.key \ 46 | -subj $SUBJ -out RootCA.crt 47 | 48 | # make 40 certificates. More can be added as necessary 49 | mkdir csr 50 | for ID in {0..39} 51 | do 52 | SUBJ="/CN=player$ID@example.com" 53 | openssl genrsa -out Player$ID.key 2048 54 | openssl req -new -key Player$ID.key -subj $SUBJ -out csr/Player$ID.csr 55 | openssl x509 -req -days 1000 -set_serial 101$ID \ 56 | -CA RootCA.crt -CAkey RootCA.key \ 57 | -in csr/Player$ID.csr -out Player$ID.crt 58 | done 59 | 60 | # Set up SCALE-MAMBA 61 | cd /root/SCALE-MAMBA 62 | ./genSetupOptions.sh 4 1 | ./Setup.x # By default set-up with 4 players 63 | 64 | # copy examples to correct locations 65 | cd /root/SCALE-MAMBA 66 | for EX in ring ring_test lwe lwe_test decrypt keygen norm perceptron 67 | do 68 | mkdir Programs/$EX 69 | cp /root/source/$EX.mpc Programs/$EX/ 70 | done 71 | 72 | for EX in input_shares output_shares 73 | do 74 | mkdir Programs/$EX 75 | cp /root/test/$EX.mpc Programs/$EX 76 | done 77 | 78 | cd /root/config 79 | ls 80 | for x in chooseSubset.py renameShare.sh genSetupMSP.sh 81 | do 82 | mkdir config/ 83 | cp $x config/$x 84 | done 85 | 86 | # add simple syntax highlighting 87 | cd 88 | mkdir -p .vim/syntax 89 | mv config/mamba.vim .vim/syntax 90 | mkdir .vim/ftdetect 91 | cd .vim/ftdetect 92 | echo "au BufNewFile,BufRead *.wir set filetype=mamba" > mamba.vim 93 | 94 | cd /root/SCALE-MAMBA 95 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_math/test_math.mpc: -------------------------------------------------------------------------------- 1 | a = sfix(-7.5) 2 | b = sfix(-6) 3 | c = sfix(-4.5) 4 | d = sfix(-3) 5 | 6 | e = sfix(3) 7 | f = sfix(4.5) 8 | g = sfix(6) 9 | h = sfix(7.5) 10 | 11 | # Test sin 12 | test(mpc_math.sin(a)) 13 | test(mpc_math.sin(b)) 14 | test(mpc_math.sin(c)) 15 | test(mpc_math.sin(d)) 16 | 17 | test(mpc_math.sin(e)) 18 | test(mpc_math.sin(f)) 19 | test(mpc_math.sin(g)) 20 | test(mpc_math.sin(h)) 21 | 22 | ## Test cos 23 | test(mpc_math.cos(a)) 24 | test(mpc_math.cos(b)) 25 | test(mpc_math.cos(c)) 26 | test(mpc_math.cos(d)) 27 | 28 | test(mpc_math.cos(e)) 29 | test(mpc_math.cos(f)) 30 | test(mpc_math.cos(g)) 31 | test(mpc_math.cos(h)) 32 | 33 | # Test tan 34 | test(mpc_math.tan(a)) 35 | test(mpc_math.tan(b)) 36 | test(mpc_math.tan(c)) 37 | test(mpc_math.tan(d)) 38 | 39 | test(mpc_math.tan(f)) 40 | test(mpc_math.tan(e)) 41 | test(mpc_math.tan(g)) 42 | test(mpc_math.tan(h)) 43 | 44 | # Test atan 45 | test(mpc_math.atan(a)) 46 | test(mpc_math.atan(b)) 47 | test(mpc_math.atan(c)) 48 | test(mpc_math.atan(d)) 49 | 50 | test(mpc_math.atan(f)) 51 | test(mpc_math.atan(e)) 52 | test(mpc_math.atan(g)) 53 | test(mpc_math.atan(h)) 54 | 55 | # Test asin 56 | a = sfix(0.1) 57 | b = sfix(0.3) 58 | c = sfix(0.5) 59 | d = sfix(0.9) 60 | e = sfix(-0.1) 61 | f = sfix(-0.3) 62 | g = sfix(-0.5) 63 | h = sfix(-0.9) 64 | 65 | test(mpc_math.asin(a)) 66 | test(mpc_math.asin(b)) 67 | test(mpc_math.asin(c)) 68 | test(mpc_math.asin(d)) 69 | test(mpc_math.asin(e)) 70 | test(mpc_math.asin(f)) 71 | test(mpc_math.asin(g)) 72 | test(mpc_math.asin(h)) 73 | 74 | 75 | # Test acos 76 | test(mpc_math.acos(a)) 77 | test(mpc_math.acos(b)) 78 | test(mpc_math.acos(c)) 79 | test(mpc_math.acos(d)) 80 | test(mpc_math.acos(e)) 81 | test(mpc_math.acos(f)) 82 | test(mpc_math.acos(g)) 83 | test(mpc_math.acos(h)) 84 | 85 | 86 | a = sfix(2) 87 | b = sfix(3) 88 | c = sfix(4) 89 | d = sfix(5) 90 | 91 | sfloat.vlen = 15 # Length of mantissa in bits 92 | sfloat.plen = 10 # Length of exponent in bits 93 | sfloat.kappa = 4 # Statistical security parameter for floats 94 | # Test log_2 95 | test(mpc_math.log2_fx(a)) 96 | test(mpc_math.log2_fx(b)) 97 | test(mpc_math.log2_fx(c)) 98 | test(mpc_math.log2_fx(d)) 99 | 100 | # Test exp_2 101 | test(mpc_math.exp2_fx(a)) 102 | test(mpc_math.exp2_fx(b)) 103 | test(mpc_math.exp2_fx(c)) 104 | test(mpc_math.exp2_fx(d)) 105 | 106 | # Test pow 107 | test(mpc_math.pow_fx(a,2),lower=3.5, upper=4.01) 108 | test(mpc_math.pow_fx(b,2),lower=8, upper=9) 109 | test(mpc_math.pow_fx(c,2),lower=15, upper=16.01) 110 | test(mpc_math.pow_fx(d,2),lower=24, upper=25) 111 | 112 | # Test log 113 | test(mpc_math.log_fx(a,3)) 114 | test(mpc_math.log_fx(b,3)) 115 | test(mpc_math.log_fx(c,3)) 116 | test(mpc_math.log_fx(d,3)) 117 | 118 | -------------------------------------------------------------------------------- /source/perceptronOld.mpc: -------------------------------------------------------------------------------- 1 | from Compiler.util import log2 2 | from ring import Ring 3 | from LWE import LWE 4 | 5 | # Number of committee members (full protocol has k+1 users) 6 | k = 9 7 | 8 | # Encryption parameters 9 | n = 2048 10 | nBitsN = 11 11 | N_ = 1 # Half-width of binomial distribution 12 | lgM = 15 13 | 14 | # w is chosen so that w^n = -1 (mod p) 15 | # where p is the size of the prime field 16 | w2048 = cint(1662636632232769309036) 17 | r = Ring(n, nBitsN, w2048) 18 | 19 | lwe = LWE(r, N_, lgM) 20 | 21 | # length of messages (array size) 22 | N = n 23 | 24 | def norm(z): 25 | mag = sint(0) 26 | for i in range(len(z)): 27 | mag += z[i]**2 28 | return mag 29 | 30 | def encrypt(a, b, n): 31 | [u, v] = lwe.enc(a,b,n) 32 | return u 33 | 34 | def decrypt(enc_u, enc_v, s): 35 | return lwe.dec(enc_u, enc_v, s) 36 | 37 | 38 | # Noises encryption with noise provided from k committee members, decrypts 39 | # by using shares of secret key, and returns noised (decrypted) result, 40 | # after applying any additional orange zone computation. 41 | def noiseAndDecrypt(a, b, enc_u, enc_v, secret_key_shares, noise, w): 42 | 43 | total_noise = Array(N, sint) 44 | s = Array(N, sint) 45 | 46 | for i in range(0, k): 47 | for j in range(N): 48 | # Reconstruct secret key 49 | s[j] += secret_key_shares[i][j] 50 | 51 | #Take all users' noise and sum up homomorphically 52 | total_noise[j] += noise[i][j] 53 | 54 | # Specific query goes here 55 | z = decrypt(enc_u, enc_v, s) 56 | w = w + z 57 | return w 58 | 59 | # Returns message if sufficiently far from delta, otherwise returns null. 60 | def threshold(query_result, T, delta): 61 | if (abs(query_result - T) < delta): 62 | print_ln("0") 63 | else: 64 | print_ln("Result is %s", query_result.reveal_to[k]); 65 | 66 | 67 | #Pull input from users 68 | 69 | # Get array of secret key shares and noise from each committee member 70 | secret_key_shares = Matrix(k, N, sint) 71 | noise = Matrix(k, N, sint) 72 | for i in range(k): 73 | for j in range(N): 74 | secret_key_shares[i][j] = sint.get_raw_input_from(i) 75 | noise[i][j] = sint.get_raw_input_from(i) 76 | 77 | 78 | # A provides public key, encrypted aggregate data, threshold 79 | 80 | a = [sint.get_raw_input_from(k) for i in range(N)] 81 | b = [sint.get_raw_input_from(k) for i in range(N)] 82 | enc_u = [sint.get_raw_input_from(k) for i in range(N)] 83 | enc_v = [sint.get_raw_input_from(k) for i in range(N)] 84 | T = sint.get_raw_input_from(k) 85 | delta = sint.get_raw_input_from(k) 86 | 87 | 88 | # State from aggregator (specific to query) 89 | 90 | # Previous round's weight vector, provided by aggregator 91 | w = sint.get_raw_input_from(k) 92 | 93 | # Decryption and main computation 94 | query_result = noiseAndDecrypt(a, b, enc_u, enc_v, secret_key_shares, noise, w) 95 | 96 | # Final release 97 | threshold(query_result, T, delta) 98 | 99 | -------------------------------------------------------------------------------- /source/perceptron.mpc: -------------------------------------------------------------------------------- 1 | from Compiler import mpc_math 2 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 3 | execfile('/root/SCALE-MAMBA/Programs/lwe/lwe.mpc') 4 | 5 | # Number of committee members (full protocol has k+1 users) 6 | k = 19 7 | 8 | # Encryption parameters 9 | l = 1 10 | nBitsN = 13 11 | N_ = 1 # Half-width of binomial distribution 12 | lgM = 31 13 | 14 | # w is chosen so that w^n = -1 (mod p) 15 | # where p is the size of the prime field 16 | w = cint(216409912179401900965416891955038263635)**8 17 | r = Ring(nBitsN, w) 18 | lwe = LWE(r, N_, lgM, l) 19 | 20 | # Length of messages (array size) 21 | N = 4096 22 | 23 | # Basic encryption function 24 | def encrypt(a, b, n): 25 | [u, v] = lwe.enc(a,b,n) 26 | return u 27 | 28 | # Basic decryption function 29 | def decrypt(enc_u, enc_v, s): 30 | return lwe.dec(enc_u, enc_v, s) 31 | 32 | # Returns L1 distance of two vectors of size N 33 | def dist(a, b, N): 34 | tmp = MemValue(sint(0)) 35 | 36 | @for_range(N) 37 | def dist(i): 38 | tmp.write(tmp + a[i] - b[i]) 39 | return tmp.read() 40 | 41 | # Returns message if sufficiently far from delta, otherwise returns null. 42 | def threshold(query_result, T, delta): 43 | if (dist(query_result, T, N) < delta): 44 | print_ln("0") 45 | else: 46 | print_ln("Result is is %s", query_result.reveal_to[k]); 47 | 48 | # Noises encryption appropriately and decrypts 49 | # by using shares of secret key. Returns noised (decrypted) result, 50 | # after applying any additional orange zone computation. 51 | def decryptAndNoise(enc_u, enc_v, s, w): 52 | 53 | # Specific query goes here: 54 | # In this case, just noise entire vector and sum result with old state 55 | result = sint.Array(N) 56 | z = decrypt(enc_u, enc_v, s) 57 | @for_range(N) 58 | def noise_z(i): 59 | result[i] = z[i] + sint.get_random_bit() + w[i] 60 | return result 61 | 62 | # A provides encrypted aggregate data, threshold, delta 63 | enc_u = cint.Array(N) 64 | enc_v = cint.Array(N) 65 | 66 | @for_range(N) 67 | def set_U(i): 68 | enc_u[i] = cint.public_input(k) 69 | 70 | @for_range(N) 71 | def set_V(i): 72 | enc_v[i] = cint.public_input(k) 73 | 74 | T = sint.Array(N) 75 | @for_range(N) 76 | def set_T(i): 77 | T[i] = sint.get_private_input_from(k) 78 | delta = sint.get_private_input_from(k) 79 | 80 | # A also may provide some additional state (specific to query) 81 | # In this case: previous round's weight vector, provided by aggregator 82 | w = sint.Array(N) 83 | @for_range(N) 84 | def set_w(i): 85 | w[i] = sint.get_private_input_from(k) 86 | 87 | # Secret shares provided by users 88 | s = sint.Array(N) 89 | @for_range(N) 90 | def copy(i): 91 | tmp = [sint()] 92 | input_shares(0, *tmp) 93 | s[i] = tmp[0] 94 | 95 | # Decryption and main orange zone computation 96 | query_result = decryptAndNoise(enc_u, enc_v, s, w) 97 | 98 | # Final release 99 | threshold(query_result, T, delta) -------------------------------------------------------------------------------- /mpc_files/Programs/kmeans/kmeans.mpc: -------------------------------------------------------------------------------- 1 | from Compiler import mpc_math 2 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 3 | execfile('/root/SCALE-MAMBA/Programs/lwe/lwe.mpc') 4 | 5 | # NOISED RELEASE OF NEW CLUSTER CENTERS 6 | 7 | 8 | 9 | # Encryption parameters 10 | k = 29 #Committee members (total participants is k+1) 11 | d = 1000 #Array size 12 | clusters = 5 13 | l = d # temporary solution!! TODO: NEED TO FIX THIS 14 | #l = d*clusters + clusters # Variable for protocol 15 | nBitsN = 13 16 | N_ = 1 # Half-width of binomial distribution 17 | lgM = 31 18 | 19 | # w is chosen so that w^n = -1 (mod p) 20 | # where p is the size of the prime field 21 | w = cint(216409912179401900965416891955038263635)**8 22 | r = Ring(nBitsN, w) 23 | lwe = LWE(r, N_, lgM, l) 24 | 25 | # Length of messages (array size) 26 | N = l 27 | 28 | # Basic encryption function 29 | def encrypt(a, b, n): 30 | [u, v] = lwe.enc(a,b,n) 31 | return u 32 | 33 | # Basic decryption function 34 | def decrypt(enc_u, enc_v, s): 35 | cenc_u = cint.Array(N) 36 | cenc_v = cint.Array(N) 37 | @for_range(N) 38 | def reveal(i): 39 | cenc_u[i] = enc_u[i].reveal() 40 | cenc_v[i] = enc_v[i].reveal() 41 | return lwe.dec(cenc_u, cenc_v, s) 42 | 43 | # Noises encryption appropriately and decrypts 44 | # by using shares of secret key. Returns noised (decrypted) result, 45 | # after applying any additional orange zone computation. 46 | def decryptAndNoise(enc_u, enc_v, s, w): 47 | 48 | # Specific query goes here: 49 | # In this case, just noise entire vector and divide by appropriate element 50 | result = sint.Array(N) 51 | z = decrypt(enc_u, enc_v, s) 52 | 53 | @for_range(N) 54 | def noise(i): 55 | result[i] = z[i] + sint.get_random_bit() 56 | 57 | @for_range(clusters) 58 | def compute(i): 59 | @for_range(d) 60 | def div(j): 61 | result[i+j] /= result[i] 62 | 63 | return result 64 | 65 | 66 | # A provides encrypted aggregate data 67 | enc_u = sint.Array(N) 68 | enc_v = sint.Array(N) 69 | 70 | @for_range(N) 71 | def set_U(i): 72 | enc_u[i] = sint.get_private_input_from(k) 73 | 74 | @for_range(N) 75 | def set_V(i): 76 | enc_v[i] = sint.get_private_input_from(k) 77 | 78 | # Optional parameters for Sparse Vector provided by A 79 | #T = sint.Array(N) 80 | #@for_range(N) 81 | #def set_T(i): 82 | # T[i] = sint.get_private_input_from(k) 83 | #delta = sint.get_private_input_from(k) 84 | 85 | # A also may provide some additional state (specific to query) 86 | # In this case: previous round's weight vector 87 | w = sint.Array(N) 88 | @for_range(N) 89 | def set_w(i): 90 | w[i] = sint.get_private_input_from(k) 91 | 92 | # Secret shares provided by users 93 | s = sint.Array(N) 94 | @for_range(N) 95 | def copy(i): 96 | tmp = [sint()] 97 | input_shares(0, *tmp) 98 | s[i] = tmp[0] 99 | 100 | # Decryption and main orange zone computation 101 | query_result = decryptAndNoise(enc_u, enc_v, s, w) 102 | 103 | #Final release 104 | @for_range(N) 105 | def q_reveal(i): 106 | query_result[i].reveal_to(k) 107 | -------------------------------------------------------------------------------- /mpc_files/Programs/perceptron/perceptron.mpc: -------------------------------------------------------------------------------- 1 | from Compiler import mpc_math 2 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 3 | execfile('/root/SCALE-MAMBA/Programs/lwe/lwe.mpc') 4 | # PERCEPTRON - ADDING TO OLD STATE 5 | 6 | 7 | 8 | # Encryption parameters 9 | nBitsN = 13 10 | k = 19 #Committee members (total participants is k+1) 11 | d = 1000 #Array size 12 | l = d #Message size 13 | N_ = 1 # Half-width of binomial distribution 14 | lgM = 31 15 | 16 | # w is chosen so that w^n = -1 (mod p) 17 | # where p is the size of the prime field 18 | w = cint(216409912179401900965416891955038263635)**8 19 | r = Ring(nBitsN, w) 20 | lwe = LWE(r, N_, lgM, l) 21 | 22 | # Length of messages (array size) 23 | N = l 24 | 25 | # Basic encryption function 26 | def encrypt(a, b, n): 27 | [u, v] = lwe.enc(a,b,n) 28 | return u 29 | 30 | # Basic decryption function 31 | def decrypt(enc_u, enc_v, s): 32 | cenc_u = cint.Array(N) 33 | cenc_v = cint.Array(N) 34 | @for_range(N) 35 | def reveal(i): 36 | cenc_u[i] = enc_u[i].reveal() 37 | cenc_v[i] = enc_v[i].reveal() 38 | return lwe.dec(cenc_u, cenc_v, s) 39 | 40 | # Returns L1 distance of two vectors of size N 41 | def dist(a, b, N): 42 | tmp = MemValue(sint(0)) 43 | 44 | @for_range(N) 45 | def dist(i): 46 | tmp.write(tmp + a[i] - b[i]) 47 | return tmp.read() 48 | 49 | # Returns message if sufficiently far from delta, otherwise returns null. 50 | def threshold(query_result, T, delta): 51 | if (dist(query_result, T, N) < delta): 52 | print_ln("0") 53 | else: 54 | @for_range(N) 55 | def q_reveal(i): 56 | query_result[i].reveal_to(k) 57 | 58 | # Noises encryption appropriately and decrypts 59 | # by using shares of secret key. Returns noised (decrypted) result, 60 | # after applying any additional orange zone computation. 61 | def decryptAndNoise(enc_u, enc_v, s, w): 62 | 63 | # Specific query goes here: 64 | # In this case, just noise entire vector and sum result with old state 65 | result = sint.Array(N) 66 | #z = sint.Array(N) 67 | z = decrypt(enc_u, enc_v, s) 68 | 69 | @for_range(N) 70 | def noise_z(i): 71 | result[i] = z[i] + sint.get_random_bit() + w[i] 72 | return result 73 | 74 | # A provides encrypted aggregate data 75 | enc_u = sint.Array(N) 76 | enc_v = sint.Array(N) 77 | 78 | @for_range(N) 79 | def set_U(i): 80 | enc_u[i] = sint.get_private_input_from(k) 81 | 82 | @for_range(N) 83 | def set_V(i): 84 | enc_v[i] = sint.get_private_input_from(k) 85 | 86 | # Optional parameters for Sparse Vector provided by A 87 | #T = sint.Array(N) 88 | #@for_range(N) 89 | #def set_T(i): 90 | # T[i] = sint.get_private_input_from(k) 91 | #delta = sint.get_private_input_from(k) 92 | 93 | # A also may provide some additional state (specific to query) 94 | # In this case: previous round's weight vector 95 | w = sint.Array(N) 96 | @for_range(N) 97 | def set_w(i): 98 | w[i] = sint.get_private_input_from(k) 99 | 100 | # Secret shares provided by users 101 | s = sint.Array(N) 102 | @for_range(N) 103 | def copy(i): 104 | tmp = [sint()] 105 | input_shares(0, *tmp) 106 | s[i] = tmp[0] 107 | 108 | # Decryption and main orange zone computation 109 | query_result = decryptAndNoise(enc_u, enc_v, s, w) 110 | 111 | # Final release 112 | #threshold(query_result, T, delta) 113 | for_range(N) 114 | def q_reveal(i): 115 | query_result[i].reveal_to(k) 116 | -------------------------------------------------------------------------------- /source/Input_Output_File.cpp: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2017, The University of Bristol, Senate House, Tyndall Avenue, Bristol, BS8 1TH, United Kingdom. 3 | Copyright (c) 2018, COSIC-KU Leuven, Kasteelpark Arenberg 10, bus 2452, B-3001 Leuven-Heverlee, Belgium. 4 | 5 | All rights reserved 6 | */ 7 | 8 | #include "Input_Output_File.h" 9 | #include "Exceptions/Exceptions.h" 10 | 11 | long Input_Output_File::open_channel(unsigned int channel) 12 | { 13 | cout << "Opening channel " << channel << endl; 14 | return 0; 15 | } 16 | 17 | void Input_Output_File::close_channel(unsigned int channel) 18 | { 19 | cout << "Closing channel " << channel << endl; 20 | } 21 | 22 | gfp Input_Output_File::private_input_gfp(unsigned int channel) 23 | { 24 | word x; 25 | (*fin) >> x; 26 | gfp y; 27 | y.assign(x); 28 | return y; 29 | } 30 | 31 | void Input_Output_File::private_output_gfp(const gfp &output, unsigned int channel) 32 | { 33 | (*fout) << "Output channel " << channel << " : "; 34 | output.output((*fout), true); 35 | (*fout) << endl; 36 | } 37 | 38 | gfp Input_Output_File::public_input_gfp(unsigned int channel) 39 | { 40 | cout << "Enter value on channel " << channel << " : "; 41 | word x; 42 | cin >> x; 43 | gfp y; 44 | y.assign(x); 45 | 46 | // Important to have this call in each version of public_input_gfp 47 | Update_Checker(y, channel); 48 | 49 | return y; 50 | } 51 | 52 | void Input_Output_File::public_output_gfp(const gfp &output, unsigned int channel) 53 | { 54 | (*fout) << "Output channel " << channel << " : "; 55 | output.output((*fout), true); 56 | (*fout) << endl; 57 | } 58 | 59 | long Input_Output_File::public_input_int(unsigned int channel) 60 | { 61 | cout << "Enter value on channel " << channel << " : "; 62 | long x; 63 | cin >> x; 64 | 65 | // Important to have this call in each version of public_input_gfp 66 | Update_Checker(x, channel); 67 | 68 | return x; 69 | } 70 | 71 | void Input_Output_File::public_output_int(const long output, unsigned int channel) 72 | { 73 | (*fout) << "Output channel " << channel << " : " << output << endl; 74 | } 75 | 76 | void Input_Output_File::output_share(const Share &S, unsigned int channel) 77 | { 78 | S.output(*fshareout, human); 79 | } 80 | 81 | Share Input_Output_File::input_share(unsigned int channel) 82 | { 83 | Share S; 84 | S.input(*fsharein, human); 85 | return S; 86 | } 87 | 88 | void Input_Output_File::trigger(Schedule &schedule) 89 | { 90 | printf("Restart requested: Enter a number to proceed\n"); 91 | int i; 92 | cin >> i; 93 | 94 | // Load new schedule file program streams, using the original 95 | // program name 96 | // 97 | // Here you could define programatically what the new 98 | // programs you want to run are, by directly editing the 99 | // public variables in the schedule object. 100 | unsigned int nthreads= schedule.Load_Programs(); 101 | if (schedule.max_n_threads() < nthreads) 102 | { 103 | throw Processor_Error("Restart requires more threads, cannot do this"); 104 | } 105 | } 106 | 107 | void Input_Output_File::debug_output(const stringstream &ss) 108 | { 109 | printf("%s", ss.str().c_str()); 110 | fflush(stdout); 111 | } 112 | 113 | void Input_Output_File::crash(unsigned int PC, unsigned int thread_num) 114 | { 115 | printf("Crashing in thread %d at PC value %d\n", thread_num, PC); 116 | throw crash_requested(); 117 | } 118 | -------------------------------------------------------------------------------- /total_costs/data_explanations: -------------------------------------------------------------------------------- 1 | ## Explanation of User and Aggregator Costs 2 | 3 | # Parameters used (choices explained in paper): 4 | N (num users) 1.3*10**9 5 | Lambda (Security parameter) 80 6 | n (The ring polynomial size) 2048 7 | p (Prime used in SCALE-MAMBA) 198766463529478683931867765928436695041 8 | length of p bits 128 9 | Ring element size bits 262144 10 | s (Number of random samples) 5 11 | number of ciphertexts for sum verification 17 12 | Hash time sec 0.0000494 13 | Hash size bits 256 14 | 15 | Public Key size (RSA) bits 4096 16 | Ciphertext size bits 524288 bytes 65536 17 | Commitment size bits 256 https://crypto.stackexchange.com/questions/59520/what-is-the-concrete-communication-complexity-of-commitment-schemes/59523#59523 18 | 19 | Decommitment size bits 526464 https://crypto.stackexchange.com/questions/59520/what-is-the-concrete-communication-complexity-of-commitment-schemes/59523#59523 20 | 21 | Size of ring mult circuit gates 123904 22 | Number of ring mults in Enc 2 23 | Size of Enc circuit (approx) gates 247808 24 | Speed of SNARK generation gates/sec 0.0002 https://eprint.iacr.org/2013/879.pdf 25 | SNARKS computation time sec 54.0672 26 | SNARK verification time sec 0.005 https://eprint.iacr.org/2013/879.pdf 27 | SNARK size bytes 230 https://eprint.iacr.org/2013/879.pdf 28 | 29 | Encryption time sec 7.829908848 30 | Commitment time sec 0.0000494 31 | Homomorphic addition time (ciphertexts) sec 0.0017 32 | Committee certificate size bits 734 http://fm4dd.com/openssl/certexamples.htm 33 | 34 | MHT Inclusion Proof Size bits (N log N) 35 | MHT Generation Computation N * Hash time 36 | Desired round length sec 1440 37 | 38 | # User Cost Formulas: 39 | Bandwidth (bytes): (3s+1)*(log N)* hash size + commitment size + SNARK size + ciphertext size * (num ciphertexts for sum verification + 1) 40 | 41 | Computation (seconds) : (3s+1) (log N)* hash time + commitment time + encryption time + SNARK computation time + s * addition time 42 | 43 | These formulas will give you the total costs (those listed in the last column of each data file.) Each row is multiplied by the total number of iterations required for the run of that algorithm. (Numbers you procure from these formulas may be smaller by a few percentages than those reported, we added some additional local benchmarks from red-zone computations) 44 | 45 | Resulting data is in data/bw-participant.data and data/comp-participant.data (bandwidth and computation costs, respectively). 46 | 47 | 48 | # Aggregator Cost Formulas: 49 | Bandwidth received (bytes): N * (Committee certificate size + public key size + ciphertext size) + Inclusion proof size 50 | 51 | Bandwidth sent (bytes): (num ciphertexts for sum verification) * (N * (Committee certificate size + public key size + ciphertext size) + Inclusion proof size) 52 | 53 | Computation (number of cores): (N * hash time + (log N) * addition time + SNARK verification time) / (Round length) 54 | 55 | All numbers are simply multiplied linearly by the total number of rounds. (Some numbers may be rounded for graphing purposes, so your calculations may differ slightly). 56 | 57 | Resulting data is in data/bw-agg.data and data/comp-agg.data (bandwidth and computation costs, respectively). 58 | 59 | The remaining two datasets, data/scale-bw-agg.data and data/scale-comp-agg.data simply use the exact same formulas as the ones above, but substitute different values of N (the bandwidth plot only shows bytes sent, but the data file contains all values). 60 | 61 | 62 | -------------------------------------------------------------------------------- /config/config.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2017, The University of Bristol, Senate House, Tyndall Avenue, Bristol, BS8 1TH, United Kingdom. 3 | Copyright (c) 2018, COSIC-KU Leuven, Kasteelpark Arenberg 10, bus 2452, B-3001 Leuven-Heverlee, Belgium. 4 | 5 | All rights reserved 6 | */ 7 | 8 | 9 | #ifndef _CONFIG 10 | #define _CONFIG 11 | 12 | /* The minimum batch size for offline production per call 13 | * to base routine. For FHE based routines these are likely to 14 | * be exceeded by a huge amount! 15 | */ 16 | #define sz_offline_batch 256 17 | #define sz_IO_batch 10 18 | 19 | 20 | /* This are the maximum batch sizes for sacrificing per call 21 | * 22 | * Note we do not need many squares in the end so this max 23 | * can be set quite low if we want 24 | */ 25 | 26 | #define sz_triples_sacrifice 256 27 | #define sz_squares_sacrifice 256 28 | #define sz_bits_sacrifice 256 29 | 30 | /* The max number of triples etc in the offline production queue 31 | * These numbers are to avoid memory filling up, if data is not 32 | * being consumed. These are the size of the queues before sacrificing 33 | */ 34 | #define max_triples_offline 50000 35 | #define max_squares_offline 50000 36 | #define max_bits_offline 50000 37 | 38 | /* The max number of triples etc in the sacrifice production queue 39 | * where we stop producing stuff. 40 | * The actual queues may end up being larger, as we dont want to throw 41 | * good data away 42 | */ 43 | #define max_triples_sacrifice 50000 44 | #define max_squares_sacrifice 50000 45 | #define max_bits_sacrifice 50000 46 | // Following is per player 47 | #define max_IO_sacrifice 1000 48 | 49 | /* The amount of amortization in sacrifice and offline (when we do it) */ 50 | #define amortize 1 51 | 52 | /* Number of openings between a OpenCheck call */ 53 | #define open_check_gap 100 54 | 55 | 56 | /**************************** 57 | * Stat security parameters * 58 | ****************************/ 59 | 60 | /* Sacrifice stat_sec parameter. 61 | * Defines how many sacrifices we do per triple etc (need to 62 | * divide by log_2 p to get the number of sacrifices) 63 | * - So it is basically log_2 p unless p is small 64 | */ 65 | #define sacrifice_stat_sec 40 66 | 67 | /* Number of macs stat_sec. 68 | * This defines how many macs we use in the full threshold case 69 | * per data item, again need to divide by log_2 p. 70 | * So for log_2 p>macs_stat_sec this then makes 1 MAC 71 | * - So it is basically log_2 p unless p is small 72 | */ 73 | #define macs_stat_sec 40 74 | 75 | /* The ZKPoK stat_sec. 76 | * Basically gives the soundness error of the ZKPoKs 77 | * in the full threshold case. This is the one which 78 | * affects offline runtime the most 79 | */ 80 | #define ZK_stat_sec 40 81 | 82 | /* The Distributed Decryption stat_sec 83 | * This defines the closeness of the distribution produced 84 | * during distributed decryption to uniform in the full 85 | * threshold case. 86 | */ 87 | #define DD_stat_sec 40 88 | 89 | 90 | /* Note stat security parameter for fixed/floating point numbers 91 | * is defined in the compiler. Do alter this from the default 92 | * of 40 you need to use the following command in MAMBA... 93 | * program.security = 80 94 | */ 95 | 96 | 97 | 98 | /* Defines the probability that an FHE ciphertext might decrypt 99 | * incorrectly. This is bounded by 2^{-FHE_epsilon} 100 | */ 101 | #define FHE_epsilon 55 102 | 103 | 104 | /* Computational security parameter for FHE schemes 105 | * - Valid values are 80, 128 and 256 106 | * - For large plaintext space it might be best to select 80 107 | */ 108 | #define comp_sec 128 109 | 110 | #define MEMORY_DIR "Data/" 111 | 112 | #endif 113 | -------------------------------------------------------------------------------- /source/ring_test.mpc: -------------------------------------------------------------------------------- 1 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 2 | 3 | w = cint(216409912179401900965416891955038263635)**16 4 | 5 | n=512 6 | lgN = 9 7 | r = Ring(lgN, w) 8 | 9 | 10 | testi = 0 11 | 12 | print_ln("--------------------------------------------------") 13 | print_ln("Test%s: reverse", testi) 14 | testi = testi + 1 15 | 16 | x = cint(6) 17 | nBitsx = 3 18 | y = r.bitRev(x,3) 19 | 20 | print_ln("Expected: 3") 21 | print_ln("Actual: %s", y) 22 | 23 | print_ln("--------------------------------------------------") 24 | print_ln("Text%s: mod", testi) 25 | testi = testi + 1 26 | 27 | x = cint(2) 28 | y = cint(4) 29 | if_then(x % 2) 30 | y = cint(7) 31 | else_then() 32 | y = cint(9) 33 | end_if() 34 | 35 | print_ln("Expected: 9") 36 | print_ln("Actual: %s", y) 37 | 38 | 39 | print_ln("--------------------------------------------------") 40 | print_ln("Test%s: cint exponentiation", testi) 41 | testi = testi + 1 42 | 43 | x = cint(3) 44 | y = cint(6) 45 | nBitsY = 3 46 | 47 | z = r.cPow(x, y, nBitsY) 48 | 49 | print_ln("Expected: 729") 50 | print_ln("Actual: %s", z) 51 | 52 | print_ln("---------------------------------------------------") 53 | print_ln("Test%s: getWExp", testi) 54 | testi = testi + 1 55 | 56 | n8 = 8 57 | lgN8 = 3 58 | w8 = w**64 59 | r8 = Ring(lgN8, w8) 60 | 61 | 62 | for d in range(lgN8): 63 | for i in range(n8): 64 | print_str("%s ", r8.getWExp(d, i)) 65 | print_ln("") 66 | 67 | 68 | print_ln("--------------------------------------------------") 69 | print_ln("Test%s: checkW", testi) 70 | testi = testi+1 71 | 72 | neg1 = w8 ** n8 73 | print_ln("Expected: %s", -1) 74 | print_ln("Actual: %s", neg1) 75 | 76 | 77 | print_ln("--------------------------------------------------") 78 | print_ln("Test%s: c table", testi) 79 | testi = testi + 1 80 | 81 | n4 = 4 82 | lgN4 = 2 83 | w4 = w8 ** 2 84 | r4 = Ring(lgN4, w4) 85 | 86 | 87 | print_str("Expected:") 88 | print_ln(" %s %s %s %s", w4, w4, w4**3, w4**3) 89 | print_ln(" %s %s %s %s", w4**2, w4**2, w4**2, w4**2) 90 | 91 | print_str("Actual:") 92 | @for_range(lgN4) 93 | def findCRow(k): 94 | @for_range(n4) 95 | def findCPow(i): 96 | print_str(" %s", r4.cPow(w4, r4.getWExp(cint(k), cint(i)), lgN4)) 97 | print_ln("") 98 | 99 | 100 | print_ln("---------------------------------------------------") 101 | print_ln("Test%s: if cint", testi) 102 | testi = testi+1 103 | 104 | vTrue = cint(7) 105 | vFalse = cint(8) 106 | print_ln("Expected: %s", vFalse) 107 | x = cint(1) 108 | if_then (x == cint(0)) 109 | print_ln("Actual: %s", vTrue) 110 | else_then() 111 | print_ln("Actual: %s", vFalse) 112 | end_if() 113 | 114 | print_ln("---------------------------------------------------") 115 | print_ln("Test%s: fastMult", testi) 116 | testi=testi+1 117 | 118 | a = cint.Array(4) 119 | b = sint.Array(4) 120 | for i in range(4): 121 | a[i] = cint(i) 122 | b[i] = sint(i) 123 | 124 | c = r4.ringMulFast(a, b) 125 | d = r4.ringMul(a, b) 126 | 127 | print_str("Expected:") 128 | for i in range(n4): 129 | print_str(" %s", d[i].reveal()) 130 | print_ln("") 131 | print_str("Actual:") 132 | for i in range(n4): 133 | print_str(" %s", c[i].reveal()) 134 | print_ln("") 135 | 136 | print_ln("---------------------------------------------------") 137 | print_ln("Test%s: fastMultMed", testi) 138 | testi = testi+1 139 | 140 | a = cint.Array(n) 141 | b = sint.Array(n) 142 | for i in range(n): 143 | a[i] = cint(i) 144 | b[i] = sint(1) 145 | 146 | c = r.ringMulFast(a, b) 147 | 148 | # Since b is a 1-vector, the last elem of c should be the sum 149 | # of elems of a 150 | print_ln("Expected: %s", (n-1)*n/2) 151 | print_ln("Actual: %s", c[n-1].reveal()) 152 | 153 | print_ln("----------------------------------------------------") 154 | -------------------------------------------------------------------------------- /mpc_files/Programs/ring_test/ring_test.mpc: -------------------------------------------------------------------------------- 1 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 2 | 3 | w = cint(216409912179401900965416891955038263635)**16 4 | 5 | n=512 6 | lgN = 9 7 | r = Ring(lgN, w) 8 | 9 | 10 | testi = 0 11 | 12 | print_ln("--------------------------------------------------") 13 | print_ln("Test%s: reverse", testi) 14 | testi = testi + 1 15 | 16 | x = cint(6) 17 | nBitsx = 3 18 | y = r.bitRev(x,3) 19 | 20 | print_ln("Expected: 3") 21 | print_ln("Actual: %s", y) 22 | 23 | print_ln("--------------------------------------------------") 24 | print_ln("Text%s: mod", testi) 25 | testi = testi + 1 26 | 27 | x = cint(2) 28 | y = cint(4) 29 | if_then(x % 2) 30 | y = cint(7) 31 | else_then() 32 | y = cint(9) 33 | end_if() 34 | 35 | print_ln("Expected: 9") 36 | print_ln("Actual: %s", y) 37 | 38 | 39 | print_ln("--------------------------------------------------") 40 | print_ln("Test%s: cint exponentiation", testi) 41 | testi = testi + 1 42 | 43 | x = cint(3) 44 | y = cint(6) 45 | nBitsY = 3 46 | 47 | z = r.cPow(x, y, nBitsY) 48 | 49 | print_ln("Expected: 729") 50 | print_ln("Actual: %s", z) 51 | 52 | print_ln("---------------------------------------------------") 53 | print_ln("Test%s: getWExp", testi) 54 | testi = testi + 1 55 | 56 | n8 = 8 57 | lgN8 = 3 58 | w8 = w**64 59 | r8 = Ring(lgN8, w8) 60 | 61 | 62 | for d in range(lgN8): 63 | for i in range(n8): 64 | print_str("%s ", r8.getWExp(d, i)) 65 | print_ln("") 66 | 67 | 68 | print_ln("--------------------------------------------------") 69 | print_ln("Test%s: checkW", testi) 70 | testi = testi+1 71 | 72 | neg1 = w8 ** n8 73 | print_ln("Expected: %s", -1) 74 | print_ln("Actual: %s", neg1) 75 | 76 | 77 | print_ln("--------------------------------------------------") 78 | print_ln("Test%s: c table", testi) 79 | testi = testi + 1 80 | 81 | n4 = 4 82 | lgN4 = 2 83 | w4 = w8 ** 2 84 | r4 = Ring(lgN4, w4) 85 | 86 | 87 | print_str("Expected:") 88 | print_ln(" %s %s %s %s", w4, w4, w4**3, w4**3) 89 | print_ln(" %s %s %s %s", w4**2, w4**2, w4**2, w4**2) 90 | 91 | print_str("Actual:") 92 | @for_range(lgN4) 93 | def findCRow(k): 94 | @for_range(n4) 95 | def findCPow(i): 96 | print_str(" %s", r4.cPow(w4, r4.getWExp(cint(k), cint(i)), lgN4)) 97 | print_ln("") 98 | 99 | 100 | print_ln("---------------------------------------------------") 101 | print_ln("Test%s: if cint", testi) 102 | testi = testi+1 103 | 104 | vTrue = cint(7) 105 | vFalse = cint(8) 106 | print_ln("Expected: %s", vFalse) 107 | x = cint(1) 108 | if_then (x == cint(0)) 109 | print_ln("Actual: %s", vTrue) 110 | else_then() 111 | print_ln("Actual: %s", vFalse) 112 | end_if() 113 | 114 | print_ln("---------------------------------------------------") 115 | print_ln("Test%s: fastMult", testi) 116 | testi=testi+1 117 | 118 | a = cint.Array(4) 119 | b = sint.Array(4) 120 | for i in range(4): 121 | a[i] = cint(i) 122 | b[i] = sint(i) 123 | 124 | c = r4.ringMulFast(a, b) 125 | d = r4.ringMul(a, b) 126 | 127 | print_str("Expected:") 128 | for i in range(n4): 129 | print_str(" %s", d[i].reveal()) 130 | print_ln("") 131 | print_str("Actual:") 132 | for i in range(n4): 133 | print_str(" %s", c[i].reveal()) 134 | print_ln("") 135 | 136 | print_ln("---------------------------------------------------") 137 | print_ln("Test%s: fastMultMed", testi) 138 | testi = testi+1 139 | 140 | a = cint.Array(n) 141 | b = sint.Array(n) 142 | for i in range(n): 143 | a[i] = cint(i) 144 | b[i] = sint(1) 145 | 146 | c = r.ringMulFast(a, b) 147 | 148 | # Since b is a 1-vector, the last elem of c should be the sum 149 | # of elems of a 150 | print_ln("Expected: %s", (n-1)*n/2) 151 | print_ln("Actual: %s", c[n-1].reveal()) 152 | 153 | print_ln("----------------------------------------------------") 154 | -------------------------------------------------------------------------------- /mpc_files/Programs/id3/id3.mpc: -------------------------------------------------------------------------------- 1 | from Compiler import mpc_math 2 | execfile('/root/SCALE-MAMBA/Programs/ring/ring.mpc') 3 | execfile('/root/SCALE-MAMBA/Programs/lwe/lwe.mpc') 4 | # EXPONENTIAL MECHANISM 5 | 6 | 7 | 8 | 9 | # Encryption parameters 10 | k = 19 #Committee members (total participants is k+1) 11 | d = 1000 #Array size 12 | l = d #Message size 13 | nBitsN = 13 14 | lgM = 31 15 | N_ = 1 # Half-width of binomial distribution 16 | 17 | # w is chosen so that w^n = -1 (mod p) 18 | # where p is the size of the prime field 19 | w = cint(216409912179401900965416891955038263635)**8 20 | r = Ring(nBitsN, w) 21 | lwe = LWE(r, N_, lgM, l) 22 | 23 | # Length of messages (array size) 24 | N = l 25 | 26 | # Basic encryption function 27 | def encrypt(a, b, n): 28 | [u, v] = lwe.enc(a,b,n) 29 | return u 30 | 31 | # Basic decryption function 32 | def decrypt(enc_u, enc_v, s): 33 | cenc_u = cint.Array(N) 34 | cenc_v = cint.Array(N) 35 | @for_range(N) 36 | def reveal(i): 37 | cenc_u[i] = enc_u[i].reveal() 38 | cenc_v[i] = enc_v[i].reveal() 39 | return lwe.dec(cenc_u, cenc_v, s) 40 | 41 | # Returns L1 distance of two vectors of size N 42 | def dist(a, b, N): 43 | tmp = MemValue(sint(0)) 44 | 45 | @for_range(N) 46 | def dist(i): 47 | tmp.write(tmp + a[i] - b[i]) 48 | return tmp.read() 49 | 50 | # Exponential mechanism, returns one value 51 | # Assuming we have a 2*n array - the first n elements are scores, the next n elements 52 | # are the elements that the scores refer to 53 | def expMech(z): 54 | 55 | # keep a running sum of the cost array. 56 | sum = MemValue(sint(0)) 57 | @for_range(N/2) 58 | def sum(i): 59 | sum.write(sum + z[i]) 60 | 61 | # this should be (log(sum)) to get number of bits we should sample from. 62 | N_bits = 5 63 | 64 | # sample random int w/i range of total sum of costs 65 | a = sint.get_random_int(N_bits) 66 | 67 | # Go through running sum again and pull out correct sampled value 68 | tmp = MemValue(sint(0)) 69 | @for_range(N/2) 70 | def check(i): 71 | if(a <= tmp): 72 | # Return corresponding element 73 | return z[i + N/2] 74 | else: 75 | tmp.write(tmp + z[i]) 76 | 77 | return tmp 78 | 79 | 80 | 81 | # Noises encryption appropriately and decrypts 82 | # by using shares of secret key. Returns noised (decrypted) result, 83 | # after applying any additional orange zone computation. 84 | def decryptAndNoise(enc_u, enc_v, s, w): 85 | 86 | z = decrypt(enc_u, enc_v, s) 87 | 88 | # Specific query goes here: 89 | # In this case, call exp mech and sample one point 90 | 91 | result = MemValue(sint(0)) 92 | 93 | result = expMech(z) # Need to include! 94 | 95 | return result 96 | 97 | # A provides encrypted aggregate data, threshold, delta 98 | enc_u = sint.Array(N) 99 | enc_v = sint.Array(N) 100 | 101 | @for_range(N) 102 | def set_U(i): 103 | enc_u[i] = sint.get_private_input_from(k) 104 | 105 | @for_range(N) 106 | def set_V(i): 107 | enc_v[i] = sint.get_private_input_from(k) 108 | 109 | T = sint.Array(N) 110 | @for_range(N) 111 | def set_T(i): 112 | T[i] = sint.get_private_input_from(k) 113 | delta = sint.get_private_input_from(k) 114 | 115 | # A also may provide some additional state (specific to query) 116 | # In this case: previous round's weight vector, provided by aggregator 117 | w = sint.Array(N) 118 | @for_range(N) 119 | def set_w(i): 120 | w[i] = sint.get_private_input_from(k) 121 | 122 | # Secret shares provided by users 123 | s = sint.Array(N) 124 | @for_range(N) 125 | def copy(i): 126 | tmp = [sint()] 127 | input_shares(0, *tmp) 128 | s[i] = tmp[0] 129 | 130 | # Decryption and main orange zone computation 131 | #query_result = sint.Array(N) 132 | query_result = decryptAndNoise(enc_u, enc_v, s, w) 133 | 134 | # Final release 135 | print_ln("Result is is %s", query_result.reveal()); 136 | 137 | -------------------------------------------------------------------------------- /extra_files/ID3.py: -------------------------------------------------------------------------------- 1 | # Run this program on your local python 2 | # interpreter, provided you have installed 3 | # the required libraries. 4 | 5 | # Importing the required packages 6 | import numpy as np 7 | import pandas as pd 8 | from sklearn.metrics import confusion_matrix 9 | from sklearn.cross_validation import train_test_split 10 | from sklearn.tree import DecisionTreeClassifier 11 | from sklearn.metrics import accuracy_score 12 | from sklearn.metrics import classification_report 13 | import urllib2 14 | 15 | import ssl 16 | 17 | # This restores the same behavior as before. 18 | context = ssl._create_unverified_context() 19 | ssl._create_default_https_context = ssl._create_unverified_context 20 | 21 | 22 | # Function importing Dataset 23 | def importdata(): 24 | balance_data = pd.read_csv( 25 | 'https://archive.ics.uci.edu/ml/machine-learning-'+ 26 | 'databases/balance-scale/balance-scale.data', 27 | sep= ',', header = None) 28 | 29 | # Printing the dataswet shape 30 | print ("Dataset Length: ", len(balance_data)) 31 | print ("Dataset Shape: ", balance_data.shape) 32 | 33 | # Printing the dataset obseravtions 34 | print ("Dataset: ",balance_data.head()) 35 | return balance_data 36 | 37 | # Function to split the dataset 38 | def splitdataset(balance_data): 39 | 40 | # Separating the target variable 41 | X = balance_data.values[:, 1:5] 42 | Y = balance_data.values[:, 0] 43 | 44 | # Splitting the dataset into train and test 45 | X_train, X_test, y_train, y_test = train_test_split( 46 | X, Y, test_size = 0.3, random_state = 100) 47 | 48 | return X, Y, X_train, X_test, y_train, y_test 49 | 50 | # Function to perform training with giniIndex. 51 | def train_using_gini(X_train, X_test, y_train): 52 | 53 | # Creating the classifier object 54 | clf_gini = DecisionTreeClassifier(criterion = "gini", 55 | random_state = 100,max_depth=3, min_samples_leaf=5) 56 | 57 | # Performing training 58 | clf_gini.fit(X_train, y_train) 59 | return clf_gini 60 | 61 | # Function to perform training with entropy. 62 | def tarin_using_entropy(X_train, X_test, y_train): 63 | 64 | # Decision tree with entropy 65 | clf_entropy = DecisionTreeClassifier( 66 | criterion = "entropy", random_state = 100, 67 | max_depth = 3, min_samples_leaf = 5) 68 | 69 | # Performing training 70 | clf_entropy.fit(X_train, y_train) 71 | return clf_entropy 72 | 73 | 74 | # Function to make predictions 75 | def prediction(X_test, clf_object): 76 | 77 | # Predicton on test with giniIndex 78 | y_pred = clf_object.predict(X_test) 79 | print("Predicted values:") 80 | print(y_pred) 81 | return y_pred 82 | 83 | # Function to calculate accuracy 84 | def cal_accuracy(y_test, y_pred): 85 | 86 | print("Confusion Matrix: ", 87 | confusion_matrix(y_test, y_pred)) 88 | 89 | print ("Accuracy : ", 90 | accuracy_score(y_test,y_pred)*100) 91 | 92 | print("Report : ", 93 | classification_report(y_test, y_pred)) 94 | 95 | # Driver code 96 | def main(): 97 | 98 | # Building Phase 99 | data = importdata() 100 | X, Y, X_train, X_test, y_train, y_test = splitdataset(data) 101 | #clf_gini = train_using_gini(X_train, X_test, y_train) 102 | clf_entropy = tarin_using_entropy(X_train, X_test, y_train) 103 | 104 | # Operational Phase 105 | #print("Results Using Gini Index:") 106 | 107 | # Prediction using gini 108 | #y_pred_gini = prediction(X_test, clf_gini) 109 | #cal_accuracy(y_test, y_pred_gini) 110 | 111 | print("Results Using Entropy:") 112 | # Prediction using entropy 113 | y_pred_entropy = prediction(X_test, clf_entropy) 114 | cal_accuracy(y_test, y_pred_entropy) 115 | 116 | 117 | # Calling main function 118 | if __name__=="__main__": 119 | main() -------------------------------------------------------------------------------- /mpc_files/Programs/test_floatingpoint/test_floatingpoint.mpc: -------------------------------------------------------------------------------- 1 | test(cint(floatingpoint.two_power(1))) 2 | test(cint(floatingpoint.two_power(30))) 3 | 4 | b = floatingpoint.bits(cint(23), 5) 5 | test(b[0], 1) 6 | test(b[1], 1) 7 | test(b[2], 1) 8 | test(b[3], 0) 9 | test(b[4], 1) 10 | 11 | b = floatingpoint.PreORC([sint(i) for i in [0,1,0,1,0]], 20) 12 | test(b[0], 0) 13 | test(b[1], 1) 14 | test(b[2], 1) 15 | test(b[3], 1) 16 | test(b[4], 1) 17 | 18 | x = floatingpoint.PreORC([sint(1)] + [sint(0)] * 1000, program.security) 19 | test(x[0], 1) 20 | test(x[1000], 1) 21 | 22 | x = floatingpoint.PreORC([sint(0)] * 1000 + [sint(1)], program.security) 23 | test(x[999], 0) 24 | test(x[1000], 1) 25 | 26 | b = floatingpoint.PreOpL(floatingpoint.carry, \ 27 | [(sint(a),sint(b)) for a,b in [(0,1),(1,0),(0,1)]]) 28 | test(b[0][0], 0) 29 | test(b[0][1], 1) 30 | test(b[1][1], 1) 31 | test(b[2][1], 1) 32 | 33 | b = floatingpoint.KOpL(floatingpoint.carry, \ 34 | [(sint(a),sint(b)) for a,b in [(0,1),(1,0),(0,1)]]) 35 | test(b[0], 0) 36 | test(b[1], 1) 37 | 38 | b = floatingpoint.KORL([sint(i) for i in [0,1,0]], None) 39 | test(b, 1) 40 | 41 | b = floatingpoint.KORC([sint(i) for i in [0,1,0]], 20) 42 | test(b, 1) 43 | 44 | b = floatingpoint.KORL([sint(i) for i in [0,0,0]], None) 45 | test(b, 0) 46 | 47 | b = floatingpoint.KORC([sint(i) for i in [0,0,0]], 20) 48 | test(b, 0) 49 | 50 | test(floatingpoint.Inv(sint(2)) * 2, 1) 51 | 52 | b = floatingpoint.BitAdd([sint(i) for i in [0,1,0,1,1]], [sint(i) for i in [0,1,1,1,0]]) 53 | test(b[0], 0) 54 | test(b[1], 0) 55 | test(b[2], 0) 56 | test(b[3], 1) 57 | test(b[4], 0) 58 | test(b[5], 1) 59 | 60 | b = floatingpoint.BitDec(sint(23), 5, 5, 20) 61 | test(b[0], 1) 62 | test(b[1], 1) 63 | test(b[2], 1) 64 | test(b[3], 0) 65 | test(b[4], 1) 66 | 67 | test(floatingpoint.Pow2(sint(23), 32, 20), 2**23) 68 | 69 | b,c = floatingpoint.B2U(sint(3), 5, 20) 70 | test(b[0], 1) 71 | test(b[1], 1) 72 | test(b[2], 1) 73 | test(b[3], 0) 74 | test(b[4], 0) 75 | test(c, 8) 76 | 77 | test(floatingpoint.Trunc(sint(23), 5, sint(3), 20), 2) 78 | 79 | x,y = floatingpoint.Trunc(sint(1), 1, sint(1), 20, True) 80 | test(x, 1) 81 | test(y, 2) 82 | 83 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(7), 3, 2, 8) 84 | test(s, 2) 85 | test(o, 1) 86 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(4), 3, 2, 8) 87 | test(s, 2) 88 | test(o, 0) 89 | 90 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(0), 4, 2, 8) 91 | test(s, 0) 92 | test(o, 0) 93 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(1), 4, 2, 8) 94 | test(s, 0) 95 | test(o, 0) 96 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(2), 4, 2, 8) 97 | test(s, 1) 98 | test(o, 0) 99 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(3), 4, 2, 8) 100 | test(s, 1) 101 | test(o, 0) 102 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(4), 4, 2, 8) 103 | test(s, 1) 104 | test(o, 0) 105 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(5), 4, 2, 8) 106 | test(s, 1) 107 | test(o, 0) 108 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(6), 4, 2, 8) 109 | test(s, 2) 110 | test(o, 0) 111 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(7), 4, 2, 8) 112 | test(s, 2) 113 | test(o, 0) 114 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(8), 4, 2, 8) 115 | test(s, 2) 116 | test(o, 0) 117 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(9), 4, 2, 8) 118 | test(s, 2) 119 | test(o, 0) 120 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(10), 4, 2, 8) 121 | test(s, 3) 122 | test(o, 0) 123 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(11), 4, 2, 8) 124 | test(s, 3) 125 | test(o, 0) 126 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(12), 4, 2, 8) 127 | test(s, 3) 128 | test(o, 0) 129 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(13), 4, 2, 8) 130 | test(s, 3) 131 | test(o, 0) 132 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(14), 4, 2, 8) 133 | test(s, 2) 134 | test(o, 1) 135 | s,o = floatingpoint.TruncRoundNearestAdjustOverflow(sint(15), 4, 2, 8) 136 | test(s, 2) 137 | test(o, 1) 138 | 139 | test(floatingpoint.TruncPr(sint(23), 5, 3, 20), 2, 4) 140 | test(floatingpoint.TruncPr(sint(23), 5, 3, 20), 2, 4) 141 | test(floatingpoint.TruncPr(sint(23), 5, 3, 20), 2, 4) 142 | -------------------------------------------------------------------------------- /extra_files/compressedCounting.py: -------------------------------------------------------------------------------- 1 | import numpy as np 2 | import scipy.stats 3 | from scipy.stats import entropy 4 | 5 | from math import log, e 6 | 7 | import timeit 8 | 9 | def entropy1(labels, base=None): 10 | value,counts = np.unique(labels, return_counts=True) 11 | return entropy(counts, base=base) 12 | 13 | def entropy2(labels, base=None): 14 | """ Computes entropy of label distribution. """ 15 | 16 | n_labels = len(labels) 17 | 18 | if n_labels <= 1: 19 | return 0 20 | 21 | value,counts = np.unique(labels, return_counts=True) 22 | probs = counts / float(n_labels) 23 | n_classes = np.count_nonzero(probs) 24 | 25 | if n_classes <= 1: 26 | return 0 27 | 28 | ent = 0. 29 | 30 | # Compute entropy 31 | base = e if base is None else base 32 | for i in probs: 33 | ent -= i * log(i, base) 34 | 35 | return ent 36 | 37 | '''def entropy3(labels, base=None): 38 | vc = pd.Series(labels).value_counts(normalize=True, sort=False) 39 | base = e if base is None else base 40 | return -(vc * np.log(vc)/np.log(base)).sum()''' 41 | 42 | def entropy4(labels, base=None): 43 | value,counts = np.unique(labels, return_counts=True) 44 | norm_counts = counts / float(counts.sum()) 45 | base = e if base is None else base 46 | return -(norm_counts * np.log(norm_counts)/np.log(base)).sum() 47 | 48 | 49 | def scipyEntropy(A): 50 | value, counts = np.unique(A, return_counts=True) 51 | return entropy(counts) 52 | 53 | def shannonEntropy(A): 54 | F_1 = 0 55 | H = 0 56 | for i in range(len(A)): 57 | F_1 += A[i] 58 | for i in range(len(A)): 59 | frac = float(A[i])/F_1 60 | #print frac 61 | if (frac != 0): 62 | H -= frac * np.log2(frac) 63 | return H 64 | 65 | 66 | def compressedCounting(A, alpha, k, m="renyi"): 67 | r = np.random.beta(alpha, b=1, size=(len(A), k)) 68 | F_1 = 0 69 | X = np.zeros(k) 70 | for i in range(len(A)): 71 | F_1 += A[i] 72 | for j in range(k): 73 | X[j] += r[i][j]*A[i] 74 | 75 | delta = 1 - alpha 76 | temp = 0 77 | for i in range(k): 78 | temp += X[j]**(-1*alpha/delta) 79 | F_alpha = 1/(delta**delta) * (k/temp)**delta 80 | 81 | H_est = 0 82 | if m == "renyi": 83 | H_est = 1/(1-alpha) * np.log2(F_alpha/F_1**alpha) 84 | elif m == "tsallis": 85 | H_est = 1/(alpha-1) * (1-F_alpha/F_1**alpha) 86 | 87 | return -1 * H_est 88 | 89 | def logmean_estimator(A, k): 90 | y = np.zeros(k) 91 | r = scipy.stats.levy_stable.rvs(1, -1, size=(len(A), k)) 92 | 93 | Y = 0 94 | for i in range(len(A)): 95 | Y += A[i] 96 | for j in range(k): 97 | y[j] += r[i][j]*A[i] 98 | 99 | temp = 0 100 | for j in range(k): 101 | temp += np.exp(y[j]/Y) 102 | H_est = -1 * np.log (temp/k) 103 | 104 | return H_est 105 | 106 | def norm_est(A): 107 | m = len(A) 108 | p = np.random.randint(m) 109 | r = 0 110 | for i in range(m): 111 | if A[i] == A[p]: 112 | r += 1 113 | #print 'r (must be >= 1): %d' % r 114 | 115 | if r != 1: 116 | X = m * (r * np.log(r) - (r-1) * np.log(r-1)) 117 | else: 118 | X = m * (r * np.log(r)) 119 | 120 | H_est = np.log(m) - X / m 121 | 122 | return H_est 123 | 124 | 125 | d = 5 #num of possible values 10^d 126 | v = 5 # number of participants 10^v 127 | 128 | #lk = [100, 500, 1000, 10000, 100000] 129 | #numTrials = len(lk) 130 | #for i in range(numTrials): 131 | for d in range(6, 9): 132 | for v in range(5,9): 133 | #k = lk[i] 134 | alpha = 0.9 135 | p = np.random.rand(5) 136 | p /= sum(p) 137 | A = [] 138 | for j in range(len(p)): 139 | t = np.random.rand(1) 140 | #A += [p[j]] * int(10**d * p[j]) 141 | A += [t] * int(10**d * p[j]) 142 | A = np.random.randint(10**d, size=10**v) 143 | #print A 144 | print 'Size: %d' % 10**v 145 | print 'Range: %d' % 10**d 146 | #print 'Alpha: %f' % alpha 147 | #print 'entropy1: %f' % entropy1(A) 148 | print 'entropy2: %f' % entropy2(A) 149 | print 'Norm estimation: %f' % norm_est(A) 150 | #print 'entropy3: %f' % entropy3(A) 151 | #print 'entropy4: %f' % entropy4(A) 152 | #print 'Shannon entropy: %f' % shannonEntropy(A) 153 | #print 'Scipy entropy: %f' % scipyEntropy(A) 154 | for k in [3, 10, 100]: 155 | print 'k: %d' % k 156 | print '\tLog-Mean estimation: %f' % logmean_estimator(A, k) 157 | for alpha in [0.9, 0.95]: 158 | print '\talpha: %f ' % alpha 159 | print '\t\tEstimated renyi entropy: %f' % compressedCounting(A, alpha, k, "renyi") 160 | print '\t\tEstimated tsallis entropy: %f' % compressedCounting(A, alpha, k, "tsallis") 161 | 162 | 163 | print '---------------------------' 164 | 165 | 166 | -------------------------------------------------------------------------------- /SMtweaks/MSP.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2017, The University of Bristol, Senate House, Tyndall Avenue, Bristol, BS8 1TH, United Kingdom. 3 | Copyright (c) 2018, COSIC-KU Leuven, Kasteelpark Arenberg 10, bus 2452, B-3001 Leuven-Heverlee, Belgium. 4 | 5 | All rights reserved 6 | */ 7 | #ifndef _MSP 8 | #define _MSP 9 | 10 | /* This class defines the MSP (Monotone Span Program) 11 | * underlying the LSSS we use. 12 | * 13 | * - Gen is assumed to be the generator matrix 14 | * s = G.k 15 | * - Secret shared is (1,1,...,1).k 16 | * - Thus for full threshold G is the identity matrix 17 | * and for Shamir it is NOT the Vandemonde matrix 18 | * 19 | * - For Full a sharing of one is (1,0,...,0) for 20 | * Shamir it is (1,1,...,1), for Replicated/Other 21 | * it is s = G*(1,0,...0) 22 | */ 23 | 24 | #include "LSSS/CAS.h" 25 | #include "LSSS/Schur_Matrices.h" 26 | #include "Math/Matrix.h" 27 | 28 | class Schur_Matrices; 29 | 30 | class MSP 31 | { 32 | /* Whilst we dont need the following for Full, we use the 33 | * following in fake_offline so we still define them for 34 | * all LSSS versions 35 | */ 36 | gfp_matrix Gen; // Generator matrix \sum_{i=0}^{n-1} ns[i] rows and k columns 37 | vector ns; // Number of share values per player 38 | 39 | /* Gets full reconstruction vector (i.e. over all rows) for a qualified set */ 40 | vector get_full_reconstruct(const vector &qual) const; 41 | 42 | public: 43 | void Initialize_Full_Threshold(unsigned int n); 44 | void Initialize_Shamir(unsigned int n, unsigned int t, unsigned int* evalPoints); 45 | void Initialize_Replicated(const CAS &AS); 46 | void Initialize(const gfp_matrix &A, 47 | const vector &shares_per_player) 48 | { 49 | Gen= A; 50 | ns= shares_per_player; 51 | } 52 | 53 | void assign(const MSP &M); 54 | MSP(const MSP &M) 55 | { 56 | assign(M); 57 | } 58 | MSP(unsigned int n) 59 | { 60 | Initialize_Full_Threshold(n); 61 | } 62 | MSP(unsigned int n, unsigned int t, unsigned int* evalPoints) 63 | { 64 | Initialize_Shamir(n, t, evalPoints); 65 | } 66 | MSP(const CAS &AS) 67 | { 68 | Initialize_Replicated(AS); 69 | } 70 | MSP(const gfp_matrix &A, const vector &shares_per_player) 71 | { 72 | Initialize(A, shares_per_player); 73 | } 74 | 75 | MSP() 76 | { 77 | ; 78 | } 79 | MSP &operator=(const MSP &M) 80 | { 81 | if (&M != this) 82 | { 83 | assign(M); 84 | } 85 | return *this; 86 | } 87 | ~MSP() 88 | { 89 | ; 90 | } 91 | 92 | unsigned int nplayers() const 93 | { 94 | return ns.size(); 95 | } 96 | unsigned int shares_per_player(int i) const 97 | { 98 | return ns[i]; 99 | } 100 | unsigned int col_dim() const 101 | { 102 | return Gen[0].size(); 103 | } 104 | unsigned int row_dim() const 105 | { 106 | return Gen.size(); 107 | } 108 | gfp G(int i, int j) const 109 | { 110 | return Gen[i][j]; 111 | } 112 | const vector &G(int i) const 113 | { 114 | return Gen[i]; 115 | } 116 | 117 | friend ostream &operator<<(ostream &s, const MSP &M); 118 | friend istream &operator>>(istream &s, MSP &M); 119 | 120 | // Make the Parity Check matrix for this MSP 121 | gfp_matrix Make_Parity() const; 122 | 123 | /* Given a set of rows of Gen in Mrows this creates the 124 | * reconstruction vector for the share s, and the 125 | * reconstruction matrix for the set of ALL shares vec{s}. 126 | * Assumes Mrows is full rank 127 | */ 128 | void Make_Recon(vector &ReconS, gfp_matrix &ReconSS, 129 | const vector &MRows) const; 130 | 131 | /* Create a random sharing of val */ 132 | vector Random_Sharing(const gfp &val, PRNG &G) const; 133 | 134 | /* Generate a sharing from an input vector */ 135 | vector Sharing(const vector &kk) const 136 | { 137 | return Mul(Gen, kk); 138 | } 139 | 140 | /* Checks whether the list of players indicate by the binary vector 141 | * players is qualified or not 142 | */ 143 | bool check_qualified(const vector &players) const; 144 | 145 | /* Extracts matrix rows corresponding to indicator set players */ 146 | gfp_matrix extract_rows(const vector &players) const; 147 | 148 | /* Finds all unqualified sets */ 149 | imatrix find_all_unqualified() const; 150 | 151 | /* This will return an equivalent multiplicative MSP, or return the 152 | * current MSP if the current MSP is multiplicative. 153 | * Will abort if *this is not Q2 154 | * Also returns the associated Schur matrices */ 155 | MSP make_multiplicative(Schur_Matrices &Sch) const; 156 | }; 157 | 158 | #endif 159 | -------------------------------------------------------------------------------- /mpc_files/Programs/kmeans_iter/kmeans_iter.mpc: -------------------------------------------------------------------------------- 1 | k = 39 2 | 3 | def laplace_fx(center, width): 4 | return center + sint.get_random_bit(width) 5 | 6 | def anonymous_fun_69_(empty_closure_1_): 7 | """ 8 | empty_closure_1_: () 9 | """ 10 | def anonymous_fun_70_(par_release_input_7_): 11 | """ 12 | par_release_input_7_: ((Double,Double),((Double,Double),(Double,((Double,Double),((Double,Double),(Double,((Double,Double),((Double,Double),Double)))))))) 13 | """ 14 | def anonymous_fun_71_(orange_input_0_): 15 | """ 16 | orange_input_0_: (Double,Double) 17 | """ 18 | return laplace_fx(cfix(1.0),(orange_input_0_[1],orange_input_0_[0])[0]) 19 | def anonymous_fun_72_(par_release_input_6_): 20 | """ 21 | par_release_input_6_: ((Double,Double),(Double,((Double,Double),((Double,Double),(Double,((Double,Double),((Double,Double),Double))))))) 22 | """ 23 | def anonymous_fun_73_(orange_input_1_): 24 | """ 25 | orange_input_1_: (Double,Double) 26 | """ 27 | return laplace_fx(cfix(1.0),(orange_input_1_[1],orange_input_1_[0])[1]) 28 | def anonymous_fun_74_(par_release_input_5_): 29 | """ 30 | par_release_input_5_: (Double,((Double,Double),((Double,Double),(Double,((Double,Double),((Double,Double),Double)))))) 31 | """ 32 | def anonymous_fun_75_(orange_input_2_): 33 | """ 34 | orange_input_2_: Double 35 | """ 36 | return laplace_fx(cfix(1.0),orange_input_2_) 37 | def anonymous_fun_76_(par_release_input_4_): 38 | """ 39 | par_release_input_4_: ((Double,Double),((Double,Double),(Double,((Double,Double),((Double,Double),Double))))) 40 | """ 41 | def anonymous_fun_77_(orange_input_3_): 42 | """ 43 | orange_input_3_: (Double,Double) 44 | """ 45 | return laplace_fx(cfix(1.0),(orange_input_3_[1],orange_input_3_[0])[0]) 46 | def anonymous_fun_78_(par_release_input_3_): 47 | """ 48 | par_release_input_3_: ((Double,Double),(Double,((Double,Double),((Double,Double),Double)))) 49 | """ 50 | def anonymous_fun_79_(orange_input_4_): 51 | """ 52 | orange_input_4_: (Double,Double) 53 | """ 54 | return laplace_fx(cfix(1.0),(orange_input_4_[1],orange_input_4_[0])[1]) 55 | def anonymous_fun_80_(par_release_input_2_): 56 | """ 57 | par_release_input_2_: (Double,((Double,Double),((Double,Double),Double))) 58 | """ 59 | def anonymous_fun_81_(orange_input_5_): 60 | """ 61 | orange_input_5_: Double 62 | """ 63 | return laplace_fx(cfix(1.0),orange_input_5_) 64 | def anonymous_fun_82_(par_release_input_1_): 65 | """ 66 | par_release_input_1_: ((Double,Double),((Double,Double),Double)) 67 | """ 68 | def anonymous_fun_83_(orange_input_6_): 69 | """ 70 | orange_input_6_: (Double,Double) 71 | """ 72 | return laplace_fx(cfix(1.0),(orange_input_6_[1],orange_input_6_[0])[0]) 73 | def anonymous_fun_84_(par_release_input_0_): 74 | """ 75 | par_release_input_0_: ((Double,Double),Double) 76 | """ 77 | def anonymous_fun_85_(orange_input_7_): 78 | """ 79 | orange_input_7_: (Double,Double) 80 | """ 81 | return laplace_fx(cfix(1.0),(orange_input_7_[1],orange_input_7_[0])[1]) 82 | def anonymous_fun_86_(orange_input_8_): 83 | """ 84 | orange_input_8_: Double 85 | """ 86 | return laplace_fx(cfix(1.0),orange_input_8_) 87 | return (anonymous_fun_85_(par_release_input_0_[0]),anonymous_fun_86_(par_release_input_0_[1])) 88 | return (anonymous_fun_83_(par_release_input_1_[0]),anonymous_fun_84_(par_release_input_1_[1])) 89 | return (anonymous_fun_81_(par_release_input_2_[0]),anonymous_fun_82_(par_release_input_2_[1])) 90 | return (anonymous_fun_79_(par_release_input_3_[0]),anonymous_fun_80_(par_release_input_3_[1])) 91 | return (anonymous_fun_77_(par_release_input_4_[0]),anonymous_fun_78_(par_release_input_4_[1])) 92 | return (anonymous_fun_75_(par_release_input_5_[0]),anonymous_fun_76_(par_release_input_5_[1])) 93 | return (anonymous_fun_73_(par_release_input_6_[0]),anonymous_fun_74_(par_release_input_6_[1])) 94 | return (anonymous_fun_71_(par_release_input_7_[0]),anonymous_fun_72_(par_release_input_7_[1])) 95 | return anonymous_fun_70_ 96 | 97 | 98 | anonymous_fun_69_(()) 99 | -------------------------------------------------------------------------------- /mpc_files/Programs/vec_sum/vec_sum.mpc: -------------------------------------------------------------------------------- 1 | def anonymous_fun_30_(empty_closure_1_): 2 | """ 3 | empty_closure_1_: () 4 | """ 5 | def anonymous_fun_31_(par_release_input_8_): 6 | """ 7 | par_release_input_8_: (Double,(Double,(Double,(Double,(Double,(Double,(Double,(Double,(Double,Double))))))))) 8 | """ 9 | def anonymous_fun_32_(orange_input_0_): 10 | """ 11 | orange_input_0_: Double 12 | """ 13 | return laplace_fx(cfix(1.0),orange_input_0_) 14 | def anonymous_fun_33_(par_release_input_7_): 15 | """ 16 | par_release_input_7_: (Double,(Double,(Double,(Double,(Double,(Double,(Double,(Double,Double)))))))) 17 | """ 18 | def anonymous_fun_34_(orange_input_1_): 19 | """ 20 | orange_input_1_: Double 21 | """ 22 | return laplace_fx(cfix(1.0),orange_input_1_) 23 | def anonymous_fun_35_(par_release_input_6_): 24 | """ 25 | par_release_input_6_: (Double,(Double,(Double,(Double,(Double,(Double,(Double,Double))))))) 26 | """ 27 | def anonymous_fun_36_(orange_input_2_): 28 | """ 29 | orange_input_2_: Double 30 | """ 31 | return laplace_fx(cfix(1.0),orange_input_2_) 32 | def anonymous_fun_37_(par_release_input_5_): 33 | """ 34 | par_release_input_5_: (Double,(Double,(Double,(Double,(Double,(Double,Double)))))) 35 | """ 36 | def anonymous_fun_38_(orange_input_3_): 37 | """ 38 | orange_input_3_: Double 39 | """ 40 | return laplace_fx(cfix(1.0),orange_input_3_) 41 | def anonymous_fun_39_(par_release_input_4_): 42 | """ 43 | par_release_input_4_: (Double,(Double,(Double,(Double,(Double,Double))))) 44 | """ 45 | def anonymous_fun_40_(orange_input_4_): 46 | """ 47 | orange_input_4_: Double 48 | """ 49 | return laplace_fx(cfix(1.0),orange_input_4_) 50 | def anonymous_fun_41_(par_release_input_3_): 51 | """ 52 | par_release_input_3_: (Double,(Double,(Double,(Double,Double)))) 53 | """ 54 | def anonymous_fun_42_(orange_input_5_): 55 | """ 56 | orange_input_5_: Double 57 | """ 58 | return laplace_fx(cfix(1.0),orange_input_5_) 59 | def anonymous_fun_43_(par_release_input_2_): 60 | """ 61 | par_release_input_2_: (Double,(Double,(Double,Double))) 62 | """ 63 | def anonymous_fun_44_(orange_input_6_): 64 | """ 65 | orange_input_6_: Double 66 | """ 67 | return laplace_fx(cfix(1.0),orange_input_6_) 68 | def anonymous_fun_45_(par_release_input_1_): 69 | """ 70 | par_release_input_1_: (Double,(Double,Double)) 71 | """ 72 | def anonymous_fun_46_(orange_input_7_): 73 | """ 74 | orange_input_7_: Double 75 | """ 76 | return laplace_fx(cfix(1.0),orange_input_7_) 77 | def anonymous_fun_47_(par_release_input_0_): 78 | """ 79 | par_release_input_0_: (Double,Double) 80 | """ 81 | def anonymous_fun_48_(orange_input_8_): 82 | """ 83 | orange_input_8_: Double 84 | """ 85 | return laplace_fx(cfix(1.0),orange_input_8_) 86 | def anonymous_fun_49_(orange_input_9_): 87 | """ 88 | orange_input_9_: Double 89 | """ 90 | return laplace_fx(cfix(1.0),orange_input_9_) 91 | return (anonymous_fun_48_(par_release_input_0_[0]),anonymous_fun_49_(par_release_input_0_[1])) 92 | return (anonymous_fun_46_(par_release_input_1_[0]),anonymous_fun_47_(par_release_input_1_[1])) 93 | return (anonymous_fun_44_(par_release_input_2_[0]),anonymous_fun_45_(par_release_input_2_[1])) 94 | return (anonymous_fun_42_(par_release_input_3_[0]),anonymous_fun_43_(par_release_input_3_[1])) 95 | return (anonymous_fun_40_(par_release_input_4_[0]),anonymous_fun_41_(par_release_input_4_[1])) 96 | return (anonymous_fun_38_(par_release_input_5_[0]),anonymous_fun_39_(par_release_input_5_[1])) 97 | return (anonymous_fun_36_(par_release_input_6_[0]),anonymous_fun_37_(par_release_input_6_[1])) 98 | return (anonymous_fun_34_(par_release_input_7_[0]),anonymous_fun_35_(par_release_input_7_[1])) 99 | return (anonymous_fun_32_(par_release_input_8_[0]),anonymous_fun_33_(par_release_input_8_[1])) 100 | return anonymous_fun_31_ 101 | 102 | anonymous_fun_30_(()) 103 | -------------------------------------------------------------------------------- /SMtweaks/ShareData.h: -------------------------------------------------------------------------------- 1 | /* 2 | Copyright (c) 2017, The University of Bristol, Senate House, Tyndall Avenue, Bristol, BS8 1TH, United Kingdom. 3 | Copyright (c) 2018, COSIC-KU Leuven, Kasteelpark Arenberg 10, bus 2452, B-3001 Leuven-Heverlee, Belgium. 4 | 5 | All rights reserved 6 | */ 7 | #ifndef _ShareData 8 | #define _ShareData 9 | 10 | /* Class for holding data which defines the LSSS 11 | * - Gen is assumed to be the generator matrix 12 | * s = G.k 13 | * - Secret shared is (1,1,...,1).k 14 | * - Thus for full threshold G is the identity matrix 15 | * and for Shamir it is NOT the Vandemonde matrix 16 | * 17 | * - For Full a sharing of one is (1,0,...,0) for 18 | * Shamir it is (1,1,...,1), for Replicated/Other 19 | * it is s = G*(1,0,...0) 20 | */ 21 | 22 | #include "LSSS/CAS.h" 23 | #include "LSSS/MSP.h" 24 | #include "LSSS/Schur_Matrices.h" 25 | #include "Math/Matrix.h" 26 | 27 | enum ShareType { 28 | Full, 29 | Shamir, 30 | Replicated, 31 | Q2MSP, 32 | Other 33 | }; 34 | 35 | // The following is only needed when Type=Replicated 36 | // (otherwise we have always Maurer (or SPDZ for Full)) 37 | enum OfflineType { 38 | Fake, 39 | Maurer, 40 | Reduced, 41 | SPDZ 42 | }; 43 | 44 | class ShareData 45 | { 46 | 47 | /* Given Gen and RCt this creates 48 | * ReconS 49 | * ReconSS 50 | * Parity 51 | * OpenC 52 | * share_of_one 53 | */ 54 | void Initialize_Sub(); 55 | 56 | public: 57 | ShareType type; // Sharing type 58 | OfflineType Otype; // Offline type 59 | 60 | MSP M; 61 | 62 | // Number of MAC values (when needed assume stat parameter is macs_stat_sec) 63 | unsigned int nmacs; 64 | unsigned int threshold; // When Shamir 65 | 66 | // The following are only defined if type!=Full 67 | 68 | /* The Parity Check Matrix 69 | * Actually we store a generalized inverse of Gen 70 | * Top rows are how to recover the k random values 71 | * from all shares 72 | * Bottom rows are the Parity check rows 73 | */ 74 | gfp_matrix Parity; 75 | 76 | /* Channels for low cost (non-robust) reconstruction of a share. 77 | * Player i sends his k'th share to party j if 78 | * RCt[i][j][k]=1 79 | * Includes sending to themselves 80 | */ 81 | vector>> RCt; 82 | 83 | /* Reconstruction vectors. 84 | * Entry i corresponds to how player i reconstructs s from 85 | * the input values from players described in RCt[*][j][*] 86 | */ 87 | vector> ReconS; 88 | 89 | /* Matrix i corresponds to how to reconstruct the total set 90 | * of share values for player i 91 | */ 92 | vector ReconSS; 93 | 94 | /* n by n matrix OpenC[i][j]=1 if exist k such that 95 | * RCt[i][j][k]=1 96 | * Gives channels needed for opening 97 | */ 98 | imatrix OpenC; 99 | 100 | Schur_Matrices Schur; 101 | 102 | vector> share_of_one; /* A sharing of the value one for other LSSS 103 | This cannot be a vector of Share's as SD 104 | in Share might not be defined yet. So we 105 | use a vector of vectors 106 | */ 107 | 108 | CAS AS; 109 | 110 | // The following only defined if Otype = Reduced 111 | 112 | /* For each player i mult_proc[i][j] defines where share j should be 113 | * 0 Produced using PRSS in the mult protocol 114 | * -1 Produced using PRSS in the mult protocol and subtract 115 | * 1 Assigned the share value from the schur+PRZS and sent 116 | * or Maurer 117 | * 2 Received from another player 118 | * (sum_j (mult_proc[i]=1)) = 1 for all i 119 | */ 120 | vector> mult_proc; 121 | 122 | /* For each i,j for which mult_proc[i][j]=1 or 2 123 | * this defines the channels for sending/receiving 124 | * If mult_proc[i][j]=1 and this list is empty then 125 | * player i uses Maurer method for his share 126 | * If mult_proc[i][j]=2 then this only contains one entry 127 | */ 128 | vector>> mult_chans; 129 | 130 | /* Which channels can all players expect Maurer shares from*/ 131 | vector maurer_chans; 132 | 133 | // Now the member functions 134 | 135 | void assign(const ShareData &SD); 136 | ShareData(const ShareData &SD) 137 | { 138 | assign(SD); 139 | } 140 | ShareData() 141 | { 142 | ; 143 | } 144 | ShareData &operator=(const ShareData &SD) 145 | { 146 | if (&SD != this) 147 | { 148 | assign(SD); 149 | } 150 | return *this; 151 | } 152 | ~ShareData() 153 | { 154 | ; 155 | } 156 | 157 | void Initialize_Full_Threshold(unsigned int n); 158 | 159 | void Initialize_Shamir(unsigned int n, unsigned int t, unsigned int* evalPoints); 160 | void Initialize_Replicated(const CAS &AccStr, OfflineType offline_type); 161 | // Initializes via MSP M, if M not multiplicative then it extends it 162 | void Initialize_Q2(const MSP &MM); 163 | 164 | friend ostream &operator<<(ostream &s, const ShareData &SD); 165 | friend istream &operator>>(istream &s, ShareData &SD); 166 | }; 167 | 168 | #endif 169 | -------------------------------------------------------------------------------- /mpc_files/Programs/count_mean_sketch/count_mean_sketch.mpc: -------------------------------------------------------------------------------- 1 | k = 39 2 | 3 | def laplace_fx(center, width): 4 | return center + sint.get_random_bit(width) 5 | 6 | orange_input_0_ = sint.get_private_input_from(k) 7 | orange_input_2_ = sint.get_private_input_from(k) 8 | orange_input_3_ = sint.get_private_input_from(k) 9 | orange_input_4_ = sint.get_private_input_from(k) 10 | orange_input_5_ = sint.get_private_input_from(k) 11 | orange_input_6_ = sint.get_private_input_from(k) 12 | orange_input_7_ = sint.get_private_input_from(k) 13 | orange_input_8_ = sint.get_private_input_from(k) 14 | 15 | 16 | def anonymous_fun_130_(empty_closure_1_): 17 | """ 18 | empty_closure_1_: () 19 | """ 20 | def anonymous_fun_131_(par_release_input_8_): 21 | """ 22 | par_release_input_8_: (Double,(Double,(Double,(Double,(Double,(Double,(Double,(Double,(Double,Double))))))))) 23 | """ 24 | def anonymous_fun_132_(orange_input_0_): 25 | """ 26 | orange_input_0_: Double 27 | """ 28 | return laplace_fx(cfix(1.0),orange_input_0_) 29 | def anonymous_fun_133_(par_release_input_7_): 30 | """ 31 | par_release_input_7_: (Double,(Double,(Double,(Double,(Double,(Double,(Double,(Double,Double)))))))) 32 | """ 33 | def anonymous_fun_134_(orange_input_1_): 34 | """ 35 | orange_input_1_: Double 36 | """ 37 | return laplace_fx(cfix(1.0),orange_input_1_) 38 | def anonymous_fun_135_(par_release_input_6_): 39 | """ 40 | par_release_input_6_: (Double,(Double,(Double,(Double,(Double,(Double,(Double,Double))))))) 41 | """ 42 | def anonymous_fun_136_(orange_input_2_): 43 | """ 44 | orange_input_2_: Double 45 | """ 46 | return laplace_fx(cfix(1.0),orange_input_2_) 47 | def anonymous_fun_137_(par_release_input_5_): 48 | """ 49 | par_release_input_5_: (Double,(Double,(Double,(Double,(Double,(Double,Double)))))) 50 | """ 51 | def anonymous_fun_138_(orange_input_3_): 52 | """ 53 | orange_input_3_: Double 54 | """ 55 | return laplace_fx(cfix(1.0),orange_input_3_) 56 | def anonymous_fun_139_(par_release_input_4_): 57 | """ 58 | par_release_input_4_: (Double,(Double,(Double,(Double,(Double,Double))))) 59 | """ 60 | def anonymous_fun_140_(orange_input_4_): 61 | """ 62 | orange_input_4_: Double 63 | """ 64 | return laplace_fx(cfix(1.0),orange_input_4_) 65 | def anonymous_fun_141_(par_release_input_3_): 66 | """ 67 | par_release_input_3_: (Double,(Double,(Double,(Double,Double)))) 68 | """ 69 | def anonymous_fun_142_(orange_input_5_): 70 | """ 71 | orange_input_5_: Double 72 | """ 73 | return laplace_fx(cfix(1.0),orange_input_5_) 74 | def anonymous_fun_143_(par_release_input_2_): 75 | """ 76 | par_release_input_2_: (Double,(Double,(Double,Double))) 77 | """ 78 | def anonymous_fun_144_(orange_input_6_): 79 | """ 80 | orange_input_6_: Double 81 | """ 82 | return laplace_fx(cfix(1.0),orange_input_6_) 83 | def anonymous_fun_145_(par_release_input_1_): 84 | """ 85 | par_release_input_1_: (Double,(Double,Double)) 86 | """ 87 | def anonymous_fun_146_(orange_input_7_): 88 | """ 89 | orange_input_7_: Double 90 | """ 91 | return laplace_fx(cfix(1.0),orange_input_7_) 92 | def anonymous_fun_147_(par_release_input_0_): 93 | """ 94 | par_release_input_0_: (Double,Double) 95 | """ 96 | def anonymous_fun_148_(orange_input_8_): 97 | """ 98 | orange_input_8_: Double 99 | """ 100 | return laplace_fx(cfix(1.0),orange_input_8_) 101 | def anonymous_fun_149_(orange_input_9_): 102 | """ 103 | orange_input_9_: Double 104 | """ 105 | return laplace_fx(cfix(1.0),orange_input_9_) 106 | return (anonymous_fun_148_(par_release_input_0_[0]),anonymous_fun_149_(par_release_input_0_[1])) 107 | return (anonymous_fun_146_(par_release_input_1_[0]),anonymous_fun_147_(par_release_input_1_[1])) 108 | return (anonymous_fun_144_(par_release_input_2_[0]),anonymous_fun_145_(par_release_input_2_[1])) 109 | return (anonymous_fun_142_(par_release_input_3_[0]),anonymous_fun_143_(par_release_input_3_[1])) 110 | return (anonymous_fun_140_(par_release_input_4_[0]),anonymous_fun_141_(par_release_input_4_[1])) 111 | return (anonymous_fun_138_(par_release_input_5_[0]),anonymous_fun_139_(par_release_input_5_[1])) 112 | return (anonymous_fun_136_(par_release_input_6_[0]),anonymous_fun_137_(par_release_input_6_[1])) 113 | return (anonymous_fun_134_(par_release_input_7_[0]),anonymous_fun_135_(par_release_input_7_[1])) 114 | return (anonymous_fun_132_(par_release_input_8_[0]),anonymous_fun_133_(par_release_input_8_[1])) 115 | return anonymous_fun_131_ 116 | 117 | 118 | anonymous_fun_130_(()) 119 | -------------------------------------------------------------------------------- /mpc_files/Programs/histogram/histogram.mpc: -------------------------------------------------------------------------------- 1 | k = 39 2 | 3 | def laplace_fx(center, width): 4 | return center + sint.get_random_bit(width) 5 | 6 | orange_input_0_ = sint.get_private_input_from(k) 7 | orange_input_1_ = sint.get_private_input_from(k) 8 | orange_input_2_ = sint.get_private_input_from(k) 9 | orange_input_3_ = sint.get_private_input_from(k) 10 | orange_input_4_ = sint.get_private_input_from(k) 11 | orange_input_5_ = sint.get_private_input_from(k) 12 | orange_input_6_ = sint.get_private_input_from(k) 13 | orange_input_7_ = sint.get_private_input_from(k) 14 | orange_input_8_ = sint.get_private_input_from(k) 15 | orange_input_8_ = sint.get_private_input_from(k) 16 | 17 | 18 | def anonymous_fun_30_(empty_closure_1_): 19 | """ 20 | empty_closure_1_: () 21 | """ 22 | def anonymous_fun_31_(par_release_input_8_): 23 | """ 24 | par_release_input_8_: (Double,(Double,(Double,(Double,(Double,(Double,(Double,(Double,(Double,Double))))))))) 25 | """ 26 | def anonymous_fun_32_(orange_input_0_): 27 | """ 28 | orange_input_0_: Double 29 | """ 30 | return laplace_fx(cfix(1.0),orange_input_0_) 31 | def anonymous_fun_33_(par_release_input_7_): 32 | """ 33 | par_release_input_7_: (Double,(Double,(Double,(Double,(Double,(Double,(Double,(Double,Double)))))))) 34 | """ 35 | def anonymous_fun_34_(orange_input_1_): 36 | """ 37 | orange_input_1_: Double 38 | """ 39 | return laplace_fx(cfix(1.0),orange_input_1_) 40 | def anonymous_fun_35_(par_release_input_6_): 41 | """ 42 | par_release_input_6_: (Double,(Double,(Double,(Double,(Double,(Double,(Double,Double))))))) 43 | """ 44 | def anonymous_fun_36_(orange_input_2_): 45 | """ 46 | orange_input_2_: Double 47 | """ 48 | return laplace_fx(cfix(1.0),orange_input_2_) 49 | def anonymous_fun_37_(par_release_input_5_): 50 | """ 51 | par_release_input_5_: (Double,(Double,(Double,(Double,(Double,(Double,Double)))))) 52 | """ 53 | def anonymous_fun_38_(orange_input_3_): 54 | """ 55 | orange_input_3_: Double 56 | """ 57 | return laplace_fx(cfix(1.0),orange_input_3_) 58 | def anonymous_fun_39_(par_release_input_4_): 59 | """ 60 | par_release_input_4_: (Double,(Double,(Double,(Double,(Double,Double))))) 61 | """ 62 | def anonymous_fun_40_(orange_input_4_): 63 | """ 64 | orange_input_4_: Double 65 | """ 66 | return laplace_fx(cfix(1.0),orange_input_4_) 67 | def anonymous_fun_41_(par_release_input_3_): 68 | """ 69 | par_release_input_3_: (Double,(Double,(Double,(Double,Double)))) 70 | """ 71 | def anonymous_fun_42_(orange_input_5_): 72 | """ 73 | orange_input_5_: Double 74 | """ 75 | return laplace_fx(cfix(1.0),orange_input_5_) 76 | def anonymous_fun_43_(par_release_input_2_): 77 | """ 78 | par_release_input_2_: (Double,(Double,(Double,Double))) 79 | """ 80 | def anonymous_fun_44_(orange_input_6_): 81 | """ 82 | orange_input_6_: Double 83 | """ 84 | return laplace_fx(cfix(1.0),orange_input_6_) 85 | def anonymous_fun_45_(par_release_input_1_): 86 | """ 87 | par_release_input_1_: (Double,(Double,Double)) 88 | """ 89 | def anonymous_fun_46_(orange_input_7_): 90 | """ 91 | orange_input_7_: Double 92 | """ 93 | return laplace_fx(cfix(1.0),orange_input_7_) 94 | def anonymous_fun_47_(par_release_input_0_): 95 | """ 96 | par_release_input_0_: (Double,Double) 97 | """ 98 | def anonymous_fun_48_(orange_input_8_): 99 | """ 100 | orange_input_8_: Double 101 | """ 102 | return laplace_fx(cfix(1.0),orange_input_8_) 103 | def anonymous_fun_49_(orange_input_9_): 104 | """ 105 | orange_input_9_: Double 106 | """ 107 | return laplace_fx(cfix(1.0),orange_input_9_) 108 | return (anonymous_fun_48_(par_release_input_0_[0]),anonymous_fun_49_(par_release_input_0_[1])) 109 | return (anonymous_fun_46_(par_release_input_1_[0]),anonymous_fun_47_(par_release_input_1_[1])) 110 | return (anonymous_fun_44_(par_release_input_2_[0]),anonymous_fun_45_(par_release_input_2_[1])) 111 | return (anonymous_fun_42_(par_release_input_3_[0]),anonymous_fun_43_(par_release_input_3_[1])) 112 | return (anonymous_fun_40_(par_release_input_4_[0]),anonymous_fun_41_(par_release_input_4_[1])) 113 | return (anonymous_fun_38_(par_release_input_5_[0]),anonymous_fun_39_(par_release_input_5_[1])) 114 | return (anonymous_fun_36_(par_release_input_6_[0]),anonymous_fun_37_(par_release_input_6_[1])) 115 | return (anonymous_fun_34_(par_release_input_7_[0]),anonymous_fun_35_(par_release_input_7_[1])) 116 | return (anonymous_fun_32_(par_release_input_8_[0]),anonymous_fun_33_(par_release_input_8_[1])) 117 | return anonymous_fun_31_ 118 | 119 | anonymous_fun_30_(()) 120 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ## Orchard 2 | 3 | This is a partial implementation of the Orchard private data analytics system. It does *not* include code to run a massively distributed data collection scheme on billions of devices. However, it does include the Orchard query engine which translates centralized queries into distributed ones. The resulting code is split into three parts: red, orange, and green zone code. 4 | - The orange zone code can be executed inside of an MPC framework. We provide a prototype of this infrastructure, with the ability to simulate many committee devices on one machine. For ease of use and to prevent inordinate costs, we do not provide the EC2 infrastructure to run these queries in a fully distributed setting. 5 | - The red zone code will be executed on user devices. We do not provide the infrastructure to run this code in a distributed way, but we provide benchmark numbers on the total costs associated with all user operations in Orchard. 6 | - The green zone code will be executed on a centralized aggregator with access to massive resources, such as a data center. We provide benchmark numbers on the total costs associated with all agregator operations as well. 7 | 8 | This repository also contains a simulation for malicious users attacking a facility clustering algorithm, and will produce the results that we report in the paper. 9 | 10 | In summary, this repository contains: 11 | - Orchard query translation source code (in cps_fuzz/) 12 | - Raw .mpc files for all sample queries in the Orchard paper, translated into orange-zone code that can be run in SCALE-MAMBA, our MPC infrastructure (in mpc_files/) 13 | - Orange-zone protocol testing infrastructure (in root-level folder) 14 | - Numbers for the k-means robustness experiment to defend against malicious users (in robustness/) 15 | - User and aggregation total cost numbers (in total_costs/) 16 | 17 | ## Instructions 18 | 19 | All of our code is implemented within a docker to allow for easy set-up and cross-compatability performance. 20 | 21 | ## Docker Setup 22 | Create a Docker image. This will take a few minutes (maybe up to half an hour). 23 | You only have to do this once (note: it may be necessary to allocate at least 8GB memory to Docker). 24 | ``` 25 | $ docker build -t orchard . 26 | ``` 27 | Spin up a Docker container from the image. 28 | ``` 29 | $ docker run -it --rm orchard 30 | ``` 31 | Please note that any changes you make in the container are not persistent. 32 | 33 | NOTE: if (for any reason), you are having any trouble with pip during the docker build, it may be because python2.7 is deprecated. If this occurs, please comment out the 4 'pip install' lines in the Dockerfile, and run the robustness/ experiment locally. These python libraries are only used for this portion of the experiments. 34 | 35 | ## Experiments 36 | 37 | To re-run the code extraction process inside of the docker container, clear the /root/cps-fuzz/extracted directory, then: 38 | ``` 39 | $ cd /root/cps-fuzz 40 | $ stack run 41 | ``` 42 | 43 | This will re-extract all benchmark algorithms into MAMBA MPC code which will be placed in the /root/cps-fuzz/extracted directory (note: this code contains both red and orange-zone code. This is then split into the pure orange-zone code inside of /root/SCALE-MAMBA/Programs/). 44 | 45 | For a walkthrough of how to write a *new* query, follow instructions in /root/cps-fuzz/ExampleQuery.md. 46 | 47 | ## Replication of Graphs/Tables in Paper 48 | 49 | (assuming you are running inside of the docker created above.) 50 | 51 | ### Table 2 52 | Examine the generated code in /root/cps-fuzz/extracted. The number of BMCS calls in each file should be the corresponding 'Optimized' column for each query's row. 53 | 54 | Since we only include one iteration in each query file, 'm' indicates that there will be one bmcs call in the extracted code, and 'm+1' indicates that there will be two bmcs calls, with only one of them required to be run in subsequent iterations. 55 | 56 | The 'Naive' column is manually generated, considering the total number of uploads towards a sum that each user must make for any given query. 57 | 58 | ### Figure 4 59 | To generate data and produce the graph (will take around 6 minutes): 60 | ``` 61 | $ cd /root/robustness/ 62 | $ mkdir defenseFigures 63 | $ python geogr.py >> geogrOut 64 | ``` 65 | 66 | This will populate a new .png image file in the defenseFigures/ folder. Note that to make this go faster, we run for less total trials (median across 10 trials, not 500!), so the data may be slightly different than reported in the paper. However, the numbers should be similar on expectation. You can play around with the parameters in geogr.py to use a different epsilon (set as 0.1) or different number of users (set as 4, meaning 10^4 total users) in the last line of this file. 67 | 68 | 'geogrOut' now also contains the raw data for Figure 4 (in the paper, we use this raw data and graph using gnuplot). 69 | 70 | ### Figure 6 71 | To simulate all committee members at once (without network costs): 72 | ``` 73 | $ cd /root/SCALE-MAMBA/ 74 | $ ./testd.sh $NUM_COMMITTEE_MEMBERS $PROG_NAME 75 | ``` 76 | 77 | Script must be run with at least 5 committee members (will take a few minutes to complete). One one machine, can be run with up to 15-17 committee members. The script will output Communication Cost in bytes, as well as timing. This script will not produce identical numbers to those in the paper, as this requires a full distributed run with a full committee, however, the numbers should reveal a similar pattern. 78 | 79 | Program names to test: 80 | - bag_filter_sum_noise 81 | - kmeans_iter 82 | - logistic_iter 83 | - naive_bayes 84 | - pca 85 | - perceptron_iter 86 | - simple_expm 87 | - above_threshold 88 | - histogram 89 | - vec_sum 90 | - count_mean_sketch 91 | - id3_iter 92 | - cdf 93 | - range_query 94 | - kmedian_iter_medium 95 | 96 | ### Figures 5, 7, 8 97 | 98 | Install gnuplot 5.2 patchlevel 6 (should be in the docker, but this version can be installed manually, if there are any issues). 99 | 100 | Go into '/root/total_costs' and run ```./plot_all.sh``` - this will populate all PDF files inside of the figures/ folder, which should be identical to those produced in the paper. 101 | 102 | The explanations for these figures are listed in the 'data_explanations' file in this folder, giving parameters/measurements and the formulas used to calculate total costs. 103 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_vector/test_vector.mpc: -------------------------------------------------------------------------------- 1 | a = 5424 2 | b = 3543 3 | 4 | ca = cint(a, size=16) 5 | cb = cint(b, size=16) 6 | sa = sint(a, size=16) 7 | sb = sint(b, size=16) 8 | 9 | test(cint(0, size=16)) 10 | test(cint(1, size=16)) 11 | test(ca) 12 | test(sb) 13 | 14 | test(sint(ca)) 15 | 16 | test(ca + cb) 17 | test(sa + cb) 18 | test(ca + sb) 19 | test(sa + sb) 20 | 21 | test(ca + b) 22 | test(a + cb) 23 | test(sa + b) 24 | test(a + sb) 25 | 26 | test(ca - cb) 27 | test(sa - cb) 28 | test(ca - sb) 29 | test(sa - sb) 30 | 31 | test(ca - b) 32 | test(a - cb) 33 | test(sa - b) 34 | test(a - sb) 35 | 36 | test(ca * cb) 37 | test(sa * cb) 38 | test(ca * sb) 39 | test(sa * sb) 40 | 41 | test(ca * b) 42 | test(a * cb) 43 | test(sa * b) 44 | test(a * sb) 45 | 46 | divisible = a - a % b 47 | test(cint(divisible, size=16) / cb) 48 | test(cint(divisible, size=16) / b) 49 | test(divisible / cb) 50 | test(sint(divisible, size=16) / cb) 51 | test(sint(divisible, size=16) / b) 52 | 53 | test(ca / 1) 54 | 55 | test(ca % cb) 56 | test(ca % b) 57 | test(a % cb) 58 | 59 | test(ca < cb) 60 | test(cb < ca) 61 | test(ca == ca) 62 | test(cb == cb) 63 | test(cb == ca) 64 | test(ca <= ca) 65 | test(ca <= ca - 1) 66 | test(ca > cb) 67 | test(cb > ca) 68 | test(ca >= cb) 69 | test(cb >= ca) 70 | test(ca >= ca) 71 | test(ca >= ca + 1) 72 | test(-ca < 0) 73 | test(0 > cb) 74 | test(ca != 0) 75 | 76 | int_max = cint(2**(program.bit_length-1) - 1, size=16) 77 | int_min = cint(-2**(program.bit_length-1), size=16) 78 | test(1 - int_max < 0) 79 | test(int_max - 1 <= int_max) 80 | test(int_max - 1 >= int_max) 81 | test(int_max - 1 < int_max) 82 | test(int_max - 1 > int_max) 83 | test(int_min < int_min + 1) 84 | test(int_min <= int_min + 1) 85 | test(int_min <= int_min) 86 | test(int_max >= 0) 87 | test(int_min <= 0) 88 | test(int_min < int_max) 89 | test(int_min > int_max) 90 | test(int_max == 0) 91 | test(int_min == 0) 92 | test(int_min == int_max) 93 | test(int_min == int_min) 94 | test(int_max == int_max) 95 | 96 | test(get_random_bit(size=16), 0, 2) 97 | 98 | test(get_random_int(1, size=16), 0, 2) 99 | test(get_random_int(16, size=16), 0, 2 ** 16) 100 | test(get_random_int(30, size=16), 0, 2 ** 30) 101 | 102 | t1, t2, t3 = sint.get_random_triple(size=16) 103 | test(reveal(t1) * reveal(t2) - reveal(t3), 0) 104 | s1, s2 = sint.get_random_square(size=16) 105 | test(reveal(s1) * reveal(s1) - reveal(s2), 0) 106 | 107 | program.bit_length = 16 108 | program.security = 8 109 | 110 | test(sa % 2) 111 | test(sb % 2) 112 | test(sa % 4) 113 | test(sb % 4) 114 | test(sa % 8) 115 | test(sb % 8) 116 | 117 | test(sa < sb) 118 | test(sa < sa) 119 | test(sa < sa + 1) 120 | test(-sa < sa) 121 | test(-sb < sb) 122 | test(sa < -sb) 123 | test(-sa < -sb) 124 | 125 | test(ca < cb) 126 | test(sa < cb) 127 | test(ca < sb) 128 | test(sa < sb) 129 | 130 | test(ca < b) 131 | test(a < cb) 132 | test(sa < b) 133 | test(a < sb) 134 | 135 | test(ca > cb) 136 | test(sa > cb) 137 | test(ca > sb) 138 | test(sa > sb) 139 | 140 | test(ca > b) 141 | test(a > cb) 142 | test(sa > b) 143 | test(a > sb) 144 | 145 | test(ca <= cb) 146 | test(sa <= cb) 147 | test(ca <= sb) 148 | test(sa <= sb) 149 | 150 | test(ca <= b) 151 | test(a <= cb) 152 | test(sa <= b) 153 | test(a <= sb) 154 | 155 | test(ca >= cb) 156 | test(sa >= cb) 157 | test(ca >= sb) 158 | test(sa >= sb) 159 | 160 | test(ca >= b) 161 | test(a >= cb) 162 | test(sa >= b) 163 | test(a >= sb) 164 | 165 | test(ca == cb) 166 | test(sa == cb) 167 | test(ca == sb) 168 | test(sa == sb) 169 | 170 | test(ca == b) 171 | test(a == cb) 172 | test(sa == b) 173 | test(a == sb) 174 | 175 | test(ca != cb) 176 | test(sa != cb) 177 | test(ca != sb) 178 | test(sa != sb) 179 | 180 | test(ca != b) 181 | test(a != cb) 182 | test(sa != b) 183 | test(a != sb) 184 | 185 | test(ca != ca) 186 | test(sa != ca) 187 | test(ca != sa) 188 | test(sa != sa) 189 | 190 | test(ca != a) 191 | test(a != ca) 192 | test(sa != a) 193 | test(a != sa) 194 | 195 | test(ca & cb) 196 | test(ca & b) 197 | test(a & cb) 198 | 199 | test(ca ^ cb) 200 | test(ca ^ b) 201 | test(a ^ cb) 202 | 203 | test(ca | cb) 204 | test(ca | b) 205 | test(a | cb) 206 | 207 | i = 3 208 | ci = cint(i, size=16) 209 | si = sint(i, size=16) 210 | 211 | test(ca << ci) 212 | test(sa << ci) 213 | test(ca << si) 214 | test(sa << si) 215 | 216 | test(ca << i) 217 | test(a << ci) 218 | test(sa << i) 219 | test(a << si) 220 | 221 | test(ca >> ci) 222 | #test(sa >> ci) 223 | test(ca >> si) 224 | test(sa >> si) 225 | 226 | test(ca >> i) 227 | test(a >> ci) 228 | test(sa >> i) 229 | test(a >> si) 230 | 231 | test(cint(0, size=16) << i) 232 | test(cint(0, size=16) << ci) 233 | test(cint(0, size=16) << si) 234 | test(cint(0, size=16) >> i) 235 | test(cint(0, size=16) >> ci) 236 | test(cint(0, size=16) >> si) 237 | 238 | test(ca >> 0) 239 | test(ca << 0) 240 | test(ca >> cint(0, size=16)) 241 | test(ca << cint(0, size=16)) 242 | test(ca >> sint(0, size=16)) 243 | test(ca << sint(0, size=16)) 244 | 245 | test(2 ** ci) 246 | test(2 ** si) 247 | 248 | test(ci ** 0) 249 | test(si ** 0) 250 | test(ci ** 1) 251 | test(si ** 1) 252 | test(ci ** 2) 253 | test(si ** 2) 254 | test(ci ** 3) 255 | test(si ** 3) 256 | test(ci ** 4) 257 | test(si ** 4) 258 | test(ci ** 5) 259 | test(si ** 5) 260 | 261 | test(-ca) 262 | test(-sa) 263 | 264 | test(~ca, ~a + 2 ** program.bit_length) 265 | 266 | store_in_mem(sa, 0) 267 | store_in_mem(cb, 0) 268 | test(sint.load_mem(0, size=16), a) 269 | test(cint.load_mem(0, size=16), b) 270 | 271 | test(sint(0, size=16) == sint(0, size=16)) 272 | test(sint(1, size=16) == sint(0, size=16)) 273 | test(sint(-1, size=16) == sint(-1, size=16)) 274 | test(sint(-1, size=16) == sint(0, size=16)) 275 | test(sint(0, size=16) != sint(0, size=16)) 276 | test(sint(1, size=16) != sint(0, size=16)) 277 | test(sint(2**(program.bit_length-1), size=16) == sint(0, size=16)) 278 | test(sint(2**(program.bit_length-1)-1, size=16) == sint(-1, size=16)) 279 | 280 | test(cint(2**31, size=16)) 281 | test(cint(2**31+1, size=16)) 282 | test(cint(-2**31, size=16)) 283 | test(cint(-2**31-1, size=16)) 284 | 285 | test(sint(2**31, size=16)) 286 | test(sint(2**31+1, size=16)) 287 | test(sint(-2**31+1, size=16)) 288 | test(sint(-2**31-1, size=16)) 289 | 290 | def f(): 291 | test(get_thread_number(size=16), 1) 292 | test(get_arg(size=16), 9876) 293 | 294 | def g(): 295 | test(cint(0)) 296 | 297 | thread = MPCThread(f, 'test') 298 | thread2 = MPCThread(g, 'test2') 299 | thread2.start() 300 | thread.start(9876) 301 | thread2.join() 302 | thread.join() 303 | -------------------------------------------------------------------------------- /mpc_files/Programs/test_comparison/test_comparison.mpc: -------------------------------------------------------------------------------- 1 | x = sint() 2 | y = sint() 3 | z = [sint() for i in range(3)] 4 | comparison.PRandM(x, y, z, 5, 3, 7) 5 | test(x, 0, 2 ** 9) 6 | test(y, 0, 2 ** 3) 7 | test(z[0], 0, 2) 8 | test(z[1], 0, 2) 9 | test(z[2], 0, 2) 10 | test(y - z[0] - 2 * z[1] - 4 * z[2], 0) 11 | 12 | x = sint() 13 | y = sint() 14 | z = sint() 15 | comparison.PRandM(x, y, [z], 16, 1, 8) 16 | test(y - z, 0) 17 | test(x, 0, 2**23) 18 | 19 | x = cint() 20 | comparison.ld2i(x, 31) 21 | test(x, 2 ** 31) 22 | 23 | x = [sint(i) for i in range(100,103)] 24 | z = [sint() for i in range(3)] 25 | comparison.PreMulC_without_inverses(z, x) 26 | test(z[0], 100) 27 | test(z[1], 100 * 101) 28 | test(z[2], 100 * 101 * 102) 29 | 30 | x = [sint(i) for i in range(100,103)] 31 | z = comparison.PreMulC(x) 32 | test(z[0], 100) 33 | test(z[1], 100 * 101) 34 | test(z[2], 100 * 101 * 102) 35 | 36 | x = [sint(i) for i in range(100,103)] 37 | z = comparison.KMulC(x) 38 | test(z, 100 * 101 * 102) 39 | 40 | x = cint(2) 41 | y = [sint(i) for i in [1,1]] 42 | z = sint() 43 | pp, a_bits, d, s, t, c, bb, pre_input = comparison.BitLTC1(z, x, y, 16) 44 | test1(bb[0], 1) 45 | test(bb[1], 1) 46 | test1(a_bits[0], 0) 47 | test(a_bits[1], 1) 48 | test1(c[2][0], 0) 49 | test1(t[0][0], 0) 50 | test1(t[1][0], 1) 51 | test(t[1][1], 2) 52 | test1(d[0], 1) 53 | test(d[1], 0) 54 | test1(pp[0], 2) 55 | test(pp[1], 1) 56 | test1(s[0], 1) 57 | test(s[1], 0) 58 | test(z, 1) 59 | 60 | x = cint(2) 61 | y = [sint(i) for i in [1,0]] 62 | z = sint() 63 | pp, a_bits, d, s, t, c, bb, pre_input = comparison.BitLTC1(z, x, y, 16) 64 | test1(a_bits[0], 0) 65 | test(c[0][1], 2) 66 | test(c[1][1], 1) 67 | test(a_bits[1], 1) 68 | test1(c[2][0], 0) 69 | test1(t[0][0], 0) 70 | test1(t[1][0], 1) 71 | test1(d[0], 1) 72 | test(c[2][1], 2) 73 | test(bb[1], 0) 74 | test(t[0][1], 0) 75 | test(t[1][1], 1) 76 | test(d[1], 1) 77 | test1(pre_input[0], 2) 78 | test1(pre_input[1], 2) 79 | test(pp[0], 4) 80 | test(pp[1], 2) 81 | test1(s[0], 2) 82 | test(s[1], 1) 83 | test(z, 0) 84 | 85 | x = cint(3) 86 | y = [sint(i) for i in [1,1]] 87 | z = sint() 88 | comparison.BitLTC1(z, x, y, 16) 89 | test(z, 0) 90 | 91 | x = cint(2) 92 | y = [sint(i) for i in [1,1]] 93 | z = sint() 94 | comparison.BitLTL(z, x, y, 16) 95 | test(z, 1) 96 | 97 | x = cint(2) 98 | y = [sint(i) for i in [1,0]] 99 | z = sint() 100 | a_bits, s0 = comparison.BitLTL(z, x, y, 16) 101 | test(a_bits[0], 0) 102 | test(a_bits[1], 1) 103 | test(s0[0], 0) 104 | test(s0[1], 1) 105 | test(z, 0) 106 | 107 | x = cint(3) 108 | y = [sint(i) for i in [1,1]] 109 | z = sint() 110 | comparison.BitLTL(z, x, y, 16) 111 | test(z, 0) 112 | 113 | x = [cint(i) for i in [1,0]] 114 | y = [sint(i) for i in [0,1]] 115 | z = sint() 116 | comparison.CarryOut(z, x, y, 0, 16) 117 | test(z, 0) 118 | 119 | x = [cint(i) for i in [1,0]] 120 | y = [sint(i) for i in [1,1]] 121 | z = sint() 122 | comparison.CarryOut(z, x, y, 0, 16) 123 | test(z, 1) 124 | 125 | x = [cint(i) for i in [1,1]] 126 | y = [sint(i) for i in [0,1]] 127 | z = sint() 128 | comparison.CarryOut(z, x, y, 0, 16) 129 | test(z, 1) 130 | 131 | x = [cint(i) for i in [0,0]] 132 | y = [sint(i) for i in [0,1]] 133 | z = sint() 134 | comparison.CarryOut(z, x, y, 0, 16) 135 | test(z, 0) 136 | 137 | x = [cint(i) for i in [0,1]] 138 | y = [sint(i) for i in [0,1]] 139 | z = sint() 140 | comparison.CarryOut(z, x, y, 0, 16) 141 | test(z, 0) 142 | 143 | x = [cint(i) for i in [1,0]] 144 | y = [sint(i) for i in [0,1]] 145 | z = sint() 146 | comparison.CarryOut(z, x, y, 1, 16) 147 | test(z, 1) 148 | 149 | x = [cint(i) for i in [0,1]] 150 | y = [sint(i) for i in [0,1]] 151 | z = sint() 152 | comparison.CarryOut(z, x, y, 1, 16) 153 | test(z, 0) 154 | 155 | x = [cint(i) for i in [1,0]] 156 | y = [sint(i) for i in [1,0]] 157 | z = sint() 158 | comparison.CarryOut(z, x, y, 1, 16) 159 | test(z, 1) 160 | 161 | x = cint(5) 162 | y = [sint(i) for i in [1,0,1]] 163 | z = sint() 164 | comparison.BitLTL(z, x, y, 16) 165 | test(z, 0) 166 | 167 | x = cint(5) 168 | y = [sint(i) for i in [1,1,1]] 169 | z = sint() 170 | comparison.BitLTL(z, x, y, 16) 171 | test(z, 1) 172 | 173 | b = 2137 174 | sb = sint(b) 175 | a_prime = sint() 176 | r_dprime, r_prime, c, c_prime, u, t, c2k1 = \ 177 | comparison.Mod2m(a_prime, sb, 16, 2, 8, True) 178 | test(r_dprime, 0, 2 ** 22) 179 | test(r_prime, 0, 2 ** 2) 180 | test(c2k1, 2 ** 15) 181 | test(t[0], 0, 2 ** 24) 182 | test(t[1], 0, 2 ** 17) 183 | test(t[2], 0, 2 ** 25) 184 | test(c, 0, 2 ** 26) 185 | test(c_prime, 0, 2 ** 2) 186 | test(u, 0, 2) 187 | test(a_prime, 0, 2 ** 2) 188 | test(a_prime, b % 4) 189 | 190 | test(comparison.TruncRoundNearest(sint(7), 16, 1, 8), 4) 191 | test(comparison.TruncRoundNearest(sint(4), 16, 1, 8), 2) 192 | 193 | test(comparison.TruncRoundNearest(sint(0), 16, 2, 8), 0) 194 | test(comparison.TruncRoundNearest(sint(1), 16, 2, 8), 0) 195 | test(comparison.TruncRoundNearest(sint(2), 16, 2, 8), 1) 196 | test(comparison.TruncRoundNearest(sint(3), 16, 2, 8), 1) 197 | test(comparison.TruncRoundNearest(sint(4), 16, 2, 8), 1) 198 | test(comparison.TruncRoundNearest(sint(5), 16, 2, 8), 1) 199 | test(comparison.TruncRoundNearest(sint(6), 16, 2, 8), 2) 200 | test(comparison.TruncRoundNearest(sint(7), 16, 2, 8), 2) 201 | test(comparison.TruncRoundNearest(sint(8), 16, 2, 8), 2) 202 | test(comparison.TruncRoundNearest(sint(9), 16, 2, 8), 2) 203 | test(comparison.TruncRoundNearest(sint(10), 16, 2, 8), 3) 204 | test(comparison.TruncRoundNearest(sint(11), 16, 2, 8), 3) 205 | test(comparison.TruncRoundNearest(sint(12), 16, 2, 8), 3) 206 | test(comparison.TruncRoundNearest(sint(13), 16, 2, 8), 3) 207 | test(comparison.TruncRoundNearest(sint(14), 16, 2, 8), 4) 208 | test(comparison.TruncRoundNearest(sint(15), 16, 2, 8), 4) 209 | 210 | test(comparison.TruncRoundNearest(sint(0), 16, 3, 8), 0) 211 | test(comparison.TruncRoundNearest(sint(1), 16, 3, 8), 0) 212 | test(comparison.TruncRoundNearest(sint(2), 16, 3, 8), 0) 213 | test(comparison.TruncRoundNearest(sint(3), 16, 3, 8), 0) 214 | test(comparison.TruncRoundNearest(sint(4), 16, 3, 8), 1) 215 | test(comparison.TruncRoundNearest(sint(5), 16, 3, 8), 1) 216 | test(comparison.TruncRoundNearest(sint(6), 16, 3, 8), 1) 217 | test(comparison.TruncRoundNearest(sint(7), 16, 3, 8), 1) 218 | test(comparison.TruncRoundNearest(sint(8), 16, 3, 8), 1) 219 | test(comparison.TruncRoundNearest(sint(9), 16, 3, 8), 1) 220 | test(comparison.TruncRoundNearest(sint(10), 16, 3, 8), 1) 221 | test(comparison.TruncRoundNearest(sint(11), 16, 3, 8), 1) 222 | test(comparison.TruncRoundNearest(sint(12), 16, 3, 8), 2) 223 | test(comparison.TruncRoundNearest(sint(13), 16, 3, 8), 2) 224 | test(comparison.TruncRoundNearest(sint(14), 16, 3, 8), 2) 225 | test(comparison.TruncRoundNearest(sint(15), 16, 3, 8), 2) 226 | 227 | x = sint(1) 228 | y = sint() 229 | comparison.Mod2(y, x, 1, 8, False) 230 | test(y, 1) 231 | 232 | x = sint(2**10 - 1) 233 | y = sint() 234 | comparison.Mod2(y, x, 10, 8, False) 235 | test(y, 1) 236 | 237 | x = sint(2**10 - 1) 238 | y = sint() 239 | comparison.Mod2(y, x, 11, 8, False) 240 | test(y, 1) 241 | 242 | x = sint(-2**10) 243 | y = sint() 244 | comparison.Mod2(y, x, 11, 8, False) 245 | test(y, 0) 246 | --------------------------------------------------------------------------------