{% include disclaimer.html translated="no" translationOutdated="no" %}
## Table Of Contents
- [Table Of Contents](#table-of-contents)
- [Introduction](#introduction)
- [Monero Multisig in a Nutshell](#monero-multisig-in-a-nutshell)
- [The Architecture of the MMS](#the-architecture-of-the-mms)
- [The MMS User Experience](#the-mms-user-experience)
- [A Messaging System](#a-messaging-system)
- [Signers and Messages](#signers-and-messages)
- [Getting the MMS](#getting-the-mms)
- [Installing and Configuring PyBitmessage](#installing-and-configuring-pybitmessage)
- [Further PyBitmessage Tweaks](#further-pybitmessage-tweaks)
- [MMS Command Overview](#mms-command-overview)
- [Configuring a Wallet for Use with the MMS](#configuring-a-wallet-for-use-with-the-mms)
- [Addresses and Labels](#addresses-and-labels)
- [Running CLI Wallet](#running-cli-wallet)
- [Initializing the MMS](#initializing-the-mms)
- [Configuring Signers](#configuring-signers)
- [Manually Configuring Signers](#manually-configuring-signers)
- [Auto-Config](#auto-config)
- [Sending Signer Configuration](#sending-signer-configuration)
- [Establishing the Multisig Address](#establishing-the-multisig-address)
- [Funding the Multisig Wallet](#funding-the-multisig-wallet)
- [Syncing Wallets](#syncing-wallets)
- [Making Multisig Transactions](#making-multisig-transactions)
- [The Commands in Detail](#the-commands-in-detail)
- [mms init](#mms-init)
- [mms info](#mms-info)
- [mms signer](#mms-signer)
- [mms list](#mms-list)
- [mms next](#mms-next)
- [mms sync](#mms-sync)
- [mms transfer](#mms-transfer)
- [mms delete](#mms-delete)
- [mms send](#mms-send)
- [mms receive](#mms-receive)
- [mms note](#mms-note)
- [mms show](#mms-show)
- [mms export](#mms-export)
- [mms set](#mms-set)
- [mms start\_auto\_config](#mms-start_auto_config)
- [mms auto\_config](#mms-auto_config)
- [mms stop\_auto\_config](#mms-stop_auto_config)
- [mms send\_signer\_config](#mms-send_signer_config)
- [Security](#security)
- [Use of Encryption and Signatures](#use-of-encryption-and-signatures)
- [Communication MMS to PyBitmessage](#communication-mms-to-pybitmessage)
- [Impersonation](#impersonation)
- [Attacker-Controlled Data](#attacker-controlled-data)
- [Troubleshooting](#troubleshooting)
- [Solving Syncing Troubles](#solving-syncing-troubles)
- [Redirecting a Transaction to Another Signer](#redirecting-a-transaction-to-another-signer)
- [Ignoring Uncooperative Signers when Syncing](#ignoring-uncooperative-signers-when-syncing)
- [Recovering from Lost or Duplicate Messages](#recovering-from-lost-or-duplicate-messages)
- [Correcting / Updating Signer Information](#correcting--updating-signer-information)
- [Starting from Scratch](#starting-from-scratch)
- [MMS / PyBitmessage Interactions](#mms--pybitmessage-interactions)
## Introduction
This manual describes the *Multisig Messaging System*, abbreviated as *MMS*. It's a system that aims to **simplify multisig transactions** for Monero and similar CrypoNote-based cryptocurrencies by making it easy to exchange info like key sets and sync data between wallets and by offering some "workflow support" guiding you through the various steps.
The MMS so far presents itself to the user as a set of new commands in the CLI wallet. This is not surprising, as currently the CLI wallet is the only way to do multisig transactions interactively anyway. Hopefully this will be extended in the future; the MMS was designed with other wallets like e.g. the Monero GUI wallet in mind.
This manual has some tutorial-like aspects and is intended to be read in sequential fashion, best without skipping any chapter before chapter *The Commands in Detail*.
If you have high requirements regarding security and are not sure whether using the MMS is acceptable for you in the first place, you may read the chapter *Security* first.
This first version of the manual was written around year-end 2018 by René Brunner (*rbrunner7*), the original author of the MMS.
## Monero Multisig in a Nutshell
Probably it will be pretty hard to understand the MMS without at least a basic grasp of how Monero multisig transactions work in principle. Here a short overview together with info about the *terminology* that this manual uses; for more details and more *technical* explanations you will have to look elsewhere.
*Multisig* means that a transaction needs multiple signatures before it can be submitted to the Monero network and executed. Instead of one Monero wallet creating, signing, and submitting transactions all on its own, you will have a whole group of wallets and collaboration between them to transact.
In this manual those wallets, or if you prefer, the people controlling them, are called *authorized signers*. Depending on the type of multisig used, not **all** authorized signers need to sign before a transaction becomes valid, but only a subset of them. The corresponding number (which is equal to or smaller than the number of authorized signers) is called *required signers*.
The usual notation in use here is *M/N*, with *M* standing for the number of required signers, and *N* standing for the total number of authorized signers. For example, probably the most useful and most popular type of multisig is written as *2/3*: Out of a total of **three** authorized signers, any **two** are needed to make a transaction valid.
For technically "simple" coins like Bitcoin and its forks doing multisig transactions consists of the following steps:
* Configure the multisig wallets and establish the multisig address
* Fund the multisig wallets / the multisig address so there is something to spend in the first place
* Do as many multisig transactions as you like
Monero adds one more type of step, necessary for internal bookkeeping so to speak. Simply told all the mechanisms that make Monero transactions truly private complicate things and lead to a necessity to exchange information between wallets to enable them to correctly process transactions, both incoming and outgoing.
The MMS uses the term *syncing* for the process to making wallets ready to transact again after sending or receiving transactions, and *multisig sync data* or simply *sync data* for the information that has to be exchanged to achieve that.
So the steps for Monero multisig look like that:
* Configure the multisig wallets and establish the multisig address
* Fund the multisig wallets / the multisig address so there is something to spend in the first place
* Sync the wallets for a first time
* Do 1 multisig transaction
* Sync the wallets again
* Do another multisig transaction and/or receive more funds
* Sync the wallets yet again
* ...
The "value" of the MMS is making it easy and painless to exchange all those data packets between the wallets, and telling the signers at which point of the "workflow" they currently are and what has to be the next action in order to proceed.
## The Architecture of the MMS
The MMS basically has 3 parts:
* A set of new commands in the CLI wallet
* A running instance of PyBitmessage reachable from the computer running the CLI wallet, doing message transport on behalf of the wallet
* Internal code extensions to wallet code managing a new `.mms` file per wallet with the messages in it and interfacing with PyBitmessage
[PyBitmessage](https://bitmessage.org/wiki/Main_Page) is currently the only supported program for message transport, the MMS won't "speak" to any other system. You can't use e-mail nor any other of the myriad of communication programs out there. If you don't like PyBitmessage or can't run it for any reason you won't be able to use the current version of the MMS.
The author of the MMS hopes that you will give it a try: PyBitmessage is fully open source, is under continued development, has enough users to almost assure message transport at any time, and takes privacy very seriously - just like Monero.
MMS communications should be **safe**: The Bitmessage system is considered safe as it's completely invisible who sends messages to whom, and all traffic is encrypted. For additional safety the MMS encrypts any message contents itself as well: Nobody except the receiver of an MMS message can decrypt and use its content, and the messages are signed, meaning the receiver can be sure they come from the right sender.
## The MMS User Experience
To see the "user experience" of multisig in the CLI wallet **without** MMS you can e.g. check [here](https://taiga.getmonero.org/project/rbrunner7-really-simple-multisig-transactions/wiki/22-multisig-in-cli-wallet) and [here](https://taiga.getmonero.org/project/rbrunner7-really-simple-multisig-transactions/wiki/23-multisig-in-cli-wallet).
Those pages are also useful to familiarize yourself with the steps for multisig transactions in general, as the MMS will not change the order of the steps or make any of them superfluous, but will just make execution considerably easier, and the MMS will be able to tell you the next step in order automatically in most cases.
### A Messaging System
The general approach of the MMS is very **similar to e-mail**: You send messages around, with the MMS command set in the CLI wallet playing the part of your e-mail client, allowing you to send messages, receive messages and manage a list of stored messages, something like a combined inbox and outbox.
The contents of those messages are of course all those things that must be transported between the wallets of the signers: key sets, wallet sync data, transactions to sign and/or submit to the network.
PyBitmessage is used for the actual message transport and thus plays the part of your e-mail server. Once configuration is done sending and receiving messages is fully automatic i.e. needs no manual intervention.
You don't use e-mail addresses, but Monero addresses to tell where messages should go, and you only ever send messages to other authorized signers: E.g. with 2/3 multisig you only have 2 partners to send something to.
Like with e-mail people don't have to be online at the same time for message transport to work: PyBitmessage will keep messages for up to 2 days, giving you time to fetch them.
The approach is in general quite flexbile and robust: If you need messages from several signers to proceed the MMS will wait until it finds all of them in the list of received messages, and the order of reception does not matter either, which results in a quite unstressed experience.
If another signer tells you that a particular message did not arrive or was lost somehow you can send it again anytime, picking it from the message list, like you would re-send an e-mail in a similar situation.
### Signers and Messages
So, where a "normal" Monero wallet without MMS simply told manages three types of data (addresses, accounts and transactions), the MMS adds two more: Signers and messages.
The MMS manages, for each multisig wallet separately, a list of *authorized signers*. With 2/3 multisig that list has **three** entries. On a technical level, each entry represents a Monero wallet containing keys that can be used to sign multisig transactions. On a conceptual level it's easier to imagine a group of 3 people, i.e. yourself and 2 partners, as those "authorized signers". (Often there will be indeed 3 distinct people controlling the 3 wallets, but not always of course.)
The MMS also manages a single list of *messages* per wallet: All messages you send, plus all messages you receive. While the list of authorized signers is the same in all involved wallets, those messages of course differ. The more authorized signers there are to send you messages, and the longer you transact, the more messages will accumulate.
## Getting the MMS
Right now, at the time of writing this manual (year-end 2018), the MMS is only available as part of the latest Monero code (`master` branch on Monero's [GitHub repository](https://github.com/monero-project/monero)). To use it, you have to check out that source code and compile it yourself. Doing so is easiest on a Linux system.
With the next hardfork in Spring 2019 the MMS will become an integral standard part of the Monero software: You install Monero, you have it.
A word of caution: At the time of writing using the latest development Monero version does not lead to conflicts and complications with any regular Monero release software and downloaded blockchain on the same system, but that may change between now and the hardfork, especially near the hardfork.
## Installing and Configuring PyBitmessage
Installing PyBitmessage is easy enough: You find links to downloads and install instructions from the [Bitmessage Wiki homepage](https://bitmessage.org/wiki/Main_Page). There are versions for all the major OS that Monero also supports: Linux, Windows, and macOS.
After installing run it, configure a Bitmessage address for you and note it, as you will later need it to configure your multisig wallet.
Don't worry right away if PyBitmessage does not seem to connect to the Bitmessage network when you run it the first time: Due to the decentral nature of that network it can take quite some time for your initial connect. It seems this often takes **half an hour**.
Likewise sending the very first message to a brand-new Bitmessage address can take time because there is a key exchange involved, sometimes another half of an hour. Once the key exchange is done messages are typically delivered within a few minutes however, sometimes within seconds.
You don't need to configure more than one Bitmessage address for you. You can run several multisig wallets over a **single** address without any problems because the MMS will be able to pick the right messages for the right wallets. You can even continue to use the same address for "normal" messages; those won't disturb the MMS, it will simply ignore any messages not intended for it.
Out of the box your PyBitmessage installation is not yet ready for use with the MMS because it does not allow other programs to use its API per default, you have to enable this explicitely (which makes sense, of course, for security reasons).
You find instructions how to **enable the API** on the [Bitmessage wiki API reference page](https://bitmessage.org/wiki/API_Reference). You will use the user name and the password you choose here later as command-line parameters for the CLI wallet so that the MMS will be able to log in to PyBitmessage.
## Further PyBitmessage Tweaks
The current official release version 0.6.3.2 has a [Dandelion++ protocol extension](https://arxiv.org/abs/1805.11060) built-in that hardens the network further against attacks that try to track message flow to find out who sends messages to whom. Unfortunately it seems that it has still a bug somewhere that can lead to wildly differing and very long message transmission times which is quite unfortunate when using the MMS.
There is a way to switch off Dandelion++ which, in general, is not recommended of course, but useful for using the MMS as of now:
* Locate PyBitmessage's config file `keys.dat`
* Make a new section there named `[network]`
* Add the following line to this new section: `dandelion = 0`
* Restart PyBitmessage
As a "good citizen" you may consider to open your PC for access from other Bitmessage nodes to your node from the outside by opening port 8444. You find background info about that in their [FAQ](https://bitmessage.org/wiki/FAQ). It's not strictly necessary however for your client to function.
## MMS Command Overview
There is only **one** new command in the CLI wallet that gives access to the MMS, sensibly called `mms`. That command has however quite a number of subcommands to handle all the various functions of the MMS. Here a list of the commands; for details each command has its own chapter later in the manual:
init Initialize and configure the MMS
info Display current MMS configuration
signer Define a signer by giving a single-word label, a transport address, and a Monero address, or list all defined signers
list List all messages
next Evaluate the next possible multisig-related action(s) according to wallet state, and execute or offer for choice
sync Force generation of multisig sync data regardless of wallet state, to recover from special situations like "stale data" errors
transfer Initiate transfer with MMS support; arguments identical to normal 'transfer' command arguments, for info see there
delete Delete a single message by giving its id, or delete all messages by using 'all'
send Send a single message by giving its id, or send all waiting messages
receive Check right away for new messages to receive
note Send a one-line note message to a signer, identified by its label, or show all unread notes
show Show detailed info about a single message
export Export the content of a message to file
set Set options, 'auto-send' being the only one so far
start_auto_config Start the auto-config process at the auto-config manager's wallet by creating new tokens
auto_config Start auto-config by using the token received from the auto-config manager
stop_auto_config Delete any tokens and abort an auto-config process
send_signer_config Send your complete signer configuration to all other signers
You get the list of commands by issuing `help mms`, and help for a particular subcommand by using `help mms `, e.g. `help mms next`. You can alternatively use `mms help ` if that feels more natural.
## Configuring a Wallet for Use with the MMS
### Addresses and Labels
First for better understanding some basic facts about addressing and referring to signers (or their wallets respectively) in the MMS:
If you create a new wallet it gets (of course) its own, unique public Monero address. If you later configure the wallet for multisig, the wallet **changes** its public address to the common multisig address that you share with all the other authorized signers.
The MMS uses the first, "original" public Monero address over the whole wallet lifetime for addressing, before **and** after "going multisig". It may be a little confusing that a wallet should have **two** public addresses somehow, but once you got the original address into your signer configuration you can more or less forget about it.
The MMS uses *labels* that allow you to name yourself and the other signers, and that the MMS commands use when referring to signers. (Using Monero addresses or Bitmessage addresses in such commands would be quite cumbersome.)
Labels must be one word, and they must be unique within a single wallet. The example later on in this manual uses the labels `alice` and `bob` for a case of 2/2 multisig.
### Running CLI Wallet
When you start the CLI wallet for use with the MMS there are the following two new (optional) command line parameters for connecting to PyBitmessage:
--bitmessage-address Use PyBitmessage instance at URL
--bitmessage-login Specify as username:password for PyBitmessage API
If you have PyBitmessage running on the same machine as the CLI wallet the default for the first parameter will do, and you should not need to set anything different. If it does not seem to find it despite running locally try to use `http://localhost` or `http://127.0.0.1` as argument for the first parameter.
Beside that, you need of course either `--testnet` or `--stagenet` to connect to the right network. Also using `--log-level 0` could be useful: This instructs the wallet to write detailed info into its logfile that might help to find bugs or problems with the MMS.
So a complete command line for the CLI wallet could look like this:
./monero-wallet-cli --testnet --bitmessage-login mmstest:p4ssw0rd --log-level 0
### Initializing the MMS
After creating a new wallet you have to initialize it for use with the MMS; without that crucial first step you won't be able to use any MMS features. The command to do so is `mms init`:
mms init /
`own_transport_address` is the Bitmessage address that you configured in your own PyBitmessage program. A full `init` command could look like this:
mms init 2/2 alice BM-2cUVEbbb3H6ojddYQziK3RafJ5GPcFQv7e
Use that `init` command **only once**: Executing it a second time will completely re-initialize the MMS by deleting any signer info and any messages, which you don't want except in special circumstances.
If you want to go through a MMS test as fast as possible you can instruct the wallet to ask for the password only when strictly necessary for technical reasons, and tell the MMS to send any generated message right away instead of prompting before doing so:
set ask-password 0
mms set auto-send 1
(Both those settings are active during the 2/2 multisig example shown in this manual.)
### Configuring Signers
About each signer the MMS needs to know three things:
* The one-word *label* that you will use to refer to that signer
* The *transport address* which currently means their Bitmessage address as long as this is the only supported message transport system
* The *Monero address* i.e. the "original" Monero address of their wallet
(See also above chapter *Addresses and Labels*.)
You don't have to create signers; after the `mms init` command they are already all "there", although without any info yet with the exception of yourself. The commands for setting signer information refer to them by number, 1 up to the total number of authorized signers, so 1 and 2 in the following 2/2 multisig example with signers named *Alice* and *Bob* and thus with the labels *alice* and *bob*.
After the above sample `init` command the list of signers looks like that:
# Label Transport Address
Auto-Config Token Monero Address
1 alice BM-2cUVEbbb3H6ojddYQziK3RafJ5GPcFQv7e
A1VRwm8HT8CgA5bSULDZKggR9Enc9enhWHNJuDXDK4wDD6Rwha3W7UG5Wu3YGwARTXdPw1AvFSzoNPBdiKfpEYEQP1b5cCH
2
Note that signer #1 is always "me" i.e. your own label, transport address and Monero address. So in Alice's signer list #1 will be Alice and #2 will be Bob, while in Bob's wallet it will be exactly the other way round.
There are **three ways** to complete signer information: You can enter it manually, or you can use the auto-config mechanism that the MMS offers, which has a second, "semi-automatic" variant. With 2/2 there is hardly a difference in effort, but with higher numbers of signers auto-config is easier and more reliable. In any case, one advantage of auto-config is a secure transport of addresses because PyBitmessage is used.
So pick **one** method from the three following chapters *Manually Configuring Signers*, *Auto-Config* and *Sending Signer Information*:
### Manually Configuring Signers
The command to manually enter signer info and display the list of signers is `mms signer`:
mms signer [