#include #include #include #include "ecgadget.hpp" #include "scalarmul.hpp" using namespace libsnark; using namespace std; int main() { // Initialize the curve parameters default_r1cs_gg_ppzksnark_pp::init_public_params(); typedef libff::Fr FieldT; // Create protoboard libff::start_profiling(); cout << "Keypair" << endl; protoboard pb; pb_variable outx, outy; pb_variable accinx, acciny, accoutx, accouty; pb_variable s; // An accumulator initial value. Its DL representation with respect // to C and P should be unknown. const FieldT Ax = FieldT("7536839002660211356286040193441766649532044555061394833845553337792579131020"); const FieldT Ay = FieldT("11391058648720923807988142436733355540810929560298907319389650598553246451302"); FieldT AXSx = Ax; FieldT AXSy = Ay; const FieldT Px = FieldT(0); const FieldT Py = FieldT("11977228949870389393715360594190192321220966033310912010610740966317727761886"); // Allocate variables outx.allocate(pb, "outx"); outy.allocate(pb, "outy"); accinx.allocate(pb, "accinx"); acciny.allocate(pb, "acciny"); accoutx.allocate(pb, "accoutx"); accouty.allocate(pb, "accouty"); s.allocate(pb, "s"); // This sets up the protoboard variables so that the first n of them // represent the public input and the rest is private input pb.set_input_sizes(2); // Initialize the accumulator pb.add_r1cs_constraint(r1cs_constraint(accinx, 1, Ax)); pb.add_r1cs_constraint(r1cs_constraint(acciny, 1, Ay)); // Initialize the gadget ec_constant_scalarmul_gadget sm(pb, accoutx, accouty, accinx, acciny, s, Px, Py, AXSx, AXSy); sm.generate_r1cs_constraints(); // Subtract the accumulator excess to get the result ec_constant_add_gadget ad(pb, outx, outy, accoutx, accouty, AXSx, -AXSy); const r1cs_constraint_system constraint_system = pb.get_constraint_system(); const r1cs_gg_ppzksnark_keypair keypair = r1cs_gg_ppzksnark_generator(constraint_system); // Add witness values cout << "Prover" << endl; pb.val(accinx) = Ax; pb.val(acciny) = Ay; pb.val(s) = FieldT::random_element(); cout << "Computing " << pb.val(s) << "*G" << endl; sm.generate_r1cs_witness(); ad.generate_r1cs_witness(); const r1cs_gg_ppzksnark_proof proof = r1cs_gg_ppzksnark_prover(keypair.pk, pb.primary_input(), pb.auxiliary_input()); cout << "Verifier" << endl; bool verified = r1cs_gg_ppzksnark_verifier_strong_IC(keypair.vk, pb.primary_input(), proof); cout << "Number of R1CS constraints: " << constraint_system.num_constraints() << endl; cout << "Primary (public) input: " << pb.primary_input() << endl; cout << "Auxiliary (private) input length: " << pb.auxiliary_input().size() << endl; //cout << "Auxiliary (private) input: " << pb.auxiliary_input() << endl; cout << "Verification status: " << verified << endl; ofstream pkfile("pk_scalarmul"); pkfile << keypair.pk; pkfile.close(); ofstream vkfile("vk_scalarmul"); vkfile << keypair.vk; vkfile.close(); ofstream pffile("proof_scalarmul"); pffile << proof; pffile.close(); cout << pb.val(s) << "*G" << " = (" << pb.val(outx) << ", " << pb.val(outy) << ")" << endl; return 0; }