8000 Parametrizing the circuits by rrtoledo · Pull Request #185 · clearmatics/zeth · GitHub
[go: up one dir, main page]
More Web Proxy on the site http://driver.im/
Skip to content

Parametrizing the circuits #185

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 2 commits into from
Apr 6, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 3 additions & 2 deletions libzeth/circuit_wrapper.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -102,12 +102,13 @@ extended_proof<ppT> circuit_wrapper<

// Compute the sum on the left hand side of the joinsplit
for (size_t i = 0; i < NumInputs; i++) {
lhs_value = binary_addition<64>(lhs_value, inputs[i].note.value());
lhs_value =
binary_addition<ZETH_V_SIZE>(lhs_value, inputs[i].note.value());
}

// Compute the sum on the right hand side of the joinsplit
for (size_t i = 0; i < NumOutputs; i++) {
rhs_value = binary_addition<64>(rhs_value, outputs[i].value());
rhs_value = binary_addition<ZETH_V_SIZE>(rhs_value, outputs[i].value());
}

// [CHECK] Make sure that the balance between rhs and lfh is respected
Expand Down
91 changes: 44 additions & 47 deletions libzeth/circuits/joinsplit.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -35,8 +35,8 @@ private:
// Number of residual bits from packing of hash digests into smaller
// field elements to which are added the public value of size 64 bits
const size_t length_bit_residual =
2 * (ZETH_V_SIZE * 8) +
digest_len_minus_field_cap * (1 + 2 * NumInputs + NumOutputs);
2 * ZETH_V_SIZE +
digest_len_minus_field_cap * (NumInputs + NumOutputs + 1 + NumInputs);
// Number of field elements needed to pack this number of bits
const size_t nb_field_residual =
libff::div_ceil(length_bit_residual, FieldT::capacity());
Expand Down Expand Up @@ -142,17 +142,17 @@ public:
// element(S)] ie, below is the index mapping of the primary input
// elements on the protoboard:
// - Index of the "Root" field element: {0}
// - Index of the "NullifierS" field elements: [1, NumInputs + 1[
// - Index of the "CommitmentS" field elements: [NumInputs + 1,
// NumOutputs + NumInputs + 1[
// - Index of the "h_sig" field element: {NumOutputs + NumInputs +
// 1}
// - Index of the "h_iS" field elements: [NumOutputs + NumInputs + 1
// + 1, NumOutputs + NumInputs + 1 + NumInputs[
// - Index of the "NullifierS" field elements: [1, 1 + NumInputs[
// - Index of the "CommitmentS" field elements: [1 + NumInputs,
// 1 + NumInputs + NumOutputs[
// - Index of the "h_sig" field element: {1 + NumInputs +
// NumOutputs}
// - Index of the "h_iS" field elements: [1 + NumInputs + NumOutputs
// + 1, 1 + NumInputs + NumOutputs + NumInputs[
// - Index of the "Residual field element(S)", ie "v_pub_in",
// "v_pub_out", and bits of previous variables not fitting within
// FieldT::capacity() [NumOutputs + NumInputs + 1 + NumInputs,
// NumOutputs + NumInputs + 1 + NumInputs + nb_field_residual[
// FieldT::capacity() [1 + NumInputs + NumOutputs + NumInputs,
// 1 + NumInputs + NumOutputs + NumInputs + nb_field_residual[

// We first allocate the root
merkle_root.reset(new libsnark::pb_variable<FieldT>);
Expand Down Expand Up @@ -204,7 +204,7 @@ public:
// and value_pub_out take `nb_field_residual` field element(s) to be
// represented
const size_t nb_packed_inputs =
2 * NumInputs + NumOutputs + 1 + nb_field_residual;
NumInputs + NumOutputs + 1 + NumInputs + nb_field_residual;
const size_t nb_inputs = 1 + nb_packed_inputs;
pb.set_input_sizes(nb_inputs);
// ---------------------------------------------------------------
Expand All @@ -213,17 +213,17 @@ public:

// Initialize the digest_variables
phi.reset(new libsnark::digest_variable<FieldT>(
pb, 256, FMT(this->annotation_prefix, " phi")));
pb, ZETH_PHI_SIZE, FMT(this->annotation_prefix, " phi")));
h_sig.reset(new libsnark::digest_variable<FieldT>(
pb, 256, FMT(this->annotation_prefix, " h_sig")));
pb, ZETH_HSIG_SIZE, FMT(this->annotation_prefix, " h_sig")));
for (size_t i = 0; i < NumInputs; i++) {
input_nullifiers[i].reset(new libsnark::digest_variable<FieldT>(
pb,
HashT::get_digest_len(),
FMT(this->annotation_prefix, " input_nullifiers[%zu]", i)));
a_sks[i].reset(new libsnark::digest_variable<FieldT>(
pb,
ZETH_A_SK_SIZE * 8,
ZETH_A_SK_SIZE,
FMT(this->annotation_prefix, " a_sks[%zu]", i)));
h_is[i].reset(new libsnark::digest_variable<FieldT>(
pb,
Expand All @@ -246,13 +246,9 @@ public:

// Allocate the zk_vpub_in and zk_vpub_out
zk_vpub_in.allocate(
pb,
ZETH_V_SIZE * 8,
FMT(this->annotation_prefix, " zk_vpub_in"));
pb, ZETH_V_SIZE, FMT(this->annotation_prefix, " zk_vpub_in"));
zk_vpub_out.allocate(
pb,
ZETH_V_SIZE * 8,
FMT(this->annotation_prefix, " zk_vpub_out"));
pb, ZETH_V_SIZE, FMT(this->annotation_prefix, " zk_vpub_out"));

// Initialize the unpacked input corresponding to the input
// NullifierS
Expand Down Expand Up @@ -284,7 +280,7 @@ public:

// Initialize the unpacked input corresponding to the h_is
for (size_t i = NumOutputs + NumInputs + 1, j = 0;
i < NumOutputs + NumInputs + 1 + NumInputs && j < NumInputs;
i < NumInputs + NumOutputs + 1 + NumInputs && j < NumInputs;
i++, j++) {
unpacked_inputs[i].insert(
unpacked_inputs[i].end(),
Expand All @@ -302,10 +298,10 @@ public:
{
// Filling with the residual bits of the h_is
for (size_t i = 0; i < NumInputs; i++) {
unpacked_inputs[NumOutputs + NumInputs + 1 + NumInputs]
unpacked_inputs[NumInputs + NumOutputs + 1 + NumInputs]
.insert(
unpacked_inputs
[NumOutputs + NumInputs + 1 + NumInputs]
[NumInputs + NumOutputs + 1 + NumInputs]
.end(),
h_is[NumInputs - i - 1]->bits.rbegin(),
h_is[NumInputs - i - 1]->bits.rbegin() +
Expand All @@ -314,10 +310,10 @@ public:

// Filling with the residual bits of the output CommitmentS
for (size_t i = 0; i < NumOutputs; i++) {
unpacked_inputs[NumOutputs + NumInputs + 1 + NumInputs]
unpacked_inputs[NumInputs + NumOutputs + 1 + NumInputs]
.insert(
unpacked_inputs
[NumOutputs + NumInputs + 1 + NumInputs]
[NumInputs + NumOutputs + 1 + NumInputs]
.end(),
output_commitments[NumOutputs - i - 1]
->bits.rbegin(),
Expand All @@ -328,45 +324,46 @@ public:

// Filling with the residual bits of the input NullifierS
for (size_t i = 0; i < NumInputs; i++) {
unpacked_inputs[NumOutputs + NumInputs + 1 + NumInputs]
unpacked_inputs[NumInputs + NumOutputs + 1 + NumInputs]
.insert(
unpacked_inputs
[NumOutputs + NumInputs + 1 + NumInputs]
[NumInputs + NumOutputs + 1 + NumInputs]
.end(),
input_nullifiers[NumInputs - i - 1]->bits.rbegin(),
input_nullifiers[NumInputs - i - 1]->bits.rbegin() +
digest_len_minus_field_cap);
}

// Filling with the residual bits of the h_sig
unpacked_inputs[NumOutputs + NumInputs + 1 + NumInputs].insert(
unpacked_inputs[NumOutputs + NumInputs + 1 + NumInputs]
unpacked_inputs[NumInputs + NumOutputs + 1 + NumInputs].insert(
unpacked_inputs[NumInputs + NumOutputs + 1 + NumInputs]
.end(),
h_sig->bits.rbegin(),
h_sig->bits.rbegin() + digest_len_minus_field_cap);

// Filling with the vpub_out (public value taken out of the mix)
unpacked_inputs[NumOutputs + NumInputs + 1 + NumInputs].insert(
unpacked_inputs[NumOutputs + NumInputs + 1 + NumInputs]
unpacked_inputs[NumInputs + NumOutputs + 1 + NumInputs].insert(
unpacked_inputs[NumInputs + NumOutputs + 1 + NumInputs]
.end(),
zk_vpub_out.rbegin(),
zk_vpub_out.rend());

// Filling with the vpub_in (public value added to the mix)
unpacked_inputs[NumOutputs + NumInputs + 1 + NumInputs].insert(
unpacked_inputs[NumOutputs + NumInputs + 1 + NumInputs]
unpacked_inputs[NumInputs + NumOutputs + 1 + NumInputs].insert(
unpacked_inputs[NumInputs + NumOutputs + 1 + NumInputs]
.end(),
zk_vpub_in.rbegin(),
zk_vpub_in.rend());
}

// [SANITY CHECK]
// The root is a FieldT, hence is not packed
// The size of the packed inputs should be NumInputs + NumOutputs +
// 1 + 1 since we are packing all the inputs nullifiers + all the
// output commitments
// + the two public values v_pub_in and v_pub_out + the h_sig + the
// h_iS.
// The size of the packed inputs should be NumInputs + NumOutputs
// + 1 + NumInputs + 1 since we are packing all the inputs
// nullifiers
// + all the output commitments + the h_sig + the h_iS + the
// residual bits of the previous variables and of the two public
// values v_pub_in and v_pub_out
assert(
packed_inputs.size() ==
NumInputs + NumOutputs + 1 + NumInputs + 1);
Expand All @@ -381,7 +378,7 @@ public:

// [SANITY CHECK] Total size of unpacked inputs
size_t total_size_unpacked_inputs = 0;
for (size_t i = 0; i < NumOutputs + NumInputs + 1 + NumInputs + 1;
for (size_t i = 0; i < NumInputs + NumOutputs + 1 + NumInputs + 1;
i++) {
total_size_unpacked_inputs += unpacked_inputs[i].size();
}
Expand Down Expand Up @@ -449,7 +446,7 @@ public:
} // End of the block dedicated to generate the verifier inputs

zk_total_uint64.allocate(
pb, ZETH_V_SIZE * 8, FMT(this->annotation_prefix, " zk_total"));
pb, ZETH_V_SIZE, FMT(this->annotation_prefix, " zk_total"));

// Input note gadgets for commitments, nullifiers, and spend authority
// as well as PRF gadgets for the h_iS
Expand Down Expand Up @@ -541,7 +538,7 @@ public:

// See: https://github.com/zcash/zcash/issues/854
// Ensure that `left_side` is a 64-bit integer
for (size_t i = 0; i < ZETH_V_SIZE * 8; i++) {
for (size_t i = 0; i < ZETH_V_SIZE; i++) {
libsnark::generate_boolean_r1cs_constraint<FieldT>(
this->pb,
zk_total_uint64[i],
Expand Down Expand Up @@ -599,7 +596,7 @@ public:
// https://stackoverflow.com/questions/13282825/adding-binary-numbers-in-c
bits64 left_side_acc = vpub_in;
for (size_t i = 0; i < NumInputs; i++) {
left_side_acc = binary_addition<ZETH_V_SIZE * 8>(
left_side_acc = binary_addition<ZETH_V_SIZE>(
left_side_acc, inputs[i].note.value());
}

Expand Down Expand Up @@ -650,10 +647,10 @@ public:
}

// Bit-length of vpub_in
acc += ZETH_V_SIZE * 8;
acc += ZETH_V_SIZE;

// Bit-length of vpub_out
acc += ZETH_V_SIZE * 8;
acc += ZETH_V_SIZE;

// Bit-length of h_sig
acc += HashT::get_digest_len();
Expand Down Expand Up @@ -713,9 +710,9 @@ public:
// Residual bits and public values (in and out) aggregated in
// `nb_field_residual` field elements
nb_elements += libff::div_ceil(
2 * (ZETH_V_SIZE * 8) +
2 * ZETH_V_SIZE +
safe_subtraction(HashT::get_digest_len(), FieldT::capacity()) *
(1 + 2 * NumInputs + NumOutputs),
(NumInputs + NumOutputs + 1 + NumInputs),
FieldT::capacity());

return nb_elements;
Expand Down
19 changes: 9 additions & 10 deletions libzeth/circuits/notes/note.tcc
Original file line number Diff line number Diff line change
Expand Up @@ -17,22 +17,22 @@ note_gadget<FieldT>::note_gadget(
{
value.allocate(
pb,
ZETH_V_SIZE * 8,
FMT(this->annotation_prefix, " value")); // ZETH_V_SIZE * 8 = 8 * 8 = 64
ZETH_V_SIZE,
FMT(this->annotation_prefix, " value")); // ZETH_V_SIZE = 64
r.allocate(
pb,
ZETH_R_SIZE * 8,
FMT(this->annotation_prefix, " r")); // ZETH_R_SIZE * 8 = 48 * 8 = 384
ZETH_R_SIZE,
FMT(this->annotation_prefix, " r")); // ZETH_R_SIZE = 384
}

template<typename FieldT> void note_gadget<FieldT>::generate_r1cs_constraints()
{
for (size_t i = 0; i < ZETH_V_SIZE * 8; i++) {
for (size_t i = 0; i < ZETH_V_SIZE; i++) {
libsnark::generate_boolean_r1cs_constraint<FieldT>(
this->pb, value[i], FMT(this->annotation_prefix, " value[%zu]", i));
}

for (size_t i = 0; i < ZETH_R_SIZE * 8; i++) {
for (size_t i = 0; i < ZETH_R_SIZE; i++) {
libsnark::generate_boolean_r1cs_constraint<FieldT>(
this->pb, r[i], FMT(this->annotation_prefix, " r[%zu]", i));
}
Expand All @@ -59,8 +59,8 @@ input_note_gadget<FieldT, HashT, HashTreeT, TreeDepth>::input_note_gadget(
const std::string &annotation_prefix)
: note_gadget<FieldT>(pb, annotation_prefix)
{
// ZETH_RHO_SIZE * 8 = 32 * 8 = 256
rho.allocate(pb, ZETH_RHO_SIZE * 8, " rho");
// ZETH_RHO_SIZE = 256
rho.allocate(pb, ZETH_RHO_SIZE, " rho");
address_bits_va.allocate(
pb, TreeDepth, FMT(this->annotation_prefix, " merkle_tree_depth"));
a_pk.reset(new libsnark::digest_variable<FieldT>(
Expand Down Expand Up @@ -154,8 +154,7 @@ void input_note_gadget<FieldT, HashT, HashTreeT, TreeDepth>::
note_gadget<FieldT>::generate_r1cs_constraints();

// Generate the constraints for the rho 256-bit string
for (size_t i = 0; i < ZETH_RHO_SIZE * 8;
i++) { // ZETH_RHO_SIZE * 8 = 32 * 8 = 256
for (size_t i = 0; i < ZETH_RHO_SIZE; i++) { // ZETH_RHO_SIZE = 256
libsnark::generate_boolean_r1cs_constraint<FieldT>(
this->pb, rho[i], FMT(this->annotation_prefix, " rho"));
}
Expand Down
10 changes: 5 additions & 5 deletions libzeth/test/blake2s_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ namespace
{

// This test corresponds to the first call of the g_primitive of blake2s(b"hello
// world"). As blake2s first formats the input blocks in 32bit words in little
// world"). As blake2s first formats the input blocks in 32-bit words in little
// endian, the inputs of the first g_primitive are "lleh" and "ow o"
// ("hello world" -> "hell" "o wo" "rld" plus padding-> "lleh" "ow o" "dlr" plus
// padding)
Expand Down Expand Up @@ -94,16 +94,16 @@ TEST(TestG, TestTrue)
ZERO);

libsnark::pb_variable_array<FieldT> a2;
a2.allocate(pb, 32, "a2");
a2.allocate(pb, BLAKE2s_word_size, "a2");

libsnark::pb_variable_array<FieldT> b2;
b2.allocate(pb, 32, "b2");
b2.allocate(pb, BLAKE2s_word_size, "b2");

libsnark::pb_variable_array<FieldT> c2;
c2.allocate(pb, 32, "c2");
c2.allocate(pb, BLAKE2s_word_size, "c2");

libsnark::pb_variable_array<FieldT> d2;
d2.allocate(pb, 32, "d2");
d2.allocate(pb, BLAKE2s_word_size, "d2");

g_primitive<FieldT> g_gadget(pb, a, b, c, d, x, y, a2, b2, c2, d2);
g_gadget.generate_r1cs_constraints();
Expand Down
11 changes: 7 additions & 4 deletions libzeth/test/commitments_test.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,9 @@
#include <libsnark/common/default_types/r1cs_gg_ppzksnark_pp.hpp>
#include <libsnark/zk_proof_systems/ppzksnark/r1cs_gg_ppzksnark/r1cs_gg_ppzksnark.hpp>

// Header to get the constants
#include "zeth.h"

// Header to use the merkle tree data structure
#include <libsnark/common/data_structures/merkle_tree.hpp>

Expand Down Expand Up @@ -195,19 +198,19 @@ TEST(TestCOMMs, TestCOMMGadget)

// hex: 0xAF000000000000FF00000000000000FF00000000000000FF00000000000000FF
libsnark::pb_variable_array<FieldT> a_pk;
a_pk.allocate(pb, 256, "a_pk");
a_pk.allocate(pb, ZETH_A_PK_SIZE, "a_pk");
a_pk.fill_with_bits(pb, get_vector_from_bits256(a_pk_bits256));

libsnark::pb_variable_array<FieldT> rho;
rho.allocate(pb, 256, "rho");
rho.allocate(pb, ZETH_RHO_SIZE, "rho");
rho.fill_with_bits(pb, get_vector_from_bits256(rho_bits256));

libsnark::pb_variable_array<FieldT> r;
r.allocate(pb, 384, "r");
r.allocate(pb, ZETH_R_SIZE, "r");
r.fill_with_bits(pb, get_vector_from_bits384(trap_r_bits384));

libsnark::pb_variable_array<FieldT> v;
v.allocate(pb, 64, "v");
v.allocate(pb, ZETH_V_SIZE, "v");
v.fill_with_bits(pb, get_vector_from_bits64(value_bits64));

std::shared_ptr<libsnark::digest_variable<FieldT>> result;
Expand Down
Loading
0