Browse Source

Allow construction of circuits with multiple verifencs at once

Ian Goldberg 4 years ago
parent
commit
7c3b086355
1 changed files with 74 additions and 46 deletions
  1. 74 46
      verifenc.cpp

+ 74 - 46
verifenc.cpp

@@ -33,8 +33,9 @@ private:
 public:
   const Mode mode;
   const pb_variable<FieldT> C1x, C1y, C2x, C2y, Kx, Ky;
-  const pb_variable<FieldT> Px, Py, k, s, y;
+  const pb_variable<FieldT> Px, Py;
   const pb_variable_array<FieldT> Ptable;
+  const pb_variable<FieldT> k, s, y;
 
   verified_encryption_gadget(protoboard<FieldT> &pb,
               Mode mode,
@@ -141,8 +142,9 @@ public:
 int main(int argc, char **argv)
 {
   Mode mode = MODE_NONE;
+  size_t numverifencs = 1;
 
-  if (argc == 2) {
+  if (argc == 2 || argc == 3) {
     if (!strcmp(argv[1], "priv")) {
         mode = MODE_PRIV;
     } else if (!strcmp(argv[1], "pub")) {
@@ -150,13 +152,17 @@ int main(int argc, char **argv)
     } else if (!strcmp(argv[1], "const")) {
         mode = MODE_CONST;
     }
+    if (argc == 3) {
+        numverifencs = atoi(argv[2]);
+    }
   }
-  if (mode == MODE_NONE) {
-    cerr << "Usage: " << argv[0] << " mode" << endl << endl;
+  if (mode == MODE_NONE || numverifencs < 1) {
+    cerr << "Usage: " << argv[0] << " mode n" << endl << endl;
     cerr << "Where mode is one of:" << endl;
     cerr << " priv:  use private Ptable" << endl;
     cerr << " pub:   use public Ptable" << endl;
-    cerr << " const: use constant public key (no Ptable)" << endl;
+    cerr << " const: use constant public key (no Ptable)" << endl << endl;
+    cerr << "and where n is the number of verifencs in the circuit" << endl;
     exit(1);
   }
 
@@ -173,10 +179,12 @@ int main(int argc, char **argv)
   cout << "Keypair" << endl;
 
   protoboard<FieldT> pb;
-  pb_variable<FieldT> C1x, C1y, C2x, C2y, Kx, Ky;
-  pb_variable<FieldT> Px, Py;
-  pb_variable_array<FieldT> Ptable;
-  pb_variable<FieldT> k, s, y, r;
+  pb_variable<FieldT> C1x[numverifencs], C1y[numverifencs];
+  pb_variable<FieldT> C2x[numverifencs], C2y[numverifencs];
+  pb_variable<FieldT> Kx[numverifencs], Ky[numverifencs];
+  pb_variable<FieldT> Px[numverifencs], Py[numverifencs];
+  pb_variable_array<FieldT> Ptable[numverifencs];
+  pb_variable<FieldT> k[numverifencs], s[numverifencs], y[numverifencs];
 
   const size_t numbits = FieldT::num_bits;
 
@@ -184,50 +192,64 @@ int main(int argc, char **argv)
 
   // Public outputs:
 
-  // El Gamal encryption of k under public key P (or H if MODE_CONST)
-  // C1 = r*G, C2 = r*P + M  (where M=(256*k+s,y))
-  C1x.allocate(pb, "C1x");
-  C1y.allocate(pb, "C1y");
-  C2x.allocate(pb, "C2x");
-  C2y.allocate(pb, "C2y");
-
-  // Public key corresponding to private key k
-  // K = k*G
-  Kx.allocate(pb, "Kx");
-  Ky.allocate(pb, "Ky");
-
-  // Public inputs:
+  for (size_t i = 0; i < numverifencs; ++i) {
+      // El Gamal encryption of k under public key P (or H if MODE_CONST)
+      // C1 = r*G, C2 = r*P + M  (where M=(256*k+s,y))
+      C1x[i].allocate(pb, "C1x");
+      C1y[i].allocate(pb, "C1y");
+      C2x[i].allocate(pb, "C2x");
+      C2y[i].allocate(pb, "C2y");
+
+      // Public key corresponding to private key k
+      // K = k*G
+      Kx[i].allocate(pb, "Kx");
+      Ky[i].allocate(pb, "Ky");
+
+      // Public inputs:
+
+      // The public key P (if not MODE_CONST)
+      if (mode != MODE_CONST) {
+        Px[i].allocate(pb, "Px");
+        Py[i].allocate(pb, "Py");
+      }
+  }
 
-  // The public key P (if not MODE_CONST)
   if (mode != MODE_CONST) {
-    Px.allocate(pb, "Px");
-    Py.allocate(pb, "Py");
-
-    // The Ptable might be public or private, according to the mode
-    Ptable.allocate(pb, 2*numbits, "Ptable");
+      for (size_t i = 0; i < numverifencs; ++i) {
+        // The Ptable might be public or private, according to the mode
+        Ptable[i].allocate(pb, 2*numbits, "Ptable");
+      }
   }
 
-  // Private inputs:
-  // k is a 246-bit random number
-  k.allocate(pb, "k");
-  // s and y are such that M = (256*k+s,y) is a point on the curve
-  s.allocate(pb, "s");
-  y.allocate(pb, "y");
+  for (size_t i = 0; i < numverifencs; ++i) {
+      // Private inputs:
+      // k is a 246-bit random number
+      k[i].allocate(pb, "k");
+      // s and y are such that M = (256*k+s,y) is a point on the curve
+      s[i].allocate(pb, "s");
+      y[i].allocate(pb, "y");
+  }
 
   // This sets up the protoboard variables so that the first n of them
   // represent the public input and the rest is private input
 
   if (mode == MODE_PRIV) {
-      pb.set_input_sizes(8);
+      pb.set_input_sizes(8*numverifencs);
   } else if (mode == MODE_PUB) {
-      pb.set_input_sizes(8+2*numbits);
+      pb.set_input_sizes(8*numverifencs+2*numbits*numverifencs);
   } else if (mode == MODE_CONST) {
-      pb.set_input_sizes(6);
+      pb.set_input_sizes(6*numverifencs);
   }
 
   // Initialize the gadgets
-  verified_encryption_gadget<FieldT> venc(pb, mode, C1x, C1y, C2x, C2y, Kx, Ky, Px, Py, Ptable, k, s, y);
-  venc.generate_r1cs_constraints();
+  vector<verified_encryption_gadget<FieldT> > vencs;
+
+  for (size_t i = 0; i < numverifencs; ++i) {
+      vencs.emplace_back(pb, mode, C1x[i], C1y[i], C2x[i], C2y[i], Kx[i], Ky[i], Px[i], Py[i], Ptable[i], k[i], s[i], y[i]);
+  }
+  for (auto&& gadget : vencs) {
+      gadget.generate_r1cs_constraints();
+  }
 
   const r1cs_constraint_system<FieldT> constraint_system = pb.get_constraint_system();
 
@@ -238,15 +260,21 @@ int main(int argc, char **argv)
   cout << "Prover" << endl;
   
   if (mode != MODE_CONST) {
-    // A variable base point P
-    pb.val(Px) = FieldT("1095194319010475832867263440470707690447963461907735667341232728633587089702");
-    pb.val(Py) = FieldT("9185463202887631101218413269806857706246311016297504828581985913021301344974");
+      for (size_t i = 0; i < numverifencs; ++i) {
+        // A variable base point P
+        pb.val(Px[i]) = FieldT("1095194319010475832867263440470707690447963461907735667341232728633587089702");
+        pb.val(Py[i]) = FieldT("9185463202887631101218413269806857706246311016297504828581985913021301344974");
+      }
+  }
+  for (size_t i = 0; i < numverifencs; ++i) {
+      pb.val(k[i]) = FieldT("31329510635628557928212225120518124937732397714111203844965919301557399521");
+      pb.val(s[i]) = FieldT(1);
+      pb.val(y[i]) = FieldT("4364798287654239504994818950156019747851405522689486598132350453516910863367");
   }
-  pb.val(k) = FieldT("31329510635628557928212225120518124937732397714111203844965919301557399521");
-  pb.val(s) = FieldT(1);
-  pb.val(y) = FieldT("4364798287654239504994818950156019747851405522689486598132350453516910863367");
 
-  venc.generate_r1cs_witness();
+  for (auto&& gadget : vencs) {
+      gadget.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());