Skip to content

Commit

Permalink
Merge branch 'staging'
Browse files Browse the repository at this point in the history
  • Loading branch information
tromer committed Jun 11, 2020
2 parents 477c9df + d955a3e commit c6dab2f
Show file tree
Hide file tree
Showing 59 changed files with 659 additions and 94 deletions.
12 changes: 11 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -166,7 +166,7 @@ currently provides three options:
For example, on Fedora 20 at its default settings, you will get the error
`zmInit ERR:can't protect` when running this code. To solve this,
run `sudo setsebool -P allow_execheap 1` to allow execution,
or use `make CURVE=ALT_BN128` instead.
or use `cmake -DCURVE=ALT_BN128` instead.

* "alt_bn128":
an alternative to "bn128", somewhat slower but avoids dynamic code generation.
Expand Down Expand Up @@ -253,6 +253,10 @@ below. (If you port libsnark to additional platforms, please let us know!)

Concretely, here are the requisite packages in some Linux distributions:

* On Debian 10 (buster), Ubuntu 18.04 LTS, Ubuntu 20.04 LTS:

$ sudo apt install build-essential cmake git libgmp3-dev libprocps-dev python3-markdown libboost-program-options-dev libssl-dev python3 pkg-config

* On Ubuntu 16.04 LTS:

$ sudo apt-get install build-essential cmake git libgmp3-dev libprocps4-dev python-markdown libboost-all-dev libssl-dev
Expand All @@ -261,6 +265,10 @@ Concretely, here are the requisite packages in some Linux distributions:

$ sudo apt-get install build-essential cmake git libgmp3-dev libprocps3-dev python-markdown libboost-all-dev libssl-dev

* On Fedora 31:

$ sudo dnf install gcc-c++ cmake make git gmp-devel procps-ng-devel boost-devel openssl-devel python3-markdown

* On Fedora 21 through 23:

$ sudo yum install gcc-c++ cmake make git gmp-devel procps-ng-devel python2-markdown
Expand Down Expand Up @@ -293,6 +301,8 @@ To compile and run the tests for this library, run:

$ make check

For faster build times you might also consider ccache from `ccache` package and using Ninja build system from `ninja-build` package. For the latter CMake invocation above becomes `cmake -GNinja ..`; and instead of `make`/`make check`/etc you should run `ninja`/`ninja check`/etc.

### Using libsnark as a library

To develop an application that uses libsnark, it's recommended to use your own build system that incorporates libsnark and dependencies. If you're using CMake, add libsnark as a git submodule, and then add it as a subdirectory. Then, add `snark` as a library dependency to the appropriate rules.
Expand Down
2 changes: 1 addition & 1 deletion depends/libff
Submodule libff updated 31 files
+9 −5 libff/algebra/curves/alt_bn128/alt_bn128_g1.cpp
+1 −0 libff/algebra/curves/alt_bn128/alt_bn128_g1.hpp
+9 −5 libff/algebra/curves/alt_bn128/alt_bn128_g2.cpp
+1 −0 libff/algebra/curves/alt_bn128/alt_bn128_g2.hpp
+4 −0 libff/algebra/curves/alt_bn128/alt_bn128_init.cpp
+9 −5 libff/algebra/curves/bn128/bn128_g1.cpp
+1 −0 libff/algebra/curves/bn128/bn128_g1.hpp
+9 −5 libff/algebra/curves/bn128/bn128_g2.cpp
+1 −0 libff/algebra/curves/bn128/bn128_g2.hpp
+4 −0 libff/algebra/curves/bn128/bn128_init.cpp
+9 −5 libff/algebra/curves/edwards/edwards_g1.cpp
+1 −0 libff/algebra/curves/edwards/edwards_g1.hpp
+9 −5 libff/algebra/curves/edwards/edwards_g2.cpp
+1 −0 libff/algebra/curves/edwards/edwards_g2.hpp
+2 −1 libff/algebra/curves/edwards/edwards_init.cpp
+9 −5 libff/algebra/curves/mnt/mnt4/mnt4_g1.cpp
+1 −0 libff/algebra/curves/mnt/mnt4/mnt4_g1.hpp
+9 −5 libff/algebra/curves/mnt/mnt4/mnt4_g2.cpp
+1 −0 libff/algebra/curves/mnt/mnt4/mnt4_g2.hpp
+2 −0 libff/algebra/curves/mnt/mnt4/mnt4_init.cpp
+9 −5 libff/algebra/curves/mnt/mnt6/mnt6_g1.cpp
+1 −0 libff/algebra/curves/mnt/mnt6/mnt6_g1.hpp
+9 −5 libff/algebra/curves/mnt/mnt6/mnt6_g2.cpp
+1 −0 libff/algebra/curves/mnt/mnt6/mnt6_g2.hpp
+2 −0 libff/algebra/curves/mnt/mnt6/mnt6_init.cpp
+9 −0 libff/algebra/curves/tests/test_bilinearity.cpp
+9 −0 libff/algebra/curves/tests/test_groups.cpp
+8 −0 libff/algebra/fields/bigint.tcc
+25 −1 libff/algebra/fields/fp.tcc
+10 −1 libff/algebra/fields/tests/test_fields.cpp
+4 −0 libff/algebra/scalar_multiplication/multiexp.tcc
2 changes: 1 addition & 1 deletion depends/libfqfft
Submodule libfqfft updated 1 files
+1 −1 depends/libff
2 changes: 2 additions & 0 deletions libsnark/common/data_structures/merkle_tree.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -29,9 +29,11 @@ typename HashT::hash_value_type two_to_one_CRH(const typename HashT::hash_value_
new_input.insert(new_input.end(), l.begin(), l.end());
new_input.insert(new_input.end(), r.begin(), r.end());

#ifdef DEBUG
const size_t digest_size = HashT::get_digest_len();
assert(l.size() == digest_size);
assert(r.size() == digest_size);
#endif

return HashT::get_hash(new_input);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -443,8 +443,10 @@ void as_waksman_route_inner(const size_t left,
const bool lhs_switch_setting = as_waksman_get_switch_setting_from_top_bottom_decision(lo, permutation_inv.get(to_route), use_top);

/* The value on the left-hand side is either the same or not set. */
#ifdef DEBUG
auto it = routing[left].find(lhs_switch);
assert(it == routing[left].end() || it->second == lhs_switch_setting);
#endif
routing[left][lhs_switch] = lhs_switch_setting;

const size_t t = as_waksman_switch_input(subnetwork_size, lo, rhs_switch, use_top);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -22,18 +22,25 @@ namespace libsnark {
template<typename FieldT>
void ALU_jmp_gadget<FieldT>::generate_r1cs_constraints()
{
/*
Note that instruction fetch semantics require program counter to
be aligned to the double word by rounding down, and pc_addr in
the outer reduction is expressed as a double word address. To
achieve this we just discard the first ap.subaddr_len() bits of
the byte address of the PC.
*/
this->pb.add_r1cs_constraint(
r1cs_constraint<FieldT>(
{ ONE },
{ this->argval2.packed },
{ pb_packing_sum<FieldT>(pb_variable_array<FieldT>(this->argval2.bits.begin() + this->pb.ap.subaddr_len(), this->argval2.bits.end())) },
{ this->result }),
FMT(this->annotation_prefix, " jmp_result"));
}

template<typename FieldT>
void ALU_jmp_gadget<FieldT>::generate_r1cs_witness()
{
this->pb.val(this->result) = this->pb.val(this->argval2.packed);
this->pb.val(this->result) = FieldT(this->pb.val(this->argval2.packed).as_ulong() >> this->pb.ap.subaddr_len());
}

template<typename FieldT>
Expand Down Expand Up @@ -61,7 +68,7 @@ void test_ALU_jmp_gadget()

jmp.generate_r1cs_witness();

assert(pb.val(result) == FieldT(123));
assert(pb.val(result) == FieldT(123 >> ap.subaddr_len()));
assert(pb.is_satisfied());
libff::print_time("positive jmp test successful");

Expand Down Expand Up @@ -129,7 +136,7 @@ void test_ALU_cjmp_gadget()
pb.val(flag) = FieldT(1);
cjmp.generate_r1cs_witness();

assert(pb.val(result) == FieldT(123));
assert(pb.val(result) == FieldT(123 >> ap.subaddr_len()));
assert(pb.is_satisfied());
libff::print_time("positive cjmp test successful");

Expand All @@ -140,7 +147,7 @@ void test_ALU_cjmp_gadget()
pb.val(flag) = FieldT(0);
cjmp.generate_r1cs_witness();

assert(pb.val(result) == FieldT(456+2*ap.w/8));
assert(pb.val(result) == FieldT(456+1));
assert(pb.is_satisfied());
libff::print_time("positive cjmp test successful");

Expand Down Expand Up @@ -208,7 +215,7 @@ void test_ALU_cnjmp_gadget()
pb.val(flag) = FieldT(0);
cnjmp.generate_r1cs_witness();

assert(pb.val(result) == FieldT(123));
assert(pb.val(result) == FieldT(123 >> ap.subaddr_len()));
assert(pb.is_satisfied());
libff::print_time("positive cnjmp test successful");

Expand All @@ -219,7 +226,7 @@ void test_ALU_cnjmp_gadget()
pb.val(flag) = FieldT(1);
cnjmp.generate_r1cs_witness();

assert(pb.val(result) == FieldT(456 + (2*pb.ap.w/8)));
assert(pb.val(result) == FieldT(456 + 1));
assert(pb.is_satisfied());
libff::print_time("positive cnjmp test successful");

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -326,26 +326,31 @@ void tinyram_cpu_checker<FieldT>::generate_r1cs_witness_other(tinyram_input_tape
}

this->pb.val(read_not1) = this->pb.val(opcode_indicators[tinyram_opcode_READ]) * (FieldT::one() - this->pb.val(arg2val->packed));
if (this->pb.val(read_not1) != FieldT::one())
{
/* reading from tape other than 0 raises the flag */
this->pb.val(instruction_flags[tinyram_opcode_READ]) = FieldT::one();
}
else

if (this->pb.val(opcode_indicators[tinyram_opcode_READ]) == FieldT::one())
{
/* otherwise perform the actual read */
if (aux_it != aux_end)
if (this->pb.val(read_not1) != FieldT::zero())
{
this->pb.val(instruction_results[tinyram_opcode_READ]) = FieldT(*aux_it);
if (++aux_it == aux_end)
{
/* tape has ended! */
this->pb.val(next_tape1_exhausted) = FieldT::one();
}
/* reading from tape other than 1 raises the flag */
this->pb.val(instruction_flags[tinyram_opcode_READ]) = FieldT::one();
}
else
{
/* handled above, so nothing to do here */
/* otherwise perform the actual read */
if (aux_it != aux_end)
{
this->pb.val(instruction_results[tinyram_opcode_READ]) = FieldT(*aux_it);
if (++aux_it == aux_end)
{
/* tape has ended! */
this->pb.val(next_tape1_exhausted) = FieldT::one();
}
}
else
{
/* we handled the case of tape exhausted above so
there is nothing further to be done here */
}
}
}

Expand All @@ -372,9 +377,10 @@ void tinyram_cpu_checker<FieldT>::generate_r1cs_witness_other(tinyram_input_tape
template<typename FieldT>
void tinyram_cpu_checker<FieldT>::dump() const
{
printf(" pc = %lu, flag = %lu\n",
this->pb.val(prev_pc_addr_as_word_variable->packed).as_ulong(),
this->pb.val(prev_flag).as_ulong());
printf(" pc_byteaddr = %lu, flag = %lu, tape1_exhausted = %lu\n",
this->pb.val(prev_pc_addr_as_word_variable->packed).as_ulong() << this->pb.ap.subaddr_len(),
this->pb.val(prev_flag).as_ulong(),
this->pb.val(prev_tape1_exhausted).as_ulong());
printf(" ");

for (size_t j = 0; j < this->pb.ap.k; ++j)
Expand All @@ -384,12 +390,68 @@ void tinyram_cpu_checker<FieldT>::dump() const
printf("\n");

const size_t opcode_val = opcode.get_field_element_from_bits(this->pb).as_ulong();
printf(" %s r%lu, r%lu, %s%lu\n",
tinyram_opcode_names[static_cast<tinyram_opcode>(opcode_val)].c_str(),
desidx.get_field_element_from_bits(this->pb).as_ulong(),
arg1idx.get_field_element_from_bits(this->pb).as_ulong(),
(this->pb.val(arg2_is_imm) == FieldT::one() ? "" : "r"),
arg2idx.get_field_element_from_bits(this->pb).as_ulong());

const char* opcode_name = tinyram_opcode_names[static_cast<tinyram_opcode>(opcode_val)].c_str();
const size_t desidx_val = desidx.get_field_element_from_bits(this->pb).as_ulong();
const size_t arg1idx_val = arg1idx.get_field_element_from_bits(this->pb).as_ulong();
const bool is_imm_val = this->pb.val(arg2_is_imm) == FieldT::one();
const size_t arg2idx_val = arg2idx.get_field_element_from_bits(this->pb).as_ulong();

switch (opcode_args[static_cast<tinyram_opcode>(opcode_val)])
{
case tinyram_opcode_args_des_arg1_arg2:
printf(" %s r%lu, r%lu, %s%lu\n", opcode_name, desidx_val, arg1idx_val, (is_imm_val ? "" : "r"), arg2idx_val);
break;
case tinyram_opcode_args_des_arg2:
printf(" %s r%lu, %s%lu\n" , opcode_name, desidx_val, (is_imm_val ? "" : "r"), arg2idx_val);
if (arg1idx_val != 0)
{
printf(" // arg1 = r%lu (should be r0)\n", arg1idx_val);
}
break;
case tinyram_opcode_args_arg1_arg2:
printf(" %s r%lu, %s%lu\n" , opcode_name, arg1idx_val, (is_imm_val ? "" : "r"), arg2idx_val);
if (desidx_val != 0)
{
printf(" // des = r%lu (should be r0)\n", desidx_val);
}
break;
case tinyram_opcode_args_arg2:
printf(" %s %s%lu\n" , opcode_name, (is_imm_val ? "" : "r"), arg2idx_val);
if (desidx_val != 0)
{
printf(" // des = r%lu (should be r0)\n", desidx_val);
}
if (arg1idx_val != 0)
{
printf(" // arg1 = r%lu (should be r0)\n", arg1idx_val);
}
break;
case tinyram_opcode_args_none:
printf(" %s\n" , opcode_name);
if (desidx_val != 0)
{
printf(" // des = r%lu (should be r0)\n", desidx_val);
}
if (arg1idx_val != 0)
{
printf(" // arg1 = r%lu (should be r0)\n", arg1idx_val);
}
if (arg2idx_val != 0 || is_imm_val)
{
printf(" // arg2 = %s%lu (should be 0)\n", (is_imm_val ? "": "r"), arg2idx_val);
}
break;
case tinyram_opcode_args_arg2_des:
printf(" %s %s%lu, r%lu\n" , opcode_name, (is_imm_val ? "" : "r"), arg2idx_val, desidx_val);
if (arg1idx_val != 0)
{
printf(" // arg1 = r%lu (should be r0)\n", arg1idx_val);
}
break;
default:
printf(" (unrecognized opcode type)\n");
}
}

} // libsnark
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ void knapsack_CRH_with_bit_out_gadget<FieldT>::sample_randomness(const size_t in
template<typename FieldT>
void test_knapsack_CRH_with_bit_out_gadget_internal(const size_t dimension, const libff::bit_vector &input_bits, const libff::bit_vector &digest_bits)
{
#ifndef NDEBUG
assert(knapsack_dimension<FieldT>::dimension == dimension);
knapsack_CRH_with_bit_out_gadget<FieldT>::sample_randomness(input_bits.size());
protoboard<FieldT> pb;
Expand All @@ -252,6 +253,12 @@ void test_knapsack_CRH_with_bit_out_gadget_internal(const size_t dimension, cons
const size_t num_constraints = pb.num_constraints();
const size_t expected_constraints = knapsack_CRH_with_bit_out_gadget<FieldT>::expected_constraints();
assert(num_constraints == expected_constraints);
#else // NDEBUG
printf("All tests here depend on assert() which is disabled by -DNDEBUG. Please recompile and run again.\n");
libff::UNUSED(dimension);
libff::UNUSED(input_bits);
libff::UNUSED(digest_bits);
#endif // NDEBUG
}

} // libsnark
Expand Down
4 changes: 4 additions & 0 deletions libsnark/gadgetlib1/gadgets/hashes/sha256/sha256_gadget.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -173,8 +173,12 @@ sha256_two_to_one_hash_gadget<FieldT>::sha256_two_to_one_hash_gadget(protoboard<
const std::string &annotation_prefix) :
gadget<FieldT>(pb, annotation_prefix)
{
#ifndef NDEBUG
assert(block_length == SHA256_block_size);
assert(input_block.bits.size() == block_length);
#else
libff::UNUSED(block_length);
#endif
f.reset(new sha256_compression_function_gadget<FieldT>(pb, SHA256_default_IV<FieldT>(pb), input_block.bits, output, FMT(this->annotation_prefix, " f")));
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -132,6 +132,7 @@ size_t merkle_tree_check_read_gadget<FieldT, HashT>::expected_constraints(const
template<typename FieldT, typename HashT>
void test_merkle_tree_check_read_gadget()
{
#ifndef NDEBUG
/* prepare test */
const size_t digest_len = HashT::get_digest_len();
const size_t tree_depth = 16;
Expand Down Expand Up @@ -189,6 +190,9 @@ void test_merkle_tree_check_read_gadget()
const size_t num_constraints = pb.num_constraints();
const size_t expected_constraints = merkle_tree_check_read_gadget<FieldT, HashT>::expected_constraints(tree_depth);
assert(num_constraints == expected_constraints);
#else // NDEBUG
printf("All tests here depend on assert() which is disabled by -DNDEBUG. Please recompile and run again.\n");
#endif // NDEBUG
}

} // libsnark
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ size_t merkle_tree_check_update_gadget<FieldT, HashT>::expected_constraints(cons
template<typename FieldT, typename HashT>
void test_merkle_tree_check_update_gadget()
{
#ifndef NDEBUG
/* prepare test */
const size_t digest_len = HashT::get_digest_len();

Expand Down Expand Up @@ -258,6 +259,9 @@ void test_merkle_tree_check_update_gadget()
const size_t num_constraints = pb.num_constraints();
const size_t expected_constraints = merkle_tree_check_update_gadget<FieldT, HashT>::expected_constraints(tree_depth);
assert(num_constraints == expected_constraints);
#else // NDEBUG
printf("All tests here depend on assert() which is disabled by -DNDEBUG. Please recompile and run again.\n");
#endif // NDEBUG
}

} // libsnark
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@

using namespace libsnark;

#ifndef NDEBUG

template<typename FieldT>
void dump_constraints(const protoboard<FieldT> &pb)
{
Expand Down Expand Up @@ -374,7 +376,7 @@ void test_full_precomputed_pairing(const std::string &annotation)
printf("number of constraints for full precomputed pairing (Fr is %s) = %zu\n", annotation.c_str(), pb.num_constraints());
}

int main(void)
int main()
{
libff::start_profiling();
libff::mnt4_pp::init_public_params();
Expand Down Expand Up @@ -428,3 +430,11 @@ int main(void)
test_hardcoded_verifier<libff::mnt4_pp, libff::mnt6_pp>("mnt4", "mnt6");
test_hardcoded_verifier<libff::mnt6_pp, libff::mnt4_pp>("mnt6", "mnt4");
}

#else // NDEBUG

int main()
{
printf("All tests here depend on assert() which is disabled by -DNDEBUG. Please recompile and run again.\n");
}
#endif // NDEBUG
4 changes: 2 additions & 2 deletions libsnark/gadgetlib2/infrastructure.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,8 @@ ::std::string GADGETLIB2_FMT(const char* format, ...) {
const int strChk = vsnprintf(buf, MAX_FMT, format, args);
#endif
va_end(args);
GADGETLIB_ASSERT(strChk >= 0 && strChk < MAX_FMT, "String length larger than buffer. Shorten"
" string or increase buffer size defined in \"MAX_FMT\".");
GADGETLIB_ASSERT(strChk >= 0 && (size_t)strChk < MAX_FMT, "String length larger than buffer. Shorten"
" string or increase buffer size defined in \"MAX_FMT\".");
return ::std::string(buf);
}
#else // not DEBUG
Expand Down
2 changes: 1 addition & 1 deletion libsnark/gadgetlib2/variable.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -270,7 +270,7 @@ string Variable::name() const {
FElem Variable::eval(const VariableAssignment& assignment) const {
try {
return assignment.at(*this);
} catch (::std::out_of_range) {
} catch (::std::out_of_range&) {
GADGETLIB_FATAL(GADGETLIB2_FMT("Attempted to evaluate unassigned Variable \"%s\", idx:%lu", name().c_str(),
index_));
}
Expand Down
Loading

0 comments on commit c6dab2f

Please sign in to comment.