diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml index a4a26a4..3f60650 100644 --- a/.github/workflows/build.yml +++ b/.github/workflows/build.yml @@ -41,19 +41,19 @@ jobs: - name: Build prover Android ARM64 run: | - mkdir build_prover_android && cd build_prover_android + mkdir -p build_prover_android && cd build_prover_android cmake .. -DTARGET_PLATFORM=ANDROID -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_android make -j4 && make install - name: Build prover Android x86_64 run: | - mkdir build_prover_android_x86_64 && cd build_prover_android_x86_64 + mkdir -p build_prover_android_x86_64 && cd build_prover_android_x86_64 cmake .. -DTARGET_PLATFORM=ANDROID_x86_64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_android_x86_64 make -j4 && make install - name: Build prover Linux run: | - mkdir build_prover && cd build_prover + mkdir -p build_prover && cd build_prover cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package make -j4 && make install @@ -65,35 +65,62 @@ jobs: package/bin/prover testdata/circuit_final.zkey testdata/witness.wtns proof.json public.json snarkjs groth16 verify testdata/verification_key.json public.json proof.json - - name: upload Android ARM64 artifacts + - name: upload Linux amd64 dev artifacts + if: github.event_name != 'release' + uses: actions/upload-artifact@v3 + with: + name: rapidsnark-linux-amd64 + path: | + package + if-no-files-found: error + + - name: upload Android dev artifacts + if: github.event_name != 'release' + uses: actions/upload-artifact@v3 + with: + name: rapidsnark-Android + path: | + package_android + if-no-files-found: error + + - name: upload Android x86_64 dev artifacts + if: github.event_name != 'release' + uses: actions/upload-artifact@v3 + with: + name: rapidsnark-Android-x86_64 + path: | + package_android_x86_64 + if-no-files-found: error + + - name: upload Android ARM64 release artifacts if: github.event_name == 'release' env: GH_TOKEN: ${{ github.token }} run: | set -x - mkdir rapidsnark-android-arm64-${{ github.ref_name }} + mkdir -p rapidsnark-android-arm64-${{ github.ref_name }} cp -r package_android/* rapidsnark-android-arm64-${{ github.ref_name }}/ zip -r rapidsnark-android-arm64-${{ github.ref_name }}.zip rapidsnark-android-arm64-${{ github.ref_name }} gh release upload ${{ github.event.release.tag_name }} rapidsnark-android-arm64-${{ github.ref_name }}.zip - - name: upload Android x86_64 artifacts + - name: upload Android x86_64 release artifacts if: github.event_name == 'release' env: GH_TOKEN: ${{ github.token }} run: | set -x - mkdir rapidsnark-android-x86_64-${{ github.ref_name }} + mkdir -p rapidsnark-android-x86_64-${{ github.ref_name }} cp -r package_android_x86_64/* rapidsnark-android-x86_64-${{ github.ref_name }}/ zip -r rapidsnark-android-x86_64-${{ github.ref_name }}.zip rapidsnark-android-x86_64-${{ github.ref_name }} gh release upload ${{ github.event.release.tag_name }} rapidsnark-android-x86_64-${{ github.ref_name }}.zip - - name: upload Linux x86_64 artifacts + - name: upload Linux x86_64 release artifacts if: github.event_name == 'release' env: GH_TOKEN: ${{ github.token }} run: | set -x - mkdir rapidsnark-linux-x86_64-${{ github.ref_name }} + mkdir -p rapidsnark-linux-x86_64-${{ github.ref_name }} cp -r package/* rapidsnark-linux-x86_64-${{ github.ref_name }}/ zip -r rapidsnark-linux-x86_64-${{ github.ref_name }}.zip rapidsnark-linux-x86_64-${{ github.ref_name }} gh release upload ${{ github.event.release.tag_name }} rapidsnark-linux-x86_64-${{ github.ref_name }}.zip @@ -119,19 +146,19 @@ jobs: if [[ ! -d "depends/gmp/package_iphone_simulator" ]]; then ./build_gmp.sh ios_simulator; fi if [[ ! -d "depends/gmp/package_macos_arm64" ]]; then ./build_gmp.sh macos_arm64; fi - mkdir build_prover_ios && cd build_prover_ios + mkdir -p build_prover_ios && cd build_prover_ios cmake .. -GXcode -DTARGET_PLATFORM=IOS -DCMAKE_INSTALL_PREFIX=../package_ios xcodebuild -destination 'generic/platform=iOS' -scheme rapidsnarkStatic -project rapidsnark.xcodeproj -configuration Release cp ../depends/gmp/package_ios_arm64/lib/libgmp.a src/Release-iphoneos cd ../ - mkdir build_prover_ios_simulator && cd build_prover_ios_simulator + mkdir -p build_prover_ios_simulator && cd build_prover_ios_simulator cmake .. -GXcode -DTARGET_PLATFORM=IOS -DCMAKE_INSTALL_PREFIX=../package_ios_simulator -DUSE_ASM=NO xcodebuild -destination 'generic/platform=iOS Simulator' -scheme rapidsnarkStatic -project rapidsnark.xcodeproj cp ../depends/gmp/package_iphone_simulator/lib/libgmp.a src/Debug-iphonesimulator cd ../ - mkdir build_prover_macos_arm64 && cd build_prover_macos_arm64 + mkdir -p build_prover_macos_arm64 && cd build_prover_macos_arm64 cmake .. -DTARGET_PLATFORM=macos_arm64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_macos_arm64 make -j4 && make install @@ -143,35 +170,62 @@ jobs: package_macos_arm64/bin/prover testdata/circuit_final.zkey testdata/witness.wtns proof.json public.json snarkjs groth16 verify testdata/verification_key.json public.json proof.json - - name: upload iOS artifacts + - name: upload macOS arm64 dev artifacts + if: github.event_name != 'release' + uses: actions/upload-artifact@v3 + with: + name: rapidsnark-macOS-arm64 + path: | + package_macos_arm64 + if-no-files-found: error + + - name: upload iOS dev artifacts + if: github.event_name != 'release' + uses: actions/upload-artifact@v3 + with: + name: rapidsnark-iOS + path: | + build_prover_ios/src/Release-iphoneos + if-no-files-found: error + + - name: upload iOS Simulator dev artifacts + if: github.event_name != 'release' + uses: actions/upload-artifact@v3 + with: + name: rapidsnark-iOS-Simulator + path: | + build_prover_ios_simulator/src/Debug-iphonesimulator + if-no-files-found: error + + - name: upload iOS release artifacts if: github.event_name == 'release' env: GH_TOKEN: ${{ github.token }} run: | set -x - mkdir rapidsnark-iOS-${{ github.ref_name }} + mkdir -p rapidsnark-iOS-${{ github.ref_name }} cp -r build_prover_ios/src/Release-iphoneos/* rapidsnark-iOS-${{ github.ref_name }}/ zip -r rapidsnark-iOS-${{ github.ref_name }}.zip rapidsnark-iOS-${{ github.ref_name }} gh release upload ${{ github.event.release.tag_name }} rapidsnark-iOS-${{ github.ref_name }}.zip - - name: upload iOS Simulator artifacts + - name: upload iOS Simulator release artifacts if: github.event_name == 'release' env: GH_TOKEN: ${{ github.token }} run: | set -x - mkdir rapidsnark-iOS-Simulator-${{ github.ref_name }} + mkdir -p rapidsnark-iOS-Simulator-${{ github.ref_name }} cp -r build_prover_ios_simulator/src/Debug-iphonesimulator/* rapidsnark-iOS-Simulator-${{ github.ref_name }}/ zip -r rapidsnark-iOS-Simulator-${{ github.ref_name }}.zip rapidsnark-iOS-Simulator-${{ github.ref_name }} gh release upload ${{ github.event.release.tag_name }} rapidsnark-iOS-Simulator-${{ github.ref_name }}.zip - - name: upload macOS arm64 artifacts + - name: upload macOS arm64 release artifacts if: github.event_name == 'release' env: GH_TOKEN: ${{ github.token }} run: | set -x - mkdir rapidsnark-macOS-arm64-${{ github.ref_name }} + mkdir -p rapidsnark-macOS-arm64-${{ github.ref_name }} cp -r package_macos_arm64/* rapidsnark-macOS-arm64-${{ github.ref_name }}/ zip -r rapidsnark-macOS-arm64-${{ github.ref_name }}.zip rapidsnark-macOS-arm64-${{ github.ref_name }} gh release upload ${{ github.event.release.tag_name }} rapidsnark-macOS-arm64-${{ github.ref_name }}.zip @@ -199,7 +253,7 @@ jobs: run: | if [[ ! -d "depends/gmp/package_macos_x86_64" ]]; then ./build_gmp.sh macos_x86_64; fi - mkdir build_prover_macos_x86_64 && cd build_prover_macos_x86_64 + mkdir -p build_prover_macos_x86_64 && cd build_prover_macos_x86_64 cmake .. -DTARGET_PLATFORM=macos_x86_64 -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package_macos_x86_64 make -j4 && make install @@ -211,13 +265,22 @@ jobs: package_macos_x86_64/bin/prover testdata/circuit_final.zkey testdata/witness.wtns proof.json public.json snarkjs groth16 verify testdata/verification_key.json public.json proof.json - - name: upload macOS x86_64 artifacts + - name: upload macOS x86_64 dev artifacts + if: github.event_name != 'release' + uses: actions/upload-artifact@v3 + with: + name: rapidsnark-macOS-x86_64 + path: | + package_macos_x86_64 + if-no-files-found: error + + - name: upload macOS x86_64 release artifacts if: github.event_name == 'release' env: GH_TOKEN: ${{ github.token }} run: | set -x - mkdir rapidsnark-macOS-x86_64-${{ github.ref_name }} + mkdir -p rapidsnark-macOS-x86_64-${{ github.ref_name }} cp -r package_macos_x86_64/* rapidsnark-macOS-x86_64-${{ github.ref_name }}/ zip -r rapidsnark-macOS-x86_64-${{ github.ref_name }}.zip rapidsnark-macOS-x86_64-${{ github.ref_name }} gh release upload ${{ github.event.release.tag_name }} rapidsnark-macOS-x86_64-${{ github.ref_name }}.zip diff --git a/build/fq.cpp b/build/fq.cpp index afdba04..2078fe6 100644 --- a/build/fq.cpp +++ b/build/fq.cpp @@ -2,8 +2,8 @@ #include #include #include -#include #include +#include static mpz_t q; @@ -162,7 +162,7 @@ void Fq_div(PFqElement r, PFqElement a, PFqElement b) { } void Fq_fail() { - assert(false); + throw std::runtime_error("Fq error"); } void Fq_longErr() diff --git a/build/fq_generic.cpp b/build/fq_generic.cpp index 58723ae..f771e20 100755 --- a/build/fq_generic.cpp +++ b/build/fq_generic.cpp @@ -1,7 +1,6 @@ #include "fq.hpp" #include #include -#include FqElement Fq_q = {0, 0x80000000, {0x3c208c16d87cfd47,0x97816a916871ca8d,0xb85045b68181585d,0x30644e72e131a029}}; FqElement Fq_R2 = {0, 0x80000000, {0xf32cfc5b538afa89,0xb5e71911d44501fb,0x47ab1eff0a417ff6,0x06d89f71cab8351f}}; diff --git a/build/fr.cpp b/build/fr.cpp index 168d95e..415a824 100644 --- a/build/fr.cpp +++ b/build/fr.cpp @@ -2,8 +2,8 @@ #include #include #include -#include #include +#include static mpz_t q; @@ -162,7 +162,7 @@ void Fr_div(PFrElement r, PFrElement a, PFrElement b) { } void Fr_fail() { - assert(false); + throw std::runtime_error("Fr error"); } void Fr_longErr() diff --git a/build/fr_generic.cpp b/build/fr_generic.cpp index 3d8ee16..6c0d874 100755 --- a/build/fr_generic.cpp +++ b/build/fr_generic.cpp @@ -1,7 +1,6 @@ #include "fr.hpp" #include #include -#include FrElement Fr_q = {0, 0x80000000, {0x43e1f593f0000001,0x2833e84879b97091,0xb85045b68181585d,0x30644e72e131a029}}; FrElement Fr_R2 = {0, 0x80000000, {0x1bb8e645ae216da7,0x53fe3ab1e35c59e3,0x8c49833d53bb8085,0x0216d0b17f4e44a5}}; diff --git a/src/binfile_utils.cpp b/src/binfile_utils.cpp index de6d0d7..4ca5dab 100644 --- a/src/binfile_utils.cpp +++ b/src/binfile_utils.cpp @@ -1,3 +1,7 @@ +#include +#include +#include +#include #include #include #include @@ -8,8 +12,70 @@ namespace BinFileUtils { +BinFile::BinFile(const std::string& fileName, const std::string& _type, uint32_t maxVersion) { + + is_fd = true; + struct stat sb; + + fd = open(fileName.c_str(), O_RDONLY); + if (fd == -1) + throw std::system_error(errno, std::generic_category(), "open"); + + + if (fstat(fd, &sb) == -1) /* To obtain file size */ + throw std::system_error(errno, std::generic_category(), "fstat"); + + size = sb.st_size; + + addr = mmap(nullptr, sb.st_size, PROT_READ, MAP_PRIVATE, fd, 0); + if (addr == MAP_FAILED) { + close(fd); + throw std::system_error(errno, std::generic_category(), "mmap failed"); + } + madvise(addr, size, MADV_SEQUENTIAL); + + type.assign((const char *)addr, 4); + pos = 4; + + if (type != _type) { + munmap(addr, size); + close(fd); + throw std::invalid_argument("Invalid file type. It should be " + _type + " and it is " + type + " filename: " + fileName); + } + + version = readU32LE(); + if (version > maxVersion) { + munmap(addr, size); + close(fd); + throw std::invalid_argument("Invalid version. It should be <=" + std::to_string(maxVersion) + " and it is " + std::to_string(version)); + } + + u_int32_t nSections = readU32LE(); + + + for (u_int32_t i=0; i())); + } + + sections[sType].push_back(Section( (void *)((u_int64_t)addr + pos), sSize)); + + pos += sSize; + } + + pos = 0; + readingSection = nullptr; +} + + BinFile::BinFile(const void *fileData, size_t fileSize, std::string _type, uint32_t maxVersion) { + is_fd = false; + fd = -1; + size = fileSize; addr = malloc(size); memcpy(addr, fileData, size); @@ -19,13 +85,13 @@ BinFile::BinFile(const void *fileData, size_t fileSize, std::string _type, uint3 if (type != _type) { free(addr); - throw new std::invalid_argument("Invalid file type. It should be " + _type + " and it is " + type); + throw std::invalid_argument("Invalid file type. It should be " + _type + " and it is " + type); } version = readU32LE(); if (version > maxVersion) { free(addr); - throw new std::invalid_argument("Invalid version. It should be <=" + std::to_string(maxVersion) + " and it is " + std::to_string(version)); + throw std::invalid_argument("Invalid version. It should be <=" + std::to_string(maxVersion) + " and it is " + std::to_string(version)); } u_int32_t nSections = readU32LE(); @@ -49,21 +115,26 @@ BinFile::BinFile(const void *fileData, size_t fileSize, std::string _type, uint3 } BinFile::~BinFile() { - free(addr); + if (is_fd) { + munmap(addr, size); + close(fd); + } else { + free(addr); + } } void BinFile::startReadSection(u_int32_t sectionId, u_int32_t sectionPos) { if (sections.find(sectionId) == sections.end()) { - throw new std::range_error("Section does not exist: " + std::to_string(sectionId)); + throw std::range_error("Section does not exist: " + std::to_string(sectionId)); } if (sectionPos >= sections[sectionId].size()) { - throw new std::range_error("Section pos too big. There are " + std::to_string(sections[sectionId].size()) + " and it's trying to access section: " + std::to_string(sectionPos)); + throw std::range_error("Section pos too big. There are " + std::to_string(sections[sectionId].size()) + " and it's trying to access section: " + std::to_string(sectionPos)); } if (readingSection != NULL) { - throw new std::range_error("Already reading a section"); + throw std::range_error("Already reading a section"); } pos = (u_int64_t)(sections[sectionId][sectionPos].start) - (u_int64_t)addr; @@ -74,7 +145,7 @@ void BinFile::startReadSection(u_int32_t sectionId, u_int32_t sectionPos) { void BinFile::endReadSection(bool check) { if (check) { if ((u_int64_t)addr + pos - (u_int64_t)(readingSection->start) != readingSection->size) { - throw new std::range_error("Invalid section size"); + throw std::range_error("Invalid section size"); } } readingSection = NULL; @@ -83,14 +154,14 @@ void BinFile::endReadSection(bool check) { void *BinFile::getSectionData(u_int32_t sectionId, u_int32_t sectionPos) { if (sections.find(sectionId) == sections.end()) { - throw new std::range_error("Section does not exist: " + std::to_string(sectionId)); + throw std::range_error("Section does not exist: " + std::to_string(sectionId)); } if (sectionPos >= sections[sectionId].size()) { - throw new std::range_error("Section pos too big. There are " + std::to_string(sections[sectionId].size()) + " and it's trying to access section: " + std::to_string(sectionPos)); + throw std::range_error("Section pos too big. There are " + std::to_string(sections[sectionId].size()) + " and it's trying to access section: " + std::to_string(sectionPos)); } - return sections[sectionId][sectionPos].start; + return sections[sectionId][sectionPos].start; } u_int64_t BinFile::getSectionSize(u_int32_t sectionId, u_int32_t sectionPos) { @@ -103,7 +174,7 @@ u_int64_t BinFile::getSectionSize(u_int32_t sectionId, u_int32_t sectionPos) { throw new std::range_error("Section pos too big. There are " + std::to_string(sections[sectionId].size()) + " and it's trying to access section: " + std::to_string(sectionPos)); } - return sections[sectionId][sectionPos].size; + return sections[sectionId][sectionPos].size; } u_int32_t BinFile::readU32LE() { @@ -124,11 +195,8 @@ void *BinFile::read(u_int64_t len) { return res; } -std::unique_ptr openExisting(std::string filename, std::string type, uint32_t maxVersion) { - - FileLoader fileLoader(filename); - - return std::unique_ptr(new BinFile(fileLoader.dataBuffer(), fileLoader.dataSize(), type, maxVersion)); +std::unique_ptr openExisting(const std::string& filename, const std::string& type, uint32_t maxVersion) { + return std::unique_ptr(new BinFile(filename, type, maxVersion)); } } // Namespace diff --git a/src/binfile_utils.hpp b/src/binfile_utils.hpp index 44b74d3..69c2201 100644 --- a/src/binfile_utils.hpp +++ b/src/binfile_utils.hpp @@ -9,6 +9,9 @@ namespace BinFileUtils { class BinFile { + bool is_fd; + int fd; + void *addr; u_int64_t size; u_int64_t pos; @@ -33,10 +36,11 @@ namespace BinFileUtils { public: BinFile(const void *fileData, size_t fileSize, std::string _type, uint32_t maxVersion); + BinFile(const std::string& fileName, const std::string& _type, uint32_t maxVersion); + BinFile(const BinFile&) = delete; + BinFile& operator=(const BinFile&) = delete; ~BinFile(); - void *getSetcionData(u_int32_t sectionId, u_int32_t sectionPos = 0); - void startReadSection(u_int32_t sectionId, u_int32_t setionPos = 0); void endReadSection(bool check = true); @@ -49,7 +53,7 @@ namespace BinFileUtils { void *read(uint64_t l); }; - std::unique_ptr openExisting(std::string filename, std::string type, uint32_t maxVersion); + std::unique_ptr openExisting(const std::string& filename, const std::string& type, uint32_t maxVersion); } #endif // BINFILE_UTILS_H diff --git a/src/fileloader.cpp b/src/fileloader.cpp index 48381a0..efc1b6c 100644 --- a/src/fileloader.cpp +++ b/src/fileloader.cpp @@ -25,7 +25,7 @@ FileLoader::FileLoader(const std::string& fileName) size = sb.st_size; - addr = mmap(NULL, size, PROT_READ, MAP_PRIVATE, fd, 0); + addr = mmap(nullptr, size, PROT_READ, MAP_PRIVATE, fd, 0); } FileLoader::~FileLoader() diff --git a/src/prover.cpp b/src/prover.cpp index 4c3fee0..d443d66 100644 --- a/src/prover.cpp +++ b/src/prover.cpp @@ -11,6 +11,7 @@ #include "wtns_utils.hpp" #include "groth16.hpp" #include "binfile_utils.hpp" +#include "fileloader.hpp" using json = nlohmann::json; @@ -65,13 +66,11 @@ unsigned long CalcPublicBufferSize(const void *zkey_buffer, unsigned long zkey_s return 0; } -int -groth16_prover(const void *zkey_buffer, unsigned long zkey_size, - const void *wtns_buffer, unsigned long wtns_size, - char *proof_buffer, unsigned long *proof_size, - char *public_buffer, unsigned long *public_size, - char *error_msg, unsigned long error_msg_maxsize) -{ +int groth16_prover(const void *zkey_buffer, unsigned long zkey_size, + const void *wtns_buffer, unsigned long wtns_size, + char *proof_buffer, unsigned long *proof_size, + char *public_buffer, unsigned long *public_size, + char *error_msg, unsigned long error_msg_maxsize) { try { BinFileUtils::BinFile zkey(zkey_buffer, zkey_size, "zkey", 1); auto zkeyHeader = ZKeyUtils::loadHeader(&zkey); @@ -160,3 +159,20 @@ groth16_prover(const void *zkey_buffer, unsigned long zkey_size, return PROVER_OK; } + +int groth16_prover_zkey_file(const char *zkey_file_path, + const void *wtns_buffer, unsigned long wtns_size, + char *proof_buffer, unsigned long *proof_size, + char *public_buffer, unsigned long *public_size, + char *error_msg, unsigned long error_msg_maxsize) { + + std::string zkey_filename(zkey_file_path); + + BinFileUtils::FileLoader fileLoader(zkey_filename); + + return groth16_prover(fileLoader.dataBuffer(), fileLoader.dataSize(), + wtns_buffer, wtns_size, + proof_buffer, proof_size, + public_buffer, public_size, + error_msg, error_msg_maxsize); +} diff --git a/src/prover.h b/src/prover.h index 79d55f0..a250bb1 100644 --- a/src/prover.h +++ b/src/prover.h @@ -25,11 +25,25 @@ unsigned long CalcPublicBufferSize(const void *zkey_buffer, unsigned long zkey_s * PROVER_ERROR_SHORT_BUFFER - in case of a short buffer error, also updates proof_size and public_size with actual proof and public sizess */ int -groth16_prover(const void *zkey_buffer, unsigned long zkey_size, - const void *wtns_buffer, unsigned long wtns_size, - char *proof_buffer, unsigned long *proof_size, - char *public_buffer, unsigned long *public_size, - char *error_msg, unsigned long error_msg_maxsize); +groth16_prover(const void *zkey_buffer, unsigned long zkey_size, + const void *wtns_buffer, unsigned long wtns_size, + char *proof_buffer, unsigned long *proof_size, + char *public_buffer, unsigned long *public_size, + char *error_msg, unsigned long error_msg_maxsize); + +/** + * groth16_prover + * @return error code: + * PROVER_OK - in case of success + * PPOVER_ERROR - in case of an error + * PROVER_ERROR_SHORT_BUFFER - in case of a short buffer error, also updates proof_size and public_size with actual proof and public sizess + */ +int +groth16_prover_zkey_file(const char *zkey_file_path, + const void *wtns_buffer, unsigned long wtns_size, + char *proof_buffer, unsigned long *proof_size, + char *public_buffer, unsigned long *public_size, + char *error_msg, unsigned long error_msg_maxsize); #ifdef __cplusplus }