Zeth - Zerocash on Ethereum  0.8
Reference implementation of the Zeth protocol by Clearmatics
mpc_phase2_contribute.cpp
Go to the documentation of this file.
1 // Copyright (c) 2015-2022 Clearmatics Technologies Ltd
2 //
3 // SPDX-License-Identifier: LGPL-3.0+
4 
6 #include "mpc_common.hpp"
7 
8 using namespace libzeth;
9 using pp = defaults::pp;
10 namespace po = boost::program_options;
11 
12 namespace
13 {
14 
15 // Usage:
16 // $0 phase2-contribute [<options>] <challenge_file> <response_file>
17 //
18 // Options:
19 // --digest <file> Write contribution hash to file
20 // --skip-user-input Use only system randomness
21 class mpc_phase2_contribute : public mpc_subcommand
22 {
23 private:
24  std::string challenge_file;
25  std::string out_file;
26  std::string digest_file;
27  bool skip_user_input;
28 
29 public:
30  mpc_phase2_contribute()
32  "phase2-contribute",
33  "Create response (MPC contribution) from challenge")
34  , challenge_file()
35  , out_file()
36  , digest_file()
37  , skip_user_input(false)
38  {
39  }
40 
41 private:
42  void initialize_suboptions(
43  po::options_description &options,
44  po::options_description &all_options,
45  po::positional_options_description &pos) override
46  {
47  options.add_options()(
48  "digest",
49  po::value<std::string>(),
50  "Write contribution digest to file")(
51  "skip-user-input", "Use only system randomness");
52  all_options.add(options).add_options()(
53  "challenge_file", po::value<std::string>(), "challenge file")(
54  "response_file", po::value<std::string>(), "response output file");
55  pos.add("challenge_file", 1).add("response_file", 1);
56  }
57 
58  void parse_suboptions(const po::variables_map &vm) override
59  {
60  if (0 == vm.count("challenge_file")) {
61  throw po::error("challenge_file not specified");
62  }
63  if (0 == vm.count("response_file")) {
64  throw po::error("response_file not specified");
65  }
66  challenge_file = vm["challenge_file"].as<std::string>();
67  out_file = vm["response_file"].as<std::string>();
68  digest_file = vm.count("digest") ? vm["digest"].as<std::string>() : "";
69  skip_user_input = (bool)vm.count("skip-user-input");
70  }
71 
72  void subcommand_usage(const char *argv0) override
73  {
74  std::cout << "Usage:\n " << argv0 << " " << subcommand_name
75  << " [<options>] <challenge_file> <response_file>\n\n";
76  }
77 
78  int execute_subcommand(const global_options &options) override
79  {
80  if (options.verbose) {
81  std::cout << "challenge_file: " << challenge_file << "\n";
82  std::cout << "out_file: " << out_file << std::endl;
83  std::cout << "digest: " << digest_file << std::endl;
84  std::cout << "skip_user_input: " << skip_user_input << std::endl;
85  }
86 
87  libff::enter_block("Load challenge file");
89  read_from_file<srs_mpc_phase2_challenge<pp>>(challenge_file);
90  libff::leave_block("Load challenge file");
91 
92  libff::enter_block("Computing randomness");
93  libff::Fr<pp> contribution = get_randomness();
94  libff::leave_block("Computing randomness");
95 
96  libff::enter_block("Computing response");
97  const srs_mpc_phase2_response<pp> response =
98  srs_mpc_phase2_compute_response<pp>(challenge, contribution);
99  libff::leave_block("Computing response");
100 
101  libff::enter_block("Writing response");
102  libff::print_indent();
103  std::cout << out_file << std::endl;
104  {
105  std::ofstream out(out_file);
106  response.write(out);
107  }
108  libff::leave_block("Writing response");
109 
110  mpc_hash_t contrib_digest;
111  response.publickey.compute_digest(contrib_digest);
112  std::cout << "Digest of the contribution was:\n";
113  mpc_hash_write(contrib_digest, std::cout);
114 
115  if (!digest_file.empty()) {
116  std::ofstream out(digest_file);
117  mpc_hash_write(contrib_digest, out);
118  std::cout << "Digest written to: " << digest_file << std::endl;
119  }
120 
121  return 0;
122  }
123 
124  libff::Fr<pp> get_randomness() const
125  {
126  using random_word = std::random_device::result_type;
127 
128  std::random_device rd;
129  mpc_hash_ostream hs;
130  uint64_t buf[4];
131  // The computation below looks (to some compilers) like an attempt to
132  // compute the number of elements in the array 'buf', and generates a
133  // warning. In fact, we want to know how many `std::random_device`
134  // elements to generate, so the calculation is correct. The cast to
135  // `size_t` prevents the compile warning.
136  const size_t buf_size_in_words =
137  sizeof(buf) / (size_t)sizeof(random_word);
138 
139  // 1024 bytes of system randomness,
140  for (size_t i = 0; i < 1024 / sizeof(buf); ++i) {
141  random_word *words = (random_word *)&buf;
142  for (size_t j = 0; j < buf_size_in_words; ++j) {
143  words[j] = rd();
144  }
145  hs.write((const char *)&buf, sizeof(buf));
146  }
147 
148  if (!skip_user_input) {
149  std::cout << "Enter some random text and press [ENTER] ..."
150  << std::endl;
151  std::string user_input;
152  std::getline(std::cin, user_input);
153  hs << user_input;
154  }
155 
156  mpc_hash_t randomness_digest;
157  hs.get_hash(randomness_digest);
158 
159  libff::Fr<pp> random_fp;
160  srs_mpc_digest_to_fp(randomness_digest, random_fp);
161  return random_fp;
162  }
163 };
164 
165 } // namespace
166 
167 mpc_subcommand *mpc_phase2_contribute_cmd = new mpc_phase2_contribute();
mpc_common.hpp
libzeth::srs_mpc_phase2_response::write
void write(std::ostream &out) const
libzeth
Definition: binary_operation.hpp:15
global_options::verbose
bool verbose
Definition: mpc_subcommand.hpp:19
libzeth::srs_mpc_phase2_challenge
Definition: phase2.hpp:110
libzeth::srs_mpc_digest_to_fp
void srs_mpc_digest_to_fp(const mpc_hash_t transcript_digest, libff::Fp_model< n, modulus > &out_fr)
global_options
Definition: mpc_subcommand.hpp:15
mpc_subcommand
libtool::subcommand< global_options > mpc_subcommand
Definition: mpc_subcommand.hpp:22
libzeth::mpc_hash_t
size_t[MPC_HASH_ARRAY_LENGTH] mpc_hash_t
Definition: mpc_hash.hpp:21
pp
defaults::pp pp
Definition: mpc_create_keypair.cpp:14
libzeth::srs_mpc_phase2_response
Definition: phase2.hpp:128
libzeth::hash_ostream::get_hash
void get_hash(typename HashT::OutBuffer out_hash)
libzeth::mpc_hash_write
void mpc_hash_write(const mpc_hash_t hash, std::ostream &out)
Definition: mpc_hash.cpp:53
libzeth::hash_ostream
Simple ostream which hashes any incoming data and discards it.
Definition: hash_stream.hpp:30
phase2.hpp
libzeth::srs_mpc_phase2_response::publickey
srs_mpc_phase2_publickey< ppT > publickey
Definition: phase2.hpp:132
libtool::subcommand
Class representing a tool subcommand.
Definition: subcommand.hpp:18
pp
defaults::pp pp
Definition: mpc_phase2_contribute.cpp:9
mpc_phase2_contribute_cmd
mpc_subcommand * mpc_phase2_contribute_cmd
Definition: mpc_phase2_contribute.cpp:167