├── .gitignore ├── .gitmodules ├── CMakeLists.txt ├── LICENSE ├── README.md ├── depends └── CMakeLists.txt └── src ├── CMakeLists.txt └── main.cpp /.gitignore: -------------------------------------------------------------------------------- 1 | *.DS_Store 2 | build -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "depends/libsnark"] 2 | path = depends/libsnark 3 | url = https://github.com/scipr-lab/libsnark.git 4 | -------------------------------------------------------------------------------- /CMakeLists.txt: -------------------------------------------------------------------------------- 1 | cmake_minimum_required(VERSION 2.8) 2 | 3 | project(libsnark-tutorial) 4 | 5 | set( 6 | CURVE 7 | "BN128" 8 | CACHE 9 | STRING 10 | "Default curve: one of ALT_BN128, BN128, EDWARDS, MNT4, MNT6" 11 | ) 12 | 13 | set( 14 | DEPENDS_DIR 15 | "${CMAKE_CURRENT_SOURCE_DIR}/depends" 16 | CACHE 17 | STRING 18 | "Optionally specify the dependency installation directory relative to the source directory (default: inside dependency folder)" 19 | ) 20 | 21 | set( 22 | OPT_FLAGS 23 | "" 24 | CACHE 25 | STRING 26 | "Override C++ compiler optimization flags" 27 | ) 28 | 29 | option( 30 | MULTICORE 31 | "Enable parallelized execution, using OpenMP" 32 | OFF 33 | ) 34 | 35 | option( 36 | WITH_PROCPS 37 | "Use procps for memory profiling" 38 | ON 39 | ) 40 | 41 | option( 42 | VERBOSE 43 | "Print internal messages" 44 | OFF 45 | ) 46 | 47 | if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") 48 | # Common compilation flags and warning configuration 49 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -Wfatal-errors -pthread") 50 | 51 | if("${MULTICORE}") 52 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp") 53 | endif() 54 | 55 | # Default optimizations flags (to override, use -DOPT_FLAGS=...) 56 | if("${OPT_FLAGS}" STREQUAL "") 57 | set(OPT_FLAGS "-ggdb3 -O2 -march=native -mtune=native") 58 | endif() 59 | endif() 60 | 61 | add_definitions(-DCURVE_${CURVE}) 62 | 63 | if(${CURVE} STREQUAL "BN128") 64 | add_definitions(-DBN_SUPPORT_SNARK=1) 65 | endif() 66 | 67 | if("${VERBOSE}") 68 | add_definitions(-DVERBOSE=1) 69 | endif() 70 | 71 | if("${MULTICORE}") 72 | add_definitions(-DMULTICORE=1) 73 | endif() 74 | 75 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPT_FLAGS}") 76 | 77 | include(FindPkgConfig) 78 | if("${WITH_PROCPS}") 79 | pkg_check_modules(PROCPS REQUIRED libprocps) 80 | else() 81 | add_definitions(-DNO_PROCPS) 82 | endif() 83 | 84 | include_directories(.) 85 | 86 | add_subdirectory(depends) 87 | add_subdirectory(src) -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2017 Howard Wu. 2 | 3 | All files, with the exceptions below, are released under the MIT License: 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # libsnark-tutorial 2 | 3 | In this library, we will create a simple zkSNARK application using [libsnark](https://www.github.com/SCIPR-Lab/libsnark), a C++ library for zkSNARK proofs. zkSNARKs enable a prover to succinctly convince any verifier of a given statement's validity without revealing any information aside from the statement's validity. This technology has formed the basis for protocols such as [Zcash](https://z.cash), a cryptocurrency that provides anonymity for users and their transactions. 4 | 5 | This tutorial will guide you through installing `libsnark`, setting up a development environment, and building a simple zkSNARK application. This library can be extended to support a testing framework, profiling infrastructure, and more. 6 | 7 | ## Table of Contents 8 | 9 | - [Introduction](#introduction) 10 | - [Build Guide](#build-guide) 11 | - [Installation](#installation) 12 | - [Development Environment](#development-environment) 13 | - [Directory Structure](#directory-structure) 14 | - [Compilation Framework](#compilation-framework) 15 | - [Development Framework](#development-framework) 16 | - [zkSNARK Application](#zksnark-application) 17 | - [Compilation](#compilation) 18 | - [Further Resources](#further-resources) 19 | - [License](#license) 20 | 21 | ## Introduction 22 | 23 | Zero-knowledge proofs were first introduced by Shafi Goldwasser, Silvio Micali and Charles Rackoff. A zero-knowledge proof allows one party, the prover, to convince another party, the verifier, that a given statement is true, without revealing any information beyond the validity of the statement itself. A zkSNARK is a variant of a zero-knowledge proof that enables a prover to succinctly convince any verifier of the validity of a given statement and achieves computational zero-knowledge without requiring interaction between the prover and any verifier. 24 | 25 | zkSNARKs can be used to prove and verify, in zero-knowledge, the integrity of computations, expressed as NP statements, in forms such as the following: 26 | 27 | - "The C program _foo_, when executed, returns exit code 0 if given the input _bar_ and some additional input _qux_." 28 | - "The Boolean circuit _foo_ is satisfiable by some input _qux_." 29 | - "The arithmetic circuit _foo_ accepts the partial assignment _bar_, when extended into some full assignment _qux_." 30 | - "The set of constraints _foo_ is satisfiable by the partial assignment _bar_, when extended into some full assignment _qux_." 31 | 32 | A prover with knowledge of the witness for the NP statement can produce a succinct proof that attests to the truth of the NP statement. Anyone can then verify this short proof, which offers the following properties: 33 | 34 | - __Zero-knowledge__ 35 | \- the verifier learns nothing from the proof beside the truth of the statement (i.e., the value _qux_, in the examples above, remains secret). 36 | - __Succinctness__ 37 | \- the proof is short and easy to verify. 38 | - __Non-interactivity:__ 39 | \- the proof is a string (i.e. it does not require back-and-forth interaction between the prover and the verifier). 40 | - __Soundness__ 41 | \- the proof is computationally sound (i.e., it is infeasible to fake a proof of a false NP statement). Such a proof system is also called an _argument_. 42 | - __Proof of knowledge__ 43 | \- the proof attests not just that the NP statement is true, but also that the 44 | prover knows why (e.g., knows a valid _qux_). 45 | 46 | Together, these properties comprise a _zkSNARK_, which stands for a _Zero-Knowledge Succinct Non-interactive ARgument of Knowledge_. 47 | 48 | ## Build Guide 49 | 50 | This repository has the following dependencies, which come from `libsnark`: 51 | 52 | - C++ build environment 53 | - CMake build infrastructure 54 | - GMP for certain bit-integer arithmetic 55 | - libprocps for reporting memory usage 56 | - Fetched and compiled via Git submodules: 57 | - [libff](https://github.com/scipr-lab/libff) for finite fields and elliptic curves 58 | - [libfqfft](https://github.com/scipr-lab/libfqfft) for fast polynomial evaluation and interpolation in various finite domains 59 | - [Google Test](https://github.com/google/googletest) (GTest) for unit tests 60 | - [ate-pairing](https://github.com/herumi/ate-pairing) for the BN128 elliptic curve 61 | - [xbyak](https://github.com/herumi/xbyak) just-in-time assembler, for the BN128 elliptic curve 62 | - [Subset of SUPERCOP](https://github.com/mbbarbosa/libsnark-supercop) for crypto primitives needed by ADSNARK 63 | 64 | ### Installation 65 | 66 | * On Ubuntu 16.04 LTS: 67 | 68 | $ sudo apt-get install build-essential cmake git libgmp3-dev libprocps4-dev python-markdown libboost-all-dev libssl-dev 69 | 70 | * On Ubuntu 14.04 LTS: 71 | 72 | $ sudo apt-get install build-essential cmake git libgmp3-dev libprocps3-dev python-markdown libboost-all-dev libssl-dev 73 | 74 | * On Fedora 21 through 23: 75 | 76 | $ sudo yum install gcc-c++ cmake make git gmp-devel procps-ng-devel python2-markdown 77 | 78 | * On Fedora 20: 79 | 80 | $ sudo yum install gcc-c++ cmake make git gmp-devel procps-ng-devel python-markdown 81 | 82 | ## Development Environment 83 | 84 | __This library includes the completed development environment. If you wish to use the provided environment, you may proceed to the [zkSNARK Application](#zksnark-application).__ 85 | 86 | ### Directory Structure 87 | 88 | We will create a library with the following directory structure: 89 | 90 | * [__src__](src): C++ source code 91 | 92 | * [__depends__](depends): dependency libraries 93 | 94 | Start by creating a `src` directory and nested `test` directory. 95 | ``` 96 | mkdir src && mkdir src/test 97 | ``` 98 | 99 | Next, create a dependency directory, called `depends`, and add `libsnark` as a submodule. 100 | ``` 101 | mkdir depends && cd depends 102 | git submodule add https://github.com/scipr-lab/libsnark.git libsnark 103 | ``` 104 | 105 | ### Compilation Framework 106 | 107 | We will use `CMake` as our compilation framework. Start by creating a `CMakeLists.txt` file in the root directory and initialize it with the following. 108 | ``` 109 | cmake_minimum_required(VERSION 2.8) 110 | 111 | project(libsnark-tutorial) 112 | 113 | set( 114 | CURVE 115 | "BN128" 116 | CACHE 117 | STRING 118 | "Default curve: one of ALT_BN128, BN128, EDWARDS, MNT4, MNT6" 119 | ) 120 | 121 | set( 122 | DEPENDS_DIR 123 | "${CMAKE_CURRENT_SOURCE_DIR}/depends" 124 | CACHE 125 | STRING 126 | "Optionally specify the dependency installation directory relative to the source directory (default: inside dependency folder)" 127 | ) 128 | 129 | set( 130 | OPT_FLAGS 131 | "" 132 | CACHE 133 | STRING 134 | "Override C++ compiler optimization flags" 135 | ) 136 | 137 | option( 138 | MULTICORE 139 | "Enable parallelized execution, using OpenMP" 140 | OFF 141 | ) 142 | 143 | option( 144 | WITH_PROCPS 145 | "Use procps for memory profiling" 146 | ON 147 | ) 148 | 149 | option( 150 | VERBOSE 151 | "Print internal messages" 152 | OFF 153 | ) 154 | 155 | if(CMAKE_COMPILER_IS_GNUCXX OR "${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang") 156 | # Common compilation flags and warning configuration 157 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wall -Wextra -Wfatal-errors -pthread") 158 | 159 | if("${MULTICORE}") 160 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fopenmp") 161 | endif() 162 | 163 | # Default optimizations flags (to override, use -DOPT_FLAGS=...) 164 | if("${OPT_FLAGS}" STREQUAL "") 165 | set(OPT_FLAGS "-ggdb3 -O2 -march=native -mtune=native") 166 | endif() 167 | endif() 168 | 169 | add_definitions(-DCURVE_${CURVE}) 170 | 171 | if(${CURVE} STREQUAL "BN128") 172 | add_definitions(-DBN_SUPPORT_SNARK=1) 173 | endif() 174 | 175 | if("${VERBOSE}") 176 | add_definitions(-DVERBOSE=1) 177 | endif() 178 | 179 | if("${MULTICORE}") 180 | add_definitions(-DMULTICORE=1) 181 | endif() 182 | 183 | set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} ${OPT_FLAGS}") 184 | 185 | include(FindPkgConfig) 186 | if("${WITH_PROCPS}") 187 | pkg_check_modules(PROCPS REQUIRED libprocps) 188 | else() 189 | add_definitions(-DNO_PROCPS) 190 | endif() 191 | 192 | include_directories(.) 193 | 194 | add_subdirectory(depends) 195 | add_subdirectory(src) 196 | ``` 197 | 198 | Next, create a `CMakeLists.txt` file in the `depends` directory and include the `libsnark` dependency. 199 | ``` 200 | add_subdirectory(libsnark) 201 | ``` 202 | 203 | Lastly, create a `CMakeLists.txt` file in the `src` directory. 204 | 205 | ### Development Framework 206 | 207 | Start by creating a boilerplate `src/main.cpp` file. 208 | ```cpp 209 | int main () { 210 | return 0; 211 | } 212 | ``` 213 | 214 | Next, create a `CMakeLists.txt` file in the `src` directory and link the `main.cpp` file as follows. 215 | ``` 216 | include_directories(.) 217 | 218 | add_executable( 219 | main 220 | 221 | main.cpp 222 | ) 223 | target_link_libraries( 224 | main 225 | 226 | snark 227 | ) 228 | target_include_directories( 229 | main 230 | 231 | PUBLIC 232 | ${DEPENDS_DIR}/libsnark 233 | ${DEPENDS_DIR}/libsnark/depends/libfqfft 234 | ) 235 | ``` 236 | 237 | ## zkSNARK Application 238 | 239 | __This library includes the completed zkSNARK application. If you wish to use the provided environment, you may proceed to [Compilation](#compilation).__ 240 | 241 | Our application will make use of the [Groth16](https://github.com/scipr-lab/libsnark/tree/master/libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark) zkSNARK protocol as provided by `libsnark`. The protocol is comprised of a setup phase, proving phase, and verification phase. The setup is responsible for constructing the public parameters that the prover and verifier use. The prover provides their public and private inputs, along with the public parameters, to construct a succinct proof. Any verifier is then able to verify this proof using the verification key, public input, and proof. Note that the verification key is derived from the public parameters. 242 | 243 | ```cpp 244 | template 245 | bool run_r1cs_gg_ppzksnark(const r1cs_example > &example) 246 | { 247 | libff::print_header("R1CS GG-ppzkSNARK Generator"); 248 | r1cs_gg_ppzksnark_keypair keypair = r1cs_gg_ppzksnark_generator(example.constraint_system); 249 | printf("\n"); libff::print_indent(); libff::print_mem("after generator"); 250 | 251 | libff::print_header("Preprocess verification key"); 252 | r1cs_gg_ppzksnark_processed_verification_key pvk = r1cs_gg_ppzksnark_verifier_process_vk(keypair.vk); 253 | 254 | libff::print_header("R1CS GG-ppzkSNARK Prover"); 255 | r1cs_gg_ppzksnark_proof proof = r1cs_gg_ppzksnark_prover(keypair.pk, example.primary_input, example.auxiliary_input); 256 | printf("\n"); libff::print_indent(); libff::print_mem("after prover"); 257 | 258 | libff::print_header("R1CS GG-ppzkSNARK Verifier"); 259 | const bool ans = r1cs_gg_ppzksnark_verifier_strong_IC(keypair.vk, example.primary_input, proof); 260 | printf("\n"); libff::print_indent(); libff::print_mem("after verifier"); 261 | printf("* The verification result is: %s\n", (ans ? "PASS" : "FAIL")); 262 | 263 | libff::print_header("R1CS GG-ppzkSNARK Online Verifier"); 264 | const bool ans2 = r1cs_gg_ppzksnark_online_verifier_strong_IC(pvk, example.primary_input, proof); 265 | assert(ans == ans2); 266 | 267 | return ans; 268 | } 269 | ``` 270 | 271 | Our application will construct a sample circuit, making use of the [binary input circuit](https://github.com/scipr-lab/libsnark/blob/master/libsnark/relations/constraint_satisfaction_problems/r1cs/examples/r1cs_examples.tcc#L100) example provided by `libsnark`. 272 | ```cpp 273 | template 274 | void test_r1cs_gg_ppzksnark(size_t num_constraints, size_t input_size) 275 | { 276 | r1cs_example > example = generate_r1cs_example_with_binary_input >(num_constraints, input_size); 277 | const bool bit = run_r1cs_gg_ppzksnark(example); 278 | assert(bit); 279 | } 280 | ``` 281 | 282 | Lastly, we invoke the methods and construct a circuit with 1000 constraints and an input size of 100 elements. 283 | ```cpp 284 | int main () { 285 | default_r1cs_gg_ppzksnark_pp::init_public_params(); 286 | test_r1cs_gg_ppzksnark(1000, 100); 287 | 288 | return 0; 289 | } 290 | ``` 291 | 292 | ## Compilation 293 | 294 | To compile this library, start by recursively fetching the dependencies. 295 | ``` 296 | git submodule update --init --recursive 297 | ``` 298 | 299 | Note, the submodules only need to be fetched once. 300 | 301 | Next, initialize the `build` directory. 302 | ``` 303 | mkdir build && cd build && cmake .. 304 | ``` 305 | 306 | Lastly, compile the library. 307 | ``` 308 | make 309 | ``` 310 | 311 | To run the application, use the following command from the `build` directory: 312 | ``` 313 | ./src/main 314 | ``` 315 | 316 | ## Further Resources 317 | 318 | ### Libraries 319 | * [libsnark](http://github.com/SCIPR-Lab/libsnark) - C++ library for zkSNARK proofs 320 | * [libfqfft](https://github.com/scipr-lab/libfqfft) - C++ library for FFTs in Finite Fields 321 | * [libff](https://github.com/scipr-lab/libff) - C++ library for Finite Fields and Elliptic Curves 322 | * [Zcash](https://github.com/zcash/zcash) - Internet Money, an implementation of the Zerocash protocol 323 | * [ZSL on Quorum](https://github.com/jpmorganchase/zsl-q) - Zero-knowledge security layer in JP Morgan Quorum 324 | * [ZoKrates](https://github.com/JacobEberhardt/ZoKrates) - A toolbox for zkSNARKs on Ethereum 325 | 326 | ### Articles 327 | * [zkSNARKs Under the Hood](https://medium.com/@VitalikButerin/zk-snarks-under-the-hood-b33151a013f6) - Vitalik Buterin 328 | * [zkSNARKs in a nutshell](https://blog.ethereum.org/2016/12/05/zksnarks-in-a-nutshell/) - Christian Reitwiessner 329 | * [What are zkSNARKs?](https://z.cash/technology/zksnarks.html) - Zcash 330 | * [zkSNARK Reading List](https://tahoe-lafs.org/trac/tahoe-lafs/wiki/SNARKs) - Tahoe-LAFS 331 | 332 | ### Talks 333 | * [Zerocash: Solving Bitcoin's Privacy Problem](https://www.youtube.com/watch?v=84Vbj7-i9CI) - Alessandro Chiesa 334 | * [SNARKs and their Practical Applications](https://simons.berkeley.edu/talks/eran-tromer-2015-06-10) - Eran Tromer 335 | * [Zcash, SNARKs, STARKs](https://www.youtube.com/watch?v=VUN35BC11Qw) - Eli Ben Sasson 336 | * [Democratizing zkSNARKs](https://www.youtube.com/watch?v=7BxoyEw6LUY) - Sean Bowe 337 | 338 | ## License 339 | 340 | [![MIT licensed](https://img.shields.io/badge/license-MIT-blue.svg)](LICENSE) 341 | 342 | -------------------------------------------------------------------------------- /depends/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(libsnark) -------------------------------------------------------------------------------- /src/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | include_directories(.) 2 | 3 | add_executable( 4 | main 5 | 6 | main.cpp 7 | ) 8 | target_link_libraries( 9 | main 10 | 11 | snark 12 | ) 13 | target_include_directories( 14 | main 15 | 16 | PUBLIC 17 | ${DEPENDS_DIR}/libsnark 18 | ${DEPENDS_DIR}/libsnark/depends/libfqfft 19 | ) -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | #include 6 | 7 | using namespace libsnark; 8 | 9 | /** 10 | * The code below provides an example of all stages of running a R1CS gppzkSNARK. 11 | * 12 | * Of course, in a real-life scenario, we would have three distinct entities, 13 | * mangled into one in the demonstration below. The three entities are as follows. 14 | * (1) The "generator", which runs the ppzkSNARK generator on input a given 15 | * constraint system CS to create a proving and a verification key for CS. 16 | * (2) The "prover", which runs the ppzkSNARK prover on input the proving key, 17 | * a primary input for CS, and an auxiliary input for CS. 18 | * (3) The "verifier", which runs the ppzkSNARK verifier on input the verification key, 19 | * a primary input for CS, and a proof. 20 | */ 21 | template 22 | bool run_r1cs_ppzksnark(const r1cs_example > &example) 23 | { 24 | libff::print_header("R1CS gppzkSNARK Generator"); 25 | r1cs_ppzksnark_keypair keypair = r1cs_ppzksnark_generator(example.constraint_system); 26 | printf("\n"); libff::print_indent(); libff::print_mem("after generator"); 27 | 28 | libff::print_header("Preprocess verification key"); 29 | r1cs_ppzksnark_processed_verification_key pvk = r1cs_ppzksnark_verifier_process_vk(keypair.vk); 30 | 31 | libff::print_header("R1CS gppzkSNARK fake Prover"); 32 | std::vector> primary_input; 33 | primary_input.resize(example.primary_input.size()); 34 | for (size_t i = 0; i < example.primary_input.size(); i++) { 35 | primary_input[i] = libff::Fr(2); 36 | } 37 | std::vector> auxiliary_input; 38 | auxiliary_input.resize(example.auxiliary_input.size()); 39 | for (size_t i = 0; i < example.auxiliary_input.size(); i++) { 40 | auxiliary_input[i] = libff::Fr(2); 41 | } 42 | r1cs_ppzksnark_proof proof = r1cs_ppzksnark_prover(keypair.pk, example.primary_input, example.auxiliary_input); 43 | printf("\n"); libff::print_indent(); libff::print_mem("after fake prover"); 44 | 45 | libff::print_header("R1CS gppzkSNARK Verifier"); 46 | const bool ans = r1cs_ppzksnark_verifier_strong_IC(keypair.vk, example.primary_input, proof); 47 | printf("\n"); libff::print_indent(); libff::print_mem("after verifier"); 48 | printf("* The verification result is: %s\n", (ans ? "PASS" : "FAIL")); 49 | 50 | libff::print_header("R1CS gppzkSNARK Online Verifier"); 51 | const bool ans2 = r1cs_ppzksnark_online_verifier_strong_IC(pvk, example.primary_input, proof); 52 | assert(ans == ans2); 53 | 54 | return ans; 55 | } 56 | 57 | template 58 | void test_r1cs_ppzksnark(size_t num_constraints, size_t input_size) 59 | { 60 | r1cs_example > example = generate_r1cs_example_with_binary_input >(num_constraints, input_size); 61 | const bool bit = run_r1cs_ppzksnark(example); 62 | assert(bit); 63 | 64 | } 65 | 66 | int main () { 67 | default_r1cs_ppzksnark_pp::init_public_params(); 68 | test_r1cs_ppzksnark(1000, 1000); 69 | 70 | return 0; 71 | } 72 | --------------------------------------------------------------------------------