Clearmatics Libsnark  0.1
C++ library for zkSNARK proofs
tutorial.cpp
Go to the documentation of this file.
1 
13 #include "depends/gtest/googletest/include/gtest/gtest.h"
14 
19 
20 namespace gadgetExamples
21 {
22 
23 using namespace gadgetlib2;
24 
25 /*
26  This test gives the first example of a construction of a constraint system.
27  We use the terms 'Constraint System' and 'Circuit' interchangeably rather
28  loosely. It is easy to visualize a circuit with inputs and outputs. Each gate
29  imposes some logic on the inputs and output wires. For instance, AND(inp1,
30  inp2) will impose the 'constraint' (inp1 & inp2 = out) Thus, we can also
31  think of this circuit as a system of constraints. Each gate is a mathematical
32  constraint and each wire is a variable. In the AND example over a boolean
33  field {0,1} we would write the constraint as (inp1 * inp2 == out). This
34  constraint is 'satisfied' relative to an assignment if we assign values to
35  {inp1, inp2, out} such that the constraint evaluates to TRUE. All following
36  examples will be either field agnostic or of a specific form of prime fields:
37  (1) Field agnostic case: In these examples we create high level circuits by
38  using lower level circuits. This way we can ignore the specifics of a field
39  and assume the lower level takes care of this. If we must explicitly write
40  constraints in these circuits, they will always be very basic constraints
41  which are defined over every field (e.g. x + y = 0). (2) All field specific
42  examples in this library are for a prime characteristic field with the
43  special form of 'quadratic rank 1 polynomials', or R1P. This is the only
44  form used with the current implementation of SNARKs. The form for these
45  constraints is (Linear Combination) * (Linear Combination) == (Linear
46  Combination). The library has been designed to allow future addition of other
47  characteristics/forms in the future by implementing only low level circuits
48  for these forms.
49 */
50 TEST(Examples, ProtoboardUsage)
51 {
52  // Initialize prime field parameters. This is always needed for R1P.
54  // The protoboard is the 'memory manager' which holds all constraints (when
55  // creating the verifying circuit) and variable assignments (when creating
56  // the proof witness). We specify the type as R1P, this can be augmented in
57  // the future to allow for BOOLEAN or GF2_EXTENSION fields in the future.
59  // We now create 3 input variables and one output
60  VariableArray input(3, "input");
61  Variable output("output");
62  // We can now add some constraints. The string is for debugging purposes and
63  // can be a textual description of the constraint
64  pb->addRank1Constraint(
65  input[0],
66  5 + input[2],
67  output,
68  "Constraint 1: input[0] * (5 + input[2]) == output");
69  // The second form addUnaryConstraint(LinearCombination) means
70  // (LinearCombination == 0).
71  pb->addUnaryConstraint(
72  input[1] - output, "Constraint 2: input[1] - output == 0");
73  // Notice this could also have been written:
74  // pb->addRank1Constraint(1, input[1] - input[2], 0, "");
75  //
76  // For fields with more general forms, once implemented, we could use
77  // addGeneralConstraint(Polynomial1, Polynomial2, string) which translates
78  // to the constraint (Polynomial1 == Polynomial2). Example:
79  // pb->addGeneralConstraint(input[0] * (3 + input[1]) * input[2], output +
80  // 5,
81  // "input[0] * (3 + input[1]) * input[2] == output
82  // + 5");
83  //
84  // Now we can assign values to the variables and see if the constraints are
85  // satisfied. Later, when we will run a SNARK (or any other proof system),
86  // the constraints will be used by the verifier, and the assigned values
87  // will be used by the prover. Notice the protoboard stores the assignment
88  // values.
89  pb->val(input[0]) = pb->val(input[1]) = pb->val(input[2]) =
90  pb->val(output) = 42;
91  EXPECT_FALSE(pb->isSatisfied());
92  // The constraint system is not satisfied. Now let's try values which
93  // satisfy the two equations above:
94  pb->val(input[0]) = 1;
95  pb->val(input[1]) = pb->val(output) = 42; // input[1] - output == 0
96  pb->val(input[2]) = 37; // 1 * (5 + 37) == 42
97  EXPECT_TRUE(pb->isSatisfied());
98 }
99 
100 /*
101  In the above example we explicitly wrote all constraints and assignments.
102 
103  In this example we will construct a very simple gadget, one that implements
104  a NAND gate. This gadget is field-agnostic as it only uses lower level
105  gadgets and the field elements '0' & '1'.
106 
107  Gadgets are the framework which allow us to delegate construction of
108  sophisticated circuitry to lower levels. Each gadget can construct a
109  constraint system or a witness or both, by defining constraints and
110  assignments as well as by utilizing sub-gadgets.
111 */
112 
113 class NAND_Gadget : public Gadget
114 {
115 public:
116  // This is a convention we use to always create gadgets as if from a factory
117  // class. This will be needed later for gadgets which have different
118  // implementations in different fields.
119  static GadgetPtr create(
120  ProtoboardPtr pb,
121  const FlagVariableArray &inputs,
122  const FlagVariable &output);
123  // generateConstraints() is the method which creates all constraints on the
124  // protoboard
125  void generateConstraints();
126  // generateWitness() is the method which generates the witness by assigning
127  // a valid value to each wire in the circuit (variable) and putting this on
128  // the protoboard
129  void generateWitness();
130 
131 private:
132  // constructor is private in order to stick to the convention that gadgets
133  // are created using a create() method. This may not make sense now, but
134  // when dealing with non-field agnostic gadgets it is very convenient to
135  // have a factory class with this convention. Notice the protoboard. This
136  // can be thought of as a 'memory manager' which holds the circuit as the
137  // constraints are being built, and the 'wire values' as the witness is
138  // being built
139  NAND_Gadget(
140  ProtoboardPtr pb,
141  const FlagVariableArray &inputs,
142  const FlagVariable &output);
143  // init() does any non trivial work which we don't want in the constructor.
144  // This is where we will 'wire' the sub-gadgets into the circuit. Each
145  // sub-gadget can be thought of as a circuit gate with some specific
146  // functionality.
147  void init();
148  // we want every gadget to be explicitly constructed
150 
151  // This is an internal gadget. Once a gadget is created it can be used as a
152  // black box gate. We will initialize this pointer to be an AND_Gadget in
153  // the init() method.
154  GadgetPtr andGadget_;
155  // These are internal variables used by the class. They will always include
156  // the variables from the constructor, but can include many more as well.
157  // Notice that almost always the variables can be declared 'const', as these
158  // are local copies of formal variables, and do not change over the span of
159  // the class' lifetime.
160  const VariableArray inputs_;
161  const FlagVariable output_;
162  const FlagVariable andResult_;
163 };
164 
165 // IMPLEMENTATION
166 // Most constructors are trivial and only initialize and assert values.
167 NAND_Gadget::NAND_Gadget(
168  ProtoboardPtr pb,
169  const FlagVariableArray &inputs,
170  const FlagVariable &output)
171  : Gadget(pb), inputs_(inputs), output_(output), andResult_("andResult")
172 {
173 }
174 
175 void NAND_Gadget::init()
176 {
177  // we 'wire' the AND gate.
178  andGadget_ = AND_Gadget::create(pb_, inputs_, andResult_);
179 }
180 
181 // The create() method will usually look like this, for field-agnostic gadgets:
183  ProtoboardPtr pb,
184  const FlagVariableArray &inputs,
185  const FlagVariable &output)
186 {
187  GadgetPtr pGadget(new NAND_Gadget(pb, inputs, output));
188  pGadget->init();
189  return pGadget;
190 }
191 
193 {
194  // we will invoke the AND gate constraint generator
195  andGadget_->generateConstraints();
196  // and add our out negation constraint in order to make this a NAND gate
198  1, 1 - andResult_, output_, "1 * (1 - andResult) = output");
199  // Another way to write the same constraint is:
200  // addUnaryConstraint(1 - andResult_ - output_, "1 - andResult == output");
201  //
202  // At first look, it would seem that this is enough. However, the AND_Gadget
203  // expects all of its inputs to be boolean, a dishonest prover could put
204  // non-boolean inputs, so we must check this here. Notice 'FlagVariable'
205  // means a variable which we intend to hold only '0' or '1', but this is
206  // just a convention (it is a typedef for Variable) and we must enforce it.
207  // Look into the internals of the R1P implementation of AND_Gadget and see
208  // that {2, 1, 0} as inputs with {1} as output would satisfy all
209  // constraints, even though this is clearly not our intent!
210  for (const auto &input : inputs_) {
211  enforceBooleanity(input); // This adds a constraint of the form: input *
212  // (1 - input) == 0
213  }
214 }
215 
217 {
218  // First we can assert that all input values are indeed boolean. The purpose
219  // of this assertion is simply to print a clear error message, it is not
220  // security critical. Notice the method val() which returns a reference to
221  // the current assignment for a variable
222  for (const auto &input : inputs_) {
224  val(input) == 0 || val(input) == 1, "NAND input is not boolean");
225  }
226  // we will invoke the AND gate witness generator, this will set andResult_
227  // correctly
228  andGadget_->generateWitness();
229  // and now we set the value of output_
230  val(output_) = 1 - val(andResult_);
231  // notice the use of 'val()' to tell the protoboard to assign this new value
232  // to the variable 'output_'. The variable itself is only a formal variable
233  // and never changes.
234 }
235 
236 // And now for a test which will exemplify the usage:
237 TEST(Examples, NAND_Gadget)
238 {
239  // initialize the field
241  // create a protoboard for a system of rank 1 constraints over a prime
242  // field.
244  // create 5 variables inputs[0]...inputs[4]. The string "inputs" is used for
245  // debug messages
246  FlagVariableArray inputs(5, "inputs");
247  FlagVariable output("output");
248  GadgetPtr nandGadget = NAND_Gadget::create(pb, inputs, output);
249  // now we can generate a constraint system (or circuit)
250  nandGadget->generateConstraints();
251  // if we try to evaluate the circuit now, an exception will be thrown,
252  // because we will be attempting to evaluate unassigned variables.
253  EXPECT_ANY_THROW(pb->isSatisfied());
254  // so let's assign the input variables for NAND and try again after creating
255  // the witness
256  for (const auto &input : inputs) {
257  pb->val(input) = 1;
258  }
259  nandGadget->generateWitness();
260  EXPECT_TRUE(pb->isSatisfied());
261  EXPECT_TRUE(pb->val(output) == 0);
262  // now let's try to ruin something and see what happens
263  pb->val(inputs[2]) = 0;
264  EXPECT_FALSE(pb->isSatisfied());
265  // now let's try to cheat. If we hadn't enforced booleanity, this would have
266  // worked!
267  pb->val(inputs[1]) = 2;
268  EXPECT_FALSE(pb->isSatisfied());
269  // now let's reset inputs[1] to a valid value
270  pb->val(inputs[1]) = 1;
271  // before, we set both the inputs and the output. Notice the output is still
272  // set to '0'
273  EXPECT_TRUE(pb->val(output) == 0);
274  // Now we will let the gadget compute the result using generateWitness() and
275  // see what happens
276  nandGadget->generateWitness();
277  EXPECT_TRUE(pb->val(output) == 1);
278  EXPECT_TRUE(pb->isSatisfied());
279 }
280 
281 /*
282  Another example showing the use of DualVariable. A DualVariable is a
283  variable which holds both a bitwise representation of a word and a packed
284  representation (e.g. both the packed value {42} and the unpacked value
285  {1,0,1,0,1,0}). If the word is short enough (for example any integer smaller
286  than the prime characteristic) then the packed representation will be stored
287  in 1 field element. 'word' in this context means a set of bits, it is a
288  convention which means we expect some semantic ability to decompose the
289  packed value into its bits. The use of DualVariables is for efficiency
290  reasons. More on this at the end of this example. In this example we will
291  construct a gadget which receives as input a packed integer value called
292  'hash', and a 'difficulty' level in bits, and constructs a circuit validating
293  that the first 'difficulty' bits of 'hash' are '0'. For simplicity we will
294  assume 'hash' is always 64 bits long.
295 */
296 
298 {
299 public:
300  static GadgetPtr create(
301  ProtoboardPtr pb,
302  const MultiPackedWord &hashValue,
303  const size_t difficultyBits);
304  void generateConstraints();
305  void generateWitness();
306 
307 private:
308  const size_t hashSizeInBits_;
309  const size_t difficultyBits_;
310  DualWord hashValue_;
311  // This GadgetPtr will be a gadget to unpack hashValue_ from packed
312  // representation to bit representation. Recall 'DualWord' holds both
313  // values, but only the packed version will be received as input to the
314  // constructor.
315  GadgetPtr hashValueUnpacker_;
316 
318  ProtoboardPtr pb,
319  const MultiPackedWord &hashValue,
320  const size_t difficultyBits);
321  void init();
322  DISALLOW_COPY_AND_ASSIGN(HashDifficultyEnforcer_Gadget);
323 };
324 
325 // IMPLEMENTATION
326 HashDifficultyEnforcer_Gadget::HashDifficultyEnforcer_Gadget(
327  ProtoboardPtr pb,
328  const MultiPackedWord &hashValue,
329  const size_t difficultyBits)
330  : Gadget(pb)
331  , hashSizeInBits_(64)
332  , difficultyBits_(difficultyBits)
333  , hashValue_(hashValue, UnpackedWord(64, "hashValue_u"))
334 {
335 }
336 
337 void HashDifficultyEnforcer_Gadget::init()
338 {
339  // because we are using a prime field with large characteristic, we can
340  // assume a 64 bit value fits in the first element of a multipacked
341  // variable.
343  hashValue_.multipacked().size() == 1,
344  "multipacked word size too large");
345  // A DualWord_Gadget's constraints assert that the unpacked and packed
346  // values represent the same integer element. The generateWitness() method
347  // has two modes, one for packing (taking the bit representation as input)
348  // and one for unpacking (creating the bit representation from the packed
349  // representation)
350  hashValueUnpacker_ =
351  DualWord_Gadget::create(pb_, hashValue_, PackingMode::UNPACK);
352 }
353 
355  ProtoboardPtr pb,
356  const MultiPackedWord &hashValue,
357  const size_t difficultyBits)
358 {
359  GadgetPtr pGadget(
360  new HashDifficultyEnforcer_Gadget(pb, hashValue, difficultyBits));
361  pGadget->init();
362  return pGadget;
363 }
364 
366 {
367  // enforce that both representations are equal
368  hashValueUnpacker_->generateConstraints();
369  // add constraints asserting that the first 'difficultyBits' bits of
370  // 'hashValue' equal 0. Note endianness, unpacked()[0] is LSB and
371  // unpacked()[63] is MSB
372  for (size_t i = 0; i < difficultyBits_; ++i) {
374  hashValue_.unpacked()[63 - i],
375  GADGETLIB2_FMT("hashValue[%u] == 0", 63 - i));
376  }
377 }
378 
380 {
381  // Take the packed representation and unpack to bits.
382  hashValueUnpacker_->generateWitness();
383  // In a real setting we would add an assertion that the value will indeed
384  // satisfy the difficulty constraint, and notify the user with an error
385  // otherwise. As this is a tutorial, we'll let invalid values pass through
386  // so that we can see how isSatisfied() returns false.
387 }
388 
389 // Remember we pointed out that DualVariables are used for efficiency reasons.
390 // Now is the time to elaborate on this. As you've seen, we needed a bit
391 // representation in order to check the first bits of hashValue. But hashValue
392 // may be used in many other places, for instance we may want to check equality
393 // with another value. Checking equality on a packed representation will 'cost'
394 // us 1 constraint, while checking equality on the unpacked value will 'cost' us
395 // 64 constraints. This translates heavily into proof construction time and
396 // memory in the ppzkSNARK proof system.
397 
399 {
401  auto pb = Protoboard::create(R1P);
402  const MultiPackedWord hashValue(64, R1P, "hashValue");
403  const size_t difficulty = 10;
404  auto difficultyEnforcer =
405  HashDifficultyEnforcer_Gadget::create(pb, hashValue, difficulty);
406  difficultyEnforcer->generateConstraints();
407  // constraints are created but no assignment yet. Will throw error on
408  // evaluation
409  EXPECT_ANY_THROW(pb->isSatisfied());
410  pb->val(hashValue[0]) = 42;
411  difficultyEnforcer->generateWitness();
412  // First 10 bits of 42 (when represented as a 64 bit number) are '0' so this
413  // should work
414  EXPECT_TRUE(pb->isSatisfied(PrintOptions::DBG_PRINT_IF_NOT_SATISFIED));
415  pb->val(hashValue[0]) = 1000000000000000000;
416  // This is a value > 2^54 so we expect constraint system not to be
417  // satisfied.
418  difficultyEnforcer
419  ->generateWitness(); // This would have failed had we put an assertion
420  EXPECT_FALSE(pb->isSatisfied());
421 }
422 
423 /*
424  In this example we will construct a gadget which builds a circuit for proof
425  (witness) and validation (constraints) that a bitcoin transaction's sum of
426  inputs equals the sum of outputs + miners fee. Construction of the proof will
427  include finding the miners' fee. This fee can be thought of as an output of
428  the circuit.
429 
430  This is a field specific gadget, as we will use the '+' operator freely. The
431  addition operation works as expected over integers while in prime
432  characteristic fields but not so in extension fields. If you are not familiar
433  with extension fields, don't worry about it. Simply be aware that + and *
434  behave differently in different fields and don't necessarily give the integer
435  values you would expect.
436 
437  The library design supports multiple field constructs due to different
438  applied use cases. Some cryptographic applications may need extension fields
439  while others may need prime fields, but with constraints which are not
440  rank-1, and yet others may need boolean circuits. The library was designed so
441  that high level gadgets can be reused by implementing only the low level for
442  a new field or constraint structure.
443 
444  Later we will supply a recipe for creation of such field specific gadgets
445  with agnostic interfaces. We use a few conventions here in order to ease the
446  process by using macros.
447 */
448 
449 // This is a macro which creates an interface class for all field specific
450 // derived gadgets Convention is: class {GadgetName}_GadgetBase
451 CREATE_GADGET_BASE_CLASS(VerifyTransactionAmounts_GadgetBase);
452 
453 // Notice the multiple inheritance. We must specify the interface as well as the
454 // field specific base gadget. This is what allows the factory class to decide
455 // at compile time which field specific class to instantiate for every
456 // protoboard. See design notes in "gadget.hpp" Convention is: class
457 // {FieldType}_{GadgetName}_Gadget
459  : public VerifyTransactionAmounts_GadgetBase
460  , public R1P_Gadget
461 {
462 public:
463  void generateConstraints();
464  void generateWitness();
465 
466  // We give the factory class friend access in order to instantiate via
467  // private constructor.
469 
470 private:
472  ProtoboardPtr pb,
473  const VariableArray &txInputAmounts,
474  const VariableArray &txOutputAmounts,
475  const Variable &minersFee);
476  void init();
477 
478  const VariableArray txInputAmounts_;
479  const VariableArray txOutputAmounts_;
480  const Variable minersFee_;
481 
483 };
484 
485 // create factory class using CREATE_GADGET_FACTORY_CLASS_XX macro (substitute
486 // XX with the number of arguments to the constructor, excluding the
487 // protoboard). Sometimes we want multiple constructors, see AND_Gadget for
488 // example. In this case we will have to manually write the factory class.
490  VerifyTransactionAmounts_Gadget,
492  txInputAmounts,
494  txOutputAmounts,
495  Variable,
496  minersFee);
497 
498 // IMPLEMENTATION
499 
500 // Destructor for the Base class
501 VerifyTransactionAmounts_GadgetBase::~VerifyTransactionAmounts_GadgetBase() {}
502 
504 {
506  sum(txInputAmounts_) - sum(txOutputAmounts_) - minersFee_,
507  "sum(txInputAmounts) == sum(txOutputAmounts) + minersFee");
508  // It would seem this is enough, but an adversary could cause an overflow of
509  // one side of the equation over the field modulus. In fact, for every
510  // input/output sum we will always find a miners' fee which will satisfy
511  // this constraint! It is left as an exercise for the reader to implement
512  // additional constraints (and witness) to check that each of the amounts
513  // (inputs, outputs, fee) are between 0 and 21,000,000 * 1E8 satoshis.
514  // Combine this with a maximum amount of inputs/outputs to disallow field
515  // overflow.
516  //
517  // Hint: use Comparison_Gadget to create a gadget which compares a
518  // variable's assigned value to a constant. Use a vector of these new
519  // gadgets to check each amount. Don't forget to: (1) Wire these gadgets in
520  // init() (2) Invoke the gadgets' constraints in generateConstraints() (3)
521  // Invoke the gadgets' witnesses in generateWitness()
522 }
523 
525 {
526  FElem sumInputs = 0;
527  FElem sumOutputs = 0;
528  for (const auto &inputAmount : txInputAmounts_) {
529  sumInputs += val(inputAmount);
530  }
531  for (const auto &outputAmount : txOutputAmounts_) {
532  sumOutputs += val(outputAmount);
533  }
534  val(minersFee_) = sumInputs - sumOutputs;
535 }
536 
537 R1P_VerifyTransactionAmounts_Gadget::R1P_VerifyTransactionAmounts_Gadget(
538  ProtoboardPtr pb,
539  const VariableArray &txInputAmounts,
540  const VariableArray &txOutputAmounts,
541  const Variable &minersFee)
542  // Notice we must initialize 3 base classes (diamond inheritance):
543  : Gadget(pb)
544  , VerifyTransactionAmounts_GadgetBase(pb)
545  , R1P_Gadget(pb)
546  , txInputAmounts_(txInputAmounts)
547  , txOutputAmounts_(txOutputAmounts)
548  , minersFee_(minersFee)
549 {
550 }
551 
552 void R1P_VerifyTransactionAmounts_Gadget::init() {}
553 
554 /*
555  As promised, recipe for creating field specific gadgets with agnostic
556  interfaces:
557 
558  (1) Create the Base class using macro:
559  CREATE_GADGET_BASE_CLASS({GadgetName}_GadgetBase);
560  (2) Create the destructor for the base class:
561  {GadgetName_Gadget}Base::~{GadgetName}_GadgetBase() {}
562  (3) Create any field specific gadgets with multiple inheritance:
563  class {FieldType}_{GadgetName}_Gadget : public {GadgetName}_GadgetBase,
564  public {FieldType_Gadget}
565  Notice all arguments to the constructors must be const& in order to use
566  the factory class macro. Constructor arguments must be the same for all field
567  specific implementations. (4) Give the factory class {GadgetName}_Gadget
568  public friend access to the field specific classes. (5) Create the factory
569  class using the macro: CREATE_GADGET_FACTORY_CLASS_XX({GadgetName}_Gadget,
570  type1, input1, type2, input2, ... , typeXX, inputXX);
571 */
572 
574 {
576  auto pb = Protoboard::create(R1P);
577  const VariableArray inputAmounts(2, "inputAmounts");
578  const VariableArray outputAmounts(3, "outputAmounts");
579  const Variable minersFee("minersFee");
580  auto verifyTx = VerifyTransactionAmounts_Gadget::create(
581  pb, inputAmounts, outputAmounts, minersFee);
582  verifyTx->generateConstraints();
583  pb->val(inputAmounts[0]) = pb->val(inputAmounts[1]) = 2;
584  pb->val(outputAmounts[0]) = pb->val(outputAmounts[1]) =
585  pb->val(outputAmounts[2]) = 1;
586  verifyTx->generateWitness();
587  EXPECT_TRUE(pb->isSatisfied());
588  EXPECT_EQ(pb->val(minersFee), 1);
589  pb->val(minersFee) = 3;
590  EXPECT_FALSE(pb->isSatisfied());
591 }
592 
593 /*
594  Below is an example of integrating gadgetlib2 constructed constraint systems
595  with the ppzkSNARK.
596 */
597 
598 TEST(gadgetLib2, Integration)
599 {
601  // Create an example constraint system and translate to libsnark format
604  const bool test_serialization = false;
605  // Run ppzksnark. Jump into function for breakdown
606  const bool bit = libsnark::run_r1cs_ppzksnark<libff::default_ec_pp>(
607  example, test_serialization);
608  EXPECT_TRUE(bit);
609 };
610 
611 } // namespace gadgetExamples
612 
613 int main(int argc, char **argv)
614 {
615  ::testing::InitGoogleTest(&argc, argv);
616  return RUN_ALL_TESTS();
617 }
gadgetExamples::CREATE_GADGET_BASE_CLASS
CREATE_GADGET_BASE_CLASS(VerifyTransactionAmounts_GadgetBase)
gadgetlib2::DualWord
Holds both representations of a word, both multipacked and unpacked.
Definition: variable.hpp:424
gadgetlib2::R1P_Gadget
Definition: gadget.hpp:146
gadgetExamples::HashDifficultyEnforcer_Gadget::generateWitness
void generateWitness()
Definition: tutorial.cpp:379
gadgetExamples::NAND_Gadget
Definition: tutorial.cpp:113
main
int main(int argc, char **argv)
Definition: tutorial.cpp:613
libsnark::r1cs_example
Definition: r1cs_examples.hpp:25
gadgetlib2::GADGETLIB2_FMT
::std::string GADGETLIB2_FMT(const char *format,...)
Definition: infrastructure.cpp:49
gadgetExamples::NAND_Gadget::create
static GadgetPtr create(ProtoboardPtr pb, const FlagVariableArray &inputs, const FlagVariable &output)
Definition: tutorial.cpp:182
gadgetExamples
Definition: tutorial.cpp:20
gadgetExamples::HashDifficultyEnforcer_Gadget
Definition: tutorial.cpp:297
simple_example.hpp
gadgetlib2::Gadget::addRank1Constraint
void addRank1Constraint(const LinearCombination &a, const LinearCombination &b, const LinearCombination &c, const ::std::string &name)
Definition: gadget.cpp:58
gadgetlib2::VariableArray
VariableArray.
Definition: variable.hpp:353
run_r1cs_ppzksnark.hpp
gadgetlib2::MultiPackedWord
Definition: variable.hpp:404
gadgetlib2::Gadget::val
FElem & val(const Variable &var)
Definition: gadget.hpp:109
gadgetlib2::Gadget
Definition: gadget.hpp:81
r1cs_examples.hpp
gadget.hpp
gadgetExamples::CREATE_GADGET_FACTORY_CLASS_3
CREATE_GADGET_FACTORY_CLASS_3(VerifyTransactionAmounts_Gadget, VariableArray, txInputAmounts, VariableArray, txOutputAmounts, Variable, minersFee)
gadgetlib2::FElem
Definition: variable.hpp:101
gadgetlib2::UnpackedWord
Definition: variable.hpp:389
gadgetlib2::DualWord_Gadget::create
static GadgetPtr create(ProtoboardPtr pb, const DualWord &var, PackingMode packingMode)
Definition: gadget.cpp:842
gadgetlib2::GadgetPtr
::std::shared_ptr< Gadget > GadgetPtr
Definition: gadget.hpp:119
DISALLOW_COPY_AND_ASSIGN
#define DISALLOW_COPY_AND_ASSIGN(TypeName)
Definition: infrastructure.hpp:40
gadgetlib2::Gadget::enforceBooleanity
void enforceBooleanity(const Variable &var)
Definition: gadget.hpp:108
gadgetExamples::NAND_Gadget::generateWitness
void generateWitness()
Definition: tutorial.cpp:216
gadgetlib2::initPublicParamsFromDefaultPp
PublicParams initPublicParamsFromDefaultPp()
Definition: pp.cpp:23
gadgetlib2::Protoboard::create
static ProtoboardPtr create(const FieldType &fieldType, ParamsCPtr pParams=NULL)
Definition: protoboard.hpp:54
gadgetlib2::Gadget::addUnaryConstraint
void addUnaryConstraint(const LinearCombination &a, const ::std::string &name)
Definition: gadget.cpp:52
gadgetExamples::TEST
TEST(Examples, ProtoboardUsage)
Definition: tutorial.cpp:50
gadgetExamples::R1P_VerifyTransactionAmounts_Gadget::VerifyTransactionAmounts_Gadget
friend class VerifyTransactionAmounts_Gadget
Definition: tutorial.cpp:468
gadgetlib2::DualWord::multipacked
MultiPackedWord multipacked() const
Definition: variable.hpp:439
gadgetlib2::Variable
A formal variable, field agnostic.
Definition: variable.hpp:306
GADGETLIB_ASSERT
#define GADGETLIB_ASSERT(predicate, msg)
Definition: infrastructure.hpp:94
gadgetlib2::DualWord::unpacked
UnpackedWord unpacked() const
Definition: variable.hpp:440
gadgetExamples::NAND_Gadget::generateConstraints
void generateConstraints()
Definition: tutorial.cpp:192
gadgetlib2::sum
LinearCombination sum(const VariableArray &inputs)
Definition: variable.cpp:616
gadgetExamples::R1P_VerifyTransactionAmounts_Gadget
Definition: tutorial.cpp:458
libsnark::gen_r1cs_example_from_gadgetlib2_protoboard
r1cs_example< libff::Fr< libff::default_ec_pp > > gen_r1cs_example_from_gadgetlib2_protoboard(const size_t size)
Definition: simple_example.cpp:19
gadgetlib2::Gadget::pb_
ProtoboardPtr pb_
Definition: gadget.hpp:87
gadgetExamples::HashDifficultyEnforcer_Gadget::create
static GadgetPtr create(ProtoboardPtr pb, const MultiPackedWord &hashValue, const size_t difficultyBits)
Definition: tutorial.cpp:354
gadgetlib2::ProtoboardPtr
::std::shared_ptr< Protoboard > ProtoboardPtr
Definition: variable.hpp:42
gadgetlib2::AND_Gadget::create
static GadgetPtr create(ProtoboardPtr pb, const VariableArray &input, const Variable &result)
Definition: gadget.cpp:190
gadgetExamples::R1P_VerifyTransactionAmounts_Gadget::generateConstraints
void generateConstraints()
Definition: tutorial.cpp:503
gadgetExamples::HashDifficultyEnforcer_Gadget::generateConstraints
void generateConstraints()
Definition: tutorial.cpp:365
gadgetExamples::R1P_VerifyTransactionAmounts_Gadget::generateWitness
void generateWitness()
Definition: tutorial.cpp:524
gadgetlib2
Definition: adapters.cpp:15
gadgetlib2::R1P
@ R1P
Definition: variable.hpp:37