Monero multisignatures explained

Written by exantech | Published 2018/07/04
Tech Story Tags: blockchain | monero | multisignatures-explained | monero-multisignatures | multisignature

TLDRvia the TL;DR App

This text opens a new series in which we will explore the inner workings of various blockchains currently being used by the industry. Today, I’m glad to present you with our first research subject: Monero, the blockchain behind XMR, a fairly well-known, privacy-centered cryptocurrency. Being anonymous, the network implements a number of interesting algorithmic and cryptographic solutions, including multisignature (or simply multisig), a digital signature scheme allowing multiple users to sign documents together as a group.

Although Monero added the support for the multisignature protocol several months ago, there is still a certain lack of information online on how this technology works, so we would like to fill this gap first of all. Since the process of creating a multisignature transaction is rather complicated, we decided to focus only on its most vital aspects, including the processes of creating a wallet and exchanging keys, which we believe is enough to understand the strengths and weaknesses of this technology.

We tried to make the article more readable by ditching off most of the formulas and replacing them with schemes and illustrations, so we hope it will be useful not only to experienced engineers but to beginners as well.

On the Monero blockchain, the multisignature-related features is primarily used to allow for wallets, that have multiple users — which isn’t new, as pretty much the same solution was previously implemented by other digital currencies such as Bitcoin and Ethereum. In a nutshell, it allows for joint ownership of tokens which are being stored in a specific wallet. Joint ownership implies each participant has full rights to the entire amount, so there’s a reasonable limitation on its disposal: every transaction must be authorized by a certain share of participants, which is set out when the wallet is created.

The total number of owners and the approval threshold define the so-called “scheme” of a wallet. For instance, a 3/3 multisig wallet has three owners who have to unanimously approve every transaction, while in case of a 2/3 wallet each owner needs just another vote to transfer funds.

Cryptography

As is the case with most digital currencies, the Monero blockchain relies on elliptical-curve cryptography (learn more on Wikipedia). Simply put, this encryption system is valued for its relative cryptographic strength, smaller key size, and faster execution compared to many of its peers.

Every Monero wallet employs two sets of private and public cryptographic keys, each set being comprised of a “spend key” and a “view key”. Taken together, the public view key and the public spend key of a given wallet make up the address, which is used to receive funds. The same way, adding a private view key to a public spend key will create a tracking key, which your counterparts may use to track the funds being sent to your wallet (but never the other way around, so your privacy remains safe).

As you have probably guessed, the full access to a wallet is secured by a combination of its private spend and private view keys, so your private spend key must be kept in secret.

For the sake of brevity, from here on we will use uppercase letters for public keys (i.e. ‘B’ for ‘public spend key’), and lowercase letters for private keys (i.e. ‘b’ for ‘private spend key’). To help you understand the notation used below, let’s take a look at a short formula showing how a public key is derived from a private key:

where G is a fixed point on the elliptic curve. The multiplication of a private (scalar) key by G yields a public key, which is also a point on the same curve.

Multisignature in Monero

The idea behind the multisig technology is pretty straightforward: having each participant to keep only a part of a wallet’s private spend key, so that transferring funds would require approval by a number of other participants.

It’s nearly impossible for any given participant to gain control over the entire private spend key, while all of them have their own unique public spend keys, as well as copies of both private and public view keys, allowing each participant to monitor the incoming funds.

Creating a multisig wallet in Monero

Currently, the Monero software supports only N/N and N-1/N schemes. To set up an N/N multisig wallet, the users need to complete a single round of calculations, with just one additional step required for the N-1/N scheme. The process of creating a 2/2 wallet is shown in Figure 1.

Figure 1. Creating a 2/2 multisig wallet

Firstly, the participants share all their private view and public spend keys, and then calculate their respective sums. The sum of the private view keys becomes the private view key for the new wallet, with its public view key being derived from the private one. Then, the public spent key is calculated the same way. If the N/N scheme was chosen, that’s all of it. The wallet is now created.

If users opt for the N-1/N scheme, they would still have to share their private view and public spend keys with each other, but then each participant must multiply all public spend keys received by their own private spend key. Thus, a new set of private spend keys is created, which is called “multisignature keys,” as shown in Figure 2.

Figure 2. Creating a 2/3 multisig wallet

You might have noticed that in the figure above, the keys of the same color have the same value. This is because such multisignature keys have one important property expressed by the following equality:

To put it simply, when multiplying a private key by a public key, the indices can be moved as one would like without affecting the result (this is, by the way, the very property of such products that underlies the elliptic curve Diffie–Hellman key exchange protocol). This means that every multisig key is shared between exactly two participants.

To calculate a public spend key, which must be the same for all participants, each of them derives a public key from their respective multisignature key, and shares the result with others. Then the public spend key is calculated by summing the distinct values of all public multisig keys.

Now the participants only have to calculate a view key, which is done the same way as for a 2/2 wallet.

So, now that the wallet is created, let’s move on to looking at how it could be used.

Monero transactions

To explain how to launch a multisig transaction, let’s briefly consider how Monero deals with funds transfer in general. In a very simplified form (not taking into account ring signatures and RingCT), it works like this:

Figure 3. Simplified representation of a transaction

On the right are the transaction outputs, or the money which the transaction generates, and on the left are the inputs, or the money being destroyed when said transaction is complete.

So, when Alice wants to send 1 XMR to Bob, she takes 1 XMR, plus the necessary commission, from her unspent outputs, puts it to her inputs, calculates a key image for each of them, and finally generates outputs for 1 XMR and an output key for each of them.

To complete the transaction, Bob uses his private view and public spend keys to restore the output keys for each output generated by Alice, and if there’s a match between the restored and the incoming keys, he will consider this output as intended for him.

From the network’s point of view, a multisig transaction isn’t in any sense different, although it’s a little bit more complicated to initiate. It’s usually done in several steps:

  • Participants exchange partial key images for all known outputs;
  • Participants re-synchronize their wallets in order to learn its accurate balance taking into account the key images;
  • The sender prepares the transaction, signs it, and sends it over to one of his counterparts;
  • Each subsequent participant adds its own part of the RingCT signature;
  • The last signer completes the creation of RingCT.

Generating key images and sharing outputs

When scanning the blockchain (i.e. during the synchronization), a wallet is unable to determine whether some of the inputs are targeting its outputs, since it does not have the data to calculate key images for them, so it’s safe to say that it only accounts for incoming transactions.

In order to run a transaction correctly, a user needs to restore the key image for each of the outputs, then synchronize with the blockchain to determine which outputs have been spent, and then proceed to generating the transaction. In Figure 4, the process of restoring key images is shown as in case of a 2/3 wallet.

Figure 4. Restoring key images as in case of a 2/3 wallet

Again, to put it simply, the key image for each output is calculated by summing the distinct values of all partial key images. As can be seen from the figure above, this can be done by any two participants out of three, and, most importantly, their private keys remain undisclosed during the transaction, making it impossible for a third party to restore the complete spend key and to seize control over their funds.

With this data, the initiating party can finalize the transaction, which is then sent to all confirmed participants to generate a Ring CT signature. Then, at the final stage, the transaction is signed and broadcast to the network.

Data exchange automation

The above are procedures for exchanging key parts and key images that need to be performed either once, or after each transaction is sent. In the current release of the Monero Core Wallet, these procedures are supposed to be performed manually by exchanging the necessary data on the secure communication channels (i.e. exporting the necessary data from the wallet and sending them via messengers or otherwise).

Here is an example of the procedures required to create a 2/3 wallet and sign a transaction. Each participant performs the following commands using the monero-wallet-cli utility:

[wallet 9uKCgo]: prepare_multisigMultisigV1baCWviNomMXe271W8HW4imh8SsnNEWP2bCswQfoB9MGzNZ8FUG3e8UCNm5toKQzSQH2e8rUWUCGazaCcvej1ToCQYBMovJZYaYiYWQvzsvyWruXycZdVDSsyugjEzwQNK3FUEkug2LXiH91NmekGb7kp9gK9kuoxDDhGn1nLKXUpnXR5

Send this multisig info to all other participants, then use make_multisig <threshold> <info1> [<info2>…] with others’ multisig info.

This includes the PRIVATE view key, so needs to be disclosed only to that multisig wallet’s participants:

[wallet 9uKCgo]: make_multisig 2 MultisigV1XQugvU4JwcwTQbKdH5qGFnavxUX54wGxNis2iN6zoLD94DahnXbyNxH1NQBp2rYRFFJCT2uiJbssHLJYEAb8X1tS5UCqTXYu3FkgRNSZt5mRNgE58iXZHPj839Pbm3ozGcXmRT6GcRMMxMjRonfYKpnPq1UyZSMN7Qr9AYin1gYyoJSh MultisigV1HVqTW8P4UNWUE8QfBaEdwDWJuXBWEPnTrKqVJiUudGG14cHREk9TKmeR9xzSs4wf4jd22mV94C2ehSViApawnpp2SpRqp19eKXLHz2JmNp7eGR6TJMt4VsDTqANRwb1FtD9weef342f5KXDRZK7iQT1MTubyHhEcFyV5aLCjjQ8owMkH

Another step is needed

MultisigxV1PQwytRuYGkB6UEVJ7v2S7q492cwNTdwySXyasToAuQQq73TvM1rBrog5bcYz5w2P6Z4jwKtzrHr7shRGo5mAShvLVbYtBdQNhQsizMb51K7iaWQB4te5mQaiB1cok84CbvA9WKnVpTJGyb7SbS7NwAgmpEhU812RTdzrdHp5sD41duYtRNW6qna5mTMYmtTjAEdKpKCvM6EwhV4ncWscpvoBfyYP

Send this multisig info to all other participants, then use finalize_multisig <info1> [<info2>…] with others’ multisig info:

[wallet 9uKCgo]: finalize_multisig MultisigxV1PdeMJo5rxcWTXDJ7rbyuacBseugsn2djZKKEdwvFYVmz73TvM1rBrog5bcYz5w2P6Z4jwKtzrHr7shRGo5mAShvLUxykuq5gho7gGQBCEa3JmBaY7rNHqqUaCUs1WWQi9tojZTMmCJJ4evwJzcXEDqcAd7ShwxsJtJtXdiATs54BbBfyCbwXbnDRKAtagJF36z74KJA58NgEmnHv23ZQeePCoacM MultisigxV1RTwyE53FjKPQaAn4ZMWM5hc8C92eJndpyKby4L9HpF2TUxykuq5gho7gGQBCEa3JmBaY7rNHqqUaCUs1WWQi9tojVbYtBdQNhQsizMb51K7iaWQB4te5mQaiB1cok84CbvA928U2yJFK86jNxtMopxHkcnYjjeYfp8TAB53Y1CukBiHfL2M4EztDALXLReXjJxkMry65Jw6vVePJp2T5CW8T8QE5

Before sending a transaction, all parties must exchange partial key images:

[wallet 9uKCgo]: export_multisig_info ki1

Multisig info exported to ki1.

[wallet 9uKCgo]: import_multisig_info ki2 ki3

Height 1103873, txid <f7e648915287fafca1dc67eb26267e09f92bba7ab7fd52a12600c3e6440db0eb>, 2.000000000000, idx 0/0

Height 1103882, txid <2e3a5591c741c0943a47a2bcbd1ec26493158088c88308bcbfc97423ea95c491>, 0.009000000000, idx 0/0

Multisig info imported

Then the wallet is re-synchronized to account for the complete keys. After having received data on outgoing payments, one of the participants can set up the transaction:

[wallet 9uKCgo]: transfer 9vUnTucAioDHD4ZqrFHXAgfLqrsC3LkZ6JFr5axBLhDiFMaHuEk33aqXimoZEMtQh5ibdYxcNSBw2hBZLAsCnuw4B4rBeZX 1

No payment id is included with this transaction. Is this okay? (Y/Yes/N/No): Y

There is currently a 2 block backlog at that fee level. Is this okay? (Y/Yes/N/No)Y

Transaction 1/1:

Spending from address index 0

Sending 1.000000000000. The transaction fee is 0.012000000000

Is this okay? (Y/Yes/N/No): Y

Unsigned transaction(s) successfully written to file: multisig_monero_tx

Then the generated file is transferred to another participant to be signed and broadcast to the network:

[wallet 9twQxU]: sign_multisig multisig_monero_tx

Loaded 1 transactions, for 1.031762770000, fee 0.012000000000, sending 1.000000000000 to 9vUnTucAioDHD4ZqrFHXAgfLqrsC3LkZ6JFr5axBLhDiFMaHuEk33aqXimoZEMtQh5ibdYxcNSBw2hBZLAsCnuw4B4rBeZX, 0.019762770000 change to 9uKCgopHzXrQLnph1ZNFQgdxZZyGhKRLfaNv7EEgWc1f3LQPSZR7BP4ZZn4oH7kAbX3kCd4oDYHg6hE541rQTKtHB7ufnmk, with min ring size 7, no payment ID. Is this okay? (Y/Yes/N/No): Y

Transaction successfully signed to file multisig_monero_tx, txid 1d28af64bc78d05b625c4f7af7c321d4c8943c4c2692f57aa53e303387f40db6

[wallet 9twQxU]: submit_multisig multisig_monero_tx

Loaded 1 transactions, for 1.031762770000, fee 0.012000000000, sending 1.000000000000 to 9vUnTucAioDHD4ZqrFHXAgfLqrsC3LkZ6JFr5axBLhDiFMaHuEk33aqXimoZEMtQh5ibdYxcNSBw2hBZLAsCnuw4B4rBeZX, 0.019762770000 change to 9uKCgopHzXrQLnph1ZNFQgdxZZyGhKRLfaNv7EEgWc1f3LQPSZR7BP4ZZn4oH7kAbX3kCd4oDYHg6hE541rQTKtHB7ufnmk, with min ring size 7, no payment ID. Is this okay? (Y/Yes/N/No): Y

Transaction successfully submitted, transaction <1d28af64bc78d05b625c4f7af7c321d4c8943c4c2692f57aa53e303387f40db6>

You can check its status by using the show_transfers command.

Obviously, with a great desire to use multisig wallets, it’s possible, but this approach is unlikely to suit beginners or mobile users.

Therefore, we are developing our own solution that would allow us to automate the exchange of such data without violating the privacy of the parties and the security of transactions, making multisig applications on Monero accessible to more people. Our solution is being designed to support both standard and multisig wallets, and is being run on an open server that provides the exchange and transfer of data to corresponding wallets.

More information on our contribution to Monero can be found at https://exan.tech/en/projects/monero/, as well as at the project’s page at https://wallet.exan.tech.

Resume

Currently, only a limited set of signature schemes is supported, but the developers plan to extend the list to allow for arbitrary values such as 2/5, etc. The only supported way to exchange necessary data is rather inconvenient, but thanks to the Monero’s open ecosystem the community puts high hopes on third-party solutions being developed to improve the situation.

Later in this series, we will talk about other aspects of the Monero blockchain, such as RingCT and ring signatures, wallets architecture and the libwallet library, as well as the network’s future prospects.

Please ask your questions in the comment section, suggest topics for new cryptocurrency-related articles, and subscribe to our blog to stay abreast of our upcoming events and valuable publications.


Published by HackerNoon on 2018/07/04