├── .gitignore
├── .travis.yml
├── .vscode
├── launch.json
├── settings.json
└── tasks.json
├── LICENSE
├── Makefile
├── README.md
├── cascade
├── algorithm.cpp
├── block.cpp
├── classical_session.cpp
├── iteration.cpp
├── key.cpp
├── mock_classical_session.cpp
├── pending_item.cpp
├── random.cpp
├── reconciliation.cpp
├── report.cpp
├── shuffle.cpp
├── shuffled_key.cpp
└── stats.cpp
├── docs
└── figures
│ ├── andre-reis-thesis-figure-5-1-original.png
│ ├── andre-reis-thesis-figure-5-1-reproduced.png
│ ├── andre-reis-thesis-figure-5-10-original.png
│ ├── andre-reis-thesis-figure-5-2-original.png
│ ├── andre-reis-thesis-figure-5-2-reproduced.png
│ ├── andre-reis-thesis-figure-5-3-original.png
│ ├── andre-reis-thesis-figure-5-3-reproduced.png
│ ├── andre-reis-thesis-figure-5-4-original.png
│ ├── andre-reis-thesis-figure-5-5-a-reproduced.png
│ ├── andre-reis-thesis-figure-5-5-b-reproduced.png
│ ├── andre-reis-thesis-figure-5-5-original.png
│ ├── andre-reis-thesis-figure-5-5a-reproduced.png
│ ├── andre-reis-thesis-figure-5-5b-reproduced.png
│ ├── andre-reis-thesis-figure-5-6-original.png
│ ├── andre-reis-thesis-figure-5-7-original.png
│ ├── andre-reis-thesis-figure-5-8-original.png
│ ├── andre-reis-thesis-figure-5-9-original.png
│ ├── demystifying-figure-1-original.png
│ ├── demystifying-figure-1-reproduced.png
│ ├── demystifying-figure-10-original.png
│ ├── demystifying-figure-10-reproduced.png
│ ├── demystifying-figure-11-original.png
│ ├── demystifying-figure-11-reproduced.png
│ ├── demystifying-figure-11-reproduced.png.png
│ ├── demystifying-figure-12-original.png
│ ├── demystifying-figure-13-original.png
│ ├── demystifying-figure-13-reproduced.png
│ ├── demystifying-figure-2-original.png
│ ├── demystifying-figure-2-reproduced.png
│ ├── demystifying-figure-3-original.png
│ ├── demystifying-figure-3-reproduced.png
│ ├── demystifying-figure-4-original.png
│ ├── demystifying-figure-4-reproduced.png
│ ├── demystifying-figure-5-original.png
│ ├── demystifying-figure-5-reproduced.png
│ ├── demystifying-figure-6-original.png
│ ├── demystifying-figure-7-original.png
│ ├── demystifying-figure-8-original.png
│ ├── demystifying-figure-8-reproduced.png
│ ├── demystifying-figure-9-original.png
│ └── demystifying-figure-9-reproduced.png
├── include
├── algorithm.h
├── block.h
├── classical_session.h
├── debug.h
├── iteration.h
├── key.h
├── mock_classical_session.h
├── pending_item.h
├── random.h
├── reconciliation.h
├── report.h
├── shuffle.h
├── shuffled_key.h
└── stats.h
├── src
└── block.cpp
├── study
├── aggregate_stats.cpp
├── aggregate_stats.h
├── data
│ ├── debug
│ │ └── data__algorithm=biconf-cascade;key_size=vary;error_rate=0.1
│ ├── papers
│ │ ├── data__algorithm=biconf;key_size=10000;error_rate=vary
│ │ ├── data__algorithm=biconf;key_size=1000;error_rate=vary
│ │ ├── data__algorithm=biconf;key_size=2000;error_rate=vary
│ │ ├── data__algorithm=biconf;key_size=vary;error_rate=0.05
│ │ ├── data__algorithm=option3;key_size=10000;error_rate=vary
│ │ ├── data__algorithm=option3;key_size=1000;error_rate=vary
│ │ ├── data__algorithm=option3;key_size=2000;error_rate=vary
│ │ ├── data__algorithm=option3;key_size=vary;error_rate=0.05
│ │ ├── data__algorithm=option4;key_size=10000;error_rate=vary
│ │ ├── data__algorithm=option4;key_size=1000;error_rate=vary
│ │ ├── data__algorithm=option4;key_size=2000;error_rate=vary
│ │ ├── data__algorithm=option4;key_size=vary;error_rate=0.05
│ │ ├── data__algorithm=option7;key_size=10000;error_rate=vary
│ │ ├── data__algorithm=option7;key_size=1000;error_rate=vary
│ │ ├── data__algorithm=option7;key_size=2000;error_rate=vary
│ │ ├── data__algorithm=option7;key_size=vary;error_rate=0.05
│ │ ├── data__algorithm=option8;key_size=10000;error_rate=vary
│ │ ├── data__algorithm=option8;key_size=1000;error_rate=vary
│ │ ├── data__algorithm=option8;key_size=2000;error_rate=vary
│ │ ├── data__algorithm=option8;key_size=vary;error_rate=0.05
│ │ ├── data__algorithm=original;key_size=10000;error_rate=vary
│ │ ├── data__algorithm=original;key_size=1000;error_rate=vary
│ │ ├── data__algorithm=original;key_size=2000;error_rate=vary
│ │ ├── data__algorithm=original;key_size=vary;error_rate=0.01
│ │ ├── data__algorithm=original;key_size=vary;error_rate=0.02
│ │ ├── data__algorithm=original;key_size=vary;error_rate=0.05
│ │ ├── data__algorithm=yanetal;key_size=10000;error_rate=vary
│ │ ├── data__algorithm=yanetal;key_size=1000;error_rate=vary
│ │ ├── data__algorithm=yanetal;key_size=2000;error_rate=vary
│ │ └── data__algorithm=yanetal;key_size=vary;error_rate=0.05
│ ├── performance
│ │ ├── data__algorithm=biconf;key_size=10000;error_rate=vary
│ │ ├── data__algorithm=biconf;key_size=vary;error_rate=0.02
│ │ ├── data__algorithm=option7;key_size=10000;error_rate=vary
│ │ ├── data__algorithm=option7;key_size=vary;error_rate=0.02
│ │ ├── data__algorithm=original;key_size=10000;error_rate=vary
│ │ ├── data__algorithm=original;key_size=vary;error_rate=0.02
│ │ ├── data__algorithm=yanetal;key_size=10000;error_rate=vary
│ │ └── data__algorithm=yanetal;key_size=vary;error_rate=0.02
│ └── zero_handling
│ │ ├── data__algorithm=biconf;key_size=10000;error_rate=vary
│ │ └── data__algorithm=original;key_size=10000;error_rate=vary
├── data_point.cpp
├── data_point.h
├── experiments.cpp
├── experiments.h
├── experiments_debug.json
├── experiments_papers.json
├── experiments_performance.json
├── experiments_profile.json
├── experiments_zero_handling.json
├── graphs_andre_reis_thesis.json
├── graphs_demystifying.json
├── graphs_performance.json
├── graphs_zero_handling.json
├── options.cpp
├── options.h
├── run_experiments.cpp
├── series.cpp
└── series.h
└── tests
├── test_algorithm.cpp
├── test_block.cpp
├── test_key.cpp
├── test_main.cpp
└── test_reconciliation.cpp
/.gitignore:
--------------------------------------------------------------------------------
1 | # Prerequisites
2 | *.d
3 |
4 | # Compiled Object files
5 | *.slo
6 | *.lo
7 | *.o
8 | *.obj
9 |
10 | # Precompiled Headers
11 | *.gch
12 | *.pch
13 |
14 | # Compiled Dynamic libraries
15 | *.so
16 | *.dylib
17 | *.dll
18 | *.dSYM/*
19 |
20 | # Fortran module files
21 | *.mod
22 | *.smod
23 |
24 | # Compiled Static libraries
25 | *.lai
26 | *.la
27 | *.a
28 | *.lib
29 |
30 | # Executables
31 | *.exe
32 | *.out
33 | *.app
34 |
35 | # Executables
36 | bin/*
37 |
38 | # Code coverage, profiling, and memory leak files
39 | coverage/*
40 | valgrind.log
41 | callgrind.out.*
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: cpp
2 | dist: bionic
3 | compiler:
4 | - clang
5 | os:
6 | - linux
7 | install:
8 | - make ubuntu-get-dependencies
9 | script:
10 | - make test-coverage
11 | after_success:
12 | - bash <(curl -s https://codecov.io/bash)
13 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | // Use IntelliSense to learn about possible attributes.
3 | // Hover to view descriptions of existing attributes.
4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
5 | "version": "0.2.0",
6 | "configurations": [
7 | {
8 | "name": "Test",
9 | "request": "launch",
10 | "program": "make",
11 | "args": ["test"],
12 | "cwd": "${workspaceFolder}",
13 | "externalConsole": false,
14 | },
15 | {
16 | "name": "Debug",
17 | "type": "cppdbg",
18 | "request": "launch",
19 | "program": "${workspaceFolder}/bin/test-coverage",
20 | "args": ["study/experiments_papers.json"],
21 | "stopAtEntry": false,
22 | "cwd": "${workspaceFolder}",
23 | "environment": [],
24 | "externalConsole": false,
25 | "MIMode": "lldb",
26 | }
27 | ]
28 | }
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | {
2 | "files.associations": {
3 | ".fantomasignore": "ignore",
4 | "random": "cpp",
5 | "__bit_reference": "cpp",
6 | "__config": "cpp",
7 | "__debug": "cpp",
8 | "__errc": "cpp",
9 | "__functional_base": "cpp",
10 | "__hash_table": "cpp",
11 | "__locale": "cpp",
12 | "__mutex_base": "cpp",
13 | "__node_handle": "cpp",
14 | "__nullptr": "cpp",
15 | "__split_buffer": "cpp",
16 | "__string": "cpp",
17 | "__threading_support": "cpp",
18 | "__tree": "cpp",
19 | "__tuple": "cpp",
20 | "algorithm": "cpp",
21 | "array": "cpp",
22 | "atomic": "cpp",
23 | "bitset": "cpp",
24 | "cctype": "cpp",
25 | "chrono": "cpp",
26 | "clocale": "cpp",
27 | "cmath": "cpp",
28 | "complex": "cpp",
29 | "condition_variable": "cpp",
30 | "csignal": "cpp",
31 | "cstdarg": "cpp",
32 | "cstddef": "cpp",
33 | "cstdint": "cpp",
34 | "cstdio": "cpp",
35 | "cstdlib": "cpp",
36 | "cstring": "cpp",
37 | "ctime": "cpp",
38 | "cwchar": "cpp",
39 | "cwctype": "cpp",
40 | "deque": "cpp",
41 | "exception": "cpp",
42 | "optional": "cpp",
43 | "fstream": "cpp",
44 | "functional": "cpp",
45 | "initializer_list": "cpp",
46 | "iomanip": "cpp",
47 | "ios": "cpp",
48 | "iosfwd": "cpp",
49 | "iostream": "cpp",
50 | "istream": "cpp",
51 | "iterator": "cpp",
52 | "limits": "cpp",
53 | "list": "cpp",
54 | "locale": "cpp",
55 | "map": "cpp",
56 | "memory": "cpp",
57 | "mutex": "cpp",
58 | "new": "cpp",
59 | "numeric": "cpp",
60 | "ostream": "cpp",
61 | "queue": "cpp",
62 | "ratio": "cpp",
63 | "set": "cpp",
64 | "sstream": "cpp",
65 | "stdexcept": "cpp",
66 | "streambuf": "cpp",
67 | "string": "cpp",
68 | "string_view": "cpp",
69 | "system_error": "cpp",
70 | "thread": "cpp",
71 | "tuple": "cpp",
72 | "type_traits": "cpp",
73 | "typeinfo": "cpp",
74 | "unordered_map": "cpp",
75 | "utility": "cpp",
76 | "vector": "cpp",
77 | "bit": "cpp",
78 | "*.tcc": "cpp",
79 | "memory_resource": "cpp",
80 | "cinttypes": "cpp",
81 | "unordered_set": "cpp",
82 | "__functional_03": "cpp",
83 | "strstream": "cpp",
84 | "typeindex": "cpp",
85 | "variant": "cpp",
86 | "cfenv": "cpp",
87 | "codecvt": "cpp",
88 | "stack": "cpp",
89 | "filesystem": "cpp",
90 | "span": "cpp"
91 | },
92 | "cSpell.words": [
93 | "Reis",
94 | "Serie",
95 | "Wunused",
96 | "biconf",
97 | "cppdbg",
98 | "dvec",
99 | "lldb",
100 | "ptree",
101 | "unshuffled",
102 | "yanetal"
103 | ],
104 | "gitlens.currentLine.enabled": false,
105 | "gitlens.hovers.currentLine.over": "line",
106 | "gitlens.codeLens.enabled": false
107 | }
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "tasks": [
3 | {
4 | "type": "shell",
5 | "label": "Unit test",
6 | "command": "make",
7 | "args": [
8 | "test"
9 | ],
10 | "group": {
11 | "kind": "build",
12 | "isDefault": true
13 | }
14 | }
15 | ],
16 | "version": "2.0.0"
17 | }
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | MIT License
2 |
3 | Copyright (c) 2020 Bruno Rijsman
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/Makefile:
--------------------------------------------------------------------------------
1 | INCLUDE_DIRS = -Iinclude
2 |
3 | UNAME_S := $(shell uname -s)
4 |
5 | CXX := clang++
6 | CXX_FLAGS := -Wall -Wextra -Weffc++ -Werror -gdwarf-4 -std=c++14 -pthread $(INCLUDE_DIRS)
7 | CXX_FLAGS_PROD := -O2
8 | CXX_FLAGS_COV := -fprofile-instr-generate -fcoverage-mapping
9 | CXX_FLAGS_DEBUG := -O0 -DENABLE_DEBUG
10 |
11 | LD_FLAGS :=
12 |
13 |
14 | ifeq ($(UNAME_S),Darwin)
15 | CASCADE_PYTHON_DIR=$(HOME)/git-personal/cascade-python
16 | LLVM_PROFDATA := /Library/Developer/CommandLineTools/usr/bin/llvm-profdata
17 | LLVM_COV := /Library/Developer/CommandLineTools/usr/bin/llvm-cov
18 | OPEN := open
19 | else
20 | CASCADE_PYTHON_DIR=$(HOME)/cascade-python
21 | LLVM_PROFDATA := llvm-profdata
22 | LLVM_COV := llvm-cov
23 | OPEN := true
24 | endif
25 |
26 | CASCADE_SRCS := $(shell find cascade -name "*.cpp")
27 | CASCADE_OBJECTS := $(patsubst cascade/%.cpp, obj/%.o, $(CASCADE_SRCS))
28 | CASCADE_OBJECTS_COV := $(patsubst cascade/%.cpp, obj-cov/%.o, $(CASCADE_SRCS))
29 | CASCADE_OBJECTS_DEBUG := $(patsubst cascade/%.cpp, obj-debug/%.o, $(CASCADE_SRCS))
30 | CASCADE_DEPS := $(CASCADE_SRCS:.cpp=.d)
31 |
32 | TEST_SRCS := $(shell find tests -name "*.cpp")
33 | TEST_OBJECTS := $(patsubst tests/%.cpp, obj/%.o, $(TEST_SRCS))
34 | TEST_OBJECTS_COV := $(patsubst tests/%.cpp, obj-cov/%.o, $(TEST_SRCS))
35 | TEST_OBJECTS_DEBUG := $(patsubst tests/%.cpp, obj-debug/%.o, $(TEST_SRCS))
36 | TEST_DEPS := $(TEST_SRCS:.cpp=.d)
37 |
38 | RUNEXP_SRCS := $(shell find study -name "*.cpp")
39 | RUNEXP_OBJECTS := $(patsubst study/%.cpp, obj/%.o, $(RUNEXP_SRCS))
40 | RUNEXP_OBJECTS_COV := $(patsubst study/%.cpp, obj-cov/%.o, $(RUNEXP_SRCS))
41 | RUNEXP_OBJECTS_DEBUG := $(patsubst study/%.cpp, obj-debug/%.o, $(RUNEXP_SRCS))
42 | RUNEXP_DEPS := $(RUNEXP_SRCS:.cpp=.d)
43 |
44 | NODEPS := clean default ubuntu-get-dependencies
45 |
46 | ifeq (0, $(words $(findstring $(MAKECMDGOALS), $(NODEPS))))
47 | -include $(CASCADE_DEPS)
48 | -include $(RUNEXP_DEPS)
49 | -include $(TEST_DEPS)
50 | endif
51 |
52 | default:
53 | @echo Please specify a make target
54 |
55 | bin/test: $(TEST_OBJECTS) $(CASCADE_OBJECTS)
56 | mkdir -p bin && \
57 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_PROD) -o bin/test $(TEST_OBJECTS) $(CASCADE_OBJECTS) \
58 | -lgtest -lpthread $(LD_FLAGS)
59 |
60 | test: bin/test
61 | bin/test
62 |
63 | bin/test_coverage: $(TEST_OBJECTS_COV) $(CASCADE_OBJECTS_COV) bin/test_coverage
64 | mkdir -p bin && \
65 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_PROD) $(CXX_FLAGS_COV) -o bin/test_coverage \
66 | $(TEST_OBJECTS_COV) $(CASCADE_OBJECTS_COV) -lgtest -lpthread $(LD_FLAGS)
67 |
68 | test-coverage: bin/test_coverage
69 | mkdir -p coverage
70 | LLVM_PROFILE_FILE="coverage/coverage-test.profraw" bin/test_coverage
71 | $(LLVM_PROFDATA) merge -sparse coverage/coverage-test.profraw \
72 | -o coverage/coverage-test.profdata
73 | $(LLVM_COV) show bin/test_coverage -instr-profile=coverage/coverage-test.profdata \
74 | -format=text > coverage/coverage-test.txt
75 | $(LLVM_COV) show bin/test_coverage -instr-profile=coverage/coverage-test.profdata \
76 | -format=html > coverage/coverage-test.html
77 | $(OPEN) coverage/coverage-test.html
78 |
79 | # This will report false positives on macOS
80 | test-valgrind: bin/test
81 | rm -f valgrind.log
82 | valgrind -v --tool=memcheck --leak-check=full --show-leak-kinds=all --error-exitcode=1 \
83 | --log-file=valgrind.log bin/test || \
84 | ( echo "Valgrind failed for bin/test -- see valgrind.log for details" ; \
85 | cat valgrind.log \
86 | false )
87 |
88 | bin/run_experiments: $(RUNEXP_OBJECTS) $(CASCADE_OBJECTS)
89 | mkdir -p bin
90 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_PROD) -o bin/run_experiments $(RUNEXP_OBJECTS) \
91 | $(CASCADE_OBJECTS) -lboost_program_options -lboost_filesystem -lboost_system $(LD_FLAGS)
92 |
93 | bin/run_experiments_debug: $(RUNEXP_OBJECTS_DEBUG) $(CASCADE_OBJECTS_DEBUG)
94 | mkdir -p bin
95 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_DEBUG) -o bin/run_experiments_debug \
96 | $(RUNEXP_OBJECTS_DEBUG) $(CASCADE_OBJECTS_DEBUG) -lboost_program_options \
97 | -lboost_filesystem -lboost_system $(LD_FLAGS)
98 |
99 | debug: bin/run_experiments_debug
100 | mkdir -p study/data/debug
101 | rm -f study/data/debug/data__*
102 | bin/run_experiments_debug study/experiments_debug.json --output-dir study/data/debug
103 |
104 | data: data-papers data-performance data-zero-handling
105 |
106 | data-papers: bin/run_experiments
107 | mkdir -p study/data/papers
108 | rm -f study/data/papers/data__*
109 | bin/run_experiments study/experiments_papers.json --output-dir study/data/papers
110 |
111 | data-papers-subset: bin/run_experiments
112 | mkdir -p study/data/papers
113 | rm -f study/data/papers/data__*
114 | bin/run_experiments study/experiments_papers.json --output-dir study/data/papers --max-runs 3
115 |
116 | data-performance: bin/run_experiments
117 | mkdir -p study/data/performance
118 | rm -f study/data/performance/data__*
119 | bin/run_experiments study/experiments_performance.json --output-dir study/data/performance
120 |
121 | data-zero-handling: bin/run_experiments
122 | mkdir -p study/data/zero_handling
123 | rm -f study/data/zero_handling/data__*
124 | bin/run_experiments study/experiments_zero_handling.json --output-dir study/data/zero_handling
125 |
126 | graphs: graphs-papers graphs-performance graphs-zero-handling
127 |
128 | graphs-papers:
129 | mkdir -p study/graphs/papers
130 | rm -f study/graphs/papers/*.png
131 | source $(CASCADE_PYTHON_DIR)/venv/bin/activate && \
132 | python $(CASCADE_PYTHON_DIR)/study/make_graphs.py study/graphs_demystifying.json \
133 | --data-dir study/data/papers
134 | source $(CASCADE_PYTHON_DIR)/venv/bin/activate && \
135 | python $(CASCADE_PYTHON_DIR)/study/make_graphs.py study/graphs_andre_reis_thesis.json \
136 | --data-dir study/data/papers
137 |
138 | graphs-performance:
139 | mkdir -p study/graphs/performance
140 | rm -f study/graphs/performance/*.png
141 | source $(CASCADE_PYTHON_DIR)/env/bin/activate && \
142 | python $(CASCADE_PYTHON_DIR)/study/make_graphs.py study/graphs_performance.json \
143 | --data-dir study/data/performance
144 |
145 | graphs-zero-handling:
146 | mkdir -p study/graphs/zero_handling
147 | rm -f study/graphs/zero_handling/*.png
148 | source $(CASCADE_PYTHON_DIR)/env/bin/activate && \
149 | python $(CASCADE_PYTHON_DIR)/study/make_graphs.py study/graphs_zero_handling.json \
150 | --data-dir study/data/zero_handling
151 |
152 | ubuntu-get-dependencies:
153 | # Gtest
154 | sudo apt-get update -y
155 | sudo apt-get install -y libgtest-dev
156 | sudo apt-get install -y cmake
157 | sudo apt-get install -y clang
158 | sudo apt-get install -y llvm
159 | sudo apt-get install -y libboost-all-dev
160 | sudo apt-get install -y valgrind
161 | cd /usr/src/gtest && \
162 | sudo cmake CMakeLists.txt && \
163 | sudo make && \
164 | sudo mkdir -p /usr/local/lib/googletest && \
165 | sudo ln -s -f /usr/lib/libgtest.a /usr/local/lib/googletest/libgtest.a && \
166 | sudo ln -s -f /usr/lib/libgtest_main.a /usr/local/lib/googletest/libgtest_main.a
167 |
168 | clean:
169 | rm -rf obj
170 | rm -rf obj-cov
171 | rm -rf obj-debug
172 | rm -rf bin
173 | rm -rf profile
174 | rm -rf coverage
175 | rm -f cascade/*.d
176 | rm -f study/*.d
177 | rm -f tests/*.d
178 | rm -rf *.dSYM
179 |
180 | cascade/%.d: cascade/%.cpp
181 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_PROD) -MM -MT '$(patsubst cascade/%.cpp,obj/%.o,$<)' $< -MF $@
182 |
183 | study/%.d: study/%.cpp
184 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_PROD) -MM -MT '$(patsubst study/%.cpp,obj/%.o,$<)' $< -MF $@
185 |
186 | tests/%.d: tests/%.cpp
187 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_PROD) -MM -MT '$(patsubst tests/%.cpp,obj/%.o,$<)' $< -MF $@
188 |
189 | obj/%.o: cascade/%.cpp cascade/%.d
190 | mkdir -p obj
191 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_PROD) -c $< -o $@
192 |
193 | obj/%.o: study/%.cpp study/%.d
194 | mkdir -p obj
195 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_PROD) -c $< -o $@
196 |
197 | obj/%.o: tests/%.cpp tests/%.d
198 | mkdir -p obj
199 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_PROD) -c $< -o $@
200 |
201 | obj-cov/%.o: cascade/%.cpp cascade/%.d
202 | mkdir -p obj-cov
203 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_PROD) $(CXX_FLAGS_COV) -c $< -o $@
204 |
205 | obj-cov/%.o: study/%.cpp study/%.d
206 | mkdir -p obj-cov
207 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_PROD) $(CXX_FLAGS_COV) -c $< -o $@
208 |
209 | obj-cov/%.o: tests/%.cpp tests/%.d
210 | mkdir -p obj-cov
211 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_PROD) $(CXX_FLAGS_COV) -c $< -o $@
212 |
213 | obj-debug/%.o: cascade/%.cpp cascade/%.d
214 | mkdir -p obj-debug
215 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_DEBUG) -c $< -o $@
216 |
217 | obj-debug/%.o: study/%.cpp study/%.d
218 | mkdir -p obj-debug
219 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_DEBUG) -c $< -o $@
220 |
221 | obj-debug/%.o: tests/%.cpp tests/%.d
222 | mkdir -p obj-debug
223 | $(CXX) $(CXX_FLAGS) $(CXX_FLAGS_DEBUG) -c $< -o $@
224 |
225 | .PHONY: clean get-dependencies
226 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | [](https://travis-ci.org/brunorijsman/cascade-cpp) [](https://codecov.io/gh/brunorijsman/cascade-cpp)
2 |
3 | # What is Cascade-CPP?
4 |
5 | [This repository](https://github.com/brunorijsman/cascade-cpp) contains a C++ implementation of
6 | Cascade information reconciliation protocol for Quantum Key Distribution (QKD).
7 |
8 | [This tutorial](https://cascade-python.readthedocs.io/en/latest/protocol.html) provides a detailed
9 | description of the Cascade information reconciliation protocol and its relation to Quantum Key
10 | Distribution.
11 |
12 |
13 | # Comparison between Cascade-Python and Cascade-CPP
14 |
15 | The C++ code in this repository is modeled after my earlier Python implementation in GitHub
16 | repository [Cascade-Python](https://github.com/brunorijsman/cascade-python), which
17 | is documented on [ReadTheDocs](https://cascade-python.readthedocs.io/en/latest/).
18 |
19 | The C++ code is orders of magnitude faster than the Python code. This is because the C++ code was
20 | carefully optimized based on the insights from profiling the code. In particular, the decision to
21 | cache Shuffle objects made a huge impact on the performance.
22 |
23 | The "make data-papers" target in the Python code does 1,000 Cascade iterations per data point and
24 | takes more than 5 days of continuous running on an AWS m5.2xlarge instance (120 hours x US$ 0.40
25 | per hour = US$ 48 in compute cost).
26 | By contrast, the "make data-papers" target the C++ code does 10,000 Cascade iterations per data
27 | point (10x better accuracy) only takes ten hours to complete (US$ 4).
28 |
29 | The C++ was more carefully debugged than the Python code. The C++ code has a "make debug" target
30 | that produces color-coded representations of the blocks at each step in the algorithm (bit errors
31 | are shown in red). This makes it much easier to follow what is going on in the algorithm. Beyond
32 | debugging, this is also a good tool for learning the Cascade algorithm.
33 |
34 | As a result of the better debugging in the C++ code, the data produced by the C++ is more consistent
35 | with the results published in
36 | [Demystifying the Information Reconciliation Protocol Cascade](https://arxiv.org/abs/1407.3257)
37 | and [Quantum Key Distribution Post Processing - A study on the Information Reconciliation Cascade Protocol](https://repositorio-aberto.up.pt/bitstream/10216/121965/2/347567.pdf).
38 |
39 | # How to install, compile and run the Cascade-CPP code
40 |
41 | To install on Ubuntu 22.04:
42 |
43 | git clone https://github.com/brunorijsman/cascade-cpp.git
44 | cd cascade-cpp
45 | sudo apt install -y make
46 | make ubuntu-get-dependencies
47 |
48 | To build and run unit tests:
49 |
50 | make test
51 |
52 | To build and run unit tests, and produce code coverage report in coverage/coverage-test.html (on a
53 | Mac this also opens the coverage report in the browser):
54 |
55 | make test-coverage
56 |
57 | To produce the data for all experiments:
58 |
59 | make data
60 |
61 | To produce the data for specific set of experiments:
62 |
63 | # Choose one of these
64 | make data-papers
65 | make data-papers-subset
66 | make data-performance
67 | make data-zero-handling
68 |
69 | To produce graphs, you need to have [Cascade-Python](https://github.com/brunorijsman/cascade-python)
70 | installed in the $HOME/cascade-python directory.
71 |
72 | The produce the graphs for specific set of experiments (this assumes that that the data has already
73 | been produced):
74 |
75 | make graphs
76 |
77 | To produce the graphs for all experiments:
78 |
79 | # Choose one of these
80 | make graphs-papers
81 | make graphs-performance
82 | make graphs-zero-handling
83 |
84 | To run a small reconciliation with full debug prints:
85 |
86 | make debug
87 |
88 | # Running experiments
89 |
90 | Under the hood, when you issue `make data-papers` the Makefile executes the following command:
91 |
92 | bin/run_experiments study/experiments_papers.json --output-dir study/data/papers
93 |
94 | The executable `run_experiments` does the following:
95 |
96 | 1. It reads an experiments JSON file which describes which experiments to run.
97 |
98 | 2. It runs the requested experiments in a multi-threaded fashion using all available CPU cores.
99 |
100 | 3. It writes the results into one or more data JSON files that can later be visualized into
101 | graphs.
102 |
103 | The executable `run_experiments` uses the following syntax:
104 |
105 | $ run_experiments --help
106 | Usage: run_experiments [options] experiments-file
107 |
108 | Options:
109 | --help Display help
110 | -d [ --disable-multi-processing ] Disable multi-processing
111 | -m [ --max-runs ] arg Maximum number of reconciliation runs per
112 | data point
113 | -s [ --seed ] arg Random seed
114 | -o [ --output-directory ] arg Output directory where to store data__*
115 | files
116 |
117 | Here is an example of an experiments JSON file (this is `experiments_papers.json`):
118 |
119 | [
120 | {
121 | "independent_variable": "error_rate",
122 | "algorithm": ["original", "biconf", "yanetal", "option3", "option4", "option7", "option8"],
123 | "error_rate": [
124 | {"start": 0.0000, "end": 0.0050, "step_size": 0.00005},
125 | {"start": 0.0050, "end": 0.1100, "step_size": 0.00050}
126 | ],
127 | "key_size": [1000, 2000, 10000],
128 | "runs": 10000
129 | },
130 | {
131 | "independent_variable": "key_size",
132 | "algorithm": ["original", "biconf", "yanetal", "option3", "option4", "option7", "option8"],
133 | "error_rate": 0.05,
134 | "key_size": {
135 | "start": 1e3,
136 | "end": 1e5,
137 | "step_factor": 1.05
138 | },
139 | "runs": 10000
140 | },
141 | {
142 | "independent_variable": "key_size",
143 | "algorithm": "original",
144 | "error_rate": [0.01, 0.02],
145 | "key_size": {
146 | "start": 1e3,
147 | "end": 1e5,
148 | "step_factor": 1.05
149 | },
150 | "runs": 10000
151 | }
152 | ]
153 |
154 | The experiments JSON file consists of a list of records, each describing a single experiment. In
155 | this example there are three experiments.
156 |
157 | Each experiment has the following arguments.
158 |
159 | * `independent_variable`: This must be `error_rate` or `key_size`.
160 |
161 | * If it is set to `error_rate`, then one separate data file is produced for each requested
162 | `key_size` (for example `data__algorithm=option3;key_size=10000;error_rate=vary`) and the
163 | `error_rate` is varied within each data file.
164 |
165 | * If it is set to `key_size`, then one separate data file is produced for each requested
166 | `error_rate` (for example `data__algorithm=option3;key_size=vary;error_rate=0.05`) and the
167 | `key_size` is varied within each data file.
168 |
169 | * `algorithm`: Either a single algorithm or a list of algorithms. Each algorithm is plotted as a line
170 | in the graph. The available algorithms are `original`, `biconf`, `biconf-cascade`,
171 | `biconf-no-complement`, `yanetal`, `option3`, `option4`, `option7`, and `option8`. See source
172 | file `algorithm.cpp` for the detailed parameters for each algorithm.
173 |
174 | * `error_rate`: The error rates to be used in the experiment in the form of a numerical list (see
175 | below).
176 |
177 | * `key_size`: The key sizes to be used in the experiment in the form of a numerical list (see
178 | below).
179 |
180 | * `run`: The number of reconciliation runs per data point in the results.
181 |
182 | A numerical list is one of the following:
183 |
184 | * A list of numbers, for example `[1, 2, 3, 4]`
185 |
186 | * A linear range of numbers, for example `{"start": 100.0, "end": 200.0, "step": 5.0}`
187 |
188 | * A log range of numbers, for example `{"start": 10.0, "end": 10000.0, "step_factor": 3.0}`
189 |
190 | * A list of any of the above.
191 |
192 | The executable `run_experiments` produces a set of data JSON files in the requested output
193 | directory, for example:
194 |
195 | $ ls -1 study/data/papers/
196 | data__algorithm=biconf;key_size=10000;error_rate=vary
197 | data__algorithm=biconf;key_size=1000;error_rate=vary
198 | data__algorithm=biconf;key_size=2000;error_rate=vary
199 | data__algorithm=biconf;key_size=vary;error_rate=0.05
200 | ...
201 | data__algorithm=yanetal;key_size=2000;error_rate=vary
202 | data__algorithm=yanetal;key_size=vary;error_rate=0.05
203 |
204 | Each data JSON file consists of a list of JSON records, one for each data point. Here is an
205 | example data point record:
206 |
207 | {
208 | "actual_bit_error_rate": {"average": 0.000050, "deviation": 0.000050},
209 | "actual_bit_errors": {"average": 0.502200, "deviation": 0.502200},
210 | "algorithm_name": "biconf",
211 | "ask_parity_bits": {"average": 2828.808000, "deviation": 2828.808000},
212 | "ask_parity_blocks": {"average": 35.360100, "deviation": 35.360100},
213 | "ask_parity_messages": {"average": 37.360100, "deviation": 37.360100},
214 | "biconf_iterations": {"average": 10.000000, "deviation": 10.000000},
215 | "elapsed_process_time": {"average": 0.001794, "deviation": 0.001794},
216 | "elapsed_real_time": {"average": 0.001795, "deviation": 0.001795},
217 | "execution_time": "2020-04-08 20:20:49 UTC",
218 | "infer_parity_blocks": {"average": 6.919900, "deviation": 6.919900},
219 | "key_size": 10000,
220 | "normal_iterations": {"average": 2.000000, "deviation": 2.000000},
221 | "reconciliation_bits_per_key_bit": {"average": 510.625974, "deviation": 510.625974},
222 | "reconciliations": 10000,
223 | "remaining_bit_error_rate": {"average": 0.000000, "deviation": 0.000000},
224 | "remaining_bit_errors": {"average": 0.000000, "deviation": 0.000000},
225 | "remaining_frame_error_rate": {"average": 0.000000, "deviation": 0.000000},
226 | "reply_parity_bits": {"average": 35.360100, "deviation": 35.360100},
227 | "requested_bit_error_rate": 0.000050,
228 | "efficiency": {"average": 4.495774, "deviation": 4.495774}
229 | }
230 |
231 |
232 | # Producing graphs
233 |
234 | We rely on the Python scripts in Cascade-Python to produce graphs from the results stored in the
235 | data file produced by the executable `run_experiments`.
236 |
237 | Under the hood, when you issue `make graphs-papers` the Makefile activates a Python3 virtual
238 | environment and executes the following Python script:
239 |
240 | python $(CASCADE_PYTHON_DIR)/study/make_graphs.py study/graphs_demystifying.json \
241 | --data-dir study/data/papers
242 |
243 | The graph JSON file (in this example `graphs_demystifying.json`) describes which variables
244 | should be plotted in the graph and other attributes that influence the appearance of the graph.
245 |
246 | This is an example of a graph file (namely the first graph in `graphs_demystifying.json`):
247 |
248 | [
249 | {
250 | "graph_name": "demystifying_figure_1",
251 | "title": "Figure 1 from \"Demystifying the Information Reconciliation Protocol Cascade\"",
252 | "x_axis": {
253 | "title": "Quantum Bit Error Rate (QBER)",
254 | "variable": "requested_bit_error_rate"
255 | },
256 | "y_axis": {
257 | "title": "Reconciliation efficiency",
258 | "variable": "efficiency",
259 | "range": [1.0, 1.3]
260 | },
261 | "series": [
262 | {
263 | "data_file": "data__algorithm=original;key_size=10000;error_rate=vary",
264 | "legend": "Cascade orig.",
265 | "line_color": "black",
266 | "deviation_color": "lightgray"
267 | },
268 | {
269 | "data_file": "data__algorithm=biconf;key_size=10000;error_rate=vary",
270 | "legend": "Cascade mod. (1)",
271 | "line_color": "blue",
272 | "deviation_color": "lightblue"
273 | }
274 | ]
275 | },
276 | ...
277 | ]
278 |
279 | This produces the following graph:
280 |
281 | 
282 |
283 | # Comparing the data produced by Cascade-CPP with published literature.
284 |
285 | In this section we compare the data produced
286 |
287 | We used Github version
288 | [c4d2194bcae4580f329597677ba2e2538bb53c81](https://github.com/brunorijsman/cascade-cpp/commit/c4d2194bcae4580f329597677ba2e2538bb53c81) (8 April 2020) of Cascade-CPP
289 | to produce the data in these graphs.
290 |
291 | ## Comparison with Demystifying the Information Reconciliation Protocol Cascade.
292 |
293 | In this section we compare the data produced by Cascade-CPP with the results reported in:
294 |
295 | [Demystifying the Information Reconciliation Protocol Cascade](https://arxiv.org/abs/1407.3257).
296 | _Jesus Martinez-Mateo, Christoph Pacher, Momtchil Peev, Alex Ciurana, and Vicente Martin._
297 | arXiv:1407.3257 \[quant-ph\], Jul 2014.
298 |
299 | ### Figure 1.
300 |
301 | Results reported in paper:
302 |
303 | 
304 |
305 | Results produced by Cascade-CPP:
306 |
307 | 
308 |
309 | ### Figure 2.
310 |
311 | Results reported in paper:
312 |
313 | 
314 |
315 | Results produced by Cascade-CPP:
316 |
317 | 
318 |
319 | ### Figure 3.
320 |
321 | Results reported in paper:
322 |
323 | 
324 |
325 | Results produced by Cascade-CPP:
326 |
327 | 
328 |
329 | ### Figure 4.
330 |
331 | Results reported in paper:
332 |
333 | 
334 |
335 | Results produced by Cascade-CPP:
336 |
337 | 
338 |
339 | ### Figure 5.
340 |
341 | Results reported in paper:
342 |
343 | 
344 |
345 | Results produced by Cascade-CPP:
346 |
347 | 
348 |
349 | ### Figure 6.
350 |
351 | Results reported in paper:
352 |
353 | 
354 |
355 | Results not produced by Cascade-CPP.
356 |
357 | ### Figure 7.
358 |
359 | Results reported in paper:
360 |
361 | 
362 |
363 | Results not produced by Cascade-CPP.
364 |
365 | ### Figure 8.
366 |
367 | Results reported in paper:
368 |
369 | 
370 |
371 | Results produced by Cascade-CPP:
372 |
373 | 
374 |
375 | ### Figure 9.
376 |
377 | Results reported in paper:
378 |
379 | 
380 |
381 | Results produced by Cascade-CPP:
382 |
383 | 
384 |
385 | ### Figure 10.
386 |
387 | Results reported in paper:
388 |
389 | 
390 |
391 | Results produced by Cascade-CPP:
392 |
393 | 
394 |
395 | ### Figure 11.
396 |
397 | Results reported in paper:
398 |
399 | 
400 |
401 | Results produced by Cascade-CPP:
402 |
403 | 
404 |
405 | ### Figure 12.
406 |
407 | Results reported in paper:
408 |
409 | 
410 |
411 | Results not produced by Cascade-CPP.
412 |
413 | ### Figure 13.
414 |
415 | Results reported in paper:
416 |
417 | 
418 |
419 | Results produced by Cascade-CPP:
420 |
421 | 
422 |
423 | ## Comparison with Quantum Key Distribution Post Processing.
424 |
425 | In this section we compare the data produced by Cascade-CPP with the results reported in:
426 |
427 | [Quantum Key Distribution Post Processing - A study on the Information Reconciliation Cascade Protocol.](https://repositorio-aberto.up.pt/bitstream/10216/121965/2/347567.pdf.
428 | _André Reis._
429 | Master’s Thesis, Faculdade de Engenharia da Universidade do Porto, Jul 2019.
430 |
431 | ### Figure 5.1.
432 |
433 | Results reported in thesis:
434 |
435 | 
436 |
437 | Results produced by Cascade-CPP:
438 |
439 | 
440 |
441 | ### Figure 5.2.
442 |
443 | Results reported in thesis:
444 |
445 | 
446 |
447 | Results produced by Cascade-CPP:
448 |
449 | 
450 |
451 | ### Figure 5.3.
452 |
453 | Results reported in thesis:
454 |
455 | 
456 |
457 | Results produced by Cascade-CPP:
458 |
459 | 
460 |
461 | ### Figure 5.4.
462 |
463 | Results reported in thesis:
464 |
465 | 
466 |
467 | Results not produced by Cascade-CPP.
468 |
469 | ### Figure 5.5.
470 |
471 | Results reported in thesis:
472 |
473 | 
474 |
475 | Results produced by Cascade-CPP:
476 |
477 | 
478 |
479 | 
480 |
481 | ### Figure 5.6.
482 |
483 | Results reported in thesis:
484 |
485 | 
486 |
487 | Results not yet produced by Cascade-CPP.
488 |
489 | ### Figure 5.7.
490 |
491 | Results reported in thesis:
492 |
493 | 
494 |
495 | Results not yet produced by Cascade-CPP.
496 |
497 | ### Figure 5.8.
498 |
499 | Results reported in thesis:
500 |
501 | 
502 |
503 | Results not yet produced by Cascade-CPP.
504 |
505 | ### Figure 5.9.
506 |
507 | Results reported in thesis:
508 |
509 | 
510 |
511 | Results not yet produced by Cascade-CPP.
512 |
513 | ### Figure 5.10.
514 |
515 | Results reported in thesis:
516 |
517 | 
518 |
519 | Results not yet produced by Cascade-CPP.
520 |
--------------------------------------------------------------------------------
/cascade/algorithm.cpp:
--------------------------------------------------------------------------------
1 | #include "algorithm.h"
2 | #include