├── .gitmodules ├── CMakeLists.txt ├── README.md ├── depends └── CMakeLists.txt └── src ├── CMakeLists.txt ├── main.cpp ├── range.cpp └── test.cpp /.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_abc) 4 | 5 | set( 6 | CURVE 7 | "ALT_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) 88 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # libsnark ABC 2 | 3 | Minimal examples to use libsnark. 4 | 5 | ## Reference 6 | 7 | - https://github.com/christianlundkvist/libsnark-tutorial 8 | - https://github.com/howardwu/libsnark-tutorial -------------------------------------------------------------------------------- /depends/CMakeLists.txt: -------------------------------------------------------------------------------- 1 | add_subdirectory(libsnark) 2 | 3 | -------------------------------------------------------------------------------- /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 | ) 20 | 21 | add_executable( 22 | test 23 | 24 | test.cpp 25 | ) 26 | target_link_libraries( 27 | test 28 | 29 | snark 30 | ) 31 | target_include_directories( 32 | test 33 | 34 | PUBLIC 35 | ${DEPENDS_DIR}/libsnark 36 | ${DEPENDS_DIR}/libsnark/depends/libfqfft 37 | ) 38 | 39 | add_executable( 40 | range 41 | 42 | range.cpp 43 | ) 44 | target_link_libraries( 45 | range 46 | 47 | snark 48 | ) 49 | target_include_directories( 50 | range 51 | 52 | PUBLIC 53 | ${DEPENDS_DIR}/libsnark 54 | ${DEPENDS_DIR}/libsnark/depends/libfqfft 55 | ) -------------------------------------------------------------------------------- /src/main.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace libsnark; 7 | 8 | /** 9 | * The code below provides an example of all stages of running a R1CS GG-ppzkSNARK. 10 | * 11 | * Of course, in a real-life scenario, we would have three distinct entities, 12 | * mangled into one in the demonstration below. The three entities are as follows. 13 | * (1) The "generator", which runs the ppzkSNARK generator on input a given 14 | * constraint system CS to create a proving and a verification key for CS. 15 | * (2) The "prover", which runs the ppzkSNARK prover on input the proving key, 16 | * a primary input for CS, and an auxiliary input for CS. 17 | * (3) The "verifier", which runs the ppzkSNARK verifier on input the verification key, 18 | * a primary input for CS, and a proof. 19 | */ 20 | template 21 | bool run_r1cs_gg_ppzksnark(const r1cs_example > &example) 22 | { 23 | libff::print_header("R1CS GG-ppzkSNARK Generator"); 24 | r1cs_gg_ppzksnark_keypair keypair = r1cs_gg_ppzksnark_generator(example.constraint_system); 25 | printf("\n"); libff::print_indent(); libff::print_mem("after generator"); 26 | 27 | libff::print_header("Preprocess verification key"); 28 | r1cs_gg_ppzksnark_processed_verification_key pvk = r1cs_gg_ppzksnark_verifier_process_vk(keypair.vk); 29 | 30 | libff::print_header("R1CS GG-ppzkSNARK Prover"); 31 | r1cs_gg_ppzksnark_proof proof = r1cs_gg_ppzksnark_prover(keypair.pk, example.primary_input, example.auxiliary_input); 32 | printf("\n"); libff::print_indent(); libff::print_mem("after prover"); 33 | 34 | libff::print_header("R1CS GG-ppzkSNARK Verifier"); 35 | const bool ans = r1cs_gg_ppzksnark_verifier_strong_IC(keypair.vk, example.primary_input, proof); 36 | printf("\n"); libff::print_indent(); libff::print_mem("after verifier"); 37 | printf("* The verification result is: %s\n", (ans ? "PASS" : "FAIL")); 38 | 39 | libff::print_header("R1CS GG-ppzkSNARK Online Verifier"); 40 | const bool ans2 = r1cs_gg_ppzksnark_online_verifier_strong_IC(pvk, example.primary_input, proof); 41 | assert(ans == ans2); 42 | 43 | return ans; 44 | } 45 | 46 | template 47 | void test_r1cs_gg_ppzksnark(size_t num_constraints, size_t input_size) 48 | { 49 | r1cs_example > example = generate_r1cs_example_with_binary_input >(num_constraints, input_size); 50 | const bool bit = run_r1cs_gg_ppzksnark(example); 51 | assert(bit); 52 | } 53 | 54 | int main () { 55 | default_r1cs_gg_ppzksnark_pp::init_public_params(); 56 | test_r1cs_gg_ppzksnark(1000, 100); 57 | 58 | return 0; 59 | } 60 | -------------------------------------------------------------------------------- /src/range.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | #include 5 | 6 | using namespace libsnark; 7 | using namespace std; 8 | 9 | int main () { 10 | typedef libff::Fr FieldT; 11 | 12 | // Initialize the curve parameters 13 | default_r1cs_gg_ppzksnark_pp::init_public_params(); 14 | 15 | // Create protoboard 16 | protoboard pb; 17 | 18 | pb_variable x, max; 19 | pb_variable less, less_or_eq; 20 | 21 | x.allocate(pb, "x"); 22 | max.allocate(pb, "max"); 23 | less.allocate(pb, "less"); // must have 24 | less_or_eq.allocate(pb, "less_or_eq"); 25 | 26 | pb.val(max)= 60; 27 | 28 | comparison_gadget cmp(pb, 10, x, max, less, less_or_eq, "cmp"); 29 | cmp.generate_r1cs_constraints(); 30 | pb.add_r1cs_constraint(r1cs_constraint(less, 1, FieldT::one())); 31 | 32 | const r1cs_constraint_system constraint_system = pb.get_constraint_system(); 33 | 34 | // generate keypair 35 | const r1cs_gg_ppzksnark_keypair keypair = r1cs_gg_ppzksnark_generator(constraint_system); 36 | 37 | // Add witness values 38 | pb.val(x) = 18; // secret 39 | cmp.generate_r1cs_witness(); 40 | 41 | // generate proof 42 | const r1cs_gg_ppzksnark_proof proof = r1cs_gg_ppzksnark_prover(keypair.pk, pb.primary_input(), pb.auxiliary_input()); 43 | 44 | // verify 45 | bool verified = r1cs_gg_ppzksnark_verifier_strong_IC(keypair.vk, pb.primary_input(), proof); 46 | 47 | cout << "Number of R1CS constraints: " << constraint_system.num_constraints() << endl; 48 | cout << "Primary (public) input: " << pb.primary_input() << endl; 49 | cout << "Auxiliary (private) input: " << pb.auxiliary_input() << endl; 50 | cout << "Verification status: " << verified << endl; 51 | 52 | return 0; 53 | } 54 | -------------------------------------------------------------------------------- /src/test.cpp: -------------------------------------------------------------------------------- 1 | #include 2 | #include 3 | #include 4 | 5 | using namespace libsnark; 6 | using namespace std; 7 | 8 | int main () { 9 | typedef libff::Fr FieldT; 10 | 11 | // Initialize the curve parameters 12 | default_r1cs_gg_ppzksnark_pp::init_public_params(); 13 | 14 | // Create protoboard 15 | protoboard pb; 16 | 17 | // Define variables 18 | pb_variable x; 19 | pb_variable sym_1; 20 | pb_variable y; 21 | pb_variable sym_2; 22 | pb_variable out; 23 | 24 | // Allocate variables to protoboard 25 | // The strings (like "x") are only for debugging purposes 26 | out.allocate(pb, "out"); 27 | x.allocate(pb, "x"); 28 | sym_1.allocate(pb, "sym_1"); 29 | y.allocate(pb, "y"); 30 | sym_2.allocate(pb, "sym_2"); 31 | 32 | // This sets up the protoboard variables 33 | // so that the first one (out) represents the public 34 | // input and the rest is private input 35 | pb.set_input_sizes(1); 36 | 37 | // Add R1CS constraints to protoboard 38 | 39 | // x*x = sym_1 40 | pb.add_r1cs_constraint(r1cs_constraint(x, x, sym_1)); 41 | 42 | // sym_1 * x = y 43 | pb.add_r1cs_constraint(r1cs_constraint(sym_1, x, y)); 44 | 45 | // y + x = sym_2 46 | pb.add_r1cs_constraint(r1cs_constraint(y + x, 1, sym_2)); 47 | 48 | // sym_2 + 5 = ~out 49 | pb.add_r1cs_constraint(r1cs_constraint(sym_2 + 5, 1, out)); 50 | 51 | const r1cs_constraint_system constraint_system = pb.get_constraint_system(); 52 | 53 | // generate keypair 54 | const r1cs_gg_ppzksnark_keypair keypair = r1cs_gg_ppzksnark_generator(constraint_system); 55 | 56 | // Add public input and witness values 57 | pb.val(out) = 35; 58 | 59 | pb.val(x) = 3; 60 | pb.val(sym_1) = 9; 61 | pb.val(y) = 27; 62 | pb.val(sym_2) = 30; 63 | 64 | // generate proof 65 | const r1cs_gg_ppzksnark_proof proof = r1cs_gg_ppzksnark_prover(keypair.pk, pb.primary_input(), pb.auxiliary_input()); 66 | 67 | // verify 68 | bool verified = r1cs_gg_ppzksnark_verifier_strong_IC(keypair.vk, pb.primary_input(), proof); 69 | 70 | cout << "Number of R1CS constraints: " << constraint_system.num_constraints() << endl; 71 | cout << "Primary (public) input: " << pb.primary_input() << endl; 72 | cout << "Auxiliary (private) input: " << pb.auxiliary_input() << endl; 73 | cout << "Verification status: " << verified << endl; 74 | 75 | return 0; 76 | } 77 | --------------------------------------------------------------------------------