libsnark refactor
This commit is contained in:
parent
4b2dd517b7
commit
66438e8610
14 changed files with 606 additions and 241 deletions
|
@ -24,52 +24,60 @@ using namespace libsnark;
|
|||
namespace gm17 {
|
||||
|
||||
template <mp_size_t Q, typename ppT, typename G1, typename G2>
|
||||
std::string serializeVerificationKey(r1cs_se_ppzksnark_verification_key<ppT>* vk)
|
||||
buffer_t serialize_verification_key(r1cs_se_ppzksnark_verification_key<ppT>* vk)
|
||||
{
|
||||
std::stringstream ss;
|
||||
unsigned queryLength = vk->query.size();
|
||||
const size_t QUERY_COUNT = vk->query.size();
|
||||
|
||||
ss << "{";
|
||||
ss << "\"h\":" << outputPointG2AffineAsHexJson<Q, G2>(vk->H) << ",";
|
||||
ss << "\"g_alpha\":" << outputPointG1AffineAsHexJson<Q, G1>(vk->G_alpha) << ",";
|
||||
ss << "\"h_beta\":" << outputPointG2AffineAsHexJson<Q, G2>(vk->H_beta) << ",";
|
||||
ss << "\"g_gamma\":" << outputPointG1AffineAsHexJson<Q, G1>(vk->G_gamma) << ",";
|
||||
ss << "\"h_gamma\":" << outputPointG2AffineAsHexJson<Q, G2>(vk->H_gamma) << ",";
|
||||
ss << "\"query\":[";
|
||||
for (size_t i = 0; i < queryLength; ++i) {
|
||||
if (i != 0)
|
||||
ss << ",";
|
||||
ss << outputPointG1AffineAsHexJson<Q, G1>(vk->query[i]);
|
||||
}
|
||||
ss << "],";
|
||||
ss << "\"raw\":\"" << encodeToHexString<2>(serialize(*vk)) << "\"";
|
||||
ss << "}";
|
||||
std::string str = ss.str();
|
||||
return str;
|
||||
const size_t G1_SIZE = Q * sizeof(mp_limb_t) * 2; // [x, y]
|
||||
const size_t G2_SIZE = Q * sizeof(mp_limb_t) * 4; // [[x0, x1], [y0, y1]]
|
||||
|
||||
const size_t LENGTH =
|
||||
(G1_SIZE * 2) +
|
||||
(G2_SIZE * 3) +
|
||||
(QUERY_COUNT * G1_SIZE);
|
||||
|
||||
// [ ----------------- LENGTH ------------------ ]
|
||||
// [ h, G_alpha, H_beta, G_gamma, H_gamma, query ]
|
||||
|
||||
buffer_t buffer;
|
||||
buffer.data = (uint8_t*)malloc(LENGTH);
|
||||
buffer.length = LENGTH;
|
||||
|
||||
uint8_t* ptr = buffer.data;
|
||||
serialize_g2_affine<Q, G2>(vk->H, ptr);
|
||||
serialize_g1_affine<Q, G1>(vk->G_alpha, ptr);
|
||||
serialize_g2_affine<Q, G2>(vk->H_beta, ptr);
|
||||
serialize_g1_affine<Q, G1>(vk->G_gamma, ptr);
|
||||
serialize_g2_affine<Q, G2>(vk->H_gamma, ptr);
|
||||
|
||||
for (size_t i = 0; i < QUERY_COUNT; ++i)
|
||||
serialize_g1_affine<Q, G1>(vk->query[i], ptr);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, mp_size_t R, typename ppT, typename G1, typename G2>
|
||||
std::string serializeProof(r1cs_se_ppzksnark_proof<ppT>* proof, const uint8_t* public_inputs, int32_t public_inputs_length)
|
||||
template <mp_size_t Q, typename ppT, typename G1, typename G2>
|
||||
buffer_t serialize_proof(r1cs_se_ppzksnark_proof<ppT>* proof)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "{";
|
||||
ss << "\"proof\":{";
|
||||
ss << "\"a\":" << outputPointG1AffineAsHexJson<Q, G1>(proof->A) << ",";
|
||||
ss << "\"b\":" << outputPointG2AffineAsHexJson<Q, G2>(proof->B) << ",";
|
||||
ss << "\"c\":" << outputPointG1AffineAsHexJson<Q, G1>(proof->C);
|
||||
ss << "},";
|
||||
ss << "\"inputs\":[";
|
||||
for (int i = 1; i < public_inputs_length; i++) {
|
||||
if (i != 1) {
|
||||
ss << ",";
|
||||
}
|
||||
ss << outputInputAsHex<R>(libsnarkBigintFromBytes<R>(public_inputs + (i * R * sizeof(mp_limb_t))));
|
||||
}
|
||||
ss << "],";
|
||||
ss << "\"raw\":\"" << encodeToHexString<2>(serialize(*proof)) << "\"";
|
||||
ss << "}";
|
||||
std::string str = ss.str();
|
||||
return str;
|
||||
const size_t G1_SIZE = Q * sizeof(mp_limb_t) * 2; // [x, y]
|
||||
const size_t G2_SIZE = Q * sizeof(mp_limb_t) * 4; // [[x0, x1], [y0, y1]]
|
||||
|
||||
const size_t LENGTH = (G1_SIZE * 2) + G2_SIZE;
|
||||
|
||||
// [ ---------- LENGTH ---------- ]
|
||||
// [ G1_SIZE, G2_SIZE, G1_SIZE ]
|
||||
// [ a, b, c ]
|
||||
|
||||
buffer_t buffer;
|
||||
buffer.data = (uint8_t*)malloc(LENGTH);
|
||||
buffer.length = LENGTH;
|
||||
|
||||
uint8_t* ptr = buffer.data;
|
||||
serialize_g1_affine<Q, G1>(proof->A, ptr);
|
||||
serialize_g2_affine<Q, G2>(proof->B, ptr);
|
||||
serialize_g1_affine<Q, G1>(proof->C, ptr);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, mp_size_t R, typename ppT, typename G1, typename G2>
|
||||
|
@ -81,23 +89,22 @@ setup_result_t setup(const uint8_t* a, const uint8_t* b, const uint8_t* c, int32
|
|||
// initialize curve parameters
|
||||
ppT::init_public_params();
|
||||
|
||||
auto cs = createConstraintSystem<r1cs_se_ppzksnark_constraint_system, R, ppT>(a, b, c, a_len, b_len, c_len, constraints, variables, inputs);
|
||||
auto cs = create_constraint_system<r1cs_se_ppzksnark_constraint_system, R, ppT>(a, b, c, a_len, b_len, c_len, constraints, variables, inputs);
|
||||
assert(cs.num_variables() >= (unsigned)inputs);
|
||||
assert(cs.num_inputs() == (unsigned)inputs);
|
||||
assert(cs.num_constraints() == (unsigned)constraints);
|
||||
|
||||
r1cs_se_ppzksnark_keypair<ppT> keypair = r1cs_se_ppzksnark_generator<ppT>(cs);
|
||||
auto vk = serializeVerificationKey<Q, ppT, G1, G2>(&keypair.vk);
|
||||
|
||||
buffer_t vk_buf = createBuffer(vk);
|
||||
buffer_t pk_buf = createBuffer(keypair.pk);
|
||||
buffer_t vk_buf = serialize_verification_key<Q, ppT, G1, G2>(&keypair.vk);
|
||||
buffer_t pk_buf = create_buffer(keypair.pk);
|
||||
|
||||
setup_result_t result(vk_buf, pk_buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, mp_size_t R, typename ppT, typename G1, typename G2>
|
||||
proof_result_t generateProof(buffer_t* pk_buf, const uint8_t* public_inputs, int32_t public_inputs_length, const uint8_t* private_inputs, int32_t private_inputs_length)
|
||||
proof_result_t generate_proof(buffer_t* pk_buf, const uint8_t* public_inputs, int32_t public_inputs_length, const uint8_t* private_inputs, int32_t private_inputs_length)
|
||||
{
|
||||
libff::inhibit_profiling_info = true;
|
||||
libff::inhibit_profiling_counters = true;
|
||||
|
@ -106,14 +113,14 @@ proof_result_t generateProof(buffer_t* pk_buf, const uint8_t* public_inputs, int
|
|||
ppT::init_public_params();
|
||||
|
||||
r1cs_se_ppzksnark_proving_key<ppT> proving_key;
|
||||
fromBuffer<r1cs_se_ppzksnark_proving_key<ppT>>(pk_buf, proving_key);
|
||||
from_buffer<r1cs_se_ppzksnark_proving_key<ppT>>(pk_buf, proving_key);
|
||||
|
||||
r1cs_variable_assignment<libff::Fr<ppT>> full_variable_assignment;
|
||||
for (int i = 1; i < public_inputs_length; i++) {
|
||||
full_variable_assignment.push_back(libff::Fr<ppT>(libsnarkBigintFromBytes<R>(public_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
full_variable_assignment.push_back(libff::Fr<ppT>(to_libff_bigint<R>(public_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
}
|
||||
for (int i = 0; i < private_inputs_length; i++) {
|
||||
full_variable_assignment.push_back(libff::Fr<ppT>(libsnarkBigintFromBytes<R>(private_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
full_variable_assignment.push_back(libff::Fr<ppT>(to_libff_bigint<R>(private_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
}
|
||||
|
||||
r1cs_primary_input<libff::Fr<ppT>> primary_input(
|
||||
|
@ -125,14 +132,12 @@ proof_result_t generateProof(buffer_t* pk_buf, const uint8_t* public_inputs, int
|
|||
full_variable_assignment.end());
|
||||
|
||||
r1cs_se_ppzksnark_proof<ppT> proof = r1cs_se_ppzksnark_prover<ppT>(proving_key, primary_input, auxiliary_input);
|
||||
std::string json = serializeProof<Q, R, ppT, G1, G2>(&proof, public_inputs, public_inputs_length);
|
||||
|
||||
buffer_t proof_buf = createBuffer(json);
|
||||
buffer_t proof_buf = serialize_proof<Q, ppT, G1, G2>(&proof);
|
||||
proof_result_t result(proof_buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <mp_size_t R, typename ppT>
|
||||
template <mp_size_t Q, mp_size_t R, typename ppT, typename G1, typename G2>
|
||||
bool verify(buffer_t* vk_buf, buffer_t* proof_buf, const uint8_t* public_inputs, int32_t public_inputs_length)
|
||||
{
|
||||
libff::inhibit_profiling_info = true;
|
||||
|
@ -141,15 +146,36 @@ bool verify(buffer_t* vk_buf, buffer_t* proof_buf, const uint8_t* public_inputs,
|
|||
// initialize curve parameters
|
||||
ppT::init_public_params();
|
||||
|
||||
r1cs_se_ppzksnark_verification_key<ppT> vk;
|
||||
r1cs_se_ppzksnark_proof<ppT> proof;
|
||||
uint8_t *ptr = vk_buf->data;
|
||||
const G2 H = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
const G1 G_alpha = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G2 H_beta = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
const G1 G_gamma = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G2 H_gamma = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
|
||||
libff::G1_vector<ppT> query_G1_vector;
|
||||
|
||||
fromBuffer<r1cs_se_ppzksnark_verification_key<ppT>>(vk_buf, vk);
|
||||
fromBuffer<r1cs_se_ppzksnark_proof<ppT>>(proof_buf, proof);
|
||||
const size_t query_count = ((vk_buf->data + vk_buf->length) - ptr) / (Q * sizeof(mp_limb_t) * 2);
|
||||
for (size_t i = 0; i < query_count; i++)
|
||||
{
|
||||
auto query = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
query_G1_vector.push_back(query);
|
||||
}
|
||||
|
||||
const r1cs_se_ppzksnark_verification_key<ppT> vk(H, G_alpha, H_beta, G_gamma, H_gamma, std::move(query_G1_vector));
|
||||
|
||||
ptr = proof_buf->data;
|
||||
G1 a = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
G2 b = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
G1 c = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
r1cs_se_ppzksnark_proof<ppT> proof(
|
||||
std::move(a),
|
||||
std::move(b),
|
||||
std::move(c));
|
||||
|
||||
r1cs_primary_input<libff::Fr<ppT>> primary_input;
|
||||
for (int i = 0; i < public_inputs_length; i++) {
|
||||
primary_input.push_back(libff::Fr<ppT>(libsnarkBigintFromBytes<R>(public_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
primary_input.push_back(libff::Fr<ppT>(to_libff_bigint<R>(public_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
}
|
||||
|
||||
return r1cs_se_ppzksnark_verifier_strong_IC<ppT>(vk, primary_input, proof);
|
||||
|
@ -171,7 +197,7 @@ proof_result_t gm17_bn128_generate_proof(buffer_t* pk_buf,
|
|||
const uint8_t* private_inputs,
|
||||
int32_t private_inputs_length)
|
||||
{
|
||||
return gm17::generateProof<libff::alt_bn128_q_limbs,
|
||||
return gm17::generate_proof<libff::alt_bn128_q_limbs,
|
||||
libff::alt_bn128_r_limbs,
|
||||
libff::alt_bn128_pp,
|
||||
libff::alt_bn128_G1,
|
||||
|
@ -184,6 +210,9 @@ proof_result_t gm17_bn128_generate_proof(buffer_t* pk_buf,
|
|||
|
||||
bool gm17_bn128_verify(buffer_t* vk_buf, buffer_t* proof_buf, const uint8_t* public_inputs, int32_t public_inputs_length)
|
||||
{
|
||||
return gm17::verify<libff::alt_bn128_r_limbs,
|
||||
libff::alt_bn128_pp>(vk_buf, proof_buf, public_inputs, public_inputs_length);
|
||||
return gm17::verify<libff::alt_bn128_q_limbs,
|
||||
libff::alt_bn128_r_limbs,
|
||||
libff::alt_bn128_pp,
|
||||
libff::alt_bn128_G1,
|
||||
libff::alt_bn128_G2>(vk_buf, proof_buf, public_inputs, public_inputs_length);
|
||||
}
|
|
@ -15,6 +15,8 @@
|
|||
#include "libff/algebra/curves/alt_bn128/alt_bn128_pp.hpp"
|
||||
// contains required interfaces and types (keypair, proof, generator, prover, verifier)
|
||||
#include <libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp>
|
||||
#include <libsnark/common/data_structures/accumulation_vector.hpp>
|
||||
#include <libsnark/knowledge_commitment/knowledge_commitment.hpp>
|
||||
|
||||
using namespace libsnark;
|
||||
|
||||
|
@ -23,59 +25,67 @@ using namespace libsnark;
|
|||
namespace pghr13 {
|
||||
|
||||
template <mp_size_t Q, typename ppT, typename G1, typename G2>
|
||||
std::string serializeVerificationKey(r1cs_ppzksnark_verification_key<ppT>* vk)
|
||||
buffer_t serialize_verification_key(r1cs_ppzksnark_verification_key<ppT>* vk)
|
||||
{
|
||||
std::stringstream ss;
|
||||
unsigned icLength = vk->encoded_IC_query.rest.indices.size();
|
||||
const size_t QUERY_COUNT = vk->encoded_IC_query.rest.indices.size();
|
||||
|
||||
ss << "{";
|
||||
ss << "\"a\":" << outputPointG2AffineAsHexJson<Q, G2>(vk->alphaA_g2) << ",";
|
||||
ss << "\"b\":" << outputPointG1AffineAsHexJson<Q, G1>(vk->alphaB_g1) << ",";
|
||||
ss << "\"c\":" << outputPointG2AffineAsHexJson<Q, G2>(vk->alphaC_g2) << ",";
|
||||
ss << "\"gamma\":" << outputPointG2AffineAsHexJson<Q, G2>(vk->gamma_g2) << ",";
|
||||
ss << "\"gamma_beta_1\":" << outputPointG1AffineAsHexJson<Q, G1>(vk->gamma_beta_g1) << ",";
|
||||
ss << "\"gamma_beta_2\":" << outputPointG2AffineAsHexJson<Q, G2>(vk->gamma_beta_g2) << ",";
|
||||
ss << "\"z\":" << outputPointG2AffineAsHexJson<Q, G2>(vk->rC_Z_g2) << ",";
|
||||
ss << "\"ic\":[";
|
||||
ss << outputPointG1AffineAsHexJson<Q, G1>(vk->encoded_IC_query.first);
|
||||
for (size_t i = 0; i < icLength; ++i) {
|
||||
ss << ",";
|
||||
ss << outputPointG1AffineAsHexJson<Q, G1>(vk->encoded_IC_query.rest.values[i]);
|
||||
}
|
||||
ss << "],";
|
||||
ss << "\"raw\":\"" << encodeToHexString<2>(serialize(*vk)) << "\"";
|
||||
ss << "}";
|
||||
std::string str = ss.str();
|
||||
return str;
|
||||
const size_t G1_SIZE = Q * sizeof(mp_limb_t) * 2; // [x, y]
|
||||
const size_t G2_SIZE = Q * sizeof(mp_limb_t) * 4; // [[x0, x1], [y0, y1]]
|
||||
|
||||
const size_t LENGTH =
|
||||
(G1_SIZE * 3) +
|
||||
(G2_SIZE * 5) +
|
||||
(QUERY_COUNT * G1_SIZE);
|
||||
|
||||
// [ -------------------- LENGTH --------------------- ]
|
||||
// [ a, b, c, gamma, gamma_beta_1, gamma_beta_2, z, ic ]
|
||||
|
||||
buffer_t buffer;
|
||||
buffer.data = (uint8_t*)malloc(LENGTH);
|
||||
buffer.length = LENGTH;
|
||||
|
||||
uint8_t* ptr = buffer.data;
|
||||
serialize_g2_affine<Q, G2>(vk->alphaA_g2, ptr);
|
||||
serialize_g1_affine<Q, G1>(vk->alphaB_g1, ptr);
|
||||
serialize_g2_affine<Q, G2>(vk->alphaC_g2, ptr);
|
||||
serialize_g2_affine<Q, G2>(vk->gamma_g2, ptr);
|
||||
serialize_g1_affine<Q, G1>(vk->gamma_beta_g1, ptr);
|
||||
serialize_g2_affine<Q, G2>(vk->gamma_beta_g2, ptr);
|
||||
serialize_g2_affine<Q, G2>(vk->rC_Z_g2, ptr);
|
||||
serialize_g1_affine<Q, G1>(vk->encoded_IC_query.first, ptr);
|
||||
|
||||
for (size_t i = 0; i < QUERY_COUNT; ++i)
|
||||
serialize_g1_affine<Q, G1>(vk->encoded_IC_query.rest.values[i], ptr);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, mp_size_t R, typename ppT, typename G1, typename G2>
|
||||
std::string serializeProof(r1cs_ppzksnark_proof<ppT>* proof, const uint8_t* public_inputs, int public_inputs_length)
|
||||
template <mp_size_t Q, typename ppT, typename G1, typename G2>
|
||||
buffer_t serialize_proof(r1cs_ppzksnark_proof<ppT>* proof)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << "{";
|
||||
ss << "\"proof\":{";
|
||||
ss << "\"a\":" << outputPointG1AffineAsHexJson<Q, G1>(proof->g_A.g) << ",";
|
||||
ss << "\"a_p\":" << outputPointG1AffineAsHexJson<Q, G1>(proof->g_A.h) << ",";
|
||||
ss << "\"b\":" << outputPointG2AffineAsHexJson<Q, G2>(proof->g_B.g) << ",";
|
||||
ss << "\"b_p\":" << outputPointG1AffineAsHexJson<Q, G1>(proof->g_B.h) << ",";
|
||||
ss << "\"c\":" << outputPointG1AffineAsHexJson<Q, G1>(proof->g_C.g) << ",";
|
||||
ss << "\"c_p\":" << outputPointG1AffineAsHexJson<Q, G1>(proof->g_C.h) << ",";
|
||||
ss << "\"h\":" << outputPointG1AffineAsHexJson<Q, G1>(proof->g_H) << ",";
|
||||
ss << "\"k\":" << outputPointG1AffineAsHexJson<Q, G1>(proof->g_K);
|
||||
ss << "},";
|
||||
ss << "\"inputs\":[";
|
||||
for (int i = 1; i < public_inputs_length; i++) {
|
||||
if (i != 1) {
|
||||
ss << ",";
|
||||
}
|
||||
ss << outputInputAsHex<R>(libsnarkBigintFromBytes<R>(public_inputs + (i * R * sizeof(mp_limb_t))));
|
||||
}
|
||||
ss << "],";
|
||||
ss << "\"raw\":\"" << encodeToHexString<2>(serialize(*proof)) << "\"";
|
||||
ss << "}";
|
||||
std::string str = ss.str();
|
||||
return str;
|
||||
const size_t G1_SIZE = Q * sizeof(mp_limb_t) * 2; // [x, y]
|
||||
const size_t G2_SIZE = Q * sizeof(mp_limb_t) * 4; // [[x0, x1], [y0, y1]]
|
||||
|
||||
const size_t LENGTH = (G1_SIZE * 7) + G2_SIZE;
|
||||
|
||||
// [ ------------- LENGTH -------------- ]
|
||||
// [ a, a_p, b, b_p, c, c_p, h, k ]
|
||||
|
||||
buffer_t buffer;
|
||||
buffer.data = (uint8_t*)malloc(LENGTH);
|
||||
buffer.length = LENGTH;
|
||||
|
||||
uint8_t* ptr = buffer.data;
|
||||
serialize_g1_affine<Q, G1>(proof->g_A.g, ptr);
|
||||
serialize_g1_affine<Q, G1>(proof->g_A.h, ptr);
|
||||
serialize_g2_affine<Q, G2>(proof->g_B.g, ptr);
|
||||
serialize_g1_affine<Q, G1>(proof->g_B.h, ptr);
|
||||
serialize_g1_affine<Q, G1>(proof->g_C.g, ptr);
|
||||
serialize_g1_affine<Q, G1>(proof->g_C.h, ptr);
|
||||
serialize_g1_affine<Q, G1>(proof->g_H, ptr);
|
||||
serialize_g1_affine<Q, G1>(proof->g_K, ptr);
|
||||
|
||||
return buffer;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, mp_size_t R, typename ppT, typename G1, typename G2>
|
||||
|
@ -87,23 +97,22 @@ setup_result_t setup(const uint8_t* a, const uint8_t* b, const uint8_t* c, int32
|
|||
// initialize curve parameters
|
||||
ppT::init_public_params();
|
||||
|
||||
auto cs = createConstraintSystem<r1cs_ppzksnark_constraint_system, R, ppT>(a, b, c, a_len, b_len, c_len, constraints, variables, inputs);
|
||||
auto cs = create_constraint_system<r1cs_ppzksnark_constraint_system, R, ppT>(a, b, c, a_len, b_len, c_len, constraints, variables, inputs);
|
||||
assert(cs.num_variables() >= (unsigned)inputs);
|
||||
assert(cs.num_inputs() == (unsigned)inputs);
|
||||
assert(cs.num_constraints() == (unsigned)constraints);
|
||||
|
||||
r1cs_ppzksnark_keypair<ppT> keypair = r1cs_ppzksnark_generator<ppT>(cs);
|
||||
auto vk = serializeVerificationKey<Q, ppT, G1, G2>(&keypair.vk);
|
||||
|
||||
buffer_t vk_buf = createBuffer(vk);
|
||||
buffer_t pk_buf = createBuffer(keypair.pk);
|
||||
buffer_t vk_buf = serialize_verification_key<Q, ppT, G1, G2>(&keypair.vk);
|
||||
buffer_t pk_buf = create_buffer(keypair.pk);
|
||||
|
||||
setup_result_t result(vk_buf, pk_buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, mp_size_t R, typename ppT, typename G1, typename G2>
|
||||
proof_result_t generateProof(buffer_t* pk_buf, const uint8_t* public_inputs, int32_t public_inputs_length, const uint8_t* private_inputs, int32_t private_inputs_length)
|
||||
proof_result_t generate_proof(buffer_t* pk_buf, const uint8_t* public_inputs, int32_t public_inputs_length, const uint8_t* private_inputs, int32_t private_inputs_length)
|
||||
{
|
||||
libff::inhibit_profiling_info = true;
|
||||
libff::inhibit_profiling_counters = true;
|
||||
|
@ -112,15 +121,15 @@ proof_result_t generateProof(buffer_t* pk_buf, const uint8_t* public_inputs, int
|
|||
ppT::init_public_params();
|
||||
|
||||
r1cs_ppzksnark_proving_key<ppT> proving_key;
|
||||
fromBuffer<r1cs_ppzksnark_proving_key<ppT>>(pk_buf, proving_key);
|
||||
from_buffer<r1cs_ppzksnark_proving_key<ppT>>(pk_buf, proving_key);
|
||||
|
||||
// assign variables based on witness values, excludes ~one
|
||||
r1cs_variable_assignment<libff::Fr<ppT>> full_variable_assignment;
|
||||
for (int i = 1; i < public_inputs_length; i++) {
|
||||
full_variable_assignment.push_back(libff::Fr<ppT>(libsnarkBigintFromBytes<R>(public_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
full_variable_assignment.push_back(libff::Fr<ppT>(to_libff_bigint<R>(public_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
}
|
||||
for (int i = 0; i < private_inputs_length; i++) {
|
||||
full_variable_assignment.push_back(libff::Fr<ppT>(libsnarkBigintFromBytes<R>(private_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
full_variable_assignment.push_back(libff::Fr<ppT>(to_libff_bigint<R>(private_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
}
|
||||
|
||||
r1cs_primary_input<libff::Fr<ppT>> primary_input(
|
||||
|
@ -132,14 +141,12 @@ proof_result_t generateProof(buffer_t* pk_buf, const uint8_t* public_inputs, int
|
|||
full_variable_assignment.end());
|
||||
|
||||
r1cs_ppzksnark_proof<ppT> proof = r1cs_ppzksnark_prover<ppT>(proving_key, primary_input, auxiliary_input);
|
||||
std::string json = serializeProof<Q, R, ppT, G1, G2>(&proof, public_inputs, public_inputs_length);
|
||||
|
||||
buffer_t proof_buf = createBuffer(json);
|
||||
buffer_t proof_buf = serialize_proof<Q, ppT, G1, G2>(&proof);
|
||||
proof_result_t result(proof_buf);
|
||||
return result;
|
||||
}
|
||||
|
||||
template <mp_size_t R, typename ppT>
|
||||
template <mp_size_t Q, mp_size_t R, typename ppT, typename G1, typename G2>
|
||||
bool verify(buffer_t* vk_buf, buffer_t* proof_buf, const uint8_t* public_inputs, int32_t public_inputs_length)
|
||||
{
|
||||
libff::inhibit_profiling_info = true;
|
||||
|
@ -148,15 +155,53 @@ bool verify(buffer_t* vk_buf, buffer_t* proof_buf, const uint8_t* public_inputs,
|
|||
// initialize curve parameters
|
||||
ppT::init_public_params();
|
||||
|
||||
r1cs_ppzksnark_verification_key<ppT> vk;
|
||||
r1cs_ppzksnark_proof<ppT> proof;
|
||||
uint8_t *ptr = vk_buf->data;
|
||||
const G2 alphaA_g2 = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
const G1 alphaB_g1 = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G2 alphaC_g2 = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
const G2 gamma_g2 = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
const G1 gamma_beta_g1 = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G2 gamma_beta_g2 = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
const G2 rC_Z_g2 = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
G1 ic_first = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
|
||||
fromBuffer<r1cs_ppzksnark_verification_key<ppT>>(vk_buf, vk);
|
||||
fromBuffer<r1cs_ppzksnark_proof<ppT>>(proof_buf, proof);
|
||||
std::vector<G1> ic_rest;
|
||||
const size_t ic_rest_count = ((vk_buf->data + vk_buf->length) - ptr) / (Q * sizeof(mp_limb_t) * 2);
|
||||
for (size_t i = 0; i < ic_rest_count; i++)
|
||||
{
|
||||
auto ic_query = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
ic_rest.push_back(ic_query);
|
||||
}
|
||||
|
||||
accumulation_vector<G1> eIC(std::move(ic_first), std::move(ic_rest));
|
||||
const r1cs_ppzksnark_verification_key<ppT> vk(alphaA_g2, alphaB_g1, alphaC_g2, gamma_g2, gamma_beta_g1, gamma_beta_g2, rC_Z_g2, eIC);
|
||||
|
||||
ptr = proof_buf->data;
|
||||
const G1 g_A_g = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G1 g_A_h = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G2 g_B_g = deserialize_g2_affine<Q, typename ppT::Fqe_type, G2>(ptr);
|
||||
const G1 g_B_h = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G1 g_C_g = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
const G1 g_C_h = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
|
||||
knowledge_commitment<G1, G1> g_A(g_A_g, g_A_h);
|
||||
knowledge_commitment<G2, G1> g_B(g_B_g, g_B_h);
|
||||
knowledge_commitment<G1, G1> g_C(g_C_g, g_C_h);
|
||||
|
||||
G1 g_H = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
G1 g_K = deserialize_g1_affine<Q, typename ppT::Fq_type, G1>(ptr);
|
||||
|
||||
const r1cs_ppzksnark_proof<ppT> proof(
|
||||
std::move(g_A),
|
||||
std::move(g_B),
|
||||
std::move(g_C),
|
||||
std::move(g_H),
|
||||
std::move(g_K)
|
||||
);
|
||||
|
||||
r1cs_primary_input<libff::Fr<ppT>> primary_input;
|
||||
for (int i = 0; i < public_inputs_length; i++) {
|
||||
primary_input.push_back(libff::Fr<ppT>(libsnarkBigintFromBytes<R>(public_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
primary_input.push_back(libff::Fr<ppT>(to_libff_bigint<R>(public_inputs + (i * R * sizeof(mp_limb_t)))));
|
||||
}
|
||||
return r1cs_ppzksnark_verifier_strong_IC<ppT>(vk, primary_input, proof);
|
||||
}
|
||||
|
@ -177,7 +222,7 @@ proof_result_t pghr13_bn128_generate_proof(buffer_t* pk_buf,
|
|||
const uint8_t* private_inputs,
|
||||
int32_t private_inputs_length)
|
||||
{
|
||||
return pghr13::generateProof<libff::alt_bn128_q_limbs,
|
||||
return pghr13::generate_proof<libff::alt_bn128_q_limbs,
|
||||
libff::alt_bn128_r_limbs,
|
||||
libff::alt_bn128_pp,
|
||||
libff::alt_bn128_G1,
|
||||
|
@ -190,6 +235,9 @@ proof_result_t pghr13_bn128_generate_proof(buffer_t* pk_buf,
|
|||
|
||||
bool pghr13_bn128_verify(buffer_t* vk_buf, buffer_t* proof_buf, const uint8_t* public_inputs, int32_t public_inputs_length)
|
||||
{
|
||||
return pghr13::verify<libff::alt_bn128_r_limbs,
|
||||
libff::alt_bn128_pp>(vk_buf, proof_buf, public_inputs, public_inputs_length);
|
||||
return pghr13::verify<libff::alt_bn128_q_limbs,
|
||||
libff::alt_bn128_r_limbs,
|
||||
libff::alt_bn128_pp,
|
||||
libff::alt_bn128_G1,
|
||||
libff::alt_bn128_G2>(vk_buf, proof_buf, public_inputs, public_inputs_length);
|
||||
}
|
|
@ -8,67 +8,92 @@
|
|||
#include <sstream>
|
||||
#include <string>
|
||||
|
||||
template <int W>
|
||||
std::string encodeToHexString(const std::string& in)
|
||||
{
|
||||
std::ostringstream out;
|
||||
out << std::setfill('0');
|
||||
for (unsigned char const& c : in) {
|
||||
out << std::hex << std::setw(W) << static_cast<unsigned int>(c);
|
||||
}
|
||||
return out.str();
|
||||
}
|
||||
|
||||
// conversion byte[N] <-> libsnark bigint.
|
||||
// conversion byte[N] -> libsnark bigint
|
||||
template <mp_size_t N>
|
||||
libff::bigint<N> libsnarkBigintFromBytes(const uint8_t* _x)
|
||||
libff::bigint<N> to_libff_bigint(const uint8_t* input)
|
||||
{
|
||||
libff::bigint<N> x;
|
||||
for (unsigned i = 0; i < N; i++) {
|
||||
for (unsigned j = 0; j < 8; j++) {
|
||||
x.data[N - 1 - i] |= uint64_t(_x[i * 8 + j]) << (8 * (7 - j));
|
||||
x.data[N - 1 - i] |= uint64_t(input[i * 8 + j]) << (8 * (7 - j));
|
||||
}
|
||||
}
|
||||
return x;
|
||||
}
|
||||
|
||||
// conversion libsnark bigint -> byte[N]
|
||||
template <mp_size_t N>
|
||||
std::string hexStringFromLibsnarkBigint(libff::bigint<N> _x)
|
||||
void from_libff_bigint(libff::bigint<N> x, uint8_t* out)
|
||||
{
|
||||
uint8_t x[N * sizeof(mp_limb_t)];
|
||||
for (unsigned i = 0; i < N; i++) {
|
||||
for (unsigned j = 0; j < 8; j++) {
|
||||
x[i * 8 + j] = uint8_t(uint64_t(_x.data[N - 1 - i]) >> (8 * (7 - j)));
|
||||
out[i * 8 + j] = uint8_t(uint64_t(x.data[N - 1 - i]) >> (8 * (7 - j)));
|
||||
}
|
||||
}
|
||||
std::string tmp((char*)x, N * sizeof(mp_limb_t));
|
||||
return encodeToHexString<2>(tmp);
|
||||
}
|
||||
|
||||
template <mp_size_t Q>
|
||||
std::string outputInputAsHex(libff::bigint<Q> _x)
|
||||
{
|
||||
return "\"0x" + hexStringFromLibsnarkBigint<Q>(_x) + "\"";
|
||||
}
|
||||
|
||||
template <mp_size_t Q, typename G1>
|
||||
std::string outputPointG1AffineAsHexJson(G1 _p)
|
||||
void serialize_g1_affine(G1 point, uint8_t*& buffer)
|
||||
{
|
||||
G1 aff = _p;
|
||||
const size_t ELEMENT_SIZE = Q * sizeof(mp_limb_t);
|
||||
|
||||
G1 aff = point;
|
||||
aff.to_affine_coordinates();
|
||||
return "[\"0x" + hexStringFromLibsnarkBigint<Q>(aff.X.as_bigint()) + "\",\"0x" + hexStringFromLibsnarkBigint<Q>(aff.Y.as_bigint()) + "\"]";
|
||||
|
||||
auto x = aff.X.as_bigint();
|
||||
auto y = aff.Y.as_bigint();
|
||||
|
||||
from_libff_bigint<Q>(x, buffer); buffer += ELEMENT_SIZE;
|
||||
from_libff_bigint<Q>(y, buffer); buffer += ELEMENT_SIZE;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, typename G2>
|
||||
std::string outputPointG2AffineAsHexJson(G2 _p)
|
||||
void serialize_g2_affine(G2 point, uint8_t*& buffer)
|
||||
{
|
||||
G2 aff = _p;
|
||||
const size_t ELEMENT_SIZE = Q * sizeof(mp_limb_t);
|
||||
|
||||
G2 aff = point;
|
||||
aff.to_affine_coordinates();
|
||||
return "[[\"0x" + hexStringFromLibsnarkBigint<Q>(aff.X.c1.as_bigint()) + "\",\"0x" + hexStringFromLibsnarkBigint<Q>(aff.X.c0.as_bigint()) + "\"], [\"0x" + hexStringFromLibsnarkBigint<Q>(aff.Y.c1.as_bigint()) + "\", \"0x" + hexStringFromLibsnarkBigint<Q>(aff.Y.c0.as_bigint()) + "\"]]";
|
||||
|
||||
auto x0 = aff.X.c0.as_bigint();
|
||||
auto x1 = aff.X.c1.as_bigint();
|
||||
auto y0 = aff.Y.c0.as_bigint();
|
||||
auto y1 = aff.Y.c1.as_bigint();
|
||||
|
||||
from_libff_bigint<Q>(x0, buffer); buffer += ELEMENT_SIZE;
|
||||
from_libff_bigint<Q>(x1, buffer); buffer += ELEMENT_SIZE;
|
||||
from_libff_bigint<Q>(y0, buffer); buffer += ELEMENT_SIZE;
|
||||
from_libff_bigint<Q>(y1, buffer); buffer += ELEMENT_SIZE;
|
||||
}
|
||||
|
||||
template <mp_size_t Q, typename Fq, typename G1>
|
||||
G1 deserialize_g1_affine(uint8_t*& buffer)
|
||||
{
|
||||
const size_t ELEMENT_SIZE = Q * sizeof(mp_limb_t);
|
||||
|
||||
auto x = to_libff_bigint<Q>(buffer); buffer += ELEMENT_SIZE;
|
||||
auto y = to_libff_bigint<Q>(buffer); buffer += ELEMENT_SIZE;
|
||||
|
||||
return G1(Fq(x), Fq(y), Fq::one());
|
||||
}
|
||||
|
||||
template <mp_size_t Q, typename Fq2, typename G2>
|
||||
G2 deserialize_g2_affine(uint8_t*& buffer)
|
||||
{
|
||||
const size_t ELEMENT_SIZE = Q * sizeof(mp_limb_t);
|
||||
|
||||
auto x0 = to_libff_bigint<Q>(buffer); buffer += ELEMENT_SIZE;
|
||||
auto x1 = to_libff_bigint<Q>(buffer); buffer += ELEMENT_SIZE;
|
||||
auto y0 = to_libff_bigint<Q>(buffer); buffer += ELEMENT_SIZE;
|
||||
auto y1 = to_libff_bigint<Q>(buffer); buffer += ELEMENT_SIZE;
|
||||
|
||||
auto x = Fq2(x0, x1);
|
||||
auto y = Fq2(y0, y1);
|
||||
return G2(x, y, Fq2::one());
|
||||
}
|
||||
|
||||
template <template <typename ppT> class ConstraintSystem, mp_size_t R, typename ppT>
|
||||
ConstraintSystem<ppT> createConstraintSystem(const uint8_t* a,
|
||||
ConstraintSystem<ppT> create_constraint_system(const uint8_t* a,
|
||||
const uint8_t* b,
|
||||
const uint8_t* c,
|
||||
int32_t a_len,
|
||||
|
@ -82,19 +107,19 @@ ConstraintSystem<ppT> createConstraintSystem(const uint8_t* a,
|
|||
cs.primary_input_size = inputs;
|
||||
cs.auxiliary_input_size = variables - inputs - 1; // ~one not included
|
||||
|
||||
std::cout << "num variables: " << variables << std::endl;
|
||||
std::cout << "num constraints: " << constraints << std::endl;
|
||||
std::cout << "num inputs: " << inputs << std::endl;
|
||||
// std::cout << "num variables: " << variables << std::endl;
|
||||
// std::cout << "num constraints: " << constraints << std::endl;
|
||||
// std::cout << "num inputs: " << inputs << std::endl;
|
||||
|
||||
struct VariableValueMapping {
|
||||
struct vvmap_t {
|
||||
int constraint_id;
|
||||
int variable_id;
|
||||
uint8_t variable_value[R * sizeof(mp_limb_t)];
|
||||
};
|
||||
|
||||
const VariableValueMapping* a_vvmap = (VariableValueMapping*)a;
|
||||
const VariableValueMapping* b_vvmap = (VariableValueMapping*)b;
|
||||
const VariableValueMapping* c_vvmap = (VariableValueMapping*)c;
|
||||
const vvmap_t* a_vvmap = (vvmap_t*)a;
|
||||
const vvmap_t* b_vvmap = (vvmap_t*)b;
|
||||
const vvmap_t* c_vvmap = (vvmap_t*)c;
|
||||
|
||||
int a_id = 0;
|
||||
int b_id = 0;
|
||||
|
@ -103,21 +128,21 @@ ConstraintSystem<ppT> createConstraintSystem(const uint8_t* a,
|
|||
for (int row = 0; row < constraints; row++) {
|
||||
linear_combination<libff::Fr<ppT>> lin_comb_a, lin_comb_b, lin_comb_c;
|
||||
while (a_id < a_len && a_vvmap[a_id].constraint_id == row) {
|
||||
libff::bigint<R> value = libsnarkBigintFromBytes<R>(a_vvmap[a_id].variable_value);
|
||||
libff::bigint<R> value = to_libff_bigint<R>(a_vvmap[a_id].variable_value);
|
||||
if (!value.is_zero()) {
|
||||
lin_comb_a.add_term(a_vvmap[a_id].variable_id, value);
|
||||
}
|
||||
a_id++;
|
||||
}
|
||||
while (b_id < b_len && b_vvmap[b_id].constraint_id == row) {
|
||||
libff::bigint<R> value = libsnarkBigintFromBytes<R>(b_vvmap[b_id].variable_value);
|
||||
libff::bigint<R> value = to_libff_bigint<R>(b_vvmap[b_id].variable_value);
|
||||
if (!value.is_zero()) {
|
||||
lin_comb_b.add_term(b_vvmap[b_id].variable_id, value);
|
||||
}
|
||||
b_id++;
|
||||
}
|
||||
while (c_id < c_len && c_vvmap[c_id].constraint_id == row) {
|
||||
libff::bigint<R> value = libsnarkBigintFromBytes<R>(c_vvmap[c_id].variable_value);
|
||||
libff::bigint<R> value = to_libff_bigint<R>(c_vvmap[c_id].variable_value);
|
||||
if (!value.is_zero()) {
|
||||
lin_comb_c.add_term(c_vvmap[c_id].variable_id, value);
|
||||
}
|
||||
|
@ -129,7 +154,7 @@ ConstraintSystem<ppT> createConstraintSystem(const uint8_t* a,
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
inline void fromBuffer(buffer_t* buffer, T& t)
|
||||
inline void from_buffer(buffer_t* buffer, T& t)
|
||||
{
|
||||
std::string tmp((char*)buffer->data, buffer->length);
|
||||
std::stringstream ss(tmp);
|
||||
|
@ -137,17 +162,12 @@ inline void fromBuffer(buffer_t* buffer, T& t)
|
|||
}
|
||||
|
||||
template <typename T>
|
||||
inline std::string serialize(const T& t)
|
||||
inline buffer_t create_buffer(T& t)
|
||||
{
|
||||
std::stringstream ss;
|
||||
ss << t;
|
||||
return ss.str();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
inline buffer_t createBuffer(T& t)
|
||||
{
|
||||
std::string tmp = serialize(t);
|
||||
std::string tmp = ss.str();
|
||||
size_t length = tmp.length();
|
||||
|
||||
buffer_t buffer;
|
||||
|
|
|
@ -64,7 +64,7 @@ impl<T: Field + BellmanFieldExtensions> Backend<T, G16> for Bellman {
|
|||
.map(parse_fr::<T>)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Proof::new(proof_points, inputs, None)
|
||||
Proof::new(proof_points, inputs)
|
||||
}
|
||||
|
||||
fn verify(
|
||||
|
@ -123,9 +123,8 @@ mod serialization {
|
|||
pub fn to_g2<T: BellmanFieldExtensions>(
|
||||
g2: G2Affine,
|
||||
) -> <T::BellmanEngine as Engine>::G2Affine {
|
||||
// apparently the order is reversed
|
||||
let x = T::new_fq2(&(g2.0).1, &(g2.0).0);
|
||||
let y = T::new_fq2(&(g2.1).1, &(g2.1).0);
|
||||
let x = T::new_fq2(&(g2.0).0, &(g2.0).1);
|
||||
let y = T::new_fq2(&(g2.1).0, &(g2.1).1);
|
||||
<T::BellmanEngine as Engine>::G2Affine::from_xy_unchecked(x, y)
|
||||
}
|
||||
}
|
||||
|
|
|
@ -249,12 +249,12 @@ mod parse {
|
|||
let captures = G2_REGEX.captures(&raw_e).unwrap();
|
||||
G2Affine(
|
||||
(
|
||||
captures.name(&"x1").unwrap().as_str().to_string(),
|
||||
captures.name(&"x0").unwrap().as_str().to_string(),
|
||||
captures.name(&"x1").unwrap().as_str().to_string(),
|
||||
),
|
||||
(
|
||||
captures.name(&"y1").unwrap().as_str().to_string(),
|
||||
captures.name(&"y0").unwrap().as_str().to_string(),
|
||||
captures.name(&"y1").unwrap().as_str().to_string(),
|
||||
),
|
||||
)
|
||||
}
|
||||
|
|
|
@ -1,13 +1,13 @@
|
|||
use ir::{Prog, Witness};
|
||||
use proof_system::libsnark::ffi::{Buffer, ProofResult, SetupResult};
|
||||
use proof_system::libsnark::{
|
||||
prepare_generate_proof, prepare_public_inputs, prepare_setup, Libsnark,
|
||||
prepare_generate_proof, prepare_public_inputs, prepare_setup, serialization::*, Libsnark,
|
||||
};
|
||||
use proof_system::scheme::gm17::GM17;
|
||||
use proof_system::scheme::gm17::{ProofPoints, VerificationKey, GM17};
|
||||
use proof_system::scheme::Scheme;
|
||||
use proof_system::{Backend, Proof, SetupKeypair};
|
||||
use zokrates_field::Bn128Field;
|
||||
use zokrates_field::Field;
|
||||
use proof_system::{Backend, G1Affine, G2Affine, Proof, SetupKeypair};
|
||||
use std::io::{BufReader, BufWriter, Write};
|
||||
use zokrates_field::{Bn128Field, Field};
|
||||
|
||||
extern "C" {
|
||||
fn gm17_bn128_setup(
|
||||
|
@ -70,7 +70,29 @@ impl Backend<Bn128Field, GM17> for Libsnark {
|
|||
(vk, pk)
|
||||
};
|
||||
|
||||
let vk = serde_json::from_str(String::from_utf8(vk).unwrap().as_str()).unwrap();
|
||||
let vk_slice = vk.as_slice();
|
||||
let mut reader = BufReader::new(vk_slice);
|
||||
|
||||
let h = read_g2(&mut reader).unwrap();
|
||||
let g_alpha = read_g1(&mut reader).unwrap();
|
||||
let h_beta = read_g2(&mut reader).unwrap();
|
||||
let g_gamma = read_g1(&mut reader).unwrap();
|
||||
let h_gamma = read_g2(&mut reader).unwrap();
|
||||
|
||||
let mut query = vec![];
|
||||
while let Ok(q) = read_g1(&mut reader) {
|
||||
query.push(q);
|
||||
}
|
||||
|
||||
let vk = VerificationKey::<G1Affine, G2Affine> {
|
||||
h,
|
||||
g_alpha,
|
||||
h_beta,
|
||||
g_gamma,
|
||||
h_gamma,
|
||||
query,
|
||||
};
|
||||
|
||||
SetupKeypair::new(vk, pk)
|
||||
}
|
||||
|
||||
|
@ -80,7 +102,7 @@ impl Backend<Bn128Field, GM17> for Libsnark {
|
|||
proving_key: Vec<u8>,
|
||||
) -> Proof<<GM17 as Scheme<Bn128Field>>::ProofPoints> {
|
||||
let (public_inputs_arr, public_inputs_length, private_inputs_arr, private_inputs_length) =
|
||||
prepare_generate_proof(program, witness);
|
||||
prepare_generate_proof(program.clone(), witness.clone());
|
||||
|
||||
let proof = unsafe {
|
||||
let mut pk_buffer = Buffer::from_vec(&proving_key);
|
||||
|
@ -105,15 +127,51 @@ impl Backend<Bn128Field, GM17> for Libsnark {
|
|||
proof
|
||||
};
|
||||
|
||||
serde_json::from_str(String::from_utf8(proof).unwrap().as_str()).unwrap()
|
||||
let mut reader = BufReader::new(proof.as_slice());
|
||||
let a = read_g1(&mut reader).unwrap();
|
||||
let b = read_g2(&mut reader).unwrap();
|
||||
let c = read_g1(&mut reader).unwrap();
|
||||
|
||||
let points = ProofPoints::<G1Affine, G2Affine> { a, b, c };
|
||||
let public_inputs: Vec<String> = program
|
||||
.main
|
||||
.arguments
|
||||
.clone()
|
||||
.iter()
|
||||
.zip(program.private.clone())
|
||||
.filter(|(_, p)| !*p)
|
||||
.map(|(v, _)| witness.clone().0.get(v).unwrap().clone())
|
||||
.chain(witness.clone().return_values())
|
||||
.map(|v| format!("0x{:064x}", v.to_biguint()))
|
||||
.collect();
|
||||
|
||||
Proof::new(points, public_inputs)
|
||||
}
|
||||
|
||||
fn verify(
|
||||
vk: <GM17 as Scheme<Bn128Field>>::VerificationKey,
|
||||
proof: Proof<<GM17 as Scheme<Bn128Field>>::ProofPoints>,
|
||||
) -> bool {
|
||||
let vk_raw = hex::decode(vk.raw.unwrap().clone()).unwrap();
|
||||
let proof_raw = hex::decode(proof.raw.unwrap().clone()).unwrap();
|
||||
let vk_buffer = vec![];
|
||||
let mut vk_writer = BufWriter::new(vk_buffer);
|
||||
|
||||
write_g2(&mut vk_writer, &vk.h);
|
||||
write_g1(&mut vk_writer, &vk.g_alpha);
|
||||
write_g2(&mut vk_writer, &vk.h_beta);
|
||||
write_g1(&mut vk_writer, &vk.g_gamma);
|
||||
write_g2(&mut vk_writer, &vk.h_gamma);
|
||||
|
||||
vk.query.iter().for_each(|q| write_g1(&mut vk_writer, q));
|
||||
|
||||
vk_writer.flush().unwrap();
|
||||
|
||||
let proof_buffer = vec![];
|
||||
let mut proof_writer = BufWriter::new(proof_buffer);
|
||||
|
||||
write_g1(&mut proof_writer, &proof.proof.a);
|
||||
write_g2(&mut proof_writer, &proof.proof.b);
|
||||
write_g1(&mut proof_writer, &proof.proof.c);
|
||||
proof_writer.flush().unwrap();
|
||||
|
||||
let public_inputs: Vec<_> = proof
|
||||
.inputs
|
||||
|
@ -124,8 +182,8 @@ impl Backend<Bn128Field, GM17> for Libsnark {
|
|||
let (public_inputs_arr, public_inputs_length) = prepare_public_inputs(public_inputs);
|
||||
|
||||
unsafe {
|
||||
let mut vk_buffer = Buffer::from_vec(&vk_raw);
|
||||
let mut proof_buffer = Buffer::from_vec(&proof_raw);
|
||||
let mut vk_buffer = Buffer::from_vec(vk_writer.get_ref());
|
||||
let mut proof_buffer = Buffer::from_vec(proof_writer.get_ref());
|
||||
|
||||
let ans = gm17_bn128_verify(
|
||||
&mut vk_buffer as *mut _,
|
||||
|
@ -141,3 +199,41 @@ impl Backend<Bn128Field, GM17> for Libsnark {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "libsnark")]
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::flat_absy::FlatVariable;
|
||||
use crate::ir::{Function, Interpreter, Prog, Statement};
|
||||
use zokrates_field::Bn128Field;
|
||||
|
||||
#[test]
|
||||
fn verify() {
|
||||
let program: Prog<Bn128Field> = Prog {
|
||||
main: Function {
|
||||
id: String::from("main"),
|
||||
arguments: vec![FlatVariable::new(0)],
|
||||
returns: vec![FlatVariable::public(0)],
|
||||
statements: vec![Statement::Constraint(
|
||||
FlatVariable::new(0).into(),
|
||||
FlatVariable::public(0).into(),
|
||||
)],
|
||||
},
|
||||
private: vec![true],
|
||||
};
|
||||
|
||||
let keypair = <Libsnark as Backend<Bn128Field, GM17>>::setup(program.clone());
|
||||
let interpreter = Interpreter::default();
|
||||
|
||||
let witness = interpreter
|
||||
.execute(&program, &vec![Bn128Field::from(42)])
|
||||
.unwrap();
|
||||
|
||||
let proof =
|
||||
<Libsnark as Backend<Bn128Field, GM17>>::generate_proof(program, witness, keypair.pk);
|
||||
|
||||
let ans = <Libsnark as Backend<Bn128Field, GM17>>::verify(keypair.vk, proof);
|
||||
assert!(ans);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -303,3 +303,57 @@ pub fn r1cs_program<T: Field>(
|
|||
}
|
||||
(variables_list, private_inputs_offset, a, b, c)
|
||||
}
|
||||
|
||||
pub mod serialization {
|
||||
use proof_system::{G1Affine, G2Affine};
|
||||
use std::io::Read;
|
||||
use std::io::Write;
|
||||
|
||||
#[inline]
|
||||
fn decode_hex(value: &String) -> Vec<u8> {
|
||||
hex::decode(value.strip_prefix("0x").unwrap()).unwrap()
|
||||
}
|
||||
|
||||
#[inline]
|
||||
fn encode_hex<T: AsRef<[u8]>>(data: T) -> String {
|
||||
format!("0x{}", hex::encode(data))
|
||||
}
|
||||
|
||||
pub fn read_g1<R: Read>(reader: &mut R) -> Result<G1Affine, ()> {
|
||||
let mut buffer = [0; 64];
|
||||
reader.read_exact(&mut buffer).map_err(|_| ())?;
|
||||
|
||||
Ok(G1Affine(
|
||||
encode_hex(&buffer[0..32].to_vec()),
|
||||
encode_hex(&buffer[32..64].to_vec()),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn read_g2<R: Read>(reader: &mut R) -> Result<G2Affine, ()> {
|
||||
let mut buffer = [0; 128];
|
||||
reader.read_exact(&mut buffer).map_err(|_| ())?;
|
||||
|
||||
Ok(G2Affine(
|
||||
(
|
||||
encode_hex(&buffer[0..32].to_vec()),
|
||||
encode_hex(&buffer[32..64].to_vec()),
|
||||
),
|
||||
(
|
||||
encode_hex(&buffer[64..96].to_vec()),
|
||||
encode_hex(&buffer[96..128].to_vec()),
|
||||
),
|
||||
))
|
||||
}
|
||||
|
||||
pub fn write_g1<W: Write>(writer: &mut W, g1: &G1Affine) {
|
||||
writer.write(decode_hex(&g1.0).as_ref()).unwrap();
|
||||
writer.write(decode_hex(&g1.1).as_ref()).unwrap();
|
||||
}
|
||||
|
||||
pub fn write_g2<W: Write>(writer: &mut W, g2: &G2Affine) {
|
||||
writer.write(decode_hex(&(g2.0).0).as_ref()).unwrap();
|
||||
writer.write(decode_hex(&(g2.0).1).as_ref()).unwrap();
|
||||
writer.write(decode_hex(&(g2.1).0).as_ref()).unwrap();
|
||||
writer.write(decode_hex(&(g2.1).1).as_ref()).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,11 +2,13 @@ use proof_system::libsnark::ffi::{Buffer, ProofResult, SetupResult};
|
|||
use proof_system::libsnark::{
|
||||
prepare_generate_proof, prepare_public_inputs, prepare_setup, Libsnark,
|
||||
};
|
||||
use proof_system::{Backend, Proof, SetupKeypair};
|
||||
use proof_system::{Backend, G1Affine, G2Affine, Proof, SetupKeypair};
|
||||
|
||||
use ir::{Prog, Witness};
|
||||
use proof_system::scheme::pghr13::PGHR13;
|
||||
use proof_system::libsnark::serialization::{read_g1, read_g2, write_g1, write_g2};
|
||||
use proof_system::scheme::pghr13::{ProofPoints, VerificationKey, PGHR13};
|
||||
use proof_system::scheme::Scheme;
|
||||
use std::io::{BufReader, BufWriter, Write};
|
||||
use zokrates_field::Bn128Field;
|
||||
use zokrates_field::Field;
|
||||
|
||||
|
@ -71,7 +73,33 @@ impl Backend<Bn128Field, PGHR13> for Libsnark {
|
|||
(vk, pk)
|
||||
};
|
||||
|
||||
let vk = serde_json::from_str(String::from_utf8(vk).unwrap().as_str()).unwrap();
|
||||
let vk_slice = vk.as_slice();
|
||||
let mut reader = BufReader::new(vk_slice);
|
||||
|
||||
let a = read_g2(&mut reader).unwrap();
|
||||
let b = read_g1(&mut reader).unwrap();
|
||||
let c = read_g2(&mut reader).unwrap();
|
||||
let gamma = read_g2(&mut reader).unwrap();
|
||||
let gamma_beta_1 = read_g1(&mut reader).unwrap();
|
||||
let gamma_beta_2 = read_g2(&mut reader).unwrap();
|
||||
let z = read_g2(&mut reader).unwrap();
|
||||
|
||||
let mut ic = vec![];
|
||||
while let Ok(q) = read_g1(&mut reader) {
|
||||
ic.push(q);
|
||||
}
|
||||
|
||||
let vk = VerificationKey::<G1Affine, G2Affine> {
|
||||
a,
|
||||
b,
|
||||
c,
|
||||
gamma,
|
||||
gamma_beta_1,
|
||||
gamma_beta_2,
|
||||
z,
|
||||
ic,
|
||||
};
|
||||
|
||||
SetupKeypair::new(vk, pk)
|
||||
}
|
||||
|
||||
|
@ -81,7 +109,7 @@ impl Backend<Bn128Field, PGHR13> for Libsnark {
|
|||
proving_key: Vec<u8>,
|
||||
) -> Proof<<PGHR13 as Scheme<Bn128Field>>::ProofPoints> {
|
||||
let (public_inputs_arr, public_inputs_length, private_inputs_arr, private_inputs_length) =
|
||||
prepare_generate_proof(program, witness);
|
||||
prepare_generate_proof(program.clone(), witness.clone());
|
||||
|
||||
let proof = unsafe {
|
||||
let mut pk_buffer = Buffer::from_vec(&proving_key);
|
||||
|
@ -106,15 +134,74 @@ impl Backend<Bn128Field, PGHR13> for Libsnark {
|
|||
proof
|
||||
};
|
||||
|
||||
serde_json::from_str(String::from_utf8(proof).unwrap().as_str()).unwrap()
|
||||
let mut reader = BufReader::new(proof.as_slice());
|
||||
let a = read_g1(&mut reader).unwrap();
|
||||
let a_p = read_g1(&mut reader).unwrap();
|
||||
let b = read_g2(&mut reader).unwrap();
|
||||
let b_p = read_g1(&mut reader).unwrap();
|
||||
let c = read_g1(&mut reader).unwrap();
|
||||
let c_p = read_g1(&mut reader).unwrap();
|
||||
let h = read_g1(&mut reader).unwrap();
|
||||
let k = read_g1(&mut reader).unwrap();
|
||||
|
||||
let points = ProofPoints::<G1Affine, G2Affine> {
|
||||
a,
|
||||
a_p,
|
||||
b,
|
||||
b_p,
|
||||
c,
|
||||
c_p,
|
||||
h,
|
||||
k,
|
||||
};
|
||||
|
||||
let public_inputs: Vec<String> = program
|
||||
.main
|
||||
.arguments
|
||||
.clone()
|
||||
.iter()
|
||||
.zip(program.private.clone())
|
||||
.filter(|(_, p)| !*p)
|
||||
.map(|(v, _)| witness.clone().0.get(v).unwrap().clone())
|
||||
.chain(witness.clone().return_values())
|
||||
.map(|v| format!("0x{:064x}", v.to_biguint()))
|
||||
.collect();
|
||||
|
||||
Proof::new(points, public_inputs)
|
||||
}
|
||||
|
||||
fn verify(
|
||||
vk: <PGHR13 as Scheme<Bn128Field>>::VerificationKey,
|
||||
proof: Proof<<PGHR13 as Scheme<Bn128Field>>::ProofPoints>,
|
||||
) -> bool {
|
||||
let vk_raw = hex::decode(vk.raw.unwrap().clone()).unwrap();
|
||||
let proof_raw = hex::decode(proof.raw.unwrap().clone()).unwrap();
|
||||
let vk_buffer = vec![];
|
||||
let mut vk_writer = BufWriter::new(vk_buffer);
|
||||
|
||||
write_g2(&mut vk_writer, &vk.a);
|
||||
write_g1(&mut vk_writer, &vk.b);
|
||||
write_g2(&mut vk_writer, &vk.c);
|
||||
write_g2(&mut vk_writer, &vk.gamma);
|
||||
write_g1(&mut vk_writer, &vk.gamma_beta_1);
|
||||
write_g2(&mut vk_writer, &vk.gamma_beta_2);
|
||||
write_g2(&mut vk_writer, &vk.z);
|
||||
|
||||
vk.ic
|
||||
.iter()
|
||||
.for_each(|ic_query| write_g1(&mut vk_writer, ic_query));
|
||||
vk_writer.flush().unwrap();
|
||||
|
||||
let proof_buffer = vec![];
|
||||
let mut proof_writer = BufWriter::new(proof_buffer);
|
||||
|
||||
write_g1(&mut proof_writer, &proof.proof.a);
|
||||
write_g1(&mut proof_writer, &proof.proof.a_p);
|
||||
write_g2(&mut proof_writer, &proof.proof.b);
|
||||
write_g1(&mut proof_writer, &proof.proof.b_p);
|
||||
write_g1(&mut proof_writer, &proof.proof.c);
|
||||
write_g1(&mut proof_writer, &proof.proof.c_p);
|
||||
write_g1(&mut proof_writer, &proof.proof.h);
|
||||
write_g1(&mut proof_writer, &proof.proof.k);
|
||||
proof_writer.flush().unwrap();
|
||||
|
||||
let public_inputs: Vec<_> = proof
|
||||
.inputs
|
||||
|
@ -125,8 +212,8 @@ impl Backend<Bn128Field, PGHR13> for Libsnark {
|
|||
let (public_inputs_arr, public_inputs_length) = prepare_public_inputs(public_inputs);
|
||||
|
||||
unsafe {
|
||||
let mut vk_buffer = Buffer::from_vec(&vk_raw);
|
||||
let mut proof_buffer = Buffer::from_vec(&proof_raw);
|
||||
let mut vk_buffer = Buffer::from_vec(vk_writer.get_ref());
|
||||
let mut proof_buffer = Buffer::from_vec(proof_writer.get_ref());
|
||||
|
||||
let ans = pghr13_bn128_verify(
|
||||
&mut vk_buffer as *mut _,
|
||||
|
@ -142,3 +229,41 @@ impl Backend<Bn128Field, PGHR13> for Libsnark {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[cfg(feature = "libsnark")]
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::flat_absy::FlatVariable;
|
||||
use crate::ir::{Function, Interpreter, Prog, Statement};
|
||||
use zokrates_field::Bn128Field;
|
||||
|
||||
#[test]
|
||||
fn verify() {
|
||||
let program: Prog<Bn128Field> = Prog {
|
||||
main: Function {
|
||||
id: String::from("main"),
|
||||
arguments: vec![FlatVariable::new(0)],
|
||||
returns: vec![FlatVariable::public(0)],
|
||||
statements: vec![Statement::Constraint(
|
||||
FlatVariable::new(0).into(),
|
||||
FlatVariable::public(0).into(),
|
||||
)],
|
||||
},
|
||||
private: vec![true],
|
||||
};
|
||||
|
||||
let keypair = <Libsnark as Backend<Bn128Field, PGHR13>>::setup(program.clone());
|
||||
let interpreter = Interpreter::default();
|
||||
|
||||
let witness = interpreter
|
||||
.execute(&program, &vec![Bn128Field::from(42)])
|
||||
.unwrap();
|
||||
|
||||
let proof =
|
||||
<Libsnark as Backend<Bn128Field, PGHR13>>::generate_proof(program, witness, keypair.pk);
|
||||
|
||||
let ans = <Libsnark as Backend<Bn128Field, PGHR13>>::verify(keypair.vk, proof);
|
||||
assert!(ans);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -29,13 +29,11 @@ impl<V: Serialize + DeserializeOwned> SetupKeypair<V> {
|
|||
pub struct Proof<T> {
|
||||
proof: T,
|
||||
inputs: Vec<String>,
|
||||
#[serde(skip_serializing_if = "Option::is_none")]
|
||||
raw: Option<String>,
|
||||
}
|
||||
|
||||
impl<T: Serialize + DeserializeOwned> Proof<T> {
|
||||
fn new(proof: T, inputs: Vec<String>, raw: Option<String>) -> Self {
|
||||
Proof { proof, inputs, raw }
|
||||
fn new(proof: T, inputs: Vec<String>) -> Self {
|
||||
Proof { proof, inputs }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -28,7 +28,6 @@ pub struct VerificationKey<G1, G2> {
|
|||
pub g_gamma: G1,
|
||||
pub h_gamma: G2,
|
||||
pub query: Vec<G1>,
|
||||
pub raw: Option<String>,
|
||||
}
|
||||
|
||||
impl<T: Field + NotBw6_761Field> Scheme<T> for GM17 {
|
||||
|
@ -202,7 +201,7 @@ contract Verifier {
|
|||
function verifyTx(
|
||||
Proof memory proof<%input_argument%>
|
||||
) public view returns (bool r) {
|
||||
uint[] memory inputValues = new uint[](input.length);
|
||||
uint[] memory inputValues = new uint[](<%vk_input_length%>);
|
||||
<%input_loop%>
|
||||
if (verify(inputValues, proof) == 0) {
|
||||
return true;
|
||||
|
@ -270,7 +269,7 @@ contract Verifier {
|
|||
proof.a = Pairing.G1Point(a[0], a[1]);
|
||||
proof.b = Pairing.G2Point([b[0][0], b[0][1]], [b[1][0], b[1][1]]);
|
||||
proof.c = Pairing.G1Point(c[0], c[1]);
|
||||
uint[] memory inputValues = new uint[](input.length);
|
||||
uint[] memory inputValues = new uint[](<%vk_input_length%>);
|
||||
<%input_loop%>
|
||||
if (verify(inputValues, proof) == 0) {
|
||||
return true;
|
||||
|
|
|
@ -181,7 +181,7 @@ contract Verifier {
|
|||
function verifyTx(
|
||||
Proof memory proof<%input_argument%>
|
||||
) public view returns (bool r) {
|
||||
uint[] memory inputValues = new uint[](input.length);
|
||||
uint[] memory inputValues = new uint[](<%vk_input_length%>);
|
||||
<%input_loop%>
|
||||
if (verify(inputValues, proof) == 0) {
|
||||
return true;
|
||||
|
|
|
@ -30,7 +30,6 @@ pub struct VerificationKey<G1, G2> {
|
|||
pub gamma_beta_2: G2,
|
||||
pub z: G2,
|
||||
pub ic: Vec<G1>,
|
||||
pub raw: Option<String>,
|
||||
}
|
||||
|
||||
impl<T: Field> Scheme<T> for PGHR13 {
|
||||
|
@ -172,8 +171,8 @@ const CONTRACT_TEMPLATE_V2: &str = r#"contract Verifier {
|
|||
Pairing.G1Point b_p;
|
||||
Pairing.G1Point c;
|
||||
Pairing.G1Point c_p;
|
||||
Pairing.G1Point k;
|
||||
Pairing.G1Point h;
|
||||
Pairing.G1Point k;
|
||||
}
|
||||
function verifyingKey() pure internal returns (VerifyingKey memory vk) {
|
||||
vk.a = Pairing.G2Point(<%vk_a%>);
|
||||
|
@ -215,7 +214,7 @@ const CONTRACT_TEMPLATE_V2: &str = r#"contract Verifier {
|
|||
function verifyTx(
|
||||
Proof memory proof<%input_argument%>
|
||||
) public view returns (bool r) {
|
||||
uint[] memory inputValues = new uint[](input.length);
|
||||
uint[] memory inputValues = new uint[](<%vk_input_length%>);
|
||||
<%input_loop%>
|
||||
if (verify(inputValues, proof) == 0) {
|
||||
return true;
|
||||
|
@ -245,8 +244,8 @@ const CONTRACT_TEMPLATE: &str = r#"contract Verifier {
|
|||
Pairing.G1Point b_p;
|
||||
Pairing.G1Point c;
|
||||
Pairing.G1Point c_p;
|
||||
Pairing.G1Point k;
|
||||
Pairing.G1Point h;
|
||||
Pairing.G1Point k;
|
||||
}
|
||||
function verifyingKey() pure internal returns (VerifyingKey memory vk) {
|
||||
vk.a = Pairing.G2Point(<%vk_a%>);
|
||||
|
@ -304,7 +303,7 @@ const CONTRACT_TEMPLATE: &str = r#"contract Verifier {
|
|||
proof.c_p = Pairing.G1Point(c_p[0], c_p[1]);
|
||||
proof.h = Pairing.G1Point(h[0], h[1]);
|
||||
proof.k = Pairing.G1Point(k[0], k[1]);
|
||||
uint[] memory inputValues = new uint[](input.length);
|
||||
uint[] memory inputValues = new uint[](<%vk_input_length%>);
|
||||
<%input_loop%>
|
||||
if (verify(inputValues, proof) == 0) {
|
||||
return true;
|
||||
|
|
|
@ -436,10 +436,10 @@ library Pairing {
|
|||
/// @return the generator of G2
|
||||
function P2() pure internal returns (G2Point memory) {
|
||||
return G2Point(
|
||||
[11559732032986387107991004021392285783925812861821192530917403151452391805634,
|
||||
10857046999023057135944570762232829481370756359578518086990519993285655852781],
|
||||
[4082367875863433681332203403145435568316851327593401208105741076214120093531,
|
||||
8495653923123431417604973247489272438418190587263600148770280649306958101930]
|
||||
[10857046999023057135944570762232829481370756359578518086990519993285655852781,
|
||||
11559732032986387107991004021392285783925812861821192530917403151452391805634],
|
||||
[8495653923123431417604973247489272438418190587263600148770280649306958101930,
|
||||
4082367875863433681332203403145435568316851327593401208105741076214120093531]
|
||||
);
|
||||
}
|
||||
/// @return the negation of p, i.e. p.addition(p.negate()) should be zero.
|
||||
|
@ -467,7 +467,7 @@ library Pairing {
|
|||
}
|
||||
/// @return r the sum of two points of G2
|
||||
function addition(G2Point memory p1, G2Point memory p2) internal view returns (G2Point memory r) {
|
||||
(r.X[1], r.X[0], r.Y[1], r.Y[0]) = BN256G2.ECTwistAdd(p1.X[1],p1.X[0],p1.Y[1],p1.Y[0],p2.X[1],p2.X[0],p2.Y[1],p2.Y[0]);
|
||||
(r.X[0], r.X[1], r.Y[0], r.Y[1]) = BN256G2.ECTwistAdd(p1.X[0],p1.X[1],p1.Y[0],p1.Y[1],p2.X[0],p2.X[1],p2.Y[0],p2.Y[1]);
|
||||
}
|
||||
/// @return r the product of a point on G1 and a scalar, i.e.
|
||||
/// p == p.scalar_mul(1) and p.addition(p) == p.scalar_mul(2) for all points p.
|
||||
|
@ -497,10 +497,10 @@ library Pairing {
|
|||
{
|
||||
input[i * 6 + 0] = p1[i].X;
|
||||
input[i * 6 + 1] = p1[i].Y;
|
||||
input[i * 6 + 2] = p2[i].X[0];
|
||||
input[i * 6 + 3] = p2[i].X[1];
|
||||
input[i * 6 + 4] = p2[i].Y[0];
|
||||
input[i * 6 + 5] = p2[i].Y[1];
|
||||
input[i * 6 + 2] = p2[i].X[1];
|
||||
input[i * 6 + 3] = p2[i].X[0];
|
||||
input[i * 6 + 4] = p2[i].Y[1];
|
||||
input[i * 6 + 5] = p2[i].Y[0];
|
||||
}
|
||||
uint[1] memory out;
|
||||
bool success;
|
||||
|
@ -584,10 +584,10 @@ library Pairing {
|
|||
/// @return the generator of G2
|
||||
function P2() pure internal returns (G2Point memory) {
|
||||
return G2Point(
|
||||
[11559732032986387107991004021392285783925812861821192530917403151452391805634,
|
||||
10857046999023057135944570762232829481370756359578518086990519993285655852781],
|
||||
[4082367875863433681332203403145435568316851327593401208105741076214120093531,
|
||||
8495653923123431417604973247489272438418190587263600148770280649306958101930]
|
||||
[10857046999023057135944570762232829481370756359578518086990519993285655852781,
|
||||
11559732032986387107991004021392285783925812861821192530917403151452391805634],
|
||||
[8495653923123431417604973247489272438418190587263600148770280649306958101930,
|
||||
4082367875863433681332203403145435568316851327593401208105741076214120093531]
|
||||
);
|
||||
}
|
||||
/// @return the negation of p, i.e. p.addition(p.negate()) should be zero.
|
||||
|
@ -615,7 +615,7 @@ library Pairing {
|
|||
}
|
||||
/// @return r the sum of two points of G2
|
||||
function addition(G2Point memory p1, G2Point memory p2) internal view returns (G2Point memory r) {
|
||||
(r.X[1], r.X[0], r.Y[1], r.Y[0]) = BN256G2.ECTwistAdd(p1.X[1],p1.X[0],p1.Y[1],p1.Y[0],p2.X[1],p2.X[0],p2.Y[1],p2.Y[0]);
|
||||
(r.X[0], r.X[1], r.Y[0], r.Y[1]) = BN256G2.ECTwistAdd(p1.X[0],p1.X[1],p1.Y[0],p1.Y[1],p2.X[0],p2.X[1],p2.Y[0],p2.Y[1]);
|
||||
}
|
||||
/// @return r the product of a point on G1 and a scalar, i.e.
|
||||
/// p == p.scalar_mul(1) and p.addition(p) == p.scalar_mul(2) for all points p.
|
||||
|
@ -645,10 +645,10 @@ library Pairing {
|
|||
{
|
||||
input[i * 6 + 0] = p1[i].X;
|
||||
input[i * 6 + 1] = p1[i].Y;
|
||||
input[i * 6 + 2] = p2[i].X[0];
|
||||
input[i * 6 + 3] = p2[i].X[1];
|
||||
input[i * 6 + 4] = p2[i].Y[0];
|
||||
input[i * 6 + 5] = p2[i].Y[1];
|
||||
input[i * 6 + 2] = p2[i].X[1];
|
||||
input[i * 6 + 3] = p2[i].X[0];
|
||||
input[i * 6 + 4] = p2[i].Y[1];
|
||||
input[i * 6 + 5] = p2[i].Y[0];
|
||||
}
|
||||
uint[1] memory out;
|
||||
bool success;
|
||||
|
|
|
@ -33,7 +33,6 @@ impl<T: Field + ZexeFieldExtensions + NotBw6_761Field> Backend<T, GM17> for Zexe
|
|||
.iter()
|
||||
.map(|g1| parse_g1::<T>(g1))
|
||||
.collect(),
|
||||
raw: None,
|
||||
};
|
||||
|
||||
SetupKeypair::new(vk, pk)
|
||||
|
@ -64,7 +63,7 @@ impl<T: Field + ZexeFieldExtensions + NotBw6_761Field> Backend<T, GM17> for Zexe
|
|||
.map(parse_fr::<T>)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Proof::new(proof_points, inputs, None)
|
||||
Proof::new(proof_points, inputs)
|
||||
}
|
||||
|
||||
fn verify(
|
||||
|
@ -128,7 +127,6 @@ impl Backend<Bw6_761Field, GM17> for Zexe {
|
|||
.iter()
|
||||
.map(|g1| parse_g1::<Bw6_761Field>(g1))
|
||||
.collect(),
|
||||
raw: None,
|
||||
};
|
||||
|
||||
SetupKeypair::new(vk, pk)
|
||||
|
@ -159,7 +157,7 @@ impl Backend<Bw6_761Field, GM17> for Zexe {
|
|||
.map(parse_fr::<Bw6_761Field>)
|
||||
.collect::<Vec<_>>();
|
||||
|
||||
Proof::new(proof_points, inputs, None)
|
||||
Proof::new(proof_points, inputs)
|
||||
}
|
||||
|
||||
fn verify(
|
||||
|
|
Loading…
Reference in a new issue