Skip to content

Commit

Permalink
Merge pull request #4 from iden3/feature/calcPublicBufferSize
Browse files Browse the repository at this point in the history
Calc Public Buffer Size
  • Loading branch information
OBrezhniev authored Jan 4, 2024
2 parents a7ec7e5 + 033fb29 commit ea72e69
Show file tree
Hide file tree
Showing 4 changed files with 98 additions and 46 deletions.
8 changes: 8 additions & 0 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,14 @@ jobs:
cmake .. -DCMAKE_BUILD_TYPE=Release -DCMAKE_INSTALL_PREFIX=../package
make -j4 && make install
- name: test prover for linux
run: |
set -x
set -e
npm install -g snarkjs
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
if: github.event_name == 'release'
env:
Expand Down
87 changes: 57 additions & 30 deletions src/main_prover.cpp
Original file line number Diff line number Diff line change
@@ -1,17 +1,21 @@
#include <iostream>
#include <fstream>
#include <gmp.h>
#include <memory>
#include <stdexcept>
#include <nlohmann/json.hpp>

#include "fileloader.hpp"
#include "prover.h"
#include <alt_bn128.hpp>
#include "binfile_utils.hpp"
#include "zkey_utils.hpp"
#include "wtns_utils.hpp"
#include "groth16.hpp"

using json = nlohmann::json;

#define handle_error(msg) \
do { perror(msg); exit(EXIT_FAILURE); } while (0)


const size_t BufferSize = 32768;


int main(int argc, char **argv)
{
if (argc != 5) {
Expand All @@ -20,57 +24,80 @@ int main(int argc, char **argv)
return EXIT_FAILURE;
}

mpz_t altBbn128r;

mpz_init(altBbn128r);
mpz_set_str(altBbn128r, "21888242871839275222246405745257275088548364400416034343698204186575808495617", 10);

try {
std::string zkeyFilename = argv[1];
std::string wtnsFilename = argv[2];
std::string proofFilename = argv[3];
std::string publicFilename = argv[4];

char proofBuffer[BufferSize];
char publicBuffer[BufferSize];
size_t proofSize = sizeof(proofBuffer);
size_t publicSize = sizeof(publicBuffer);
char errorMessage[256];
int error = 0;

BinFileUtils::FileLoader zkeyFileLoader(zkeyFilename);
BinFileUtils::FileLoader wtnsFileLoader(wtnsFilename);
auto zkey = BinFileUtils::openExisting(zkeyFilename, "zkey", 1);
auto zkeyHeader = ZKeyUtils::loadHeader(zkey.get());

error = groth16_prover(zkeyFileLoader.dataBuffer(), zkeyFileLoader.dataSize(),
wtnsFileLoader.dataBuffer(), wtnsFileLoader.dataSize(),
proofBuffer, &proofSize,
publicBuffer, &publicSize,
errorMessage, sizeof(errorMessage));
std::string proofStr;
if (mpz_cmp(zkeyHeader->rPrime, altBbn128r) != 0) {
throw std::invalid_argument( "zkey curve not supported" );
}

if (error == PPROVER_ERROR_SHORT_BUFFER) {
auto wtns = BinFileUtils::openExisting(wtnsFilename, "wtns", 2);
auto wtnsHeader = WtnsUtils::loadHeader(wtns.get());

std::cerr << "Error: Short buffer for proof or public" << '\n';
return EXIT_FAILURE;
if (mpz_cmp(wtnsHeader->prime, altBbn128r) != 0) {
throw std::invalid_argument( "different wtns curve" );
}

else if (error) {
std::cerr << errorMessage << '\n';
return EXIT_FAILURE;
}
auto prover = Groth16::makeProver<AltBn128::Engine>(
zkeyHeader->nVars,
zkeyHeader->nPublic,
zkeyHeader->domainSize,
zkeyHeader->nCoefs,
zkeyHeader->vk_alpha1,
zkeyHeader->vk_beta1,
zkeyHeader->vk_beta2,
zkeyHeader->vk_delta1,
zkeyHeader->vk_delta2,
zkey->getSectionData(4), // Coefs
zkey->getSectionData(5), // pointsA
zkey->getSectionData(6), // pointsB1
zkey->getSectionData(7), // pointsB2
zkey->getSectionData(8), // pointsC
zkey->getSectionData(9) // pointsH1
);
AltBn128::FrElement *wtnsData = (AltBn128::FrElement *)wtns->getSectionData(2);
auto proof = prover->prove(wtnsData);

std::ofstream proofFile;
proofFile.open (proofFilename);
proofFile << proofBuffer;
proofFile << proof->toJson();
proofFile.close();

std::ofstream publicFile;
publicFile.open (publicFilename);
publicFile << publicBuffer;

json jsonPublic;
AltBn128::FrElement aux;
for (int i=1; i<=zkeyHeader->nPublic; i++) {
AltBn128::Fr.toMontgomery(aux, wtnsData[i]);
jsonPublic.push_back(AltBn128::Fr.toString(aux));
}

publicFile << jsonPublic;
publicFile.close();

} catch (std::exception* e) {
mpz_clear(altBbn128r);
std::cerr << e->what() << '\n';
return EXIT_FAILURE;

} catch (std::exception& e) {
mpz_clear(altBbn128r);
std::cerr << e.what() << '\n';
return EXIT_FAILURE;
}

mpz_clear(altBbn128r);
exit(EXIT_SUCCESS);
}
29 changes: 20 additions & 9 deletions src/prover.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,12 @@ using json = nlohmann::json;

static size_t ProofBufferMinSize()
{
return 726;
return 810;
}

static size_t PublicBufferMinSize(size_t count)
{
return count * 81 + 3;
return count * 82 + 4;
}

static void VerifyPrimes(mpz_srcptr zkey_prime, mpz_srcptr wtns_prime)
Expand Down Expand Up @@ -54,6 +54,17 @@ std::string BuildPublicString(AltBn128::FrElement *wtnsData, size_t nPublic)
return jsonPublic.dump();
}

unsigned long CalcPublicBufferSize(const void *zkey_buffer, unsigned long zkey_size) {
try {
BinFileUtils::BinFile zkey(zkey_buffer, zkey_size, "zkey", 1);
auto zkeyHeader = ZKeyUtils::loadHeader(&zkey);
return PublicBufferMinSize(zkeyHeader->nPublic);
} catch (...) {
}

return 0;
}

int
groth16_prover(const void *zkey_buffer, unsigned long zkey_size,
const void *wtns_buffer, unsigned long wtns_size,
Expand All @@ -72,7 +83,7 @@ groth16_prover(const void *zkey_buffer, unsigned long zkey_size,
snprintf(error_msg, error_msg_maxsize,
"Invalid witness length. Circuit: %u, witness: %u",
zkeyHeader->nVars, wtnsHeader->nVars);
return PPROVER_INVALID_WITNESS_LENGTH;
return PROVER_INVALID_WITNESS_LENGTH;
}

size_t proofMinSize = ProofBufferMinSize();
Expand All @@ -83,7 +94,7 @@ groth16_prover(const void *zkey_buffer, unsigned long zkey_size,
*proof_size = proofMinSize;
*public_size = publicMinSize;

return PPROVER_ERROR_SHORT_BUFFER;
return PROVER_ERROR_SHORT_BUFFER;
}

VerifyPrimes(zkeyHeader->rPrime, wtnsHeader->prime);
Expand Down Expand Up @@ -119,7 +130,7 @@ groth16_prover(const void *zkey_buffer, unsigned long zkey_size,
*proof_size = stringProofSize;
*public_size = stringPublicSize;

return PPROVER_ERROR_SHORT_BUFFER;
return PROVER_ERROR_SHORT_BUFFER;
}

std::strncpy(proof_buffer, stringProof.data(), *proof_size);
Expand All @@ -130,22 +141,22 @@ groth16_prover(const void *zkey_buffer, unsigned long zkey_size,
if (error_msg) {
strncpy(error_msg, e.what(), error_msg_maxsize);
}
return PPROVER_ERROR;
return PROVER_ERROR;

} catch (std::exception *e) {

if (error_msg) {
strncpy(error_msg, e->what(), error_msg_maxsize);
}
delete e;
return PPROVER_ERROR;
return PROVER_ERROR;

} catch (...) {
if (error_msg) {
strncpy(error_msg, "unknown error", error_msg_maxsize);
}
return PPROVER_ERROR;
return PROVER_ERROR;
}

return PRPOVER_OK;
return PROVER_OK;
}
20 changes: 13 additions & 7 deletions src/prover.h
Original file line number Diff line number Diff line change
Expand Up @@ -6,18 +6,24 @@ extern "C" {
#endif

//Error codes returned by the functions.
#define PRPOVER_OK 0x0
#define PPROVER_ERROR 0x1
#define PPROVER_ERROR_SHORT_BUFFER 0x2
#define PPROVER_INVALID_WITNESS_LENGTH 0x3
#define PROVER_OK 0x0
#define PROVER_ERROR 0x1
#define PROVER_ERROR_SHORT_BUFFER 0x2
#define PROVER_INVALID_WITNESS_LENGTH 0x3

/**
* Calculates buffer size to output public signals as json string
* @returns buffer size in bytes or 0 in case of an error
*/
unsigned long CalcPublicBufferSize(const void *zkey_buffer, unsigned long zkey_size);

/**
* groth16_prover
* @return error code:
* PRPOVER_OK - in case of success.
* PPROVER_ERROR - in case of an error.
* 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(const void *zkey_buffer, unsigned long zkey_size,
const void *wtns_buffer, unsigned long wtns_size,
Expand Down

0 comments on commit ea72e69

Please sign in to comment.