Initial commit
This commit is contained in:
commit
86beff8c7f
|
@ -0,0 +1,6 @@
|
|||
test
|
||||
*.o
|
||||
*.d
|
||||
depinst
|
||||
depsrc
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
The MIT License (MIT)
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in
|
||||
all copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
THE SOFTWARE.
|
|
@ -0,0 +1,17 @@
|
|||
OPTFLAGS = -march=native -mtune=native -O2
|
||||
CXXFLAGS += -g -Wall -Wextra -Wno-unused-parameter -std=c++11 -fPIC -Wno-unused-variable
|
||||
CXXFLAGS += -I $(DEPINST)/include -I $(DEPINST)/include/libsnark -DUSE_ASM -DCURVE_ALT_BN128
|
||||
LDFLAGS += -flto
|
||||
|
||||
DEPSRC=depsrc
|
||||
DEPINST=depinst
|
||||
|
||||
LDLIBS += -L $(DEPINST)/lib -Wl,-rpath $(DEPINST)/lib -L . -lsnark -lgmpxx -lgmp
|
||||
LDLIBS += -lboost_system
|
||||
|
||||
all:
|
||||
$(CXX) -o test.o src/test.cpp -c $(CXXFLAGS)
|
||||
$(CXX) -o test test.o $(CXXFLAGS) $(LDFLAGS) $(LDLIBS)
|
||||
|
||||
clean:
|
||||
$(RM) test.o test
|
|
@ -0,0 +1,39 @@
|
|||
#!/bin/bash
|
||||
# To pass options options to libsnark Makefile, put them in env var LIBSNARK_FLAGS.
|
||||
# To clone libsnark from an alternate location, set env var LIBSNARK_SRC. For example:
|
||||
# LIBSNARK_SRC="$HOME/libsnark.git --branch master" ./get-libsnark
|
||||
# To use curve ALT_BN128 instead of BN128 (which is x64-only), use:
|
||||
# CURVE=ALT_BN128 ./get-libsnark
|
||||
|
||||
set -e
|
||||
|
||||
LIBSNARK_SRC=${LIBSNARK_SRC:-https://github.com/scipr-lab/libsnark}
|
||||
|
||||
CURVE=${CURVE:-BN128}
|
||||
|
||||
LIBSNARK_FLAGS="$LIBSNARK_FLAGS NO_SUPERCOP=1 NO_GTEST=1 NO_DOCS=1 CURVE=$CURVE"
|
||||
if [[ `uname -s` == "Darwin" ]]; then
|
||||
LIBSNARK_FLAGS="$LIBSNARK_FLAGS NO_PROCPS=1"
|
||||
fi
|
||||
|
||||
set -x
|
||||
|
||||
DEPSRC=./depsrc
|
||||
DEPINST=./depinst
|
||||
|
||||
mkdir -p $DEPINST
|
||||
DEPINST=`pwd -P`/$DEPINST # remember absolute path
|
||||
|
||||
mkdir -p $DEPSRC
|
||||
cd $DEPSRC
|
||||
|
||||
[ ! -d libsnark ] && git clone $LIBSNARK_SRC libsnark
|
||||
cd libsnark
|
||||
git pull
|
||||
if [ "$CURVE" == "BN128" ]; then
|
||||
# TODO: submit -fPIC patch to ate-pairing
|
||||
INC_DIR=-fPIC ./prepare-depends.sh
|
||||
fi
|
||||
make clean
|
||||
make lib $LIBSNARK_FLAGS
|
||||
make install PREFIX=$DEPINST $LIBSNARK_FLAGS
|
|
@ -0,0 +1,26 @@
|
|||
#include "libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.hpp"
|
||||
#include "algebra/fields/field_utils.hpp"
|
||||
|
||||
using namespace libsnark;
|
||||
|
||||
template<typename FieldT>
|
||||
class l_gadget : public gadget<FieldT> {
|
||||
public:
|
||||
unsigned int dimension; /* N */
|
||||
|
||||
pb_variable_array<FieldT> input_as_field_elements; /* R1CS input */
|
||||
pb_variable_array<FieldT> input_as_bits; /* unpacked R1CS input */
|
||||
std::shared_ptr<multipacking_gadget<FieldT> > unpack_inputs; /* multipacking gadget */
|
||||
|
||||
std::vector<pb_variable_array<FieldT>> puzzle_values;
|
||||
|
||||
|
||||
l_gadget(protoboard<FieldT> &pb, unsigned int n);
|
||||
void generate_r1cs_constraints();
|
||||
void generate_r1cs_witness(std::vector<bit_vector> &puzzle_values);
|
||||
};
|
||||
|
||||
template<typename FieldT>
|
||||
r1cs_primary_input<FieldT> l_input_map(std::vector<bit_vector> &puzzle_values);
|
||||
|
||||
#include "gadget.tcc"
|
|
@ -0,0 +1,55 @@
|
|||
template<typename FieldT>
|
||||
l_gadget<FieldT>::l_gadget(protoboard<FieldT> &pb, unsigned int n) :
|
||||
gadget<FieldT>(pb, FMT(annotation_prefix, " l_gadget"))
|
||||
{
|
||||
dimension = n;
|
||||
|
||||
const size_t input_size_in_bits = n * n * 8;
|
||||
{
|
||||
const size_t input_size_in_field_elements = div_ceil(input_size_in_bits, FieldT::capacity());
|
||||
input_as_field_elements.allocate(pb, input_size_in_field_elements, "input_as_field_elements");
|
||||
this->pb.set_input_sizes(input_size_in_field_elements);
|
||||
}
|
||||
|
||||
puzzle_values.resize(n*n);
|
||||
|
||||
for (unsigned int i = 0; i < (n*n); i++) {
|
||||
puzzle_values[i].allocate(pb, 8, "puzzle_value[i]");
|
||||
input_as_bits.insert(input_as_bits.end(), puzzle_values[i].begin(), puzzle_values[i].end());
|
||||
}
|
||||
|
||||
assert(input_as_bits.size() == input_size_in_bits);
|
||||
unpack_inputs.reset(new multipacking_gadget<FieldT>(this->pb, input_as_bits, input_as_field_elements, FieldT::capacity(), FMT(this->annotation_prefix, " unpack_inputs")));
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
void l_gadget<FieldT>::generate_r1cs_constraints()
|
||||
{
|
||||
unpack_inputs->generate_r1cs_constraints(true);
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
void l_gadget<FieldT>::generate_r1cs_witness(std::vector<bit_vector> &input_puzzle_values)
|
||||
{
|
||||
assert(input_puzzle_values.size() == dimension*dimension);
|
||||
for (unsigned int i = 0; i < dimension*dimension; i++) {
|
||||
assert(input_puzzle_values[i].size() == 8);
|
||||
puzzle_values[i].fill_with_bits(this->pb, input_puzzle_values[i]);
|
||||
}
|
||||
|
||||
unpack_inputs->generate_r1cs_witness_from_bits();
|
||||
}
|
||||
|
||||
template<typename FieldT>
|
||||
r1cs_primary_input<FieldT> l_input_map(unsigned int n, std::vector<bit_vector> &input_puzzle_values)
|
||||
{
|
||||
assert(input_puzzle_values.size() == n*n);
|
||||
bit_vector input_as_bits;
|
||||
|
||||
for (unsigned int i = 0; i < n*n; i++) {
|
||||
assert(input_puzzle_values[i].size() == 8);
|
||||
input_as_bits.insert(input_as_bits.end(), input_puzzle_values[i].begin(), input_puzzle_values[i].end());
|
||||
}
|
||||
std::vector<FieldT> input_as_field_elements = pack_bit_vector_into_field_element_vector<FieldT>(input_as_bits);
|
||||
return input_as_field_elements;
|
||||
}
|
|
@ -0,0 +1,25 @@
|
|||
#include "libsnark/gadgetlib1/gadgets/basic_gadgets.hpp"
|
||||
#include "libsnark/zk_proof_systems/ppzksnark/r1cs_ppzksnark/r1cs_ppzksnark.hpp"
|
||||
#include "libsnark/common/default_types/r1cs_ppzksnark_pp.hpp"
|
||||
#include "libsnark/common/utils.hpp"
|
||||
#include <boost/optional.hpp>
|
||||
|
||||
using namespace libsnark;
|
||||
|
||||
std::vector<std::vector<bool>> convertPuzzleToBool(std::vector<uint8_t>);
|
||||
|
||||
template<typename ppzksnark_ppT>
|
||||
r1cs_ppzksnark_keypair<ppzksnark_ppT> generate_keypair();
|
||||
|
||||
template<typename ppzksnark_ppT>
|
||||
boost::optional<r1cs_ppzksnark_proof<ppzksnark_ppT>> generate_proof(r1cs_ppzksnark_proving_key<ppzksnark_ppT> proving_key,
|
||||
std::vector<uint8_t> &puzzle
|
||||
);
|
||||
|
||||
template<typename ppzksnark_ppT>
|
||||
bool verify_proof(r1cs_ppzksnark_verification_key<ppzksnark_ppT> verification_key,
|
||||
r1cs_ppzksnark_proof<ppzksnark_ppT> proof,
|
||||
std::vector<uint8_t> &puzzle
|
||||
);
|
||||
|
||||
#include "snark.tcc"
|
|
@ -0,0 +1,76 @@
|
|||
#include "gadget.hpp"
|
||||
|
||||
using namespace std;
|
||||
|
||||
std::vector<bool> convertIntToVector(uint8_t val) {
|
||||
std::vector<bool> ret;
|
||||
|
||||
for(unsigned int i = 0; i < sizeof(val) * 8; ++i, val >>= 1) {
|
||||
ret.push_back(val & 0x01);
|
||||
}
|
||||
|
||||
reverse(ret.begin(), ret.end());
|
||||
return ret;
|
||||
}
|
||||
|
||||
std::vector<std::vector<bool>> convertPuzzleToBool(std::vector<uint8_t> puzzle) {
|
||||
std::vector<vector<bool>> new_puzzle;
|
||||
|
||||
for(vector<uint8_t>::iterator it = puzzle.begin(); it != puzzle.end(); ++it) {
|
||||
new_puzzle.insert(new_puzzle.end(), convertIntToVector(*it));
|
||||
}
|
||||
|
||||
return new_puzzle;
|
||||
}
|
||||
|
||||
template<typename ppzksnark_ppT>
|
||||
r1cs_ppzksnark_keypair<ppzksnark_ppT> generate_keypair()
|
||||
{
|
||||
typedef Fr<ppzksnark_ppT> FieldT;
|
||||
|
||||
protoboard<FieldT> pb;
|
||||
l_gadget<FieldT> g(pb, 9);
|
||||
g.generate_r1cs_constraints();
|
||||
const r1cs_constraint_system<FieldT> constraint_system = pb.get_constraint_system();
|
||||
|
||||
cout << "Number of R1CS constraints: " << constraint_system.num_constraints() << endl;
|
||||
|
||||
return r1cs_ppzksnark_generator<ppzksnark_ppT>(constraint_system);
|
||||
}
|
||||
|
||||
template<typename ppzksnark_ppT>
|
||||
boost::optional<r1cs_ppzksnark_proof<ppzksnark_ppT>> generate_proof(r1cs_ppzksnark_proving_key<ppzksnark_ppT> proving_key,
|
||||
vector<uint8_t> &puzzle
|
||||
)
|
||||
{
|
||||
typedef Fr<ppzksnark_ppT> FieldT;
|
||||
|
||||
protoboard<FieldT> pb;
|
||||
l_gadget<FieldT> g(pb, 9);
|
||||
g.generate_r1cs_constraints();
|
||||
|
||||
auto new_puzzle = convertPuzzleToBool(puzzle);
|
||||
|
||||
g.generate_r1cs_witness(new_puzzle);
|
||||
|
||||
if (!pb.is_satisfied()) {
|
||||
return boost::none;
|
||||
}
|
||||
|
||||
return r1cs_ppzksnark_prover<ppzksnark_ppT>(proving_key, pb.primary_input(), pb.auxiliary_input());
|
||||
}
|
||||
|
||||
template<typename ppzksnark_ppT>
|
||||
bool verify_proof(r1cs_ppzksnark_verification_key<ppzksnark_ppT> verification_key,
|
||||
r1cs_ppzksnark_proof<ppzksnark_ppT> proof,
|
||||
vector<uint8_t> &puzzle
|
||||
)
|
||||
{
|
||||
typedef Fr<ppzksnark_ppT> FieldT;
|
||||
|
||||
auto new_puzzle = convertPuzzleToBool(puzzle);
|
||||
|
||||
const r1cs_primary_input<FieldT> input = l_input_map<FieldT>(9, new_puzzle);
|
||||
|
||||
return r1cs_ppzksnark_verifier_strong_IC<ppzksnark_ppT>(verification_key, input, proof);
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
#include <stdlib.h>
|
||||
#include <iostream>
|
||||
|
||||
#include "snark.hpp"
|
||||
#include "test.h"
|
||||
|
||||
using namespace libsnark;
|
||||
using namespace std;
|
||||
|
||||
int main()
|
||||
{
|
||||
// Initialize the curve parameters.
|
||||
default_r1cs_ppzksnark_pp::init_public_params();
|
||||
// Generate the verifying/proving keys. (This is trusted setup!)
|
||||
auto keypair = generate_keypair<default_r1cs_ppzksnark_pp>();
|
||||
|
||||
// Run test vectors.
|
||||
assert(run_test(keypair));
|
||||
}
|
||||
|
||||
bool run_test(r1cs_ppzksnark_keypair<default_r1cs_ppzksnark_pp>& keypair
|
||||
) {
|
||||
vector<uint8_t> v(81, 0);
|
||||
|
||||
cout << "Trying to generate proof..." << endl;
|
||||
auto proof = generate_proof<default_r1cs_ppzksnark_pp>(keypair.pk, v);
|
||||
cout << "Proof generated!" << endl;
|
||||
|
||||
if (!proof) {
|
||||
return false;
|
||||
} else {
|
||||
assert(verify_proof(keypair.vk, *proof, v));
|
||||
return true;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,3 @@
|
|||
|
||||
bool run_test(r1cs_ppzksnark_keypair<default_r1cs_ppzksnark_pp>& keypair
|
||||
);
|
Loading…
Reference in New Issue