├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── README.md ├── experiments ├── dkg-bw │ ├── bandwidth-1M.csv │ ├── benchmark.sh │ ├── export-latex.py │ └── redraw.sh ├── dkg │ ├── .gitignore │ ├── README.md │ ├── amt-dkg-2-1048576-dvorak.csv │ ├── export-latex.py │ ├── kate-dkg-2-32768-dvorak.csv │ ├── redraw.sh │ └── run-experiments.sh ├── redraw-all.sh ├── redraw-vss-and-dkg-deal.sh ├── threshsig │ ├── efficient-threshsig-2-1048576-dvorak.csv │ ├── export-latex.py │ ├── naive-threshsig-2-1048576-dvorak.csv │ ├── redraw-blogpost.sh │ ├── redraw.sh │ └── run-experiments.sh └── vss │ ├── .gitignore │ ├── amt.csv │ ├── export-latex.py │ ├── feld.csv │ ├── kate.csv │ ├── redraw.sh │ └── run-experiments.sh ├── libpolycrypto ├── CMakeLists.txt ├── app │ ├── BandwidthCalc.cpp │ ├── CMakeLists.txt │ ├── ParamsGenPowers.cpp │ ├── ParamsGenTrapdoors.cpp │ ├── ParamsValidate.cpp │ └── PolylogDkg.cpp ├── bench │ ├── BenchAMT.cpp │ ├── BenchApproxVerifyKateProofs.cpp │ ├── BenchBatchVerification.cpp │ ├── BenchConvertAndMultiexp.cpp │ ├── BenchDKG.cpp │ ├── BenchExp.cpp │ ├── BenchFFT.cpp │ ├── BenchMultiexp.cpp │ ├── BenchNizkPok.cpp │ ├── BenchNtlConversion.cpp │ ├── BenchPairing.cpp │ ├── BenchPolyDivideXnc.cpp │ ├── BenchPolynomialOps.cpp │ ├── BenchRootsOfUnityEval.cpp │ ├── BenchSecretReconstruction.cpp │ ├── BenchThresholdSig.cpp │ ├── BenchVSS.cpp │ ├── CMakeLists.txt │ └── Utils.h ├── examples │ └── CMakeLists.txt ├── include │ └── polycrypto │ │ ├── AbstractKatePlayer.h │ │ ├── AbstractPlayer.h │ │ ├── AccumulatorTree.h │ │ ├── AmtDkg.h │ │ ├── BinaryTree.h │ │ ├── Configuration.h │ │ ├── Dkg.h │ │ ├── DkgCommon.h │ │ ├── FFThresh.h │ │ ├── FeldmanDkg.h │ │ ├── KateDkg.h │ │ ├── KatePublicParameters.h │ │ ├── Lagrange.h │ │ ├── NizkPok.h │ │ ├── NtlLib.h │ │ ├── PolyCrypto.h │ │ ├── PolyOps.h │ │ ├── RootsOfUnityEval.h │ │ ├── Utils.h │ │ └── internal │ │ └── PicoSha2.h ├── src │ ├── AmtDkg.cpp │ ├── CMakeLists.txt │ ├── FFThresh.cpp │ ├── KateDkg.cpp │ ├── KatePublicParameters.cpp │ ├── Lagrange.cpp │ ├── NizkPok.cpp │ ├── PolyCrypto.cpp │ ├── PolyOps.cpp │ └── Utils.cpp └── test │ ├── CMakeLists.txt │ ├── TestAMT.cpp │ ├── TestDKGandVSS.cpp │ ├── TestKatePublicParams.cpp │ ├── TestLagrange.cpp │ ├── TestLibff.cpp │ ├── TestNizkPok.cpp │ ├── TestParallelPairing.cpp │ ├── TestPolyDivideXnc.cpp │ ├── TestPolyOps.cpp │ ├── TestRootsOfUnity.cpp │ └── TestRootsOfUnityEval.cpp ├── public-params ├── 65536 │ ├── 65536 │ ├── 65536-0 │ ├── 65536-0.log │ ├── 65536-1 │ ├── 65536-1.log │ ├── 65536-10 │ ├── 65536-10.log │ ├── 65536-11 │ ├── 65536-11.log │ ├── 65536-2 │ ├── 65536-2.log │ ├── 65536-3 │ ├── 65536-3.log │ ├── 65536-4 │ ├── 65536-4.log │ ├── 65536-5 │ ├── 65536-5.log │ ├── 65536-6 │ ├── 65536-6.log │ ├── 65536-7 │ ├── 65536-7.log │ ├── 65536-8 │ ├── 65536-8.log │ ├── 65536-9 │ └── 65536-9.log └── .gitignore └── scripts └── linux ├── cmake.sh ├── cols.sh ├── dkg-cols.sh ├── generate-qsdh-params.sh ├── humanize-csv.py ├── install-deps.sh ├── install-libs.sh ├── make.sh ├── plot-bandwidth.py ├── plot-deal-times.py ├── plot-dkg-times.py ├── plot-threshsig.py ├── plot-vss-times.py ├── recompute-polylog-dkg.sh ├── set-env.sh ├── shlibs ├── check-env.sh └── os.sh ├── submodule-update.sh ├── test.sh └── vss-cols.sh /.gitignore: -------------------------------------------------------------------------------- 1 | *.o 2 | *.a 3 | *.so 4 | *.d 5 | depinst/ 6 | depsrc/ 7 | /build 8 | README.html 9 | CHANGELOG.html 10 | doxygen/ 11 | /Testing 12 | core 13 | *.png 14 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "depends/libff"] 2 | path = depends/libff 3 | url = git://github.com/scipr-lab/libff.git 4 | [submodule "depends/libfqfft"] 5 | path = depends/libfqfft 6 | url = https://github.com/scipr-lab/libfqfft.git 7 | [submodule "depends/xbyak"] 8 | path = depends/xbyak 9 | url = git://github.com/herumi/xbyak.git 10 | [submodule "depends/ate-pairing"] 11 | path = depends/ate-pairing 12 | url = git://github.com/herumi/ate-pairing.git 13 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required (VERSION 3.2) 2 | # project( VERSION LANGUAGES CXX) 3 | project(libpolycrypto VERSION 0.1.0.0 LANGUAGES CXX) 4 | 5 | # 6 | # Configuration options 7 | # 8 | set( 9 | CURVE 10 | "BN128" 11 | CACHE 12 | STRING 13 | "Default curve: one of ALT_BN128, BN128, EDWARDS, MNT4, MNT6" 14 | ) 15 | 16 | option( 17 | BINARY_OUTPUT 18 | "In serialization of elliptic curve points, output raw binary data (instead of decimal), which is smaller and faster." 19 | OFF 20 | ) 21 | 22 | add_definitions( 23 | -DCURVE_${CURVE} 24 | ) 25 | 26 | option( 27 | USE_MULTITHREADING 28 | "Enable parallelized execution of DKG protocols using OpenMP" 29 | OFF 30 | ) 31 | 32 | if(${CURVE} STREQUAL "BN128") 33 | add_definitions( 34 | -DBN_SUPPORT_SNARK=1 35 | ) 36 | endif() 37 | 38 | # 39 | # Configure CCache if available 40 | # 41 | find_program(CCACHE_FOUND ccache) 42 | if(CCACHE_FOUND) 43 | set_property(GLOBAL PROPERTY RULE_LAUNCH_COMPILE ccache) 44 | set_property(GLOBAL PROPERTY RULE_LAUNCH_LINK ccache) 45 | endif(CCACHE_FOUND) 46 | 47 | #find_package(Threads REQUIRED) 48 | #find_package(Boost 1.65 COMPONENTS program_options REQUIRED) 49 | #include_directories(${Boost_INCLUDE_DIR}) 50 | 51 | set(polycrypto_packages 52 | xassert 53 | xutils 54 | ) 55 | 56 | # 57 | # Dependencies 58 | # 59 | # TODO: Find ate-pairing, libff, libfqfft too or issue error with pointer to install script 60 | foreach(package ${polycrypto_packages}) 61 | find_package(${package} QUIET) 62 | 63 | if(${package}_FOUND) 64 | message("${package} library is installed!") 65 | else() 66 | message("${package} library not installed locally, please download from https//github.com/alinush/lib${package}") 67 | endif() 68 | endforeach() 69 | 70 | # 71 | # C++ options 72 | # TODO: change to set_target_properties? 73 | # https://crascit.com/2015/03/28/enabling-cxx11-in-cmake/ 74 | # 75 | set(CMAKE_CXX_STANDARD 11) 76 | set(CMAKE_CXX_STANDARD_REQUIRED ON) 77 | set(CMAKE_CXX_EXTENSIONS OFF) 78 | 79 | # 80 | # Compiler flags 81 | # 82 | 83 | # When you do 'a > b in 'C/C++, if a is unsigned and b is signed and equal to -1, C/C++ 84 | # actually casts b to unsigned (probably because casting unsigned to signed would require a bigger data type) 85 | # Thus, 1 > -1 will evaluate to false because during the cast -1 will be set to to 2^32 - 1 86 | # 87 | # WARNING: For the love of god, do not remove this flag or you will regret it. Instead, 88 | # just use signed types everywhere and cast your unsigned to signed when mixing unsigned 89 | # variables with signed ones. See: http://soundsoftware.ac.uk/c-pitfall-unsigned 90 | set(CXX_FLAGS_INTEGER_CORRECTNESS 91 | "-Wconversion -Wsign-conversion -Wsign-compare") 92 | set(CXX_FLAGS_FORMAT 93 | "-Wformat-y2k -Wno-format-extra-args -Wno-format-zero-length -Wformat-nonliteral -Wformat-security -Wformat=2") 94 | set(CXX_FLAGS_OPTIMIZATIONS "-O3") 95 | 96 | string(APPEND CXX_FLAGS " ${CXX_FLAGS_OPTIMIZATIONS}") 97 | string(APPEND CXX_FLAGS " ${CXX_FLAGS_FORMAT}") 98 | string(APPEND CXX_FLAGS " ${CXX_FLAGS_INTEGER_CORRECTNESS}") 99 | # TODO: use target_compile_features instead: 100 | # https://cmake.org/cmake/help/v3.1/command/target_compile_features.html#command:target_compile_features 101 | # https://cmake.org/cmake/help/v3.1/prop_gbl/CMAKE_CXX_KNOWN_FEATURES.html#prop_gbl:CMAKE_CXX_KNOWN_FEATURES 102 | string(APPEND CXX_FLAGS " -Wall") 103 | string(APPEND CXX_FLAGS " -Werror") 104 | string(APPEND CXX_FLAGS " -Wextra") 105 | 106 | 107 | # TODO: Figure out right way to deal with -fstrict-overflow / -Wstrict-overflow related errors 108 | string(APPEND CXX_FLAGS 109 | " -fno-strict-overflow") 110 | string(APPEND CXX_FLAGS_DEBUG 111 | " -D_FORTIFY_SOURCE=2") 112 | #" -D_FORTIFY_SOURCE=2 -D_GLIBCXX_DEBUG") 113 | # TODO: add -D_GLIBCXX_DEBUG if you want bounds checking for std::vector::operator[] but it seems to cause a segfault at the end of execution 114 | 115 | if("${USE_MULTITHREADING}") 116 | add_definitions(-DUSE_MULTITHREADING) 117 | string(APPEND CMAKE_CXX_FLAGS " -fopenmp") 118 | endif() 119 | 120 | # GNU and Clang-specific flags 121 | string(APPEND CMAKE_CXX_FLAGS 122 | " ${CXX_FLAGS}") 123 | string(APPEND CMAKE_CXX_FLAGS_DEBUG 124 | " ${CXX_FLAGS_DEBUG}") 125 | # When building with 'cmake -DCMAKE_BUILD_TYPE=Trace' 126 | string(APPEND CMAKE_CXX_FLAGS_TRACE 127 | " ${CXX_FLAGS_DEBUG} -DTRACE") 128 | 129 | # using Clang 130 | if (CMAKE_CXX_COMPILER_ID MATCHES "Clang") 131 | # Clang-specific options 132 | string(APPEND CMAKE_CXX_FLAGS 133 | " -ferror-limit=3") 134 | string(APPEND CMAKE_CXX_FLAGS_DEBUG 135 | " -fstack-protector-all") 136 | 137 | # using GCC 138 | elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "GNU") 139 | # GCC-specific options 140 | string(APPEND CMAKE_CXX_FLAGS 141 | " -fmax-errors=3") 142 | string(APPEND CMAKE_CXX_FLAGS_DEBUG 143 | " -fstack-protector-all") 144 | 145 | # TODO: using Intel C++ 146 | elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Intel") 147 | 148 | # TODO: using Visual Studio C++ 149 | elseif ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "MSVC") 150 | 151 | endif() 152 | 153 | # 154 | # Testing flags 155 | # 156 | enable_testing() 157 | 158 | # Subdirectories 159 | add_subdirectory(libpolycrypto) 160 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright 2019, Robert Chen and Alin Tomescu 2 | 3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions: 4 | 5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software. 6 | 7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. 8 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # libpolycrypto 2 | 3 | ## Build on Linux 4 | 5 | Step zero is to clone this repo and `cd` to the right directory: 6 | 7 | cd 8 | 9 | First, install deps using: 10 | 11 | scripts/linux/install-libs.sh 12 | scripts/linux/install-deps.sh 13 | 14 | Then, set up the environment. This **will store the built code in ~/builds/polycrypto/**: 15 | 16 | . scripts/linux/set-env.sh release 17 | 18 | ...you can also use `debug`, `relwithdebug` or `trace` as an argument for `set-env.sh`. 19 | 20 | To build: 21 | 22 | make.sh 23 | 24 | ..tests, benchmarks and any other binaries are automatically added to `PATH` but can also be found in 25 | 26 | cd ~/builds/polycrypto/master/release/libpolycrypto/bin/ 27 | 28 | (or replace `release` with `debug` or whatever you used in `set-env.sh`) 29 | 30 | ## Useful scripts 31 | 32 | There's a bunch of useful scripts in `scripts/linux/`: 33 | 34 | - `plot-*.py` for generating plots 35 | - `cols.sh, dkg-cols.sh, vss-cols.sh` for viewing CSV data in the terminal 36 | - `generate-qsbdh-params.sh` for generating public parameters for the VSS/DKG code 37 | 38 | ## Git submodules 39 | 40 | This is just for reference purposes. 41 | No need to execute these. 42 | To fetch the submodules, just do: 43 | 44 | git submodule init 45 | git submodule update 46 | 47 | For historical purposes, (i.e., don't execute these), when I set up the submodules, I did: 48 | 49 | cd depends/ 50 | git submodule add git://github.com/herumi/ate-pairing.git 51 | git submodule add git://github.com/herumi/xbyak.git 52 | git submodule add git://github.com/scipr-lab/libff.git 53 | git submodule add https://github.com/scipr-lab/libfqfft.git 54 | 55 | To update your submodules with changes from their upstream github repos, do: 56 | 57 | git submodule foreach git pull origin master 58 | 59 | -------------------------------------------------------------------------------- /experiments/dkg-bw/bandwidth-1M.csv: -------------------------------------------------------------------------------- 1 | t,n,dkg,download_bw_bytes,download_bw_hum,upload_bw_bytes,upload_bw_hum,comm_bw_bytes,comm_bw_hum,total_bw_bytes,total_bw_hum 2 | 2,3,JF-DKG,192,192.00 bytes,128,128.00 bytes,320,320.00 bytes,960,960.00 bytes 3 | 2,3,eJF-DKG,448,448.00 bytes,288,288.00 bytes,736,736.00 bytes,2208,2.16 KiB 4 | 2,3,AMT DKG,448,448.00 bytes,288,288.00 bytes,736,736.00 bytes,2208,2.16 KiB 5 | 4,7,JF-DKG,960,960.00 bytes,320,320.00 bytes,1280,1.25 KiB,8960,8.75 KiB 6 | 4,7,eJF-DKG,1344,1.31 KiB,544,544.00 bytes,1888,1.84 KiB,13216,12.91 KiB 7 | 4,7,AMT DKG,1536,1.50 KiB,736,736.00 bytes,2272,2.22 KiB,15904,15.53 KiB 8 | 8,15,JF-DKG,4032,3.94 KiB,704,704.00 bytes,4736,4.62 KiB,71040,69.38 KiB 9 | 8,15,eJF-DKG,3136,3.06 KiB,1056,1.03 KiB,4192,4.09 KiB,62880,61.41 KiB 10 | 8,15,AMT DKG,4032,3.94 KiB,1952,1.91 KiB,5984,5.84 KiB,89760,87.66 KiB 11 | 16,31,JF-DKG,16320,15.94 KiB,1472,1.44 KiB,17792,17.38 KiB,551552,538.62 KiB 12 | 16,31,eJF-DKG,6720,6.56 KiB,2080,2.03 KiB,8800,8.59 KiB,272800,266.41 KiB 13 | 16,31,AMT DKG,9600,9.38 KiB,4960,4.84 KiB,14560,14.22 KiB,451360,440.78 KiB 14 | 32,63,JF-DKG,65472,63.94 KiB,3008,2.94 KiB,68480,66.88 KiB,4314240,4.11 MiB 15 | 32,63,eJF-DKG,13888,13.56 KiB,4128,4.03 KiB,18016,17.59 KiB,1135008,1.08 MiB 16 | 32,63,AMT DKG,21824,21.31 KiB,12064,11.78 KiB,33888,33.09 KiB,2134944,2.04 MiB 17 | 64,127,JF-DKG,262080,255.94 KiB,6080,5.94 KiB,268160,261.88 KiB,34056320,32.48 MiB 18 | 64,127,eJF-DKG,28224,27.56 KiB,8224,8.03 KiB,36448,35.59 KiB,4628896,4.41 MiB 19 | 64,127,AMT DKG,48384,47.25 KiB,28384,27.72 KiB,76768,74.97 KiB,9749536,9.30 MiB 20 | 128,255,JF-DKG,1048512,1023.94 KiB,12224,11.94 KiB,1060736,1.01 MiB,270487680,257.96 MiB 21 | 128,255,eJF-DKG,56896,55.56 KiB,16416,16.03 KiB,73312,71.59 KiB,18694560,17.83 MiB 22 | 128,255,AMT DKG,105664,103.19 KiB,65184,63.66 KiB,170848,166.84 KiB,43566240,41.55 MiB 23 | 256,511,JF-DKG,4194240,4.00 MiB,24512,23.94 KiB,4218752,4.02 MiB,2155782272,2.01 GiB 24 | 256,511,eJF-DKG,114240,111.56 KiB,32800,32.03 KiB,147040,143.59 KiB,75137440,71.66 MiB 25 | 256,511,AMT DKG,228480,223.12 KiB,147040,143.59 KiB,375520,366.72 KiB,191890720,183.00 MiB 26 | 512,1023,JF-DKG,16777152,16.00 MiB,49088,47.94 KiB,16826240,16.05 MiB,17213243520,16.03 GiB 27 | 512,1023,eJF-DKG,228928,223.56 KiB,65568,64.03 KiB,294496,287.59 KiB,301269408,287.31 MiB 28 | 512,1023,AMT DKG,490560,479.06 KiB,327200,319.53 KiB,817760,798.59 KiB,836568480,797.81 MiB 29 | 1024,2047,JF-DKG,67108800,64.00 MiB,98240,95.94 KiB,67207040,64.09 MiB,137572810880,128.12 GiB 30 | 1024,2047,eJF-DKG,458304,447.56 KiB,131104,128.03 KiB,589408,575.59 KiB,1206518176,1.12 GiB 31 | 1024,2047,AMT DKG,1047552,1023.00 KiB,720352,703.47 KiB,1767904,1.69 MiB,3618899488,3.37 GiB 32 | 2048,4095,JF-DKG,268435392,256.00 MiB,196544,191.94 KiB,268631936,256.19 MiB,1100047777920,1.00 TiB 33 | 2048,4095,eJF-DKG,917056,895.56 KiB,262176,256.03 KiB,1179232,1.12 MiB,4828955040,4.50 GiB 34 | 2048,4095,AMT DKG,2227136,2.12 MiB,1572256,1.50 MiB,3799392,3.62 MiB,15558510240,14.49 GiB 35 | 4096,8191,JF-DKG,1073741760,1024.00 MiB,393152,383.94 KiB,1074134912,1.00 GiB,8798239064192,8.00 TiB 36 | 4096,8191,eJF-DKG,1834560,1.75 MiB,524320,512.03 KiB,2358880,2.25 MiB,19321586080,17.99 GiB 37 | 4096,8191,AMT DKG,4717440,4.50 MiB,3407200,3.25 MiB,8124640,7.75 MiB,66548926240,61.98 GiB 38 | 8192,16383,JF-DKG,4294967232,4.00 GiB,786368,767.94 KiB,4295753600,4.00 GiB,70377331228800,64.01 TiB 39 | 8192,16383,eJF-DKG,3669568,3.50 MiB,1048608,1.00 MiB,4718176,4.50 MiB,77297877408,71.99 GiB 40 | 8192,16383,AMT DKG,9960256,9.50 MiB,7339296,7.00 MiB,17299552,16.50 MiB,283418560416,263.95 GiB 41 | 16384,32767,JF-DKG,17179869120,16.00 GiB,1572800,1.50 MiB,17181441920,16.00 GiB,562984307392640,512.03 TiB 42 | 16384,32767,eJF-DKG,7339584,7.00 MiB,2097184,2.00 MiB,9436768,9.00 MiB,309214577056,287.98 GiB 43 | 16384,32767,AMT DKG,20970240,20.00 MiB,15727840,15.00 MiB,36698080,35.00 MiB,1202485987360,1.09 TiB 44 | 32768,65535,JF-DKG,68719476672,64.00 GiB,3145664,3.00 MiB,68722622336,64.00 GiB,4503737054789760,4096.12 TiB 45 | 32768,65535,eJF-DKG,14679616,14.00 MiB,4194336,4.00 MiB,18873952,18.00 MiB,1236904444320,1.12 TiB 46 | 32768,65535,AMT DKG,44038848,42.00 MiB,33553568,32.00 MiB,77592416,74.00 MiB,5085018982560,4.62 TiB 47 | 65536,131071,JF-DKG,274877906880,256.00 GiB,6291392,6.00 MiB,274884198272,256.01 GiB,36029346751709312,32768.50 TiB 48 | 65536,131071,eJF-DKG,29359680,28.00 MiB,8388640,8.00 MiB,37748320,36.00 MiB,4947710050720,4.50 TiB 49 | 65536,131071,AMT DKG,92273280,88.00 MiB,71302240,68.00 MiB,163575520,156.00 MiB,21440006981920,19.50 TiB 50 | 131072,262143,JF-DKG,1099511627712,1024.00 GiB,12582848,12.00 MiB,1099524210560,1.00 TiB,288232575128830080,262146.00 TiB 51 | 131072,262143,eJF-DKG,58719808,56.00 MiB,16777248,16.00 MiB,75497056,72.00 MiB,19791024751008,18.00 TiB 52 | 131072,262143,AMT DKG,192936512,184.00 MiB,150993952,144.00 MiB,343930464,328.00 MiB,90158963624352,82.00 TiB 53 | 262144,524287,JF-DKG,4398046511040,4.00 TiB,25165760,24.00 MiB,4398071676800,4.00 TiB,2305851805214441600,2097160.00 TiB 54 | 262144,524287,eJF-DKG,117440064,112.00 MiB,33554464,32.00 MiB,150994528,144.00 MiB,79164468101536,72.00 TiB 55 | 262144,524287,AMT DKG,402651648,384.00 MiB,318766048,304.00 MiB,721417696,688.00 MiB,378229919582752,344.00 TiB 56 | 524288,1048575,JF-DKG,17592186044352,16.00 TiB,50331584,48.00 MiB,17592236375936,16.00 TiB,18446779257897091200,16777248.00 TiB 57 | 524288,1048575,eJF-DKG,234880576,224.00 MiB,67108896,64.00 MiB,301989472,288.00 MiB,316658610602400,288.00 TiB 58 | 524288,1048575,AMT DKG,838859200,800.00 MiB,671087520,640.00 MiB,1509946720,1.41 GiB,1583292381924000,1440.00 TiB 59 | 1048576,2097151,JF-DKG,70368744177600,64.00 TiB,100663232,96.00 MiB,70368844840832,64.00 TiB,147574093326795669632,134217856.00 TiB 60 | 1048576,2097151,eJF-DKG,469761600,448.00 MiB,134217760,128.00 MiB,603979360,576.00 MiB,1266635918803360,1152.00 TiB 61 | 1048576,2097151,AMT DKG,1744828800,1.62 GiB,1409284960,1.31 GiB,3154113760,2.94 GiB,6614652825897760,6015.99 TiB 62 | -------------------------------------------------------------------------------- /experiments/dkg-bw/benchmark.sh: -------------------------------------------------------------------------------- 1 | #BandwidthCalc bandwidth-32767.csv 32768 2 | BandwidthCalc bandwidth-1M.csv $((1024*1024)) 3 | -------------------------------------------------------------------------------- /experiments/dkg-bw/export-latex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2.7 2 | 3 | import matplotlib 4 | matplotlib.use('Agg') # otherwise script does not work when invoked over SSH 5 | 6 | import matplotlib.pyplot as plt 7 | from matplotlib.ticker import FuncFormatter 8 | from matplotlib.dates import MonthLocator, DateFormatter, DayLocator, epoch2num, num2date 9 | import pandas 10 | import sys 11 | import os 12 | import time 13 | 14 | improvLatexSymb="\\texttimes" 15 | 16 | if len(sys.argv) < 3: 17 | print "Usage:", sys.argv[0], " [ ...]" 18 | sys.exit(0) 19 | 20 | del sys.argv[0] 21 | 22 | out_tex_file = sys.argv[0] 23 | del sys.argv[0] 24 | 25 | if not out_tex_file.endswith('.tex'): 26 | print "ERROR: Expected .tex file as first argument" 27 | sys.exit(1) 28 | 29 | data_files = [f for f in sys.argv] 30 | 31 | print "Reading CSV files:", data_files, "..." 32 | 33 | csv_data = pandas.concat((pandas.read_csv(f) for f in data_files)) 34 | 35 | #print "Raw:" 36 | #print csv_data.to_string() 37 | #print csv_data.columns 38 | #print csv_data['dictSize'].values 39 | 40 | #print "Averaged:" 41 | 42 | minN = csv_data.n.unique().min(); 43 | maxN = csv_data.n.unique().max(); 44 | 45 | print "min N:", minN 46 | print "max N:", maxN 47 | 48 | # we specify the DKGs here in a specific order so they are plotted with the right colors 49 | dkgs_known = [ "eJF-DKG", "AMT DKG", "JF-DKG" ] 50 | dkgs_file = csv_data.dkg.unique() 51 | 52 | print csv_data.to_string() # print all data 53 | 54 | print "DKGs in file:", dkgs_file 55 | print "DKGs known: ", dkgs_known 56 | 57 | # open the file in append mode, and truncate it to zero bytes if it has data 58 | f = open(out_tex_file, "a+") 59 | 60 | isEmpty = os.fstat(f.fileno()).st_size == 0 61 | 62 | if not isEmpty: 63 | f.truncate(0) 64 | 65 | def write_latex_case_macro(f, data, macroName, col1, col2): 66 | f.write("\\newcommand{\\" + macroName + "}[1]{%\n") 67 | f.write(" \IfStrEqCase{#1}{") 68 | for _, r in data.iterrows(): 69 | f.write("\n {" + str(r[col1]).strip() + "}{" + str(r[col2]).strip() + "\\xspace}") 70 | 71 | f.write("}[\\textcolor{red}{\\textbf{NODATA}}]}\n\n") 72 | 73 | write_latex_case_macro(f, csv_data[csv_data.dkg == 'JF-DKG'], 'jfDkgDownload', 'n', 'download_bw_hum') 74 | write_latex_case_macro(f, csv_data[csv_data.dkg == 'AMT DKG'], 'amtDkgDownload', 'n', 'download_bw_hum') 75 | write_latex_case_macro(f, csv_data[csv_data.dkg == 'eJF-DKG'], 'ejfDkgDownload', 'n', 'download_bw_hum') 76 | write_latex_case_macro(f, csv_data[csv_data.dkg == 'JF-DKG'], 'jfDkgUpload', 'n', 'upload_bw_hum') 77 | write_latex_case_macro(f, csv_data[csv_data.dkg == 'AMT DKG'], 'amtDkgUpload', 'n', 'upload_bw_hum') 78 | write_latex_case_macro(f, csv_data[csv_data.dkg == 'eJF-DKG'], 'ejfDkgUpload', 'n', 'upload_bw_hum') 79 | write_latex_case_macro(f, csv_data[csv_data.dkg == 'JF-DKG'], 'jfDkgComm', 'n', 'comm_bw_hum') 80 | write_latex_case_macro(f, csv_data[csv_data.dkg == 'AMT DKG'], 'amtDkgComm', 'n', 'comm_bw_hum') 81 | write_latex_case_macro(f, csv_data[csv_data.dkg == 'eJF-DKG'], 'ejfDkgComm', 'n', 'comm_bw_hum') 82 | 83 | # compute the download overhead of AMT over eJF-DKG 84 | ejf_bytes = csv_data[csv_data.dkg == 'eJF-DKG']['download_bw_bytes'] 85 | #print ejf_bytes 86 | #print 87 | amt_bytes = csv_data[csv_data.dkg == 'AMT DKG']['download_bw_bytes'] 88 | #print amt_bytes 89 | #print 90 | overhead = amt_bytes.values.astype(float) / ejf_bytes.values 91 | 92 | overhead_data = pandas.concat( 93 | [ 94 | pandas.DataFrame(csv_data.n.unique(), columns=["n"]), 95 | pandas.DataFrame(overhead, columns=["overhead"]) 96 | ], 97 | axis=1) 98 | overhead_data['overhead'] = overhead_data['overhead'].round(decimals=2) 99 | overhead_data['overhead'] = overhead_data['overhead'].astype(str) + improvLatexSymb 100 | #print overhead_data 101 | 102 | write_latex_case_macro(f, overhead_data, 'amtDkgDownloadOverhead', 'n', 'overhead') 103 | 104 | # compute the upload overhead of AMT over eJF-DKG 105 | ejf_bytes = csv_data[csv_data.dkg == 'eJF-DKG']['upload_bw_bytes'] 106 | #print ejf_bytes 107 | #print 108 | amt_bytes = csv_data[csv_data.dkg == 'AMT DKG']['upload_bw_bytes'] 109 | #print amt_bytes 110 | #print 111 | overhead = amt_bytes.values.astype(float) / ejf_bytes.values 112 | 113 | overhead_data = pandas.concat( 114 | [ 115 | pandas.DataFrame(csv_data.n.unique(), columns=["n"]), 116 | pandas.DataFrame(overhead, columns=["overhead"]) 117 | ], 118 | axis=1) 119 | overhead_data['overhead'] = overhead_data['overhead'].round(decimals=2) 120 | overhead_data['overhead'] = overhead_data['overhead'].astype(str) + improvLatexSymb 121 | #print overhead_data 122 | 123 | write_latex_case_macro(f, overhead_data, 'amtDkgUploadOverhead', 'n', 'overhead') 124 | 125 | # compute the download+upload overhead of AMT over eJF-DKG 126 | ejf_bytes = csv_data[csv_data.dkg == 'eJF-DKG']['comm_bw_bytes'] 127 | #print ejf_bytes 128 | #print 129 | amt_bytes = csv_data[csv_data.dkg == 'AMT DKG']['comm_bw_bytes'] 130 | #print amt_bytes 131 | #print 132 | overhead = amt_bytes.values.astype(float) / ejf_bytes.values 133 | 134 | overhead_data = pandas.concat( 135 | [ 136 | pandas.DataFrame(csv_data.n.unique(), columns=["n"]), 137 | pandas.DataFrame(overhead, columns=["overhead"]) 138 | ], 139 | axis=1) 140 | overhead_data['overhead'] = overhead_data['overhead'].round(decimals=2) 141 | overhead_data['overhead'] = overhead_data['overhead'].astype(str) + improvLatexSymb 142 | #print overhead_data 143 | 144 | write_latex_case_macro(f, overhead_data, 'amtDkgCommOverhead', 'n', 'overhead') 145 | -------------------------------------------------------------------------------- /experiments/dkg-bw/redraw.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | scriptdir=$(cd $(dirname $0); pwd -P) 5 | 6 | plot_cmd=$scriptdir/../../scripts/linux/plot-bandwidth.py 7 | 8 | rm -f $scriptdir/bw-ejf-vs-amt.png 9 | 10 | $plot_cmd \ 11 | $scriptdir/bw-ejf-vs-amt.png \ 12 | "AMT DKG,eJF-DKG" 0 0 \ 13 | $scriptdir/bandwidth-1M.csv 14 | -------------------------------------------------------------------------------- /experiments/dkg/.gitignore: -------------------------------------------------------------------------------- 1 | *html 2 | -------------------------------------------------------------------------------- /experiments/dkg/README.md: -------------------------------------------------------------------------------- 1 | AMT and Kate's avg_reconstr_bc_usec is from Feldman VSS best case reconstruction, since you just interpolate and verify against PK 2 | Kate's avg_reconstr_wc_usec is from Kate VSS worst-case reconstruction, since you must verify all shares and interpolate and you're done 3 | -------------------------------------------------------------------------------- /experiments/dkg/amt-dkg-2-1048576-dvorak.csv: -------------------------------------------------------------------------------- 1 | t,n,build,dkg,num_deal_iters,num_verify_bc_iters,num_verify_wc_iters,num_reconstr_bc_iters,num_reconstr_wc_iters,avg_deal_usec,avg_verify_best_case_usec,avg_verify_worst_case_usec,avg_reconstr_bc_usec,avg_reconstr_wc_usec,avg_deal_hum,avg_verify_bc_hum,avg_verify_wc_hum,avg_reconstr_bc_hum,avg_reconstr_wc_hum,stddev_deal,stddev_verify_bc,stddev_verify_wc,stddev_reconstr_bc,stddev_reconstr_wc,vms_hum,rss_hum 2 | 2,3,release,amt,10,100,100,1000,100,1500,4984,8958,252,7906,1.50 ms,4.98 ms,8.96 ms,252.00 mus,7.91 ms,19.308288,86.59153,161.842299,20.399266,26.409385,25.64 MiB,5.16 MiB 3 | 4,7,release,amt,10,100,100,1000,100,4113,7829,39048,258,21339,4.11 ms,7.83 ms,39.05 ms,258.00 mus,21.34 ms,34.698847,121.606126,5886.311722,9.137422,431.625087,25.64 MiB,5.16 MiB 4 | 8,15,release,amt,10,100,100,1000,100,13539,16029,109897,278,56461,13.54 ms,16.03 ms,109.90 ms,278.00 mus,56.46 ms,226.608473,2253.329982,13153.912288,11.161128,6897.94169,25.64 MiB,5.16 MiB 5 | 16,31,release,amt,10,100,100,1000,100,30112,26339,261695,323,126689,30.11 ms,26.34 ms,261.69 ms,323.00 mus,126.69 ms,445.769234,3809.979382,30012.484295,9.81902,5067.391131,25.75 MiB,5.31 MiB 6 | 32,63,release,amt,10,100,100,200,100,57978,48484,598946,454,297713,57.98 ms,48.48 ms,598.95 ms,454.00 mus,297.71 ms,8082.72761,6183.465925,44081.628218,7.880722,25113.864901,25.82 MiB,5.42 MiB 7 | 64,127,release,amt,10,100,80,50,100,100814,72249,1165768,910,663187,100.81 ms,72.25 ms,1.17 secs,910.00 mus,663.19 ms,1425.97028,4304.915924,52374.078739,9.799367,3066.468099,26.79 MiB,6.39 MiB 8 | 128,255,release,amt,10,100,80,25,100,212781,137867,2597391,1645,1456378,212.78 ms,137.87 ms,2.60 secs,1.65 ms,1.46 secs,1288.237695,10203.430212,86875.779514,7.172615,4099.383155,27.11 MiB,6.88 MiB 9 | 256,511,release,amt,10,100,80,10,100,450767,270248,5623142,3225,3169765,450.77 ms,270.25 ms,5.62 secs,3.23 ms,3.17 secs,10620.380634,10964.297387,57581.470464,6.321392,5371.132416,27.99 MiB,7.77 MiB 10 | 512,1023,release,amt,10,100,80,10,100,937162,519821,12185914,6582,6840211,937.16 ms,519.82 ms,12.19 secs,6.58 ms,6.84 secs,3153.7576,3930.568554,149714.918134,9.914131,8337.87832,29.80 MiB,9.58 MiB 11 | 1024,2047,release,amt,10,100,40,10,10,1949535,1036757,26329264,13585,15766090,1.95 secs,1.04 secs,26.33 secs,13.59 ms,15.77 secs,7012.187408,7356.880136,163697.87628,152.221713,243156.64672,34.15 MiB,13.88 MiB 12 | 2048,4095,release,amt,10,100,20,10,10,4035805,2071200,56444950,28807,34420027,4.04 secs,2.07 secs,56.44 secs,28.81 ms,34.42 secs,13214.455861,11004.63499,227415.023574,210.574001,165022.377715,43.04 MiB,22.80 MiB 13 | 4096,8191,release,amt,10,100,8,10,10,8355453,4137753,120367118,60008,73511419,8.36 secs,4.14 secs,2.01 mins,60.01 ms,1.23 mins,122995.801636,18716.300704,45540.256045,720.67483,321945.372435,61.18 MiB,40.91 MiB 14 | 8192,16383,release,amt,8,80,4,10,10,17176256,8146050,256036169,126440,154051124,17.18 secs,8.15 secs,4.27 mins,126.44 ms,2.57 mins,156274.931455,96364.591155,419570.976062,634.12125,546087.759819,90.68 MiB,70.34 MiB 15 | 16384,32767,release,amt,5,40,2,10,4,36915313,18995633,626432490,266547,300764697,36.92 secs,19.00 secs,10.44 mins,266.55 ms,5.01 mins,400403.258993,1398533.444603,579072.5,824.137877,1180156.122893,136.18 MiB,115.82 MiB 16 | 32768,65535,release,amt,3,20,1,10,2,72210892,32963383,1149038776,565439,628361931,1.20 mins,32.96 secs,19.15 mins,565.44 ms,10.47 mins,109258.002625,161330.165309,na,1792.784482,34665,222.68 MiB,202.41 MiB 17 | 65536,131071,release,amt,3,16,1,10,1,148579474,68932189,2423691394,1211522,1320742343,2.48 mins,1.15 mins,40.39 mins,1.21 secs,22.01 mins,88269.067834,1036823.76479,na,4825.504115,na,431.68 MiB,411.38 MiB 18 | 131072,262143,release,amt,2,8,1,10,1,301880929,135698661,5094131827,2585132,2836830065,5.03 mins,2.26 mins,1.42 hrs,2.59 secs,47.28 mins,209899.5,5305874.848762,na,8409.261599,na,801.75 MiB,781.46 MiB 19 | 262144,524287,release,amt,1,4,1,10,1,615321830,266378461,10663969766,5635568,6454067514,10.26 mins,4.44 mins,2.96 hrs,5.64 secs,1.79 hrs,na,2834802.50533,na,367964.265927,na,1.59 GiB,1.57 GiB 20 | 524288,1048575,release,amt,1,3,1,10,1,1251233151,528211991,22290359836,11784576,12637106980,20.85 mins,8.80 mins,6.19 hrs,11.78 secs,3.51 hrs,na,4112340.329949,na,50709.220002,na,3.24 GiB,3.22 GiB 21 | 1048576,2097151,release,amt,1,2,1,10,1,2541258565,1088894716,46495388837,24712133,24574860611,42.35 mins,18.15 mins,12.92 hrs,24.71 secs,6.83 hrs,na,4060125,na,75107.605953,na,6.65 GiB,6.63 GiB 22 | -------------------------------------------------------------------------------- /experiments/dkg/kate-dkg-2-32768-dvorak.csv: -------------------------------------------------------------------------------- 1 | t,n,build,dkg,num_deal_iters,num_verify_bc_iters,num_verify_wc_iters,num_reconstr_bc_iters,num_reconstr_wc_iters,avg_deal_usec,avg_verify_best_case_usec,avg_verify_worst_case_usec,avg_reconstr_bc_usec,avg_reconstr_wc_usec,avg_deal_hum,avg_verify_bc_hum,avg_verify_wc_hum,avg_reconstr_bc_hum,avg_reconstr_wc_hum,stddev_deal,stddev_verify_bc,stddev_verify_wc,stddev_reconstr_bc,stddev_reconstr_wc,vms_hum,rss_hum 2 | 2,3,release,kate,10,100,100,1000,1000,1569,4992,8918,252,7115,1.57 ms,4.99 ms,8.92 ms,252.00 mus,7.12 ms,133.154,97.002957,130.697252,20.399266,483.598889,25.57 MiB,5.05 MiB 3 | 4,7,release,kate,10,100,100,1000,1000,5262,6916,26628,258,15277,5.26 ms,6.92 ms,26.63 ms,258.00 mus,15.28 ms,139.29,490.13879,266.43494,9.137422,1347.859917,25.57 MiB,5.05 MiB 4 | 8,15,release,kate,10,100,100,1000,1000,13032,10875,62585,278,32169,13.03 ms,10.88 ms,62.59 ms,278.00 mus,32.17 ms,100.205,98.384053,749.325555,11.161128,3013.210512,25.57 MiB,5.05 MiB 5 | 16,31,release,kate,10,100,100,1000,1000,40061,18840,134611,323,67402,40.06 ms,18.84 ms,134.61 ms,323.00 mus,67.40 ms,100.053,102.609654,3145.596173,9.81902,7083.840119,25.68 MiB,5.60 MiB 6 | 32,63,release,kate,10,100,100,200,1000,133709,35007,277072,454,146856,133.71 ms,35.01 ms,277.07 ms,454.00 mus,146.86 ms,550.034,401.369226,3326.606821,7.880722,17797.064188,25.77 MiB,5.69 MiB 7 | 64,127,release,kate,10,100,50,50,500,459117,66512,559602,910,256329,459.12 ms,66.51 ms,559.60 ms,910.00 mus,256.33 ms,2796.2,825.405453,3423.958071,9.799367,201.751038,26.08 MiB,5.46 MiB 8 | 128,255,release,kate,10,100,25,25,250,1602309,128565,1130723,1645,514931,1.60 secs,128.56 ms,1.13 secs,1.65 ms,514.93 ms,4441.19,1094.14308,8765.737533,7.172615,438.624752,26.62 MiB,6.47 MiB 9 | 256,511,release,kate,10,100,12,10,120,5698797,254127,2258189,3225,1017670,5.70 secs,254.13 ms,2.26 secs,3.23 ms,1.02 secs,7293.22,3019.561529,6442.764029,6.321392,35299.079512,27.40 MiB,7.39 MiB 10 | 512,1023,release,kate,10,50,10,10,60,20605535,507002,4529116,6582,2065289,20.61 secs,507.00 ms,4.53 secs,6.58 ms,2.07 secs,37342,3329.386879,10506.843094,9.914131,436.36419,28.79 MiB,8.63 MiB 11 | 1024,2047,release,kate,8,25,10,10,30,75223594,1014561,9076809,13585,4293806,1.25 mins,1.01 secs,9.08 secs,13.59 ms,4.29 secs,336556,5721.576954,16397.603479,152.221713,112196.690034,31.11 MiB,10.64 MiB 12 | 2048,4095,release,kate,2,12,10,10,15,285270946,1999978,18140261,28807,8277573,4.75 mins,2.00 secs,18.14 secs,28.81 ms,8.28 secs,7057540,10087.150667,20417.334057,210.574001,1256.019611,33.30 MiB,12.50 MiB 13 | 4096,8191,release,kate,1,10,5,10,10,1051799743,3999384,36335019,60008,17988963,17.53 mins,4.00 secs,36.34 secs,60.01 ms,17.99 secs,na,16406.363222,48864.11941,720.67483,430384.209342,47.70 MiB,27.04 MiB 14 | 8192,16383,release,kate,1,10,3,10,10,4170460379,8013628,72566671,126440,32497790,1.16 hrs,8.01 secs,1.21 mins,126.44 ms,32.50 secs,na,23289.777474,74465.521288,634.12125,157327.258782,62.20 MiB,41.91 MiB 15 | 16384,32767,release,kate,1,10,2,10,10,16670120237,16411938,149351765,266547,66268468,4.63 hrs,16.41 secs,2.49 mins,266.55 ms,1.10 mins,na,410196.105678,310032,824.137877,3871.926967,89.32 MiB,69.16 MiB 16 | 32768,65535,release,kate,1,10,1,10,10,59895940919,32463650,290794480,565439,132609283,16.64 hrs,32.46 secs,4.85 mins,565.44 ms,2.21 mins,na,59361.955535,na,1792.784482,5544.718244,144.63 MiB,124.46 MiB 17 | 65536,131071,release,kate,0,10,1,10,10,209635793216.5,65551401,584569501,1211522,265648988,2.43 days,1.09 mins,9.74 mins,1.21 secs,4.43 mins,na,105287.850494,na,4825.504115,13855.558915,na,na 18 | 131072,262143,release,kate,0,10,1,10,8,733725276257.75,128960280,1166005433,2585132,533085745,8.49 days,2.15 mins,19.43 mins,2.59 secs,8.88 mins,na,1029548.828031,na,8409.261599,43919.0234,na,na 19 | 262144,524287,release,kate,0,10,1,10,4,2568038466902.12,259289366,2329301935,5635568,1358290627,29.72 days,4.32 mins,38.82 mins,5.64 secs,22.64 mins,na,1366207.194313,na,367964.265927,23827183.67437,na,na 20 | 524288,1048575,release,kate,0,10,1,10,2,8988134634157.44,511046828,4663771619,11784576,2670754733,104.03 days,8.52 mins,1.30 hrs,11.78 secs,44.51 mins,na,5522531.027568,na,50709.220002,255899.5,na,na 21 | 1048576,2097151,release,kate,0,10,1,10,1,31458471219551,1070561739,9331561814,24712133,4103020080,364.10 days,17.84 mins,2.59 hrs,24.71 secs,1.14 hrs,na,5434862.804556,na,75107.605953,na,na,na 22 | -------------------------------------------------------------------------------- /experiments/dkg/redraw.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | scriptdir=$(cd $(dirname $0); pwd -P) 4 | 5 | prefix=${1:-""} 6 | 7 | plot_cmd=$scriptdir/../../scripts/linux/plot-dkg-times.py 8 | 9 | png_prefix=dkg 10 | 11 | rm -f ${png_prefix}*.png 12 | 13 | # Just plots Kate vs AMT 14 | $plot_cmd \ 15 | $png_prefix 2 0 \ 16 | $scriptdir/*${prefix}*kate*dvorak*.csv \ 17 | $scriptdir/*${prefix}*amt*dvorak*.csv 18 | 19 | # Just plots Kate 20 | #$plot_cmd \ 21 | # "$png_prefix-ejf" 2 0 \ 22 | # $scriptdir/*${prefix}*kate*dvorak*.csv \ 23 | -------------------------------------------------------------------------------- /experiments/dkg/run-experiments.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if [ $# -lt 2 ]; then 6 | echo "Runs the DKG benchmark for the specified DKG(s) with thresholds f+1 = {2, 4, 8, 16, ..., 32768} and n = 2f+1" 7 | echo 8 | echo "Usage: $0 " 9 | echo 10 | echo "OPTIONS:" 11 | echo " can be either 'kate', 'kate-sim', 'amt' or 'amt-sim'" 12 | exit 1 13 | fi 14 | 15 | scriptdir=$(cd $(dirname $0); pwd -P) 16 | date=`date +%Y-%m-%d` 17 | machine=$1 18 | dkg_type=$2 19 | pp_file=$scriptdir/../../public-params/1048576/1048576 20 | multicore=0 21 | 22 | which BenchDKG 2>&1 >/dev/null || { echo "ERROR: You did not set up the environment"; exit 1; } 23 | 24 | if [ "$dkg_type" = "kate" ]; then 25 | : 26 | elif [ "$dkg_type" = "kate-sim" ]; then 27 | : 28 | elif [ "$dkg_type" = "amt" ]; then 29 | : 30 | elif [ "$dkg_type" = "amt-sim" ]; then 31 | : 32 | else 33 | echo "ERROR: Unknown DKG type '$dkg_type'" 34 | exit 1 35 | fi 36 | 37 | # Format: t n numDealIters numVerifyBcIters numVerifyWcIters numReconstrBcIters numReconstrWc scheme 38 | benchmarks_kate_sim="\ 39 | 2 32 10 100 100 0 0 kate-sim 40 | 64 64 10 100 50 0 0 kate-sim 41 | 128 128 10 100 25 0 0 kate-sim 42 | 256 256 10 100 12 0 0 kate-sim 43 | 512 512 10 50 10 0 0 kate-sim 44 | 1024 1024 10 25 10 0 0 kate-sim 45 | 2048 2048 10 12 10 0 0 kate-sim 46 | 4096 4096 10 10 5 0 0 kate-sim 47 | 8192 8192 10 10 3 0 0 kate-sim 48 | 16384 16384 10 10 2 0 0 kate-sim 49 | 32768 32768 10 10 1 0 0 kate-sim 50 | 65536 65536 10 10 1 0 0 kate-sim 51 | 131072 131072 5 10 1 0 0 kate-sim 52 | 262144 262144 4 10 1 0 0 kate-sim 53 | 524288 524288 3 10 1 0 0 kate-sim 54 | 1048576 1048576 2 10 1 0 0 kate-sim 55 | " 56 | 57 | benchmarks_kate="\ 58 | 2 32 10 100 100 0 0 kate 59 | 64 64 10 100 50 0 0 kate 60 | 128 128 10 100 25 0 0 kate 61 | 256 256 10 100 12 0 0 kate 62 | 512 512 10 000 10 0 0 kate 63 | 1024 1024 8 000 10 0 0 kate 64 | 2048 2048 2 000 10 0 0 kate 65 | 4096 32768 1 000 10 0 0 kate 66 | " 67 | 68 | benchmarks_amt="\ 69 | 2 32 10 100 100 0 0 amt 70 | 64 512 10 100 80 0 0 amt 71 | 1024 1024 10 100 40 0 0 amt 72 | 2048 2048 10 100 20 0 0 amt 73 | 4096 4096 10 100 8 0 0 amt 74 | 8192 8192 8 80 4 0 0 amt 75 | 16384 16384 5 40 2 0 0 amt 76 | 32768 32768 3 20 1 0 0 amt 77 | 65536 65536 3 16 1 0 0 amt 78 | 131072 131072 2 8 1 0 0 amt 79 | 262144 262144 1 4 1 0 0 amt 80 | 524288 524288 1 3 1 0 0 amt 81 | 1048576 1048576 1 2 1 0 0 amt 82 | " 83 | 84 | benchmarks="\ 85 | $benchmarks_kate_sim 86 | $benchmarks_amt 87 | " 88 | 89 | files= 90 | numFiles=0 91 | t1min=$((1048576*1024)) 92 | t2max=0 93 | while read -r b; do 94 | t1=`echo $b | cut -d' ' -f 1` 95 | t2=`echo $b | cut -d' ' -f 2` 96 | numDealIters=`echo $b | cut -d' ' -f 3` 97 | numVerifyBcIters=`echo $b | cut -d' ' -f 4` 98 | numVerifyWcIters=`echo $b | cut -d' ' -f 5` 99 | numReconstrBcIters=`echo $b | cut -d' ' -f 6` 100 | numReconstrWcIters=`echo $b | cut -d' ' -f 7` 101 | dkg=`echo $b | cut -d' ' -f 8` 102 | 103 | if [ "$dkg" != "$dkg_type" ]; then 104 | continue 105 | fi 106 | 107 | echo "Running t \\in $t1 to $t2 $dkg DKG with $numDealIters dealing and $numVerifyBcIters/$numVerifyWcIters BC/WC verifying" 108 | 109 | [ $t1 -lt $t1min ] && t1min=$t1 110 | [ $t2 -gt $t2max ] && t2max=$t2 111 | 112 | file=${date}-${dkg}-dkg-${t1}-${t2}-${machine}.csv 113 | logfile=${date}-${dkg}-dkg-${t1}-${t2}-${machine}.log 114 | echo "Logging to $logfile ..." 115 | if [ $multicore -eq 1 ]; then 116 | BenchDKG $pp_file $t1 $t2 $dkg $numDealIters \ 117 | $numVerifyBcIters \ 118 | $numVerifyWcIters \ 119 | $numReconstrBcIters \ 120 | $numReconstrWcIters \ 121 | $file &>$logfile & 122 | sleep 1 123 | else 124 | BenchDKG $pp_file $t1 $t2 $dkg $numDealIters \ 125 | $numVerifyBcIters \ 126 | $numVerifyWcIters \ 127 | $numReconstrBcIters \ 128 | $numReconstrWcIters \ 129 | $file 2>&1 | tee -a $logfile 130 | fi 131 | 132 | files="$files $file" 133 | logfiles="$logfiles $logfile" 134 | numFiles=$(($numFiles + 1)) 135 | done <<< "$benchmarks" 136 | 137 | if [ $multicore -eq 1 ]; then 138 | echo "Waiting for processes to finish..." 139 | wait 140 | fi 141 | 142 | echo 143 | 144 | if [ $numFiles -gt 1 ]; then 145 | # initially, no hours/minutes/seconds 146 | merged_file=${date}-${dkg_type}-dkg-${t1min}-${t2max}-${machine}.csv 147 | new_logfile=${date}-${dkg_type}-dkg-${t1min}-${t2max}-${machine}.log 148 | while [ -f "$merged_file" -o -f "$new_logfile" ]; do 149 | # but if file name clashes, add hours/minutes/seconds 150 | extra_date=`date +%H-%M-%S` 151 | merged_file=${date}-${extra_date}-${dkg_type}-dkg-${t1min}-${t2max}-${machine}.csv 152 | new_logfile=${date}-${extra_date}-${dkg_type}-dkg-${t1min}-${t2max}-${machine}.log 153 | done 154 | 155 | cat $logfiles >"$new_logfile" 156 | ( 157 | first_file=`echo $files | cut -f 1 -d' '` 158 | head -n 1 $first_file 159 | for f in $files; do 160 | tail -n +2 $f 161 | done 162 | ) >$merged_file 163 | rm $files $logfiles 164 | 165 | echo "Merged files: " 166 | echo 167 | for f in $files; do echo " $f"; done 168 | echo 169 | echo "...into: " 170 | echo 171 | echo " $merged_file" 172 | echo 173 | fi 174 | -------------------------------------------------------------------------------- /experiments/redraw-all.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | scriptdir=$(cd $(dirname $0); pwd -P) 5 | 6 | #echo "Script dir: $scriptdir" 7 | 8 | (cd $scriptdir/threshsig/; pwd; ./redraw.sh; ) 9 | (cd $scriptdir/dkg/; ./redraw.sh ) 10 | (cd $scriptdir/dkg-bw/; ./redraw.sh ) 11 | (cd $scriptdir/vss/; ./redraw.sh ) 12 | 13 | # DKG dealing times are basically the same as eVSS dealing times 14 | $scriptdir/redraw-vss-and-dkg-deal.sh 15 | -------------------------------------------------------------------------------- /experiments/redraw-vss-and-dkg-deal.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | scriptdir=$(cd $(dirname $0); pwd -P) 5 | 6 | #echo "Script dir: $scriptdir" 7 | 8 | # DKG dealing times are basically the same as eVSS dealing times 9 | #$scriptdir/../scripts/linux/plot-deal-times.py "-with-feld" 0 0 vss/kate.csv vss/feld.csv vss/amt.csv; 10 | $scriptdir/../scripts/linux/plot-deal-times.py "" 0 0 vss/kate.csv vss/amt.csv; 11 | -------------------------------------------------------------------------------- /experiments/threshsig/efficient-threshsig-2-1048576-dvorak.csv: -------------------------------------------------------------------------------- 1 | k,n,interpolation_method,num_samples,lagr_usec,multiexp_usec,total_usec,lagr_hum,multiexp_hum,total_hum 2 | 2,3,fft-eval,100,23,298,321,23.00 mus,298.00 mus,321.00 mus 3 | 4,7,fft-eval,100,40,645,685,40.00 mus,645.00 mus,685.00 mus 4 | 8,15,fft-eval,100,75,707,782,75.00 mus,707.00 mus,782.00 mus 5 | 16,31,fft-eval,100,156,1243,1399,156.00 mus,1.24 ms,1.40 ms 6 | 32,63,fft-eval,100,358,2098,2456,358.00 mus,2.10 ms,2.46 ms 7 | 64,127,fft-eval,100,649,3614,4263,649.00 mus,3.61 ms,4.26 ms 8 | 128,255,fft-eval,100,1365,6272,7637,1.36 ms,6.27 ms,7.64 ms 9 | 256,511,fft-eval,10,2944,11363,14307,2.94 ms,11.36 ms,14.31 ms 10 | 512,1023,fft-eval,10,6318,20601,26919,6.32 ms,20.60 ms,26.92 ms 11 | 1024,2047,fft-eval,10,13469,37270,50739,13.47 ms,37.27 ms,50.74 ms 12 | 2048,4095,fft-eval,10,28235,67931,96166,28.23 ms,67.93 ms,96.17 ms 13 | 4096,8191,fft-eval,10,60538,126015,186553,60.54 ms,126.02 ms,186.55 ms 14 | 8192,16383,fft-eval,10,128443,236556,364999,128.44 ms,236.56 ms,365.00 ms 15 | 16384,32767,fft-eval,10,271989,447666,719655,271.99 ms,447.67 ms,719.65 ms 16 | 32768,65535,fft-eval,10,577351,885574,1462925,577.35 ms,885.57 ms,1.46 secs 17 | 65536,131071,fft-eval,10,1226723,1639906,2866629,1.23 secs,1.64 secs,2.87 secs 18 | 131072,262143,fft-eval,10,2605592,3112656,5718248,2.61 secs,3.11 secs,5.72 secs 19 | 262144,524287,fft-eval,10,5489921,5906719,11396640,5.49 secs,5.91 secs,11.40 secs 20 | 524288,1048575,fft-eval,10,12490665,11671527,24162192,12.49 secs,11.67 secs,24.16 secs 21 | 1048576,2097151,fft-eval,10,25004058,21260093,46264151,25.00 secs,21.26 secs,46.26 secs 22 | -------------------------------------------------------------------------------- /experiments/threshsig/export-latex.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2.7 2 | 3 | import matplotlib 4 | matplotlib.use('Agg') # otherwise script does not work when invoked over SSH 5 | 6 | import matplotlib.pyplot as plt 7 | from matplotlib.ticker import FuncFormatter 8 | from matplotlib.dates import MonthLocator, DateFormatter, DayLocator, epoch2num, num2date 9 | import pandas 10 | import sys 11 | import os 12 | import time 13 | 14 | improvLatexSymb="\\texttimes" 15 | 16 | if len(sys.argv) < 3: 17 | print "Usage:", sys.argv[0], " [ ...]" 18 | sys.exit(0) 19 | 20 | del sys.argv[0] 21 | 22 | out_tex_file = sys.argv[0] 23 | del sys.argv[0] 24 | 25 | if not out_tex_file.endswith('.tex'): 26 | print "ERROR: Expected .tex file as first argument" 27 | sys.exit(1) 28 | 29 | data_files = [f for f in sys.argv] 30 | 31 | print "Reading CSV files:", data_files, "..." 32 | 33 | csv_data = pandas.concat((pandas.read_csv(f) for f in data_files), ignore_index=True) 34 | 35 | #print "Raw:" 36 | #print csv_data.to_string() 37 | #print csv_data.columns 38 | #print csv_data['dictSize'].values 39 | 40 | #print "Averaged:" 41 | 42 | minN = csv_data.n.unique().min(); 43 | maxN = csv_data.n.unique().max(); 44 | 45 | print "min N:", minN 46 | print "max N:", maxN 47 | 48 | #print csv_data.to_string() # print all data 49 | print csv_data[['k','n','interpolation_method', 'lagr_hum', 'multiexp_hum', 'total_hum']].to_string() 50 | 51 | # open the file in append mode, and truncate it to zero bytes if it has data 52 | f = open(out_tex_file, "a+") 53 | 54 | isEmpty = os.fstat(f.fileno()).st_size == 0 55 | 56 | if not isEmpty: 57 | f.truncate(0) 58 | 59 | def humanizeBytes(numBytes, precision = 2): 60 | result = float(numBytes) 61 | units = [ "bytes", "KiB", "MiB", "GiB", "TiB" ] 62 | i = 0; 63 | while result >= 1024.0 and i < len(units) - 1: 64 | result /= 1024.0 65 | i = i+1 66 | 67 | #string = (("%." + str(precision) + "f") % result) 68 | string = ("{:." + str(precision) + "f}").format(result) 69 | string += " " 70 | string += units[i] 71 | 72 | return string 73 | 74 | def humanizeMicroseconds(mus, precision = 2): 75 | result = float(mus) 76 | units = [ "mus", "ms", "secs", "mins", "hrs", "days", "years" ] 77 | numUnits = len(units) 78 | i = 0 79 | 80 | while result >= 1000.0 and i < 2: 81 | result /= 1000.0 82 | i = i+1 83 | 84 | while result >= 60.0 and i >= 2 and i < 4: 85 | result /= 60.0 86 | i = i+1 87 | 88 | if i == 4 and result >= 24.0: 89 | result /= 24.0 90 | i = i+1 91 | 92 | if i == 5 and result >= 365.25: 93 | result /= 365.25 94 | i = i+1 95 | 96 | assert(i < numUnits) 97 | string = ("{:." + str(precision) + "f}").format(result) 98 | string += " " 99 | string += units[i] 100 | 101 | return string 102 | 103 | # update avg_deal+verify_hum with humanized bytes, if they are 'nan': 104 | for idx, r in csv_data.iterrows(): 105 | if str(r['total_hum']) == 'nan': 106 | #print "Humanizing row:", r.values 107 | csv_data.ix[idx, 'total_hum'] = humanizeMicroseconds(int(r['total_usec'])) 108 | 109 | print csv_data[['k','n','interpolation_method', 'lagr_hum', 'multiexp_hum', 'total_hum', 'total_usec']].to_string() 110 | 111 | def write_latex_case_macro(f, data, macroName, col1, col2): 112 | f.write("\\newcommand{\\" + macroName + "}[1]{%\n") 113 | f.write(" \IfStrEqCase{#1}{") 114 | for _, r in data.iterrows(): 115 | f.write("\n {" + str(r[col1]).strip() + "}{" + str(r[col2]).strip() + "\\xspace}") 116 | 117 | f.write("}[\\textcolor{red}{\\textbf{NODATA}}]}\n\n") 118 | 119 | write_latex_case_macro(f, csv_data[csv_data.interpolation_method == 'naive-lagr-wnk'], 'blsNaiveTime', 'n', 'total_hum') 120 | write_latex_case_macro(f, csv_data[csv_data.interpolation_method == 'naive-lagr-wnk'], 'naiveLagrTime', 'n', 'lagr_hum') 121 | write_latex_case_macro(f, csv_data[csv_data.interpolation_method == 'naive-lagr-wnk'], 'multiexpTime', 'n', 'multiexp_hum') 122 | write_latex_case_macro(f, csv_data[csv_data.interpolation_method == 'fft-eval'], 'blsEffTime', 'n', 'total_hum') 123 | write_latex_case_macro(f, csv_data[csv_data.interpolation_method == 'fft-eval'], 'fastLagrTime', 'n', 'lagr_hum') 124 | 125 | # compute the improvement of FFT over naive Lagr 126 | naive = csv_data[csv_data.interpolation_method == 'naive-lagr-wnk']['total_usec'] 127 | eff = csv_data[csv_data.interpolation_method == 'fft-eval']['total_usec'] 128 | improv = naive.values / eff.values.astype(float) 129 | print eff.values 130 | print naive.values 131 | 132 | improv_data = pandas.concat( 133 | [ 134 | pandas.DataFrame(csv_data.n.unique(), columns=["n"]), 135 | pandas.DataFrame(improv, columns=["improv"]) 136 | ], 137 | axis=1) 138 | 139 | improv_data['improv'] = improv_data['improv'].round(decimals=2) 140 | 141 | # extract the threshold # of players n at which we beat naive 142 | min_improv = 1.2 143 | outperform = improv_data[(improv_data.improv > 1.2) & (improv_data.n > 64)].copy() # we might beat the naive scheme at small thresholds too, but then later on we don't beat it anymore 144 | outperform.reset_index(drop=True, inplace=True) # because copy() does not renumber the rows of the dataframe 145 | outperform.sort_values(by='improv', ascending=True) 146 | outperform_num = int(outperform.ix[0]['n']) 147 | 148 | improv_data['improv'] = improv_data['improv'].astype(str) + improvLatexSymb 149 | #print improv_data 150 | 151 | write_latex_case_macro(f, improv_data, 'blsTimeImprov', 'n', 'improv') 152 | 153 | print "Starts outperforming naive at:", outperform_num 154 | f.write("\\newcommand{\\blsOutperformN}{" + str(outperform_num) + "}\n") 155 | -------------------------------------------------------------------------------- /experiments/threshsig/naive-threshsig-2-1048576-dvorak.csv: -------------------------------------------------------------------------------- 1 | k,n,interpolation_method,num_samples,lagr_usec,multiexp_usec,total_usec,lagr_hum,multiexp_hum,total_hum 2 | 2,3,naive-lagr-wnk,100,11,303,314,11.00 mus,303.00 mus,314.00 mus 3 | 4,7,naive-lagr-wnk,100,16,649,665,16.00 mus,649.00 mus,665.00 mus 4 | 8,15,naive-lagr-wnk,100,33,731,764,33.00 mus,731.00 mus,764.00 mus 5 | 16,31,naive-lagr-wnk,100,77,1278,1355,77.00 mus,1.28 ms,1.35 ms 6 | 32,63,naive-lagr-wnk,100,212,2137,2349,212.00 mus,2.14 ms,2.35 ms 7 | 64,127,naive-lagr-wnk,100,642,3651,4293,642.00 mus,3.65 ms,4.29 ms 8 | 128,255,naive-lagr-wnk,100,2184,6408,8592,2.18 ms,6.41 ms,8.59 ms 9 | 256,511,naive-lagr-wnk,100,7966,11306,19272,7.97 ms,11.31 ms,19.27 ms 10 | 512,1023,naive-lagr-wnk,10,30559,20273,50832,30.56 ms,20.27 ms,50.83 ms 11 | 1024,2047,naive-lagr-wnk,10,118719,36896,155615,118.72 ms,36.90 ms,155.62 ms 12 | 2048,4095,naive-lagr-wnk,10,558174,78426,636600,558.17 ms,78.43 ms,636.60 ms 13 | 4096,8191,naive-lagr-wnk,10,1933103,129120,2062223,1.93 secs,129.12 ms,2.06 secs 14 | 8192,16383,naive-lagr-wnk,10,7346641,235698,7582339,7.35 secs,235.70 ms,7.58 secs 15 | 16384,32767,naive-lagr-wnk,10,29292176,449913,29742089,29.29 secs,449.91 ms,29.74 secs 16 | 32768,65535,naive-lagr-wnk,8,119119494,871959,119991453,1.99 mins,871.96 ms,2.00 mins 17 | 65536,131071,naive-lagr-wnk,4,481370443,1625375,482995818,8.02 mins,1.63 secs,8.05 mins 18 | 131072,262143,naive-lagr-wnk,2,1990918732,3129692,1994048424,33.18 mins,3.13 secs,33.23 mins 19 | 262144,524287,naive-lagr-wnk,1,7538170354,5978289,7544148643,2.09 hrs,5.98 secs,2.10 hrs 20 | 524288,1048575,naive-lagr-wnk,1,31112329597,11411533,31123741130,8.64 hrs,11.41 secs,8.65 hrs 21 | 1048576,2097151,naive-lagr-wnk,1,137142564327,22120695,137164685022,1.59 days,22.12 secs,1.59 days 22 | -------------------------------------------------------------------------------- /experiments/threshsig/redraw-blogpost.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | scriptdir=$(cd $(dirname $0); pwd -P) 5 | 6 | plot_cmd=$scriptdir/../../scripts/linux/plot-threshsig.py 7 | 8 | rm -f $scriptdir/thresh.png 9 | $plot_cmd $scriptdir/bls-thresh-naive.png 0 0 0 $scriptdir/*naive*.csv 10 | $plot_cmd $scriptdir/bls-thresh-eff.png 0 0 0 $scriptdir/*naive*.csv $scriptdir/*efficient*.csv 11 | -------------------------------------------------------------------------------- /experiments/threshsig/redraw.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | scriptdir=$(cd $(dirname $0); pwd -P) 5 | 6 | plot_cmd=$scriptdir/../../scripts/linux/plot-threshsig.py 7 | 8 | rm -f $scriptdir/thresh.png 9 | $plot_cmd $scriptdir/thresh.png 0 0 1 $scriptdir/*naive*.csv $scriptdir/*efficient*.csv 10 | #$plot_cmd $scriptdir/thresh-nodetail-naive.png 0 0 0 $scriptdir/*naive*.csv 11 | #$plot_cmd $scriptdir/thresh-nodetail-naive+eff.png 0 0 0 $scriptdir/*naive*.csv $scriptdir/*efficient*.csv 12 | -------------------------------------------------------------------------------- /experiments/threshsig/run-experiments.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $# -lt 2 ]; then 4 | echo "Runs the threshold signature benchmark for the specified scheme with thresholds f+1 = 2^k, k \\in {1, 2, 3, ..., 20} and n = 2f+1" 5 | echo 6 | echo "Usage: $0 " 7 | echo 8 | echo "OPTIONS:" 9 | echo " can be either 'naive' or 'efficient'" 10 | exit 1 11 | fi 12 | 13 | date=`date +%Y-%m-%d` # %H-%M-%S if you want hours, minutes & seconds 14 | machine=$1 15 | scheme=$2 16 | multicore=0 17 | 18 | if [ $scheme = "naive" ]; then 19 | isEff=0 20 | elif [ $scheme = "efficient" ]; then 21 | isEff=1 22 | else 23 | echo "ERROR: must be either 'naive' or 'efficient'" 24 | exit 1 25 | fi 26 | 27 | 28 | which BenchThresholdSig 2>&1 >/dev/null || { echo "ERROR: You did not set up the environment"; exit 1; } 29 | # Format: 30 | benchmarks="\ 31 | 2 256 100 naive 32 | 512 4096 10 naive 33 | 8192 16384 10 naive 34 | 32768 32768 8 naive 35 | 65536 65536 4 naive 36 | 131072 131072 2 naive 37 | 262144 262144 1 naive 38 | 524288 524288 1 naive 39 | 1048576 1048576 1 naive 40 | 2 256 100 efficient 41 | 512 1048576 10 efficient 42 | " 43 | 44 | files= 45 | numFiles=0 46 | t1min=$((1048576*1024)) 47 | t2max=0 48 | while read -r b; do 49 | t1=`echo $b | cut -d' ' -f 1` 50 | t2=`echo $b | cut -d' ' -f 2` 51 | numDealIters=`echo $b | cut -d' ' -f 3` 52 | sch=`echo $b | cut -d' ' -f 4` 53 | 54 | if [ "$sch" != "$scheme" ]; then 55 | continue 56 | fi 57 | 58 | echo "Running t \\in $t1 to $t2 $vss threshold sigs with $numDealIters iters" 59 | 60 | [ $t1 -lt $t1min ] && t1min=$t1 61 | [ $t2 -gt $t2max ] && t2max=$t2 62 | 63 | file=${date}-${sch}-threshsig-${t1}-${t2}-${machine}.csv 64 | logfile=${date}-${sch}-threshsig-${t1}-${t2}-${machine}.log 65 | echo "Logging to $logfile ..." 66 | if [ $multicore -eq 1 ]; then 67 | BenchThresholdSig $isEff $t1 $t2 $numDealIters $file 2>&1 >$logfile & 68 | sleep 1 69 | else 70 | BenchThresholdSig $isEff $t1 $t2 $numDealIters $file 2>&1 | tee -a $logfile 71 | fi 72 | 73 | files="$files $file" 74 | logfiles="$logfiles $logfile" 75 | numFiles=$(($numFiles + 1)) 76 | done <<< "$benchmarks" 77 | 78 | if [ $multicore -eq 1 ]; then 79 | echo "Waiting for them to finish..." 80 | wait 81 | fi 82 | 83 | extra_date=`date +%H-%M-%S` 84 | 85 | echo 86 | 87 | if [ $numFiles -gt 1 ]; then 88 | # initially, no hours/minutes/seconds 89 | merged_file=${date}-${scheme}-threshsig-${t1min}-${t2max}-${machine}.csv 90 | new_logfile=${date}-${scheme}-threshsig-${t1min}-${t2max}-${machine}.log 91 | while [ -f "$merged_file" -o -f "$new_logfile" ]; do 92 | # but if file name clashes, add hours/minutes/seconds 93 | extra_date=`date +%H-%M-%S` 94 | merged_file=${date}-${extra_date}-${scheme}-threshsig-${t1min}-${t2max}-${machine}.csv 95 | new_logfile=${date}-${extra_date}-${scheme}-threshsig-${t1min}-${t2max}-${machine}.log 96 | done 97 | 98 | cat $logfiles >"$new_logfile" 99 | cat $files >$merged_file 100 | 101 | rm $files 102 | 103 | echo "Merged files: " 104 | echo 105 | for f in $files; do echo " $f"; done 106 | echo 107 | echo "...into: " 108 | echo 109 | echo " $merged_file" 110 | echo 111 | fi 112 | -------------------------------------------------------------------------------- /experiments/vss/.gitignore: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinush/libpolycrypto/89a69ed90ee4e9287222cc5781ff11562286f454/experiments/vss/.gitignore -------------------------------------------------------------------------------- /experiments/vss/amt.csv: -------------------------------------------------------------------------------- 1 | t,n,vss,build,num_deal_iters,num_verify_iters,num_reconstr_iters,avg_deal_usec,avg_verify_usec,avg_reconstr_bc_usec,avg_reconstr_wc_usec,avg_deal_hum,avg_verify_hum,avg_reconstr_bc_hum,avg_reconstr_wc_hum,stddev_deal,stddev_verify,stddev_reconstr_bc,stddev_reconstr_wc,vms_hum,rss_hum,num_real_players 2 | 2,3,amt,release,100,1000,100,987,2073,4803,7654,987.00 mus,2.07 ms,4.80 ms,7.65 ms,12.569531,60.27984,33.173994,26.409385,26.25 MiB,5.61 MiB,3 3 | 4,7,amt,release,100,1000,100,3562,3003,11628,21081,3.56 ms,3.00 ms,11.63 ms,21.08 ms,21.611515,296.569445,517.836091,431.625087,26.25 MiB,5.61 MiB,7 4 | 8,15,amt,release,100,1000,100,9081,3929,27315,56183,9.08 ms,3.93 ms,27.32 ms,56.18 ms,41.503469,383.453116,3338.064552,6897.94169,26.40 MiB,5.61 MiB,15 5 | 16,31,amt,release,100,1000,100,23061,4856,54545,126366,23.06 ms,4.86 ms,54.55 ms,126.37 ms,3544.444966,291.608162,2585.166104,5067.391131,26.53 MiB,5.98 MiB,31 6 | 32,63,amt,release,100,1000,100,45962,5779,115380,297259,45.96 ms,5.78 ms,115.38 ms,297.26 ms,100.824467,521.286998,10742.700882,25113.864901,27.43 MiB,7.01 MiB,63 7 | 64,127,amt,release,100,1000,100,99535,6708,233056,662277,99.53 ms,6.71 ms,233.06 ms,662.28 ms,226.669438,105.950635,2554.661439,3066.468099,29.85 MiB,9.24 MiB,100 8 | 128,255,amt,release,100,1000,100,219312,7629,469164,1454733,219.31 ms,7.63 ms,469.16 ms,1.45 secs,217.182973,10.681189,3758.997017,4099.383155,32.95 MiB,13.04 MiB,100 9 | 256,511,amt,release,100,1000,100,461691,8557,941438,3166540,461.69 ms,8.56 ms,941.44 ms,3.17 secs,387.941544,9.234076,5421.053641,5371.132416,39.14 MiB,19.23 MiB,100 10 | 512,1023,amt,release,100,1000,100,963937,9479,1887600,6833629,963.94 ms,9.48 ms,1.89 secs,6.83 secs,735.649554,9.193392,6861.331409,8337.87832,51.55 MiB,31.64 MiB,100 11 | 1024,2047,amt,release,100,1000,10,2172173,10404,4067340,15752505,2.17 secs,10.40 ms,4.07 secs,15.75 secs,77589.617831,1492.343488,120607.218393,243156.64672,80.61 MiB,60.34 MiB,100 12 | 2048,4095,amt,release,100,1000,10,4622650,11327,8301247,34391220,4.62 secs,11.33 ms,8.30 secs,34.39 secs,168236.425935,1557.183063,180264.935257,165022.377715,130.88 MiB,111.05 MiB,100 13 | 4096,8191,amt,release,100,1000,10,9548806,12259,16677503,73451411,9.55 secs,12.26 ms,16.68 secs,1.22 mins,253657.09913,1952.434557,261153.050152,321945.372435,231.28 MiB,211.45 MiB,100 14 | 8192,16383,amt,release,50,1000,10,18284396,13185,33186394,153924684,18.28 secs,13.19 ms,33.19 secs,2.57 mins,595506.176772,1881.4112,304848.349237,546087.759819,249.35 MiB,228.98 MiB,50 15 | 16384,32767,amt,release,22,1000,4,36145147,14104,61326297,300498150,36.15 secs,14.10 ms,1.02 mins,5.01 mins,28310.29352,331.959048,252044.877437,1180156.122893,265.73 MiB,245.45 MiB,22 16 | 32768,65535,amt,release,10,1000,2,74274854,15028,121848980,627796492,1.24 mins,15.03 ms,2.03 mins,10.46 mins,368943.001602,12.361052,59598,34665,331.71 MiB,311.35 MiB,10 17 | 65536,131071,amt,release,5,1000,1,187342908,15957,244359637,1319530821,3.12 mins,15.96 ms,4.07 mins,21.99 mins,28553237.369637,12.019191,nan,nan,499.69 MiB,479.39 MiB,5 18 | 131072,262143,amt,release,3,1000,1,312371382,16887,503389130,2834244933,5.21 mins,16.89 ms,8.39 mins,47.24 mins,1322569.135975,8.896601,nan,nan,877.74 MiB,857.41 MiB,3 19 | 262144,524287,amt,release,2,1000,1,618165909,17811,999613197,6448431946,10.30 mins,17.81 ms,16.66 mins,1.79 hrs,850382.5,249.108565,nan,nan,1.62 GiB,1.60 GiB,2 20 | 524288,1048575,amt,release,1,1000,1,1264185446,18734,1940110959,12625322404,21.07 mins,18.73 ms,32.34 mins,3.51 hrs,nan,573.457635,nan,nan,2.15 GiB,2.13 GiB,1 21 | 1048576,2097151,amt,release,1,1000,1,2529287337,19849,3844925261,24550148478,42.15 mins,19.85 ms,1.07 hrs,6.82 hrs,nan,213.462733,nan,nan,4.28 GiB,4.26 GiB,1 22 | -------------------------------------------------------------------------------- /experiments/vss/feld.csv: -------------------------------------------------------------------------------- 1 | t,n,vss,build,num_deal_iters,num_verify_iters,num_reconstr_iters,avg_deal_usec,avg_verify_usec,avg_reconstr_bc_usec,avg_reconstr_wc_usec,avg_deal_hum,avg_verify_hum,avg_reconstr_bc_hum,avg_reconstr_wc_hum,stddev_deal,stddev_verify,stddev_reconstr_bc,stddev_reconstr_wc,vms_hum,rss_hum,num_real_players 2 | 2,3,feld,release,100,1000,1000,711,364.666666667,252,1094,711.00 mus,364.00 mus,252.00 mus,1.09 ms,19.037571,249.040646,20.399266,86.385683,25.51 MiB,4.26 MiB,3 3 | 4,7,feld,release,100,1000,1000,1026,628.714285714,258,4401,1.03 ms,628.00 mus,258.00 mus,4.40 ms,17.608098,266.280774,9.137422,28.970722,25.51 MiB,4.26 MiB,7 4 | 8,15,feld,release,100,1000,1000,2051,797.266666667,278,11959,2.05 ms,797.00 mus,278.00 mus,11.96 ms,31.907195,300.562976,11.161128,30.000415,25.51 MiB,4.26 MiB,15 5 | 16,31,feld,release,100,1000,1000,4104,1138,323,35278,4.10 ms,1.14 ms,323.00 mus,35.28 ms,38.61742,405.148192,9.81902,70.190575,25.63 MiB,5.32 MiB,31 6 | 32,63,feld,release,100,1000,200,8200,1792.52380952,454,112929,8.20 ms,1.79 ms,454.00 mus,112.93 ms,58.682379,655.510344,7.880722,72.667514,26.14 MiB,5.61 MiB,63 7 | 64,127,feld,release,100,1000,50,16384,2945.95275591,910,374136,16.38 ms,2.94 ms,910.00 mus,374.14 ms,89.501228,1107.34576,9.799367,102.104278,27.60 MiB,7.34 MiB,100 8 | 128,255,feld,release,100,1000,25,32671,5024.98823529,1645,1281372,32.67 ms,5.02 ms,1.65 ms,1.28 secs,129.230575,1964.935771,7.172615,117604.71687,29.36 MiB,9.12 MiB,100 9 | 256,511,feld,release,100,1000,10,65990,8474.05675147,3225,4330243,65.99 ms,8.47 ms,3.23 ms,4.33 secs,666.718082,3570.732282,6.321392,18294.078494,32.96 MiB,12.87 MiB,100 10 | 512,1023,feld,release,100,1000,10,131413,14878.4193548,6582,15220623,131.41 ms,14.88 ms,6.58 ms,15.22 secs,1847.896332,6500.019507,9.914131,1954.340884,40.14 MiB,20.18 MiB,100 11 | 1024,2047,feld,release,50,1000,5,262852,26892.9223254,13585,55049812,262.85 ms,26.89 ms,13.59 ms,55.05 secs,377.618802,12086.396221,152.221713,27650.694005,40.33 MiB,20.41 MiB,50 12 | 2048,4095,feld,release,20,500,2,683707,63257.6742369,28807,259040176,683.71 ms,63.26 ms,28.81 ms,4.32 mins,38892.333575,30721.678861,210.574001,667339,38.38 MiB,18.21 MiB,20 13 | 4096,8191,feld,release,20,250,2,1051061,91835.764986,60008,752226751,1.05 secs,91.83 ms,60.01 ms,12.54 mins,765.105842,43631.183458,720.67483,1159981,50.84 MiB,30.73 MiB,20 14 | 8192,16383,feld,release,10,120,2,2102824,171134.641213,126440,2803698827,2.10 secs,171.13 ms,126.44 ms,46.73 mins,1085.73098,86005.887064,634.12125,463221.5,53.07 MiB,33.09 MiB,10 15 | 16384,32767,feld,release,10,60,1,4230564,325531.425489,266547,10666688219,4.23 secs,325.53 ms,266.55 ms,2.96 hrs,18577.072139,161458.179057,824.137877,na,80.25 MiB,60.05 MiB,10 16 | 32768,65535,feld,release,10,30,0,8459022,569671.301846,565439,37333408766.5,8.46 secs,569.67 ms,565.44 ms,10.37 hrs,3482.047847,270426.550982,1792.784482,na,117.71 MiB,97.46 MiB,10 17 | 65536,131071,feld,release,10,15,0,17362468,996917.172241,1211522,130666930683,17.36 secs,996.92 ms,1.21 secs,1.51 days,782976.811717,668272.987008,4825.504115,na,209.71 MiB,189.38 MiB,10 18 | 131072,262143,feld,release,5,10,0,33958228,1744598.39626,2585132,457334257390,33.96 secs,1.74 secs,2.59 secs,5.29 days,3877.003606,1266530.35009,8409.261599,na,213.64 MiB,193.34 MiB,5 19 | 262144,524287,feld,release,3,10,0,67741482,3053041.37021,5635568,1600669900860,1.13 mins,3.05 secs,5.64 secs,18.53 days,42967.000456,2930643.78209,367964.265927,na,257.62 MiB,237.30 MiB,3 20 | 524288,1048575,feld,release,3,8,0,135721500,5342817.30255,11784576,5602344653020,2.26 mins,5.34 secs,11.78 secs,64.84 days,285731.475626,4767141.87121,50709.220002,na,489.62 MiB,469.38 MiB,3 21 | 1048576,2097151,feld,release,2,5,0,271510203,9349925.82107,24712133,19608206285600,4.53 mins,9.35 secs,24.71 secs,226.95 days,5378,10344858.108,75107.605953,na,671.62 MiB,651.28 MiB,2 22 | -------------------------------------------------------------------------------- /experiments/vss/kate.csv: -------------------------------------------------------------------------------- 1 | t,n,vss,build,num_deal_iters,num_verify_iters,num_reconstr_iters,avg_deal_usec,avg_verify_usec,avg_reconstr_bc_usec,avg_reconstr_wc_usec,avg_deal_hum,avg_verify_hum,avg_reconstr_bc_hum,avg_reconstr_wc_hum,stddev_deal,stddev_verify,stddev_reconstr_bc,stddev_reconstr_wc,vms_hum,rss_hum,num_real_players 2 | 2,3,kate,release,10,1000,1000,989,2193,4903,6863,989.00 mus,2.19 ms,4.90 ms,6.86 ms,15.4211,254.997885,351.627259,483.598889,25.62 MiB,4.27 MiB,3 3 | 4,7,kate,release,10,1000,1000,4690,2107,9002,15019,4.69 ms,2.11 ms,9.00 ms,15.02 ms,297.747,106.311779,825.582608,1347.859917,25.62 MiB,4.27 MiB,7 4 | 8,15,kate,release,10,1000,1000,12673,2086,17501,31891,12.67 ms,2.09 ms,17.50 ms,31.89 ms,197.596,13.696351,1718.429225,3013.210512,25.62 MiB,5.44 MiB,15 5 | 16,31,kate,release,10,1000,1000,39858,2158,35150,67079,39.86 ms,2.16 ms,35.15 ms,67.08 ms,303.2,51.986234,3972.557339,7083.840119,25.75 MiB,5.44 MiB,31 6 | 32,63,kate,release,10,1000,1000,133331,2248,74987,146402,133.33 ms,2.25 ms,74.99 ms,146.40 ms,1627.22,245.984154,9930.616165,17797.064188,26.25 MiB,6.02 MiB,63 7 | 64,127,kate,release,10,1000,500,457742,2154,129510,255419,457.74 ms,2.15 ms,129.51 ms,255.42 ms,5437.99,8.916361,166.681771,201.751038,27.70 MiB,7.24 MiB,100 8 | 128,255,kate,release,10,1000,250,1602352,2153,258851,513286,1.60 secs,2.15 ms,258.85 ms,513.29 ms,5729.03,9.169153,292.193506,438.624752,29.65 MiB,9.69 MiB,100 9 | 256,511,kate,release,10,1000,120,5697629,2146,509889,1014445,5.70 secs,2.15 ms,509.89 ms,1.01 secs,8482.97,43.088887,18977.929608,35299.079512,26.96 MiB,6.86 MiB,10 10 | 512,1023,kate,release,10,1000,60,20627145,2150,1033994,2058707,20.63 secs,2.15 ms,1.03 secs,2.06 secs,24211,8.412602,421.156562,436.36419,28.15 MiB,8.28 MiB,10 11 | 1024,2047,kate,release,10,1000,30,75465111,2238,2148827,4280221,1.26 mins,2.24 ms,2.15 secs,4.28 secs,855219,232.341117,59736.834201,112196.690034,30.55 MiB,10.70 MiB,10 12 | 2048,4095,kate,release,3,1000,15,278784385,2161,4188740,8248766,4.65 mins,2.16 ms,4.19 secs,8.25 secs,791791,8.375737,181701.597284,1256.019611,35.50 MiB,15.59 MiB,10 13 | 4096,8191,kate,release,2,1000,10,1045012136,2360,9052471,17928955,17.42 mins,2.36 ms,9.05 secs,17.93 secs,543713,335.406824,339645.517699,430384.209342,45.33 MiB,25.32 MiB,10 14 | 8192,16383,kate,release,2,1000,10,3883646013,2135,16249037,32371350,1.08 hrs,2.13 ms,16.25 secs,32.37 secs,4323540,31.372,107420.919157,157327.258782,64.62 MiB,44.73 MiB,10 15 | 16384,32767,kate,release,1,1000,10,14707293637,2165,33141046,66001921,4.09 hrs,2.17 ms,33.14 secs,1.10 mins,na,10.415322,3254.892823,3871.926967,123.65 MiB,103.54 MiB,10 16 | 32768,65535,kate,release,1,1000,10,54416986456,2159,66317613,132043844,15.12 hrs,2.16 ms,1.11 mins,2.20 mins,na,8.511404,4360.953255,5544.718244,181.32 MiB,161.29 MiB,10 17 | 65536,131071,kate,release,0,1000,10,190459452596,2154,132839398,264437466,2.20 days,2.15 ms,2.21 mins,4.41 mins,na,9.119942,5779.929744,13855.558915,336.87 MiB,316.94 MiB,10 18 | 131072,262143,kate,release,0,1000,8,666608084086,2153,266585454,530500613,7.72 days,2.15 ms,4.44 mins,8.84 mins,na,13.085102,10166.289881,43919.0234,467.88 MiB,447.83 MiB,5 19 | 262144,524287,kate,release,0,1000,4,2333128294301,2144,674160675,1352655059,27.00 days,2.14 ms,11.24 mins,22.54 mins,na,9.052645,10882029.230189,23827183.67437,750.00 MiB,729.74 MiB,3 20 | 524288,1048575,kate,release,0,1000,2,8165949030053.5,2088,1337918089,2658970157,94.51 days,2.09 ms,22.30 mins,44.32 mins,na,12.198351,638069.5,255899.5,1.39 GiB,1.37 GiB,3 21 | 1048576,2097151,kate,release,0,1000,1,28580821605187.2,2075,2052039062,4078307947,330.80 days,2.08 ms,34.20 mins,1.13 hrs,na,5.52507,na,na,2.41 GiB,2.39 GiB,2 22 | -------------------------------------------------------------------------------- /experiments/vss/redraw.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | set -e 3 | 4 | scriptdir=$(cd $(dirname $0); pwd -P) 5 | 6 | plot_cmd=$scriptdir/../../scripts/linux/plot-vss-times.py 7 | 8 | rm -f $scriptdir/*.png 9 | 10 | #$plot_cmd \ 11 | # "-evss-only" 2 0 \ 12 | # $scriptdir/kate.csv 13 | 14 | ( 15 | cd $scriptdir; 16 | $plot_cmd \ 17 | "" 2 0 \ 18 | kate.csv \ 19 | amt.csv \ 20 | ) 21 | 22 | #$plot_cmd \ 23 | # "-with-feld" 31 0 \ 24 | # $scriptdir/kate.csv \ 25 | # $scriptdir/amt.csv \ 26 | # $scriptdir/feld.csv \ 27 | -------------------------------------------------------------------------------- /experiments/vss/run-experiments.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | if [ $# -lt 2 ]; then 6 | echo "Runs the VSS benchmark for the specified VSS(s) with thresholds f+1 = {2, 4, 8, 16, ..., 32768} and n = 2f+1" 7 | echo 8 | echo "Usage: $0 " 9 | echo 10 | echo "OPTIONS:" 11 | echo " can be either 'feld', 'kate' or 'amt'" 12 | exit 1 13 | fi 14 | 15 | scriptdir=$(cd $(dirname $0); pwd -P) 16 | date=`date +%Y-%m-%d` 17 | logfile=`mktemp` 18 | machine=$1 19 | vss_type=$2 20 | 21 | which BenchVSS || { echo "ERROR: You did not set up the environment"; exit 1; } 22 | 23 | if [ "$vss_type" = "feld" ]; then 24 | pp_file="/dev/null" 25 | elif [ "$vss_type" = "kate" ]; then 26 | pp_file=$scriptdir/../../public-params/1048576/1048576 27 | elif [ "$vss_type" = "kate-sim" ]; then 28 | pp_file=$scriptdir/../../public-params/1048576/1048576 29 | elif [ "$vss_type" = "amt" ]; then 30 | pp_file=$scriptdir/../../public-params/1048576/1048576 31 | else 32 | echo "ERROR: Unknown VSS type '$vss_type'" 33 | exit 1 34 | fi 35 | 36 | # Format: 37 | 38 | # NOTE: Feldman VSS needs more players created to get a good average of the verification time 39 | feld_benchmarks="\ 40 | 2 16 100 1000 1000 feld 41 | 32 32 100 1000 200 feld 42 | 64 64 100 1000 50 feld 43 | 128 128 100 1000 25 feld 44 | 256 256 100 1000 10 feld 45 | 512 512 100 1000 10 feld 46 | 1024 1024 50 1000 5 feld 47 | 2048 2048 20 500 2 feld 48 | 4096 4096 20 250 2 feld 49 | 8192 8192 10 120 2 feld 50 | 16384 16384 10 60 1 feld 51 | 32768 32768 10 30 0 feld 52 | 65536 65536 10 15 0 feld 53 | 131072 131072 10 10 0 feld 54 | 262144 262144 10 10 0 feld 55 | 524288 524288 10 8 0 feld 56 | 1048576 1048576 10 5 0 feld 57 | " 58 | kate_benchmarks="\ 59 | 2 32 10 1000 1000 kate 60 | 64 64 10 1000 500 kate 61 | 128 128 10 1000 250 kate 62 | 256 256 10 1000 120 kate 63 | 512 512 10 1000 60 kate 64 | 1024 1024 10 1000 30 kate 65 | 2048 2048 3 1000 15 kate 66 | 4096 4096 2 1000 10 kate 67 | 8192 8192 2 1000 10 kate 68 | 16384 32768 1 1000 5 kate 69 | " 70 | kate_sim_benchmarks="\ 71 | 2 32 100 1000 1000 kate-sim 72 | 64 64 100 1000 500 kate-sim 73 | 128 128 100 1000 250 kate-sim 74 | 256 256 100 1000 120 kate-sim 75 | 512 512 10 1000 60 kate-sim 76 | 1024 1024 10 1000 30 kate-sim 77 | 2048 2048 10 1000 15 kate-sim 78 | 4096 4096 10 1000 10 kate-sim 79 | 8192 8192 10 1000 10 kate-sim 80 | 16384 32768 10 1000 10 kate-sim 81 | 65536 65536 10 1000 10 kate-sim 82 | 131072 131072 5 1000 8 kate-sim 83 | 262144 262144 3 1000 4 kate-sim 84 | 524288 524288 3 1000 2 kate-sim 85 | 1048576 1048576 2 1000 1 kate-sim 86 | " 87 | amt_benchmarks="\ 88 | 2 512 100 1000 100 amt 89 | 1024 4096 100 1000 10 amt 90 | 8192 8192 50 1000 10 amt 91 | 16384 16384 22 1000 4 amt 92 | 32768 32768 10 1000 2 amt 93 | 65536 65536 5 1000 1 amt 94 | 262144 262144 2 1000 1 amt 95 | 524288 524288 1 1000 1 amt 96 | 1048576 1048576 1 1000 1 amt 97 | " 98 | benchmarks="\ 99 | $amt_benchmarks 100 | $kate_benchmarks 101 | $kate_sim_benchmarks 102 | $feld_benchmarks 103 | " 104 | 105 | files= 106 | numFiles=0 107 | t1min=$((1048576*1024)) 108 | t2max=0 109 | while read -r b; do 110 | t1=`echo $b | cut -d' ' -f 1` 111 | t2=`echo $b | cut -d' ' -f 2` 112 | numDealIters=`echo $b | cut -d' ' -f 3` 113 | numVerIters=`echo $b | cut -d' ' -f 4` 114 | numReconstrIters=`echo $b | cut -d' ' -f 5` 115 | vss=`echo $b | cut -d' ' -f 6` 116 | 117 | if [ "$vss" != "$vss_type" ]; then 118 | continue 119 | fi 120 | 121 | echo "Running t \\in $t1 to $t2 $vss VSS with $numDealIters iters for dealing" 122 | 123 | [ $t1 -lt $t1min ] && t1min=$t1 124 | [ $t2 -gt $t2max ] && t2max=$t2 125 | 126 | file=${date}-${vss}-vss-${t1}-${t2}-${machine}.csv 127 | 128 | echo "Logging to $logfile ..." 129 | BenchVSS $pp_file $t1 $t2 $vss $numDealIters $numVerIters $numReconstrIters $file 2>&1 | tee -a $logfile 130 | 131 | files="$files $file" 132 | numFiles=$(($numFiles + 1)) 133 | done <<< "$benchmarks" 134 | 135 | extra_date=`date +%H-%M-%S` 136 | 137 | echo 138 | 139 | if [ $numFiles -gt 1 ]; then 140 | # initially, no hours/minutes/seconds 141 | merged_file=${date}-${vss_type}-vss-${t1min}-${t2max}-${machine}.csv 142 | new_logfile=${date}-${vss_type}-vss-${t1min}-${t2max}-${machine}.log 143 | while [ -f "$merged_file" -o -f "$new_logfile" ]; do 144 | # but if file name clashes, add hours/minutes/seconds 145 | extra_date=`date +%H-%M-%S` 146 | merged_file=${date}-${extra_date}-${vss_type}-vss-${t1min}-${t2max}-${machine}.csv 147 | new_logfile=${date}-${extra_date}-${vss_type}-vss-${t1min}-${t2max}-${machine}.log 148 | done 149 | 150 | mv "$logfile" "$new_logfile" 151 | 152 | cat $files >$merged_file 153 | rm $files 154 | 155 | echo "Merged files: " 156 | echo 157 | for f in $files; do echo " $f"; done 158 | echo 159 | echo "...into: " 160 | echo 161 | echo " $merged_file" 162 | echo 163 | fi 164 | -------------------------------------------------------------------------------- /libpolycrypto/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(src) 2 | add_subdirectory(examples) 3 | add_subdirectory(test) 4 | add_subdirectory(bench) 5 | add_subdirectory(app) 6 | -------------------------------------------------------------------------------- /libpolycrypto/app/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(polycrypto_app_sources 2 | BandwidthCalc.cpp 3 | ParamsGenTrapdoors.cpp 4 | ParamsGenPowers.cpp 5 | ParamsValidate.cpp 6 | PolylogDkg.cpp 7 | ) 8 | 9 | foreach(appSrc ${polycrypto_app_sources}) 10 | get_filename_component(appName ${appSrc} NAME_WE) 11 | set(appDir ../bin/app) 12 | 13 | add_executable(${appName} ${appSrc}) 14 | target_link_libraries(${appName} PUBLIC polycrypto) 15 | 16 | set_target_properties(${appName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${appDir}) 17 | endforeach() 18 | 19 | #install(TARGETS PlayApp DESTINATION bin) 20 | -------------------------------------------------------------------------------- /libpolycrypto/app/ParamsGenPowers.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | using namespace std; 7 | using namespace libpolycrypto; 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | libpolycrypto::initialize(nullptr, 0); 12 | 13 | if(argc < 5) { 14 | cout << "Usage: " << argv[0] << " " << endl; 15 | cout << endl; 16 | cout << "Reads 's' from and outputs q-SDH parameters (g_1^{s_i}) for i \\in [, ) to ." << endl; 17 | return 1; 18 | } 19 | 20 | string inFile(argv[1]); 21 | string outFile(argv[2]); 22 | size_t start = static_cast(std::stoi(argv[3])), 23 | end = static_cast(std::stoi(argv[4])); 24 | 25 | ifstream fin(inFile); 26 | 27 | if(fin.fail()) { 28 | throw std::runtime_error("Could not read trapdoors input file"); 29 | } 30 | 31 | Fr s; 32 | fin >> s; 33 | 34 | Dkg::KatePublicParameters::generate(start, end, s, outFile, true); 35 | 36 | 37 | loginfo << "All done!" << endl; 38 | 39 | return 0; 40 | } 41 | -------------------------------------------------------------------------------- /libpolycrypto/app/ParamsGenTrapdoors.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | 6 | using namespace std; 7 | using namespace libpolycrypto; 8 | 9 | int main(int argc, char *argv[]) 10 | { 11 | libpolycrypto::initialize(nullptr, 0); 12 | 13 | if(argc < 3) { 14 | cout << "Usage: " << argv[0] << " " << endl; 15 | cout << endl; 16 | cout << "Generates 's' and writes it and 'q' to " << endl; 17 | return 1; 18 | } 19 | 20 | string outFile(argv[1]); 21 | size_t q = static_cast(std::stoi(argv[2])); 22 | 23 | ofstream fout(outFile); 24 | 25 | if(fout.fail()) { 26 | std::cout << "ERROR: Could not open file: " << outFile << endl; 27 | throw std::runtime_error("Could not open trapdoor output file"); 28 | } 29 | 30 | Fr s = Fr::random_element(); 31 | fout << s << endl; 32 | fout << q << endl; 33 | 34 | loginfo << "All done!" << endl; 35 | 36 | return 0; 37 | } 38 | -------------------------------------------------------------------------------- /libpolycrypto/app/ParamsValidate.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | 7 | using namespace std; 8 | using namespace libpolycrypto; 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | libpolycrypto::initialize(nullptr, 0); 13 | 14 | if(argc < 2) { 15 | cout << "Usage: " << argv[0] << " " << endl; 16 | cout << endl; 17 | cout << "Reads 's', 'q' from and then reads the parameters from - for i = 0, 1, ..." << endl; 18 | return 1; 19 | } 20 | 21 | string inFile(argv[1]); 22 | 23 | Dkg::KatePublicParameters pp(inFile, 0, true, true); 24 | 25 | loginfo << "All done!" << endl; 26 | 27 | return 0; 28 | } 29 | -------------------------------------------------------------------------------- /libpolycrypto/bench/BenchAMT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | using namespace libfqfft; 18 | using namespace libpolycrypto; 19 | 20 | void logMemUsage() { 21 | size_t vms, rss; 22 | getMemUsage(vms, rss); 23 | logperf << "VMS: " << Utils::humanizeBytes(vms) << endl; 24 | logperf << "RSS: " << Utils::humanizeBytes(rss) << endl; 25 | logperf << endl; 26 | } 27 | 28 | int main(int argc, char *argv[]) { 29 | libpolycrypto::initialize(nullptr, 0); 30 | 31 | if(argc < 5) { 32 | cout << "Usage: " << argv[0] << " " << endl; 33 | cout << endl; 34 | cout << "OPTIONS: " << endl; 35 | cout << " the Kate public parameters file" << endl; 36 | cout << " the degree of the evaluated polynomial + 1" << endl; 37 | cout << " the # of points to evaluate at (i.e., # of AMT leaves)" << endl; 38 | cout << " the # of times to repeat the AMT auth + verif" << endl; 39 | cout << endl; 40 | 41 | return 1; 42 | } 43 | 44 | std::string ppFile = argv[1]; 45 | size_t t = static_cast(std::stoi(argv[2])); 46 | size_t n = static_cast(std::stoi(argv[3])); 47 | size_t r = static_cast(std::stoi(argv[4])); 48 | 49 | std::unique_ptr kpp( 50 | new Dkg::KatePublicParameters(ppFile, t-1)); 51 | loginfo << "Degree t = " << t - 1 << " poly, evaluated at n = " << n << " points, iters = " << r << endl; 52 | 53 | AveragingTimer at("Accum tree"); 54 | at.startLap(); 55 | AccumulatorTree accs(n); 56 | auto mus = at.endLap(); 57 | 58 | logperf << " - AccumulatorTree: " << Utils::humanizeMicroseconds(mus, 2) << endl; 59 | 60 | // NOTE: Uncomment this to see beautiful roots-of-unity structure 61 | //std::cout << "Accumulator tree for n = " << n << endl; 62 | //std::cout << accs.toString() << endl; 63 | 64 | std::vector f = random_field_elems(t); 65 | 66 | // Step 1: Fast multipoint eval 67 | AveragingTimer c1("Roots-of-unity eval "); 68 | c1.startLap(); 69 | RootsOfUnityEvaluation eval(f, accs); 70 | std::vector evals = eval.getEvaluations(); 71 | mus = c1.endLap(); 72 | 73 | logperf << " - Roots of unity eval: " << Utils::humanizeMicroseconds(mus, 2) << endl; 74 | 75 | // Step 2: Authenticate AccumulatorTree 76 | AveragingTimer aat("Auth accum tree"); 77 | aat.startLap(); 78 | AuthAccumulatorTree authAccs(accs, *kpp, t); 79 | mus = aat.endLap(); 80 | 81 | logperf << " - AuthAccumulatorTree: " << Utils::humanizeMicroseconds(mus, 2) << endl; 82 | 83 | // Step 3: Authenticate Multipoint Evaluation 84 | AveragingTimer ars("Auth roots-of-unity eval (simulated)"); 85 | for(size_t i = 0; i < r; i++) { 86 | ars.startLap(); 87 | AuthRootsOfUnityEvaluation authEval(eval, *kpp, true); 88 | mus = ars.endLap(); 89 | 90 | logperf << " - AuthRootsOfUnityEval simulated (iter " << i << "): " << Utils::humanizeMicroseconds(mus, 2) << endl; 91 | } 92 | 93 | AveragingTimer ar("Auth roots-of-unity eval"); 94 | for(size_t i = 0; i < r; i++) { 95 | ar.startLap(); 96 | AuthRootsOfUnityEvaluation authEval(eval, *kpp, false); 97 | mus = ar.endLap(); 98 | 99 | logperf << " - AuthRootsOfUnityEval (iter " << i << "): " << Utils::humanizeMicroseconds(mus, 2) << endl; 100 | } 101 | 102 | logperf << endl; 103 | logperf << at << endl; 104 | logperf << c1 << endl; 105 | logperf << aat << endl; 106 | logperf << ar << endl; 107 | logperf << ars << endl; 108 | logperf << endl; 109 | 110 | // Step 4: Verify AMT proofs (TODO: implement) 111 | 112 | loginfo << "Exited succsessfully!" << endl; 113 | 114 | return 0; 115 | } 116 | -------------------------------------------------------------------------------- /libpolycrypto/bench/BenchBatchVerification.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | #include 17 | 18 | using namespace libpolycrypto; 19 | using namespace std; 20 | using namespace libfqfft; 21 | 22 | int main() { 23 | 24 | libpolycrypto::initialize(nullptr, 0); 25 | 26 | size_t f = 100000; 27 | for (size_t invalidPercent = 0; invalidPercent <= 10; invalidPercent += 1) { 28 | size_t k, n; 29 | k = f, n = 2 * f; 30 | 31 | ManualTimer t1, t2; 32 | 33 | loginfo << "k = " << k << ", n = " << n << ", %invalid = " << invalidPercent << "%." << endl; 34 | 35 | G1 H = G1::random_element(); 36 | 37 | vector s, L; 38 | vector pkSigners; 39 | G2 pk; 40 | 41 | // generate public key pk and signer keys s 42 | t2.restart(); 43 | generate_keys(n, k, pk, s, &pkSigners); 44 | string gen_keys_usec = to_string(t2.restart().count()); 45 | //string gen_keys_usec = "N/A"; 46 | 47 | 48 | vector randset = random_subset(n, (100 - invalidPercent) * n / 100); 49 | // sigShare[i] = H(m)^s_i 50 | vector sigShare(n); 51 | t2.restart(); 52 | for (size_t i : randset) { 53 | sigShare[i] = shareSign(s[i], H); 54 | } 55 | string share_sign_total_usec = to_string(t2.restart().count()); 56 | 57 | // verify e(H(m)^s_i, g2) = e(H(m), g2^s_i) 58 | // naively verify one by one: 59 | t2.restart(); 60 | for (size_t i = 0; i < n; i++) { 61 | if (ReducedPairing(sigShare[i], G2::one()) == ReducedPairing(H, pkSigners[i])) { 62 | 63 | } 64 | } 65 | string naive_verify_usec = to_string(t2.restart().count()); 66 | 67 | t2.restart(); 68 | // batch verification: 69 | vector isValidShare = batch_ver(sigShare, pkSigners, H); 70 | string batch_verify_usec = to_string(t2.restart().count()); 71 | 72 | logperf << "naive_verify_usec: " << naive_verify_usec << endl; 73 | logperf << "batch_verify_usec: " << batch_verify_usec << endl << endl; 74 | } 75 | return 0; 76 | } 77 | -------------------------------------------------------------------------------- /libpolycrypto/bench/BenchConvertAndMultiexp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | #include 18 | 19 | #include 20 | 21 | using namespace std; 22 | using namespace libfqfft; 23 | using namespace libpolycrypto; 24 | 25 | int main() { 26 | initialize(nullptr, 0); 27 | std::vector bases; 28 | int count = 3, numBench = 0; 29 | double avgPctage = 0.0; 30 | size_t maxSize = 1024*128; 31 | 32 | loginfo << "Picking " << maxSize << " random G1 elements to bench multiexponentiation with..."; 33 | bases.resize(maxSize); 34 | for(size_t i = 0; i < bases.size(); i++) { 35 | bases[i] = G1::random_element(); 36 | } 37 | std::cout << endl; 38 | 39 | //for (size_t i = 1; i <= 1024*128; i *= 2) { 40 | for(size_t i = maxSize; i >= 1; i /= 2) { 41 | logperf << "poly degree = " << i-1 << ", iters = " << count 42 | << endl; 43 | numBench++; 44 | AveragingTimer conv, exp; 45 | 46 | ZZ_pX poly; 47 | std::vector ffpoly; 48 | 49 | bases.resize(i); 50 | 51 | for (int rep = 0; rep < count; rep++) { 52 | random(poly, static_cast(i)); 53 | 54 | conv.startLap(); 55 | //conv_zp_fr(poly, ffpoly); 56 | convNtlToLibff(poly, ffpoly); 57 | conv.endLap(); 58 | 59 | 60 | exp.startLap(); 61 | multiExp(bases, ffpoly); 62 | exp.endLap(); 63 | } 64 | 65 | auto avgConv = conv.averageLapTime(), avgExp = exp.averageLapTime(); 66 | double pctage = (double)avgConv/(double)(avgConv+avgExp)*100.0; 67 | logperf << " + Conv to libff: " << (double) avgConv / 1000000 << " seconds." << endl; 68 | logperf << " + Multiexp: " << (double) avgExp / 1000000 << " seconds." << endl; 69 | logperf << " + " << pctage << "% time spent converting" << endl; 70 | logperf << endl; 71 | 72 | avgPctage += pctage; 73 | } 74 | 75 | avgPctage /= numBench; 76 | 77 | logperf << endl; 78 | logperf << "On average, " << avgPctage << "% time spent converting" << endl; 79 | return 0; 80 | } 81 | -------------------------------------------------------------------------------- /libpolycrypto/bench/BenchExp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | using namespace libpolycrypto; 17 | 18 | int main(int argc, char *argv[]) { 19 | libpolycrypto::initialize(nullptr, 0); 20 | 21 | if(argc < 2) { 22 | cout << "Usage: " << argv[0] << " " << endl; 23 | cout << endl; 24 | cout << "OPTIONS: " << endl; 25 | cout << " the number of times to repeat the exponentiation" << endl; 26 | cout << endl; 27 | 28 | return 1; 29 | } 30 | 31 | size_t n = static_cast(std::stoi(argv[1])); 32 | 33 | loginfo << "Picking " << n << " random group elements..." << endl; 34 | auto a = random_group_elems(n); 35 | loginfo << "Picking " << n << " random field elements..." << endl; 36 | auto e = random_field_elems(n); 37 | 38 | loginfo << "Doing " << n << " exponentiations..." << endl; 39 | AveragingTimer tn("Exp"); 40 | G1 r; 41 | for(size_t i = 0; i < n; i++) { 42 | tn.startLap(); 43 | r = e[i]*a[i]; 44 | tn.endLap(); 45 | } 46 | 47 | logperf << tn << endl; 48 | 49 | logperf << "Total time: " << Utils::humanizeMicroseconds(tn.totalLapTime()) << endl; 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /libpolycrypto/bench/BenchFFT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace libpolycrypto; 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | (void)argc; (void)argv; 16 | 17 | libpolycrypto::initialize(nullptr, 0); 18 | 19 | size_t count = 10; 20 | if(argc < 3) { 21 | cout << "Usage: " << argv[0] << " []" << endl; 22 | cout << endl; 23 | cout << "Measures an FFT of size on poly of degree times." << endl; 24 | return 1; 25 | } 26 | 27 | size_t d = static_cast(std::stoi(argv[1])); 28 | size_t n = static_cast(std::stoi(argv[2])); 29 | if(argc > 3) 30 | count = static_cast(std::stoi(argv[3])); 31 | 32 | AveragingTimer 33 | df("FFT"); 34 | 35 | // Step 0: Pick random polynomial 36 | vector p = random_field_elems(d+1), vals; 37 | 38 | for(size_t i = 0; i < count; i++) { 39 | loginfo << "d = " << d << ", n = " << n << endl; 40 | 41 | // Step 1: Do an FFT 42 | vector q, r, rhs; 43 | df.startLap(); 44 | poly_fft(p, n, vals); 45 | df.endLap(); 46 | } 47 | 48 | logperf << df << endl; 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /libpolycrypto/bench/BenchMultiexp.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | using namespace std; 16 | 17 | using libpolycrypto::Fr; 18 | using libpolycrypto::G1; 19 | using libpolycrypto::random_group_elems; 20 | using libpolycrypto::random_field_elems; 21 | 22 | void benchAllRootsOfUnity(size_t n, size_t r) { 23 | if(n < 3) { 24 | logerror << "Need n bigger than 2" << endl; 25 | throw std::runtime_error("WTH"); 26 | } 27 | 28 | std::vector bases = random_group_elems(n); 29 | 30 | //size_t id = static_cast(rand()) % n; 31 | for(size_t id = 0; id < n; id++) { 32 | //loginfo << "Picking roots of unity exps for player #" << id << endl; 33 | std::string name = "Multiexp for #" + std::to_string(id); 34 | Fr wnid = libff::get_root_of_unity(1u << Utils::log2ceil(n)) ^ id; 35 | std::vector exp; 36 | exp.push_back(1); 37 | exp.push_back(wnid); 38 | for(size_t i = 0; i < n-2; i++) { 39 | exp.push_back(exp.back() * wnid); 40 | } 41 | 42 | //loginfo << " * picking random bases" << endl; 43 | 44 | AveragingTimer tn(name.c_str()); 45 | for(size_t i = 0; i < r; i++) { 46 | //loginfo << "Round #" << i+1 << endl; 47 | tn.startLap(); 48 | libpolycrypto::multiExp(bases, exp); 49 | tn.endLap(); 50 | } 51 | 52 | logperf << tn << endl; 53 | logperf << "Time per 1 exp: " << static_cast(tn.averageLapTime()) / static_cast(n) << " microseconds" << endl; 54 | } 55 | } 56 | 57 | int main(int argc, char *argv[]) { 58 | libpolycrypto::initialize(nullptr, 0); 59 | srand(static_cast(time(nullptr))); 60 | 61 | if(argc < 3) { 62 | cout << "Usage: " << argv[0] << " " << endl; 63 | cout << endl; 64 | cout << "OPTIONS: " << endl; 65 | cout << " the number of exponentiations to do in a single multiexp" << endl; 66 | cout << " the number of times to repeat the multiexps" << endl; 67 | cout << endl; 68 | 69 | return 1; 70 | } 71 | 72 | size_t n = static_cast(std::stoi(argv[1])); 73 | size_t r = static_cast(std::stoi(argv[2])); 74 | 75 | loginfo << "Picking " << n << " random exponents (only once)" << endl; 76 | std::vector exp = random_field_elems(n); 77 | 78 | //loginfo << "Picking all " << n << " " << n << "th roots of unity as the exponents (only once)" << endl; 79 | //exp = libpolycrypto::get_all_roots_of_unity(Utils::log2ceil(n)); 80 | //exp.resize(n); 81 | 82 | //int id = 14; 83 | //exp.push_back(id); 84 | //for(size_t i = 0; i < n-1; i++) { 85 | // exp.push_back(exp.back() * Fr(id)); 86 | //} 87 | std::vector bases = random_group_elems(n); 88 | 89 | AveragingTimer tn("Multiexp rand base & exp"); 90 | for(size_t i = 0; i < r; i++) { 91 | //loginfo << "Round #" << i+1 << endl; 92 | tn.startLap(); 93 | libpolycrypto::multiExp(bases, exp); 94 | tn.endLap(); 95 | } 96 | 97 | logperf << tn << endl; 98 | logperf << "Time per 1 exp: " << static_cast(tn.averageLapTime()) / static_cast(n) << " microseconds" << endl; 99 | 100 | return 0; 101 | } 102 | -------------------------------------------------------------------------------- /libpolycrypto/bench/BenchNizkPok.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | #include 8 | #include 9 | 10 | #include 11 | #include 12 | #include 13 | 14 | using namespace std; 15 | 16 | using libpolycrypto::Fr; 17 | using libpolycrypto::G1; 18 | using libpolycrypto::NizkPok; 19 | 20 | int main(int argc, char *argv[]) { 21 | libpolycrypto::initialize(nullptr, 0); 22 | 23 | if(argc > 1 && (strcmp(argv[1], "-h") == 0 || strcmp(argv[1], "--help") == 0)) { 24 | cout << "Usage: " << argv[0] << " []" << endl; 25 | cout << endl; 26 | cout << "OPTIONS: " << endl; 27 | cout << " the number of times to repeat the measurements" << endl; 28 | cout << endl; 29 | 30 | return 1; 31 | } 32 | 33 | int r = 500; 34 | if(argc > 1) 35 | r = std::stoi(argv[1]); 36 | 37 | AveragingTimer tp("NIZK prove (diff x) "), tv("NIZK verify (diff pi) "); 38 | for(int i = 0; i < r; i++) { 39 | Fr x = Fr::random_element(); 40 | G1 gToX = x*G1::one(); 41 | 42 | tp.startLap(); 43 | auto pi = NizkPok::prove(G1::one(), x, gToX); 44 | tp.endLap(); 45 | 46 | tv.startLap(); 47 | testAssertTrue(NizkPok::verify(pi, G1::one(), gToX)); 48 | tv.endLap(); 49 | } 50 | 51 | logperf << tp << endl; 52 | logperf << tv << endl; 53 | 54 | AveragingTimer tps("NIZK prove (same x) "), tvs("NIZK verify (same pi)"); 55 | Fr x = Fr::random_element(); 56 | G1 gToX = x*G1::one(); 57 | NizkPok pi; 58 | for(int i = 0; i < r; i++) { 59 | tps.startLap(); 60 | pi = NizkPok::prove(G1::one(), x, gToX); 61 | tps.endLap(); 62 | } 63 | 64 | for(int i = 0; i < r; i++) { 65 | tvs.startLap(); 66 | testAssertTrue(NizkPok::verify(pi, G1::one(), gToX)); 67 | tvs.endLap(); 68 | } 69 | 70 | logperf << tps << endl; 71 | logperf << tvs << endl; 72 | 73 | return 0; 74 | } 75 | -------------------------------------------------------------------------------- /libpolycrypto/bench/BenchNtlConversion.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace NTL; 14 | using namespace std; 15 | using namespace libpolycrypto; 16 | 17 | int main() 18 | { 19 | initialize(nullptr, 0); 20 | 21 | // degree bound 22 | size_t sz = 1024*512; 23 | 24 | std::vector fr1, fr2; 25 | ZZ_pX zp, zp2; 26 | 27 | loginfo << "Picking random ZZ_pX... "; 28 | NTL::random(zp, static_cast(sz)); 29 | cout << "done." << endl; 30 | 31 | ManualTimer t1; 32 | 33 | t1.restart(); 34 | convNtlToLibff_slow(zp, fr1); 35 | auto delta = t1.stop().count(); 36 | logperf << sz << " NTL to libff conversions (slow; w/ stringstream): " << delta/1000 << " millisecs" << endl; 37 | 38 | t1.restart(); 39 | convNtlToLibff(zp, fr2); 40 | delta = t1.stop().count(); 41 | logperf << sz << " NTL to libff conversions (fast; w/ byte array): " << delta/1000 << " millisecs" << endl; 42 | 43 | t1.restart(); 44 | convLibffToNtl_slow(fr2, zp2); 45 | delta = t1.stop().count(); 46 | logperf << sz << " libff to NTL conversions: " << delta/1000 << " millisecs" << endl; 47 | 48 | if(fr1 != fr2) { 49 | logerror << "Our two implementation for converting from NTL to libff disagree" << endl; 50 | return 1; 51 | } 52 | 53 | if(zp != zp2) { 54 | logerror << "Converting from libff to NTL (slow; with byte array) failed" << endl; 55 | return 1; 56 | } 57 | 58 | //loginfo << "libff recovered polys: " << endl; 59 | //poly_print(std::cout, fr); 60 | //poly_print(std::cout, fr2); 61 | //poly_print(std::cout, fr3); 62 | 63 | loginfo << "All done!" << endl; 64 | 65 | return 0; 66 | } 67 | -------------------------------------------------------------------------------- /libpolycrypto/bench/BenchPairing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | #include 10 | #include 11 | #include 12 | 13 | using namespace std; 14 | 15 | using libpolycrypto::Fr; 16 | using libpolycrypto::G1; 17 | using libpolycrypto::G2; 18 | 19 | int main(int argc, char *argv[]) { 20 | libpolycrypto::initialize(nullptr, 0); 21 | 22 | if(argc < 2) { 23 | cout << "Usage: " << argv[0] << " " << endl; 24 | cout << endl; 25 | cout << "OPTIONS: " << endl; 26 | cout << " the number of times to repeat the pairing computation" << endl; 27 | cout << endl; 28 | 29 | return 1; 30 | } 31 | 32 | int n = std::stoi(argv[1]); 33 | 34 | G1 a = G1::random_element(); 35 | G2 b = G2::random_element(); 36 | 37 | AveragingTimer tn("Same a, b"); 38 | for(int i = 0; i < n; i++) { 39 | tn.startLap(); 40 | libpolycrypto::ReducedPairing(a, b); 41 | tn.endLap(); 42 | } 43 | 44 | logperf << tn << endl; 45 | 46 | AveragingTimer td("Different a, b"); 47 | for(int i = 0; i < n; i++) { 48 | G1 x = G1::random_element(); 49 | G2 y = G2::random_element(); 50 | td.startLap(); 51 | libpolycrypto::ReducedPairing(x, y); 52 | td.endLap(); 53 | } 54 | 55 | logperf << td << endl; 56 | 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /libpolycrypto/bench/BenchPolyDivideXnc.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace libpolycrypto; 12 | 13 | int main(int argc, char *argv[]) 14 | { 15 | (void)argc; (void)argv; 16 | 17 | libpolycrypto::initialize(nullptr, 0); 18 | 19 | size_t count = 10; 20 | if(argc < 3) { 21 | cout << "Usage: " << argv[0] << " []" << endl; 22 | cout << endl; 23 | cout << "Divides random poly a(x) (of deg n) by b(x) = x^m - c (of deg m) = " << count << " times." << endl; 24 | cout << "Measures how fast the optimized algorithm is relative to a naive one." << endl; 25 | return 1; 26 | } 27 | 28 | size_t n = static_cast(std::stoi(argv[1])); 29 | size_t m = static_cast(std::stoi(argv[2])); 30 | if(argc > 3) 31 | count = static_cast(std::stoi(argv[3])); 32 | 33 | loginfo << "Dividing a (of deg n) by b (of deg m) " << count << " times..." << endl << endl; 34 | 35 | AveragingTimer 36 | df("O(n) division "), 37 | dn("O(n log n) division"); 38 | for(size_t i = 0; i < count; i++) { 39 | 40 | loginfo << "n = " << n << ", m = " << m << endl; 41 | 42 | // Step 0: Pick random polynomials 43 | vector a = random_field_elems(n+1); 44 | 45 | XncPoly b(m, Fr::random_element()); 46 | //poly_print(a); std::cout << endl; 47 | 48 | // Step 1: Do our fast division 49 | vector q, r, rhs; 50 | df.startLap(); 51 | poly_divide_xnc(a, b, q, r); 52 | df.endLap(); 53 | 54 | // INVARIANT: deg(r) < deg(b) 55 | testAssertStrictlyLessThan(r.size(), m + 1); 56 | if(a.size() >= b.n + 1) { 57 | testAssertEqual(q.size(), n - m + 1); 58 | } 59 | 60 | auto bf = b.toLibff(); 61 | libfqfft::_polynomial_multiplication(rhs, bf, q); 62 | libfqfft::_polynomial_addition(rhs, rhs, r); 63 | 64 | //poly_print(a); std::cout << endl; 65 | //poly_print(rhs); std::cout << endl; 66 | testAssertEqual(a, rhs); 67 | 68 | // Step 2: Do libntl division 69 | ZZ_pX za, zb, zq, zr; 70 | convLibffToNtl_slow(a, za); 71 | convLibffToNtl_slow(bf, zb); 72 | dn.startLap(); 73 | NTL::DivRem(zq, zr, za, zb); 74 | dn.endLap(); 75 | 76 | std::vector rr, qq; 77 | convNtlToLibff(zr, rr); 78 | convNtlToLibff(zq, qq); 79 | 80 | testAssertEqual(rr, r); 81 | testAssertEqual(qq, q); 82 | } 83 | 84 | logperf << df << endl; 85 | logperf << dn << endl; 86 | 87 | return 0; 88 | } 89 | -------------------------------------------------------------------------------- /libpolycrypto/bench/BenchPolynomialOps.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | 14 | #include 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | using namespace std; 21 | using namespace libfqfft; 22 | using namespace libpolycrypto; 23 | 24 | int main(int argc, char *argv[]) { 25 | libpolycrypto::initialize(nullptr, 0); 26 | 27 | loginfo << endl; 28 | loginfo << "Initial NTL numThreads: " << NTL::AvailableThreads() << endl; 29 | loginfo << endl; 30 | 31 | size_t startSz = 16; 32 | // 2^24 - 1 seems to be the max # of roots of unity supported by BN254 33 | // Also it seems to be the max degree for which libntl doesn't crash dvorak, but makes it very slow 34 | if(argc > 1) 35 | startSz = static_cast(std::stoi(argv[1])); 36 | 37 | int count = 2; 38 | if(argc > 2) 39 | count = std::stoi(argv[2]); 40 | 41 | if(argc > 3) { 42 | long numThreads = std::stoi(argv[3]); 43 | if(numThreads > static_cast(getNumCores())) { 44 | logerror << "Number of cores for libntl (" << numThreads << ") cannot be bigger than # of cores on machine, which is " << getNumCores() << endl; 45 | return 1; 46 | } 47 | 48 | if(numThreads > 1) { 49 | NTL::SetNumThreads(numThreads); 50 | loginfo << "Changed NTL NumThreads to " << numThreads << endl; 51 | loginfo << "NTL pool active: " << NTL::GetThreadPool()->active() << endl; 52 | loginfo << endl; 53 | } 54 | } 55 | 56 | loginfo << "Multiplication benchmark for degree " << startSz << ". Iterating " << count << " time(s)" << endl; 57 | loginfo << endl; 58 | 59 | for (size_t i = startSz; i <= startSz; i *= 2) { 60 | vector a, b; 61 | vector p1, p2, res; 62 | ZZ_pX polyX, polyA, polyB; 63 | 64 | bool noFFT = i > 32768; 65 | 66 | AveragingTimer c1, c2, c3, c4; 67 | for (int rep = 0; rep < count; rep++) { 68 | { 69 | //ScopedTimer<> t(std::cout, "Picking random polynomials took ", " microsecs\n"); 70 | NTL::random(polyA, static_cast(i+1)); 71 | NTL::random(polyB, static_cast(i+1)); 72 | convNtlToLibff(polyA, a); 73 | convNtlToLibff(polyB, b); 74 | } 75 | 76 | if(!noFFT) { 77 | c1.startLap(); 78 | _polynomial_multiplication(p1, a, b); 79 | c1.endLap(); 80 | } 81 | 82 | 83 | if(i <= 4096) { 84 | c2.startLap(); 85 | polynomial_multiplication_naive(p2, a, b); 86 | c2.endLap(); 87 | } 88 | 89 | c3.startLap(); 90 | { 91 | c4.startLap(); 92 | mul(polyX, polyA, polyB); 93 | c4.endLap(); 94 | } 95 | convNtlToLibff(polyX, p2); 96 | c3.endLap(); 97 | 98 | if(!noFFT) { 99 | _polynomial_subtraction(res, p1, p2); 100 | if (res.size() != 0) { 101 | logerror 102 | << "The two multiplication functions returned different products" 103 | << endl; 104 | throw std::runtime_error( 105 | "One of the multiplication implementations is wrong"); 106 | } 107 | } 108 | p1.clear(); 109 | p2.clear(); 110 | 111 | } 112 | logperf << "a.size() = " << a.size() << ", b.size() = " << b.size() << ", iters = " << count 113 | << endl; 114 | if(c1.numIterations() == 0) { 115 | //logperf << " + FFT: skipped" << endl; 116 | } else { 117 | logperf << " + FFT mult: " << (double) c1.averageLapTime() / 1000000 118 | << " seconds." << endl; 119 | } 120 | if(c2.numIterations() == 0) { 121 | //logperf << " + Naive: skipped" << endl; 122 | } else { 123 | logperf << " + Naive mult: " << (double) c2.averageLapTime() / 1000000 124 | << " seconds." << endl; 125 | } 126 | logperf << " + NTL mult: " 127 | << (double) c4.averageLapTime() / 1000000 << " +/- " << c4.stddev() / 1000000 << " seconds " << endl; 128 | logperf << " + NTL (with conv): " << (double) c3.averageLapTime() / 1000000 129 | << " seconds." << endl; 130 | logperf << endl; 131 | } 132 | return 0; 133 | } 134 | -------------------------------------------------------------------------------- /libpolycrypto/bench/BenchRootsOfUnityEval.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace std; 17 | using namespace libfqfft; 18 | using namespace libpolycrypto; 19 | 20 | int main(int argc, char *argv[]) { 21 | libpolycrypto::initialize(nullptr, 0); 22 | 23 | if(argc < 4) { 24 | cout << "Usage: " << argv[0] << " " << endl; 25 | cout << endl; 26 | cout << "OPTIONS: " << endl; 27 | cout << " the degree of the evaluated polynomial + 1" << endl; 28 | cout << " the number of points to evaluate at" << endl; 29 | cout << " the number of times to repeat the eval" << endl; 30 | cout << endl; 31 | 32 | return 1; 33 | } 34 | 35 | // Evaluating f at all points in u. 36 | std::vector f; 37 | std::vector evals, actualEvals, fftEvals; 38 | 39 | double maxEvalTime = 3.0; 40 | bool skipEval = false; 41 | size_t t = static_cast(std::stoi(argv[1])); 42 | size_t n = static_cast(std::stoi(argv[2])); 43 | long r = std::stoi(argv[3]); 44 | 45 | logperf << "Degree = " << t - 1 << ", # points evaluated = " << n << ", iters = " << r << endl; 46 | 47 | f.resize(t); 48 | actualEvals.resize(n); 49 | fftEvals.resize(n); 50 | 51 | AveragingTimer at("Accum tree"); 52 | at.startLap(); 53 | AccumulatorTree accs(n); 54 | at.endLap(); 55 | logperf << at << endl; 56 | 57 | std::vector omegas = accs.getAllNthRootsOfUnity(); 58 | assertEqual(omegas.size(), Utils::smallestPowerOfTwoAbove(n)); 59 | omegas.resize(n); 60 | 61 | AveragingTimer c1("Fast eval "), 62 | c2("FFT eval "), 63 | c3("Naive eval"); 64 | 65 | logperf << endl; 66 | for(int rep = 0; rep < r; rep++) { 67 | f = random_field_elems(t); 68 | 69 | // Step 1: Fast multipoint eval 70 | c1.startLap(); 71 | RootsOfUnityEvaluation eval(f, accs); 72 | evals = eval.getEvaluations(); 73 | auto lastLap = c1.endLap(); 74 | 75 | logperf << "Our eval (iter " << rep+1 << "): " << Utils::humanizeMicroseconds(lastLap) << endl; 76 | 77 | // Step 2: Direct FFT 78 | c2.startLap(); 79 | poly_fft(f, n, fftEvals); 80 | c2.endLap(); 81 | 82 | size_t vms, rss; 83 | getMemUsage(vms, rss); 84 | logperf << "VMS: " << Utils::humanizeBytes(vms) << endl; 85 | logperf << "RSS: " << Utils::humanizeBytes(rss) << endl; 86 | 87 | if(n > 4096 || skipEval) 88 | continue; 89 | 90 | // Step 3: Slow, libff evaluation 91 | c3.startLap(); 92 | for(size_t i = 0; i < omegas.size(); i++) { 93 | //logdbg << "w_n^" << i << " = " << omegas[i] << endl; 94 | actualEvals[i] = libfqfft::evaluate_polynomial(f.size(), f, omegas[i]); 95 | } 96 | c3.endLap(); 97 | 98 | assertEqual(evals.size(), actualEvals.size()); 99 | for(size_t k = 0; k < evals.size(); k++) { 100 | if(evals[k] != actualEvals[k] || evals[k] != fftEvals[k]) { 101 | logerror << "The multipoint evaluation function returned a different evaluation at " 102 | << k << "!" << endl; 103 | logerror << " * Eval at w_n^" << k << " = " << evals[k] << endl; 104 | logerror << " * Actual at w_n^" << k << " = " << actualEvals[k] << endl; 105 | logerror << " * FFT at w_n^" << k << " = " << fftEvals[k] << endl; 106 | 107 | throw std::runtime_error( 108 | "The multipoint evaluation function is wrong!"); 109 | } 110 | } 111 | } 112 | 113 | logperf << endl; 114 | logperf << c1 << endl; 115 | logperf << c2 << endl; 116 | 117 | if(c3.numIterations() > 0) { 118 | logperf << c3 << endl; 119 | 120 | if(static_cast(c3.averageLapTime()) / 1000000.0 >= maxEvalTime) { 121 | logperf << "libff eval exceeded " << maxEvalTime << " seconds, skipping from now on..." << endl; 122 | skipEval = true; 123 | } 124 | } 125 | 126 | logperf << endl; 127 | 128 | return 0; 129 | } 130 | -------------------------------------------------------------------------------- /libpolycrypto/bench/BenchSecretReconstruction.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace libpolycrypto; 17 | using namespace std; 18 | using namespace libfqfft; 19 | 20 | void printUsage(const char * prog) { 21 | cout << "Usage: " << prog << " " << endl 22 | << endl 23 | << "Benchmarks k=f+1 out of n=2f+1 secret reconstruction in our VSS/DKG scheme, with f starting at doubling all the way up to " << endl 24 | << "Only focuses on combining Lagr and shares." << endl 25 | << "Ignores Lagrange interpolation time, which we can extract from the threshold signature experiments." << endl 26 | << "Ignores share verification time, which we can extract from VSS/DKG experiments." << endl 27 | << endl 28 | << " starting value of f" << endl 29 | << " ending value of f" << endl 30 | << " how many times to measure Lagrange of size k and 2n + 1 pairings" << endl 31 | << " output file to write results in" << endl 32 | << endl; 33 | } 34 | 35 | int main(int argc, char * argv[]) { 36 | libpolycrypto::initialize(nullptr, 0); 37 | 38 | if (argc < 5) { 39 | printUsage(argv[0]); 40 | return 1; 41 | } 42 | 43 | int minf = std::stoi(argv[1]); 44 | int maxf = std::stoi(argv[2]); 45 | int numSamples = std::stoi(argv[3]); 46 | std::string fileName = argv[4]; 47 | 48 | ofstream fout(fileName); 49 | 50 | if(fout.fail()) { 51 | throw std::runtime_error("Could not open " + fileName + " for writing"); 52 | } 53 | 54 | fout << "k," 55 | << "n," 56 | << "num_samples," 57 | << "combine_usec," // the time to compute s = \sum_i \Ell_i(0) s_i 58 | << endl; 59 | 60 | std::vector shares; 61 | vector lagr; // Lagrange coeffs 62 | for(int p = Utils::smallestPowerOfTwoAbove(minf); p <= maxf + 1; p *= 2) { 63 | size_t f = static_cast(p - 1); 64 | size_t k = f + 1; 65 | size_t n = 2 * f + 1; 66 | 67 | loginfo << "k = " << k << ", n = " << n << "." << endl; 68 | 69 | loginfo << "Picking " << k - shares.size() << " random shares and Lagrange coeffs..." << endl; 70 | while(shares.size() < k) { 71 | shares.push_back(Fr::random_element()); 72 | lagr.push_back(Fr::random_element()); 73 | } 74 | //loginfo << " * Done!" << endl; 75 | 76 | AveragingTimer tc("Combine"); 77 | loginfo << "Taking " << numSamples << " measurements..." << endl; 78 | for(int sample = 0; sample < numSamples; sample++) { 79 | 80 | testAssertEqual(lagr.size(), shares.size()); 81 | 82 | // Bench: recover secret as \sum_i s_i * L_i(0) = p(0) = s 83 | tc.startLap(); 84 | Fr s = Fr::zero(); 85 | for(size_t i = 0; i < k; i++) { 86 | s += shares[i] * lagr[i]; 87 | } 88 | tc.endLap(); 89 | } 90 | 91 | logperf << " * " << tc << endl; 92 | 93 | auto combine_usec = tc.averageLapTime(); 94 | 95 | fout << k << "," 96 | << n << "," 97 | << numSamples << "," 98 | << combine_usec << "," 99 | << endl; 100 | } 101 | 102 | loginfo << "Benchmark ended successfully!" << endl; 103 | return 0; 104 | } 105 | -------------------------------------------------------------------------------- /libpolycrypto/bench/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(polycrypto_bench_sources 2 | BenchApproxVerifyKateProofs.cpp 3 | BenchAMT.cpp 4 | BenchConvertAndMultiexp.cpp 5 | BenchDKG.cpp 6 | BenchExp.cpp 7 | BenchFFT.cpp 8 | BenchVSS.cpp 9 | BenchMultiexp.cpp 10 | BenchNizkPok.cpp 11 | BenchNtlConversion.cpp 12 | BenchPairing.cpp 13 | BenchPolyDivideXnc.cpp 14 | BenchPolynomialOps.cpp 15 | BenchRootsOfUnityEval.cpp 16 | BenchSecretReconstruction.cpp 17 | BenchThresholdSig.cpp 18 | ) 19 | 20 | foreach(appSrc ${polycrypto_bench_sources}) 21 | get_filename_component(appName ${appSrc} NAME_WE) 22 | set(appDir ../bin/bench) 23 | 24 | add_executable(${appName} ${appSrc}) 25 | target_link_libraries(${appName} PRIVATE polycrypto) 26 | 27 | set_target_properties(${appName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${appDir}) 28 | endforeach() 29 | -------------------------------------------------------------------------------- /libpolycrypto/bench/Utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include // for boost::starts_with(str, pattern) 9 | 10 | Dkg::AbstractPlayer* createPlayer(const std::string& dkgType, const Dkg::DkgParams& params, size_t id, const KatePublicParameters* kpp, const Dkg::FeldmanPublicParameters* fpp, bool isSimulated, bool isDkgPlayer) { 11 | assertInclusiveRange(0, id, params.n - 1); 12 | 13 | if(dkgType == "feld") { 14 | return new Dkg::FeldmanPlayer(params, *fpp, id, isSimulated, isDkgPlayer); 15 | } else if(boost::starts_with(dkgType, "kate")) { 16 | return new Dkg::KatePlayer(params, *kpp, id, isSimulated, isDkgPlayer); 17 | } else if(boost::starts_with(dkgType, "amt")) { 18 | return new Dkg::MultipointPlayer(params, *kpp, id, isSimulated, isDkgPlayer); 19 | } else { 20 | logerror << "Unknown type of DKG/VSS: '" << dkgType << "'. Exiting..." << endl; 21 | throw std::runtime_error("Invalid DKG/VSS type"); 22 | } 23 | } 24 | 25 | bool needsKatePublicParams(const std::vector& types) { 26 | bool needsKpp = false; 27 | 28 | for(auto& t : types) { 29 | if(boost::starts_with(t, "amt") || boost::starts_with(t, "kate")) { 30 | needsKpp = true; 31 | break; 32 | } 33 | } 34 | 35 | return needsKpp; 36 | } 37 | 38 | bool needsFeldmanPublicParams(const std::vector& types) { 39 | bool needsFpp = false; 40 | 41 | for(auto& t : types) { 42 | if(t == "feld") { 43 | needsFpp = true; 44 | break; 45 | } 46 | } 47 | 48 | return needsFpp; 49 | } 50 | 51 | std::string sumAvgTimeOrNan(const std::vector& timers, bool humanize) { 52 | microseconds::rep sum = 0; 53 | 54 | for(const auto& t : timers) { 55 | if(t.numIterations() > 0) { 56 | sum += t.averageLapTime(); 57 | } else { 58 | return "nan"; 59 | } 60 | } 61 | 62 | if(humanize) 63 | return Utils::humanizeMicroseconds(sum, 2); 64 | else 65 | return std::to_string(sum); 66 | } 67 | 68 | std::string avgTimeOrNan(const AveragingTimer& t, bool humanize) { 69 | auto v = {t}; 70 | return sumAvgTimeOrNan(v, humanize); 71 | } 72 | 73 | std::string stddevOrNan(const AveragingTimer& t) { 74 | return t.numIterations() > 0 ? std::to_string(t.stddev()) : "nan"; 75 | } 76 | -------------------------------------------------------------------------------- /libpolycrypto/examples/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Targets 3 | # 4 | 5 | set(polycrypto_example_sources 6 | ) 7 | 8 | foreach(appSrc ${polycrypto_example_sources}) 9 | get_filename_component(appName ${appSrc} NAME_WE) 10 | set(appDir ../bin/examples) 11 | 12 | add_executable(${appName} ${appSrc}) 13 | target_link_libraries(${appName} PRIVATE polycrypto) 14 | 15 | add_test(NAME ${appName} COMMAND ${appName}) 16 | 17 | set_target_properties(${appName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${appDir}) 18 | endforeach() 19 | -------------------------------------------------------------------------------- /libpolycrypto/include/polycrypto/AbstractPlayer.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | #include 8 | 9 | namespace Dkg { 10 | 11 | using libpolycrypto::Fr; 12 | using libpolycrypto::G1; 13 | using libpolycrypto::AccumulatorTree; 14 | using libpolycrypto::AuthAccumulatorTree; 15 | using libpolycrypto::RootsOfUnityEvaluation; 16 | 17 | class AbstractPlayer { 18 | public: 19 | size_t id; // this player's ID (from 0 to n-1) 20 | 21 | const DkgParams& params; 22 | 23 | /** 24 | * Random degree t-1 poly f_id(x). 25 | * In DKG, the final polynomial f(x) will be \sum_{j\in IDs} f_j(x) 26 | */ 27 | std::vector f_id; 28 | 29 | /** 30 | * Shares of f_id(x) for other players. 31 | * i.e., shares[j] = f_id(j). 32 | * Player IDs start at j = 0. 33 | */ 34 | std::vector shares; 35 | 36 | Fr share; // share of the final DKG secret: f(id) = \sum_{j\in IDs} f_j(id) 37 | G1 pk; // the corresponding PK of the final DKG secret 38 | 39 | /** 40 | * True when this player will simulate dealing rather than actually deal 41 | * (to make benchmarks faster). 42 | * 43 | * For Feldman, simulation is the same as normal dealing. 44 | * For Kate, the trapdoor is used to compute proofs in O(1) rather than O(n) time. 45 | * Same for AMT. 46 | */ 47 | bool simulated; 48 | 49 | /** 50 | * If this is a VSS (not a DKG) player, then the NIZKPoK and f0comm are not needed in Kate/AMT subclasses 51 | */ 52 | bool isDkgPlayer; 53 | 54 | public: 55 | AbstractPlayer(const DkgParams& params, size_t id, bool isSimulated, bool isDkgPlayer) 56 | : id(id), params(params), share(0), pk(G1::zero()), simulated(isSimulated), isDkgPlayer(isDkgPlayer) 57 | {} 58 | 59 | virtual ~AbstractPlayer() {} 60 | 61 | public: 62 | bool isSimulated() const { return simulated; } 63 | void deal() { 64 | // picks a degree t-1 polynomial that can be recovered by t people 65 | f_id = libpolycrypto::random_field_elems(params.t); 66 | // evaluate f_id(.) to compute shares for each player 67 | // NOTE: KatePlayer will set this to do nothing, since evaluation happens "for free" as proofs are computed 68 | evaluate(); 69 | 70 | if(simulated) { 71 | simulatedDealImpl(); 72 | } else { 73 | // implementation-specific DKG dealing code 74 | dealImpl(); 75 | } 76 | } 77 | 78 | /** 79 | * Returns the secret f_id(0) 80 | */ 81 | const Fr& getSecret() const { 82 | return f_id[0]; 83 | } 84 | 85 | /** 86 | * Evaluates f_id() to compute shares for all players. 87 | * 88 | * Feldman does this via an FFT. 89 | * Kate does this while computing proofs. 90 | * AMT does this using the roots-of-unity evaluation tree. 91 | */ 92 | virtual void evaluate() = 0; 93 | 94 | /** 95 | * Implements the per-player verification in a DKG protocol. 96 | * Verifies this player's share of f_j(x) received from player j != id. 97 | * Assembles this player's final share of f(x) = \sum_{j \in IDs} f_j(x). 98 | */ 99 | virtual bool verifyOtherPlayers(const std::vector& allPlayers, bool agg) = 0; 100 | 101 | /** 102 | * See subclasses for how reconstruction uses subset/fast-track. 103 | * 104 | * @param subset a subset of player IDs used to interpolate 105 | * @param fastTrack true if should simulate a fast-track reconstruction, false otherwise 106 | */ 107 | virtual bool reconstructionVerify(const std::vector& subset, bool fastTrack) = 0; 108 | 109 | /** 110 | * Interpolates the secret from a subset of size t of the players. 111 | * 112 | * For DKG this should be done from on the aggregated shares, but it would give the same performance, so we just do it on one of the DKG players. 113 | */ 114 | Fr interpolate(const std::vector& subset) { 115 | assertEqual(subset.size(), params.t); 116 | 117 | // get all N Nth roots of unity 118 | const std::vector& allOmegas = params.omegas; 119 | 120 | // get interpolation points 121 | vector someOmegas; 122 | for(auto pid : subset) { 123 | testAssertStrictlyLessThan(pid, allOmegas.size()); 124 | someOmegas.push_back(allOmegas[pid]); 125 | } 126 | 127 | // interpolate 128 | std::vector lagr; 129 | // TODO: parameterize threshold where fast Lagrange beats naive Lagrange 130 | if(subset.size() < 64) { 131 | lagrange_coefficients_naive(lagr, allOmegas, someOmegas, subset); 132 | } else { 133 | lagrange_coefficients(lagr, allOmegas, someOmegas, subset); 134 | } 135 | Fr s = Fr::zero(); 136 | assertEqual(lagr.size(), subset.size()); 137 | for(size_t i = 0; i < lagr.size(); i++) { 138 | s += lagr[i] * shares[subset[i]]; 139 | } 140 | 141 | return s; 142 | } 143 | 144 | /** 145 | * After receiving shares from all players in the DKG protocol, this function 146 | * should verify the final share of this player against the final commitment. 147 | */ 148 | virtual bool verifyFinalShareProof() = 0; 149 | 150 | virtual void simulatedDealImpl() = 0; 151 | 152 | virtual void dealImpl() = 0; 153 | }; 154 | 155 | } 156 | -------------------------------------------------------------------------------- /libpolycrypto/include/polycrypto/BinaryTree.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | using namespace std; 18 | 19 | namespace libpolycrypto { 20 | 21 | /** 22 | * Base class used to represent a full binary tree. 23 | * Leaves are at level 0. 24 | * TODO: Should change to q-ary tree (for time/space trade-off) 25 | */ 26 | template 27 | class BinaryTree { 28 | public: 29 | /** 30 | * tree[k][i] is the ith node at level k in the tree (k = 0 is the last level with leaves) 31 | */ 32 | vector> tree; 33 | 34 | /** 35 | * WARNING: Lambdas that 'capture' variables cannot be passed as arguments where a function pointer is expected. 36 | * std::function must be used instead to pass in a lambda. 37 | */ 38 | //typedef void (*ComputeNodeFunc)(size_t, size_t); 39 | typedef std::function ComputeNodeFunc; 40 | 41 | public: 42 | friend std::ostream& operator<<(std::ostream& out, const BinaryTree& t) { 43 | for(size_t i = 0; i < t.tree.size(); i++) { 44 | for(size_t j = 0; j < t.tree[i].size(); j++) { 45 | out << t.tree[i][j] << "; "; 46 | } 47 | out << endl; 48 | } 49 | 50 | return out; 51 | } 52 | 53 | /** 54 | * Allocates a tree capable of storing the specified # of leaves. 55 | * 56 | * @param maxLevel instead of creating a full tree with a root node, stops creating nodes past 57 | * this level, resulting in a forest of trees, each with 2^maxLevel leaves 58 | */ 59 | void allocateTree(size_t numLeaves, size_t maxLevel) { 60 | testAssertIsPowerOfTwo(numLeaves); 61 | 62 | /** 63 | * Height of tree in # of levels, where levels are counted as nodes (not as edges) 64 | * For example, when numLeaves = 2, height is 2. 65 | * Or, when numLeaves = 3 or 4, height is 3. 66 | * Or, when numLeaves = 5, 6, 7 or 8, height is 4. 67 | * In general, height is ceil(log2(numLeaves)) + 1. 68 | */ 69 | size_t maxHeight = static_cast(Utils::log2ceil(numLeaves) + 1); 70 | if(maxLevel >= maxHeight) { 71 | logerror << "Cannot create tree with max level # " << maxLevel << endl; 72 | logerror << "Max possible level # (starting at 0) for tree with " << numLeaves << " leaves is " << maxHeight - 1 << endl; 73 | throw std::runtime_error("Invalid max level"); 74 | } 75 | 76 | size_t numLevels = maxLevel + 1; 77 | tree.resize(numLevels); 78 | tree[0].resize(numLeaves); 79 | 80 | for(size_t k = 1; k < numLevels; k++) { 81 | tree[k].resize(tree[k-1].size() / 2); 82 | } 83 | 84 | // Check the root level has size 1 85 | assertEqual(tree[maxLevel].size(), numLeaves / (1u << maxLevel)); 86 | } 87 | 88 | size_t getNumLeaves() const { 89 | return tree[0].size(); 90 | } 91 | 92 | /** 93 | * Returns the number of levels in the tree (e.g., a one-node tree has 1 level). 94 | */ 95 | //size_t getNumLevels() const { 96 | // return tree.size(); 97 | //} 98 | 99 | /** 100 | * Returns the path of nodes starting at the specified leaf all the way up to the root. 101 | * index 0 will store leaves and higher indices will store internal nodes. 102 | */ 103 | std::vector getPathFromLeaf(size_t leafIdx) const { 104 | std::vector nodes; 105 | logtrace << "Fetching path for " << leafIdx << endl; 106 | for(auto& lvl : tree) { 107 | assertValidIndex(leafIdx, lvl); 108 | 109 | logtrace << "Pushing one node" << endl; 110 | nodes.push_back(lvl[leafIdx]); 111 | 112 | leafIdx /= 2; 113 | } 114 | return nodes; 115 | } 116 | // TODO: maybe add a pathExec() that executes a function for each node on the path? 117 | 118 | /** 119 | * Pre-order traversal of the tree: (root, left child, right child) 120 | * Used when computing quotients in the tree and when committing to polynomials in the tree. 121 | */ 122 | void traversePreorder(const ComputeNodeFunc& func) { 123 | assertStrictlyGreaterThan(tree.size(), 0); 124 | 125 | size_t rootLevel = tree.size() - 1; 126 | size_t numRoots = tree.back().size(); 127 | for(size_t i = 0; i < numRoots; i++) 128 | traversePreorder(rootLevel, i, func); 129 | } 130 | 131 | void traversePreorder(size_t k, size_t idx, const ComputeNodeFunc& func) { 132 | func(k, idx); 133 | 134 | // if we haven't reached the last level yet, 135 | if(k > 0) { 136 | traversePreorder(k - 1, 2*idx, func); // go left 137 | if(2*idx + 1 < tree[k - 1].size()) { // and, if you can, 138 | traversePreorder(k - 1, 2*idx + 1, func); // go right 139 | } 140 | } 141 | } 142 | }; 143 | 144 | } // end of namespace libpolycrypto 145 | -------------------------------------------------------------------------------- /libpolycrypto/include/polycrypto/Configuration.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | // NOTE: Instead of modifying this file, just build using `cmake -DCMAKE_BUILD_TYPE=Trace` which will define TRACE for you 6 | //#define TRACE 7 | 8 | // Some compilers have different #define's for C++11's noexcept 9 | 10 | #ifdef _GLIBCXX_NOEXCEPT 11 | # define _NOEXCEPT _GLIBCXX_USE_NOEXCEPT 12 | #else 13 | # ifndef _NOEXCEPT 14 | # error "_NOEXCEPT is not defined" 15 | # endif 16 | #endif 17 | -------------------------------------------------------------------------------- /libpolycrypto/include/polycrypto/Dkg.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | //#include 4 | #include 5 | #include 6 | #include 7 | 8 | -------------------------------------------------------------------------------- /libpolycrypto/include/polycrypto/DkgCommon.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | namespace Dkg { 11 | 12 | using libpolycrypto::Fr; 13 | using libpolycrypto::G1; 14 | using libpolycrypto::G2; 15 | using libpolycrypto::GT; 16 | using libpolycrypto::ReducedPairing; 17 | using libpolycrypto::AccumulatorTree; 18 | using libpolycrypto::AuthAccumulatorTree; 19 | 20 | /** 21 | * TODO: Both Kate and Feldman PublicParams should extend this class. 22 | * TODO: AmtPublicParams should extend this class and have the accumulators. 23 | * TODO: eh, actually, i think we need to differentiate between a thresholdconfig and the actual public params 24 | * since in our experiments we want pp's for the "largest" thresholdconfig, and we want to create them only once 25 | * whereas we'll be creating thresholdconfig's for each experiment 26 | * 27 | * Not to be confused with public params, no? 28 | * Although the authAccs could be public params. 29 | */ 30 | class DkgParams { 31 | public: 32 | size_t t; // the threshold t to reconstruct the secret (=> degree t-1 polynomial) 33 | size_t n; // the total # of players 34 | size_t N; // the smallest N = 2^k such that n <= N 35 | size_t numBits; // the number of bits in a player ID: i.e., log2(N) 36 | size_t maxLevel; // the max level in a accumulator/roots-of-unity eval tree (leaves are level 0) 37 | 38 | std::unique_ptr accs; // needed for AMT VSS/DKG 39 | const AuthAccumulatorTree * authAccs; // needed for KZG/AMT VSS/DKG 40 | 41 | std::vector omegas; // the first n Nth roots of unity 42 | GT gt; // the generator of GT 43 | 44 | public: 45 | DkgParams(size_t t, size_t n, bool needsAccs) 46 | : t(t), 47 | n(n), 48 | N(Utils::smallestPowerOfTwoAbove(n)), 49 | numBits(Utils::log2ceil(n)), 50 | maxLevel(Utils::log2floor(t-1)), 51 | accs(needsAccs ? new AccumulatorTree(n) : nullptr), 52 | authAccs(nullptr), 53 | omegas(needsAccs ? accs->getAllNthRootsOfUnity() : libpolycrypto::get_all_roots_of_unity(N)), 54 | gt(ReducedPairing(G1::one(), G2::one())) 55 | { 56 | } 57 | 58 | void setAuthAccumulators(const AuthAccumulatorTree* aa) { 59 | authAccs = aa; 60 | } 61 | 62 | /** 63 | * Returns the evaluation point for the player with the specified id \in {0, ..., n-1}. 64 | * For us, it's w_N^{id}. 65 | */ 66 | const Fr& getEvaluationPoint(size_t id) const { 67 | assertInclusiveRange(0, id, n - 1); 68 | return omegas[id]; 69 | } 70 | 71 | /** 72 | * Returns the KZG commitment to (x-\omega_N^id) needed to verify KZG proofs for f(id) 73 | */ 74 | const G2& getMonomialCommitment(size_t playerId) const { 75 | assertNotNull(authAccs); 76 | assertStrictlyLessThan(playerId, n); 77 | 78 | auto leafIdx = libff::bitreverse(playerId, numBits); 79 | return authAccs->getLeaf(leafIdx); 80 | } 81 | }; 82 | 83 | 84 | } 85 | -------------------------------------------------------------------------------- /libpolycrypto/include/polycrypto/FFThresh.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | using namespace std; 9 | 10 | namespace libpolycrypto { 11 | 12 | /** 13 | * Generates public key pk and signer keys s. 14 | * 15 | * @param pkSigners will store the PKs of each signer here, if not null 16 | */ 17 | void generate_keys(size_t n, size_t k, G2& pk, vector& s, vector* pkSigners); 18 | 19 | /** 20 | * Signs a message hash with a signer key. 21 | */ 22 | G1 shareSign(const Fr& shareKey, const G1& msgHash); 23 | 24 | /** 25 | * Takes in signature shares and lagrange coefficients to return the signature. 26 | */ 27 | G1 aggregate(const vector& sigShare, const vector& coeffs); 28 | 29 | /** 30 | * Returns signature shares with indices corresponding to the subset signers. 31 | */ 32 | vector align_shares(const vector& sigShare, const vector& signers); 33 | 34 | /** 35 | * Returns boolean array storing whether the signature share at each index is valid. 36 | */ 37 | vector batch_ver(const vector& sigShare, const vector& pkSigners, const G1& H); 38 | 39 | /** 40 | * Builds binary trees for signature shares and public keys for batch verification. 41 | */ 42 | void build_batch_trees( 43 | const vector& sigShare, 44 | const vector& pkSigners, 45 | vector>& sigShareTree, 46 | vector>& pkTree); 47 | 48 | /** 49 | * Checks if the combined signature share at height k and index is valid. 50 | * If not, checks the combined signature shares of its children. 51 | */ 52 | void descend_batch_trees( 53 | vector& validShares, 54 | const vector>& sigShareTree, 55 | const vector>& pkTree, 56 | const G1& H, size_t k, size_t index); 57 | } 58 | -------------------------------------------------------------------------------- /libpolycrypto/include/polycrypto/KatePublicParameters.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | 11 | namespace Dkg { 12 | 13 | using libpolycrypto::Fr; 14 | using libpolycrypto::G1; 15 | using libpolycrypto::G2; 16 | using libpolycrypto::ReducedPairing; 17 | using libpolycrypto::multiExp; 18 | using libpolycrypto::convNtlToLibff; 19 | 20 | class KatePublicParameters { 21 | public: 22 | size_t q; 23 | std::vector g1si; // g1si[i] = g1^{s^i} 24 | std::vector g2si; // g2si[i] = g2^{s^i} 25 | Fr s; 26 | 27 | protected: 28 | KatePublicParameters(size_t q) 29 | : q(q) 30 | { 31 | resize(q); 32 | 33 | // pick trapdoor s 34 | s = Fr::random_element(); 35 | 36 | Fr si = s^0; 37 | int prevPct = -1; 38 | size_t c = 0; 39 | 40 | loginfo << "Generating q-SDH params, q = " << q << endl; 41 | for (size_t i = 0; i <= q; i++) { 42 | g1si[i] = si * G1::one(); 43 | g2si[i] = si * G2::one(); 44 | 45 | si *= s; 46 | 47 | c++; 48 | 49 | int pct = static_cast(static_cast(c)/static_cast(q + 1) * 100.0); 50 | if(pct > prevPct) { 51 | logdbg << pct << "% ... (i = " << i << " out of " << q << ")" << endl; 52 | prevPct = pct; 53 | } 54 | } 55 | } 56 | 57 | public: 58 | /** 59 | * Reads s, tau and q from trapFile. 60 | * Then reads the q-PKE parameters from trapFile + "-0", trapFile + "-1", ... 61 | * and so on, until q+1 parameters are read: g, g^s, \dots, g^{s^q}. 62 | */ 63 | KatePublicParameters(const std::string& trapFile, size_t maxQ = 0, bool progress = true, bool verify = false); 64 | 65 | public: 66 | static Fr generateTrapdoor(size_t q, const std::string& outFile); 67 | 68 | static void generate(size_t startIncl, size_t endExcl, const Fr& s, const std::string& outFile, bool progress); 69 | 70 | /** 71 | * Generates Kate public parameters on the fly. Used for testing. 72 | */ 73 | static KatePublicParameters getRandom(size_t q) { 74 | return KatePublicParameters(q); 75 | } 76 | 77 | 78 | public: 79 | void resize(size_t q) { 80 | g1si.resize(q+1); // g1^{s^i} with i from 0 to q, including q 81 | g2si.resize(q+1); // g2^{s^i} with i from 0 to q, including q 82 | } 83 | 84 | G1 getG1toS() const { 85 | return g1si[1]; 86 | } 87 | 88 | G2 getG2toS() const { 89 | assertStrictlyGreaterThan(g2si.size(), 1); 90 | return g2si[1]; 91 | } 92 | 93 | const Fr& getTrapdoor() const { 94 | return s; 95 | } 96 | }; 97 | 98 | } 99 | -------------------------------------------------------------------------------- /libpolycrypto/include/polycrypto/Lagrange.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | #include 6 | 7 | using namespace libpolycrypto; 8 | 9 | /* 10 | * Let Num(x) = \prod_{i\in T} (x - w_N^i). 11 | * Computes N0[i] = N_i(0) = Num(0) / (0 - w_N^i) for all i \in T 12 | * 13 | * @param[out] N0 this is where N_i(0)'s are outputted 14 | * @param allOmegas all N Nth roots of unity 15 | * @param T the set of signer IDs in {0, ... N-1} 16 | * @param num0 Num(x) evaluated at x = 0 17 | */ 18 | void compute_numerators(std::vector& N0, const std::vector& allOmegas, const std::vector& T, const Fr& num0); 19 | 20 | void lagrange_coefficients(std::vector& lagr, const std::vector& allOmegas, const std::vector& T); 21 | 22 | /** 23 | * Computes Lagrange coefficients L_i^T(0) = \prod_{j\in T, j \ne i} (0 - x_j) / (x_i - x_j) 24 | * for x_i = w_N^i where i \in T in O(k \log^2{k}) time, where k = |T| 25 | * 26 | * @param[out] lagr the output Lagrange coefficients 27 | * @param allOmegas contains all N Nth roots of unity w_N^k 28 | * Let N = allOmegas.size() 29 | * @param someOmegas the signer IDs as roots of unity 30 | * @param T the actual signer IDs: i.e., i such that allOmegas[i] \in someOmegas 31 | */ 32 | void lagrange_coefficients(std::vector& lagr, const std::vector& allOmegas, const std::vector& someOmegas, const std::vector& T); 33 | 34 | /** 35 | * Computes Lagrange coefficients L_i(0) for set of points in 'x' in O(k^2) time, where k = |pts| 36 | * 37 | * @param[out] L the output Lagrange coefficients 38 | * @param allOmegas all N Nth roots of unity 39 | * @param someOmegas the signer IDs as roots of unity 40 | * @param T the actual signer IDs: i.e., i such that allOmegas[i] \in someOmegas 41 | */ 42 | void lagrange_coefficients_naive(std::vector& L, const std::vector& allOmegas, const std::vector& someOmegas, const std::vector& T); 43 | -------------------------------------------------------------------------------- /libpolycrypto/include/polycrypto/NizkPok.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | 5 | namespace libpolycrypto { 6 | 7 | class NizkPok { 8 | public: 9 | Fr h; 10 | Fr s; 11 | 12 | public: 13 | NizkPok() {} 14 | NizkPok(const Fr& h, const Fr& s) : h(h), s(s) {} 15 | 16 | public: 17 | /** 18 | * Computes a NIZKPoK for x that verifies against g^x. 19 | * i.e., just a Schnorr signature s = k + H(m|g^k)x under x, where m = g|g^x 20 | */ 21 | static NizkPok prove(const G1& g, const Fr& x, const G1& gToX); 22 | static NizkPok getDummyProof(); 23 | 24 | /** 25 | * Verifies the NIZKPoK for g^x. 26 | * i.e., just a Schnorr signature verification: 1 hash + 2 exps + 1 group op 27 | * 28 | * @param pi the NIZKPoK 29 | * @param gToX g^x 30 | */ 31 | static bool verify(const NizkPok& pi, const G1& g, const G1& gToX); 32 | }; 33 | 34 | } 35 | -------------------------------------------------------------------------------- /libpolycrypto/include/polycrypto/NtlLib.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | #include 19 | 20 | using NTL::ZZ_p; 21 | using NTL::ZZ_pX; 22 | using NTL::ZZ; 23 | using NTL::vec_ZZ_p; 24 | using namespace std; 25 | 26 | namespace libpolycrypto { 27 | 28 | /** 29 | * Some useful NTL functions to know (see https://www.shoup.net/ntl/doc/ZZ_pX.cpp.html) 30 | * NOTE: Unfortunately, as far as I can tell, there's no way to compute f(w_i) fast using FFT in libntl. 31 | * It seems that NTL uses a complicated representation for the f(w_i) values and doesn't expose them as ZZ_p's. 32 | * 33 | * ZZ_pX(INIT_SIZE, n) -> initializes to zero, but space is pre-allocated 34 | * 35 | * const ZZ_pX& ZZ_pX::zero() -> returns const reference to 0 polynomial 36 | * 37 | * void ZZ_pX::SetMaxLength(long n) -> f.SetMaxLength(n) pre-allocate spaces for n coefficients. The polynomial that f represents is unchanged. 38 | * 39 | * clear(ZZ_pX& x) -> x = 0 40 | * set(ZZ_pX& x) -> x = 1 41 | * random(ZZ_pX& x, long degBound) -> picks random poly of degree = degBound - 1 (documentation is confusing; it says < degBound, which is not precise; but code generates exactly degBound - 1) 42 | * 43 | * rem(r, a, b) -> r = a%b 44 | * DivRem(q, r, a, b) -> q = a/b, r = a%b 45 | * div(q, a, b) -> q = a/b 46 | * diff(d, f) -> d = derivative of f 47 | */ 48 | 49 | 50 | template 51 | void conv_single_fr_zp(const FieldT& a, ZZ_p& b, mpz_t& rop, ZZ& mid) { 52 | (a.as_bigint()).to_mpz(rop); 53 | char *s = mpz_get_str(NULL, 10, rop); 54 | 55 | mid = NTL::conv(s); 56 | b = NTL::conv(mid); 57 | 58 | void (*freefunc)(void *, size_t); 59 | mp_get_memory_functions(NULL, NULL, &freefunc); 60 | freefunc(s, strlen(s) + 1); 61 | } 62 | 63 | template 64 | void convLibffToNtl(const vector &a, ZZ_pX &pa) 65 | { 66 | (void)a; 67 | (void)pa; 68 | throw libxutils::NotImplementedException(); 69 | } 70 | 71 | /* 72 | * DEPRECATED: This uses strings and is slower than the implementation above. 73 | */ 74 | template 75 | void convLibffToNtl_slow(const vector &a, ZZ_pX &pa) 76 | { 77 | pa = ZZ_pX(NTL::INIT_MONO, (long)(a.size() - 1)); 78 | 79 | mpz_t rop; 80 | mpz_init(rop); 81 | ZZ mid; 82 | 83 | for (size_t i = 0; i < a.size(); i++) { 84 | conv_single_fr_zp(a[i], pa[static_cast(i)], rop, mid); 85 | } 86 | 87 | mpz_clear(rop); 88 | } 89 | 90 | /** 91 | * Converts an NTL vec_ZZ_p vector of field elements to a vector of libff field elements. 92 | */ 93 | template 94 | void convNtlToLibff(const ZZ_p& zzp, FieldT& ff) { 95 | long numBytes = NumBytes(ZZ_p::modulus()); 96 | AutoBuf buf(static_cast(numBytes)); 97 | buf.zeroize(); 98 | 99 | mpz_t interm; 100 | mpz_init(interm); 101 | 102 | const ZZ& rep = NTL::rep(zzp); 103 | 104 | // NOTE: Puts the least significant byte in buf[0] 105 | NTL::BytesFromZZ(buf, rep, numBytes); 106 | 107 | // convert byte array to mpz_t 108 | mpz_import(interm, 109 | /*count =*/static_cast(numBytes), 110 | /*order =*/-1, 111 | /*size =*/1, 112 | /*endian=*/0, 113 | /*nails =*/0, 114 | buf); 115 | 116 | ff = libff::bigint(interm); 117 | 118 | mpz_clear(interm); 119 | } 120 | 121 | template 122 | void convNtlToLibff(const vec_ZZ_p& pn, vector& pf) { 123 | // allocate enough space for libff polynomial 124 | pf.resize(static_cast(pn.length())); 125 | 126 | mpz_t interm; 127 | mpz_init(interm); 128 | 129 | long numBytes = NumBytes(ZZ_p::modulus()); 130 | AutoBuf buf(static_cast(numBytes)); 131 | buf.zeroize(); 132 | 133 | for (size_t i = 0; i < pf.size(); i++) { 134 | const ZZ_p& coeff = pn[static_cast(i)]; 135 | const ZZ& coeffRep = NTL::rep(coeff); 136 | 137 | // NOTE: Puts the least significant byte in buf[0] 138 | NTL::BytesFromZZ(buf, coeffRep, numBytes); 139 | 140 | // convert byte array to mpz_t 141 | mpz_import(interm, 142 | /*count =*/static_cast(numBytes), 143 | /*order =*/-1, 144 | /*size =*/1, 145 | /*endian=*/0, 146 | /*nails =*/0, 147 | buf); 148 | 149 | pf[i] = libff::bigint(interm); 150 | } 151 | 152 | mpz_clear(interm); 153 | } 154 | 155 | /** 156 | * Converts an NTL ZZ_pX polynomial to libff polynomial. 157 | */ 158 | template 159 | void convNtlToLibff(const ZZ_pX& pn, vector& pf) { 160 | convNtlToLibff(pn.rep, pf); 161 | } 162 | 163 | /** 164 | * DEPRECATED: Converts an NTL ZZ_pX polynomial to libff polynomial. 165 | * This uses string streams and is slower than the implementation above. 166 | */ 167 | template 168 | void convNtlToLibff_slow(const ZZ_pX &pa, vector &a) { 169 | a.resize((size_t)(NTL::deg(pa)+1)); 170 | 171 | stringstream ss; 172 | for (size_t i = 0; i < a.size(); i++) { 173 | ss << pa[(long)i]; 174 | 175 | a[i] = libff::bigint(ss.str().c_str()); 176 | ss.str(""); 177 | } 178 | } 179 | 180 | template 181 | Group multiExp( 182 | const std::vector& bases, 183 | const vec_ZZ_p& exps) 184 | { 185 | std::vector expsff; 186 | convNtlToLibff(exps, expsff); 187 | 188 | long minSize = static_cast(bases.size()); 189 | if(exps.length() < minSize) 190 | minSize = exps.length(); 191 | 192 | return multiExp(bases.cbegin(), bases.cbegin() + minSize, 193 | expsff.cbegin(), expsff.cbegin() + minSize); 194 | } 195 | 196 | template 197 | Group multiExp( 198 | const std::vector& bases, 199 | const ZZ_pX& exps) 200 | { 201 | return multiExp(bases, exps.rep); 202 | } 203 | 204 | } // end of namespace libpolycrypto 205 | -------------------------------------------------------------------------------- /libpolycrypto/include/polycrypto/PolyCrypto.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | 9 | using namespace std; 10 | 11 | namespace libpolycrypto { 12 | 13 | // Type of group G1 14 | using G1 = typename libff::default_ec_pp::G1_type; 15 | // Type of group G2 16 | using G2 = typename libff::default_ec_pp::G2_type; 17 | // Type of group GT (recall pairing e : G1 x G2 -> GT) 18 | using GT = typename libff::default_ec_pp::GT_type; 19 | // Type of the finite field "in the exponent" of the EC group elements 20 | using Fr = typename libff::default_ec_pp::Fp_type; 21 | 22 | // Pairing function, takes an element in G1, another in G2 and returns the one in GT 23 | //using libff::default_ec_pp::reduced_pairing; 24 | //using ECPP::reduced_pairing; 25 | // Found this solution on SO: https://stackoverflow.com/questions/9864125/c11-how-to-alias-a-function 26 | // ('using ECPP::reduced_pairing;' doesn't work, even if you expand ECPP) 27 | template 28 | auto ReducedPairing( 29 | Args&&... args) -> decltype(libff::default_ec_pp::reduced_pairing(std::forward(args)...)) { 30 | return libff::default_ec_pp::reduced_pairing(std::forward(args)...); 31 | } 32 | 33 | /** 34 | * Initializes the library, including its randomness. 35 | */ 36 | void initialize(unsigned char * randSeed, int size = 0); 37 | 38 | /** 39 | * Picks num random field elements 40 | */ 41 | vector random_field_elems(size_t num); 42 | 43 | template 44 | vector random_group_elems(size_t n) { 45 | vector bases; 46 | for(size_t j = 0; j < n; j++) { 47 | bases.push_back(Group::random_element()); 48 | } 49 | return bases; 50 | } 51 | 52 | size_t getNumCores(); 53 | 54 | /** 55 | * Returns the first n Nth roots of unity where N = 2^k is the smallest number such that n <= N. 56 | */ 57 | vector get_all_roots_of_unity(size_t n); 58 | 59 | /** 60 | * Picks a random polynomial of degree deg. 61 | */ 62 | //vector random_poly(size_t degree); 63 | 64 | /** 65 | * Performs a multi-exponentiation using libfqfft 66 | */ 67 | template 68 | Group multiExp( 69 | typename std::vector::const_iterator base_begin, 70 | typename std::vector::const_iterator base_end, 71 | typename std::vector::const_iterator exp_begin, 72 | typename std::vector::const_iterator exp_end 73 | ) 74 | { 75 | long sz = base_end - base_begin; 76 | long expsz = exp_end - exp_begin; 77 | if(sz != expsz) 78 | throw std::runtime_error("multiExp needs the same number of bases as exponents"); 79 | //size_t numCores = getNumCores(); 80 | 81 | if(sz > 4) { 82 | if(sz > 16384) { 83 | return libff::multi_exp(base_begin, base_end, 84 | exp_begin, exp_end, 1);//numCores); 85 | } else { 86 | return libff::multi_exp(base_begin, base_end, 87 | exp_begin, exp_end, 1);//numCores); 88 | } 89 | } else { 90 | return libff::multi_exp(base_begin, base_end, 91 | exp_begin, exp_end, 1); 92 | } 93 | } 94 | 95 | /** 96 | * Performs a multi-exponentiation using libfqfft 97 | */ 98 | template 99 | Group multiExp( 100 | const std::vector& bases, 101 | const std::vector& exps) 102 | { 103 | assertEqual(bases.size(), exps.size()); 104 | return multiExp(bases.cbegin(), bases.cend(), 105 | exps.cbegin(), exps.cend()); 106 | } 107 | 108 | } // end of namespace libpolycrypto 109 | 110 | namespace boost { 111 | 112 | std::size_t hash_value(const libpolycrypto::Fr& f); 113 | 114 | } // end of boost namespace 115 | -------------------------------------------------------------------------------- /libpolycrypto/include/polycrypto/Utils.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | /** 9 | * Returns k unique random numbers in the range [0, n-1] as a vector 10 | */ 11 | vector random_subset(size_t k, size_t n); 12 | 13 | /** 14 | * Originally from: https://stackoverflow.com/questions/669438/how-to-get-memory-usage-at-runtime-using-c 15 | * 16 | * process_mem_usage(double &, double &) - takes two doubles by reference, 17 | * attempts to read the system-dependent data for a process' virtual memory 18 | * size and resident set size, and return the results in bytes. 19 | * 20 | * On failure, returns 0, 0; 21 | */ 22 | void printMemUsage(const char * headerMessage = nullptr); 23 | 24 | void getMemUsage(size_t& vm_usage, size_t& resident_set); 25 | -------------------------------------------------------------------------------- /libpolycrypto/src/AmtDkg.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | namespace Dkg { 6 | 7 | std::ostream& operator<<(std::ostream& out, const AmtProof& pi) { 8 | out << "[ "; 9 | for(auto q : pi.quoComms) { 10 | out << q << ", "; 11 | } 12 | out << "]"; 13 | 14 | return out; 15 | } 16 | } 17 | -------------------------------------------------------------------------------- /libpolycrypto/src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | # 2 | # Targets 3 | # 4 | 5 | add_library(polycrypto 6 | AmtDkg.cpp 7 | PolyCrypto.cpp 8 | FFThresh.cpp 9 | KateDkg.cpp 10 | KatePublicParameters.cpp 11 | Lagrange.cpp 12 | NizkPok.cpp 13 | PolyOps.cpp 14 | Utils.cpp 15 | ) 16 | 17 | target_include_directories(polycrypto PUBLIC 18 | "$" 19 | "$" 20 | ) 21 | 22 | target_link_libraries(polycrypto PUBLIC 23 | ntl ff pthread zm gmp gmpxx xutils xassert 24 | ) 25 | 26 | include(FindOpenMP) 27 | if(OPENMP_FOUND) 28 | target_link_libraries(polycrypto PUBLIC gomp) 29 | endif() 30 | 31 | #target_link_libraries(polycrypto PUBLIC Threads::Threads) 32 | 33 | # 34 | # Installation 35 | # TODO: Add Config[Version].cmake files so this package can be easily imported? 36 | # (See https://cmake.org/cmake/help/git-master/manual/cmake-packages.7.html#creating-packages) 37 | # 38 | 39 | # This creates the Config.cmake file and installs it 40 | install(TARGETS polycrypto EXPORT polycryptoConfig 41 | ARCHIVE DESTINATION lib) 42 | install(EXPORT polycryptoConfig DESTINATION lib/cmake/polycrypto) 43 | 44 | # This installs the static or (/and?) dynamic library 45 | install(TARGETS polycrypto 46 | ARCHIVE DESTINATION lib 47 | LIBRARY DESTINATION lib 48 | ) 49 | 50 | # This installs the headers 51 | # WARNING: Don't add / at the end. No slash means polycrypto/ directory is created in the destination path 52 | install(DIRECTORY include/polycrypto DESTINATION include) 53 | -------------------------------------------------------------------------------- /libpolycrypto/src/FFThresh.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | 4 | #include 5 | #include 6 | #include 7 | 8 | #include 9 | 10 | using namespace std; 11 | 12 | namespace libpolycrypto { 13 | 14 | void generate_keys(size_t n, size_t k, G2& pk, vector& sk, vector* pkSigners) { 15 | // set random polynomial p of degree k - 1 16 | std::vector p = random_field_elems(k); 17 | 18 | // set signer id's to w_N^0, w_N^1, w_N^2, ... w_N^{n-1} where N = 2^i is the smallest N such that n <= N 19 | // (and no signer id should be 0 since the secret key s = p(0) ) 20 | size_t N = Utils::smallestPowerOfTwoAbove(n); 21 | 22 | // pk = g2^s = g2^p(0) 23 | pk = p[0] * G2::one(); 24 | 25 | // sk[i] = p evaluated at w_N^i 26 | poly_fft(p, N, sk); 27 | // we only need the first n <= N roots of unity 28 | sk.resize(n); 29 | 30 | if(pkSigners != nullptr) { 31 | // pkSigners[i] = g2^s_i 32 | pkSigners->resize(n); 33 | for (size_t i = 0; i < n; i++) { 34 | (*pkSigners)[i] = sk[i] * G2::one(); 35 | } 36 | } 37 | } 38 | 39 | G1 shareSign(const Fr& shareKey, const G1& msgHash) { 40 | // TODO: assuming message is really H(message) 41 | return shareKey * msgHash; 42 | } 43 | 44 | G1 aggregate(const vector& sigShare, const vector& coeffs) { 45 | return multiExp(sigShare, coeffs); 46 | } 47 | 48 | vector align_shares(const vector& sigShare, const vector& signers) { 49 | vector sigSharesSubset(signers.size()); 50 | 51 | for (size_t i = 0; i < sigSharesSubset.size(); i++) { 52 | sigSharesSubset[i] = sigShare[signers[i]]; 53 | } 54 | 55 | return sigSharesSubset; 56 | } 57 | 58 | vector batch_ver(const vector& sigShare, const vector& pkSigners, const G1& H) { 59 | vector validShares(sigShare.size(), true); 60 | vector> sigShareTree; 61 | vector> pkTree; 62 | 63 | size_t height = static_cast (ceil(log(sigShare.size()) / log(2)) + 1); 64 | 65 | build_batch_trees(sigShare, pkSigners, sigShareTree, pkTree); 66 | descend_batch_trees(validShares, sigShareTree, pkTree, H, height - 1, 0); 67 | return validShares; 68 | } 69 | 70 | void build_batch_trees( 71 | const vector& sigShare, 72 | const vector& pkSigners, 73 | vector>& sigShareTree, 74 | vector>& pkTree) 75 | { 76 | size_t height = static_cast (ceil(log(sigShare.size()) / log(2)) + 1); 77 | sigShareTree.resize(height); 78 | pkTree.resize(height); 79 | sigShareTree[0] = sigShare; 80 | pkTree[0] = pkSigners; 81 | 82 | for (size_t i = 1; i < height; i++) { 83 | sigShareTree[i].resize((sigShareTree[i-1].size() + 1) / 2); 84 | pkTree[i].resize((pkTree[i-1].size() + 1) / 2); 85 | for (size_t j = 0; j < sigShareTree[i].size(); j++) { 86 | // if last node cannot be paired, set parent to itself 87 | if (2 * j + 1 >= sigShareTree[i-1].size()) { 88 | sigShareTree[i][j] = sigShareTree[i - 1][2 * j]; 89 | pkTree[i][j] = pkTree[i - 1][2 * j]; 90 | } else { 91 | sigShareTree[i][j] = sigShareTree[i - 1][2 * j] + sigShareTree[i - 1][2 * j + 1]; 92 | pkTree[i][j] = pkTree[i - 1][2 * j] + pkTree[i - 1][2 * j + 1]; 93 | } 94 | } 95 | } 96 | } 97 | 98 | void descend_batch_trees( 99 | vector& validShares, 100 | const vector>& sigShareTree, 101 | const vector>& pkTree, 102 | const G1& H, size_t k, size_t index) 103 | { 104 | // return if verifies correctly 105 | if (ReducedPairing(sigShareTree[k][index], G2::one()) == ReducedPairing(H, pkTree[k][index])) return; 106 | 107 | // if on bottom row, set share to false 108 | if (k == 0) { 109 | validShares[index] = false; 110 | return; 111 | } 112 | 113 | // check children 114 | descend_batch_trees(validShares, sigShareTree, pkTree, H, k - 1, index * 2); 115 | if (index * 2 + 1 < sigShareTree[k - 1].size()) { 116 | descend_batch_trees(validShares, sigShareTree, pkTree, H, k - 1, index * 2 + 1); 117 | } 118 | } 119 | 120 | } 121 | -------------------------------------------------------------------------------- /libpolycrypto/src/KateDkg.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | namespace Dkg { 6 | 7 | } 8 | -------------------------------------------------------------------------------- /libpolycrypto/src/Lagrange.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | using namespace libfqfft; 19 | using namespace std; 20 | 21 | void compute_numerators(std::vector& N0, const std::vector& allOmegas, const std::vector& T, const Fr& num0) { 22 | size_t N = allOmegas.size(); 23 | assertTrue(Utils::isPowerOfTwo(N)); 24 | 25 | N0.resize(T.size()); 26 | size_t j = 0; 27 | for (auto i : T) { 28 | /** 29 | * Recall that: 30 | * a) Inverses can be computed fast as: (w_N^k)^{-1} = w_N^{-k} = w_N^N w_N^{-k} = w_N^{N-k} 31 | * b) Negations can be computed fast as: -w_N^k = w_N^{k + N/2} 32 | * 33 | * So, (0 - w_N^i)^{-1} = (w_N^{i + N/2})^{-1} = w_N^{N - (i + N/2)} = w_N^{N/2 - i} 34 | * If N/2 < i, then you wrap around to N + N/2 - i. 35 | */ 36 | size_t idx; 37 | 38 | if(N/2 < i) { 39 | idx = N + N/2 - i; 40 | } else { 41 | idx = N/2 - i; 42 | } 43 | 44 | N0[j++] = num0 * allOmegas[idx]; 45 | } 46 | 47 | assertEqual(j, N0.size()); 48 | } 49 | 50 | void lagrange_coefficients(std::vector& lagr, const std::vector& allOmegas, const std::vector& someOmegas, const std::vector& T) { 51 | size_t N = allOmegas.size(); 52 | 53 | // Num(x) = product of all (x - x_i), i.e., root of subproduct tree 54 | std::vector Num; 55 | //{ 56 | // NOTE: Using libff-based multiplication for interpolating N(x) is 8x slower than libntl 57 | //ScopedTimer rt(std::cout, "N(x) from roots took: ", " ms\n"); 58 | Num = poly_from_roots(someOmegas); 59 | //} 60 | 61 | // N0[i] = N_i(0) = Num(0) / (0 - x_i) 62 | std::vector N0; 63 | compute_numerators(N0, allOmegas, T, Num[0]); 64 | 65 | // Ndiff = Num'(x) 66 | std::vector Ndiff; 67 | poly_differentiate(Num, Ndiff); 68 | 69 | // D[i] = D_i = Num'(x_i), so we evaluate Num' at allOmegas and then return the values at someOmegas 70 | std::vector D; 71 | poly_fft(Ndiff, N, D); 72 | 73 | // L[i] = L_i(0) = N_i(0) / D_i 74 | lagr.resize(T.size()); 75 | for (size_t i = 0; i < lagr.size(); i++) { 76 | lagr[i] = N0[i] * D[T[i]].inverse(); 77 | } 78 | } 79 | 80 | void lagrange_coefficients(std::vector& lagr, const std::vector& allOmegas, const std::vector& T) { 81 | std::vector someOmegas; 82 | for(size_t i : T) { 83 | assertStrictlyLessThan(i, allOmegas.size()); 84 | someOmegas.push_back(allOmegas[i]); 85 | } 86 | 87 | return lagrange_coefficients(lagr, allOmegas, someOmegas, T); 88 | } 89 | 90 | void lagrange_coefficients_naive(std::vector& L, const std::vector& allOmegas, const std::vector& someOmegas, const std::vector& T) { 91 | size_t N = allOmegas.size(); 92 | assertTrue(Utils::isPowerOfTwo(N)); 93 | assertEqual(someOmegas.size(), T.size()); 94 | assertStrictlyLessThan(someOmegas.size(), N); // assuming N-1 out of N is "max" threshold, which we don't have to assume 95 | 96 | // WARNING: We want to make sure N*N fits in a size_t, so we can optimize the num0 code below to only compute % once 97 | testAssertStrictlyLessThan(N, 1u << 31); 98 | testAssertEqual(sizeof(size_t), 8); 99 | 100 | // Num(0) = \prod_{i\in T} (0 - w_N^i) = (-1)^|T| w_N^{(\sum_{i\in T} i) % N} 101 | Fr num0 = 1; 102 | vector N0, D; 103 | 104 | L.resize(someOmegas.size()); 105 | 106 | if(T.size() % 2 == 1) 107 | num0 = -Fr::one(); 108 | 109 | size_t sum = 0; 110 | // NOTE: this sum is < 1 + 2 + ... + N < N*N. That's why we assert sizeof(N*N) < sizeof(size_t) 111 | for(auto i : T) { 112 | //sum = (sum + i) % N; // a bit slower, so should avoid 113 | sum += i; 114 | } 115 | sum %= N; 116 | assertStrictlyLessThan(sum, allOmegas.size()); 117 | num0 *= allOmegas[sum]; 118 | 119 | // Naively, we'd be doing a lot more field operations: 120 | //for(auto i : T) { 121 | // size_t idx; 122 | // if(i + N/2 >= N) { 123 | // // idx = (i + N/2) - N 124 | // idx = i - N/2; 125 | // } else { 126 | // idx = i + N/2; 127 | // } 128 | // num0 *= allOmegas[idx]; 129 | //} 130 | 131 | // N0[i] = N_i(0) = Num(0) / (0 - x_i) 132 | compute_numerators(N0, allOmegas, T, num0); 133 | 134 | // D[i] = product (x_i - x_j), j != i 135 | D.resize(someOmegas.size(), 1); 136 | for (size_t i = 0; i < someOmegas.size(); i++) { 137 | for (size_t j = 0; j < someOmegas.size(); j++) { 138 | if (j != i) { 139 | D[i] *= (someOmegas[i] - someOmegas[j]); 140 | } 141 | } 142 | } 143 | 144 | // L[i] = L_i(0) = N_i(0) / D_i 145 | for (size_t i = 0; i < L.size(); i++) { 146 | L[i] = N0[i] * D[i].inverse(); 147 | } 148 | } 149 | -------------------------------------------------------------------------------- /libpolycrypto/src/NizkPok.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | 7 | namespace libpolycrypto { 8 | 9 | /** 10 | * Returns H(g, g^x, g^k) as a field element. 11 | * 12 | * @param g g 13 | * @param gToX g^x 14 | * @param r r = g^k 15 | */ 16 | static Fr nizkHash(const G1& g, const G1& gToX, const G1& gToK) { 17 | // convert (g, g^x, g^k) to a string 18 | std::stringstream ss; 19 | ss << g << "|" << gToX << "|" << gToK; 20 | 21 | // hash string, but output a hex string not bytes 22 | std::string hex; 23 | picosha2::hash256_hex_string(ss.str(), hex); 24 | hex.pop_back(); // small enough for BN-P254 field 25 | 26 | // convert hex to mpz_t 27 | mpz_t rop; 28 | mpz_init(rop); 29 | mpz_set_str(rop, hex.c_str(), 16); 30 | 31 | // convert mpz_t to Fr 32 | Fr fr = libff::bigint(rop); 33 | mpz_clear(rop); 34 | 35 | return fr; 36 | } 37 | 38 | NizkPok NizkPok::prove(const G1& g, const Fr& x, const G1& gToX) { 39 | /** 40 | * Picks random k \in Fr 41 | * Sets r = g^k 42 | * Sets h = H(g, g^x, r) 43 | * Sets s = k - h*x 44 | */ 45 | Fr k = Fr::random_element(); 46 | G1 r = k * g; 47 | Fr h = nizkHash(g, gToX, r); 48 | 49 | return NizkPok(h, k - h*x); 50 | } 51 | 52 | NizkPok NizkPok::getDummyProof() { 53 | return NizkPok(Fr::random_element(), Fr::random_element()); 54 | } 55 | 56 | bool NizkPok::verify(const NizkPok& pi, const G1& g, const G1& gToX) { 57 | auto lhs = nizkHash(g, gToX, (pi.s * g) + (pi.h * gToX)); 58 | 59 | return lhs == pi.h; 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /libpolycrypto/src/PolyCrypto.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include // get_root_of_unity 14 | 15 | #ifdef USE_MULTITHREADING 16 | # include 17 | #endif 18 | 19 | using namespace std; 20 | using namespace NTL; 21 | 22 | namespace libpolycrypto { 23 | 24 | void initialize(unsigned char * randSeed, int size) { 25 | (void)randSeed; // TODO: initialize entropy source 26 | (void)size; // TODO: initialize entropy source 27 | 28 | // Apparently, libff logs some extra info when computing pairings 29 | libff::inhibit_profiling_info = true; 30 | 31 | // Initializes the default EC curve, so as to avoid "surprises" 32 | libff::default_ec_pp::init_public_params(); 33 | 34 | // Initializes the NTL finite field 35 | ZZ p = conv ("21888242871839275222246405745257275088548364400416034343698204186575808495617"); 36 | ZZ_p::init(p); 37 | 38 | NTL::SetSeed(randSeed, size); 39 | 40 | #ifdef USE_MULTITHREADING 41 | // NOTE: See https://stackoverflow.com/questions/11095309/openmp-set-num-threads-is-not-working 42 | loginfo << "Using " << getNumCores() << " threads" << endl; 43 | omp_set_dynamic(0); // Explicitly disable dynamic teams 44 | omp_set_num_threads(static_cast(getNumCores())); // Use 4 threads for all consecutive parallel regions 45 | #else 46 | //loginfo << "NOT using multithreading" << endl; 47 | #endif 48 | } 49 | 50 | vector random_field_elems(size_t num) { 51 | vector p(num); 52 | for (size_t i = 0; i < p.size(); i++) { 53 | p[i] = Fr::random_element(); 54 | } 55 | return p; 56 | } 57 | 58 | size_t getNumCores() { 59 | static size_t numCores = std::thread::hardware_concurrency(); 60 | if(numCores == 0) 61 | throw std::runtime_error("Could not get number of cores"); 62 | return numCores; 63 | } 64 | 65 | vector get_all_roots_of_unity(size_t n) { 66 | if(n < 1) 67 | throw std::runtime_error("Cannot get 0th root-of-unity"); 68 | 69 | size_t N = Utils::smallestPowerOfTwoAbove(n); 70 | 71 | // initialize array of roots of unity 72 | Fr omega = libff::get_root_of_unity(N); 73 | std::vector omegas(n); 74 | omegas[0] = Fr::one(); 75 | 76 | if(n > 1) { 77 | omegas[1] = omega; 78 | for(size_t i = 2; i < n; i++) { 79 | omegas[i] = omega * omegas[i-1]; 80 | } 81 | } 82 | 83 | return omegas; 84 | } 85 | 86 | //vector random_poly(size_t deg) { 87 | // return random_field_elems(deg+1); 88 | //} 89 | 90 | } // end of namespace libpolycrypto 91 | 92 | namespace boost { 93 | 94 | std::size_t hash_value(const libpolycrypto::Fr& f) 95 | { 96 | size_t size; 97 | mpz_t rop; 98 | mpz_init(rop); 99 | f.as_bigint().to_mpz(rop); 100 | 101 | //char *s = mpz_get_str(NULL, 10, rop); 102 | //size = strlen(s); 103 | //auto h = boost::hash_range(s, s + size); 104 | 105 | //void (*freefunc)(void *, size_t); 106 | //mp_get_memory_functions(NULL, NULL, &freefunc); 107 | //freefunc(s, size); 108 | 109 | 110 | mpz_export(NULL, &size, 1, 1, 1, 0, rop); 111 | AutoBuf buf(static_cast(size)); 112 | 113 | mpz_export(buf, &size, 1, 1, 1, 0, rop); 114 | auto h = boost::hash_range(buf, buf + buf.size()); 115 | 116 | mpz_clear(rop); 117 | return h; 118 | } 119 | 120 | } // end of boost namespace 121 | -------------------------------------------------------------------------------- /libpolycrypto/src/PolyOps.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | 8 | using namespace std; 9 | using namespace NTL; 10 | 11 | namespace libpolycrypto { 12 | 13 | ZZ_pX poly_from_roots_ntl(const vec_ZZ_p& roots, long startIncl, long endExcl) { 14 | // base case is startIncl == endExcl - 1, so return (x - root) 15 | if(startIncl == endExcl - 1) { 16 | ZZ_pX monom(NTL::INIT_MONO, 1); 17 | monom[0] = -roots[startIncl]; 18 | monom[1] = 1; 19 | assertEqual(NTL::deg(monom), 1); 20 | return monom; 21 | } 22 | 23 | ZZ_pX p; 24 | 25 | long middle = (startIncl + endExcl) / 2; 26 | 27 | NTL::mul( 28 | p, 29 | poly_from_roots_ntl(roots, startIncl, middle), 30 | poly_from_roots_ntl(roots, middle, endExcl) 31 | ); 32 | 33 | return p; 34 | } 35 | 36 | XncPoly operator*(const XncPoly& lhs, const XncPoly& rhs) { 37 | return XncPoly(lhs.n + rhs.n, lhs.c*rhs.c); 38 | } 39 | 40 | std::ostream& operator<<(std::ostream& out, const XncPoly& rhs) { 41 | out << "x^" << rhs.n << " + " << rhs.c; 42 | return out; 43 | } 44 | 45 | } 46 | -------------------------------------------------------------------------------- /libpolycrypto/src/Utils.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #ifndef __APPLE__ 9 | # include 10 | # include 11 | # include 12 | # include 13 | # include 14 | #else 15 | # include 16 | #endif 17 | 18 | vector random_subset(size_t k, size_t n) { 19 | vector x(n); 20 | for (size_t i = 0; i < x.size(); i++) { 21 | x[i] = i; 22 | } 23 | 24 | random_shuffle(x.begin(), x.end()); 25 | 26 | x.resize(k); 27 | return x; 28 | } 29 | 30 | void printMemUsage(const char * headerMessage) { 31 | size_t vms, rss; 32 | getMemUsage(vms, rss); 33 | if(headerMessage != nullptr) { 34 | loginfo << headerMessage << ": " << endl; 35 | } 36 | 37 | loginfo << "VMS: " << Utils::humanizeBytes(vms) << endl; 38 | loginfo << "RSS: " << Utils::humanizeBytes(rss) << endl; 39 | } 40 | 41 | void getMemUsage(size_t& vm_usage, size_t& resident_set) 42 | { 43 | vm_usage = 0; 44 | resident_set = 0; 45 | #ifndef __APPLE__ 46 | using std::ios_base; 47 | using std::ifstream; 48 | using std::string; 49 | 50 | vm_usage = 0; 51 | resident_set = 0; 52 | 53 | // 'file' stat seems to give the most reliable results 54 | // 55 | ifstream stat_stream("/proc/self/stat",ios_base::in); 56 | 57 | // dummy vars for leading entries in stat that we don't care about 58 | // 59 | string pid, comm, state, ppid, pgrp, session, tty_nr; 60 | string tpgid, flags, minflt, cminflt, majflt, cmajflt; 61 | string utime, stime, cutime, cstime, priority, nice; 62 | string O, itrealvalue, starttime; 63 | 64 | // the two fields we want 65 | // 66 | unsigned long vsize; 67 | long rss; 68 | 69 | stat_stream >> pid >> comm >> state >> ppid >> pgrp >> session >> tty_nr 70 | >> tpgid >> flags >> minflt >> cminflt >> majflt >> cmajflt 71 | >> utime >> stime >> cutime >> cstime >> priority >> nice 72 | >> O >> itrealvalue >> starttime >> vsize >> rss; // don't care about the rest 73 | 74 | stat_stream.close(); 75 | 76 | long page_size_bytes = sysconf(_SC_PAGE_SIZE); // in case x86-64 is configured to use 2MB pages 77 | vm_usage = vsize; 78 | resident_set = static_cast(rss * page_size_bytes); 79 | #else 80 | struct proc_taskinfo pti; 81 | pid_t pid = getpid(); 82 | 83 | //long page_size_bytes = sysconf(_SC_PAGE_SIZE); // in case x86-64 is configured to use 2MB pages 84 | 85 | if(sizeof(pti) == proc_pidinfo(pid, PROC_PIDTASKINFO, 0, &pti, sizeof(pti))) { 86 | vm_usage = pti.pti_virtual_size; // / 1024 / PAGE_SIZE_KB; 87 | resident_set = pti.pti_resident_size; // / 1024 / PAGE_SIZE_KB; 88 | } else { 89 | throw std::runtime_error("proc_pidinfo failed"); 90 | } 91 | #endif 92 | } 93 | -------------------------------------------------------------------------------- /libpolycrypto/test/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | set(polycrypto_test_sources 2 | TestAMT.cpp 3 | TestDKGandVSS.cpp 4 | TestKatePublicParams.cpp 5 | TestPolyOps.cpp 6 | TestLagrange.cpp 7 | TestLibff.cpp 8 | TestNizkPok.cpp 9 | TestParallelPairing.cpp 10 | TestPolyDivideXnc.cpp 11 | TestRootsOfUnity.cpp 12 | TestRootsOfUnityEval.cpp 13 | ) 14 | 15 | foreach(appSrc ${polycrypto_test_sources}) 16 | get_filename_component(appName ${appSrc} NAME_WE) 17 | set(appDir ../bin/test) 18 | 19 | add_executable(${appName} ${appSrc}) 20 | target_link_libraries(${appName} PRIVATE polycrypto) 21 | 22 | add_test(NAME ${appName} COMMAND ${appName}) 23 | set_target_properties(${appName} PROPERTIES RUNTIME_OUTPUT_DIRECTORY ${appDir}) 24 | endforeach() 25 | -------------------------------------------------------------------------------- /libpolycrypto/test/TestAMT.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | #include 8 | #include 9 | #include 10 | #include 11 | #include 12 | 13 | #include 14 | #include 15 | #include 16 | 17 | using namespace std; 18 | using namespace libfqfft; 19 | using namespace libpolycrypto; 20 | using Dkg::DkgParams; 21 | 22 | static size_t pow2(size_t exp) { 23 | return 1u << exp; 24 | } 25 | 26 | int main(int argc, char *argv[]) { 27 | libpolycrypto::initialize(nullptr, 0); 28 | srand(static_cast(time(NULL))); 29 | 30 | if(argc > 1 && (std::string(argv[1]) == "-h" || std::string(argv[1]) == "--help")) { 31 | //cout << "Usage: " << argv[0] << "[ ] [r]" << endl; 32 | cout << "Usage: " << argv[0] << "[]" << endl; 33 | cout << endl; 34 | cout << "OPTIONS: " << endl; 35 | //cout << " the degree of the evaluated polynomial + 1" << endl; 36 | cout << " the # of points to evaluate at (i.e., # of AMT leaves)" << endl; 37 | //cout << " the # of times to repeat a test for each (t,n) threshold " << endl; 38 | cout << endl; 39 | 40 | return 1; 41 | } 42 | 43 | size_t maxN = argc > 2 ? static_cast(std::stoi(argv[1])) : 32; 44 | //size_t r = argc > 3 ? static_cast(std::stoi(argv[2])) : 100; 45 | 46 | size_t maxT = maxN - 1; 47 | size_t maxDeg = maxT - 1; 48 | 49 | auto kpp = Dkg::KatePublicParameters::getRandom(maxDeg); 50 | 51 | // NOTE: This code shows that AccumulatorTree's are subsets of one another. 52 | // Just keep in mind that w_{2N}^{2k} = w_N^k. 53 | //for(size_t i = 2; i <= 16; i *= 2) 54 | //{ 55 | // AccumulatorTree accs(i); 56 | // cout << "Size: " << i << endl << accs.toString() << endl << endl; 57 | //} 58 | 59 | // Testing that a_4 is a subset of a_8! 60 | AccumulatorTree a4(4); 61 | AuthAccumulatorTree aa4(a4, kpp, 5); 62 | AccumulatorTree a8(8); 63 | AuthAccumulatorTree aa8(a8, kpp, 9); 64 | 65 | for(size_t level = 0; level < 3; level++) { 66 | for(size_t idx = 0; idx < pow2(2 - level); idx++) { 67 | //logdbg << level << ", " << idx << endl; 68 | testAssertEqual(a4.tree[level][idx], a8.tree[level][idx]); 69 | testAssertEqual(aa4.tree[level][idx], aa8.tree[level][idx]); 70 | } 71 | } 72 | 73 | // Authenticate AccumulatorTree 74 | AccumulatorTree maxAccs(maxN); 75 | AuthAccumulatorTree authAccs(maxAccs, kpp, maxT); 76 | authAccs._assertValid(); 77 | 78 | //for(size_t i = 0; i < r; i++) { 79 | loginfo << "Testing thresholds: " << std::flush; 80 | for(size_t n = 3; n <= maxN; n++) { 81 | for(size_t t = 2; t < n; t++) { 82 | cout << "(" << t << ", " << n << ") " << std::flush; 83 | 84 | std::vector f = random_field_elems(t); 85 | 86 | // Step 1: Fast multipoint eval 87 | DkgParams params(t, n, true); 88 | params.setAuthAccumulators(&authAccs); 89 | RootsOfUnityEvaluation eval(f, *params.accs); 90 | 91 | // Step 2: Authenticate Multipoint Evaluation 92 | //loginfo << "Computing AMT: "; 93 | for(bool isSimulated : { true, false }) { 94 | AuthRootsOfUnityEvaluation authEval(eval, kpp, isSimulated); 95 | 96 | // Verify all monomial commitments 97 | for(size_t i = 0; i < n; i++) { 98 | const auto& vk = params.getMonomialCommitment(i); 99 | //loginfo << "vk[" << i << "]: " << vk << endl; 100 | 101 | testAssertEqual( 102 | kpp.getG2toS() - params.omegas[i] * G2::one(), 103 | vk); 104 | } 105 | } 106 | 107 | // Step 3: Verify all proofs 108 | } 109 | } 110 | //} 111 | cout << endl; 112 | 113 | // TODO: Step 4: Verify AMT proofs 114 | 115 | loginfo << "Exited succsessfully!" << endl; 116 | 117 | return 0; 118 | } 119 | -------------------------------------------------------------------------------- /libpolycrypto/test/TestKatePublicParams.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | #include 9 | #include 10 | #include 11 | 12 | using namespace libpolycrypto; 13 | using namespace Dkg; 14 | using std::endl; 15 | 16 | int main(int argc, char *argv[]) 17 | { 18 | (void)argc; (void)argv; 19 | initialize(nullptr, 0); 20 | srand(42); 21 | 22 | size_t q = argc < 2 ? 4096 : static_cast(std::stoi(argv[1])); 23 | 24 | size_t numChunks = 5; 25 | if(q < numChunks) 26 | throw std::runtime_error("q must be bigger than the # of chunks"); 27 | size_t chunkSize = q / numChunks; 28 | 29 | std::string trapFile = "/tmp/libpolycrypto-test-trapFile"; 30 | Fr s = KatePublicParameters::generateTrapdoor(q, trapFile); 31 | 32 | for(size_t i = 0; i < numChunks; i++) { 33 | size_t start = i*chunkSize; 34 | size_t end = (i < numChunks-1) ? (i+1)*chunkSize : q+1; 35 | 36 | logdbg << "Writing chunk #" << i+1 << ": [" << start << ", " << end << ") ..." << endl; 37 | KatePublicParameters::generate(start, end, s, trapFile + "-" + std::to_string(i), false); 38 | } 39 | 40 | KatePublicParameters pp(trapFile, 0, true, true); 41 | 42 | std::cout << "Test '" << argv[0] << "' finished successfully" << std::endl; 43 | 44 | return 0; 45 | } 46 | -------------------------------------------------------------------------------- /libpolycrypto/test/TestLagrange.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | #include 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | using namespace libpolycrypto; 17 | using namespace std; 18 | using namespace libfqfft; 19 | 20 | using libpolycrypto::Fr; 21 | 22 | int main() { 23 | libpolycrypto::initialize(nullptr, 0); 24 | srand(static_cast(time(NULL))); 25 | 26 | for (size_t f = 2; f < 1024*8; f *= 2) { 27 | // get all roots of unity w_n^k, for k = 0, ..., n-1, where n = 2f+1 28 | size_t n = 2*f + 1; 29 | size_t N = Utils::smallestPowerOfTwoAbove(n); 30 | std::vector omegas = get_all_roots_of_unity(N); 31 | testAssertEqual(omegas.size(), N); 32 | 33 | loginfo << f + 1 << " out of " << n << endl; 34 | 35 | // pick random subset of f+1 w_n^k's 36 | std::vector someOmegas; 37 | std::vector idxs; 38 | Utils::randomSubset(idxs, static_cast(n), static_cast(f + 1)); 39 | for(auto i : idxs) { 40 | someOmegas.push_back(omegas[i]); 41 | } 42 | testAssertEqual(someOmegas.size(), f + 1); 43 | 44 | // computes lagrange coefficients L_i(0) w.r.t. to the points in 'someOmegas' 45 | std::vector L, L_naive; 46 | lagrange_coefficients(L, omegas, someOmegas, idxs); 47 | lagrange_coefficients_naive(L_naive, omegas, someOmegas, idxs); 48 | 49 | testAssertEqual(L, L_naive); 50 | 51 | //logdbg << "L = " << endl << L << endl; 52 | //logdbg << endl; 53 | //logdbg << "L_naive = " << endl << L << endl; 54 | } 55 | 56 | loginfo << "Test ended successfully!" << endl; 57 | return 0; 58 | } 59 | -------------------------------------------------------------------------------- /libpolycrypto/test/TestLibff.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | 5 | #include 6 | #include 7 | 8 | using namespace libpolycrypto; 9 | 10 | int main(int argc, char *argv[]) 11 | { 12 | (void)argc; (void)argv; 13 | 14 | libpolycrypto::initialize(nullptr, 0); 15 | 16 | // libff naming weirdness that I'm trying to understand: 17 | // zero() is the group's identity (since ECs use additive notation) 18 | // one() is the group's generator 19 | 20 | std::clog << "G1 zero: " << G1::zero() << std::endl; 21 | std::clog << "G1 one: " << G1::one() << std::endl; 22 | testAssertNotEqual(G1::one(), G1::zero()); 23 | 24 | std::clog << "G2 zero: " << G2::zero() << std::endl; 25 | std::clog << "G2 one: " << G2::one() << std::endl; 26 | testAssertNotEqual(G2::one(), G2::zero()); 27 | 28 | // a, b <-$- random 29 | Fr a = Fr::random_element(), b = Fr::random_element(); 30 | // compute (ab) 31 | Fr ab = a * b; 32 | // g1^a 33 | G1 g1a = a * G1::one(); 34 | // g2^a 35 | G2 g2b = b * G2::one(); 36 | // gt^(ab) 37 | 38 | // test some simple arithmetic 39 | testAssertEqual(b*g1a, (ab)*G1::one()); 40 | testAssertEqual(a*g2b, (ab)*G2::one()); 41 | 42 | // Get generator in GT 43 | GT gt = ReducedPairing(G1::one(), G2::one()); 44 | 45 | // test pairing 46 | GT gt_ab = gt^(ab); 47 | 48 | testAssertEqual( 49 | gt_ab, 50 | ReducedPairing(g1a, g2b)); 51 | 52 | testAssertEqual( 53 | gt_ab, 54 | ReducedPairing(g1a, G2::one())^b); 55 | 56 | testAssertEqual( 57 | gt_ab, 58 | ReducedPairing(G1::one(), g2b)^a); 59 | 60 | std::cout << "Test '" << argv[0] << "' finished successfully" << std::endl; 61 | 62 | return 0; 63 | } 64 | -------------------------------------------------------------------------------- /libpolycrypto/test/TestNizkPok.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | using namespace libpolycrypto; 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | (void)argc; (void)argv; 14 | 15 | libpolycrypto::initialize(nullptr, 0); 16 | 17 | for(size_t i = 0; i < 128; i++) { 18 | Fr x = Fr::random_element(); 19 | Fr y = Fr::random_element(); 20 | G1 g = G1::one(); 21 | G1 h = G1::random_element(); 22 | G1 gToX = x * g; 23 | 24 | NizkPok pi = NizkPok::prove(g, x, gToX); 25 | testAssertTrue(NizkPok::verify(pi, g, gToX)); 26 | testAssertFalse(NizkPok::verify(pi, h, gToX)); 27 | testAssertFalse(NizkPok::verify(pi, g, y*g)); 28 | testAssertFalse(NizkPok::verify(pi, h, y*g)); 29 | } 30 | 31 | std::cout << "Test '" << argv[0] << "' finished successfully" << std::endl; 32 | 33 | return 0; 34 | } 35 | -------------------------------------------------------------------------------- /libpolycrypto/test/TestParallelPairing.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | using namespace std; 12 | using namespace libpolycrypto; 13 | 14 | int main(int argc, char *argv[]) { 15 | (void)argc; 16 | (void)argv; 17 | libpolycrypto::initialize(nullptr, 0); 18 | 19 | size_t numIters = 100; 20 | 21 | #ifdef USE_MULTITHREADING 22 | loginfo << "Multithreading enabled!" << endl; 23 | #else 24 | loginfo << "Multithreading disabled!" << endl; 25 | #endif 26 | 27 | std::vector a(numIters); 28 | std::vector b(numIters); 29 | 30 | #ifdef USE_MULTITHREADING 31 | #pragma omp parallel for 32 | #endif 33 | for(size_t i = 0; i < numIters; i++) { 34 | a[i] = G1::random_element(); 35 | b[i] = G2::random_element(); 36 | } 37 | 38 | loginfo << "Picked " << numIters << " random group elements in G1 and G2" << endl; 39 | 40 | #ifdef USE_MULTITHREADING 41 | #pragma omp parallel for 42 | #endif 43 | for(size_t i = 0; i < numIters; i++) { 44 | // TODO: this seems to crash for some reason. 45 | //ReducedPairing(a[i], b[i]); 46 | libff::default_ec_pp::reduced_pairing(a[i], b[i]); 47 | } 48 | 49 | loginfo << "All tests succeeded!" << endl; 50 | 51 | return 0; 52 | } 53 | -------------------------------------------------------------------------------- /libpolycrypto/test/TestPolyDivideXnc.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | #include 7 | #include 8 | 9 | using namespace libpolycrypto; 10 | 11 | int main(int argc, char *argv[]) 12 | { 13 | (void)argc; (void)argv; 14 | 15 | libpolycrypto::initialize(nullptr, 0); 16 | 17 | size_t count = 100; 18 | if(argc > 1 && strcmp(argv[1], "-h") == 0) { 19 | cout << "Usage: " << argv[0] << " " << endl; 20 | cout << endl; 21 | cout << "Divides random poly a(x) (of deg n) by b(x) = x^m - c (of deg m), doubles their degrees and repeats " << count << " times." << endl; 22 | return 1; 23 | } 24 | 25 | size_t a_deg = argc < 3 ? 8 : static_cast(std::stoi(argv[1])); 26 | size_t b_deg = argc < 3 ? 4 : static_cast(std::stoi(argv[2])); 27 | 28 | loginfo << "Dividing a (of deg n) by b (of deg m)..." << endl << endl; 29 | 30 | for(size_t i = 0; i < count; i++) { 31 | size_t n = a_deg*(i+1); // degree of a 32 | size_t m = b_deg*(i+1); // degree of b 33 | 34 | loginfo << "n = " << n << ", m = " << m << endl; 35 | 36 | vector a = random_field_elems(n+1); 37 | 38 | XncPoly b(m, Fr::random_element()); 39 | //poly_print(a); std::cout << endl; 40 | 41 | vector q, r, rhs; 42 | poly_divide_xnc(a, b, q, r); 43 | 44 | // INVARIANT: deg(r) < deg(b) 45 | testAssertStrictlyLessThan(r.size(), m + 1); 46 | if(a.size() >= b.n + 1) { 47 | testAssertEqual(q.size(), n - m + 1); 48 | } 49 | 50 | libfqfft::_polynomial_multiplication(rhs, b.toLibff(), q); 51 | libfqfft::_polynomial_addition(rhs, rhs, r); 52 | 53 | //poly_print(a); std::cout << endl; 54 | //poly_print(rhs); std::cout << endl; 55 | testAssertEqual(a, rhs); 56 | } 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /libpolycrypto/test/TestPolyOps.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | 3 | #include 4 | #include 5 | 6 | 7 | 8 | #include 9 | #include 10 | 11 | using namespace libpolycrypto; 12 | 13 | std::vector poly_from_roots_naive(const std::vector& roots) { 14 | std::vector monom(2), acc(1, Fr::one()); 15 | for(size_t i = 0; i < roots.size(); i++) { 16 | Fr r = roots[i]; 17 | //logdbg << "Multiplying in root " << r << endl; 18 | 19 | monom[0] = -r; 20 | monom[1] = 1; 21 | libfqfft::_polynomial_multiplication_on_fft(acc, acc, monom); 22 | 23 | testAssertEqual(acc.size(), i+2); 24 | 25 | //poly_print(acc); 26 | } 27 | 28 | return acc; 29 | } 30 | 31 | int main(int argc, char *argv[]) 32 | { 33 | (void)argc; (void)argv; 34 | 35 | libpolycrypto::initialize(nullptr, 0); 36 | 37 | const size_t maxSize = 64; 38 | std::vector roots; 39 | for(size_t i = 0; i < maxSize; i++) { 40 | roots.push_back(Fr::random_element()); 41 | loginfo << "Testing interpolation from " << i+1 << " roots..." << endl; 42 | 43 | auto expected = poly_from_roots_naive(roots); 44 | auto computed = poly_from_roots(roots); 45 | 46 | testAssertEqual(computed.size(), roots.size() + 1); 47 | testAssertEqual(expected, computed); 48 | } 49 | 50 | return 0; 51 | } 52 | -------------------------------------------------------------------------------- /libpolycrypto/test/TestRootsOfUnityEval.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | #include 6 | #include 7 | #include 8 | #include 9 | #include 10 | 11 | #include 12 | #include 13 | #include 14 | 15 | #include 16 | #include 17 | 18 | using namespace std; 19 | using namespace libfqfft; 20 | using namespace libpolycrypto; 21 | 22 | void assertEvals(const std::vector& f, const std::vector& evals, size_t numPoints); 23 | 24 | void testRootsOfUnityEvaluation(size_t deg, const AccumulatorTree& accs) { 25 | size_t numPoints = accs.getNumPoints(); 26 | 27 | std::vector f = random_field_elems(deg+1); 28 | 29 | RootsOfUnityEvaluation eval(f, accs); 30 | 31 | testAssertTrue(eval._testIsConsistent()); 32 | 33 | std::vector evals = eval.getEvaluations(); 34 | assertEvals(f, evals, numPoints); 35 | } 36 | 37 | void testMultipointMerging(size_t deg, const AccumulatorTree& accs) { 38 | size_t numPoints = accs.getNumPoints(); 39 | 40 | std::vector f1, f2, f3; 41 | f1 = random_field_elems(deg+1); 42 | f2 = random_field_elems(deg+1); 43 | 44 | libfqfft::_polynomial_addition(f3, f1, f2); 45 | 46 | // evaluate f1 and f2 47 | RootsOfUnityEvaluation eval1(f1, accs); 48 | RootsOfUnityEvaluation eval2(f2, accs); 49 | 50 | testAssertTrue(eval1._testIsConsistent()); 51 | testAssertTrue(eval2._testIsConsistent()); 52 | assertEvals(f1, eval1.getEvaluations(), numPoints); 53 | assertEvals(f2, eval2.getEvaluations(), numPoints); 54 | 55 | // merge the evaluation of f1(x) and f2(x) to get the evaluation tree of their sum (f1+f2)(x) 56 | eval1 += eval2; 57 | 58 | testAssertTrue(eval1._testIsConsistent()); 59 | assertEvals(f3, eval1.getEvaluations(), numPoints); 60 | } 61 | 62 | int main() { 63 | libpolycrypto::initialize(nullptr, 0); 64 | 65 | for (size_t numPoints = 2; numPoints <= 32; numPoints++) { 66 | for (size_t deg = 1; deg <= 32; deg++) { 67 | loginfo << "Evaluating degree " << deg << " polynomials at the first " << numPoints << " roots of unity" << endl; 68 | AccumulatorTree accs(numPoints); 69 | testRootsOfUnityEvaluation(deg, accs); 70 | testMultipointMerging(deg, accs); 71 | } 72 | } 73 | 74 | loginfo << "Test passed!" << endl; 75 | 76 | return 0; 77 | } 78 | 79 | void assertEvals(const std::vector& f, const std::vector& evals, size_t numPoints) { 80 | std::vector actual; 81 | 82 | auto omegas = get_all_roots_of_unity(numPoints); 83 | for(size_t i = 0; i < numPoints; i++) { 84 | Fr v = libfqfft::evaluate_polynomial(f.size(), f, omegas[i]); 85 | actual.push_back(v); 86 | } 87 | 88 | for(size_t i = 0; i < evals.size(); i++) { 89 | if(evals[i] != actual[i]) { 90 | logdbg << "The multipoint evaluation function returned a different f(\\omega^" 91 | << i << ")!" << endl; 92 | logdbg << " * Eval: " << evals[i] << endl; 93 | logdbg << " * Actual: " << actual[i] << endl; 94 | throw std::runtime_error("The multipoint evaluation function is wrong!"); 95 | } else { 96 | //logdbg << "At point w_n^" << i << " = " << evals[i] << endl; 97 | } 98 | } 99 | } 100 | -------------------------------------------------------------------------------- /public-params/.gitignore: -------------------------------------------------------------------------------- 1 | /1048576 2 | -------------------------------------------------------------------------------- /public-params/65536/65536: -------------------------------------------------------------------------------- 1 | 9755664001534477976373346953458667014047014860280947403107771413787640486060 2 | 65536 3 | -------------------------------------------------------------------------------- /public-params/65536/65536-0.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinush/libpolycrypto/89a69ed90ee4e9287222cc5781ff11562286f454/public-params/65536/65536-0.log -------------------------------------------------------------------------------- /public-params/65536/65536-1.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinush/libpolycrypto/89a69ed90ee4e9287222cc5781ff11562286f454/public-params/65536/65536-1.log -------------------------------------------------------------------------------- /public-params/65536/65536-10.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinush/libpolycrypto/89a69ed90ee4e9287222cc5781ff11562286f454/public-params/65536/65536-10.log -------------------------------------------------------------------------------- /public-params/65536/65536-11.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinush/libpolycrypto/89a69ed90ee4e9287222cc5781ff11562286f454/public-params/65536/65536-11.log -------------------------------------------------------------------------------- /public-params/65536/65536-2.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinush/libpolycrypto/89a69ed90ee4e9287222cc5781ff11562286f454/public-params/65536/65536-2.log -------------------------------------------------------------------------------- /public-params/65536/65536-3.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinush/libpolycrypto/89a69ed90ee4e9287222cc5781ff11562286f454/public-params/65536/65536-3.log -------------------------------------------------------------------------------- /public-params/65536/65536-4.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinush/libpolycrypto/89a69ed90ee4e9287222cc5781ff11562286f454/public-params/65536/65536-4.log -------------------------------------------------------------------------------- /public-params/65536/65536-5.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinush/libpolycrypto/89a69ed90ee4e9287222cc5781ff11562286f454/public-params/65536/65536-5.log -------------------------------------------------------------------------------- /public-params/65536/65536-6.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinush/libpolycrypto/89a69ed90ee4e9287222cc5781ff11562286f454/public-params/65536/65536-6.log -------------------------------------------------------------------------------- /public-params/65536/65536-7.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinush/libpolycrypto/89a69ed90ee4e9287222cc5781ff11562286f454/public-params/65536/65536-7.log -------------------------------------------------------------------------------- /public-params/65536/65536-8.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinush/libpolycrypto/89a69ed90ee4e9287222cc5781ff11562286f454/public-params/65536/65536-8.log -------------------------------------------------------------------------------- /public-params/65536/65536-9.log: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/alinush/libpolycrypto/89a69ed90ee4e9287222cc5781ff11562286f454/public-params/65536/65536-9.log -------------------------------------------------------------------------------- /scripts/linux/cmake.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | scriptdir=$(cd $(dirname $0); pwd -P) 5 | sourcedir=$(cd $scriptdir/../..; pwd -P) 6 | . $scriptdir/shlibs/check-env.sh 7 | . $scriptdir/shlibs/os.sh 8 | 9 | $scriptdir/submodule-update.sh 10 | 11 | builddir=$POLYCRYPTO_BUILD_DIR 12 | mkdir -p "$builddir" 13 | cd "$builddir" 14 | 15 | #if [ "$OS" = "Linux" ]; then 16 | # export CXX=clang++ 17 | #fi 18 | cmake $POLYCRYPTO_CMAKE_ARGS $@ "$sourcedir" 19 | -------------------------------------------------------------------------------- /scripts/linux/cols.sh: -------------------------------------------------------------------------------- 1 | print_usage() { 2 | echo "Usage: $0 [ ...] " 3 | echo 4 | echo "You can use 'all' for ." 5 | echo 6 | echo "Example: $0 some-file.csv other-file.csv 1,4,5" 7 | echo "Example: $0 some-file.csv all" 8 | } 9 | 10 | get_num_cols() { 11 | file1=$1 12 | num_cols=0; 13 | for f in `cat "$file1" | head -n 1 | tr ',' '\n'`; do 14 | num_cols=$((num_cols+1)) 15 | done 16 | echo $num_cols 17 | } 18 | 19 | get_cols() { 20 | file1=$1 21 | echo 22 | num_cols=0; 23 | for f in `cat "$file1" | head -n 1 | tr ',' '\n'`; do 24 | num_cols=$((num_cols+1)) 25 | echo $num_cols - $f 26 | done 27 | } 28 | 29 | assert_same_cols() { 30 | prev_file=$1 31 | prev_cols=`get_cols $prev_file` 32 | shift 33 | 34 | while [ $# -gt 0 ]; do 35 | cols=`get_cols $1` 36 | 37 | if [ "$prev_cols" != "$cols" ]; then 38 | echo "ERROR: '$file1' and '$1' have different columns!" 39 | echo 40 | echo "$prev_file:" 41 | echo "$prev_cols" 42 | echo 43 | echo "$1:" 44 | echo "$cols" 45 | 46 | exit 1 47 | fi 48 | 49 | shift 50 | done 51 | } 52 | 53 | hscroll_size=20 54 | 55 | file1=$1 56 | shift 57 | files=$file1 58 | 59 | while [ -f $1 ] && [ $# -gt 0 ]; do 60 | files="$files $1" 61 | shift 62 | done 63 | 64 | # INVARIANT: every file in $files exists and we might have extra argument(s) that are NOT files 65 | 66 | # if we parsed all files from command args and no columns were specified as args, then print usage, then print the columns, then exit (see next chunks) 67 | if [ $# -eq 0 ]; then 68 | print_usage 69 | if [ -z "$files" ]; then 70 | exit 71 | fi 72 | fi 73 | 74 | if [ $# -gt 1 ]; then 75 | shift 76 | echo "ERROR: You gave $(($#-1)) extra argument(s): $@" 77 | echo 78 | print_usage 79 | exit 1 80 | fi 81 | 82 | assert_same_cols $files 83 | 84 | arg_cols=$1 85 | num_cols=`get_num_cols $file1` 86 | 87 | # print fields of CSV file, even if args are bad 88 | echo 89 | echo "Columns in files $files:" 90 | echo "$(get_cols $file1)" 91 | 92 | # exit, if no columns were specified 93 | if [ $# -lt 1 ]; then 94 | exit 1 95 | fi 96 | 97 | # if 'all' columns were specified then build comma separated list of all columns 98 | if [ "$arg_cols" == "all" ]; then 99 | sel_cols="1" 100 | for c in `seq 2 $num_cols`; do 101 | sel_cols="$sel_cols,$c" 102 | done 103 | else 104 | sel_cols=$arg_cols 105 | fi 106 | first_col=`echo $sel_cols | cut -f1 -d,` 107 | 108 | echo "Columns: $sel_cols" 109 | echo "Sort by column: $first_col" 110 | echo "Files: $files" 111 | 112 | ( head -n 1 $file1; for f in $files; do tail -n +2 $f; done | sort -g -t',' -k$first_col ) | cut -d',' -f$sel_cols | sed -e 's/,,/, ,/g' | column -s, -t | less -#$hscroll_size -N -S 113 | -------------------------------------------------------------------------------- /scripts/linux/dkg-cols.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | scriptdir=$(cd $(dirname $0); pwd -P) 5 | 6 | if [ $# -lt 1 ]; then 7 | echo "Usage: $0 [ ...]" 8 | exit 1 9 | fi 10 | 11 | $scriptdir/cols.sh "$@" 1,2,3,4,5,6,7,8,9,15,16,17,18,19 12 | -------------------------------------------------------------------------------- /scripts/linux/generate-qsdh-params.sh: -------------------------------------------------------------------------------- 1 | #!/bin/sh 2 | 3 | set -e 4 | 5 | scriptdir=$(cd $(dirname $0); pwd -P) 6 | . $scriptdir/shlibs/os.sh 7 | 8 | if [ $# -ne 2 ]; then 9 | echo "Usage: $0 " 10 | exit 1 11 | fi 12 | 13 | trap_file=$1; shift 1; 14 | q=$1; shift 1; 15 | num_chunks=$NUM_CPUS 16 | 17 | if [ $q -lt $num_chunks ]; then 18 | num_chunks=$q 19 | fi 20 | 21 | chunk_size=$(($q/$num_chunks)) 22 | 23 | echo "Generating q-SDH params in '$trap_file' (q = $q, numChunks = $NUM_CPUS, chunk_size = $chunk_size) ..." 24 | 25 | ParamsGenTrapdoors "$trap_file" $q 26 | 27 | for i in `seq 0 $(($num_chunks-1))`; do 28 | start=$(($i * $chunk_size)) 29 | if [ $i -lt $(($num_chunks - 1)) ]; then 30 | end=$((($i+1) * $chunk_size)) 31 | else 32 | end=$(($q+1)) 33 | fi 34 | 35 | echo "Generating [$start, $end) ..." 36 | # Send to background 37 | out_file=${trap_file}-$i 38 | ParamsGenPowers "$trap_file" "$out_file" $start $end &>$out_file.log & 39 | done 40 | -------------------------------------------------------------------------------- /scripts/linux/humanize-csv.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2.7 2 | 3 | import math 4 | import os 5 | import pandas 6 | import sys 7 | import time 8 | import matplotlib.pyplot as plt 9 | from matplotlib.ticker import FuncFormatter 10 | from matplotlib.dates import MonthLocator, DateFormatter, DayLocator, epoch2num, num2date 11 | 12 | def print_usage(cmd_name): 13 | print "Usage:", cmd_name, " [] []" 14 | 15 | cmd_path = sys.argv[0] 16 | cmd_name = os.path.basename(cmd_path) 17 | 18 | if len(sys.argv) < 2: 19 | print_usage(cmd_name) 20 | sys.exit(0) 21 | 22 | def humanizeMicroseconds(mus, precision = 2): 23 | result = float(mus) 24 | units = [ "mus", "ms", "secs", "mins", "hrs", "days", "years" ] 25 | numUnits = len(units) 26 | i = 0 27 | 28 | while result >= 1000.0 and i < 2: 29 | result /= 1000.0 30 | i = i+1 31 | 32 | while result >= 60.0 and i >= 2 and i < 4: 33 | result /= 60.0 34 | i = i+1 35 | 36 | if i == 4 and result >= 24.0: 37 | result /= 24.0 38 | i = i+1 39 | 40 | if i == 5 and result >= 365.25: 41 | result /= 365.25 42 | i = i+1 43 | 44 | assert(i < numUnits) 45 | string = ("{:." + str(precision) + "f}").format(result) 46 | string += " " 47 | string += units[i] 48 | 49 | return string 50 | 51 | del sys.argv[0] 52 | 53 | data_files = [ sys.argv[0] ] 54 | del sys.argv[0] 55 | 56 | usec_col=None 57 | hum_col=None 58 | 59 | if len(sys.argv) >= 1: 60 | usec_col = sys.argv[0] 61 | del sys.argv[0] 62 | 63 | if len(sys.argv) >= 1: 64 | hum_col = sys.argv[0] 65 | del sys.argv[0] 66 | else: 67 | print "ERROR: Must specify after " 68 | print 69 | print_usage(cmd_name) 70 | sys.exit(1) 71 | 72 | csv_data = pandas.concat((pandas.read_csv(f) for f in data_files)) 73 | 74 | cols = list(csv_data.columns.values) 75 | 76 | print csv_data.to_string(); 77 | 78 | if usec_col is not None: 79 | for idx, r in csv_data.iterrows(): 80 | if r[usec_col] != 'todo' and str(r[usec_col]) != 'nan': 81 | csv_data.ix[idx, hum_col] = humanizeMicroseconds(int(r[usec_col])) 82 | 83 | else: 84 | for c_usec in cols: 85 | if c_usec.endswith("_usec"): 86 | c_hum = c_usec[:-5] + "_hum" 87 | print c_usec 88 | print c_hum 89 | 90 | for idx, r in csv_data.iterrows(): 91 | if r[c_usec] != 'todo' and str(r[c_usec]) != 'nan': 92 | csv_data.ix[idx, c_hum] = humanizeMicroseconds(int(r[c_usec])) 93 | 94 | print csv_data.to_string(); 95 | 96 | csv_data.to_csv(data_files[0], float_format='%f', index=False); 97 | -------------------------------------------------------------------------------- /scripts/linux/install-deps.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | scriptdir=$(cd $(dirname $0); pwd -P) 5 | sourcedir=$(cd $scriptdir/../..; pwd -P) 6 | 7 | sudo apt-get install cmake clang 8 | -------------------------------------------------------------------------------- /scripts/linux/install-libs.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | scriptdir=$(cd $(dirname $0); pwd -P) 5 | sourcedir=$(cd $scriptdir/../..; pwd -P) 6 | 7 | . $scriptdir/shlibs/os.sh 8 | 9 | CLEAN_BUILD=0 10 | if [ "$1" == "debug" ]; then 11 | echo "Debug build..." 12 | echo 13 | ATE_PAIRING_FLAGS="DBG=on" 14 | elif [ "$1" == "clean" ]; then 15 | CLEAN_BUILD=1 16 | fi 17 | 18 | # NOTE: Seemed like setting this to OFF caused a simple cout << G1::zero(); to segfault but it was just that I forgot to call init_public_params() 19 | BINARY_OUTPUT=OFF 20 | NO_PT_COMPRESSION=ON 21 | MULTICORE=ON 22 | if [ "$OS" == "OSX" ]; then 23 | # libff's multicore implementation uses OpenMP which clang on OS X apparently doesn't support 24 | MULTICORE=OFF 25 | fi 26 | 27 | ( 28 | cd $sourcedir/ 29 | git submodule init 30 | git submodule update 31 | ) 32 | 33 | # install libxassert and libxutils 34 | 35 | ( 36 | cd /tmp 37 | mkdir -p libpolycrypto-deps/ 38 | cd libpolycrypto-deps/ 39 | 40 | for lib in `echo libxassert; echo libxutils`; do 41 | if [ ! -d $lib ]; then 42 | git clone https://github.com/alinush/$lib.git 43 | fi 44 | 45 | echo 46 | echo "Installing $lib..." 47 | echo 48 | 49 | ( 50 | cd $lib/ 51 | mkdir -p build/ 52 | cd build/ 53 | cmake -DCMAKE_BUILD_TYPE=Release .. 54 | cmake --build . 55 | sudo cmake --build . --target install 56 | ) 57 | done 58 | 59 | ) 60 | 61 | cd $sourcedir/depends 62 | 63 | # NOTE TO SELF: After one day of trying to get CMake to add these using ExternalProject_Add (or add_subdirectory), I give up. 64 | 65 | ( 66 | cd ate-pairing/ 67 | if [ $CLEAN_BUILD -eq 1 ]; then 68 | echo "Cleaning previous build..." 69 | echo 70 | make clean 71 | fi 72 | make -C src \ 73 | SUPPORT_SNARK=1 \ 74 | $ATE_PAIRING_FLAGS 75 | 76 | INCL_DIR=/usr/local/include/ate-pairing 77 | sudo mkdir -p "$INCL_DIR" 78 | sudo cp include/bn.h "$INCL_DIR" 79 | sudo cp include/zm.h "$INCL_DIR" 80 | sudo cp include/zm2.h "$INCL_DIR" 81 | # WARNING: Need this due to a silly #include "depends/[...]" directive from libff 82 | # (/usr/local/include/libff/algebra/curves/bn128/bn128_g1.hpp:12:44: fatal error: depends/ate-pairing/include/bn.h: No such file or directory) 83 | sudo mkdir -p "$INCL_DIR/../depends/ate-pairing/" 84 | sudo ln -sf "$INCL_DIR" "$INCL_DIR/../depends/ate-pairing/include" 85 | 86 | LIB_DIR=/usr/local/lib 87 | sudo cp lib/libzm.a "$LIB_DIR" 88 | # NOTE: Not sure why, but getting error at runtime that this cannot be loaded. Maybe it should be zm.so? 89 | #sudo cp lib/zm.so "$LIB_DIR/libzm.so" 90 | ) 91 | 92 | ( 93 | cd libff/ 94 | if [ $CLEAN_BUILD -eq 1 ]; then 95 | echo "Cleaning previous build..." 96 | echo 97 | rm -rf build/ 98 | fi 99 | mkdir -p build/ 100 | cd build/ 101 | # WARNING: Does not link correctly with -DPERFORMANCE=ON 102 | cmake \ 103 | -DCMAKE_BUILD_TYPE=RelWithDebInfo \ 104 | -DCMAKE_INSTALL_PREFIX=/usr/local \ 105 | -DIS_LIBFF_PARENT=OFF \ 106 | -DBINARY_OUTPUT=$BINARY_OUTPUT \ 107 | -DNO_PT_COMPRESSION=$NO_PT_COMPRESSION \ 108 | -DCMAKE_CXX_FLAGS="-Wno-unused-parameter -Wno-unused-value -Wno-unused-variable -I$sourcedir" \ 109 | -DUSE_ASM=ON \ 110 | -DPERFORMANCE=OFF \ 111 | -DMULTICORE=$MULTICORE \ 112 | -DCURVE="BN128" \ 113 | -DWITH_PROCPS=OFF .. 114 | 115 | make 116 | sudo make install 117 | ) 118 | 119 | ( 120 | # NOTE: Headers-only library 121 | cd libfqfft/ 122 | 123 | INCL_DIR=/usr/local/include/libfqfft 124 | sudo mkdir -p "$INCL_DIR" 125 | sudo cp -r libfqfft/* "$INCL_DIR/" 126 | sudo rm "$INCL_DIR/CMakeLists.txt" 127 | ) 128 | -------------------------------------------------------------------------------- /scripts/linux/make.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | scriptdir=$(cd $(dirname $0); pwd -P) 5 | sourcedir=$(cd $scriptdir/../..; pwd -P) 6 | . $scriptdir/shlibs/os.sh 7 | . $scriptdir/shlibs/check-env.sh 8 | 9 | builddir=$POLYCRYPTO_BUILD_DIR 10 | 11 | echo "Making in '$builddir' ..." 12 | echo 13 | [ ! -d "$builddir" ] && $scriptdir/cmake.sh 14 | cd "$builddir" 15 | make -j $NUM_CPUS $@ 16 | -------------------------------------------------------------------------------- /scripts/linux/plot-bandwidth.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python2.7 2 | 3 | import matplotlib 4 | matplotlib.use('Agg') # otherwise script does not work when invoked over SSH 5 | from cycler import cycler 6 | import matplotlib.pyplot as plt 7 | import matplotlib.ticker as plticker 8 | import pandas 9 | import sys 10 | import time 11 | import numpy as np 12 | 13 | setTitle=False 14 | 15 | if len(sys.argv) < 5: 16 | print "Usage:", sys.argv[0], " [] ..." 17 | sys.exit(0) 18 | 19 | del sys.argv[0] 20 | 21 | out_png_file = sys.argv[0] 22 | del sys.argv[0] 23 | 24 | dkgs_allowed = sys.argv[0].split(",") 25 | del sys.argv[0] 26 | 27 | minN = int(sys.argv[0]) 28 | del sys.argv[0] 29 | 30 | maxN = int(sys.argv[0]) 31 | del sys.argv[0] 32 | 33 | if not out_png_file.endswith('.png'): 34 | print "ERROR: Expected .png file as first argument" 35 | sys.exit(1) 36 | 37 | data_files = [f for f in sys.argv] 38 | 39 | print "Reading CSV files:", data_files, "..." 40 | 41 | csv_data = pandas.concat((pandas.read_csv(f) for f in data_files)) 42 | 43 | #print "Raw:" 44 | #print csv_data.to_string() 45 | #print csv_data.columns 46 | #print csv_data['dictSize'].values 47 | 48 | #print "Averaged:" 49 | 50 | if minN == 0: 51 | minN = csv_data.n.unique().min(); 52 | if maxN == 0: 53 | maxN = csv_data.n.unique().max(); 54 | 55 | print "min N:", minN 56 | print "max N:", maxN 57 | 58 | # we specify the DKGs here in a specific order so they are plotted with the right colors 59 | dkgs = [ "eJF-DKG", "AMT DKG", "JF-DKG" ] 60 | csv_data.dkg.replace('Feldman', 'JF-DKG', inplace=True) 61 | csv_data.dkg.replace('Kate et al', 'eJF-DKG', inplace=True) 62 | csv_data.dkg.replace('AMT', 'AMT DKG', inplace=True) 63 | 64 | #csv_data = csv_data[csv_data.dkg != 'Feldman'] 65 | csv_data = csv_data[csv_data.n >= minN] 66 | csv_data = csv_data[csv_data.n <= maxN] 67 | 68 | csv_data.download_bw_bytes /= 1024*1024 # bytes to MB 69 | csv_data.upload_bw_bytes /= 1024*1024 # bytes to MB 70 | 71 | print csv_data.to_string() # print all data 72 | 73 | #SMALL_SIZE = 10 74 | MEDIUM_SIZE = 20 75 | BIG_SIZE = 24 76 | BIGGER_SIZE = 28 77 | BIGGEST_SIZE = 32 78 | 79 | plt.rc('lines', linewidth=3, markersize=8, markeredgewidth=3) # width of graph line & size of marker on graph line for data point 80 | plt.rc('font', size= BIGGER_SIZE) # controls default text sizes 81 | #plt.rc('axes', titlesize= BIGGER_SIZE) # fontsize of the axes title 82 | #plt.rc('axes', labelsize= MEDIUM_SIZE) # fontsize of the x and y labels 83 | plt.rc('xtick', labelsize= BIG_SIZE) 84 | plt.rc('ytick', labelsize= BIG_SIZE) 85 | plt.rc('legend', fontsize= BIGGER_SIZE) 86 | #plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title 87 | 88 | #plt.rcParams['axes.prop_cycle'] = cycler(color='bgrcmyk') 89 | plt.rcParams['axes.prop_cycle'] = cycler(color=[ 90 | '#1f77b4', # blue 91 | '#1f77b4', # blue 92 | '#ff7f0e', # orange 93 | '#ff7f0e', # orange 94 | ]) 95 | 96 | print "DKGs in file:", csv_data.dkg.unique() 97 | print "DKGs known: ", dkgs 98 | 99 | def plotNumbers(data): 100 | x = data.n.unique() #.unique() # x-axis is the number of total players n 101 | 102 | #logBase = 10 103 | logBase = 2 104 | 105 | print "Plotting with log base", logBase 106 | 107 | # adjust the size of the plot: (20, 10) is bigger than (10, 5) in the 108 | # sense that fonts will look smaller on (20, 10) 109 | fig, ax1 = plt.subplots(figsize=(12,7.5)) 110 | ax1.set_xscale("log", basex=logBase) 111 | ax1.set_yscale("log") 112 | #ax1.set_xlabel("Total # of players n") 113 | if setTitle: 114 | ax1.set_title('DKG per-player bandwidth') #, fontsize=fontsize) 115 | #ax1.set_ylabel("Bandwidth (in MB)") #, fontsize=fontsize) 116 | ax1.grid(True) 117 | 118 | plots1 = [] 119 | names1 = [] 120 | 121 | #plt.xticks(x, x, rotation=30) 122 | for dkg in dkgs: 123 | if dkg not in dkgs_allowed: 124 | print "Skipping over disallowed:", dkg 125 | continue 126 | 127 | filtered = data[data.dkg == dkg] 128 | col1 = filtered.download_bw_bytes.values 129 | 130 | assert len(x) == len(col1) 131 | plt1, = ax1.plot(x, col1, linestyle="-", marker="o") 132 | plots1.append(plt1) 133 | names1.append(str(dkg) + " download") 134 | 135 | col1 = filtered.upload_bw_bytes.values 136 | 137 | assert len(x) == len(col1) 138 | plt1, = ax1.plot(x, col1, linestyle="--", marker="x") 139 | plots1.append(plt1) 140 | names1.append(str(dkg) + " upload") 141 | 142 | #plt.xticks(x, x, rotation=30) 143 | 144 | ax1.set_xticks(x) 145 | ax1.set_xticklabels(np.log2(x).astype(int), rotation=30) 146 | 147 | locmaj = plticker.LogLocator(base=10,numticks=12) 148 | ax1.yaxis.set_major_locator(locmaj) 149 | locmin = plticker.LogLocator(base=10.0,numticks=12) #,subs=(0.2,0.4,0.6,0.8) 150 | ax1.yaxis.set_minor_locator(locmin) 151 | ax1.yaxis.set_minor_formatter(plticker.NullFormatter()) 152 | 153 | ax1.legend(plots1, 154 | names1, 155 | loc='upper left')#, fontsize=fontsize 156 | 157 | plt.tight_layout() 158 | #date = time.strftime("%Y-%m-%d-%H-%M-%S") 159 | #out_png_file = 'append-only-proofs-' + date + '.png' 160 | plt.savefig(out_png_file, bbox_inches='tight') 161 | plt.close() 162 | 163 | plotNumbers(csv_data) 164 | 165 | #plt.xticks(fontsize=fontsize) 166 | #plt.yticks(fontsize=fontsize) 167 | plt.show() 168 | -------------------------------------------------------------------------------- /scripts/linux/plot-deal-times.py: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env python3 2 | 3 | import matplotlib.pyplot as plt 4 | import matplotlib.ticker as plticker 5 | import pandas 6 | import sys 7 | import time 8 | import numpy as np 9 | 10 | if len(sys.argv) < 5: 11 | print("Usage:", sys.argv[0], " [] ...") 12 | sys.exit(0) 13 | 14 | del sys.argv[0] 15 | 16 | png_file_suffix = sys.argv[0] 17 | del sys.argv[0] 18 | 19 | minN = int(sys.argv[0]) 20 | del sys.argv[0] 21 | 22 | maxN = int(sys.argv[0]) 23 | del sys.argv[0] 24 | 25 | data_files = [f for f in sys.argv] 26 | 27 | print("Reading CSV files:", data_files, "...") 28 | 29 | csv_data = pandas.concat((pandas.read_csv(f) for f in data_files)) 30 | 31 | #print "Raw:" 32 | #print csv_data.to_string() 33 | #print csv_data.columns 34 | #print csv_data['dictSize'].values 35 | 36 | #print "Averaged:" 37 | 38 | if minN == 0: 39 | minN = csv_data.n.unique().min(); 40 | if maxN == 0: 41 | maxN = csv_data.n.unique().max(); 42 | 43 | print("min N:", minN) 44 | print("max N:", maxN) 45 | 46 | #csv_data = csv_data[csv_data.dkg != 'Feldman'] 47 | csv_data.vss.replace('amt', 'AMT DKG/VSS', inplace=True) 48 | csv_data.vss.replace('kate', 'eVSS / eJF-DKG', inplace=True) 49 | csv_data.vss.replace('feld', 'Feldman DKG/VSS', inplace=True) 50 | csv_data = csv_data[csv_data.n >= minN] 51 | csv_data = csv_data[csv_data.n <= maxN] 52 | 53 | # we recompute these columns with more precision, even though the CSV file already has them 54 | csv_data['avg_deal_sec'] = csv_data.avg_deal_usec / (1000*1000) 55 | 56 | print(csv_data.to_string()) # print all data 57 | 58 | #SMALL_SIZE = 10 59 | MEDIUM_SIZE = 20 60 | BIG_SIZE = 24 61 | BIGGER_SIZE = 28 62 | BIGGEST_SIZE = 32 63 | 64 | plt.rc('font', size= BIGGER_SIZE) # controls default text sizes 65 | #plt.rc('axes', titlesize= BIGGER_SIZE) # fontsize of the axes title 66 | #plt.rc('axes', labelsize= MEDIUM_SIZE) # fontsize of the x and y labels 67 | plt.rc('xtick', labelsize= BIG_SIZE) 68 | plt.rc('ytick', labelsize= BIG_SIZE) 69 | plt.rc('legend', fontsize= BIGGER_SIZE) 70 | #plt.rc('figure', titlesize=BIGGER_SIZE) # fontsize of the figure title 71 | 72 | 73 | def plotNumbers(data, colNames, legendAppendix, png_name, timeUnit='seconds', title=None): 74 | x = data.t.unique() #.unique() # x-axis is the number of total players n 75 | 76 | #logBase = 10 77 | logBase = 2 78 | 79 | #print "Plotting with log base", logBase 80 | 81 | # adjust the size of the plot: (20, 10) is bigger than (10, 5) in the 82 | # sense that fonts will look smaller on (20, 10) 83 | fig, ax1 = plt.subplots(figsize=(12,7.5)) 84 | ax1.set_xscale("log", basex=logBase) 85 | ax1.set_yscale("log") 86 | #ax1.set_xlabel("Total # of players n") 87 | #ax1.set_ylabel("Time (in " + timeUnit + ")") #, fontsize=fontsize) 88 | ax1.grid(True) 89 | 90 | plots = [] 91 | names = [] 92 | 93 | #plt.xticks(x, x, rotation=30) 94 | schemes = data.vss.unique() 95 | for scheme in schemes: 96 | for i in range(len(colNames)): 97 | colName = colNames[i] 98 | appendix = legendAppendix[i] 99 | 100 | print("Plotting column", colName, "for:", scheme) 101 | 102 | filtered = data[data.vss == scheme] 103 | col1 = filtered[colName].values 104 | 105 | if len(x) > len(col1): 106 | print("WARNING: Not enough y-values on column", colName) 107 | print("Expected", len(x), "got", len(col1)) 108 | 109 | linestyle="-" 110 | marker="o" 111 | 112 | plt1, = ax1.plot(x[:len(col1)], col1, linestyle=linestyle, linewidth=4, marker=marker, markersize=10) 113 | 114 | plots.append(plt1) 115 | names.append(scheme + appendix) 116 | 117 | #plt.xticks(x, x, rotation=30) 118 | 119 | #print "X:", x 120 | #print "len(x):", len(x) 121 | 122 | if title != None: 123 | ax1.set_title(title) 124 | ax1.set_xticks(x) 125 | ax1.set_xticklabels(np.log2(x).astype(int), rotation=30) 126 | 127 | locmaj = plticker.LogLocator(base=10,numticks=12) 128 | ax1.yaxis.set_major_locator(locmaj) 129 | locmin = plticker.LogLocator(base=10.0,numticks=12) #,subs=(0.2,0.4,0.6,0.8) 130 | ax1.yaxis.set_minor_locator(locmin) 131 | ax1.yaxis.set_minor_formatter(plticker.NullFormatter()) 132 | 133 | ax1.legend(plots, 134 | names, 135 | loc='upper left')#, fontsize=fontsize 136 | 137 | plt.tight_layout() 138 | 139 | out_file = png_name + png_file_suffix + ".png" 140 | print("Saving graph to", out_file) 141 | 142 | #date = time.strftime("%Y-%m-%d-%H-%M-%S") 143 | plt.savefig(out_file, bbox_inches='tight') 144 | plt.close() 145 | 146 | plotNumbers(csv_data, 147 | ['avg_deal_sec'], 148 | [''], 149 | 'all-deal-times') # NOTE: we converted usecs to secs above 150 | 151 | #plt.xticks(fontsize=fontsize) 152 | #plt.yticks(fontsize=fontsize) 153 | plt.show() 154 | -------------------------------------------------------------------------------- /scripts/linux/recompute-polylog-dkg.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | set -e 4 | 5 | scriptdir=$(cd $(dirname $0); pwd -P) 6 | . $scriptdir/shlibs/os.sh 7 | 8 | out_file_name=$scriptdir/../../experiments/polylog-dkg 9 | 10 | for secparam in 40 60 80 100 128; do 11 | out_file="${out_file_name}-${secparam}.csv" 12 | rm -f $out_file 13 | 14 | n=1024 15 | for i in `seq 1 14`; do 16 | n=$((n*2)) 17 | echo "Getting numbers for lambda = $secparam and n = $n ..." 18 | if ! PolylogDkg $secparam $n $out_file; then #&>/dev/null; then 19 | echo "ERROR: Failed generating params for current config" 20 | exit 1 21 | fi 22 | done 23 | done 24 | -------------------------------------------------------------------------------- /scripts/linux/set-env.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | 3 | if [ $# -lt 1 ]; then 4 | name=${BASH_SOURCE[@]} 5 | echo "Usage: source $name [ ...]" 6 | echo 7 | echo "Examples:" 8 | echo 9 | echo "source $name debug" 10 | echo "source $name trace" 11 | echo "source $name release" 12 | echo "source $name relwithdebug" 13 | echo 14 | if [ -n "$POLYCRYPTO_HAS_ENV_SET" ]; then 15 | echo "Currently-set environment" 16 | echo "=========================" 17 | echo "Build directory: $POLYCRYPTO_BUILD_DIR" 18 | echo "CMake args: $POLYCRYPTO_CMAKE_ARGS" 19 | fi 20 | else 21 | # WARNING: Need to exit using control-flow rather than 'exit 1' because this script is sourced 22 | invalid_buildtype=0 23 | 24 | buildtype=`echo "$1" | tr '[:upper:]' '[:lower:]'` 25 | shift; 26 | 27 | extra_cmake_args=$@ 28 | 29 | scriptdir=$(cd $(dirname ${BASH_SOURCE[@]}); pwd -P) 30 | sourcedir=$(cd $scriptdir/../..; pwd -P) 31 | #echo "Source dir: $sourcedir" 32 | 33 | branch=`git branch | grep "\*"` 34 | branch=${branch/\* /} 35 | builddir_base=~/builds/polycrypto/$branch 36 | case "$buildtype" in 37 | trace) 38 | builddir=$builddir_base/trace 39 | cmake_args="-DCMAKE_BUILD_TYPE=Trace" 40 | ;; 41 | debug) 42 | builddir=$builddir_base/debug 43 | cmake_args="-DCMAKE_BUILD_TYPE=Debug" 44 | ;; 45 | release) 46 | builddir=$builddir_base/release 47 | cmake_args="-DCMAKE_BUILD_TYPE=Release" 48 | ;; 49 | relwithdebug) 50 | builddir=$builddir_base/relwithdebug 51 | cmake_args="-DCMAKE_BUILD_TYPE=RelWithDebInfo" 52 | ;; 53 | *) 54 | invalid_buildtype=1 55 | ;; 56 | esac 57 | 58 | cmake_args="$cmake_args $extra_cmake_args" 59 | 60 | # 61 | # grep-code alias 62 | # 63 | alias grep-code='grep --exclude-dir=.git --exclude=".gitignore" --exclude="*.html"' 64 | 65 | if [ $invalid_buildtype -eq 0 ]; then 66 | echo "Configuring for build type '$buildtype' ..." 67 | echo 68 | 69 | export PATH="$scriptdir:$PATH" 70 | export PATH="$builddir/libpolycrypto/bin:$PATH" 71 | export PATH="$builddir/libpolycrypto/bin/test:$PATH" 72 | export PATH="$builddir/libpolycrypto/bin/bench:$PATH" 73 | export PATH="$builddir/libpolycrypto/bin/app:$PATH" 74 | export PATH="$builddir/libpolycrypto/bin/examples:$PATH" 75 | 76 | echo "Build directory: $builddir" 77 | echo "CMake args: $cmake_args" 78 | echo "PATH envvar: $PATH" 79 | 80 | export POLYCRYPTO_BUILD_DIR=$builddir 81 | export POLYCRYPTO_CMAKE_ARGS=$cmake_args 82 | export POLYCRYPTO_HAS_ENV_SET=1 83 | export POLYCRYPTO_SOURCE_DIR=$sourcedir 84 | else 85 | echo "ERROR: Invalid build type '$buildtype'" 86 | fi 87 | fi 88 | -------------------------------------------------------------------------------- /scripts/linux/shlibs/check-env.sh: -------------------------------------------------------------------------------- 1 | if [ -z "$POLYCRYPTO_HAS_ENV_SET" ]; then 2 | echo "ERROR: You must call 'source set-env.sh ' first" 3 | exit 1 4 | fi 5 | 6 | #which clang++ 2>&1 >/dev/null || { echo "ERROR: Clang is not installed."; exit 1; } 7 | #which parallel 2>&1 >/dev/null || { echo "ERROR: GNU parallel needs to be installed."; exit 1; } 8 | -------------------------------------------------------------------------------- /scripts/linux/shlibs/os.sh: -------------------------------------------------------------------------------- 1 | OS_FLAVOR="Unknown" 2 | NUM_CPUS= 3 | 4 | if [ "$(uname -s)" = "Darwin" ]; then 5 | OS="OSX" 6 | NUM_CPUS=`sysctl -n hw.ncpu` 7 | elif [ "$(uname -s)" = "Linux" ]; then 8 | OS="Linux" 9 | NUM_CPUS=`grep -c ^processor /proc/cpuinfo` 10 | if [ -f /etc/issue ]; then 11 | if grep Fedora /etc/issue >/dev/null; then 12 | OS_FLAVOR="Fedora" 13 | elif grep Ubuntu /etc/issue >/dev/null; then 14 | OS_FLAVOR="Ubuntu" 15 | fi 16 | fi 17 | fi 18 | 19 | #echo "OS: $OS" 20 | #echo "OS Flavor: $OS_FLAVOR" 21 | -------------------------------------------------------------------------------- /scripts/linux/submodule-update.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | scriptdir=$(cd $(dirname $0); pwd -P) 5 | sourcedir=$(cd $scriptdir/../..; pwd -P) 6 | . $scriptdir/shlibs/check-env.sh 7 | . $scriptdir/shlibs/os.sh 8 | 9 | builddir=$POLYCRYPTO_BUILD_DIR 10 | 11 | ( 12 | cd $sourcedir; 13 | git submodule init; 14 | git submodule update; 15 | ) 16 | -------------------------------------------------------------------------------- /scripts/linux/test.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | scriptdir=$(cd $(dirname $0); pwd -P) 5 | sourcedir=$(cd $scriptdir/../..; pwd -P) 6 | . $scriptdir/shlibs/check-env.sh 7 | 8 | builddir=$POLYCRYPTO_BUILD_DIR 9 | 10 | cd "$builddir" 11 | ctest --verbose 12 | -------------------------------------------------------------------------------- /scripts/linux/vss-cols.sh: -------------------------------------------------------------------------------- 1 | #!/bin/bash 2 | set -e 3 | 4 | scriptdir=$(cd $(dirname $0); pwd -P) 5 | 6 | if [ $# -lt 1 ]; then 7 | echo "Usage: $0 [ ...]" 8 | exit 1 9 | fi 10 | 11 | $scriptdir/cols.sh "$@" 1,2,3,4,5,6,7,12,13,14,15 12 | --------------------------------------------------------------------------------