Skip to content

Commit

Permalink
zeth-tool: replace some boiler-plate with generic code to handle mult…
Browse files Browse the repository at this point in the history
…iple curves / snarks
  • Loading branch information
dtebbs committed May 13, 2021
1 parent a878460 commit 879746f
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 167 deletions.
62 changes: 21 additions & 41 deletions zeth_tool/dump_proof_cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,85 +14,65 @@ namespace zethtool
namespace commands
{

class dump_proof_cmd : public zeth_subcommand
class dump_proof_cmd : public generic_subcommand<dump_proof_cmd>
{
public:
using base_class = generic_subcommand<dump_proof_cmd>;

dump_proof_cmd(
const std::string &subcommand_name, const std::string &description)
: zeth_subcommand(subcommand_name, description)
: base_class(subcommand_name, description)
{
}

protected:
/// Given in the form of a class, in order to be used as a parameter to
/// curve_and_snark_resolver.
template<typename ppT, typename snarkT> class prove_runner
template<typename ppT, typename snarkT>
int execute_generic(const global_options &)
{
public:
static int execute(const std::string &proof_file)
ppT::init_public_params();
libff::inhibit_profiling_info = true;
libff::inhibit_profiling_counters = true;

typename snarkT::proof proof;
{
ppT::init_public_params();
libff::inhibit_profiling_info = true;
libff::inhibit_profiling_counters = true;

typename snarkT::proof proof;
{
std::ifstream in_s =
libtool::open_input_binary_file(proof_file);
snarkT::proof_read_bytes(proof, in_s);
}

snarkT::proof_write_json(proof, std::cout);
std::cout << "\n";
return 0;
std::ifstream in_s = libtool::open_input_binary_file(proof_file);
snarkT::proof_read_bytes(proof, in_s);
}

snarkT::proof_write_json(proof, std::cout);
std::cout << "\n";
return 0;
};

protected:
void initialize_suboptions(
boost::program_options::options_description &options,
boost::program_options::options_description &all_options,
boost::program_options::positional_options_description &pos) override
{
// Options
options.add_options()(
"curve,c",
po::value<std::string>(),
"Curve: alt-bn128, bls12-377 or bw6-761");
options.add_options()(
"snark,s", po::value<std::string>(), "Snark: groth16 or pghr13");
base_class::initialize_suboptions(options, all_options, pos);

all_options.add(options).add_options()(
"proof_file", po::value<std::string>(), "(Output) Proof file");

pos.add("proof_file", 1);
}

void parse_suboptions(
const boost::program_options::variables_map &vm) override
{
base_class::parse_suboptions(vm);

if (vm.count("proof_file") == 0) {
throw po::error("proof_file not specified");
}
proof_file = vm["proof_file"].as<std::string>();

curve = vm.count("curve") ? vm["curve"].as<std::string>() : "alt-bn128";
snark = vm.count("snark") ? vm["snark"].as<std::string>() : "groth16";
}

void subcommand_usage(const char *argv0) override
{
std::cout << "Usage:\n " << argv0 << " dump-proof [proof_file]\n";
}

int execute_subcommand(const global_options &) override
{
return curve_and_snark_resolver<prove_runner>::resolve(
curve, snark, proof_file);
}

std::string proof_file;
std::string curve;
std::string snark;
};

} // namespace commands
Expand Down
106 changes: 40 additions & 66 deletions zeth_tool/prove_cmd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -14,73 +14,60 @@ namespace zethtool
namespace commands
{

class prove_cmd : public zeth_subcommand
class prove_cmd : public generic_subcommand<prove_cmd>
{
public:
using base_class = generic_subcommand<prove_cmd>;

prove_cmd(
const std::string &subcommand_name, const std::string &description)
: zeth_subcommand(subcommand_name, description)
: base_class(subcommand_name, description)
{
}

protected:
/// Given in the form of a class, in order to be used as a parameter to
/// curve_and_snark_resolver.
template<typename ppT, typename snarkT> class prove_runner
template<typename ppT, typename snarkT>
int execute_generic(const global_options &)
{
public:
static int execute(
const std::string &pk_file,
const std::string &assignment_file,
uint16_t num_primary_inputs,
const std::string &proof_file)
ppT::init_public_params();
libff::inhibit_profiling_info = true;
libff::inhibit_profiling_counters = true;

typename snarkT::proving_key proving_key;
{
std::ifstream in_s = libtool::open_input_binary_file(pk_file);
snarkT::proving_key_read_bytes(proving_key, in_s);
}

libsnark::r1cs_primary_input<libff::Fr<ppT>> primary;
libsnark::r1cs_auxiliary_input<libff::Fr<ppT>> auxiliary;
{
std::ifstream in_s =
libtool::open_input_binary_file(assignment_file);
libzeth::r1cs_variable_assignment_read_bytes(
primary, auxiliary, num_primary_inputs, in_s);
}

typename snarkT::proof proof =
snarkT::generate_proof(proving_key, primary, auxiliary);

// Write to output file
std::cout << "Writing proof to file: " << proof_file << "\n";
{
ppT::init_public_params();
libff::inhibit_profiling_info = true;
libff::inhibit_profiling_counters = true;

typename snarkT::proving_key proving_key;
{
std::ifstream in_s = libtool::open_input_binary_file(pk_file);
snarkT::proving_key_read_bytes(proving_key, in_s);
}

libsnark::r1cs_primary_input<libff::Fr<ppT>> primary;
libsnark::r1cs_auxiliary_input<libff::Fr<ppT>> auxiliary;
{
std::ifstream in_s =
libtool::open_input_binary_file(assignment_file);
libzeth::r1cs_variable_assignment_read_bytes(
primary, auxiliary, num_primary_inputs, in_s);
}

typename snarkT::proof proof =
snarkT::generate_proof(proving_key, primary, auxiliary);

// Write to output file
std::cout << "Writing proof to file: " << proof_file << "\n";
{
std::ofstream out_s =
libtool::open_output_binary_file(proof_file);
snarkT::proof_write_bytes(proof, out_s);
}

return 0;
std::ofstream out_s = libtool::open_output_binary_file(proof_file);
snarkT::proof_write_bytes(proof, out_s);
}
};

return 0;
}

protected:
void initialize_suboptions(
boost::program_options::options_description &options,
boost::program_options::options_description &all_options,
boost::program_options::positional_options_description &pos) override
{
// Options
options.add_options()(
"curve,c",
po::value<std::string>(),
"Curve: alt-bn128, bls12-377 or bw6-761");
options.add_options()(
"snark,s", po::value<std::string>(), "Snark: groth16 or pghr13");
base_class::initialize_suboptions(options, all_options, pos);

options.add_options()(
"primary_inputs,p",
po::value<uint16_t>(),
Expand All @@ -101,6 +88,8 @@ class prove_cmd : public zeth_subcommand
void parse_suboptions(
const boost::program_options::variables_map &vm) override
{
base_class::parse_suboptions(vm);

if (vm.count("pk_file") == 0) {
throw po::error("pk_file not specified");
}
Expand All @@ -117,8 +106,6 @@ class prove_cmd : public zeth_subcommand
if (vm.count("primary_inputs")) {
num_primary_inputs = vm["primary_inputs"].as<uint16_t>();
}
curve = vm.count("curve") ? vm["curve"].as<std::string>() : "alt-bn128";
snark = vm.count("snark") ? vm["snark"].as<std::string>() : "groth16";
}

void subcommand_usage(const char *argv0) override
Expand All @@ -129,23 +116,10 @@ class prove_cmd : public zeth_subcommand
<< " prove [pk_file] [assignment_file] [proof_file]\n";
}

int execute_subcommand(const global_options &) override
{
return curve_and_snark_resolver<prove_runner>::resolve(
curve,
snark,
pk_file,
assignment_file,
num_primary_inputs,
proof_file);
}

std::string pk_file;
std::string assignment_file;
std::string proof_file;
uint16_t num_primary_inputs;
std::string curve;
std::string snark;
};

} // namespace commands
Expand Down
69 changes: 69 additions & 0 deletions zeth_tool/tool_common.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,75 @@ class curve_and_snark_resolver
}
};

/// Base class of subcommands with entry points generic over curve and snark.
/// Implementations are expected to implement a public generic
/// `execute_generic` method of the form:
///
/// class my_cmd : generic_subcommand_base<my_cmd>
/// {
/// public:
/// template<typename ppT, typename snarkT> int execute_generic(
/// const global_options &)
/// {
/// ...
/// }
/// }
///
/// along side the usual parsing entry points `initialize_suboptions` and
/// `parse_suboptions`, which MUST call the equivalent methods on this base
/// class.
template<class CommandT> class generic_subcommand : public zeth_subcommand
{
public:
generic_subcommand(
const std::string &subcommand_name, const std::string &description)
: zeth_subcommand(subcommand_name, description)
{
}

protected:
void initialize_suboptions(
boost::program_options::options_description &options,
boost::program_options::options_description &,
boost::program_options::positional_options_description &) override
{
// Options
options.add_options()(
"curve,c",
po::value<std::string>(),
"Curve: alt-bn128, bls12-377 or bw6-761");
options.add_options()(
"snark,s", po::value<std::string>(), "Snark: groth16 or pghr13");
}

void parse_suboptions(
const boost::program_options::variables_map &vm) override
{
curve = vm.count("curve") ? vm["curve"].as<std::string>() : "alt-bn128";
snark = vm.count("snark") ? vm["snark"].as<std::string>() : "groth16";
}

int execute_subcommand(const global_options &options) override
{
return curve_and_snark_resolver<this_caller>::resolve(
curve, snark, this, options);
}

protected:
template<typename ppT, typename snarkT> class this_caller
{
public:
static int execute(
generic_subcommand<CommandT> *that, const global_options &o)
{
return ((CommandT *)that)->template execute_generic<ppT, snarkT>(o);
}
};

std::string curve;
std::string snark;
};

} // namespace zethtool

#endif // __ZETH_TOOL_TOOL_COMMON_HPP__
Loading

0 comments on commit 879746f

Please sign in to comment.