Monero
multisig_account.h
Go to the documentation of this file.
1 // Copyright (c) 2021-2022, The Monero Project
2 //
3 // All rights reserved.
4 //
5 // Redistribution and use in source and binary forms, with or without modification, are
6 // permitted provided that the following conditions are met:
7 //
8 // 1. Redistributions of source code must retain the above copyright notice, this list of
9 // conditions and the following disclaimer.
10 //
11 // 2. Redistributions in binary form must reproduce the above copyright notice, this list
12 // of conditions and the following disclaimer in the documentation and/or other
13 // materials provided with the distribution.
14 //
15 // 3. Neither the name of the copyright holder nor the names of its contributors may be
16 // used to endorse or promote products derived from this software without specific
17 // prior written permission.
18 //
19 // THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY
20 // EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
21 // MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL
22 // THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 // SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
24 // PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 // INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT,
26 // STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF
27 // THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
28 
29 #pragma once
30 
31 #include "crypto/crypto.h"
32 #include "multisig_kex_msg.h"
33 
34 #include <cstdint>
35 #include <string>
36 #include <unordered_map>
37 #include <unordered_set>
38 #include <vector>
39 
40 
41 namespace multisig
42 {
79  std::unordered_map<crypto::public_key_memsafe, std::unordered_set<crypto::public_key>>;
80 
81  class multisig_account final
82  {
83  public:
84  //constructors
85  // default constructor
86  multisig_account() = default;
87 
95  multisig_account(const crypto::secret_key &base_privkey,
96  const crypto::secret_key &base_common_privkey);
97 
98  // reconstruct from full account details (not recommended)
99  multisig_account(const std::uint32_t threshold,
100  std::vector<crypto::public_key> signers,
101  const crypto::secret_key &base_privkey,
102  const crypto::secret_key &base_common_privkey,
103  std::vector<crypto::secret_key> multisig_privkeys,
104  const crypto::secret_key &common_privkey,
105  const crypto::public_key &multisig_pubkey,
106  const crypto::public_key &common_pubkey,
107  const std::uint32_t kex_rounds_complete,
108  multisig_keyset_map_memsafe_t kex_origins_map,
109  std::string next_round_kex_message);
110 
111  // copy constructor: default
112 
113  //destructor: default
114  ~multisig_account() = default;
115 
116  //overloaded operators: none
117 
118  //getters
119  // get threshold
121  // get signers
122  const std::vector<crypto::public_key>& get_signers() const { return m_signers; }
123  // get base privkey
125  // get base pubkey
127  // get base common privkey
129  // get multisig privkeys
130  const std::vector<crypto::secret_key>& get_multisig_privkeys() const { return m_multisig_privkeys; }
131  // get common privkey
133  // get multisig pubkey
135  // get common pubkey
137  // get kex rounds complete
139  // get kex keys to origins map
141  // get the kex msg for the next round
143 
144  //account status functions
145  // account has been intialized, and the account holder can use the 'common' key
146  bool account_is_active() const;
147  // account has gone through main kex rounds, only remaining step is to verify all other participants are ready
148  bool main_kex_rounds_done() const;
149  // account is ready to make multisig signatures
150  bool multisig_is_ready() const;
151 
152  //account helpers
153  private:
154  // set the threshold (M) and signers (N)
155  void set_multisig_config(const std::size_t threshold, std::vector<crypto::public_key> signers);
156 
157  //account mutators: key exchange to set up account
158  public:
163  void initialize_kex(const std::uint32_t threshold,
164  std::vector<crypto::public_key> signers,
165  const std::vector<multisig_kex_msg> &expanded_msgs_rnd1);
180  void kex_update(const std::vector<multisig_kex_msg> &expanded_msgs,
181  const bool force_update_use_with_caution = false);
182 
183  private:
184  // implementation of kex_update() (non-transactional)
185  void kex_update_impl(const std::vector<multisig_kex_msg> &expanded_msgs, const bool incomplete_signer_set);
195  void initialize_kex_update(const std::vector<multisig_kex_msg> &expanded_msgs,
196  const std::uint32_t kex_rounds_required,
197  std::vector<crypto::public_key> &exclude_pubkeys_out);
204  void finalize_kex_update(const std::uint32_t kex_rounds_required,
205  multisig_keyset_map_memsafe_t result_keys_to_origins_map);
206 
207  //member variables
208  private:
210  // [M] minimum number of co-signers to sign a message with the aggregate pubkey
212  // [N] base keys of all participants in the multisig (used to initiate key exchange, and as participant ids for msg signing)
213  std::vector<crypto::public_key> m_signers;
214 
216  // base keypair of the participant
217  // - used for signing messages, as the initial base key for key exchange, and to make DH derivations for key exchange
220  // common base privkey, used to produce the aggregate common privkey
222 
224  // the account's private key shares of the multisig address
225  // TODO: also record which other signers have these privkeys, to enable aggregation signing (instead of round-robin)
226  std::vector<crypto::secret_key> m_multisig_privkeys;
227  // a privkey owned by all multisig participants (e.g. a cryptonote view key)
229  // the multisig public key (e.g. a cryptonote spend key)
231  // the common public key (e.g. a view spend key)
233 
235  // number of key exchange rounds that have been completed (all messages for the round collected and processed)
237  // this account's pubkeys for the in-progress key exchange round
238  // - either DH derivations (intermediate rounds), H(derivation)*G (final round), empty (when kex is done)
240  // the account's message for the in-progress key exchange round
242  };
243 
255  std::uint32_t multisig_kex_rounds_required(const std::uint32_t num_signers, const std::uint32_t threshold);
256 
264  std::uint32_t multisig_setup_rounds_required(const std::uint32_t num_signers, const std::uint32_t threshold);
265 } //namespace multisig
std::uint32_t m_kex_rounds_complete
kex variables
Definition: multisig_account.h:236
const std::vector< crypto::public_key > & get_signers() const
Definition: multisig_account.h:122
bool main_kex_rounds_done() const
Definition: multisig_account.cpp:117
void finalize_kex_update(const std::uint32_t kex_rounds_required, multisig_keyset_map_memsafe_t result_keys_to_origins_map)
Definition: multisig_account_kex_impl.cpp:745
std::string m_next_round_kex_message
Definition: multisig_account.h:241
std::vector< crypto::secret_key > m_multisig_privkeys
core multisig account keys
Definition: multisig_account.h:226
::std::string string
Definition: gtest-port.h:1097
crypto::public_key m_base_pubkey
Definition: multisig_account.h:219
const crypto::secret_key & get_base_common_privkey() const
Definition: multisig_account.h:128
const crypto::public_key & get_multisig_pubkey() const
Definition: multisig_account.h:134
crypto::public_key m_common_pubkey
Definition: multisig_account.h:232
void initialize_kex(const std::uint32_t threshold, std::vector< crypto::public_key > signers, const std::vector< multisig_kex_msg > &expanded_msgs_rnd1)
Definition: multisig_account.cpp:169
bool account_is_active() const
Definition: multisig_account.cpp:110
crypto::secret_key m_common_privkey
Definition: multisig_account.h:228
std::uint32_t get_threshold() const
Definition: multisig_account.h:120
unsigned int uint32_t
Definition: stdint.h:126
std::uint32_t multisig_setup_rounds_required(const std::uint32_t num_signers, const std::uint32_t threshold)
Definition: multisig_account.cpp:206
bool multisig_is_ready() const
Definition: multisig_account.cpp:127
const crypto::secret_key & get_common_privkey() const
Definition: multisig_account.h:132
std::uint32_t m_threshold
misc. account details
Definition: multisig_account.h:211
void set_multisig_config(const std::size_t threshold, std::vector< crypto::public_key > signers)
Definition: multisig_account.cpp:137
crypto::public_key m_multisig_pubkey
Definition: multisig_account.h:230
const multisig_keyset_map_memsafe_t & get_kex_keys_to_origins_map() const
Definition: multisig_account.h:140
Definition: multisig_account.h:81
std::vector< crypto::public_key > m_signers
Definition: multisig_account.h:213
POD_CLASS public_key
Definition: crypto.h:61
const crypto::public_key & get_base_pubkey() const
Definition: multisig_account.h:126
std::uint32_t multisig_kex_rounds_required(const std::uint32_t num_signers, const std::uint32_t threshold)
Definition: multisig_account.cpp:197
const crypto::secret_key & get_base_privkey() const
Definition: multisig_account.h:124
void initialize_kex_update(const std::vector< multisig_kex_msg > &expanded_msgs, const std::uint32_t kex_rounds_required, std::vector< crypto::public_key > &exclude_pubkeys_out)
Definition: multisig_account_kex_impl.cpp:687
void kex_update_impl(const std::vector< multisig_kex_msg > &expanded_msgs, const bool incomplete_signer_set)
Definition: multisig_account_kex_impl.cpp:852
crypto::secret_key m_base_privkey
local participant&#39;s personal keys
Definition: multisig_account.h:218
Definition: multisig.cpp:45
const std::vector< crypto::secret_key > & get_multisig_privkeys() const
Definition: multisig_account.h:130
const std::string & get_next_kex_round_msg() const
Definition: multisig_account.h:142
multisig_keyset_map_memsafe_t m_kex_keys_to_origins_map
Definition: multisig_account.h:239
std::uint32_t get_kex_rounds_complete() const
Definition: multisig_account.h:138
const crypto::public_key & get_common_pubkey() const
Definition: multisig_account.h:136
crypto::secret_key m_base_common_privkey
Definition: multisig_account.h:221
void kex_update(const std::vector< multisig_kex_msg > &expanded_msgs, const bool force_update_use_with_caution=false)
Definition: multisig_account.cpp:184
std::unordered_map< crypto::public_key_memsafe, std::unordered_set< crypto::public_key > > multisig_keyset_map_memsafe_t
Definition: multisig_account.h:79