|
@@ -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());
|
|
|
|