scipr-lab / libsnark

C++ library for zkSNARKs
Other
1.81k stars 579 forks source link

Libsnark tutorial does not compile #93

Closed Recognition2 closed 6 years ago

Recognition2 commented 6 years ago

End goal: Use libsnark as a library

When trying to utilize libsnark from an external project, following the steps in the readme as following.

  1. add libsnark as a subdirectory.
  2. add snark as a dependency to the target.
  3. install libsnark to /usr/local/include

Then when trying to compile a subset of one of your tests:

#include <iostream>

#include <libsnark/gadgetlib2/pp.hpp>
#include <libsnark/gadgetlib2/protoboard.hpp>

using namespace gadgetlib2;

int main () {
    initPublicParamsFromDefaultPp();
    auto pb = Protoboard::create(R1P)

    return 0;
}

It fails on:

In file included from /home/XXX/Documents/zkproofs/libsnark/depends/libff/libff/algebra/curves/bn128/bn128_pp.hpp:10:0,
                 from /home/XXX/Documents/zkproofs/libsnark/depends/libff/libff/common/default_types/ec_pp.hpp:28,
                 from /usr/local/include/libsnark/gadgetlib2/pp.hpp:16,
                 from /home/XXX/Documents/zkproofs/main.cpp:3:
/home/XXX/Documents/zkproofs/libsnark/depends/libff/libff/algebra/curves/bn128/bn128_g1.hpp:12:44: fatal error: depends/ate-pairing/include/bn.h: No such file or directory

The #include "depends/ate-pairing/include/bn.h" fails.

We used the defines from the flags.make, as stated in the README, but still things kept going wrong.

Do we need to add an extra dependency in the cmake lists or is something else going wrong?

howardwu commented 6 years ago

Thanks for filing this. The issue is that the compiler will need to be capable of seeing the dependencies that BN128 requires from your compilation path.

There are a few ways to resolve this, in order of complexity for your case.

Option 1

Use ALT_BN128 instead of BN128.

Both BN128 and ALT_BN128 instantiate a Barreto-Naehrig curve, however with different architectures. BN128 attempts stronger optimizations using dynamic code generation. One can expect ALT_BN128 to be slightly slower.

Option 2

Create a depends directory and add ate-pairing and xbyak as git submodules in the depends directory.

mkdir depends && cd depends
git submodule add https://github.com/herumi/ate-pairing.git ate-pairing
git submodule add https://github.com/herumi/xbyak.git xbyak

Then, add the following CMakeLists.txt file in the depends directory.

if(${CURVE} STREQUAL "BN128")
  include_directories(ate-pairing/include)
  include_directories(xbyak)
  add_library(
    zm
    STATIC

    ate-pairing/src/zm.cpp
    ate-pairing/src/zm2.cpp
  )
endif()

In the root CMakeLists.txt file, add a reference to it with add_subdirectory(depends).

In the source folder CMakeLists.txt file, link it as follows.

set(SNARK_EXTRALIBS)
if(${CURVE} STREQUAL "BN128")
  set(
    SNARK_EXTRALIBS

    ${SNARK_EXTRALIBS}
    ${PROCPS_LIBRARIES}
    zm
  )
endif()

add_executable(
  main

  main.cpp
)
target_link_libraries(
  main

  ${LIBSNARK_LIBRARIES}
  ${SNARK_EXTRALIBS}
)

Option 3

Create a depends directory and add libsnark as a git submodule.

mkdir depends && cd depends
git submodule add https://github.com/scipr-lab/libsnark.git libsnark

Remember to recursively fetch the submodules from libsnark.

Add libsnark as a subdirectory in the depends/CMakeLists.txt file.

add_subdirectory(libsnark)

Add the depends directory as a subdirectory in the root CMakeLists.txt file before calling to the src subdirectory.

add_subdirectory(depends)
howardwu commented 6 years ago

As you have already installed libsnark on your machine, I would recommend going with Option 2.

hasinitg commented 6 years ago

Hi @howardwu,

I am also trying to use libsnark as a library in my project. I followed the option 3 that you have mentioned above. However, it seems to me that adding 'depends' folder as a subdirectory is not sufficient and we need to link libsnark.a and libff.a as well. Therefore I added the following line at the end of my root CMakeLists.txt as well. target_link_libraries(myProject libsnark.a libff.a)

When I do that, I get many errors similar to below: Undefined symbols for architecture x86_64: "mie::Fp::getDirectP(int)", referenced from: bn::Fp2T<mie::Fp>::Dbl::squareC(bn::Fp2T<mie::Fp>::Dbl&, bn::Fp2T<mie::Fp> const&) in libff.a(bn128_pairing.cpp.o)

All the not found symbols are from the "mie" namespace which is referenced from "bn" namespace, in libff.a I did set the CURVE to be ALT_BN128 by changing the following entry in depends/libsnark/CMakeLists.txt as follows: set( CURVE "ALT_BN128" CACHE STRING "Default curve: one of ALT_BN128, BN128, EDWARDS, MNT4, MNT6" )

I also tried linking only libsnark.a as mentioned in README, without linking libff.a, then I get errors about undefined symbols in libsnark.a that are referenced from libff::bn128 related namespace, as below:

Undefined symbols for architecture x86_64: "libff::bn128_modulus_r", referenced from: libff::Fp_model<4l, libff::bn128_modulus_r>::Fp_model(long, bool) in libsnark.a(pp.cpp.o) "libff::bn128_pp::init_public_params()", referenced from: gadgetlib2::initPublicParamsFromDefaultPp() in libsnark.a(pp.cpp.o) "___gmpn_copyi", referenced from: done0 in libsnark.a(pp.cpp.o)

I would really appreciate any insights in resolving the issue in order to link libsnark to my project properly.

Thank you very much in advance.

hasinitg commented 6 years ago

Hi @howardwu,

I found your libsnark-tutorial in your GitHub profile (https://github.com/howardwu/libsnark-tutorial). It was very helpful, in order to learn all the steps of properly integrating libsnark to our own application. Please ignore my previous question. The above tutorial should have been linked in the libsnark README file, as the steps in the current libsnark README file is not complete. If so, it would have saved lot of my time. Thank you so much again for that tutorial and please consider linking it in the libsnark README file for the benefit of future users of libsnark.

Thank you.

howardwu commented 6 years ago

Glad you found libsnark-tutorial useful! Marking as resolved.