nick = one "type" byte (currently "J") + one version byte (current jm_version protocol value) + Base58 (not Base58Check) of: first joinmarket.message_channel.NICK_HASH_LEN bytes of sha256 of : ephemeral per-bot-process public key.
If length(X) < joinmarket.message_channel.NICK_MAX_ENCODED, right pad with 'O' char to that length.
T: taker
M: maker
* : indicates message not including NS is encrypted
[t,m]encpubkey : taker and maker encryption pubkeys, per transaction, for ECDH setup
C: single data field for commitment to a utxo by taker, by default for PoDLE (C=H(P2)). First byte is commitment type, default "P" for PoDLE.
B(p): bitcoin signature of an encryption pubkey p (signed message format standardised as for Bitcoin Core etc.)
Commitment data for default PoDLE construct:
O: commitment opening serialization, consists of the following fields separated by a field separator (default '|'):
U: utxo used for PoDLE (not necessarily from wallet)
P: pubkey used for PoDLE (not necessarily from wallet)
P2: shifted base point pubkey for PoDLE
s, e: schnorr sig values for PoDLE
maker_auth_pub: pubkey of keypair used to authorize and setup encryption by maker (must correspond to one of maker's input addresses)
coinjoinA: coinjoin address used by maker
changeA: change address used by maker
ulist: list of utxos that maker proposes to be used in transaction
(NS): nick signature (either of form pub, sig or from pubkey recovery, bitcoin type) : message to be signed is the whole message to be sent + message channel identifier str(serverport
) (the latter to prevent cross-channel replay).
1: M: !ordertype [order details]!ordertype [orderdetails]... (NS)
2: T: !fill order-id amount tencpubkey C (NS)
3: M: !pubkey mencpubkey (NS)
4: T*: !auth O (NS)
5: M*: !ioauth ulist maker_auth_pub coinjoinA changeA B(mencpubkey) (NS)
6: T*: !tx txhex (NS)
7: M*: !sig txsig (NS)
After step 2, if provided commitment is blacklisted according to maker's policy, maker quits. Current implementation stores utxo commitments (note that there are taker_utxo_retries
possible commitments per utxo, and that the commitments do not reveal the utxo, thus effectively the same utxo can be tried that many times) in a file named blacklist
.
After step 4, if PoDLE verification fails, the maker quits before sending !ioauth
, thereby disallowing receipt of owned utxos.
For PODLE calculation see here
In 5, !ioauth ulist maker_auth_pub coinjoinA changeA B(mencpubkey) (NS)
, returned by maker, it's to be noted here that maker_auth_pub
is needed to use an input , rather than an output, pubkey, as the anti-MITM key for the reason that a maker might not always own the coinjoin output key (see e.g. patientsendpayment mixing of maker/taker role).
Nick signature: currently re-calculates expected nick from given pubkey then validates signature against the entire message before NS. In future could cut out ~ 66 bytes by making use of secp256k1 pubkey recovery. The purpose of this feature is to prevent impersonation of a running bot by using its nick on a different message channel (see issue 568).
Taker side auth of utxo has been REMOVED, see overview of argument here and see also earlier background.