Quellcode durchsuchen

Allow Ptables to be public or private

Private Ptables are more expensive for the prover but cheaper for the
verifier, and public Ptables are the reverse.
Ian Goldberg vor 6 Jahren
Ursprung
Commit
881144454e
2 geänderte Dateien mit 165 neuen und 26 gelöschten Zeilen
  1. 145 19
      ecgadget.hpp
  2. 20 7
      varscalarmul.cpp

+ 145 - 19
ecgadget.hpp

@@ -661,6 +661,9 @@ public:
   }
   }
 };
 };
 
 
+template<typename FieldT>
+class ec_scalarmul_gadget;
+
 // Compute A + s*P as (outx, outy) for an accumulator A, a precomputed
 // Compute A + s*P as (outx, outy) for an accumulator A, a precomputed
 // addition table Ptable for a variable point P, and s given as a bit
 // addition table Ptable for a variable point P, and s given as a bit
 // vector.  The _caller_ is responsible for proving that the elements of
 // vector.  The _caller_ is responsible for proving that the elements of
@@ -669,17 +672,27 @@ public:
 // subtracted from the accumulator A.  The addition table is a variable
 // subtracted from the accumulator A.  The addition table is a variable
 // array of length 2*numbits (where numbits is the length of svec) such
 // array of length 2*numbits (where numbits is the length of svec) such
 // that Ptable[2*i] and Ptable[2*i+1] are the (x,y) coordinates of
 // that Ptable[2*i] and Ptable[2*i+1] are the (x,y) coordinates of
-// 2^i * P + C.
+// 2^i * P + C.  Set Ptable_set_constraints to true (exactly once
+// in the event the same Ptable is reused in the same circuit) if
+// the Ptable is part of the private input.  Set Ptable_fill_values
+// to true exactly once per Ptable (again, in case it it reused in the
+// same circuit).
 template<typename FieldT>
 template<typename FieldT>
 class ec_scalarmul_vec_accum_gadget : public gadget<FieldT> {
 class ec_scalarmul_vec_accum_gadget : public gadget<FieldT> {
 private:
 private:
   FieldT Cx, Cy;
   FieldT Cx, Cy;
   pb_variable_array<FieldT> accumx, accumy;
   pb_variable_array<FieldT> accumx, accumy;
+  pb_variable_array<FieldT> twoiPx, twoiPy;
+  std::vector<ec_constant_add_gadget<FieldT> > cadders;
+  std::vector<ec_add_gadget<FieldT> > adders;
   std::vector<ec_2_1constant_add_gadget<FieldT> > twoadders;
   std::vector<ec_2_1constant_add_gadget<FieldT> > twoadders;
 public:
 public:
   const pb_variable<FieldT> outx, outy;
   const pb_variable<FieldT> outx, outy;
   const pb_variable<FieldT> Ax, Ay;
   const pb_variable<FieldT> Ax, Ay;
-  const pb_variable_array<FieldT> svec, Ptable;
+  const pb_variable_array<FieldT> svec;
+  const pb_variable<FieldT> Px, Py;
+  const pb_variable_array<FieldT> Ptable;
+  bool Ptable_set_constraints, Ptable_fill_values;
 
 
   ec_scalarmul_vec_accum_gadget(protoboard<FieldT> &pb,
   ec_scalarmul_vec_accum_gadget(protoboard<FieldT> &pb,
               const pb_variable<FieldT> &outx,
               const pb_variable<FieldT> &outx,
@@ -687,16 +700,59 @@ public:
               const pb_variable<FieldT> &Ax,
               const pb_variable<FieldT> &Ax,
               const pb_variable<FieldT> &Ay,
               const pb_variable<FieldT> &Ay,
               const pb_variable_array<FieldT> &svec,
               const pb_variable_array<FieldT> &svec,
+              const pb_variable<FieldT> &Px,
+              const pb_variable<FieldT> &Py,
               const pb_variable_array<FieldT> &Ptable,
               const pb_variable_array<FieldT> &Ptable,
+              bool Ptable_set_constraints,
+              bool Ptable_fill_values,
               FieldT &AXSx, FieldT &AXSy) :
               FieldT &AXSx, FieldT &AXSy) :
     gadget<FieldT>(pb, "ec_scalarmul_vec_accum_gadget"),
     gadget<FieldT>(pb, "ec_scalarmul_vec_accum_gadget"),
     // Precomputed coordinates of C
     // Precomputed coordinates of C
     Cx(2),
     Cx(2),
     Cy("4950745124018817972378217179409499695353526031437053848725554590521829916331"),
     Cy("4950745124018817972378217179409499695353526031437053848725554590521829916331"),
-    outx(outx), outy(outy), Ax(Ax), Ay(Ay), svec(svec), Ptable(Ptable)
+    outx(outx), outy(outy), Ax(Ax), Ay(Ay), svec(svec),
+    Px(Px), Py(Py), Ptable(Ptable),
+    Ptable_set_constraints(Ptable_set_constraints),
+    Ptable_fill_values(Ptable_fill_values)
   {
   {
     size_t numbits = svec.size();
     size_t numbits = svec.size();
     assert(Ptable.size() == 2*numbits);
     assert(Ptable.size() == 2*numbits);
+
+    if (Ptable_set_constraints) {
+        // Create the adders to fill the Ptable with the correct values.
+        // Ptable[2*i] and Ptable[2*i+1] are the (x,y) coordinates of
+        // 2^i * P + C.
+        if (numbits > 0) {
+            // Add P and C to get Ptable[0,1] = P+C
+            cadders.emplace_back(this->pb, Ptable[0], Ptable[1],
+                    Px, Py, Cx, Cy);
+        }
+        if (numbits > 1) {
+            // Add P and P+C to get Ptable[2,3] = 2*P+C
+            adders.emplace_back(this->pb, Ptable[2], Ptable[3],
+                    Px, Py, Ptable[0], Ptable[1]);
+        }
+        if (numbits > 2) {
+            twoiPx.allocate(this->pb, numbits-2, "twoiPx");
+            twoiPy.allocate(this->pb, numbits-2, "twoiPy");
+        }
+        for (size_t i = 2; i < numbits; ++i) {
+            // Invariant: twoiP[i] = 2^{i+1} * P
+
+            // Compute 2^{i-1}*P = (2^{i-1}*P + C) - C
+            cadders.emplace_back(this->pb,
+                    twoiPx[i-2], twoiPy[i-2],
+                    Ptable[2*(i-1)], Ptable[2*(i-1)+1],
+                    Cx, -Cy);
+
+            // Compute 2^{i}*P + C = (2^{i-1}*P + C) + (2^{i-1}*P)
+            adders.emplace_back(this->pb,
+                    Ptable[2*i], Ptable[2*i+1],
+                    Ptable[2*i-2], Ptable[2*i-1],
+                    twoiPx[i-2], twoiPy[i-2]);
+        }
+    }
+
     accumx.allocate(this->pb, numbits-1, "accumx");
     accumx.allocate(this->pb, numbits-1, "accumx");
     accumy.allocate(this->pb, numbits-1, "accumy");
     accumy.allocate(this->pb, numbits-1, "accumy");
 
 
@@ -717,6 +773,14 @@ public:
 
 
   void generate_r1cs_constraints()
   void generate_r1cs_constraints()
   {
   {
+    if (Ptable_set_constraints) {
+        for (auto&& gadget : cadders) {
+            gadget.generate_r1cs_constraints();
+        }
+        for (auto&& gadget : adders) {
+            gadget.generate_r1cs_constraints();
+        }
+    }
     for (auto&& gadget : twoadders) {
     for (auto&& gadget : twoadders) {
         gadget.generate_r1cs_constraints();
         gadget.generate_r1cs_constraints();
     }
     }
@@ -724,6 +788,24 @@ public:
 
 
   void generate_r1cs_witness()
   void generate_r1cs_witness()
   {
   {
+    if (Ptable_set_constraints) {
+        // We also have to satisfy the constraints we set
+        size_t numbits = Ptable.size() / 2;
+
+        if (numbits > 0) {
+            cadders[0].generate_r1cs_witness();
+        }
+        if (numbits > 1) {
+            adders[0].generate_r1cs_witness();
+        }
+        for (size_t i = 2; i < numbits; ++i) {
+            cadders[i-1].generate_r1cs_witness();
+            adders[i-1].generate_r1cs_witness();
+        }
+    } else if (Ptable_fill_values) {
+        // We can just compute the Ptable values manually
+        ec_scalarmul_gadget<FieldT>::compute_Ptable(this->pb, Ptable, Px, Py);
+    }
     for (auto&& gadget : twoadders) {
     for (auto&& gadget : twoadders) {
         gadget.generate_r1cs_witness();
         gadget.generate_r1cs_witness();
     }
     }
@@ -738,7 +820,11 @@ public:
 // subtracted from the accumulator A.  The addition table is a variable
 // subtracted from the accumulator A.  The addition table is a variable
 // array of length 2*numbits (where numbits is the length of the FieldT
 // array of length 2*numbits (where numbits is the length of the FieldT
 // size) such that Ptable[2*i] and Ptable[2*i+1] are the (x,y)
 // size) such that Ptable[2*i] and Ptable[2*i+1] are the (x,y)
-// coordinates of 2^i * P + C.
+// coordinates of 2^i * P + C.  Set Ptable_set_constraints to true
+// (exactly once in the event the same Ptable is reused in the same
+// circuit) if the Ptable is part of the private input.  Set
+// Ptable_fill_values to true exactly once per Ptable (again, in case it
+// it reused in the same circuit).
 template<typename FieldT>
 template<typename FieldT>
 class ec_scalarmul_accum_gadget : public gadget<FieldT> {
 class ec_scalarmul_accum_gadget : public gadget<FieldT> {
 private:
 private:
@@ -750,7 +836,9 @@ public:
   const pb_variable<FieldT> outx, outy;
   const pb_variable<FieldT> outx, outy;
   const pb_variable<FieldT> Ax, Ay;
   const pb_variable<FieldT> Ax, Ay;
   const pb_variable<FieldT> s;
   const pb_variable<FieldT> s;
+  const pb_variable<FieldT> Px, Py;
   const pb_variable_array<FieldT> Ptable;
   const pb_variable_array<FieldT> Ptable;
+  bool Ptable_set_constraints, Ptable_fill_values;
 
 
   ec_scalarmul_accum_gadget(protoboard<FieldT> &pb,
   ec_scalarmul_accum_gadget(protoboard<FieldT> &pb,
               const pb_variable<FieldT> &outx,
               const pb_variable<FieldT> &outx,
@@ -758,10 +846,17 @@ public:
               const pb_variable<FieldT> &Ax,
               const pb_variable<FieldT> &Ax,
               const pb_variable<FieldT> &Ay,
               const pb_variable<FieldT> &Ay,
               const pb_variable<FieldT> &s,
               const pb_variable<FieldT> &s,
+              const pb_variable<FieldT> &Px,
+              const pb_variable<FieldT> &Py,
               const pb_variable_array<FieldT> &Ptable,
               const pb_variable_array<FieldT> &Ptable,
+              bool Ptable_set_constraints,
+              bool Ptable_fill_values,
               FieldT &AXSx, FieldT &AXSy) :
               FieldT &AXSx, FieldT &AXSy) :
     gadget<FieldT>(pb, "ec_scalarmul_accum_gadget"),
     gadget<FieldT>(pb, "ec_scalarmul_accum_gadget"),
-    outx(outx), outy(outy), Ax(Ax), Ay(Ay), s(s), Ptable(Ptable)
+    outx(outx), outy(outy), Ax(Ax), Ay(Ay), s(s),
+    Px(Px), Py(Py), Ptable(Ptable),
+    Ptable_set_constraints(Ptable_set_constraints),
+    Ptable_fill_values(Ptable_fill_values)
   {
   {
     // Allocate variables to protoboard
     // Allocate variables to protoboard
     // The strings (like "x") are only for debugging purposes
     // The strings (like "x") are only for debugging purposes
@@ -769,7 +864,9 @@ public:
     size_t numbits = FieldT::num_bits;
     size_t numbits = FieldT::num_bits;
     svec.allocate(this->pb, numbits, "svec");
     svec.allocate(this->pb, numbits, "svec");
     packers.emplace_back(this->pb, svec, s);
     packers.emplace_back(this->pb, svec, s);
-    vecgadget.emplace_back(this->pb, outx, outy, Ax, Ay, svec, Ptable, AXSx, AXSy);
+    vecgadget.emplace_back(this->pb, outx, outy, Ax, Ay, svec,
+        Px, Py, Ptable, Ptable_set_constraints, Ptable_fill_values,
+        AXSx, AXSy);
   }
   }
 
 
   void generate_r1cs_constraints()
   void generate_r1cs_constraints()
@@ -790,7 +887,11 @@ public:
 // responsible for proving that the elements of svec are bits.
 // responsible for proving that the elements of svec are bits.
 // The addition table is a variable array of length 2*numbits (where
 // The addition table is a variable array of length 2*numbits (where
 // numbits is the length of svec) such that Ptable[2*i] and
 // numbits is the length of svec) such that Ptable[2*i] and
-// Ptable[2*i+1] are the (x,y) coordinates of 2^i * P + C.
+// Ptable[2*i+1] are the (x,y) coordinates of 2^i * P + C.  Set
+// Ptable_set_constraints to true (exactly once in the event the same
+// Ptable is reused in the same circuit) if the Ptable is part of the
+// private input.  Set Ptable_fill_values to true exactly once per
+// Ptable (again, in case it it reused in the same circuit).
 template<typename FieldT>
 template<typename FieldT>
 class ec_scalarmul_vec_gadget : public gadget<FieldT> {
 class ec_scalarmul_vec_gadget : public gadget<FieldT> {
 private:
 private:
@@ -801,20 +902,29 @@ private:
 public:
 public:
   const pb_variable<FieldT> outx, outy;
   const pb_variable<FieldT> outx, outy;
   const pb_variable_array<FieldT> svec;
   const pb_variable_array<FieldT> svec;
+  const pb_variable<FieldT> Px, Py;
   const pb_variable_array<FieldT> Ptable;
   const pb_variable_array<FieldT> Ptable;
+  bool Ptable_set_constraints, Ptable_fill_values;
 
 
   ec_scalarmul_vec_gadget(protoboard<FieldT> &pb,
   ec_scalarmul_vec_gadget(protoboard<FieldT> &pb,
               const pb_variable<FieldT> &outx,
               const pb_variable<FieldT> &outx,
               const pb_variable<FieldT> &outy,
               const pb_variable<FieldT> &outy,
               const pb_variable_array<FieldT> &svec,
               const pb_variable_array<FieldT> &svec,
-              const pb_variable_array<FieldT> &Ptable) :
+              const pb_variable<FieldT> &Px,
+              const pb_variable<FieldT> &Py,
+              const pb_variable_array<FieldT> &Ptable,
+              bool Ptable_set_constraints,
+              bool Ptable_fill_values) :
     gadget<FieldT>(pb, "ec_scalarmul_vec_gadget"),
     gadget<FieldT>(pb, "ec_scalarmul_vec_gadget"),
     // Precomputed coordinates of C and A
     // Precomputed coordinates of C and A
     Cx(2),
     Cx(2),
     Cy("4950745124018817972378217179409499695353526031437053848725554590521829916331"),
     Cy("4950745124018817972378217179409499695353526031437053848725554590521829916331"),
     Ax("7536839002660211356286040193441766649532044555061394833845553337792579131020"),
     Ax("7536839002660211356286040193441766649532044555061394833845553337792579131020"),
     Ay("11391058648720923807988142436733355540810929560298907319389650598553246451302"),
     Ay("11391058648720923807988142436733355540810929560298907319389650598553246451302"),
-    outx(outx), outy(outy), svec(svec), Ptable(Ptable)
+    outx(outx), outy(outy), svec(svec),
+    Px(Px), Py(Py), Ptable(Ptable),
+    Ptable_set_constraints(Ptable_set_constraints),
+    Ptable_fill_values(Ptable_fill_values)
   {
   {
     AXSx = Ax;
     AXSx = Ax;
     AXSy = Ay;
     AXSy = Ay;
@@ -823,7 +933,9 @@ public:
     accoutx.allocate(this->pb, "accoutx");
     accoutx.allocate(this->pb, "accoutx");
     accouty.allocate(this->pb, "accouty");
     accouty.allocate(this->pb, "accouty");
 
 
-    scalarmuls.emplace_back(pb, accoutx, accouty, accinx, acciny, svec, Ptable, AXSx, AXSy);
+    scalarmuls.emplace_back(pb, accoutx, accouty, accinx, acciny, svec,
+        Px, Py, Ptable, Ptable_set_constraints, Ptable_fill_values,
+        AXSx, AXSy);
     adders.emplace_back(pb, outx, outy, accoutx, accouty, AXSx, -AXSy);
     adders.emplace_back(pb, outx, outy, accoutx, accouty, AXSx, -AXSy);
   }
   }
 
 
@@ -848,7 +960,11 @@ public:
 // for a variable point P, and s given as a field element.  The addition
 // for a variable point P, and s given as a field element.  The addition
 // table is a variable array of length 2*numbits (where numbits is the
 // table is a variable array of length 2*numbits (where numbits is the
 // length of the FieldT size) such that Ptable[2*i] and Ptable[2*i+1]
 // length of the FieldT size) such that Ptable[2*i] and Ptable[2*i+1]
-// are the (x,y) coordinates of 2^i * P + C.
+// are the (x,y) coordinates of 2^i * P + C.  Set Ptable_set_constraints
+// to true (exactly once in the event the same Ptable is reused in the
+// same circuit) if the Ptable is part of the private input.  Set
+// Ptable_fill_values to true exactly once per Ptable (again, in case it
+// it reused in the same circuit).
 template<typename FieldT>
 template<typename FieldT>
 class ec_scalarmul_gadget : public gadget<FieldT> {
 class ec_scalarmul_gadget : public gadget<FieldT> {
 private:
 private:
@@ -859,15 +975,24 @@ private:
 public:
 public:
   const pb_variable<FieldT> outx, outy;
   const pb_variable<FieldT> outx, outy;
   const pb_variable<FieldT> s;
   const pb_variable<FieldT> s;
+  const pb_variable<FieldT> Px, Py;
   const pb_variable_array<FieldT> Ptable;
   const pb_variable_array<FieldT> Ptable;
+  bool Ptable_set_constraints, Ptable_fill_values;
 
 
   ec_scalarmul_gadget(protoboard<FieldT> &pb,
   ec_scalarmul_gadget(protoboard<FieldT> &pb,
               const pb_variable<FieldT> &outx,
               const pb_variable<FieldT> &outx,
               const pb_variable<FieldT> &outy,
               const pb_variable<FieldT> &outy,
               const pb_variable<FieldT> &s,
               const pb_variable<FieldT> &s,
-              const pb_variable_array<FieldT> &Ptable) :
+              const pb_variable<FieldT> &Px,
+              const pb_variable<FieldT> &Py,
+              const pb_variable_array<FieldT> &Ptable,
+              bool Ptable_set_constraints,
+              bool Ptable_fill_values) :
     gadget<FieldT>(pb, "ec_scalarmul_gadget"),
     gadget<FieldT>(pb, "ec_scalarmul_gadget"),
-    outx(outx), outy(outy), s(s), Ptable(Ptable)
+    outx(outx), outy(outy), s(s),
+    Px(Px), Py(Py), Ptable(Ptable),
+    Ptable_set_constraints(Ptable_set_constraints),
+    Ptable_fill_values(Ptable_fill_values)
   {
   {
     // Allocate variables to protoboard
     // Allocate variables to protoboard
     // The strings (like "x") are only for debugging purposes
     // The strings (like "x") are only for debugging purposes
@@ -875,7 +1000,8 @@ public:
     size_t numbits = FieldT::num_bits;
     size_t numbits = FieldT::num_bits;
     svec.allocate(this->pb, numbits, "svec");
     svec.allocate(this->pb, numbits, "svec");
     packers.emplace_back(this->pb, svec, s);
     packers.emplace_back(this->pb, svec, s);
-    vecgadget.emplace_back(this->pb, outx, outy, svec, Ptable);
+    vecgadget.emplace_back(this->pb, outx, outy, svec,
+        Px, Py, Ptable, Ptable_set_constraints, Ptable_fill_values);
   }
   }
 
 
   void generate_r1cs_constraints()
   void generate_r1cs_constraints()
@@ -894,9 +1020,9 @@ public:
   // of length 2*numbits such that Ptable[2*i] and Ptable[2*i+1] are the
   // of length 2*numbits such that Ptable[2*i] and Ptable[2*i+1] are the
   // (x,y) coordinates of 2^i * P + C.
   // (x,y) coordinates of 2^i * P + C.
   static void compute_Ptable(protoboard<FieldT> &pb,
   static void compute_Ptable(protoboard<FieldT> &pb,
-                pb_variable_array<FieldT> &Ptable,
-                const FieldT &Px,
-                const FieldT &Py)
+                const pb_variable_array<FieldT> &Ptable,
+                const pb_variable<FieldT> &Px,
+                const pb_variable<FieldT> &Py)
   {
   {
     const FieldT Cx(2);
     const FieldT Cx(2);
     const FieldT Cy("4950745124018817972378217179409499695353526031437053848725554590521829916331");
     const FieldT Cy("4950745124018817972378217179409499695353526031437053848725554590521829916331");
@@ -904,8 +1030,8 @@ public:
     assert(Ptable.size() % 2 == 0);
     assert(Ptable.size() % 2 == 0);
     size_t numbits = Ptable.size() / 2;
     size_t numbits = Ptable.size() / 2;
 
 
-    FieldT twoiPx = Px;
-    FieldT twoiPy = Py;
+    FieldT twoiPx = pb.val(Px);
+    FieldT twoiPy = pb.val(Py);
 
 
     for (size_t i = 0; i < numbits; ++i) {
     for (size_t i = 0; i < numbits; ++i) {
         // Invariant: (twoiPx, twoiPy) = 2^i * P
         // Invariant: (twoiPx, twoiPy) = 2^i * P

+ 20 - 7
varscalarmul.cpp

@@ -8,8 +8,15 @@
 using namespace libsnark;
 using namespace libsnark;
 using namespace std;
 using namespace std;
 
 
-int main()
+int main(int argc, char **argv)
 {
 {
+  // Should the Ptable be private or public (arg of "1" = public, "0" = private)
+  bool Ptable_is_private = true;
+
+  if (argc > 1 && atoi(argv[1]) > 0) {
+    Ptable_is_private = false;
+  }
+
   // Initialize the curve parameters
   // Initialize the curve parameters
 
 
   default_r1cs_gg_ppzksnark_pp::init_public_params();
   default_r1cs_gg_ppzksnark_pp::init_public_params();
@@ -24,28 +31,32 @@ int main()
 
 
   protoboard<FieldT> pb;
   protoboard<FieldT> pb;
   pb_variable<FieldT> outx, outy;
   pb_variable<FieldT> outx, outy;
+  pb_variable<FieldT> Px, Py;
   pb_variable<FieldT> s;
   pb_variable<FieldT> s;
   pb_variable_array<FieldT> Ptable;
   pb_variable_array<FieldT> Ptable;
 
 
-  // A variable base point P
-  const FieldT Px = FieldT("1095194319010475832867263440470707690447963461907735667341232728633587089702");
-  const FieldT Py = FieldT("9185463202887631101218413269806857706246311016297504828581985913021301344974");
 
 
   // Allocate variables
   // Allocate variables
 
 
   size_t numbits = FieldT::num_bits;
   size_t numbits = FieldT::num_bits;
   outx.allocate(pb, "outx");
   outx.allocate(pb, "outx");
   outy.allocate(pb, "outy");
   outy.allocate(pb, "outy");
+  Px.allocate(pb, "Px");
+  Py.allocate(pb, "Py");
   Ptable.allocate(pb, 2*numbits, "Ptable");
   Ptable.allocate(pb, 2*numbits, "Ptable");
   s.allocate(pb, "s");
   s.allocate(pb, "s");
 
 
   // This sets up the protoboard variables so that the first n of them
   // This sets up the protoboard variables so that the first n of them
   // represent the public input and the rest is private input
   // represent the public input and the rest is private input
 
 
-  pb.set_input_sizes(2+2*numbits);
+  if (Ptable_is_private) {
+      pb.set_input_sizes(4);
+  } else {
+      pb.set_input_sizes(4+2*numbits);
+  }
 
 
   // Initialize the gadget
   // Initialize the gadget
-  ec_scalarmul_gadget<FieldT> sm(pb, outx, outy, s, Ptable);
+  ec_scalarmul_gadget<FieldT> sm(pb, outx, outy, s, Px, Py, Ptable, Ptable_is_private, true);
   sm.generate_r1cs_constraints();
   sm.generate_r1cs_constraints();
 
 
   const r1cs_constraint_system<FieldT> constraint_system = pb.get_constraint_system();
   const r1cs_constraint_system<FieldT> constraint_system = pb.get_constraint_system();
@@ -57,9 +68,11 @@ int main()
   cout << "Prover" << endl;
   cout << "Prover" << endl;
   
   
   pb.val(s) = FieldT::random_element();
   pb.val(s) = FieldT::random_element();
+  // A variable base point P
+  pb.val(Px) = FieldT("1095194319010475832867263440470707690447963461907735667341232728633587089702");
+  pb.val(Py) = FieldT("9185463202887631101218413269806857706246311016297504828581985913021301344974");
   cout << "Computing " << pb.val(s) << "*G" << endl;
   cout << "Computing " << pb.val(s) << "*G" << endl;
 
 
-  ec_scalarmul_gadget<FieldT>::compute_Ptable(pb, Ptable, Px, Py);
   sm.generate_r1cs_witness();
   sm.generate_r1cs_witness();
 
 
   const r1cs_gg_ppzksnark_proof<default_r1cs_gg_ppzksnark_pp> proof = r1cs_gg_ppzksnark_prover<default_r1cs_gg_ppzksnark_pp>(keypair.pk, pb.primary_input(), pb.auxiliary_input());
   const r1cs_gg_ppzksnark_proof<default_r1cs_gg_ppzksnark_pp> proof = r1cs_gg_ppzksnark_prover<default_r1cs_gg_ppzksnark_pp>(keypair.pk, pb.primary_input(), pb.auxiliary_input());