8 #include <boost/program_options.hpp> 
   13 namespace po = boost::program_options;
 
   28     std::string challenge_0_file;
 
   29     std::string transcript_file;
 
   30     std::string final_challenge_file;
 
   34     mpc_phase2_verify_transcript()
 
   36               "phase2-verify-transcript",
 
   37               "Verify full transcript, check specific contribution")
 
   40         , final_challenge_file()
 
   46     void initialize_suboptions(
 
   47         po::options_description &options,
 
   48         po::options_description &all_options,
 
   49         po::positional_options_description &pos)
 override 
   51         options.add_options()(
 
   53             po::value<std::string>(),
 
   54             "Check that transcript includes contribution digest");
 
   55         all_options.add(options).add_options()(
 
   56             "challenge_0_file", po::value<std::string>(), 
"challenge file")(
 
   57             "transcript_file", po::value<std::string>(), 
"transcript file")(
 
   58             "final_challenge_file",
 
   59             po::value<std::string>(),
 
   60             "final challenge file");
 
   61         pos.add(
"challenge_0_file", 1)
 
   62             .add(
"transcript_file", 1)
 
   63             .add(
"final_challenge_file", 1);
 
   66     void parse_suboptions(
const po::variables_map &vm)
 override 
   68         if (0 == vm.count(
"challenge_0_file")) {
 
   69             throw po::error(
"challenge_0_file not specified");
 
   71         if (0 == vm.count(
"transcript_file")) {
 
   72             throw po::error(
"transcript_file not specified");
 
   74         if (0 == vm.count(
"final_challenge_file")) {
 
   75             throw po::error(
"final_challenge_file not specified");
 
   77         challenge_0_file = vm[
"challenge_0_file"].as<std::string>();
 
   78         transcript_file = vm[
"transcript_file"].as<std::string>();
 
   79         final_challenge_file = vm[
"final_challenge_file"].as<std::string>();
 
   80         digest = vm.count(
"digest") ? vm[
"digest"].as<std::string>() : 
"";
 
   83     void subcommand_usage(
const char *argv0)
 override 
   85         std::cout << 
"Usage:\n  " << argv0 << 
" " << subcommand_name
 
   86                   << 
" \\\n    <challenge_0_file> <transcript_file> " 
   87                      "<final_challenge_file>\n\n";
 
   93             std::cout << 
"challenge_0: " << challenge_0_file << 
"\n" 
   94                       << 
"transcript: " << transcript_file << 
"\n" 
   95                       << 
"final_challenge: " << final_challenge_file
 
  100         libff::enter_block(
"Load challenge_0 file");
 
  102             read_from_file<const srs_mpc_phase2_challenge<pp>>(
 
  104         libff::leave_block(
"Load challenge_0 file");
 
  111                 init_transcript_digest,
 
  115                          init_transcript_digest,
 
  118                 throw std::invalid_argument(
 
  119                     "transcript digest does not match starting challenge");
 
  123         bool check_for_contribution = 
false;
 
  128         if (!digest.empty()) {
 
  129             std::ifstream in(digest, std::ios_base::in);
 
  131                 std::ios_base::eofbit | std::ios_base::badbit |
 
  132                 std::ios_base::failbit);
 
  134                 throw std::invalid_argument(
 
  135                     "could not parse contribution digest");
 
  138             check_for_contribution = 
true;
 
  142         libff::enter_block(
"Verify transcript");
 
  143         libff::G1<pp> final_delta;
 
  147                 transcript_file, std::ios_base::binary | std::ios_base::in);
 
  148             bool transcript_valid = 
false;
 
  149             bool contribution_found = 
false;
 
  150             if (check_for_contribution) {
 
  151                 transcript_valid = srs_mpc_phase2_verify_transcript<pp>(
 
  154                     check_contribution_digest,
 
  157                     final_transcript_digest,
 
  160                 contribution_found = 
true;
 
  161                 transcript_valid = srs_mpc_phase2_verify_transcript<pp>(
 
  166                     final_transcript_digest);
 
  169             if (!transcript_valid) {
 
  170                 std::cerr << 
"Transcript was invalid" << std::endl;
 
  174             if (!contribution_found) {
 
  175                 std::cerr << 
"Specified contribution digest was not found" 
  180         libff::leave_block(
"Verify transcript");
 
  183         libff::enter_block(
"Load phase2 output");
 
  185             read_from_file<const srs_mpc_phase2_challenge<pp>>(
 
  186                 final_challenge_file);
 
  187         libff::leave_block(
"Load phase2 output");
 
  189         libff::enter_block(
"Verify final output");
 
  192                      final_transcript_digest,
 
  194             throw std::invalid_argument(
 
  195                 "invalid transcript digest in final accumulator");
 
  197         if (final_challenge.
accumulator.delta_g1 != final_delta) {
 
  198             throw std::invalid_argument(
 
  199                 "invalid delta_g1 in final accumulator");
 
  203             throw std::invalid_argument(
"accumlators are inconsistent");
 
  205         libff::leave_block(
"Verify final output");
 
  207         std::cout << 
"Transcript OK!" << std::endl;
 
  215     new mpc_phase2_verify_transcript();