1
0
Fork 0
mirror of synced 2025-09-24 04:40:05 +00:00
ZoKrates/zokrates_core/lib/util.tcc
2020-05-22 15:50:44 +02:00

159 lines
No EOL
4.7 KiB
C++

#pragma once
#include "ffi.hpp"
#include <cassert>
#include <iomanip>
#include <iostream>
#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.
template <mp_size_t N>
libff::bigint<N> libsnarkBigintFromBytes(const uint8_t* _x)
{
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));
}
}
return x;
}
template <mp_size_t N>
std::string hexStringFromLibsnarkBigint(libff::bigint<N> _x)
{
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)));
}
}
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)
{
G1 aff = _p;
aff.to_affine_coordinates();
return "[\"0x" + hexStringFromLibsnarkBigint<Q>(aff.X.as_bigint()) + "\",\"0x" + hexStringFromLibsnarkBigint<Q>(aff.Y.as_bigint()) + "\"]";
}
template <mp_size_t Q, typename G2>
std::string outputPointG2AffineAsHexJson(G2 _p)
{
G2 aff = _p;
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()) + "\"]]";
}
template <template <typename ppT> class ConstraintSystem, mp_size_t R, typename ppT>
ConstraintSystem<ppT> createConstraintSystem(const uint8_t* a,
const uint8_t* b,
const uint8_t* c,
int32_t a_len,
int32_t b_len,
int32_t c_len,
int32_t constraints,
int32_t variables,
int32_t inputs)
{
ConstraintSystem<ppT> cs;
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;
struct VariableValueMapping {
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;
int a_id = 0;
int b_id = 0;
int c_id = 0;
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);
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);
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);
if (!value.is_zero()) {
lin_comb_c.add_term(c_vvmap[c_id].variable_id, value);
}
c_id++;
}
cs.add_constraint(r1cs_constraint<libff::Fr<ppT>>(lin_comb_a, lin_comb_b, lin_comb_c));
}
return cs;
}
template <typename T>
inline void fromBuffer(buffer_t* buffer, T& t)
{
std::string tmp((char*)buffer->data, buffer->length);
std::stringstream ss(tmp);
ss >> t;
}
template <typename T>
inline std::string serialize(const T& t)
{
std::stringstream ss;
ss << t;
return ss.str();
}
template <typename T>
inline buffer_t createBuffer(T& t)
{
std::string tmp = serialize(t);
size_t length = tmp.length();
buffer_t buffer;
buffer.data = (uint8_t*)malloc(length);
buffer.length = length;
tmp.copy(reinterpret_cast<char*>(buffer.data), buffer.length);
return buffer;
}