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