Skip to content

Commit

Permalink
Merge pull request #175 from clearmatics/templatize-code
Browse files Browse the repository at this point in the history
Templatize code
  • Loading branch information
AntoineRondelet committed Mar 25, 2020
2 parents 593e22f + 31ad249 commit 95944e1
Show file tree
Hide file tree
Showing 13 changed files with 320 additions and 210 deletions.
59 changes: 4 additions & 55 deletions src/libsnark_helpers/debug_helpers.cpp
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
// DISCLAIMER:
// Content taken and adapted from:
// wraplibsnark.cpp (originally written by Jacob Eberhardt and Dennis Kuhnert)
// Copyright (c) 2015-2020 Clearmatics Technologies Ltd
//
// SPDX-License-Identifier: LGPL-3.0+

#include "libsnark_helpers/debug_helpers.hpp"

Expand All @@ -9,57 +9,6 @@
namespace libzeth
{

// Conversion byte[32] <-> libsnark bigint.
libff::bigint<libff::alt_bn128_r_limbs> libsnark_bigint_from_bytes(
const uint8_t *_x)
{
libff::bigint<libff::alt_bn128_r_limbs> x;

for (unsigned i = 0; i < 4; i++) {
for (unsigned j = 0; j < 8; j++) {
x.data[3 - i] |= uint64_t(_x[i * 8 + j]) << (8 * (7 - j));
}
}
return x;
}

std::string hex_from_libsnark_bigint(libff::bigint<libff::alt_bn128_r_limbs> _x)
{
uint8_t x[32];
for (unsigned i = 0; i < 4; i++) {
for (unsigned j = 0; j < 8; j++) {
x[i * 8 + j] = uint8_t(uint64_t(_x.data[3 - i]) >> (8 * (7 - j)));
}
}

std::stringstream ss;
ss << std::setfill('0');
for (unsigned i = 0; i < 32; i++) {
ss << std::hex << std::setw(2) << (int)x[i];
}

std::string str = ss.str();
return str.erase(0, std::min(str.find_first_not_of('0'), str.size() - 1));
}

std::string point_g1_affine_as_hex(libff::alt_bn128_G1 _p)
{
libff::alt_bn128_G1 aff = _p;
aff.to_affine_coordinates();
return "\"0x" + hex_from_libsnark_bigint(aff.X.as_bigint()) + "\", \"0x" +
hex_from_libsnark_bigint(aff.Y.as_bigint()) + "\"";
}

std::string point_g2_affine_as_hex(libff::alt_bn128_G2 _p)
{
libff::alt_bn128_G2 aff = _p;
aff.to_affine_coordinates();
return "[\"0x" + hex_from_libsnark_bigint(aff.X.c1.as_bigint()) +
"\", \"0x" + hex_from_libsnark_bigint(aff.X.c0.as_bigint()) +
"\"],\n [\"0x" + hex_from_libsnark_bigint(aff.Y.c1.as_bigint()) +
"\", \"0x" + hex_from_libsnark_bigint(aff.Y.c0.as_bigint()) + "\"]";
}

boost::filesystem::path get_path_to_setup_directory()
{
const char *path = std::getenv("ZETH_TRUSTED_SETUP_DIR");
Expand Down Expand Up @@ -94,4 +43,4 @@ bool replace(std::string &str, const std::string &from, const std::string &to)
return true;
}

} // namespace libzeth
} // namespace libzeth
28 changes: 15 additions & 13 deletions src/libsnark_helpers/debug_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,26 +7,26 @@

#include <boost/filesystem.hpp>
#include <cassert>
#include <fstream>
#include <iomanip>
#include <iostream>
#include <sstream>
#include <libff/common/default_types/ec_pp.hpp>
#include <stdbool.h>
#include <stdint.h>

// Contains definition of alt_bn128 ec public parameters
#include <libff/algebra/curves/alt_bn128/alt_bn128_pp.hpp>
#include <libff/common/default_types/ec_pp.hpp>

namespace libzeth
{

libff::bigint<libff::alt_bn128_r_limbs> libsnark_bigint_from_bytes(
const uint8_t *_x);
template<typename FieldT>
std::string hex_from_libsnark_bigint(
libff::bigint<libff::alt_bn128_r_limbs> _x);
std::string point_g1_affine_as_hex(libff::alt_bn128_G1 _p);
std::string point_g2_affine_as_hex(libff::alt_bn128_G2 _p);
const libff::bigint<FieldT::num_limbs> &limbs);

template<typename FieldT>
libff::bigint<FieldT::num_limbs> libsnark_bigint_from_bytes(
const uint8_t bytes[(FieldT::num_bits + 8 - 1) / 8]);

template<typename ppT>
std::string point_g1_affine_as_hex(const libff::G1<ppT> &point);

template<typename ppT>
std::string point_g2_affine_as_hex(const libff::G2<ppT> &point);

boost::filesystem::path get_path_to_setup_directory();
boost::filesystem::path get_path_to_debug_directory();
Expand All @@ -35,4 +35,6 @@ bool replace(std::string &str, const std::string &from, const std::string &to);

} // namespace libzeth

#include "libsnark_helpers/debug_helpers.tcc"

#endif // __ZETH_DEBUG_HELPERS_HPP__
137 changes: 137 additions & 0 deletions src/libsnark_helpers/debug_helpers.tcc
Original file line number Diff line number Diff line change
@@ -0,0 +1,137 @@
// Copyright (c) 2015-2020 Clearmatics Technologies Ltd
//
// SPDX-License-Identifier: LGPL-3.0+

#ifndef __ZETH_DEBUG_HELPERS_TCC__
#define __ZETH_DEBUG_HELPERS_TCC__

#include <fstream>
#include <iomanip>
#include <iostream>
#include <libff/algebra/fields/bigint.hpp>
#include <libff/common/default_types/ec_pp.hpp>
#include <sstream>

// This file uses types and preprocessor variables defined in the `gmp.h`
// header:
// - `mp_size_t`
// - `GMP_LIMB_BITS`
// - `GMP_NAIL_BITS`

namespace libzeth
{

// WARNING: The following function assumes that NAILS are NOT used
// See Section 8.2 (page 68): https://gmplib.org/gmp-man-6.2.0.pdf
// In other words, we assume below that:
// - GMP_NUMB_BITS = GMP_LIMB_BITS and thus,
// - GMP_NAIL_BITS = 0
//
// This function decomposes a bigint into an array of bytes.
//
// For instance, if the number of bits in a Limb is 64,
// and we have `input_bigint = [Limb0, Limb1, Limb2, Limb3]`,
// where every Limb{i} is of type `mp_limb_t`, then the function returns
//
// x = [x0, ..., x7, x8, ..., x15, x16, ..., x23, x24, ..., x31]
// ^ ^ ^ ^ ^ ^ ^ ^
// |_______| |________| |_________| |_________|
// | | | |
// Limb3 Limb2 Limb1 Limb0
//
// where all x_i's are bytes (uint8_t)
template<typename FieldT>
std::string hex_from_libsnark_bigint(
const libff::bigint<FieldT::num_limbs> &limbs)
{
const unsigned bytes_per_limb = (GMP_LIMB_BITS + 8 - 1) / 8;

uint8_t x[bytes_per_limb * FieldT::num_limbs];
for (unsigned i = 0; i < FieldT::num_limbs; i++) {
for (unsigned j = 0; j < bytes_per_limb; j++) {
x[i * 8 + j] = uint8_t(
uint64_t(limbs.data[(FieldT::num_limbs - 1) - i]) >>
(GMP_LIMB_BITS - 8 * (j + 1)));
}
}

std::stringstream ss;

// Display every byte as 2 hexadecimal characters
ss << std::setfill('0');
for (unsigned i = 0; i < bytes_per_limb * FieldT::num_limbs; i++) {
ss << std::hex << std::setw(2) << (int)x[i];
}
std::string str = ss.str();

// Remove leading 0's
return str.erase(0, std::min(str.find_first_not_of('0'), str.size() - 1));
}

// WARNING: The following function assumes that NAILS are NOT used
// See Section 8.2 (page 68): https://gmplib.org/gmp-man-6.2.0.pdf
// In other words, we assume below that:
// - GMP_NUMB_BITS = GMP_LIMB_BITS and thus,
// - GMP_NAIL_BITS = 0
//
// This function recomposes a bigint from an array of bytes.
//
// For instance, if the number of bits in a Limb is 64, and we have as input:
// x = [x0, ..., x7, x8, ..., x15, x16, ..., x23, x24, ..., x31]
// ^ ^ ^ ^ ^ ^ ^ ^
// |_______| |________| |_________| |_________|
// | | | |
// Limb3 Limb2 Limb1 Limb0
// where all x_i's are bytes (uint8_t)
//
// then the function returns:
// and we have `res_bigint = [Limb0, Limb1, Limb2, Limb3]`,
// where every Limb{i} is of type `mp_limb_t`,
template<typename FieldT>
libff::bigint<FieldT::num_limbs> libsnark_bigint_from_bytes(
const uint8_t bytes[(FieldT::num_bits + 8 - 1) / 8])
{
const unsigned bytes_per_limb = (GMP_LIMB_BITS + 8 - 1) / 8;

libff::bigint<FieldT::num_limbs> res;

for (unsigned i = 0; i < FieldT::num_limbs; i++) {
for (unsigned j = 0; j < bytes_per_limb; j++) {
res.data[FieldT::num_limbs - i] |= mp_limb_t(bytes[i * 8 + j])
<< (GMP_LIMB_BITS - 8 * (j + 1));
}
}
return res;
}

template<typename ppT>
std::string point_g1_affine_as_hex(const libff::G1<ppT> &point)
{
libff::G1<ppT> affine_p = point;
affine_p.to_affine_coordinates();
return "\"0x" +
hex_from_libsnark_bigint<libff::Fq<ppT>>(affine_p.X.as_bigint()) +
"\", \"0x" +
hex_from_libsnark_bigint<libff::Fq<ppT>>(affine_p.Y.as_bigint()) +
"\"";
}

template<typename ppT>
std::string point_g2_affine_as_hex(const libff::G2<ppT> &point)
{
libff::G2<ppT> affine_p = point;
affine_p.to_affine_coordinates();
return "[\"0x" +
hex_from_libsnark_bigint<libff::Fq<ppT>>(affine_p.X.c1.as_bigint()) +
"\", \"0x" +
hex_from_libsnark_bigint<libff::Fq<ppT>>(affine_p.X.c0.as_bigint()) +
"\"],\n [\"0x" +
hex_from_libsnark_bigint<libff::Fq<ppT>>(affine_p.Y.c1.as_bigint()) +
"\", \"0x" +
hex_from_libsnark_bigint<libff::Fq<ppT>>(affine_p.Y.c0.as_bigint()) +
"\"]";
}

} // namespace libzeth

#endif // __ZETH_DEBUG_HELPERS_TCC__
11 changes: 6 additions & 5 deletions src/libsnark_helpers/extended_proof.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,8 @@ void extended_proof<ppT>::write_primary_input(
<< "["; // 1 should always be the first variable passed
for (size_t i = 0; i < *this->primary_inputs.size(); ++i) {
ss << "\"0x"
<< hex_from_libsnark_bigint(*this->primary_inputs[i].as_bigint())
<< hex_from_libsnark_bigint<libff::Fr<ppT>>(
*this->primary_inputs[i].as_bigint())
<< "\"";
if (i < *this->primary_inputs.size() - 1) {
ss << ", ";
Expand All @@ -79,7 +80,7 @@ template<typename ppT> void extended_proof<ppT>::dump_primary_inputs() const
<< "["; // 1 should always be the first variable passed
for (size_t i = 0; i < (*this->primary_inputs).size(); ++i) {
std::cout << "\"0x"
<< hex_from_libsnark_bigint(
<< hex_from_libsnark_bigint<libff::Fr<ppT>>(
(*this->primary_inputs)[i].as_bigint())
<< "\"";
if (i < (*this->primary_inputs).size() - 1) {
Expand All @@ -94,19 +95,19 @@ template<typename ppT>
void extended_proof<ppT>::write_proof(boost::filesystem::path path) const
{
proof_to_json<ppT>(*this->proof, path);
};
}

template<typename ppT>
void extended_proof<ppT>::write_extended_proof(
boost::filesystem::path path) const
{
proof_and_inputs_to_json<ppT>(*this->proof, *this->primary_inputs, path);
};
}

template<typename ppT> void extended_proof<ppT>::dump_proof() const
{
display_proof<ppT>(*this->proof);
};
}

} // namespace libzeth

Expand Down
7 changes: 2 additions & 5 deletions src/libsnark_helpers/libsnark_helpers.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,15 +12,12 @@
#include <fstream>
#include <iomanip>
#include <iostream>
#include <libff/common/default_types/ec_pp.hpp>
#include <libsnark/gadgetlib1/gadget.hpp>
#include <sstream>
#include <stdbool.h>
#include <stdint.h>

// Contains definition of alt_bn128 ec public parameters
#include <libff/algebra/curves/alt_bn128/alt_bn128_pp.hpp>
#include <libff/common/default_types/ec_pp.hpp>
#include <libsnark/gadgetlib1/gadget.hpp>

// Contains required interfaces and types (keypair, proof, generator, prover,
// verifier)
#include "extended_proof.hpp"
Expand Down
4 changes: 3 additions & 1 deletion src/libsnark_helpers/libsnark_helpers.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -124,7 +124,9 @@ void fill_stringstream_with_json_constraints(
ss << "{";
ss << "\"index\":" << lt.index << ",";
ss << "\"value\":"
<< "\"0x" + hex_from_libsnark_bigint(lt.coeff.as_bigint()) << "\"";
<< "\"0x" +
hex_from_libsnark_bigint<libff::Fr<ppT>>(lt.coeff.as_bigint())
<< "\"";
ss << "}";
count++;
}
Expand Down
21 changes: 12 additions & 9 deletions src/snarks/groth16/api/response.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -21,16 +21,18 @@ void prepare_proof_response(
prover_proto::HexPointBaseGroup1Affine *c =
new prover_proto::HexPointBaseGroup1Affine();

a->CopyFrom(format_hexPointBaseGroup1Affine(proof_obj.g_A));
b->CopyFrom(format_hexPointBaseGroup2Affine(proof_obj.g_B)); // in G2
c->CopyFrom(format_hexPointBaseGroup1Affine(proof_obj.g_C));
a->CopyFrom(format_hexPointBaseGroup1Affine<ppT>(proof_obj.g_A));
b->CopyFrom(format_hexPointBaseGroup2Affine<ppT>(proof_obj.g_B)); // in G2
c->CopyFrom(format_hexPointBaseGroup1Affine<ppT>(proof_obj.g_C));

libsnark::r1cs_ppzksnark_primary_input<ppT> public_inputs =
ext_proof.get_primary_input();
std::stringstream ss;
ss << "[";
for (size_t i = 0; i < public_inputs.size(); ++i) {
ss << "\"0x" << hex_from_libsnark_bigint(public_inputs[i].as_bigint())
ss << "\"0x"
<< hex_from_libsnark_bigint<libff::Fr<ppT>>(
public_inputs[i].as_bigint())
<< "\"";
if (i < public_inputs.size() - 1) {
ss << ", ";
Expand Down Expand Up @@ -63,15 +65,16 @@ void prepare_verification_key_response(
prover_proto::HexPointBaseGroup2Affine *d =
new prover_proto::HexPointBaseGroup2Affine(); // in G2

a->CopyFrom(format_hexPointBaseGroup1Affine(vk.alpha_g1)); // in G1
b->CopyFrom(format_hexPointBaseGroup2Affine(vk.beta_g2)); // in G2
d->CopyFrom(format_hexPointBaseGroup2Affine(vk.delta_g2)); // in G2
a->CopyFrom(format_hexPointBaseGroup1Affine<ppT>(vk.alpha_g1)); // in G1
b->CopyFrom(format_hexPointBaseGroup2Affine<ppT>(vk.beta_g2)); // in G2
d->CopyFrom(format_hexPointBaseGroup2Affine<ppT>(vk.delta_g2)); // in G2

std::stringstream ss;
unsigned abc_length = vk.ABC_g1.rest.indices.size() + 1;
ss << "[[" << point_g1_affine_as_hex(vk.ABC_g1.first) << "]";
ss << "[[" << point_g1_affine_as_hex<ppT>(vk.ABC_g1.first) << "]";
for (size_t i = 1; i < abc_length; ++i) {
auto vk_abc_i = point_g1_affine_as_hex(vk.ABC_g1.rest.values[i - 1]);
auto vk_abc_i =
point_g1_affine_as_hex<ppT>(vk.ABC_g1.rest.values[i - 1]);
ss << ",[" << vk_abc_i << "]";
}
ss << "]";
Expand Down
Loading

0 comments on commit 95944e1

Please sign in to comment.