I can only explain it to the extent I understand myself.
As written in the original post, we have user 1 with address (B, A) and user 2 with address (C, A), where B and C are individual public spend keys and A is the shared public view key (further on, small-caps will mean secret keys).
So, the 2/2 multisig address is obtained by simply summing the public spend keys of individual participants. The address is then (B+C, A). That's the address, but who can spend from it once some funds are received?
To an outsider it's just like any other address (F, A), where F = B+C. If you give the address to someone and say "send to this", he has no idea that the public spend key is actually composed of 2 (or more) keys, he sees only the combined key F. In fact, there exists a wallet which is able to spend from the multisig address alone. It can be constructed by whomever obtains the required number of individual secret keys. For doing this, there's a tool being added in PR-2218 (currently only N/N). Even without any special way of constructing TX-es, this allows for an one-time use multisig wallet. User 1 gives the private spend key to user 2 who constructs the master wallet and does whatever he wants with it further on.
But we want to sign individual transactions and avoid handing over control of the entire wallet. That makes it a bit more complicated, as the TX construction has to be done in steps which don't reveal the secret key to the other pary.
So, both parties already have the shared secret view key a and the combined public spend key F. This lets them both have a watch-only wallet and scan for incoming transfer. Recall how one-time public keys destined for this wallet are constructed:
P = Hs(rA||i)G + F,
and the recipient (any 1 of them) can check:
P' = Hs(aR||i)G + F, P = P' ?.
That's the output. To spend, we must produce a key image (also to check spent status) and produce a signature with the corresponding one-time secret key, but without revealing the "owning" wallet secret spend key.
As described in Luigi's write-up, fist step is key image creation.
Normally, the key image would be:
I = xHp(P),
but to construct it you need to know x, and you can't know x without the "master wallet" secret spend key, because:
x = Hs(aR||i) + f.
However, we can build it in parts:
User 1 does: I_1' = bHp(P), and
user 2 does: I_2' = cHp(P).
Any user can compute the complete key image from the partial pieces:
I = Hs(aR||i)Hp(P) + I_1 + I_2,
which works because:
I = Hs(aR||i)*Hp(P) + I_1 + I_2 =
= Hs(aR||i)Hp(P) + bHp(P) + cHp(P)
= (Hs(aR||i) + b + c)Hp(P)
= (Hs(aR||i) + f)Hp(P)
= xHp(P)
Further on, we construct the ring signature, etc. but that part I don't understand well, so can't continue.
A
andB
denote both users and public keys. 2)I_D = I1_D + I2_D
is different from what I would expect from a regular key image built from the address(A, B+C)
, which should be just(b+c)*H(D)
. 3) The explanation uses terms that non-developers like myself are likely not familiar with, such as MLSAG_Gen, ss, ecdhInfo, cc etc.